]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
remove inode_setattr
authorChristoph Hellwig <hch@lst.de>
Fri, 4 Jun 2010 09:30:02 +0000 (11:30 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 9 Aug 2010 20:47:37 +0000 (16:47 -0400)
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>
35 files changed:
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

index e5e5f823d6870fece5c4a4ba3c918597ca3f9c0b..32625f366fb5bbd8befd32e25db1b0f35a0654fb 100644 (file)
@@ -110,7 +110,9 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
        if ((attr->ia_valid & ATTR_SIZE) &&
            (attr->ia_size != inode->i_size))
                return -EINVAL;
-       return inode_setattr(inode, attr);
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 
index 643b413d9f0f395fca978a56641cbe582beee773..e818f53ccfd773164086c0c029f3de5d84d14cfe 100644 (file)
@@ -968,12 +968,18 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
                goto err_out_exit;
        }
 
-       err = inode_setattr(inode, attr);
-       if (err) {
-               dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
-               goto err_out_exit;
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               err = vmtruncate(inode, attr->ia_size);
+               if (err) {
+                       dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
+                       goto err_out_exit;
+               }
        }
 
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
        dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
                        __func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
                        inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
index 4331b3b5ee1c978a8a7b4b719ed6da14ede32cff..4b3ad6ac9a41d4a2c28ff0d0e9a7fb7c2f363867 100644 (file)
@@ -896,10 +896,19 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
        }
 
        retval = p9_client_wstat(fid, &wstat);
-       if (retval >= 0)
-               retval = inode_setattr(dentry->d_inode, iattr);
+       if (retval < 0)
+               return retval;
+
+       if ((iattr->ia_valid & ATTR_SIZE) &&
+           iattr->ia_size != i_size_read(dentry->d_inode)) {
+               retval = vmtruncate(dentry->d_inode, iattr->ia_size);
+               if (retval)
+                       return retval;
+       }
 
-       return retval;
+       setattr_copy(dentry->d_inode, iattr);
+       mark_inode_dirty(dentry->d_inode);
+       return 0;
 }
 
 /**
index f4b2a4ee4f911bde737b152c0e4434322bb0a82f..6883d5fb84cfcc31f01e41b79f8bf84f7b31f43c 100644 (file)
@@ -235,8 +235,17 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
                goto out;
        }
 
-       error = inode_setattr(inode, attr);
-       if (!error && (attr->ia_valid & ATTR_MODE))
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
+       if (attr->ia_valid & ATTR_MODE)
                mode_to_prot(inode);
 out:
        return error;
index aeac826f4774c185b5e60e0c1d1b4e516755b2ff..ed44d8ae8bf1ac7d95da36d908a157af6cc3bf44 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -146,31 +146,6 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
 }
 EXPORT_SYMBOL(setattr_copy);
 
-/*
- * note this function is deprecated, the new truncate sequence should be
- * used instead -- see eg. simple_setsize, setattr_copy.
- */
-int inode_setattr(struct inode *inode, const struct iattr *attr)
-{
-       unsigned int ia_valid = attr->ia_valid;
-
-       if (ia_valid & ATTR_SIZE &&
-           attr->ia_size != i_size_read(inode)) {
-               int error;
-
-               error = vmtruncate(inode, attr->ia_size);
-               if (error)
-                       return error;
-       }
-
-       setattr_copy(inode, attr);
-
-       mark_inode_dirty(inode);
-
-       return 0;
-}
-EXPORT_SYMBOL(inode_setattr);
-
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
        struct inode *inode = dentry->d_inode;
index 1bff92ad474434a535b711abebb14d7a692cabca..7f9e0536db1ac6e0def03fa0a4d18ca7645bac70 100644 (file)
@@ -3656,13 +3656,15 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
                if (err)
                        return err;
        }
-       attr->ia_valid &= ~ATTR_SIZE;
 
