Re: [PATCH 2/3] ceph: save name and fsid in mount source

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

 



On Wed, May 10, 2023 at 08:42:10AM +0800, Xiubo Li wrote:
> 
> On 5/9/23 21:55, 胡玮文 wrote:
> > On Tue, May 09, 2023 at 09:36:16AM +0800, Xiubo Li wrote:
> > > On 5/8/23 01:55, Hu Weiwen wrote:
> > > > From: Hu Weiwen <sehuww@xxxxxxxxxxxxxxxx>
> > > > 
> > > > We have name and fsid in the new device syntax.  It is confusing that
> > > > the kernel accept these info but do not take them into account when
> > > > connecting to the cluster.
> > > > 
> > > > Although the mount.ceph helper program will extract the name from device
> > > > spec and pass it as name options, these changes are still useful if we
> > > > don't have that program installed, or if we want to call `mount()'
> > > > directly.
> > > > 
> > > > Signed-off-by: Hu Weiwen <sehuww@xxxxxxxxxxxxxxxx>
> > > > ---
> > > >    fs/ceph/super.c | 17 +++++++++++++++++
> > > >    1 file changed, 17 insertions(+)
> > > > 
> > > > diff --git a/fs/ceph/super.c b/fs/ceph/super.c
> > > > index 4e1f4031e888..74636b9383b8 100644
> > > > --- a/fs/ceph/super.c
> > > > +++ b/fs/ceph/super.c
> > > > @@ -267,6 +267,7 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
> > > >    	struct ceph_fsid fsid;
> > > >    	struct ceph_parse_opts_ctx *pctx = fc->fs_private;
> > > >    	struct ceph_mount_options *fsopt = pctx->opts;
> > > > +	struct ceph_options *copts = pctx->copts;
> > > >    	char *fsid_start, *fs_name_start;
> > > >    	if (*dev_name_end != '=') {
> > > > @@ -285,6 +286,12 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
> > > >    	if (ceph_parse_fsid(fsid_start, &fsid))
> > > >    		return invalfc(fc, "Invalid FSID");
> > > > +	if (!(copts->flags & CEPH_OPT_FSID)) {
> > > > +		copts->fsid = fsid;
> > > > +		copts->flags |= CEPH_OPT_FSID;
> > > > +	} else if (ceph_fsid_compare(&fsid, &copts->fsid)) {
> > > > +		return invalfc(fc, "Mismatching cluster FSID");
> > > > +	}
> > > >    	++fs_name_start; /* start of file system name */
> > > >    	len = dev_name_end - fs_name_start;
> > > > @@ -298,6 +305,16 @@ static int ceph_parse_new_source(const char *dev_name, const char *dev_name_end,
> > > >    	}
> > > >    	dout("file system (mds namespace) '%s'\n", fsopt->mds_namespace);
> > > > +	len = fsid_start - dev_name - 1;
> > > > +	if (!copts->name) {
> > > > +		copts->name = kstrndup(dev_name, len, GFP_KERNEL);
> > > > +		if (!copts->name)
> > > > +			return -ENOMEM;
> > > Shouldn't we kfree the 'copts->mds_namespace' here ?
> > Seems not necessary.  ceph_free_fc() will take care of releasing the
> > whole 'struct ceph_parse_opts_ctx', including 'copts->mds_namespace'.
> > Besides, the mds_namespace may already be set before we parse the source
> > here.
> > 
> > ceph_free_fc() is called from:
> > put_fs_context
> 
> 457 void put_fs_context(struct fs_context *fc)
> 458 {
> 459         struct super_block *sb;
> 460
> 461         if (fc->root) {
> 462                 sb = fc->root->d_sb;
> 463                 dput(fc->root);
> 464                 fc->root = NULL;
> 465                 deactivate_super(sb);
> 466         }
> 467
> 468         if (fc->need_free && fc->ops && fc->ops->free)
> 469                 fc->ops->free(fc);
> 
> But are u sure the 'fc->need_free' is correctly set ?
> 
> It seems not from my reading if I didn't miss something.

'fc->need_free' is initialized to true just after init_fs_context() is
called, see 'alloc_fs_context()'.  And it is only reset to false after
calling free().

I've verified with gdb that ceph_free_fc() got called if
ceph_parse_new_source() returns an error.

Anyway, if ceph_free_fc() is not invoked, then we are leaking a lot of
things, not just mds_namespace.  The whole fs_context need to be freed
unconditionally after the mount is finished.

> Thanks
> 
> - Xiubo
> 
> > do_new_mount
> > do_mount
> > 
> > > > +	} else if (!strstrn_equals(copts->name, dev_name, len)) {
> > > > +		return invalfc(fc, "Mismatching cephx name");
> > > > +	}
> > > > +	dout("cephx name '%s'\n", copts->name);
> > > > +
> > > >    	fsopt->new_dev_syntax = true;
> > > >    	return 0;
> > > >    }
> 



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Ceph Dev]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux