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 20 #include <linux/mm.h> 21 #include <linux/fs.h> 22 #include <linux/posix_acl.h> 23 #include <linux/quotaops.h> 24 #include "jfs_incore.h" 25 #include "jfs_inode.h" 26 #include "jfs_dmap.h" 27 #include "jfs_txnmgr.h" 28 #include "jfs_xattr.h" 29 #include "jfs_acl.h" 30 #include "jfs_debug.h" 31 32 int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) 33 { 34 struct inode *inode = file->f_mapping->host; 35 int rc = 0; 36 37 rc = filemap_write_and_wait_range(inode->i_mapping, start, end); 38 if (rc) 39 return rc; 40 41 inode_lock(inode); 42 if (!(inode->i_state & I_DIRTY_ALL) || 43 (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) { 44 /* Make sure committed changes hit the disk */ 45 jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1); 46 inode_unlock(inode); 47 return rc; 48 } 49 50 rc |= jfs_commit_inode(inode, 1); 51 inode_unlock(inode); 52 53 return rc ? -EIO : 0; 54 } 55 56 static int jfs_open(struct inode *inode, struct file *file) 57 { 58 int rc; 59 60 if ((rc = dquot_file_open(inode, file))) 61 return rc; 62 63 /* 64 * We attempt to allow only one "active" file open per aggregate 65 * group. Otherwise, appending to files in parallel can cause 66 * fragmentation within the files. 67 * 68 * If the file is empty, it was probably just created and going 69 * to be written to. If it has a size, we'll hold off until the 70 * file is actually grown. 71 */ 72 if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE && 73 (inode->i_size == 0)) { 74 struct jfs_inode_info *ji = JFS_IP(inode); 75 spin_lock_irq(&ji->ag_lock); 76 if (ji->active_ag == -1) { 77 struct jfs_sb_info *jfs_sb = JFS_SBI(inode->i_sb); 78 ji->active_ag = BLKTOAG(addressPXD(&ji->ixpxd), jfs_sb); 79 atomic_inc(&jfs_sb->bmap->db_active[ji->active_ag]); 80 } 81 spin_unlock_irq(&ji->ag_lock); 82 } 83 84 return 0; 85 } 86 static int jfs_release(struct inode *inode, struct file *file) 87 { 88 struct jfs_inode_info *ji = JFS_IP(inode); 89 90 spin_lock_irq(&ji->ag_lock); 91 if (ji->active_ag != -1) { 92 struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap; 93 atomic_dec(&bmap->db_active[ji->active_ag]); 94 ji->active_ag = -1; 95 } 96 spin_unlock_irq(&ji->ag_lock); 97 98 return 0; 99 } 100 101 int jfs_setattr(struct dentry *dentry, struct iattr *iattr) 102 { 103 struct inode *inode = d_inode(dentry); 104 int rc; 105 106 rc = inode_change_ok(inode, iattr); 107 if (rc) 108 return rc; 109 110 if (is_quota_modification(inode, iattr)) { 111 rc = dquot_initialize(inode); 112 if (rc) 113 return rc; 114 } 115 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) || 116 (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) { 117 rc = dquot_transfer(inode, iattr); 118 if (rc) 119 return rc; 120 } 121 122 if ((iattr->ia_valid & ATTR_SIZE) && 123 iattr->ia_size != i_size_read(inode)) { 124 inode_dio_wait(inode); 125 126 rc = inode_newsize_ok(inode, iattr->ia_size); 127 if (rc) 128 return rc; 129 130 truncate_setsize(inode, iattr->ia_size); 131 jfs_truncate(inode); 132 } 133 134 setattr_copy(inode, iattr); 135 mark_inode_dirty(inode); 136 137 if (iattr->ia_valid & ATTR_MODE) 138 rc = posix_acl_chmod(inode, inode->i_mode); 139 return rc; 140 } 141 142 const struct inode_operations jfs_file_inode_operations = { 143 .setxattr = jfs_setxattr, 144 .getxattr = jfs_getxattr, 145 .listxattr = jfs_listxattr, 146 .removexattr = jfs_removexattr, 147 .setattr = jfs_setattr, 148 #ifdef CONFIG_JFS_POSIX_ACL 149 .get_acl = jfs_get_acl, 150 .set_acl = jfs_set_acl, 151 #endif 152 }; 153 154 const struct file_operations jfs_file_operations = { 155 .open = jfs_open, 156 .llseek = generic_file_llseek, 157 .read_iter = generic_file_read_iter, 158 .write_iter = generic_file_write_iter, 159 .mmap = generic_file_mmap, 160 .splice_read = generic_file_splice_read, 161 .splice_write = iter_file_splice_write, 162 .fsync = jfs_fsync, 163 .release = jfs_release, 164 .unlocked_ioctl = jfs_ioctl, 165 #ifdef CONFIG_COMPAT 166 .compat_ioctl = jfs_compat_ioctl, 167 #endif 168 }; 169