fsync.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * QNX4 file system, Linux implementation.
  3. *
  4. * Version : 0.1
  5. *
  6. * Using parts of the xiafs filesystem.
  7. *
  8. * History :
  9. *
  10. * 24-03-1998 by Richard Frowijn : first release.
  11. */
  12. #include <linux/config.h>
  13. #include <linux/errno.h>
  14. #include <linux/time.h>
  15. #include <linux/stat.h>
  16. #include <linux/fcntl.h>
  17. #include <linux/smp_lock.h>
  18. #include <linux/buffer_head.h>
  19. #include <linux/fs.h>
  20. #include <linux/qnx4_fs.h>
  21. #include <asm/system.h>
  22. /*
  23. * The functions for qnx4 fs file synchronization.
  24. */
  25. #ifdef CONFIG_QNX4FS_RW
  26. static int sync_block(struct inode *inode, unsigned short *block, int wait)
  27. {
  28. struct buffer_head *bh;
  29. unsigned short tmp;
  30. if (!*block)
  31. return 0;
  32. tmp = *block;
  33. bh = sb_find_get_block(inode->i_sb, *block);
  34. if (!bh)
  35. return 0;
  36. if (*block != tmp) {
  37. brelse(bh);
  38. return 1;
  39. }
  40. if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
  41. brelse(bh);
  42. return -1;
  43. }
  44. if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
  45. brelse(bh);
  46. return 0;
  47. }
  48. ll_rw_block(WRITE, 1, &bh);
  49. atomic_dec(&bh->b_count);
  50. return 0;
  51. }
  52. #ifdef WTF
  53. static int sync_iblock(struct inode *inode, unsigned short *iblock,
  54. struct buffer_head **bh, int wait)
  55. {
  56. int rc;
  57. unsigned short tmp;
  58. *bh = NULL;
  59. tmp = *iblock;
  60. if (!tmp)
  61. return 0;
  62. rc = sync_block(inode, iblock, wait);
  63. if (rc)
  64. return rc;
  65. *bh = sb_bread(inode->i_sb, tmp);
  66. if (tmp != *iblock) {
  67. brelse(*bh);
  68. *bh = NULL;
  69. return 1;
  70. }
  71. if (!*bh)
  72. return -1;
  73. return 0;
  74. }
  75. #endif
  76. static int sync_direct(struct inode *inode, int wait)
  77. {
  78. int i;
  79. int rc, err = 0;
  80. for (i = 0; i < 7; i++) {
  81. rc = sync_block(inode,
  82. (unsigned short *) qnx4_raw_inode(inode)->di_first_xtnt.xtnt_blk + i, wait);
  83. if (rc > 0)
  84. break;
  85. if (rc)
  86. err = rc;
  87. }
  88. return err;
  89. }
  90. #ifdef WTF
  91. static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
  92. {
  93. int i;
  94. struct buffer_head *ind_bh;
  95. int rc, err = 0;
  96. rc = sync_iblock(inode, iblock, &ind_bh, wait);
  97. if (rc || !ind_bh)
  98. return rc;
  99. for (i = 0; i < 512; i++) {
  100. rc = sync_block(inode,
  101. ((unsigned short *) ind_bh->b_data) + i,
  102. wait);
  103. if (rc > 0)
  104. break;
  105. if (rc)
  106. err = rc;
  107. }
  108. brelse(ind_bh);
  109. return err;
  110. }
  111. static int sync_dindirect(struct inode *inode, unsigned short *diblock,
  112. int wait)
  113. {
  114. int i;
  115. struct buffer_head *dind_bh;
  116. int rc, err = 0;
  117. rc = sync_iblock(inode, diblock, &dind_bh, wait);
  118. if (rc || !dind_bh)
  119. return rc;
  120. for (i = 0; i < 512; i++) {
  121. rc = sync_indirect(inode,
  122. ((unsigned short *) dind_bh->b_data) + i,
  123. wait);
  124. if (rc > 0)
  125. break;
  126. if (rc)
  127. err = rc;
  128. }
  129. brelse(dind_bh);
  130. return err;
  131. }
  132. #endif
  133. int qnx4_sync_file(struct file *file, struct dentry *dentry, int unused)
  134. {
  135. struct inode *inode = dentry->d_inode;
  136. int wait, err = 0;
  137. (void) file;
  138. if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
  139. S_ISLNK(inode->i_mode)))
  140. return -EINVAL;
  141. lock_kernel();
  142. for (wait = 0; wait <= 1; wait++) {
  143. err |= sync_direct(inode, wait);
  144. }
  145. err |= qnx4_sync_inode(inode);
  146. unlock_kernel();
  147. return (err < 0) ? -EIO : 0;
  148. }
  149. #endif