fsync.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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