Merge tag 'fuse-update-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Sep 2023 19:45:55 +0000 (12:45 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Sep 2023 19:45:55 +0000 (12:45 -0700)
Pull fuse updates from Miklos Szeredi:

 - Revert non-waiting FLUSH due to a regression

 - Fix a lookup counter leak in readdirplus

 - Add an option to allow shared mmaps in no-cache mode

 - Add btime support and statx intrastructure to the protocol

 - Invalidate positive/negative dentry on failed create/delete

* tag 'fuse-update-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: conditionally fill kstat in fuse_do_statx()
  fuse: invalidate dentry on EEXIST creates or ENOENT deletes
  fuse: cache btime
  fuse: implement statx
  fuse: add ATTR_TIMEOUT macro
  fuse: add STATX request
  fuse: handle empty request_mask in statx
  fuse: write back dirty pages before direct write in direct_io_relax mode
  fuse: add a new fuse init flag to relax restrictions in no cache mode
  fuse: invalidate page cache pages before direct write
  fuse: nlookup missing decrement in fuse_direntplus_link
  Revert "fuse: in fuse_flush only wait if someone wants the return code"

1  2 
fs/fuse/dir.c
fs/fuse/inode.c

diff --cc fs/fuse/dir.c
@@@ -1220,11 -1308,24 +1308,24 @@@ retry
  
        if (sync) {
                forget_all_cached_acls(inode);
-               err = fuse_do_getattr(inode, stat, file);
+               /* Try statx if BTIME is requested */
+               if (!fc->no_statx && (request_mask & ~STATX_BASIC_STATS)) {
+                       err = fuse_do_statx(inode, file, stat);
+                       if (err == -ENOSYS) {
+                               fc->no_statx = 1;
+                               goto retry;
+                       }
+               } else {
+                       err = fuse_do_getattr(inode, stat, file);
+               }
        } else if (stat) {
 -              generic_fillattr(&nop_mnt_idmap, inode, stat);
 +              generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
                stat->mode = fi->orig_i_mode;
                stat->ino = fi->orig_ino;
+               if (test_bit(FUSE_I_BTIME, &fi->state)) {
+                       stat->btime = fi->i_btime;
+                       stat->result_mask |= STATX_BTIME;
+               }
        }
  
        return err;
diff --cc fs/fuse/inode.c
@@@ -194,8 -196,28 +196,27 @@@ void fuse_change_attributes_common(stru
                inode->i_mtime.tv_nsec  = attr->mtimensec;
        }
        if (!(cache_mask & STATX_CTIME)) {
 -              inode->i_ctime.tv_sec   = attr->ctime;
 -              inode->i_ctime.tv_nsec  = attr->ctimensec;
 +              inode_set_ctime(inode, attr->ctime, attr->ctimensec);
        }
+       if (sx) {
+               /* Sanitize nsecs */
+               sx->btime.tv_nsec =
+                       min_t(u32, sx->btime.tv_nsec, NSEC_PER_SEC - 1);
+               /*
+                * Btime has been queried, cache is valid (whether or not btime
+                * is available or not) so clear STATX_BTIME from inval_mask.
+                *
+                * Availability of the btime attribute is indicated in
+                * FUSE_I_BTIME
+                */
+               set_mask_bits(&fi->inval_mask, STATX_BTIME, 0);
+               if (sx->mask & STATX_BTIME) {
+                       set_bit(FUSE_I_BTIME, &fi->state);
+                       fi->i_btime.tv_sec = sx->btime.tv_sec;
+                       fi->i_btime.tv_nsec = sx->btime.tv_nsec;
+               }
+       }
  
        if (attr->blksize != 0)
                inode->i_blkbits = ilog2(attr->blksize);