Commit 1025774ce411f2bd4b059ad7b53f0003569b74fa

Authored by Christoph Hellwig
Committed by Al Viro
1 parent eef2380c18

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
... ... @@ -110,7 +110,9 @@
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  
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,
... ... @@ -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 /**
... ... @@ -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;
... ... @@ -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;
... ... @@ -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  
... ... @@ -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);
... ... @@ -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(
... ... @@ -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:
... ... @@ -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  
... ... @@ -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 /**
... ... @@ -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);
... ... @@ -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 }
... ... @@ -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  
... ... @@ -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 = {
... ... @@ -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,
... ... @@ -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  
... ... @@ -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 = {
... ... @@ -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 = {
... ... @@ -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;
... ... @@ -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  
... ... @@ -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)
... ... @@ -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)
... ... @@ -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 = {
... ... @@ -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 = {
... ... @@ -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)
... ... @@ -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)
... ... @@ -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 = {
... ... @@ -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 = {
... ... @@ -525,7 +525,10 @@
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 = {
... ... @@ -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);