-       if (attr->ia_valid)
-               err = inode_setattr(inode, attr);
+       if (attr->ia_valid) {
+               setattr_copy(inode, attr);
+               mark_inode_dirty(inode);
+
+               if (attr->ia_valid & ATTR_MODE)
+                       err = btrfs_acl_chmod(inode);
+       }
 
-       if (!err && ((attr->ia_valid & ATTR_MODE)))
-               err = btrfs_acl_chmod(inode);
        return err;
 }
 
index a15b3a9bbff40af95532b152a5bbf993a44bac99..9c6a40f5cc577cf67d4407020ec2b91d47edcd47 100644 (file)
@@ -1889,18 +1889,27 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
 
-       if (!rc) {
-               rc = inode_setattr(inode, attrs);
+       if (rc)
+               goto out;
 
-               /* force revalidate when any of these times are set since some
-                  of the fs types (eg ext3, fat) do not have fine enough
-                  time granularity to match protocol, and we do not have a
-                  a way (yet) to query the server fs's time granularity (and
-                  whether it rounds times down).
-               */
-               if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
-                       cifsInode->time = 0;
+       if ((attrs->ia_valid & ATTR_SIZE) &&
+           attrs->ia_size != i_size_read(inode)) {
+               rc = vmtruncate(inode, attrs->ia_size);
+               if (rc)
+                       goto out;
        }
+
+       setattr_copy(inode, attrs);
+       mark_inode_dirty(inode);
+
+       /* force revalidate when any of these times are set since some
+          of the fs types (eg ext3, fat) do not have fine enough
+          time granularity to match protocol, and we do not have a
+          a way (yet) to query the server fs's time granularity (and
+          whether it rounds times down).
+       */
+       if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
+               cifsInode->time = 0;
 out:
        kfree(args);
        kfree(full_path);
@@ -2040,8 +2049,20 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        /* do not need local check to inode_check_ok since the server does
           that */
-       if (!rc)
-               rc = inode_setattr(inode, attrs);
+       if (rc)
+               goto cifs_setattr_exit;
+
+       if ((attrs->ia_valid & ATTR_SIZE) &&
+           attrs->ia_size != i_size_read(inode)) {
+               rc = vmtruncate(inode, attrs->ia_size);
+               if (rc)
+                       goto cifs_setattr_exit;
+       }
+
+       setattr_copy(inode, attrs);
+       mark_inode_dirty(inode);
+       return 0;
+
 cifs_setattr_exit:
        kfree(full_path);
        FreeXid(xid);
index 4bb6ef822e46d8daba3b312afbb4258aab7ea1ee..4bfc1f4fd013aac24683bad410de98ef8c1d26f4 100644 (file)
@@ -887,8 +887,18 @@ int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
        if (error)
                return error;
 
-       error = inode_setattr(inode, iattr);
-       return error;
+       if ((iattr->ia_valid & ATTR_SIZE) &&
+           iattr->ia_size != i_size_read(inode)) {
+               int error;
+
+               error = vmtruncate(inode, iattr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, iattr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
index 5c6f07eefa4a04ba1ff8aa98dcd488bfd253f1db..b04d119366838ef147747426649348c10ddfb4ae 100644 (file)
@@ -3208,9 +3208,17 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
                ext3_journal_stop(handle);
        }
 
-       rc = inode_setattr(inode, attr);
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               rc = vmtruncate(inode, attr->ia_size);
+               if (rc)
+                       goto err_out;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
 
-       if (!rc && (ia_valid & ATTR_MODE))
+       if (ia_valid & ATTR_MODE)
                rc = ext3_acl_chmod(inode);
 
 err_out:
index 3da3c9646e5e10a2bab91fb2e21e3ca5703f51c2..1fb390359bc5f7808242adfa645f03c46efc8968 100644 (file)
@@ -5539,11 +5539,19 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        ext4_truncate(inode);
        }
 
-       rc = inode_setattr(inode, attr);
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode))
+               rc = vmtruncate(inode, attr->ia_size);
 
