Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

remove inode_setattr

Replace inode_setattr with opencoded variants of it in all callers. This
moves the remaining call to vmtruncate into the filesystem methods where it
can be replaced with the proper truncate sequence.

In a few cases it was obvious that we would never end up calling vmtruncate
so it was left out in the opencoded variant:

spufs: explicitly checks for ATTR_SIZE earlier
btrfs,hugetlbfs,logfs,dlmfs: explicitly clears ATTR_SIZE earlier
ufs: contains an opencoded simple_seattr + truncate that sets the filesize just above

In addition to that ncpfs called inode_setattr with handcrafted iattrs,
which allowed to trim down the opencoded variant.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Christoph Hellwig and committed by
Al Viro
1025774c eef2380c

+416 -194
+3 -1
arch/powerpc/platforms/cell/spufs/inode.c
··· 110 110 if ((attr->ia_valid & ATTR_SIZE) && 111 111 (attr->ia_size != inode->i_size)) 112 112 return -EINVAL; 113 - return inode_setattr(inode, attr); 113 + setattr_copy(inode, attr); 114 + mark_inode_dirty(inode); 115 + return 0; 114 116 } 115 117 116 118
+10 -4
drivers/staging/pohmelfs/inode.c
··· 968 968 goto err_out_exit; 969 969 } 970 970 971 - err = inode_setattr(inode, attr); 972 - if (err) { 973 - dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino); 974 - goto err_out_exit; 971 + if ((attr->ia_valid & ATTR_SIZE) && 972 + attr->ia_size != i_size_read(inode)) { 973 + err = vmtruncate(inode, attr->ia_size); 974 + if (err) { 975 + dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino); 976 + goto err_out_exit; 977 + } 975 978 } 979 + 980 + setattr_copy(inode, attr); 981 + mark_inode_dirty(inode); 976 982 977 983 dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n", 978 984 __func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
+12 -3
fs/9p/vfs_inode.c
··· 896 896 } 897 897 898 898 retval = p9_client_wstat(fid, &wstat); 899 - if (retval >= 0) 900 - retval = inode_setattr(dentry->d_inode, iattr); 899 + if (retval < 0) 900 + return retval; 901 901 902 - return retval; 902 + if ((iattr->ia_valid & ATTR_SIZE) && 903 + iattr->ia_size != i_size_read(dentry->d_inode)) { 904 + retval = vmtruncate(dentry->d_inode, iattr->ia_size); 905 + if (retval) 906 + return retval; 907 + } 908 + 909 + setattr_copy(dentry->d_inode, iattr); 910 + mark_inode_dirty(dentry->d_inode); 911 + return 0; 903 912 } 904 913 905 914 /**
+11 -2
fs/affs/inode.c
··· 235 235 goto out; 236 236 } 237 237 238 - error = inode_setattr(inode, attr); 239 - if (!error && (attr->ia_valid & ATTR_MODE)) 238 + if ((attr->ia_valid & ATTR_SIZE) && 239 + attr->ia_size != i_size_read(inode)) { 240 + error = vmtruncate(inode, attr->ia_size); 241 + if (error) 242 + return error; 243 + } 244 + 245 + setattr_copy(inode, attr); 246 + mark_inode_dirty(inode); 247 + 248 + if (attr->ia_valid & ATTR_MODE) 240 249 mode_to_prot(inode); 241 250 out: 242 251 return error;
-25
fs/attr.c
··· 146 146 } 147 147 EXPORT_SYMBOL(setattr_copy); 148 148 149 - /* 150 - * note this function is deprecated, the new truncate sequence should be 151 - * used instead -- see eg. simple_setsize, setattr_copy. 152 - */ 153 - int inode_setattr(struct inode *inode, const struct iattr *attr) 154 - { 155 - unsigned int ia_valid = attr->ia_valid; 156 - 157 - if (ia_valid & ATTR_SIZE && 158 - attr->ia_size != i_size_read(inode)) { 159 - int error; 160 - 161 - error = vmtruncate(inode, attr->ia_size); 162 - if (error) 163 - return error; 164 - } 165 - 166 - setattr_copy(inode, attr); 167 - 168 - mark_inode_dirty(inode); 169 - 170 - return 0; 171 - } 172 - EXPORT_SYMBOL(inode_setattr); 173 - 174 149 int notify_change(struct dentry * dentry, struct iattr * attr) 175 150 { 176 151 struct inode *inode = dentry->d_inode;
+7 -5
fs/btrfs/inode.c
··· 3656 3656 if (err) 3657 3657 return err; 3658 3658 } 3659 - attr->ia_valid &= ~ATTR_SIZE; 3660 3659 3661 - if (attr->ia_valid) 3662 - err = inode_setattr(inode, attr); 3660 + if (attr->ia_valid) { 3661 + setattr_copy(inode, attr); 3662 + mark_inode_dirty(inode); 3663 3663 3664 - if (!err && ((attr->ia_valid & ATTR_MODE))) 3665 - err = btrfs_acl_chmod(inode); 3664 + if (attr->ia_valid & ATTR_MODE) 3665 + err = btrfs_acl_chmod(inode); 3666 + } 3667 + 3666 3668 return err; 3667 3669 } 3668 3670
+33 -12
fs/cifs/inode.c
··· 1889 1889 CIFS_MOUNT_MAP_SPECIAL_CHR); 1890 1890 } 1891 1891 1892 - if (!rc) { 1893 - rc = inode_setattr(inode, attrs); 1892 + if (rc) 1893 + goto out; 1894 1894 1895 - /* force revalidate when any of these times are set since some 1896 - of the fs types (eg ext3, fat) do not have fine enough 1897 - time granularity to match protocol, and we do not have a 1898 - a way (yet) to query the server fs's time granularity (and 1899 - whether it rounds times down). 1900 - */ 1901 - if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))) 1902 - cifsInode->time = 0; 1895 + if ((attrs->ia_valid & ATTR_SIZE) && 1896 + attrs->ia_size != i_size_read(inode)) { 1897 + rc = vmtruncate(inode, attrs->ia_size); 1898 + if (rc) 1899 + goto out; 1903 1900 } 1901 + 1902 + setattr_copy(inode, attrs); 1903 + mark_inode_dirty(inode); 1904 + 1905 + /* force revalidate when any of these times are set since some 1906 + of the fs types (eg ext3, fat) do not have fine enough 1907 + time granularity to match protocol, and we do not have a 1908 + a way (yet) to query the server fs's time granularity (and 1909 + whether it rounds times down). 1910 + */ 1911 + if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)) 1912 + cifsInode->time = 0; 1904 1913 out: 1905 1914 kfree(args); 1906 1915 kfree(full_path); ··· 2049 2040 2050 2041 /* do not need local check to inode_check_ok since the server does 2051 2042 that */ 2052 - if (!rc) 2053 - rc = inode_setattr(inode, attrs); 2043 + if (rc) 2044 + goto cifs_setattr_exit; 2045 + 2046 + if ((attrs->ia_valid & ATTR_SIZE) && 2047 + attrs->ia_size != i_size_read(inode)) { 2048 + rc = vmtruncate(inode, attrs->ia_size); 2049 + if (rc) 2050 + goto cifs_setattr_exit; 2051 + } 2052 + 2053 + setattr_copy(inode, attrs); 2054 + mark_inode_dirty(inode); 2055 + return 0; 2056 + 2054 2057 cifs_setattr_exit: 2055 2058 kfree(full_path); 2056 2059 FreeXid(xid);
+12 -2
fs/exofs/inode.c
··· 887 887 if (error) 888 888 return error; 889 889 890 - error = inode_setattr(inode, iattr); 891 - return error; 890 + if ((iattr->ia_valid & ATTR_SIZE) && 891 + iattr->ia_size != i_size_read(inode)) { 892 + int error; 893 + 894 + error = vmtruncate(inode, iattr->ia_size); 895 + if (error) 896 + return error; 897 + } 898 + 899 + setattr_copy(inode, iattr); 900 + mark_inode_dirty(inode); 901 + return 0; 892 902 } 893 903 894 904 static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
+10 -2
fs/ext3/inode.c
··· 3208 3208 ext3_journal_stop(handle); 3209 3209 } 3210 3210 3211 - rc = inode_setattr(inode, attr); 3211 + if ((attr->ia_valid & ATTR_SIZE) && 3212 + attr->ia_size != i_size_read(inode)) { 3213 + rc = vmtruncate(inode, attr->ia_size); 3214 + if (rc) 3215 + goto err_out; 3216 + } 3212 3217 3213 - if (!rc && (ia_valid & ATTR_MODE)) 3218 + setattr_copy(inode, attr); 3219 + mark_inode_dirty(inode); 3220 + 3221 + if (ia_valid & ATTR_MODE) 3214 3222 rc = ext3_acl_chmod(inode); 3215 3223 3216 3224 err_out:
+12 -4
fs/ext4/inode.c
··· 5539 5539 ext4_truncate(inode); 5540 5540 } 5541 5541 5542 - rc = inode_setattr(inode, attr); 5542 + if ((attr->ia_valid & ATTR_SIZE) && 5543 + attr->ia_size != i_size_read(inode)) 5544 + rc = vmtruncate(inode, attr->ia_size); 5543 5545 5544 - /* If inode_setattr's call to ext4_truncate failed to get a 5545 - * transaction handle at all, we need to clean up the in-core 5546 - * orphan list manually. */ 5546 + if (!rc) { 5547 + setattr_copy(inode, attr); 5548 + mark_inode_dirty(inode); 5549 + } 5550 + 5551 + /* 5552 + * If the call to ext4_truncate failed to get a transaction handle at 5553 + * all, we need to clean up the in-core orphan list manually. 5554 + */ 5547 5555 if (inode->i_nlink) 5548 5556 ext4_orphan_del(NULL, inode); 5549 5557
+18 -7
fs/gfs2/inode.c
··· 991 991 992 992 static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) 993 993 { 994 + struct inode *inode = &ip->i_inode; 994 995 struct buffer_head *dibh; 995 996 int error; 996 997 997 998 error = gfs2_meta_inode_buffer(ip, &dibh); 998 - if (!error) { 999 - error = inode_setattr(&ip->i_inode, attr); 1000 - gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); 1001 - gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1002 - gfs2_dinode_out(ip, dibh->b_data); 1003 - brelse(dibh); 999 + if (error) 1000 + return error; 1001 + 1002 + if ((attr->ia_valid & ATTR_SIZE) && 1003 + attr->ia_size != i_size_read(inode)) { 1004 + error = vmtruncate(inode, attr->ia_size); 1005 + if (error) 1006 + return error; 1004 1007 } 1005 - return error; 1008 + 1009 + setattr_copy(inode, attr); 1010 + mark_inode_dirty(inode); 1011 + 1012 + gfs2_assert_warn(GFS2_SB(inode), !error); 1013 + gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1014 + gfs2_dinode_out(ip, dibh->b_data); 1015 + brelse(dibh); 1016 + return 0; 1006 1017 } 1007 1018 1008 1019 /**
+10 -2
fs/gfs2/ops_inode.c
··· 1136 1136 if (error) 1137 1137 goto out_end_trans; 1138 1138 1139 - error = inode_setattr(inode, attr); 1140 - gfs2_assert_warn(sdp, !error); 1139 + if ((attr->ia_valid & ATTR_SIZE) && 1140 + attr->ia_size != i_size_read(inode)) { 1141 + int error; 1142 + 1143 + error = vmtruncate(inode, attr->ia_size); 1144 + gfs2_assert_warn(sdp, !error); 1145 + } 1146 + 1147 + setattr_copy(inode, attr); 1148 + mark_inode_dirty(inode); 1141 1149 1142 1150 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1143 1151 gfs2_dinode_out(ip, dibh->b_data);
+18 -6
fs/gfs2/xattr.c
··· 1296 1296 1297 1297 int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) 1298 1298 { 1299 + struct inode *inode = &ip->i_inode; 1299 1300 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1300 1301 struct gfs2_ea_location el; 1301 1302 struct buffer_head *dibh; ··· 1322 1321 return error; 1323 1322 1324 1323 error = gfs2_meta_inode_buffer(ip, &dibh); 1325 - if (!error) { 1326 - error = inode_setattr(&ip->i_inode, attr); 1327 - gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); 1328 - gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1329 - gfs2_dinode_out(ip, dibh->b_data); 1330 - brelse(dibh); 1324 + if (error) 1325 + goto out_trans_end; 1326 + 1327 + if ((attr->ia_valid & ATTR_SIZE) && 1328 + attr->ia_size != i_size_read(inode)) { 1329 + int error; 1330 + 1331 + error = vmtruncate(inode, attr->ia_size); 1332 + gfs2_assert_warn(GFS2_SB(inode), !error); 1331 1333 } 1332 1334 1335 + setattr_copy(inode, attr); 1336 + mark_inode_dirty(inode); 1337 + 1338 + gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1339 + gfs2_dinode_out(ip, dibh->b_data); 1340 + brelse(dibh); 1341 + 1342 + out_trans_end: 1333 1343 gfs2_trans_end(sdp); 1334 1344 return error; 1335 1345 }
+9 -3
fs/hfs/inode.c
··· 612 612 attr->ia_mode = inode->i_mode & ~S_IWUGO; 613 613 attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask; 614 614 } 615 - error = inode_setattr(inode, attr); 616 - if (error) 617 - return error; 618 615 616 + if ((attr->ia_valid & ATTR_SIZE) && 617 + attr->ia_size != i_size_read(inode)) { 618 + error = vmtruncate(inode, attr->ia_size); 619 + if (error) 620 + return error; 621 + } 622 + 623 + setattr_copy(inode, attr); 624 + mark_inode_dirty(inode); 619 625 return 0; 620 626 } 621 627
+11 -1
fs/hfsplus/inode.c
··· 298 298 error = inode_change_ok(inode, attr); 299 299 if (error) 300 300 return error; 301 - return inode_setattr(inode, attr); 301 + 302 + if ((attr->ia_valid & ATTR_SIZE) && 303 + attr->ia_size != i_size_read(inode)) { 304 + error = vmtruncate(inode, attr->ia_size); 305 + if (error) 306 + return error; 307 + } 308 + 309 + setattr_copy(inode, attr); 310 + mark_inode_dirty(inode); 311 + return 0; 302 312 } 303 313 304 314 static const struct inode_operations hfsplus_file_inode_operations = {
+15 -3
fs/hostfs/hostfs_kern.c
··· 849 849 850 850 int hostfs_setattr(struct dentry *dentry, struct iattr *attr) 851 851 { 852 + struct inode *inode = dentry->d_inode; 852 853 struct hostfs_iattr attrs; 853 854 char *name; 854 855 int err; 855 856 856 - int fd = HOSTFS_I(dentry->d_inode)->fd; 857 + int fd = HOSTFS_I(inode)->fd; 857 858 858 - err = inode_change_ok(dentry->d_inode, attr); 859 + err = inode_change_ok(inode, attr); 859 860 if (err) 860 861 return err; 861 862 ··· 906 905 if (err) 907 906 return err; 908 907 909 - return inode_setattr(dentry->d_inode, attr); 908 + if ((attr->ia_valid & ATTR_SIZE) && 909 + attr->ia_size != i_size_read(inode)) { 910 + int error; 911 + 912 + error = vmtruncate(inode, attr->ia_size); 913 + if (err) 914 + return err; 915 + } 916 + 917 + setattr_copy(inode, attr); 918 + mark_inode_dirty(inode); 919 + return 0; 910 920 } 911 921 912 922 static const struct inode_operations hostfs_iops = {
+9 -3
fs/hpfs/inode.c
··· 277 277 if (error) 278 278 goto out_unlock; 279 279 280 - error = inode_setattr(inode, attr); 281 - if (error) 282 - goto out_unlock; 280 + if ((attr->ia_valid & ATTR_SIZE) && 281 + attr->ia_size != i_size_read(inode)) { 282 + error = vmtruncate(inode, attr->ia_size); 283 + if (error) 284 + return error; 285 + } 286 + 287 + setattr_copy(inode, attr); 288 + mark_inode_dirty(inode); 283 289 284 290 hpfs_write_inode(inode); 285 291
+9 -8
fs/hugetlbfs/inode.c
··· 448 448 449 449 error = inode_change_ok(inode, attr); 450 450 if (error) 451 - goto out; 451 + return error; 452 452 453 453 if (ia_valid & ATTR_SIZE) { 454 454 error = -EINVAL; 455 - if (!(attr->ia_size & ~huge_page_mask(h))) 456 - error = hugetlb_vmtruncate(inode, attr->ia_size); 455 + if (attr->ia_size & ~huge_page_mask(h)) 456 + return -EINVAL; 457 + error = hugetlb_vmtruncate(inode, attr->ia_size); 457 458 if (error) 458 - goto out; 459 - attr->ia_valid &= ~ATTR_SIZE; 459 + return error; 460 460 } 461 - error = inode_setattr(inode, attr); 462 - out: 463 - return error; 461 + 462 + setattr_copy(inode, attr); 463 + mark_inode_dirty(inode); 464 + return 0; 464 465 } 465 466 466 467 static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
+11 -3
fs/jfs/file.c
··· 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 19 20 + #include <linux/mm.h> 20 21 #include <linux/fs.h> 21 22 #include <linux/quotaops.h> 22 23 #include "jfs_incore.h" ··· 108 107 return rc; 109 108 } 110 109 111 - rc = inode_setattr(inode, iattr); 110 + if ((iattr->ia_valid & ATTR_SIZE) && 111 + iattr->ia_size != i_size_read(inode)) { 112 + rc = vmtruncate(inode, iattr->ia_size); 113 + if (rc) 114 + return rc; 115 + } 112 116 113 - if (!rc && (iattr->ia_valid & ATTR_MODE)) 117 + setattr_copy(inode, iattr); 118 + mark_inode_dirty(inode); 119 + 120 + if (iattr->ia_valid & ATTR_MODE) 114 121 rc = jfs_acl_chmod(inode); 115 - 116 122 return rc; 117 123 } 118 124
+11 -7
fs/logfs/file.c
··· 232 232 struct inode *inode = dentry->d_inode; 233 233 int err = 0; 234 234 235 - if (attr->ia_valid & ATTR_SIZE) 235 + if (attr->ia_valid & ATTR_SIZE) { 236 236 err = logfs_truncate(inode, attr->ia_size); 237 - attr->ia_valid &= ~ATTR_SIZE; 237 + if (err) 238 + return err; 239 + } 238 240 239 - if (!err) 240 - err = inode_change_ok(inode, attr); 241 - if (!err) 242 - err = inode_setattr(inode, attr); 243 - return err; 241 + err = inode_change_ok(inode, attr); 242 + if (err) 243 + return err; 244 + 245 + setattr_copy(inode, attr); 246 + mark_inode_dirty(inode); 247 + return 0; 244 248 } 245 249 246 250 const struct inode_operations logfs_reg_iops = {
+11 -1
fs/minix/file.c
··· 31 31 error = inode_change_ok(inode, attr); 32 32 if (error) 33 33 return error; 34 - return inode_setattr(inode, attr); 34 + 35 + if ((attr->ia_valid & ATTR_SIZE) && 36 + attr->ia_size != i_size_read(inode)) { 37 + error = vmtruncate(inode, attr->ia_size); 38 + if (error) 39 + return error; 40 + } 41 + 42 + setattr_copy(inode, attr); 43 + mark_inode_dirty(inode); 44 + return 0; 35 45 } 36 46 37 47 const struct inode_operations minix_file_inode_operations = {
+12 -12
fs/ncpfs/inode.c
··· 924 924 tmpattr.ia_valid = ATTR_MODE; 925 925 tmpattr.ia_mode = attr->ia_mode; 926 926 927 - result = inode_setattr(inode, &tmpattr); 928 - if (result) 929 - goto out; 927 + setattr_copy(inode, &tmpattr); 928 + mark_inode_dirty(inode); 930 929 } 931 930 } 932 931 #endif ··· 953 954 result = ncp_make_closed(inode); 954 955 if (result) 955 956 goto out; 956 - { 957 - struct iattr tmpattr; 958 - 959 - tmpattr.ia_valid = ATTR_SIZE; 960 - tmpattr.ia_size = attr->ia_size; 961 - 962 - result = inode_setattr(inode, &tmpattr); 957 + 958 + if (attr->ia_size != i_size_read(inode)) { 959 + result = vmtruncate(inode, attr->ia_size); 963 960 if (result) 964 961 goto out; 962 + mark_inode_dirty(inode); 965 963 } 966 964 } 967 965 if ((attr->ia_valid & ATTR_CTIME) != 0) { ··· 998 1002 NCP_FINFO(inode)->nwattr = info.attributes; 999 1003 #endif 1000 1004 } 1001 - if (!result) 1002 - result = inode_setattr(inode, attr); 1005 + if (result) 1006 + goto out; 1007 + 1008 + setattr_copy(inode, attr); 1009 + mark_inode_dirty(inode); 1010 + 1003 1011 out: 1004 1012 unlock_kernel(); 1005 1013 return result;
+20 -7
fs/nilfs2/inode.c
··· 656 656 err = nilfs_transaction_begin(sb, &ti, 0); 657 657 if (unlikely(err)) 658 658 return err; 659 - err = inode_setattr(inode, iattr); 660 - if (!err && (iattr->ia_valid & ATTR_MODE)) 661 - err = nilfs_acl_chmod(inode); 662 - if (likely(!err)) 663 - err = nilfs_transaction_commit(sb); 664 - else 665 - nilfs_transaction_abort(sb); 666 659 660 + if ((iattr->ia_valid & ATTR_SIZE) && 661 + iattr->ia_size != i_size_read(inode)) { 662 + err = vmtruncate(inode, iattr->ia_size); 663 + if (unlikely(err)) 664 + goto out_err; 665 + } 666 + 667 + setattr_copy(inode, iattr); 668 + mark_inode_dirty(inode); 669 + 670 + if (iattr->ia_valid & ATTR_MODE) { 671 + err = nilfs_acl_chmod(inode); 672 + if (unlikely(err)) 673 + goto out_err; 674 + } 675 + 676 + return nilfs_transaction_commit(sb); 677 + 678 + out_err: 679 + nilfs_transaction_abort(sb); 667 680 return err; 668 681 } 669 682
-3
fs/ntfs/inode.c
··· 2879 2879 * 2880 2880 * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also 2881 2881 * called with ->i_alloc_sem held for writing. 2882 - * 2883 - * Basically this is a copy of generic notify_change() and inode_setattr() 2884 - * functionality, except we intercept and abort changes in i_size. 2885 2882 */ 2886 2883 int ntfs_setattr(struct dentry *dentry, struct iattr *attr) 2887 2884 {
+5 -3
fs/ocfs2/dlmfs/dlmfs.c
··· 214 214 215 215 attr->ia_valid &= ~ATTR_SIZE; 216 216 error = inode_change_ok(inode, attr); 217 - if (!error) 218 - error = inode_setattr(inode, attr); 217 + if (error) 218 + return error; 219 219 220 - return error; 220 + setattr_copy(inode, attr); 221 + mark_inode_dirty(inode); 222 + return 0; 221 223 } 222 224 223 225 static unsigned int dlmfs_file_poll(struct file *file, poll_table *wait)
+12 -4
fs/ocfs2/file.c
··· 1238 1238 * Otherwise, we could get into problems with truncate as 1239 1239 * ip_alloc_sem is used there to protect against i_size 1240 1240 * changes. 1241 + * 1242 + * XXX: this means the conditional below can probably be removed. 1241 1243 */ 1242 - status = inode_setattr(inode, attr); 1243 - if (status < 0) { 1244 - mlog_errno(status); 1245 - goto bail_commit; 1244 + if ((attr->ia_valid & ATTR_SIZE) && 1245 + attr->ia_size != i_size_read(inode)) { 1246 + status = vmtruncate(inode, attr->ia_size); 1247 + if (status) { 1248 + mlog_errno(status); 1249 + goto bail_commit; 1250 + } 1246 1251 } 1252 + 1253 + setattr_copy(inode, attr); 1254 + mark_inode_dirty(inode); 1247 1255 1248 1256 status = ocfs2_mark_inode_dirty(handle, inode, bh); 1249 1257 if (status < 0)
+11 -1
fs/omfs/file.c
··· 349 349 error = inode_change_ok(inode, attr); 350 350 if (error) 351 351 return error; 352 - return inode_setattr(inode, attr); 352 + 353 + if ((attr->ia_valid & ATTR_SIZE) && 354 + attr->ia_size != i_size_read(inode)) { 355 + error = vmtruncate(inode, attr->ia_size); 356 + if (error) 357 + return error; 358 + } 359 + 360 + setattr_copy(inode, attr); 361 + mark_inode_dirty(inode); 362 + return 0; 353 363 } 354 364 355 365 const struct inode_operations omfs_file_inops = {
+13 -3
fs/proc/base.c
··· 561 561 return -EPERM; 562 562 563 563 error = inode_change_ok(inode, attr); 564 - if (!error) 565 - error = inode_setattr(inode, attr); 566 - return error; 564 + if (error) 565 + return error; 566 + 567 + if ((attr->ia_valid & ATTR_SIZE) && 568 + attr->ia_size != i_size_read(inode)) { 569 + error = vmtruncate(inode, attr->ia_size); 570 + if (error) 571 + return error; 572 + } 573 + 574 + setattr_copy(inode, attr); 575 + mark_inode_dirty(inode); 576 + return 0; 567 577 } 568 578 569 579 static const struct inode_operations proc_def_inode_operations = {
+12 -6
fs/proc/generic.c
··· 12 12 #include <linux/time.h> 13 13 #include <linux/proc_fs.h> 14 14 #include <linux/stat.h> 15 + #include <linux/mm.h> 15 16 #include <linux/module.h> 16 17 #include <linux/slab.h> 17 18 #include <linux/mount.h> ··· 259 258 260 259 error = inode_change_ok(inode, iattr); 261 260 if (error) 262 - goto out; 261 + return error; 263 262 264 - error = inode_setattr(inode, iattr); 265 - if (error) 266 - goto out; 263 + if ((iattr->ia_valid & ATTR_SIZE) && 264 + iattr->ia_size != i_size_read(inode)) { 265 + error = vmtruncate(inode, iattr->ia_size); 266 + if (error) 267 + return error; 268 + } 269 + 270 + setattr_copy(inode, iattr); 271 + mark_inode_dirty(inode); 267 272 268 273 de->uid = inode->i_uid; 269 274 de->gid = inode->i_gid; 270 275 de->mode = inode->i_mode; 271 - out: 272 - return error; 276 + return 0; 273 277 } 274 278 275 279 static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
+12 -3
fs/proc/proc_sysctl.c
··· 329 329 return -EPERM; 330 330 331 331 error = inode_change_ok(inode, attr); 332 - if (!error) 333 - error = inode_setattr(inode, attr); 332 + if (error) 333 + return error; 334 334 335 - return error; 335 + if ((attr->ia_valid & ATTR_SIZE) && 336 + attr->ia_size != i_size_read(inode)) { 337 + error = vmtruncate(inode, attr->ia_size); 338 + if (error) 339 + return error; 340 + } 341 + 342 + setattr_copy(inode, attr); 343 + mark_inode_dirty(inode); 344 + return 0; 336 345 } 337 346 338 347 static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+51 -44
fs/reiserfs/inode.c
··· 3134 3134 } 3135 3135 3136 3136 error = inode_change_ok(inode, attr); 3137 - if (!error) { 3138 - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || 3139 - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { 3140 - error = reiserfs_chown_xattrs(inode, attr); 3137 + if (error) 3138 + goto out; 3141 3139 3142 - if (!error) { 3143 - struct reiserfs_transaction_handle th; 3144 - int jbegin_count = 3145 - 2 * 3146 - (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + 3147 - REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + 3148 - 2; 3140 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || 3141 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { 3142 + struct reiserfs_transaction_handle th; 3143 + int jbegin_count = 3144 + 2 * 3145 + (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + 3146 + REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + 3147 + 2; 3149 3148 3150 - /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ 3151 - error = 3152 - journal_begin(&th, inode->i_sb, 3153 - jbegin_count); 3154 - if (error) 3155 - goto out; 3156 - error = dquot_transfer(inode, attr); 3157 - if (error) { 3158 - journal_end(&th, inode->i_sb, 3159 - jbegin_count); 3160 - goto out; 3161 - } 3162 - /* Update corresponding info in inode so that everything is in 3163 - * one transaction */ 3164 - if (attr->ia_valid & ATTR_UID) 3165 - inode->i_uid = attr->ia_uid; 3166 - if (attr->ia_valid & ATTR_GID) 3167 - inode->i_gid = attr->ia_gid; 3168 - mark_inode_dirty(inode); 3169 - error = 3170 - journal_end(&th, inode->i_sb, jbegin_count); 3171 - } 3149 + error = reiserfs_chown_xattrs(inode, attr); 3150 + 3151 + if (error) 3152 + return error; 3153 + 3154 + /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ 3155 + error = journal_begin(&th, inode->i_sb, jbegin_count); 3156 + if (error) 3157 + goto out; 3158 + error = dquot_transfer(inode, attr); 3159 + if (error) { 3160 + journal_end(&th, inode->i_sb, jbegin_count); 3161 + goto out; 3172 3162 } 3173 - if (!error) { 3174 - /* 3175 - * Relax the lock here, as it might truncate the 3176 - * inode pages and wait for inode pages locks. 3177 - * To release such page lock, the owner needs the 3178 - * reiserfs lock 3179 - */ 3180 - reiserfs_write_unlock_once(inode->i_sb, depth); 3181 - error = inode_setattr(inode, attr); 3182 - depth = reiserfs_write_lock_once(inode->i_sb); 3183 - } 3163 + 3164 + /* Update corresponding info in inode so that everything is in 3165 + * one transaction */ 3166 + if (attr->ia_valid & ATTR_UID) 3167 + inode->i_uid = attr->ia_uid; 3168 + if (attr->ia_valid & ATTR_GID) 3169 + inode->i_gid = attr->ia_gid; 3170 + mark_inode_dirty(inode); 3171 + error = journal_end(&th, inode->i_sb, jbegin_count); 3172 + if (error) 3173 + goto out; 3184 3174 } 3175 + 3176 + /* 3177 + * Relax the lock here, as it might truncate the 3178 + * inode pages and wait for inode pages locks. 3179 + * To release such page lock, the owner needs the 3180 + * reiserfs lock 3181 + */ 3182 + reiserfs_write_unlock_once(inode->i_sb, depth); 3183 + if ((attr->ia_valid & ATTR_SIZE) && 3184 + attr->ia_size != i_size_read(inode)) 3185 + error = vmtruncate(inode, attr->ia_size); 3186 + 3187 + if (!error) { 3188 + setattr_copy(inode, attr); 3189 + mark_inode_dirty(inode); 3190 + } 3191 + depth = reiserfs_write_lock_once(inode->i_sb); 3185 3192 3186 3193 if (!error && reiserfs_posixacl(inode->i_sb)) { 3187 3194 if (attr->ia_valid & ATTR_MODE)
+11 -1
fs/sysv/file.c
··· 38 38 error = inode_change_ok(inode, attr); 39 39 if (error) 40 40 return error; 41 - return inode_setattr(inode, attr); 41 + 42 + if ((attr->ia_valid & ATTR_SIZE) && 43 + attr->ia_size != i_size_read(inode)) { 44 + error = vmtruncate(inode, attr->ia_size); 45 + if (error) 46 + return error; 47 + } 48 + 49 + setattr_copy(inode, attr); 50 + mark_inode_dirty(inode); 51 + return 0; 42 52 } 43 53 44 54 const struct inode_operations sysv_file_inode_operations = {
+11 -1
fs/udf/file.c
··· 236 236 error = inode_change_ok(inode, attr); 237 237 if (error) 238 238 return error; 239 - return inode_setattr(inode, attr); 239 + 240 + if ((attr->ia_valid & ATTR_SIZE) && 241 + attr->ia_size != i_size_read(inode)) { 242 + error = vmtruncate(inode, attr->ia_size); 243 + if (error) 244 + return error; 245 + } 246 + 247 + setattr_copy(inode, attr); 248 + mark_inode_dirty(inode); 249 + return 0; 240 250 } 241 251 242 252 const struct inode_operations udf_file_inode_operations = {
+4 -1
fs/ufs/truncate.c
··· 525 525 if (error) 526 526 return error; 527 527 } 528 - return inode_setattr(inode, attr); 528 + 529 + setattr_copy(inode, attr); 530 + mark_inode_dirty(inode); 531 + return 0; 529 532 } 530 533 531 534 const struct inode_operations ufs_file_inode_operations = {
-1
include/linux/fs.h
··· 2392 2392 2393 2393 extern int inode_change_ok(const struct inode *, struct iattr *); 2394 2394 extern int inode_newsize_ok(const struct inode *, loff_t offset); 2395 - extern int __must_check inode_setattr(struct inode *, const struct iattr *); 2396 2395 extern void setattr_copy(struct inode *inode, const struct iattr *attr); 2397 2396 2398 2397 extern void file_update_time(struct file *file);