Commit 1025774ce411f2bd4b059ad7b53f0003569b74fa
Committed by
Al Viro
1 parent
eef2380c18
Exists in
master
and in
4 other branches
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>
Showing 35 changed files with 416 additions and 194 deletions Side-by-side Diff
- arch/powerpc/platforms/cell/spufs/inode.c
- drivers/staging/pohmelfs/inode.c
- fs/9p/vfs_inode.c
- fs/affs/inode.c
- fs/attr.c
- fs/btrfs/inode.c
- fs/cifs/inode.c
- fs/exofs/inode.c
- fs/ext3/inode.c
- fs/ext4/inode.c
- fs/gfs2/inode.c
- fs/gfs2/ops_inode.c
- fs/gfs2/xattr.c
- fs/hfs/inode.c
- fs/hfsplus/inode.c
- fs/hostfs/hostfs_kern.c
- fs/hpfs/inode.c
- fs/hugetlbfs/inode.c
- fs/jfs/file.c
- fs/logfs/file.c
- fs/minix/file.c
- fs/ncpfs/inode.c
- fs/nilfs2/inode.c
- fs/ntfs/inode.c
- fs/ocfs2/dlmfs/dlmfs.c
- fs/ocfs2/file.c
- fs/omfs/file.c
- fs/proc/base.c
- fs/proc/generic.c
- fs/proc/proc_sysctl.c
- fs/reiserfs/inode.c
- fs/sysv/file.c
- fs/udf/file.c
- fs/ufs/truncate.c
- include/linux/fs.h
arch/powerpc/platforms/cell/spufs/inode.c
drivers/staging/pohmelfs/inode.c
... | ... | @@ -968,11 +968,17 @@ |
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, |
fs/9p/vfs_inode.c
... | ... | @@ -896,10 +896,19 @@ |
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 | /** |
fs/affs/inode.c
... | ... | @@ -235,8 +235,17 @@ |
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; |
fs/attr.c
... | ... | @@ -146,31 +146,6 @@ |
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; |
fs/btrfs/inode.c
... | ... | @@ -3656,13 +3656,15 @@ |
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 |
fs/cifs/inode.c
... | ... | @@ -1889,18 +1889,27 @@ |
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); |
... | ... | @@ -2040,8 +2049,20 @@ |
2040 | 2049 | |
2041 | 2050 | /* do not need local check to inode_check_ok since the server does |
2042 | 2051 | that */ |
2043 | - if (!rc) | |
2044 | - rc = inode_setattr(inode, attrs); | |
2052 | + if (rc) | |
2053 | + goto cifs_setattr_exit; | |
2054 | + | |
2055 | + if ((attrs->ia_valid & ATTR_SIZE) && | |
2056 | + attrs->ia_size != i_size_read(inode)) { | |
2057 | + rc = vmtruncate(inode, attrs->ia_size); | |
2058 | + if (rc) | |
2059 | + goto cifs_setattr_exit; | |
2060 | + } | |
2061 | + | |
2062 | + setattr_copy(inode, attrs); | |
2063 | + mark_inode_dirty(inode); | |
2064 | + return 0; | |
2065 | + | |
2045 | 2066 | cifs_setattr_exit: |
2046 | 2067 | kfree(full_path); |
2047 | 2068 | FreeXid(xid); |
fs/exofs/inode.c
... | ... | @@ -887,8 +887,18 @@ |
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( |
fs/ext3/inode.c
... | ... | @@ -3208,9 +3208,17 @@ |
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: |
fs/ext4/inode.c
... | ... | @@ -5539,11 +5539,19 @@ |
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 |
fs/gfs2/inode.c
... | ... | @@ -991,18 +991,29 @@ |
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 | /** |
fs/gfs2/ops_inode.c
... | ... | @@ -1136,8 +1136,16 @@ |
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); |
fs/gfs2/xattr.c
... | ... | @@ -1296,6 +1296,7 @@ |
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; |
1302 | 1303 | |
... | ... | @@ -1321,14 +1322,25 @@ |
1321 | 1322 | return error; |
1322 | 1323 | |
1323 | 1324 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1324 | - if (!error) { | |
1325 | - error = inode_setattr(&ip->i_inode, attr); | |
1326 | - gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | |
1327 | - gfs2_trans_add_bh(ip->i_gl, dibh, 1); | |
1328 | - gfs2_dinode_out(ip, dibh->b_data); | |
1329 | - brelse(dibh); | |
1325 | + if (error) | |
1326 | + goto out_trans_end; | |
1327 | + | |
1328 | + if ((attr->ia_valid & ATTR_SIZE) && | |
1329 | + attr->ia_size != i_size_read(inode)) { | |
1330 | + int error; | |
1331 | + | |
1332 | + error = vmtruncate(inode, attr->ia_size); | |
1333 | + gfs2_assert_warn(GFS2_SB(inode), !error); | |
1330 | 1334 | } |
1331 | 1335 | |
1336 | + setattr_copy(inode, attr); | |
1337 | + mark_inode_dirty(inode); | |
1338 | + | |
1339 | + gfs2_trans_add_bh(ip->i_gl, dibh, 1); | |
1340 | + gfs2_dinode_out(ip, dibh->b_data); | |
1341 | + brelse(dibh); | |
1342 | + | |
1343 | +out_trans_end: | |
1332 | 1344 | gfs2_trans_end(sdp); |
1333 | 1345 | return error; |
1334 | 1346 | } |
fs/hfs/inode.c
... | ... | @@ -612,10 +612,16 @@ |
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 |
fs/hfsplus/inode.c
... | ... | @@ -298,7 +298,17 @@ |
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 = { |
fs/hostfs/hostfs_kern.c
... | ... | @@ -849,13 +849,14 @@ |
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 | |
... | ... | @@ -905,7 +906,18 @@ |
905 | 906 | if (err) |
906 | 907 | return err; |
907 | 908 | |
908 | - return inode_setattr(dentry->d_inode, attr); | |
909 | + if ((attr->ia_valid & ATTR_SIZE) && | |
910 | + attr->ia_size != i_size_read(inode)) { | |
911 | + int error; | |
912 | + | |
913 | + error = vmtruncate(inode, attr->ia_size); | |
914 | + if (err) | |
915 | + return err; | |
916 | + } | |
917 | + | |
918 | + setattr_copy(inode, attr); | |
919 | + mark_inode_dirty(inode); | |
920 | + return 0; | |
909 | 921 | } |
910 | 922 | |
911 | 923 | static const struct inode_operations hostfs_iops = { |
fs/hpfs/inode.c
... | ... | @@ -277,9 +277,15 @@ |
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 |
fs/hugetlbfs/inode.c
... | ... | @@ -448,19 +448,20 @@ |
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, |
fs/jfs/file.c
... | ... | @@ -17,6 +17,7 @@ |
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" |
23 | 24 | |
24 | 25 | |
... | ... | @@ -107,11 +108,18 @@ |
107 | 108 | return rc; |
108 | 109 | } |
109 | 110 | |
110 | - rc = inode_setattr(inode, iattr); | |
111 | + if ((iattr->ia_valid & ATTR_SIZE) && | |
112 | + iattr->ia_size != i_size_read(inode)) { | |
113 | + rc = vmtruncate(inode, iattr->ia_size); | |
114 | + if (rc) | |
115 | + return rc; | |
116 | + } | |
111 | 117 | |
112 | - if (!rc && (iattr->ia_valid & ATTR_MODE)) | |
113 | - rc = jfs_acl_chmod(inode); | |
118 | + setattr_copy(inode, iattr); | |
119 | + mark_inode_dirty(inode); | |
114 | 120 | |
121 | + if (iattr->ia_valid & ATTR_MODE) | |
122 | + rc = jfs_acl_chmod(inode); | |
115 | 123 | return rc; |
116 | 124 | } |
117 | 125 |
fs/logfs/file.c
... | ... | @@ -232,15 +232,19 @@ |
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 = { |
fs/minix/file.c
... | ... | @@ -31,7 +31,17 @@ |
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 = { |
fs/ncpfs/inode.c
... | ... | @@ -924,9 +924,8 @@ |
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 |
933 | 932 | |
... | ... | @@ -954,15 +953,12 @@ |
954 | 953 | result = ncp_make_closed(inode); |
955 | 954 | if (result) |
956 | 955 | goto out; |
957 | - { | |
958 | - struct iattr tmpattr; | |
959 | - | |
960 | - tmpattr.ia_valid = ATTR_SIZE; | |
961 | - tmpattr.ia_size = attr->ia_size; | |
962 | - | |
963 | - result = inode_setattr(inode, &tmpattr); | |
956 | + | |
957 | + if (attr->ia_size != i_size_read(inode)) { | |
958 | + result = vmtruncate(inode, attr->ia_size); | |
964 | 959 | if (result) |
965 | 960 | goto out; |
961 | + mark_inode_dirty(inode); | |
966 | 962 | } |
967 | 963 | } |
968 | 964 | if ((attr->ia_valid & ATTR_CTIME) != 0) { |
... | ... | @@ -1002,8 +998,12 @@ |
1002 | 998 | NCP_FINFO(inode)->nwattr = info.attributes; |
1003 | 999 | #endif |
1004 | 1000 | } |
1005 | - if (!result) | |
1006 | - result = inode_setattr(inode, attr); | |
1001 | + if (result) | |
1002 | + goto out; | |
1003 | + | |
1004 | + setattr_copy(inode, attr); | |
1005 | + mark_inode_dirty(inode); | |
1006 | + | |
1007 | 1007 | out: |
1008 | 1008 | unlock_kernel(); |
1009 | 1009 | return result; |
fs/nilfs2/inode.c
... | ... | @@ -656,14 +656,27 @@ |
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)) | |
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) { | |
661 | 671 | err = nilfs_acl_chmod(inode); |
662 | - if (likely(!err)) | |
663 | - err = nilfs_transaction_commit(sb); | |
664 | - else | |
665 | - nilfs_transaction_abort(sb); | |
672 | + if (unlikely(err)) | |
673 | + goto out_err; | |
674 | + } | |
666 | 675 | |
676 | + return nilfs_transaction_commit(sb); | |
677 | + | |
678 | +out_err: | |
679 | + nilfs_transaction_abort(sb); | |
667 | 680 | return err; |
668 | 681 | } |
669 | 682 |
fs/ntfs/inode.c
... | ... | @@ -2879,9 +2879,6 @@ |
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 | { |
fs/ocfs2/dlmfs/dlmfs.c
... | ... | @@ -214,10 +214,12 @@ |
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) |
fs/ocfs2/file.c
... | ... | @@ -1238,12 +1238,20 @@ |
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) |
fs/omfs/file.c
... | ... | @@ -349,7 +349,17 @@ |
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 = { |
fs/proc/base.c
... | ... | @@ -561,9 +561,19 @@ |
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 = { |
fs/proc/generic.c
... | ... | @@ -12,6 +12,7 @@ |
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> |
18 | 19 | |
19 | 20 | |
... | ... | @@ -258,17 +259,22 @@ |
258 | 259 | |
259 | 260 | error = inode_change_ok(inode, iattr); |
260 | 261 | if (error) |
261 | - goto out; | |
262 | + return error; | |
262 | 263 | |
263 | - error = inode_setattr(inode, iattr); | |
264 | - if (error) | |
265 | - goto out; | |
264 | + if ((iattr->ia_valid & ATTR_SIZE) && | |
265 | + iattr->ia_size != i_size_read(inode)) { | |
266 | + error = vmtruncate(inode, iattr->ia_size); | |
267 | + if (error) | |
268 | + return error; | |
269 | + } | |
270 | + | |
271 | + setattr_copy(inode, iattr); | |
272 | + mark_inode_dirty(inode); | |
266 | 273 | |
267 | 274 | de->uid = inode->i_uid; |
268 | 275 | de->gid = inode->i_gid; |
269 | 276 | de->mode = inode->i_mode; |
270 | -out: | |
271 | - return error; | |
277 | + return 0; | |
272 | 278 | } |
273 | 279 | |
274 | 280 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, |
fs/proc/proc_sysctl.c
... | ... | @@ -329,10 +329,19 @@ |
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) |
fs/reiserfs/inode.c
... | ... | @@ -3134,54 +3134,61 @@ |
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) |
fs/sysv/file.c
... | ... | @@ -38,7 +38,17 @@ |
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 = { |
fs/udf/file.c
... | ... | @@ -236,7 +236,17 @@ |
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 = { |
fs/ufs/truncate.c
include/linux/fs.h
... | ... | @@ -2392,7 +2392,6 @@ |
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); |