fsync.c 3.0 KB

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