From: Miklos Szeredi Pass the open file into the filesystem's ->setattr() method for fchmod, fchown and some of the utimes variants. This is needed to be able to correctly implement open-unlink-fsetattr semantics in some filesystem such as sshfs, without having to resort to "silly-renaming". The infrastructure is already there, so just need to fill in attrs.ia_file and set ATTR_FILE in attrs.ia_valid. Signed-off-by: Miklos Szeredi --- Index: linux/fs/open.c =================================================================== --- linux.orig/fs/open.c 2007-09-21 13:44:57.000000000 +0200 +++ linux/fs/open.c 2007-09-21 13:45:04.000000000 +0200 @@ -581,7 +581,8 @@ asmlinkage long sys_fchmod(unsigned int if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE; + newattrs.ia_file = file; err = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); @@ -631,7 +632,8 @@ asmlinkage long sys_chmod(const char __u return sys_fchmodat(AT_FDCWD, filename, mode); } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, + struct file *file) { struct inode * inode; int error; @@ -660,6 +662,10 @@ static int chown_common(struct dentry * if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; + if (file) { + newattrs.ia_file = file; + newattrs.ia_valid |= ATTR_FILE; + } mutex_lock(&inode->i_mutex); error = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); @@ -675,7 +681,7 @@ asmlinkage long sys_chown(const char __u error = user_path_walk(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, user, group, NULL); path_release(&nd); out: return error; @@ -695,7 +701,7 @@ asmlinkage long sys_fchownat(int dfd, co error = __user_walk_fd(dfd, filename, follow, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, user, group, NULL); path_release(&nd); out: return error; @@ -709,7 +715,7 @@ asmlinkage long sys_lchown(const char __ error = user_path_walk_link(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, user, group, NULL); path_release(&nd); out: return error; @@ -728,7 +734,7 @@ asmlinkage long sys_fchown(unsigned int dentry = file->f_path.dentry; audit_inode(NULL, dentry); - error = chown_common(dentry, user, group); + error = chown_common(dentry, user, group, file); fput(file); out: return error; Index: linux/fs/utimes.c =================================================================== --- linux.orig/fs/utimes.c 2007-09-21 13:44:57.000000000 +0200 +++ linux/fs/utimes.c 2007-09-21 13:45:04.000000000 +0200 @@ -130,6 +130,10 @@ long do_utimes(int dfd, char __user *fil } } } + if (f) { + newattrs.ia_file = f; + newattrs.ia_valid |= ATTR_FILE; + } mutex_lock(&inode->i_mutex); error = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/