All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Max Reitz <mreitz@redhat.com>
Cc: virtio-fs@redhat.com
Subject: Re: [Virtio-fs] [RFC 2/2] virtiofsd: Set st_rdev for sub-mount points
Date: Wed, 6 May 2020 17:04:11 +0100	[thread overview]
Message-ID: <20200506160411.GO2743@work-vm> (raw)
In-Reply-To: <20200506154010.241055-2-mreitz@redhat.com>

* Max Reitz (mreitz@redhat.com) wrote:
> Whenever we encounter a directory with an st_dev that differs from that
> of its parent, we set st_rdev accordingly so the guest can create a
> submount for it.
> 
> Make this behavior optional, so submounts are only announced to the
> guest with the announce_submounts option.  Some users may prefer the
> current behavior, so that the guest learns nothing about the host mount
> structure.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>

Does this need to be wired to a flag in the INIT message (like say
FUSE_ASYNC_READ) to indicate that the kernel/daemon supports this, or is
it really safe just to start sending the changed rdev?

Dave

> ---
>  tools/virtiofsd/passthrough_ll.c | 59 +++++++++++++++++++++++++++-----
>  1 file changed, 50 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
> index 6cf471d31a..abf9d33493 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -159,6 +159,7 @@ struct lo_data {
>      int timeout_set;
>      int readdirplus_set;
>      int readdirplus_clear;
> +    int announce_submounts;
>      struct lo_inode root;
>      GHashTable *inodes; /* protected by lo->mutex */
>      struct lo_map ino_map; /* protected by lo->mutex */
> @@ -187,6 +188,7 @@ static const struct fuse_opt lo_opts[] = {
>      { "norace", offsetof(struct lo_data, norace), 1 },
>      { "readdirplus", offsetof(struct lo_data, readdirplus_set), 1 },
>      { "no_readdirplus", offsetof(struct lo_data, readdirplus_clear), 1 },
> +    { "announce_submounts", offsetof(struct lo_data, announce_submounts), 1 },
>      FUSE_OPT_END
>  };
>  static bool use_syslog = false;
> @@ -582,17 +584,42 @@ static void lo_init(void *userdata, struct fuse_conn_info *conn)
>      }
>  }
>  
> +/**
> + * Call fstatat() and set st_rdev whenever a directory's st_dev
> + * differs from the rparent's st_dev (@parent_dev).  This will
> + * announce submounts to the FUSE client (unless @announce_submounts
> + * is false).
> + */
> +static int do_fstatat(int dirfd, const char *pathname, struct stat *statbuf,
> +                      int flags, dev_t parent_dev, bool announce_submounts)
> +{
> +    int res = fstatat(dirfd, pathname, statbuf, flags);
> +    if (res == -1) {
> +        return res;
> +    }
> +
> +    if (statbuf->st_dev != parent_dev && S_ISDIR(statbuf->st_mode) &&
> +        announce_submounts)
> +    {
> +        statbuf->st_rdev = statbuf->st_dev;
> +    }
> +
> +    return 0;
> +}
> +
>  static void lo_getattr(fuse_req_t req, fuse_ino_t ino,
>                         struct fuse_file_info *fi)
>  {
>      int res;
>      struct stat buf;
>      struct lo_data *lo = lo_data(req);
> +    struct lo_inode *inode = lo_inode(req, ino);
>  
>      (void)fi;
>  
> -    res =
> -        fstatat(lo_fd(req, ino), "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
> +    res = do_fstatat(inode->fd, "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW,
> +                     inode->parent_dev, lo->announce_submounts);
> +    lo_inode_put(lo, &inode);
>      if (res == -1) {
>          return (void)fuse_reply_err(req, errno);
>      }
> @@ -645,7 +672,9 @@ retry:
>          pthread_mutex_unlock(&lo->mutex);
>      } else {
>          *last = '\0';
> -        res = fstatat(AT_FDCWD, last == path ? "/" : path, &stat, 0);
> +        /* Pass parent_dev=0 because st_rdev will be ignored anyway */
> +        res = do_fstatat(AT_FDCWD, last == path ? "/" : path, &stat, 0, 0,
> +                         lo->announce_submounts);
>          if (res == -1) {
>              if (!retries) {
>                  fuse_log(FUSE_LOG_WARNING,
> @@ -663,7 +692,8 @@ retry:
>          }
>      }
>      last++;
> -    res = fstatat(p->fd, last, &stat, AT_SYMLINK_NOFOLLOW);
> +    res = do_fstatat(p->fd, last, &stat, AT_SYMLINK_NOFOLLOW, p->key.dev,
> +                     lo->announce_submounts);
>      if (res == -1) {
>          if (!retries) {
>              fuse_log(FUSE_LOG_WARNING,
> @@ -925,7 +955,8 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
>          goto out_err;
>      }
>  
> -    res = fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
> +    res = do_fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW,
> +                     dir->key.dev, lo->announce_submounts);
>      if (res == -1) {
>          goto out_err;
>      }
> @@ -1207,7 +1238,9 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t parent,
>          goto out_err;
>      }
>  
> -    res = fstatat(inode->fd, "", &e.attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
> +    res = do_fstatat(inode->fd, "", &e.attr,
> +                     AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW,
> +                     parent_inode->key.dev, lo->announce_submounts);
>      if (res == -1) {
>          goto out_err;
>      }
> @@ -1246,14 +1279,22 @@ static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent,
>  {
>      int res;
>      struct stat attr;
> +    struct lo_data *lo = lo_data(req);
> +    struct lo_inode *dir = lo_inode(req, parent);
>  
> -    res = fstatat(lo_fd(req, parent), name, &attr,
> -                  AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
> +    if (!dir) {
> +        return NULL;
> +    }
> +
> +    res = do_fstatat(dir->fd, name, &attr,
> +                     AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, dir->key.dev,
> +                     lo->announce_submounts);
> +    lo_inode_put(lo, &dir);
>      if (res == -1) {
>          return NULL;
>      }
>  
> -    return lo_find(lo_data(req), &attr);
> +    return lo_find(lo, &attr);
>  }
>  
>  static void lo_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
> -- 
> 2.26.2
> 
> _______________________________________________
> Virtio-fs mailing list
> Virtio-fs@redhat.com
> https://www.redhat.com/mailman/listinfo/virtio-fs
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK


  reply	other threads:[~2020-05-06 16:04 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-06 15:32 [Virtio-fs] [RFC] Duplicate submounts in the guest Max Reitz
2020-05-06 15:35 ` [Virtio-fs] [RFC 0/5] fuse: Auto-mounted submounts Max Reitz
2020-05-06 15:36   ` [Virtio-fs] [RFC 1/5] fuse: Store fuse_conn in fuse_req Max Reitz
2020-05-06 15:36   ` [Virtio-fs] [RFC 2/5] fuse: Drop fuse_conn parameter where possible Max Reitz
2020-05-06 15:36   ` [Virtio-fs] [RFC 3/5] fuse: Split fuse_mount off of fuse_conn Max Reitz
2020-05-07  9:56     ` Miklos Szeredi
2020-05-07 11:16       ` Max Reitz
2020-05-07 11:24         ` Miklos Szeredi
2020-05-07 12:07           ` Max Reitz
2020-05-07 14:05             ` Miklos Szeredi
2020-05-07 15:05               ` Max Reitz
2020-05-07 15:19                 ` Miklos Szeredi
2020-05-06 15:36   ` [Virtio-fs] [RFC 4/5] fuse: Allow fuse_fill_super_common() for submounts Max Reitz
2020-05-06 15:36   ` [Virtio-fs] [RFC 5/5] fuse: Implement crossmounts Max Reitz
2020-05-06 15:38 ` [Virtio-fs] [RFC 0/2] virtiofsd: Announce submounts Max Reitz
2020-05-06 15:40   ` [Virtio-fs] [RFC 1/2] virtiofsd: Store every lo_inode's parent_dev Max Reitz
2020-05-06 15:40   ` [Virtio-fs] [RFC 2/2] virtiofsd: Set st_rdev for sub-mount points Max Reitz
2020-05-06 16:04     ` Dr. David Alan Gilbert [this message]
2020-05-07 10:56       ` Max Reitz
2020-05-07 11:43         ` Miklos Szeredi
2020-05-07 12:18           ` Max Reitz
2020-05-07 13:06             ` Dr. David Alan Gilbert
2020-05-07 14:29             ` Miklos Szeredi
2020-05-07 15:15               ` Max Reitz
2020-05-07 15:23                 ` Miklos Szeredi
2020-05-06 15:52 ` [Virtio-fs] [RFC] Duplicate submounts in the guest Dr. David Alan Gilbert
2020-05-07 10:50   ` Max Reitz
2020-05-07 20:53 ` Vivek Goyal
2020-05-08  7:31   ` Max Reitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200506160411.GO2743@work-vm \
    --to=dgilbert@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=virtio-fs@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.