-       /* If inode_setattr's call to ext4_truncate failed to get a
-        * transaction handle at all, we need to clean up the in-core
-        * orphan list manually. */
+       if (!rc) {
+               setattr_copy(inode, attr);
+               mark_inode_dirty(inode);
+       }
+
+       /*
+        * If the call to ext4_truncate failed to get a transaction handle at
+        * all, we need to clean up the in-core orphan list manually.
+        */
        if (inode->i_nlink)
                ext4_orphan_del(NULL, inode);
 
index f03afd9c44bc748b51811bff46ccdab3d66fa619..6c023a3b5d25711b90b91b8f3a120a5f582c38cc 100644 (file)
@@ -991,18 +991,29 @@ fail:
 
 static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
 {
+       struct inode *inode = &ip->i_inode;
        struct buffer_head *dibh;
        int error;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
-       if (!error) {
-               error = inode_setattr(&ip->i_inode, attr);
-               gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
-               gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-               gfs2_dinode_out(ip, dibh->b_data);
-               brelse(dibh);
+       if (error)
+               return error;
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
        }
-       return error;
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
+       gfs2_assert_warn(GFS2_SB(inode), !error);
+       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+       gfs2_dinode_out(ip, dibh->b_data);
+       brelse(dibh);
+       return 0;
 }
 
 /**
index 98cdd05f3316f17b98a82bf11d95805168445aee..d7d410a4ca421a8586d2b35c5113f2441dcd8b70 100644 (file)
@@ -1136,8 +1136,16 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
        if (error)
                goto out_end_trans;
 
-       error = inode_setattr(inode, attr);
-       gfs2_assert_warn(sdp, !error);
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               int error;
+
+               error = vmtruncate(inode, attr->ia_size);
+               gfs2_assert_warn(sdp, !error);
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
index 82f93da00d1b4e2373bea8b36f691dc39ae0a8d2..776af6eb4bcb1b193ecf5ef858ac09cb0535b95f 100644 (file)
@@ -1296,6 +1296,7 @@ fail:
 
 int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
 {
+       struct inode *inode = &ip->i_inode;
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_ea_location el;
        struct buffer_head *dibh;
@@ -1321,14 +1322,25 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
                return error;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
-       if (!error) {
-               error = inode_setattr(&ip->i_inode, attr);
-               gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
-               gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-               gfs2_dinode_out(ip, dibh->b_data);
-               brelse(dibh);
+       if (error)
+               goto out_trans_end;
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               int error;
+
+               error = vmtruncate(inode, attr->ia_size);
+               gfs2_assert_warn(GFS2_SB(inode), !error);
        }
 
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
+       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+       gfs2_dinode_out(ip, dibh->b_data);
+       brelse(dibh);
+
+out_trans_end:
        gfs2_trans_end(sdp);
        return error;
 }
index 8df18e63eb6b1eb2b08b905a8ba055133befd125..87de671baa8326a38bc9d3f686a2b5d8fe146200 100644 (file)
@@ -612,10 +612,16 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
                        attr->ia_mode = inode->i_mode & ~S_IWUGO;
                attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask;
        }
-       error = inode_setattr(inode, attr);
-       if (error)
-               return error;
 
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
        return 0;
 }
 
index d6ebe53fbdbf63eb2430abf032fbe8d4d3eb4b6c..654c5a8ddf1cf90c83eab97041e5bf9c881346ec 100644 (file)
@@ -298,7 +298,17 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (error)
                return error;
-       return inode_setattr(inode, attr);
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static const struct inode_operations hfsplus_file_inode_operations = {
index 87ac1891a18584a05d56b88572a66b440c7b4766..7943ff11d4899350d416a0b7b3359676a57defed 100644 (file)
@@ -849,13 +849,14 @@ int hostfs_permission(struct inode *ino, int desired)
 
 int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
+       struct inode *inode = dentry->d_inode;
        struct hostfs_iattr attrs;
        char *name;
        int err;
 
-       int fd = HOSTFS_I(dentry->d_inode)->fd;
+       int fd = HOSTFS_I(inode)->fd;
 
-       err = inode_change_ok(dentry->d_inode, attr);
+       err = inode_change_ok(inode, attr);
        if (err)
                return err;
 
@@ -905,7 +906,18 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
        if (err)
                return err;
 
-       return inode_setattr(dentry->d_inode, attr);
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               int error;
+
+               error = vmtruncate(inode, attr->ia_size);
+               if (err)
+                       return err;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static const struct inode_operations hostfs_iops = {
index 1042a9bc97f3710c0930c80333afd303ae10a8d5..3f3b397fd4e6c5f132045379a7d2f191641c85ea 100644 (file)
@@ -277,9 +277,15 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
        if (error)
                goto out_unlock;
 
-       error = inode_setattr(inode, attr);
-       if (error)
-               goto out_unlock;
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
 
        hpfs_write_inode(inode);
 
index a4e9a7ec3691a4066deb8948da3aacd12606b896..d5f019d48b09e7ed91a159f1d94f7a29db16067a 100644 (file)
@@ -448,19 +448,20 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        error = inode_change_ok(inode, attr);
        if (error)
-               goto out;
+               return error;
 
        if (ia_valid & ATTR_SIZE) {
                error = -EINVAL;
-               if (!(attr->ia_size & ~huge_page_mask(h)))
-                       error = hugetlb_vmtruncate(inode, attr->ia_size);
+               if (attr->ia_size & ~huge_page_mask(h))
+                       return -EINVAL;
+               error = hugetlb_vmtruncate(inode, attr->ia_size);
                if (error)
-                       goto out;
-               attr->ia_valid &= ~ATTR_SIZE;
+                       return error;
        }
-       error = inode_setattr(inode, attr);
-out:
-       return error;
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, 
index 127263cc865715de2d3f42f6658320ac89a5106e..c5ce6c1d1ff406c567d0b59d0ffe03ed11b8daa5 100644 (file)
@@ -17,6 +17,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+#include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/quotaops.h>
 #include "jfs_incore.h"
@@ -107,11 +108,18 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
                        return rc;
        }
 
-       rc = inode_setattr(inode, iattr);
+       if ((iattr->ia_valid & ATTR_SIZE) &&
+           iattr->ia_size != i_size_read(inode)) {
+               rc = vmtruncate(inode, iattr->ia_size);
+               if (rc)
+                       return rc;
+       }
 
-       if (!rc && (iattr->ia_valid & ATTR_MODE))
-               rc = jfs_acl_chmod(inode);
+       setattr_copy(inode, iattr);
+       mark_inode_dirty(inode);
 
+       if (iattr->ia_valid & ATTR_MODE)
+               rc = jfs_acl_chmod(inode);
        return rc;
 }
 
index abe1cafbd4c263f4191217a591d3d5f4f258a841..23b4d03bbd26b38a084e309085ad639e923d2d68 100644 (file)
@@ -232,15 +232,19 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int err = 0;
 
-       if (attr->ia_valid & ATTR_SIZE)
+       if (attr->ia_valid & ATTR_SIZE) {
                err = logfs_truncate(inode, attr->ia_size);
-       attr->ia_valid &= ~ATTR_SIZE;
+               if (err)
+                       return err;
+       }
 
-       if (!err)
-               err = inode_change_ok(inode, attr);
-       if (!err)
-               err = inode_setattr(inode, attr);
-       return err;
+       err = inode_change_ok(inode, attr);
+       if (err)
+               return err;
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations logfs_reg_iops = {
index 7a45dd1fe2e54b3fc1ae78be29954c2faae4e334..4493ce695ab83af7986eefdc72f683f65537c3a9 100644 (file)
@@ -31,7 +31,17 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (error)
                return error;
-       return inode_setattr(inode, attr);
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations minix_file_inode_operations = {
index fa3385154023484659003aeb98b6f421c5eb3b4a..b4e8aaae14be5d8425132d92c50798b63d8adf4f 100644 (file)
@@ -924,9 +924,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                                tmpattr.ia_valid = ATTR_MODE;
                                tmpattr.ia_mode = attr->ia_mode;
 
-                               result = inode_setattr(inode, &tmpattr);
-                               if (result)
-                                       goto out;
+                               setattr_copy(inode, &tmpattr);
+                               mark_inode_dirty(inode);
                        }
                }
 #endif
@@ -954,15 +953,12 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                result = ncp_make_closed(inode);
                if (result)
                        goto out;
-               {
-                       struct iattr tmpattr;
-                       
-                       tmpattr.ia_valid = ATTR_SIZE;
-                       tmpattr.ia_size = attr->ia_size;
-                       
-                       result = inode_setattr(inode, &tmpattr);
+
+               if (attr->ia_size != i_size_read(inode)) {
+                       result = vmtruncate(inode, attr->ia_size);
                        if (result)
                                goto out;
+                       mark_inode_dirty(inode);
                }
        }
        if ((attr->ia_valid & ATTR_CTIME) != 0) {
@@ -1002,8 +998,12 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                        NCP_FINFO(inode)->nwattr = info.attributes;
 #endif
        }
-       if (!result)
-               result = inode_setattr(inode, attr);
+       if (result)
+               goto out;
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
 out:
        unlock_kernel();
        return result;
index 5c694ece172efca68c72eebd4bfe29e9e3549864..051d279abb379f3d603dba0bef4c851c3906e340 100644 (file)
@@ -656,14 +656,27 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
        err = nilfs_transaction_begin(sb, &ti, 0);
        if (unlikely(err))
                return err;
-       err = inode_setattr(inode, iattr);
-       if (!err && (iattr->ia_valid & ATTR_MODE))
+
+       if ((iattr->ia_valid & ATTR_SIZE) &&
+           iattr->ia_size != i_size_read(inode)) {
+               err = vmtruncate(inode, iattr->ia_size);
+               if (unlikely(err))
+                       goto out_err;
+       }
+
+       setattr_copy(inode, iattr);
+       mark_inode_dirty(inode);
+
+       if (iattr->ia_valid & ATTR_MODE) {
                err = nilfs_acl_chmod(inode);
-       if (likely(!err))
-               err = nilfs_transaction_commit(sb);
-       else
-               nilfs_transaction_abort(sb);
+               if (unlikely(err))
+                       goto out_err;
+       }
+
+       return nilfs_transaction_commit(sb);
 
+out_err:
+       nilfs_transaction_abort(sb);
        return err;
 }
 
index 4b57fb1eac2abe5a1e90d462c9febc8b1d6169d0..fdef8f729c3ada2b0ee514986820d84ddd6ffab6 100644 (file)
@@ -2879,9 +2879,6 @@ void ntfs_truncate_vfs(struct inode *vi) {
  *
  * Called with ->i_mutex held.  For the ATTR_SIZE (i.e. ->truncate) case, also
  * called with ->i_alloc_sem held for writing.
- *
- * Basically this is a copy of generic notify_change() and inode_setattr()
- * functionality, except we intercept and abort changes in i_size.
  */
 int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
