Re: [RFC PATCH 04/11] ceph: hold extra reference to r_parent over life of request

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

 



On Wed, Apr 10, 2019 at 6:27 AM Luis Henriques <lhenriques@xxxxxxxx> wrote:
>
> Jeff Layton <jlayton@xxxxxxxxxx> writes:
>
> > Currently, we just assume that it will stick around by virtue of the
> > submitter's reference, but later patches will allow the syscall to
> > return early and we can't rely on that reference at that point.
> >
> > Take an extra reference to the inode when setting r_parent and release
> > it when releasing the request.
>
> Couldn't you move all these ihold into ceph_mdsc_do_request?  I took a
> quick look and it seems like it could use a logic similar to what's in
> ceph_mdsc_release_request, i.e.:
>
>         if (req->r_parent)
>                 ihold(req->r_parent);
>
> Cheers,
> --
> Luis
>
> >
> > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> > ---
> >  fs/ceph/dir.c        | 8 ++++++++
> >  fs/ceph/export.c     | 1 +
> >  fs/ceph/file.c       | 1 +
> >  fs/ceph/mds_client.c | 4 +++-
> >  4 files changed, 13 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> > index a8f429882249..3eb9bc226b77 100644
> > --- a/fs/ceph/dir.c
> > +++ b/fs/ceph/dir.c
> > @@ -783,6 +783,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
> >       req->r_args.getattr.mask = cpu_to_le32(mask);
> >
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       err = ceph_mdsc_do_request(mdsc, NULL, req);
> >       err = ceph_handle_snapdir(req, dentry, err);
> > @@ -850,6 +851,7 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
> >       req->r_dentry = dget(dentry);
> >       req->r_num_caps = 2;
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_args.mknod.mode = cpu_to_le32(mode);
> >       req->r_args.mknod.rdev = cpu_to_le32(rdev);
> > @@ -907,6 +909,7 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
> >               goto out;
> >       }
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_dentry = dget(dentry);
> >       req->r_num_caps = 2;
> > @@ -963,6 +966,7 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
> >       req->r_dentry = dget(dentry);
> >       req->r_num_caps = 2;
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_args.mkdir.mode = cpu_to_le32(mode);
> >       req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
> > @@ -1008,6 +1012,7 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
> >       req->r_num_caps = 2;
> >       req->r_old_dentry = dget(old_dentry);
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
> >       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
> > @@ -1055,6 +1060,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
> >       req->r_dentry = dget(dentry);
> >       req->r_num_caps = 2;
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
> >       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
> > @@ -1104,6 +1110,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
> >       req->r_old_dentry = dget(old_dentry);
> >       req->r_old_dentry_dir = old_dir;
> >       req->r_parent = new_dir;
> > +     ihold(new_dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
> >       req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
> > @@ -1586,6 +1593,7 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
> >                       req->r_dentry = dget(dentry);
> >                       req->r_num_caps = 2;
> >                       req->r_parent = dir;
> > +                     ihold(dir);
> >
> >                       mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
> >                       if (ceph_security_xattr_wanted(dir))
> > diff --git a/fs/ceph/export.c b/fs/ceph/export.c
> > index d3ef7ee429ec..e7804720549d 100644
> > --- a/fs/ceph/export.c
> > +++ b/fs/ceph/export.c
> > @@ -519,6 +519,7 @@ static int ceph_get_name(struct dentry *parent, char *name,
> >       ihold(inode);
> >       req->r_ino2 = ceph_vino(d_inode(parent));
> >       req->r_parent = d_inode(parent);
> > +     ihold(req->r_parent);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       req->r_num_caps = 2;
> >       err = ceph_mdsc_do_request(mdsc, NULL, req);
> > diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> > index 0e505a5e09fe..f24d18f46715 100644
> > --- a/fs/ceph/file.c
> > +++ b/fs/ceph/file.c
> > @@ -478,6 +478,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
> >         req->r_args.open.mask = cpu_to_le32(mask);
> >
> >       req->r_parent = dir;
> > +     ihold(dir);
> >       set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
> >       err = ceph_mdsc_do_request(mdsc,
> >                                  (flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
> > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> > index 9d1ac87e5897..8c05cfe57adf 100644
> > --- a/fs/ceph/mds_client.c
> > +++ b/fs/ceph/mds_client.c
> > @@ -696,8 +696,10 @@ void ceph_mdsc_release_request(struct kref *kref)
> >               ceph_put_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
> >               iput(req->r_inode);
> >       }
> > -     if (req->r_parent)
> > +     if (req->r_parent) {
> >               ceph_put_cap_refs(ceph_inode(req->r_parent), CEPH_CAP_PIN);
> > +             iput(req->r_parent);
> > +     }
> >       iput(req->r_target_inode);
> >       if (req->r_dentry)
> >               dput(req->r_dentry);


Yes, I think so. I'll make that change.

Thanks,
-- 
Jeff Layton <jlayton@xxxxxxxxxxxxxxx>



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

  Powered by Linux