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