index b83d6107a1f5e0eb9e63c4dae29746c3b3888fce..85e4ccaedd1f3615dd44f650238cc8a9603d342a 100644 (file)
@@ -214,10 +214,12 @@ static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr)
 
        attr->ia_valid &= ~ATTR_SIZE;
        error = inode_change_ok(inode, attr);
-       if (!error)
-               error = inode_setattr(inode, attr);
+       if (error)
+               return error;
 
-       return error;
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static unsigned int dlmfs_file_poll(struct file *file, poll_table *wait)
index 2b10b36d15772efcae056a62b4df1a9fe8aa2c53..584cf8ac167aabaac71d9a77cc9a622846bfe9e5 100644 (file)
@@ -1238,13 +1238,21 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
         * Otherwise, we could get into problems with truncate as
         * ip_alloc_sem is used there to protect against i_size
         * changes.
+        *
+        * XXX: this means the conditional below can probably be removed.
         */
-       status = inode_setattr(inode, attr);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail_commit;
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               status = vmtruncate(inode, attr->ia_size);
+               if (status) {
+                       mlog_errno(status);
+                       goto bail_commit;
+               }
        }
 
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+
        status = ocfs2_mark_inode_dirty(handle, inode, bh);
        if (status < 0)
                mlog_errno(status);
