From 65549603b30d10136b411949e568522cf70f258f Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Sun, 6 Mar 2011 15:59:19 -0500 Subject: [PATCH] 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 --- fs/unionfs/inode.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c index 062163a9e96..9b3d226b8d4 100644 --- a/fs/unionfs/inode.c +++ b/fs/unionfs/inode.c @@ -895,6 +895,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); @@ -982,8 +988,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; @@ -1011,7 +1024,7 @@ out: unionfs_unlock_dentry(dentry); unionfs_unlock_parent(dentry, parent); unionfs_read_unlock(dentry->d_sb); - +out_err: return err; } -- 2.34.1