Message ID | 20220104140414.155198-2-brauner@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ceph: support idmapped mounts | expand |
On Tue, 2022-01-04 at 15:04 +0100, Christian Brauner wrote: > From: Christian Brauner <christian.brauner@ubuntu.com> > > When sending a mds request cephfs will send relevant data for the > requested operation. For creation requests the caller's fs{g,u}id is > used to set the ownership of the newly created filesystem object. For > setattr requests the caller can pass in arbitrary {g,u}id values to > which the relevant filesystem object is supposed to be changed. > > If the caller is performing the relevant operation via an idmapped mount > cephfs simply needs to take the idmapping into account when it sends the > relevant mds request. > > In order to support idmapped mounts for cephfs we stash the idmapping > whenever they are relevant for the operation for the duration of the > request. Since mds requests can be queued and performed asynchronously > we make sure to keep the idmapping around and release it once the > request has finished. > > In follow-up patches we will use this to send correct ownership > information over the wire. This patch just adds the basic infrastructure > to keep the idmapping around. The actual conversion patches are all > fairly minimal. > > Cc: Jeff Layton <jlayton@kernel.org> > Cc: Ilya Dryomov <idryomov@gmail.com> > Cc: ceph-devel@vger.kernel.org > Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com> > --- > fs/ceph/mds_client.c | 7 +++++++ > fs/ceph/mds_client.h | 1 + > 2 files changed, 8 insertions(+) > > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > index c30eefc0ac19..ae2cc4ce1d48 100644 > --- a/fs/ceph/mds_client.c > +++ b/fs/ceph/mds_client.c > @@ -12,6 +12,7 @@ > #include <linux/bits.h> > #include <linux/ktime.h> > #include <linux/bitmap.h> > +#include <linux/mnt_idmapping.h> > > #include "super.h" > #include "mds_client.h" > @@ -862,6 +863,8 @@ void ceph_mdsc_release_request(struct kref *kref) > kfree(req->r_path1); > kfree(req->r_path2); > put_cred(req->r_cred); > + if (!initial_idmapping(req->mnt_userns)) > + put_user_ns(req->mnt_userns); I assume initial_idmapping returns true if it's init_user_ns ? > if (req->r_pagelist) > ceph_pagelist_release(req->r_pagelist); > put_request_session(req); > @@ -918,6 +921,10 @@ static void __register_request(struct ceph_mds_client *mdsc, > insert_request(&mdsc->request_tree, req); > > req->r_cred = get_current_cred(); > + if (!req->mnt_userns) > + req->mnt_userns = &init_user_ns; > + else > + get_user_ns(req->mnt_userns); > > if (mdsc->oldest_tid == 0 && req->r_op != CEPH_MDS_OP_SETFILELOCK) > mdsc->oldest_tid = req->r_tid; > diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h > index 97c7f7bfa55f..1b648645e340 100644 > --- a/fs/ceph/mds_client.h > +++ b/fs/ceph/mds_client.h > @@ -275,6 +275,7 @@ struct ceph_mds_request { > union ceph_mds_request_args r_args; > int r_fmode; /* file mode, if expecting cap */ > const struct cred *r_cred; > + struct user_namespace *mnt_userns; Can we call this r_mnt_userns to match the other fields ? > int r_request_release_offset; > struct timespec64 r_stamp; >
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index c30eefc0ac19..ae2cc4ce1d48 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -12,6 +12,7 @@ #include <linux/bits.h> #include <linux/ktime.h> #include <linux/bitmap.h> +#include <linux/mnt_idmapping.h> #include "super.h" #include "mds_client.h" @@ -862,6 +863,8 @@ void ceph_mdsc_release_request(struct kref *kref) kfree(req->r_path1); kfree(req->r_path2); put_cred(req->r_cred); + if (!initial_idmapping(req->mnt_userns)) + put_user_ns(req->mnt_userns); if (req->r_pagelist) ceph_pagelist_release(req->r_pagelist); put_request_session(req); @@ -918,6 +921,10 @@ static void __register_request(struct ceph_mds_client *mdsc, insert_request(&mdsc->request_tree, req); req->r_cred = get_current_cred(); + if (!req->mnt_userns) + req->mnt_userns = &init_user_ns; + else + get_user_ns(req->mnt_userns); if (mdsc->oldest_tid == 0 && req->r_op != CEPH_MDS_OP_SETFILELOCK) mdsc->oldest_tid = req->r_tid; diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 97c7f7bfa55f..1b648645e340 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -275,6 +275,7 @@ struct ceph_mds_request { union ceph_mds_request_args r_args; int r_fmode; /* file mode, if expecting cap */ const struct cred *r_cred; + struct user_namespace *mnt_userns; int r_request_release_offset; struct timespec64 r_stamp;