index 78c9f0c1a2f3d6c9e2b01fe3839f3f40d12b0b09..5542c284dc1cd528d53a1f4e18db84ac6c592767 100644 (file)
@@ -349,7 +349,17 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (error)
                return error;
-       return inode_setattr(inode, attr);
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations omfs_file_inops = {
index acb7ef80ea4fcc4987b0b2159f70d599f659c31e..a49d9dd06d1d7e9de38b6bed2a40e3dd0a572706 100644 (file)
@@ -561,9 +561,19 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr)
                return -EPERM;
 
        error = inode_change_ok(inode, attr);
-       if (!error)
-               error = inode_setattr(inode, attr);
-       return error;
+       if (error)
+               return error;
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static const struct inode_operations proc_def_inode_operations = {
index 2791907744edffdc25719cebe93f15b0d0e23242..dd29f033766101acfcee512850db17c8e086c7ed 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/mount.h>
@@ -258,17 +259,22 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
 
        error = inode_change_ok(inode, iattr);
        if (error)
-               goto out;
+               return error;
 
-       error = inode_setattr(inode, iattr);
-       if (error)
-               goto out;
+       if ((iattr->ia_valid & ATTR_SIZE) &&
+           iattr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, iattr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, iattr);
+       mark_inode_dirty(inode);
        
        de->uid = inode->i_uid;
        de->gid = inode->i_gid;
        de->mode = inode->i_mode;
-out:
-       return error;
+       return 0;
 }
 
 static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
