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;
 }
 
 
 
                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);
 
        }
 
        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;
 }
 
 /**
 
                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;
 
 }
 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;
 
                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;
 }
 
 
                                        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);
 
        /* 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);
 
        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(
 
                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:
 
                        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);
 
 
 
 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;
 }
 
 /**
 
        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);
 
 
 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;
                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;
 }
 
                        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;
 }
 
 
        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 = {
 
 
 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;
 
        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 = {
 
        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);
 
 
 
        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, 
 
  *   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"
                        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;
 }
 
 
        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 = {
 
        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 = {
 
                                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
                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) {
                        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;
 
        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;
 }
 
 
  *
  * 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)
 {
 
 
        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)
 
         * 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);
 
        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 = {
 
                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 = {
 
 #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>
 
        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,
 
                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)
 
        }
 
        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);
 
        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 = {
 
        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 = {
 
                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 = {
 
 
 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);