Skip to content

Commit

Permalink
remove inode_setattr
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Aug 9, 2010
1 parent eef2380 commit 1025774
Show file tree
Hide file tree
Showing 35 changed files with 416 additions and 194 deletions.
4 changes: 3 additions & 1 deletion arch/powerpc/platforms/cell/spufs/inode.c
Expand Up @@ -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;
}


Expand Down
14 changes: 10 additions & 4 deletions drivers/staging/pohmelfs/inode.c
Expand Up @@ -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);
Expand Down
15 changes: 12 additions & 3 deletions fs/9p/vfs_inode.c
Expand Up @@ -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;
}

/**
Expand Down
13 changes: 11 additions & 2 deletions fs/affs/inode.c
Expand Up @@ -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;
Expand Down
25 changes: 0 additions & 25 deletions fs/attr.c
Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions fs/btrfs/inode.c
Expand Up @@ -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;
}

Expand Down
45 changes: 33 additions & 12 deletions fs/cifs/inode.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 12 additions & 2 deletions fs/exofs/inode.c
Expand Up @@ -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(
Expand Down
12 changes: 10 additions & 2 deletions fs/ext3/inode.c
Expand Up @@ -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:
Expand Down
16 changes: 12 additions & 4 deletions fs/ext4/inode.c
Expand Up @@ -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);

Expand Down
25 changes: 18 additions & 7 deletions fs/gfs2/inode.c
Expand Up @@ -991,18 +991,29 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,

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;
}

/**
Expand Down
12 changes: 10 additions & 2 deletions fs/gfs2/ops_inode.c
Expand Up @@ -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);
Expand Down
24 changes: 18 additions & 6 deletions fs/gfs2/xattr.c
Expand Up @@ -1296,6 +1296,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,

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;
Expand All @@ -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;
}
Expand Down
12 changes: 9 additions & 3 deletions fs/hfs/inode.c
Expand Up @@ -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;
}

Expand Down
12 changes: 11 additions & 1 deletion fs/hfsplus/inode.c
Expand Up @@ -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 = {
Expand Down

0 comments on commit 1025774

Please sign in to comment.