diff options
author | David S. Miller <davem@davemloft.net> | 2018-12-20 21:53:28 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-20 22:53:36 +0300 |
commit | 2be09de7d6a06f58e768de1255a687c9aaa66606 (patch) | |
tree | 298f9e04caf105873d987e807eccba27710a49cc /fs/fuse/dir.c | |
parent | 44a7b3b6e3a458f9549c2cc28e74ecdc470e42f1 (diff) | |
parent | 1d51b4b1d3f2db0d6d144175e31a84e472fbd99a (diff) | |
download | linux-2be09de7d6a06f58e768de1255a687c9aaa66606.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Lots of conflicts, by happily all cases of overlapping
changes, parallel adds, things of that nature.
Thanks to Stephen Rothwell, Saeed Mahameed, and others
for their guidance in these resolutions.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 47395b0c3b35..e909678afa2d 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1119,8 +1119,10 @@ static int fuse_permission(struct inode *inode, int mask) if (fc->default_permissions || ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { struct fuse_inode *fi = get_fuse_inode(inode); + u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID; - if (time_before64(fi->i_time, get_jiffies_64())) { + if (perm_mask & READ_ONCE(fi->inval_mask) || + time_before64(fi->i_time, get_jiffies_64())) { refreshed = true; err = fuse_perm_getattr(inode, mask); @@ -1241,7 +1243,7 @@ static int fuse_dir_open(struct inode *inode, struct file *file) static int fuse_dir_release(struct inode *inode, struct file *file) { - fuse_release_common(file, FUSE_RELEASEDIR); + fuse_release_common(file, true); return 0; } @@ -1249,7 +1251,25 @@ static int fuse_dir_release(struct inode *inode, struct file *file) static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - return fuse_fsync_common(file, start, end, datasync, 1); + struct inode *inode = file->f_mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); + int err; + + if (is_bad_inode(inode)) + return -EIO; + + if (fc->no_fsyncdir) + return 0; + + inode_lock(inode); + err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR); + if (err == -ENOSYS) { + fc->no_fsyncdir = 1; + err = 0; + } + inode_unlock(inode); + + return err; } static long fuse_dir_ioctl(struct file *file, unsigned int cmd, |