From: Erez Zadok Date: Sat, 30 Apr 2011 05:31:29 +0000 (-0400) Subject: Unionfs: ->setattr fixes X-Git-Url: https://git.fsl.cs.sunysb.edu/?a=commitdiff_plain;h=dec7af1d74824d45d4e2c1b34958437accc347d7;p=unionfs-2.6.39.y.git Unionfs: ->setattr fixes Call inode_check_ok first thing on our inode. Pass lower_file in struct iattr to lower file system. Signed-off-by: Erez Zadok --- diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c index 4c36f16b4d2..cc994bdb348 100644 --- a/fs/unionfs/inode.c +++ b/fs/unionfs/inode.c @@ -901,6 +901,12 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia) struct inode *lower_inode; int bstart, bend, bindex; loff_t size; + struct iattr lower_ia; + + /* check if user has permission to change inode */ + err = inode_change_ok(dentry->d_inode, ia); + if (err) + goto out_err; unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); @@ -988,8 +994,15 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia) * unlinked (no inode->i_sb and i_ino==0. This happens if someone * tries to open(), unlink(), then ftruncate() a file. */ + /* prepare our own lower struct iattr (with our own lower file) */ + memcpy(&lower_ia, ia, sizeof(lower_ia)); + if (ia->ia_valid & ATTR_FILE) { + lower_ia.ia_file = unionfs_lower_file(ia->ia_file); + BUG_ON(!lower_ia.ia_file); // XXX? + } + mutex_lock(&lower_dentry->d_inode->i_mutex); - err = notify_change(lower_dentry, ia); + err = notify_change(lower_dentry, &lower_ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); if (err) goto out; @@ -1017,7 +1030,7 @@ out: unionfs_unlock_dentry(dentry); unionfs_unlock_parent(dentry, parent); unionfs_read_unlock(dentry->d_sb); - +out_err: return err; }