index 6ff9981f0a1887d497cf0b53768f539ceceb23fe..5be436ea088eeea37ab8a440e64a32f0b879fb7c 100644 (file)
@@ -329,10 +329,19 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
                return -EPERM;
 
        error = inode_change_ok(inode, attr);
-       if (!error)
-               error = inode_setattr(inode, attr);
+       if (error)
+               return error;
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
 
-       return error;
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
index 045729f5674ace47f01585ae1b3f2a301da69d10..2b8dc5c22867bdd42f48027de69221a3a84e8626 100644 (file)
@@ -3134,55 +3134,62 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        error = inode_change_ok(inode, attr);
-       if (!error) {
-               if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-                   (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
-                       error = reiserfs_chown_xattrs(inode, attr);
+       if (error)
+               goto out;
 
-                       if (!error) {
-                               struct reiserfs_transaction_handle th;
-                               int jbegin_count =
-                                   2 *
-                                   (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
-                                    REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
-                                   2;
-
-                               /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
-                               error =
-                                   journal_begin(&th, inode->i_sb,
-                                                 jbegin_count);
-                               if (error)
-                                       goto out;
-                               error = dquot_transfer(inode, attr);
-                               if (error) {
-                                       journal_end(&th, inode->i_sb,
-                                                   jbegin_count);
-                                       goto out;
-                               }
-                               /* Update corresponding info in inode so that everything is in
-                                * one transaction */
-                               if (attr->ia_valid & ATTR_UID)
-                                       inode->i_uid = attr->ia_uid;
-                               if (attr->ia_valid & ATTR_GID)
-                                       inode->i_gid = attr->ia_gid;
-                               mark_inode_dirty(inode);
-                               error =
-                                   journal_end(&th, inode->i_sb, jbegin_count);
-                       }
-               }
-               if (!error) {
-                       /*
-                        * Relax the lock here, as it might truncate the
-                        * inode pages and wait for inode pages locks.
-                        * To release such page lock, the owner needs the
-                        * reiserfs lock
-                        */
-                       reiserfs_write_unlock_once(inode->i_sb, depth);
-                       error = inode_setattr(inode, attr);
-                       depth = reiserfs_write_lock_once(inode->i_sb);
+       if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+               struct reiserfs_transaction_handle th;
+               int jbegin_count =
+                   2 *
+                   (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
+                    REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
+                   2;
+
+               error = reiserfs_chown_xattrs(inode, attr);
+
+               if (error)
+                       return error;
+
+               /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
+               error = journal_begin(&th, inode->i_sb, jbegin_count);
+               if (error)
+                       goto out;
+               error = dquot_transfer(inode, attr);
+               if (error) {
+                       journal_end(&th, inode->i_sb, jbegin_count);
+                       goto out;
                }
+
+               /* Update corresponding info in inode so that everything is in
+                * one transaction */
+               if (attr->ia_valid & ATTR_UID)
+                       inode->i_uid = attr->ia_uid;
+               if (attr->ia_valid & ATTR_GID)
+                       inode->i_gid = attr->ia_gid;
+               mark_inode_dirty(inode);
+               error = journal_end(&th, inode->i_sb, jbegin_count);
+               if (error)
+                       goto out;
        }
 
+       /*
+        * Relax the lock here, as it might truncate the
+        * inode pages and wait for inode pages locks.
+        * To release such page lock, the owner needs the
+        * reiserfs lock
+        */
+       reiserfs_write_unlock_once(inode->i_sb, depth);
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode))
+               error = vmtruncate(inode, attr->ia_size);
+
+       if (!error) {
+               setattr_copy(inode, attr);
+               mark_inode_dirty(inode);
+       }
+       depth = reiserfs_write_lock_once(inode->i_sb);
+
        if (!error && reiserfs_posixacl(inode->i_sb)) {
                if (attr->ia_valid & ATTR_MODE)
                        error = reiserfs_acl_chmod(inode);
index 94f6319292a10d71fc6ac14c3307226d83550e9f..0a65939508e964f609b6e5ab7432cc2e177a45ad 100644 (file)
@@ -38,7 +38,17 @@ static int sysv_setattr(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (error)
                return error;
-       return inode_setattr(inode, attr);
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations sysv_file_inode_operations = {
index 7376032c89ce09e078b5e12bba36bf6e19591134..04bb5bf076308a055cb25f0f6c941b70f07ed47b 100644 (file)
@@ -236,7 +236,17 @@ static int udf_setattr(struct dentry *dentry, struct iattr *attr)
        error = inode_change_ok(inode, attr);
        if (error)
                return error;
-       return inode_setattr(inode, attr);
+
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size != i_size_read(inode)) {
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations udf_file_inode_operations = {
index 589e01a465bad16f8708b74de4b0fad11e24676d..085e11623b7b9ba3ef2e63143c64d654e39d7be4 100644 (file)
@@ -525,7 +525,10 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
                if (error)
                        return error;
        }
-       return inode_setattr(inode, attr);
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 const struct inode_operations ufs_file_inode_operations = {
index 8ebb5f01a4181144bd23d66e65b1537137ce33b4..6ecb83c00a6db2c51a8f98661dbf1f601e9868c5 100644 (file)
@@ -2392,7 +2392,6 @@ extern int buffer_migrate_page(struct address_space *,
 
 extern int inode_change_ok(const struct inode *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
-extern int __must_check inode_setattr(struct inode *, const struct iattr *);
 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
 
 extern void file_update_time(struct file *file);