[PATCH] Convert Samba to OFD locking - version 2
Jeff Layton
jlayton at samba.org
Mon May 23 14:26:42 UTC 2016
On Fri, 2016-05-20 at 17:07 -0700, Jeremy Allison wrote:
> On Fri, May 20, 2016 at 07:01:18AM -0400, Jeff Layton wrote:
> > On Thu, 2016-05-19 at 14:12 -0700, Jeremy Allison wrote:
> > > OK, here is version 2 with Uri and Simo's changes
> > > incorporated. Compile-time checks now run the test
> > > code rather than just compiling, and there's a
> > > tuneable "smbd:force process locks" that will force
> > > the old-style process specific locks. Advice to
> > > use it gets printed in the log if fcntl returns
> > > EINVAL.
> > >
> > > Please review and push if happy !
> > >
> > > Thanks,
> > >
> > > Jeremy.
> >
> > Looks reasonable to me, though again, I don't know the userland
> > samba
> > code that well. So, fwiw...
> >
> > Acked-by: Jeff Layton <jlayton at samba.org>
> >
> > ...also attached is an untested patch for cifsfs, which I was
> > thinking
> > would do the right thing wrt lockowners. I'll test it out as soon
> > as I
> > can put a test rig together for it. In the meantime, thoughts?
>
> Looks exactly right to me. With that and my patches
> OFD-locks should work over the wire to Samba with
> cifsfs and SMB1. You'll have to wait until my
> autobuild lands in master first though (2 unrelated
> and random different failures so far, grrr. I keep trying).
>
> SMB2 uses the persistent part of the handle as the
> lock context so once we've gotten SMB2+ unix extensions
> onboard this should just work out of the box over
> SMB3.
>
AFAICT, this patch makes no material difference in testing.
The client first compares the incoming lock request vs. the local lock
database. If there is already a conflicting lock set on the file, it's
rejected there before the lock request ever goes to the server. I guess
this makes sense from a performance standpoint -- no need to go out
over the network if we already know there's a conflicting lock.
This patch does seem more correct to me than sending the pid, given how
samba uses that field. But, I think we already have working OFD
semantics anyway, as long as the client's kernel supports them properly
for local filesystems.
Steve, I figure this is your call. Should I send it to linux-cifs? If
you do want it, there's certainly no urgency. It could soak in linux-
next for a cycle or two...
-- Jeff
> > From c976fce960bad85bb97ad62b7d3efc8fe04aafad Mon Sep 17 00:00:00
> > 2001
> > From: Jeff Layton <jeff.layton at primarydata.com>
> > Date: Fri, 20 May 2016 06:18:24 -0400
> > Subject: [PATCH] cifs: stuff the fl_owner into "pid" field in the
> > lock request
> >
> > Right now, we send a "pid" across the wire. What we really want to
> > send
> > though is a hashed fl_owner_t. That should allow OFD locks to work
> > seamlessly in cifs with POSIX extensions.
> >
> > Signed-off-by: Jeff Layton <jeff.layton at primarydata.com>
> > ---
> > fs/cifs/cifsfs.c | 3 +++
> > fs/cifs/cifsglob.h | 1 +
> > fs/cifs/file.c | 14 +++++++++++---
> > 3 files changed, 15 insertions(+), 3 deletions(-)
> >
> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > index 08fa36e5b2bc..1ef5b8aee878 100644
> > --- a/fs/cifs/cifsfs.c
> > +++ b/fs/cifs/cifsfs.c
> > @@ -87,6 +87,7 @@ extern mempool_t *cifs_req_poolp;
> > extern mempool_t *cifs_mid_poolp;
> >
> > struct workqueue_struct *cifsiod_wq;
> > +__u32 cifs_lock_secret;
> >
> > /*
> > * Bumps refcount for cifs super block.
> > @@ -1271,6 +1272,8 @@ init_cifs(void)
> > spin_lock_init(&cifs_file_list_lock);
> > spin_lock_init(&GlobalMid_Lock);
> >
> > + get_random_bytes(&cifs_lock_secret,
> > sizeof(cifs_lock_secret));
> > +
> > if (cifs_max_pending < 2) {
> > cifs_max_pending = 2;
> > cifs_dbg(FYI, "cifs_max_pending set to min of
> > 2\n");
> > diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> > index bba106cdc43c..8f1d8c1e72be 100644
> > --- a/fs/cifs/cifsglob.h
> > +++ b/fs/cifs/cifsglob.h
> > @@ -1619,6 +1619,7 @@ void cifs_oplock_break(struct work_struct
> > *work);
> >
> > extern const struct slow_work_ops cifs_oplock_break_ops;
> > extern struct workqueue_struct *cifsiod_wq;
> > +extern __u32 cifs_lock_secret;
> >
> > extern mempool_t *cifs_mid_poolp;
> >
> > diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> > index 9793ae0bcaa2..d4890b6dc22d 100644
> > --- a/fs/cifs/file.c
> > +++ b/fs/cifs/file.c
> > @@ -1112,6 +1112,12 @@ cifs_push_mandatory_locks(struct
> > cifsFileInfo *cfile)
> > return rc;
> > }
> >
> > +static __u32
> > +hash_lockowner(fl_owner_t owner)
> > +{
> > + return cifs_lock_secret ^ hash32_ptr((const void *)owner);
> > +}
> > +
> > struct lock_to_push {
> > struct list_head llist;
> > __u64 offset;
> > @@ -1178,7 +1184,7 @@ cifs_push_posix_locks(struct cifsFileInfo
> > *cfile)
> > else
> > type = CIFS_WRLCK;
> > lck = list_entry(el, struct lock_to_push, llist);
> > - lck->pid = flock->fl_pid;
> > + lck->pid = hash_lockowner(flock->fl_owner);
> > lck->netfid = cfile->fid.netfid;
> > lck->length = length;
> > lck->type = type;
> > @@ -1305,7 +1311,8 @@ cifs_getlk(struct file *file, struct
> > file_lock *flock, __u32 type,
> > posix_lock_type = CIFS_RDLCK;
> > else
> > posix_lock_type = CIFS_WRLCK;
> > - rc = CIFSSMBPosixLock(xid, tcon, netfid, current-
> > >tgid,
> > + rc = CIFSSMBPosixLock(xid, tcon, netfid,
> > + hash_lockowner(flock-
> > >fl_owner),
> > flock->fl_start, length,
> > flock,
> > posix_lock_type, wait_flag);
> > return rc;
> > @@ -1505,7 +1512,8 @@ cifs_setlk(struct file *file, struct
> > file_lock *flock, __u32 type,
> > posix_lock_type = CIFS_UNLCK;
> >
> > rc = CIFSSMBPosixLock(xid, tcon, cfile-
> > >fid.netfid,
> > - current->tgid, flock-
> > >fl_start, length,
> > + hash_lockowner(flock-
> > >fl_owner),
> > + flock->fl_start, length,
> > NULL, posix_lock_type,
> > wait_flag);
> > goto out;
> > }
> > --
> > 2.5.5
> >
>
--
Jeff Layton <jlayton at samba.org>
More information about the samba-technical
mailing list