From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f65.google.com ([74.125.82.65]:36279 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754442AbcKBWyG (ORCPT ); Wed, 2 Nov 2016 18:54:06 -0400 Received: by mail-wm0-f65.google.com with SMTP id c17so5189343wmc.3 for ; Wed, 02 Nov 2016 15:54:05 -0700 (PDT) From: Jose Lopes To: Alexander Viro Cc: Jose Lopes , linux-fsdevel@vger.kernel.org, fuse-devel@lists.sourceforge.net Subject: [PATCH] Make file struct available to fchmod FS handlers. Date: Wed, 2 Nov 2016 23:53:40 +0100 Message-Id: <20161102225340.11613-1-jabolopes@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: Syscall 'ftruncate' makes the 'file' struct available to filesystem handlers. This makes it possible, e.g., for filesystems, such as, FUSE, to access the file handle associated with the file descriptor that was passed to 'ftruncate'. In the specific case of FUSE, this also makes it possible for (userspace) FUSE-based filesystems to distinguish between calls to 'truncate' and 'ftruncate'. >>From an implementation point of view, this is possible because the 'ftruncate' syscall passes the 'file' struct to the underlying filesystem handlers via the 'ia_file' field and the 'ia_valid' field mask. Similarly to 'ftruncate', pass the 'file' struct to 'fchmod', which allows filesystem handlers to get the file handle associated with the file descriptor passed to 'fchmod' and allows FUSE-based filesystems to distinguish between calls to 'chmod' and 'fchmod'. In a future patch, make a similar change to the 'fchown' and 'futimens' syscalls. Signed-off-by: Jose Lopes --- fs/open.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/open.c b/fs/open.c index d3ed817..00214c5 100644 --- a/fs/open.c +++ b/fs/open.c @@ -516,7 +516,8 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) return error; } -static int chmod_common(const struct path *path, umode_t mode) +static int chmod_common(const struct path *path, umode_t mode, + struct file *filp) { struct inode *inode = path->dentry->d_inode; struct inode *delegated_inode = NULL; @@ -533,6 +534,10 @@ static int chmod_common(const struct path *path, umode_t mode) goto out_unlock; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; + if (filp) { + newattrs.ia_file = filp; + newattrs.ia_valid |= ATTR_FILE; + } error = notify_change(path->dentry, &newattrs, &delegated_inode); out_unlock: inode_unlock(inode); @@ -552,7 +557,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) if (f.file) { audit_file(f.file); - err = chmod_common(&f.file->f_path, mode); + err = chmod_common(&f.file->f_path, mode, f.file); fdput(f); } return err; @@ -566,7 +571,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode retry: error = user_path_at(dfd, filename, lookup_flags, &path); if (!error) { - error = chmod_common(&path, mode); + error = chmod_common(&path, mode, NULL); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -- 2.9.0