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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *   Copyright (c) International Business Machines Corp., 2000-2002
  3.  *   Portions Copyright (c) Christoph Hellwig, 2001-2002
  4.  *
  5.  *   This program is free software;  you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 2 of the License, or 
  8.  *   (at your option) any later version.
  9.  * 
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13.  *   the GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program;  if not, write to the Free Software 
  17.  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  */
  19. #include <linux/fs.h>
  20. #include "jfs_incore.h"
  21. #include "jfs_dmap.h"
  22. #include "jfs_txnmgr.h"
  23. #include "jfs_xattr.h"
  24. #include "jfs_debug.h"
  25. extern int jfs_commit_inode(struct inode *, int);
  26. int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
  27. {
  28. struct inode *inode = dentry->d_inode;
  29. int rc = 0;
  30. rc = fsync_inode_data_buffers(inode);
  31. if (!(inode->i_state & I_DIRTY))
  32. return rc;
  33. if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
  34. return rc;
  35. rc |= jfs_commit_inode(inode, 1);
  36. return rc ? -EIO : 0;
  37. }
  38. /*
  39.  * Guts of jfs_truncate.  Called with locks already held.  Can be called
  40.  * with directory for truncating directory index table.
  41.  */
  42. void jfs_truncate_nolock(struct inode *ip, loff_t length)
  43. {
  44. loff_t newsize;
  45. tid_t tid;
  46. ASSERT(length >= 0);
  47. if (test_cflag(COMMIT_Nolink, ip)) {
  48. xtTruncate(0, ip, length, COMMIT_WMAP);
  49. return;
  50. }
  51. do {
  52. tid = txBegin(ip->i_sb, 0);
  53. /*
  54.  * The commit_sem cannot be taken before txBegin.
  55.  * txBegin may block and there is a chance the inode
  56.  * could be marked dirty and need to be committed
  57.  * before txBegin unblocks
  58.  */
  59. down(&JFS_IP(ip)->commit_sem);
  60. newsize = xtTruncate(tid, ip, length,
  61.      COMMIT_TRUNCATE | COMMIT_PWMAP);
  62. if (newsize < 0) {
  63. txEnd(tid);
  64. up(&JFS_IP(ip)->commit_sem);
  65. break;
  66. }
  67. ip->i_mtime = ip->i_ctime = CURRENT_TIME;
  68. mark_inode_dirty(ip);
  69. txCommit(tid, 1, &ip, 0);
  70. txEnd(tid);
  71. up(&JFS_IP(ip)->commit_sem);
  72. } while (newsize > length); /* Truncate isn't always atomic */
  73. }
  74. static void jfs_truncate(struct inode *ip)
  75. {
  76. jFYI(1, ("jfs_truncate: size = 0x%lxn", (ulong) ip->i_size));
  77. IWRITE_LOCK(ip);
  78. jfs_truncate_nolock(ip, ip->i_size);
  79. IWRITE_UNLOCK(ip);
  80. }
  81. static int jfs_open(struct inode *inode, struct file *file)
  82. {
  83. int rc;
  84. if ((rc = generic_file_open(inode, file)))
  85. return rc;
  86. /*
  87.  * We attempt to allow only one "active" file open per aggregate
  88.  * group.  Otherwise, appending to files in parallel can cause
  89.  * fragmentation within the files.
  90.  *
  91.  * If the file is empty, it was probably just created and going
  92.  * to be written to.  If it has a size, we'll hold off until the
  93.  * file is actually grown.
  94.  */
  95. if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE &&
  96.     (inode->i_size == 0)) {
  97. struct jfs_inode_info *ji = JFS_IP(inode);
  98. if (ji->active_ag == -1) {
  99. ji->active_ag = ji->agno;
  100. atomic_inc(
  101.     &JFS_SBI(inode->i_sb)->bmap->db_active[ji->agno]);
  102. }
  103. }
  104. return 0;
  105. }
  106. static int jfs_release(struct inode *inode, struct file *file)
  107. {
  108. struct jfs_inode_info *ji = JFS_IP(inode);
  109. if (ji->active_ag != -1) {
  110. struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
  111. atomic_dec(&bmap->db_active[ji->active_ag]);
  112. ji->active_ag = -1;
  113. }
  114. return 0;
  115. }
  116. struct inode_operations jfs_file_inode_operations = {
  117. .truncate = jfs_truncate,
  118. .setxattr = jfs_setxattr,
  119. .getxattr = jfs_getxattr,
  120. .listxattr = jfs_listxattr,
  121. .removexattr = jfs_removexattr,
  122. };
  123. struct file_operations jfs_file_operations = {
  124. .open = jfs_open,
  125. .llseek = generic_file_llseek,
  126. .write = generic_file_write,
  127. .read = generic_file_read,
  128. .mmap = generic_file_mmap,
  129. .fsync = jfs_fsync,
  130. .release = jfs_release,
  131. };