Re: [PATCH v2 RESEND 2/2] fuse: Use the high bit of request ID for indicating resend requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 29 Nov 2023 at 10:43, Zhao Chen <winters.zc@xxxxxxxxxxxx> wrote:
>
> Some FUSE daemons want to know if the received request is a resend
> request, after writing to the sysfs resend API. The high bit of the fuse
> request id is utilized for indicating this, enabling the receiver to
> perform appropriate handling.
>
> An init flag is added to indicate this feature.
>
> Signed-off-by: Zhao Chen <winters.zc@xxxxxxxxxxxx>
> ---
>  fs/fuse/dev.c             | 11 +++++++----
>  fs/fuse/inode.c           |  3 ++-
>  include/uapi/linux/fuse.h | 11 +++++++++++
>  3 files changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index c91cb2bd511b..8a90a41b9a17 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -28,6 +28,7 @@ MODULE_ALIAS("devname:fuse");
>  /* Ordinary requests have even IDs, while interrupts IDs are odd */
>  #define FUSE_INT_REQ_BIT (1ULL << 0)
>  #define FUSE_REQ_ID_STEP (1ULL << 1)
> +#define FUSE_REQ_ID_MASK (~(FUSE_INT_REQ_BIT | FUSE_REQ_ID_RESEND_BIT))
>
>  static struct kmem_cache *fuse_req_cachep;
>
> @@ -194,14 +195,14 @@ EXPORT_SYMBOL_GPL(fuse_len_args);
>
>  u64 fuse_get_unique(struct fuse_iqueue *fiq)
>  {
> -       fiq->reqctr += FUSE_REQ_ID_STEP;
> +       fiq->reqctr = (fiq->reqctr + FUSE_REQ_ID_STEP) & FUSE_REQ_ID_MASK;
>         return fiq->reqctr;
>  }
>  EXPORT_SYMBOL_GPL(fuse_get_unique);
>
>  static unsigned int fuse_req_hash(u64 unique)
>  {
> -       return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
> +       return hash_long(unique & FUSE_REQ_ID_MASK, FUSE_PQ_HASH_BITS);

Possible simplification if FUSE_REQ_ID_RESEND_BIT is not used as a
separate flag, but as a part of the unique request ID.  That way
there's no need to mask it out.

>  }
>
>  /*
> @@ -1813,7 +1814,7 @@ static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
>         struct fuse_req *req;
>
>         list_for_each_entry(req, &fpq->processing[hash], list) {
> -               if (req->in.h.unique == unique)
> +               if ((req->in.h.unique & FUSE_REQ_ID_MASK) == unique)

Same here.


>                         return req;
>         }
>         return NULL;
> @@ -1884,7 +1885,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
>         spin_lock(&fpq->lock);
>         req = NULL;
>         if (fpq->connected)
> -               req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
> +               req = request_find(fpq, oh.unique & FUSE_REQ_ID_MASK);
>
>         err = -ENOENT;
>         if (!req) {
> @@ -2274,6 +2275,8 @@ void fuse_resend_pqueue(struct fuse_conn *fc)
>
>         list_for_each_entry_safe(req, next, &to_queue, list) {
>                 __set_bit(FR_PENDING, &req->flags);
> +               /* mark the request as resend request */
> +               req->in.h.unique |= FUSE_REQ_ID_RESEND_BIT;
>         }
>
>         spin_lock(&fiq->lock);
> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
> index 2a6d44f91729..e774865fbfa3 100644
> --- a/fs/fuse/inode.c
> +++ b/fs/fuse/inode.c
> @@ -1330,7 +1330,8 @@ void fuse_send_init(struct fuse_mount *fm)
>                 FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
>                 FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT |
>                 FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP |
> -               FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_ALLOW_MMAP;
> +               FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_ALLOW_MMAP |
> +               FUSE_UID_HAS_RESEND_BIT;
>  #ifdef CONFIG_FUSE_DAX
>         if (fm->fc->dax)
>                 flags |= FUSE_MAP_ALIGNMENT;
> diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
> index e7418d15fe39..ecfb7cbcfe30 100644
> --- a/include/uapi/linux/fuse.h
> +++ b/include/uapi/linux/fuse.h
> @@ -410,6 +410,8 @@ struct fuse_file_lock {
>   *                     symlink and mknod (single group that matches parent)
>   * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
>   * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode.
> + * FUSE_UID_HAS_RESEND_BIT: use high bit of request ID for indicating resend
> + *                         requests
>   */
>  #define FUSE_ASYNC_READ                (1 << 0)
>  #define FUSE_POSIX_LOCKS       (1 << 1)
> @@ -449,6 +451,7 @@ struct fuse_file_lock {
>  #define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
>  #define FUSE_HAS_EXPIRE_ONLY   (1ULL << 35)
>  #define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36)
> +#define FUSE_UID_HAS_RESEND_BIT (1ULL << 37)

"FUSE_HAS_RESEND" should be sufficiently descriptive.

>
>  /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */
>  #define FUSE_DIRECT_IO_RELAX   FUSE_DIRECT_IO_ALLOW_MMAP
> @@ -960,6 +963,14 @@ struct fuse_fallocate_in {
>         uint32_t        padding;
>  };
>
> +/**
> + * FUSE request unique ID flag
> + *
> + * Indicates whether this is a resend request. The receiver should handle this
> + * request accordingly.
> + */
> +#define FUSE_REQ_ID_RESEND_BIT (1ULL << 63)

How about "FUSE_UNIQUE_RESEND"?

Thanks,
Miklos




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux