NFSD: Rervert "knfsd: locks: flag NFSv4-owned locks"
Subsystems (4)
PATCH 2/4 NFSD: Rervert "knfsd: locks: flag NFSv4-owned locks"
Commit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock for nfsd4_lock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock for nfsd4_lockt always be NULL too.
So that, using fl_lmops cannot checking nfsd4 lockowner for it always be NULL.
This patch save the strhashval in nfs4_lockowner for searching lockownerlike before.
--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)
fs/nfsd/nfs4state.c +23 -12
@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; + +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)
@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */
@@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);
@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;
@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();
@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,
fs/nfsd/state.h +1 -0
@@ -362,6 +362,7 @@ struct nfs4_openowner {struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval; };static inline struct nfs4_openowner *openowner (struct nfs4_stateowner *so)
Signature · 1 line
1.9.3
Quoted 28 lines · On Mon, 07 Jul 2014 22:12:21 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.This patch save the strhashval in
nfs4_lockownerfor searching lockownerlike before.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +0
-3@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = {
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4293
Quoted 10 lines
fs/nfsd/nfs4state.c +9
-1-}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; +
^^^^
Maybe a WARN_ON_ONCE or something here would be appropriate?
Quoted 69 lines
fs/nfsd/nfs4state.c +14
-8+list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ @@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,fs/nfsd/state.h +0
-0
fs/nfsd/state.h struct nfs4_openowner { · line 368
Quoted 7 lines
fs/nfsd/state.h +1
-0@@ -362,6 +362,7 @@ struct nfs4_openowner {struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval; };static inline struct nfs4_openowner *openowner (struct nfs4_stateowner *so)
Looks fine other than the comment about the warning. I do have some patches that change the ownerstr_hashtbl to be a per-client entity. I'll need to respin them to account for this change, but that shouldn't be too onerous.
Quoted 107 lines · On Mon, 07 Jul 2014 22:12:21 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.This patch save the strhashval in
nfs4_lockownerfor searching lockownerlike before.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +23
-12@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; + +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ @@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,fs/nfsd/state.h +0
-0
fs/nfsd/state.h struct nfs4_openowner { · line 365
Quoted 4 lines
fs/nfsd/state.h +1
-0@@ -362,6 +362,7 @@ struct nfs4_openowner {struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval;
Actually, I have another comment here too. I'm not sure there's a lot of value in tracking the lo_hashval here. Why not just recompute it in nfs4_verify_lock_stateowner?
You'd need to pass down a pointer to the nfs4_client in order to do so, but you could do that instead of passing down 'nn' and then just call net_generic on clp->net where you needed it.
Quoted 4 lines
fs/nfsd/state.h +0
-0}; static inline struct nfs4_openowner * openowner(struct
nfs4_stateowner*so)
Signature · 1 line
Jeff Layton <[email protected]>
Quoted 28 lines · Jeff Layton
Quoted 25 lines · On Mon, 07 Jul 2014 22:12:21 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.This patch save the strhashval in
nfs4_lockownerfor searching lockownerlike before.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +0
-0@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; }
Quoted 16 lines
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4293
Quoted 13 lines
fs/nfsd/nfs4state.c +9
-4-/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; +^^^^
Maybe aWARN_ON_ONCEor something here would be appropriate?
No, I don't think so.
If the owner stored in fl->fl_owner isn't a nfs4_lockowner, the lo->lo_hashval field maybe any value, but it's all right.
Just return false here.
Quoted 76 lines
Quoted 76 lines
fs/nfsd/nfs4state.c +14
-8+list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ @@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,fs/nfsd/state.h +1
-0@@ -362,6 +362,7 @@ struct nfs4_openowner {struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval; };
Quoted 6 lines
fs/nfsd/state.h struct nfs4_openowner { · line 368
Quoted 1 line
fs/nfsd/state.h +0
-0static inline struct nfs4_openowner *openowner (struct nfs4_stateowner *so)Looks fine other than the comment about the warning. I do have some patches that change the
ownerstr_hashtblto be a per-client entity. I'll need to respin them to account for this change, but that shouldn't be too onerous.
Thanks for your review.
I will follow Bruce's tree and try to remake this patch after your change.
thanks,
Kinglong Mee
Quoted 111 lines · Jeff Layton
Quoted 108 lines · On Mon, 07 Jul 2014 22:12:21 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.This patch save the strhashval in
nfs4_lockownerfor searching lockownerlike before.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +23
-12@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; + +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ @@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,fs/nfsd/state.h +0
-0@@ -362,6 +362,7 @@ struct nfs4_openowner {
Quoted 7 lines
fs/nfsd/state.h struct nfs4_openowner { · line 365
Quoted 3 lines
fs/nfsd/state.h +1
-0struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval;Actually, I have another comment here too. I'm not sure there's a lot of value in tracking the
lo_hashvalhere. Why not just recompute it innfs4_verify_lock_stateowner?
No, ownerstr_hashval() needs a client which holds the conflicting lock, in nfsd4_lock/nfsd4_lockt cannot know the client from vfs_lock_file()
or vfs_test_lock().
Quoted 4 lines
You'd need to pass down a pointer to the
nfs4_clientin order to do so, but you could do that instead of passing down 'nn' and then just callnet_genericonclp->netwhere you needed it.
I find patch "[PATCH v3 069/114] nfsd: Move the open owner hash table into struct nfs4_client" have remove the client argument from ownerstr_hashval().
So, the lo_hashval isn't needed after that patch.
After Bruce merging that patch, I will resend a new patch recomputing the hash value instead recording in lo_hashval.
thanks,
Kinglong Mee
Quoted 120 lines · On Tue, 08 Jul 2014 11:23:49 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 111 lines · Jeff Layton
Quoted 108 lines · On Mon, 07 Jul 2014 22:12:21 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.This patch save the strhashval in
nfs4_lockownerfor searching lockownerlike before.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 35 +++++++++++++++++++++++------------ fs/nfsd/state.h | 1 + 2 files changed, 24 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +23
-12@@ -4282,18 +4282,30 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfsd_net *nn) +{ +struct nfs4_stateowner *local =NULL ; +unsigned hashval = lo->lo_hashval; + +if (hashval >=OWNER_HASH_SIZE ) +return false; + +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfsd_net *nn) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, nn)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4350,6 +4362,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, strif (!lo)return NULL ;INIT_LIST_HEAD (&lo->lo_owner.so_stateids); + lo->lo_hashval = strhashval; lo->lo_owner.so_is_open_owner =0 ;/* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ @@ -4564,7 +4577,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4587,7 +4599,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, nn);break ;case (EDEADLK ): status = nfserr_deadlock;@@ -4695,7 +4707,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, nn); } out:nfs4_unlock_state ();@@ -4746,7 +4758,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,fs/nfsd/state.h +0
-0@@ -362,6 +362,7 @@ struct nfs4_openowner {Quoted 7 lines
fs/nfsd/state.h struct nfs4_openowner { · line 365
Quoted 3 lines
fs/nfsd/state.h +1
-0struct nfs4_lockowner {struct nfs4_stateowner lo_owner;/* must be first element */ +unsigned int lo_hashval;Actually, I have another comment here too. I'm not sure there's a lot of value in tracking the
lo_hashvalhere. Why not just recompute it innfs4_verify_lock_stateowner?
Quoted 4 lines
No,
ownerstr_hashval()needs a client which holds the conflicting lock, in nfsd4_lock/nfsd4_lockt cannot know the client fromvfs_lock_file()
orvfs_test_lock().
Right, that was why I mentioned that you'd need to pass down the nfs4_client pointer to these functions, and then use that to derive the "nn".
Quoted 5 lines
Quoted 4 lines
You'd need to pass down a pointer to the
nfs4_clientin order to do so, but you could do that instead of passing down 'nn' and then just callnet_genericonclp->netwhere you needed it.
Quoted 8 lines
I find patch "[PATCH v3 069/114] nfsd: Move the open owner hash table into struct
nfs4_client" have remove the client argument fromownerstr_hashval().So, the
lo_hashvalisn't needed after that patch.
After Bruce merging that patch, I will resend a new patch recomputing the hash value instead recording inlo_hashval.
Ok. I guess the only question is whether this is a bugfix that needs to go in before those patches. If so, then we may want to do something closer to this patch.
It's untested, but it should be OK now that we cache the clp in the cstate. If this needs to go into 3.16 then we'll need to get that pointer elsewhere, but that's doable.
-------------------------[snip]------------------------------
[PATCH] NFSD: Rervert "knfsd: locks: flag NFSv4-owned locks"
Commit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock for nfsd4_lock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock for nfsd4_lockt always be NULL too.
So that, using fl_lmops cannot checking nfsd4 lockowner for it always be NULL.
--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)
fs/nfsd/nfs4state.c +22 -12
@@ -4312,18 +4312,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfs4_client *clp) +{ +struct nfs4_stateowner *local =NULL ; +struct nfsd_net *nn =net_generic (clp->net, nfsd_net_id); +unsigned int hashval =ownerstr_hashval (clp->cl_clientid.cl_id, + &lo->lo_owner.so_owner); + +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfs4_client *clp) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, clp)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)
@@ -4594,7 +4605,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);
@@ -4617,7 +4627,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, + cstate->clp);break ;case (EDEADLK ): status = nfserr_deadlock;
@@ -4725,7 +4736,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, cstate->clp); } out:nfs4_unlock_state ();
@@ -4776,7 +4787,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,
Signature · 1 line
1.9.3
Quoted 35 lines · Jeff Layton
Quoted 4 lines · On Tue, 08 Jul 2014 11:23:49 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 3 lines · Jeff Layton
On Mon, 07 Jul 2014 22:12:21 +0800
Kinglong Mee <[email protected]> wrote:-------------------------[snip]------------------------------
[PATCH] NFSD: Rervert "knfsd: locks: flag NFSv4-owned locks"
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.Signed-off-by Kinglong Mee <[email protected]>Signed-off-by Jeff Layton <[email protected]>--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +0
-1@@ -4312,18 +4312,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4321
Quoted 10 lines
fs/nfsd/nfs4state.c +7
-3-* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfs4_client *clp) +{ +struct nfs4_stateowner *local =NULL ; +struct nfsd_net *nn =net_generic (clp->net, nfsd_net_id); +unsigned int hashval =ownerstr_hashval (clp->cl_clientid.cl_id, + &lo->lo_owner.so_owner);
Needs the conflicting client which holds the lock, Not the new client which try to locking the file has be locked.
Quoted 42 lines
fs/nfsd/nfs4state.c +14
-6+ +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfs4_client *clp) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, clp)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4594,7 +4605,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4617,7 +4627,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, + cstate->clp);break ;case (EDEADLK ): status = nfserr_deadlock;
fs/nfsd/nfs4state.c nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 4739
Quoted 5 lines
fs/nfsd/nfs4state.c +1
-1@@ -4725,7 +4736,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, cstate->clp);
The clp is the client which try to lock the file here, but the file have be locked by other client or server.
With this patch, the hashval is wrong.
*correct* *this patch*
clid conflicting client new request lock client
owner from vfs_lock_file() from vfs_lock_file()
or vfs_test_lock() or vfs_test_lock()
hashval right hashval bad hashval (never exist)
With this patch, LOCK/LOCKT compound gets client with all zero, and owner with all zero.
thanks,
Kinglong Mee
Quoted 108 lines · On Tue, 08 Jul 2014 20:26:03 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 35 lines · Jeff Layton
Quoted 4 lines · On Tue, 08 Jul 2014 11:23:49 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 3 lines · Jeff Layton
On Mon, 07 Jul 2014 22:12:21 +0800
Kinglong Mee <[email protected]> wrote:-------------------------[snip]------------------------------
[PATCH] NFSD: Rervert "knfsd: locks: flag NFSv4-owned locks"
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, using
fl_lmopscannot checking nfsd4 lockowner for it always be NULL.Signed-off-by Kinglong Mee <[email protected]>Signed-off-by Jeff Layton <[email protected]>--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)fs/nfsd/nfs4state.c +0
-1@@ -4312,18 +4312,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4321
Quoted 10 lines
fs/nfsd/nfs4state.c +7
-3-* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; +static bool +nfs4_verify_lock_stateowner (struct nfs4_lockowner *lo,struct nfs4_client *clp) +{ +struct nfs4_stateowner *local =NULL ; +struct nfsd_net *nn =net_generic (clp->net, nfsd_net_id); +unsigned int hashval =ownerstr_hashval (clp->cl_clientid.cl_id, + &lo->lo_owner.so_owner);Needs the conflicting client which holds the lock, Not the new client which try to locking the file has be locked.
Quoted 42 lines
fs/nfsd/nfs4state.c +14
-6+ +list_for_each_entry (local, &nn->ownerstr_hashtbl[hashval], so_strhash) { +if (local == &lo->lo_owner) +return true; + } + +return false; +}static inline void -nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) +nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny, +struct nfs4_client *clp) { -struct nfs4_lockowner *lo; +struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { - lo = (struct nfs4_lockowner *) fl->fl_owner; +if (nfs4_verify_lock_stateowner (lo, clp)) { deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );if (!deny->ld_owner.data)@@ -4594,7 +4605,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -4617,7 +4627,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,case (EAGAIN ):/* conflock holds conflicting lock */ status = nfserr_denied;dprintk ("NFSD: nfsd4_lock: conflicting lock found!\n" ); -nfs4_set_lock_denied (conflock, &lock->lk_denied); +nfs4_set_lock_denied (conflock, &lock->lk_denied, + cstate->clp);break ;case (EDEADLK ): status = nfserr_deadlock;fs/nfsd/nfs4state.c nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 4739
Quoted 5 lines
fs/nfsd/nfs4state.c +1
-1@@ -4725,7 +4736,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (file_lock->fl_type !=F_UNLCK ) { status = nfserr_denied; -nfs4_set_lock_denied (file_lock, &lockt->lt_denied); +nfs4_set_lock_denied (file_lock, &lockt->lt_denied, cstate->clp);The clp is the client which try to lock the file here, but the file have be locked by other client or server.
With this patch, the hashval is wrong.
*correct* *this patch*
clid conflicting client new request lock client
owner fromvfs_lock_file()fromvfs_lock_file()
orvfs_test_lock()orvfs_test_lock()
hashval right hashval bad hashval (never exist)
Quoted 8 lines
With this patch, LOCK/LOCKT compound gets client with all zero, and owner with all zero.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
<facepalm>
Ahh ok, I see what you're saying now. I'll leave it to you to respin once the rest of the client_mutex removal series is merged. </facepalm>
Signature · 1 line
Jeff Layton <[email protected]>
Quoted 4 lines · Jeff Layton
<facepalm>
Ahh ok, I see what you're saying now. I'll leave it to you to respin once the rest of theclient_mutexremoval series is merged. </facepalm>
Apologies, ignored this thread, but I'm dropping this patch for now based on that comment.
--b.
PATCH 1/1 fs/locks.c: Copy fl_lmops to conflock for nfsd using
In reply to Kinglong MeeCommit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock for nfsd4_lock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock for nfsd4_lockt always be NULL too.
So that, nfsd4 lockowner for it always be NULL too.
This patch re-coping the fl_lmops to conflock.
--- fs/locks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/locks.c +1 -2
@@ -279,7 +279,7 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + new->fl_lmops = fl->fl_lmops; }EXPORT_SYMBOL (__locks_copy_lock);
@@ -290,7 +290,6 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)__locks_copy_lock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }
Signature · 1 line
1.9.3
Re: [PATCH] fs/locks.c: Copy fl_lmops to conflock for nfsd using
Quoted 34 lines · Kinglong Mee
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, nfsd4 lockowner for it always be NULL too.
This patch re-coping the
fl_lmopsto conflock.Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)fs/locks.c +1
-1@@ -279,7 +279,7 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + new->fl_lmops = fl->fl_lmops; }EXPORT_SYMBOL (__locks_copy_lock);
fs/locks.c void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
Quoted 8 lines
fs/locks.c +0
-2@@ -290,7 +290,6 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)__locks_copy_lock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } --
No. There is a very good reason why we separate __locks_copy_lock and locks_copy_private(). We don't want to have anyone calling notifiers etc for copies of locks.
Signature · 5 lines
Trond Myklebust Linux NFS client maintainer, PrimaryData [email protected]
Re: [PATCH] fs/locks.c: Copy fl_lmops to conflock for nfsd using
In reply to a message not in the archiveQuoted 34 lines · On Sat, 02 Aug 2014 22:45:17 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, nfsd4 lockowner for it always be NULL too.
This patch re-coping the
fl_lmopsto conflock.Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)fs/locks.c +1
-1@@ -279,7 +279,7 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + new->fl_lmops = fl->fl_lmops; }EXPORT_SYMBOL (__locks_copy_lock);
fs/locks.c void locks_copy_lock(struct file_lock *new, struct file_lock *fl) · line 295
Quoted 7 lines
fs/locks.c +0
-1@@ -290,7 +290,6 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)__locks_copy_lock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }
This looks sane to me AFAICT.
I'll run a few tests with it, and put it into I'll plan to pick this up since I have some other fs/locks.c related patches slated for 3.17.
Thanks!
Signature · 5 lines
Jeff Layton <[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] fs/locks.c: Copy fl_lmops to conflock for nfsd using
In reply to a message not in the archiveQuoted 42 lines · Jeff Layton
Quoted 39 lines · On Sat, 02 Aug 2014 22:45:17 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, nfsd4 lockowner for it always be NULL too.
This patch re-coping the
fl_lmopsto conflock.Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)fs/locks.c +1
-2@@ -279,7 +279,7 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + new->fl_lmops = fl->fl_lmops; }EXPORT_SYMBOL (__locks_copy_lock);@@ -290,7 +290,6 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)__locks_copy_lock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;
Quoted 7 lines
fs/locks.c void locks_copy_lock(struct file_lock *new, struct file_lock *fl) · line 295
Quoted 2 lines
fs/locks.c +0
-0locks_copy_private (new, fl); }This looks sane to me AFAICT.
I'll run a few tests with it, and put it into I'll plan to pick this up since I have some other
fs/locks.crelated patches slated for 3.17.
Looks like your mail and Trond's crossed? I'd need to go remind myself of the __locks_copy_lock callers, but I'm pretty sure Trond's right....
--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] fs/locks.c: Copy fl_lmops to conflock for nfsd using
In reply to a message not in the archiveQuoted 48 lines · On Tue, 5 Aug 2014 15:14:58 -0400 "J. Bruce Fields"…
Quoted 47 lines · Jeff Layton
Quoted 34 lines · On Sat, 02 Aug 2014 22:45:17 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock fornfsd4_lockalways be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock fornfsd4_locktalways be NULL too.So that, nfsd4 lockowner for it always be NULL too.
This patch re-coping the
fl_lmopsto conflock.Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)fs/locks.c +1
-1@@ -279,7 +279,7 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + new->fl_lmops = fl->fl_lmops; }EXPORT_SYMBOL (__locks_copy_lock);fs/locks.c void locks_copy_lock(struct file_lock *new, struct file_lock *fl) · line 295
Quoted 7 lines
fs/locks.c +0
-1@@ -290,7 +290,6 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)__locks_copy_lock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }This looks sane to me AFAICT.
Quoted 7 lines
Quoted 2 lines
I'll run a few tests with it, and put it into I'll plan to pick this up since I have some other
fs/locks.crelated patches slated for 3.17.Looks like your mail and Trond's crossed? I'd need to go remind myself of the
__locks_copy_lockcallers, but I'm pretty sure Trond's right....--b.
Yeah, I missed his earlier reply and have since dropped this patch. The potential race that Trond pointed out trumps the minor problem of not having conflock info, so I'm inclined to wait for a better solution to that problem.
Signature · 5 lines
Jeff Layton <[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/3 NFSD: New FL_NFSD for marking file_lock belongs to NFSD
In reply to a message not in the archiveUsing fl_flags instead of fl_lmops for marking file_lock belongs to NFSD.
--- fs/nfsd/nfs4state.c | 15 ++++----------- include/linux/fs.h | 1 + 2 files changed, 5 insertions(+), 11 deletions(-)
fs/nfsd/nfs4state.c +4 -11
@@ -4867,17 +4867,12 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; -static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {struct nfs4_lockowner *lo; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { +if (fl->fl_flags &FL_NFSD ) { lo = (struct nfs4_lockowner *) fl->fl_owner; deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );
@@ -5241,8 +5236,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lock_sop; file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);
@@ -5375,7 +5369,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);
@@ -5437,8 +5431,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,
include/linux/fs.h +1 -0
@@ -819,6 +819,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NFSD 2048/* NFSD holds this lock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/3 NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archive--- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
fs/nfsd/nfs4state.c +31 -2
@@ -4867,6 +4867,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } +static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} + +static void nfsd4_fl_copy_lock (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; +get_lockowner (lo); +} + +static void nfsd4_fl_release_lock (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; +nfs4_put_stateowner (&lo->lo_owner); +} + +static const struct file_lock_operations nfsd4_fl_lock_ops = { + .fl_copy_lock = nfsd4_fl_copy_lock, + .fl_release_private = nfsd4_fl_release_lock, +}; +static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {
@@ -5233,10 +5256,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);
@@ -5399,6 +5424,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);
@@ -5420,6 +5446,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);
@@ -5428,10 +5456,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }locks_init_lock (file_lock); file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 3/3 fs/locks.c: Copy all infomation for conflock
In reply to a message not in the archiveMake sure copy the private information by fl_copy_lock() in struct file_lock_operations, use locks_copy_lock copying all information for conflock.
--- fs/lockd/svclock.c | 2 +- fs/locks.c | 27 ++++++--------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 28 deletions(-)
fs/lockd/svclock.c +1 -1
@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }
fs/locks.c +6 -21
@@ -266,35 +266,20 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; - new->fl_ops =NULL ; - new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {
@@ -718,7 +703,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else
@@ -921,7 +906,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
include/linux/fs.h +0 -6
@@ -942,7 +942,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
@@ -1002,11 +1001,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] NFSD: New FL_NFSD for marking file_lock belongs to NFSD
In reply to Kinglong MeeQuoted 65 lines · On Wed, 06 Aug 2014 21:33:25 +0800 Kinglong Mee <[email protected]> wrote:
Using
fl_flagsinstead offl_lmopsfor markingfile_lockbelongs to NFSD.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 15 ++++----------- include/linux/fs.h | 1 + 2 files changed, 5 insertions(+), 11 deletions(-)fs/nfsd/nfs4state.c +4
-11@@ -4867,17 +4867,12 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; -static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {struct nfs4_lockowner *lo; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { +if (fl->fl_flags &FL_NFSD ) { lo = (struct nfs4_lockowner *) fl->fl_owner; deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );@@ -5241,8 +5236,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lock_sop; file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -5375,7 +5369,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);@@ -5437,8 +5431,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,include/linux/fs.h +0
-0
include/linux/fs.h static inline struct file *get_file(struct file *f) · line 825
Quoted 7 lines
include/linux/fs.h +1
-0@@ -819,6 +819,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NFSD 2048/* NFSD holds this lock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for
Honestly, I'd prefer not using a fl_flag for this. Why, might you ask?
Currently, there are two alternate lock managers in the kernel (nfsd and lockd) but there could (in principle) be an arbitrary number of them later. What's so special about knfsd that it warrants its own flag?
I think existing use of an empty lock_manager_operations is a cleaner solution than this for identifying locks owned by knfsd.
Signature · 1 line
Jeff Layton <[email protected]>
Re: [PATCH 2/3] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 73 lines · On Wed, 06 Aug 2014 21:35:40 +0800 Kinglong Mee…
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)fs/nfsd/nfs4state.c +29
-1@@ -4867,6 +4867,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } +static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} + +static void nfsd4_fl_copy_lock (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; +get_lockowner (lo); +} + +static void nfsd4_fl_release_lock (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; +nfs4_put_stateowner (&lo->lo_owner); +} + +static const struct file_lock_operations nfsd4_fl_lock_ops = { + .fl_copy_lock = nfsd4_fl_copy_lock, + .fl_release_private = nfsd4_fl_release_lock, +}; +static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {@@ -5233,10 +5256,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -5399,6 +5424,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5420,6 +5446,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);@@ -5428,10 +5456,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }locks_init_lock (file_lock);
fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5466
Quoted 10 lines
fs/nfsd/nfs4state.c +2
-1file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,
(Sorry I didn't respond to these before -- I no longer work for Red
Hat, so emails to [email protected] don't get to me).
This looks really wrong. In this case, knfsd is acting as a (server-side) lock manager, not a filesystem:
const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */
const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */
So really, taking and putting of lockowner references is really the purview of the lockmanager. If you had a filesystem that set fl_ops and was exportable, then this will likely break it.
The fact that the file locking code uses struct file_lock for lock requests and for tracking the locks themselves makes for a horribly confusing interface. If I were designing this from scratch I would have made those two distinct structures. Maybe we should do that anyway sometime.
What you probably ought want to do is to declare some new fl_lmops for taking and putting lockowner references and add hooks to call them at the appropriate places.
Signature · 5 lines
Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] NFSD: New FL_NFSD for marking file_lock belongs to NFSD
In reply to a message not in the archiveQuoted 78 lines · Jeff Layton
Quoted 65 lines · On Wed, 06 Aug 2014 21:33:25 +0800 Kinglong Mee…
Using
fl_flagsinstead offl_lmopsfor markingfile_lockbelongs to NFSD.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 15 ++++----------- include/linux/fs.h | 1 + 2 files changed, 5 insertions(+), 11 deletions(-)fs/nfsd/nfs4state.c +4
-11@@ -4867,17 +4867,12 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ -static const struct lock_manager_operations nfsd_posix_mng_ops = { -}; -static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {struct nfs4_lockowner *lo; -if (fl->fl_lmops == &nfsd_posix_mng_ops) { +if (fl->fl_flags &FL_NFSD ) { lo = (struct nfs4_lockowner *) fl->fl_owner; deny->ld_owner.data =kmemdup (lo->lo_owner.so_owner.data, lo->lo_owner.so_owner.len,GFP_KERNEL );@@ -5241,8 +5236,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lock_sop; file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -5375,7 +5369,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);@@ -5437,8 +5431,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; - file_lock->fl_flags =FL_POSIX ; - file_lock->fl_lmops = &nfsd_posix_mng_ops; + file_lock->fl_flags =FL_POSIX |FL_NFSD ; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,include/linux/fs.h +0
-0include/linux/fs.h static inline struct file *get_file(struct file *f) · line 825
Quoted 7 lines
include/linux/fs.h +1
-0@@ -819,6 +819,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NFSD 2048/* NFSD holds this lock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for Honestly, I'd prefer not using a
fl_flagfor this. Why, might you ask?
Quoted 6 lines
Currently, there are two alternate lock managers in the kernel (nfsd and lockd) but there could (in principle) be an arbitrary number of them later. What's so special about knfsd that it warrants its own flag?
I think existing use of an empty
lock_manager_operationsis a cleaner solution than this for identifying locks owned by knfsd.
Thanks for your explication.
I will drop this patch in v2.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 1/3 fs/locks.c: Copy all information for conflock
In reply to a message not in the archiveCommit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock always be NULL too.
v2: Only change the order from 3/3 to 1/3 now.
--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)
fs/lockd/svclock.c +1 -1
@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }
fs/locks.c +6 -19
@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {
@@ -718,7 +705,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else
@@ -921,7 +908,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
include/linux/fs.h +0 -6
@@ -941,7 +941,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
@@ -1001,11 +1000,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/3 fs/locks.c: New ops in file_lock_operations for copying/releasing owner
In reply to a message not in the archiveNFSD or other lockmanager may increase the owner's reference, so adds two new options for copying and releasing owner.
v2: A new patch isn't exist in v1.
--- fs/locks.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-)
fs/locks.c +10 -2
@@ -230,8 +230,12 @@ void locks_release_private(struct file_lock *fl) fl->fl_ops->fl_release_private (fl); fl->fl_ops =NULL ; } - fl->fl_lmops =NULL ; +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_release_owner) + fl->fl_lmops->lm_release_owner (fl); + fl->fl_lmops =NULL ; + } }EXPORT_SYMBOL_GPL (locks_release_private);
@@ -262,8 +266,12 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) fl->fl_ops->fl_copy_lock (new, fl); new->fl_ops = fl->fl_ops; } -if (fl->fl_lmops) + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_copy_owner) + fl->fl_lmops->lm_copy_owner (new, fl); new->fl_lmops = fl->fl_lmops; + } }void locks_copy_lock (struct file_lock *new,struct file_lock *fl)
include/linux/fs.h +2 -0
@@ -843,6 +843,8 @@ struct file_lock_operations {struct lock_manager_operations {int (*lm_compare_owner)(struct file_lock *,struct file_lock *);unsigned long (*lm_owner_key)(struct file_lock *); +void (*lm_copy_owner)(struct file_lock *,struct file_lock *); +void (*lm_release_owner)(struct file_lock *);void (*lm_notify)(struct file_lock *);/* unblock callback */ int (*lm_grant)(struct file_lock *,struct file_lock *,int );void (*lm_break)(struct file_lock *);
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 3/3 NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archivev2: Fix bad using of struct file_lock_operations for handle the owner.
--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
fs/nfsd/nfs4state.c +30 -2
@@ -4867,9 +4867,33 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } +static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} + +static void nfsd4_fl_copy_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )get_lockowner (lo); +} + +static void nfsd4_fl_release_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +/* Hack!: For now, we're defining this just so we can use a pointer to it * as a unique cookie to identify our (NFSv4's) posix locks. */ static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_copy_owner = nfsd4_fl_copy_owner, + .lm_release_owner = nfsd4_fl_release_owner, }; static inline void
@@ -5238,7 +5262,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
@@ -5405,6 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);
@@ -5426,6 +5452,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);
@@ -5434,7 +5462,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }locks_init_lock (file_lock); file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 106 lines · Jeff Layton
Quoted 73 lines · On Wed, 06 Aug 2014 21:35:40 +0800 Kinglong Mee…
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)fs/nfsd/nfs4state.c +29
-1@@ -4867,6 +4867,29 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } +static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} + +static void nfsd4_fl_copy_lock (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; +get_lockowner (lo); +} + +static void nfsd4_fl_release_lock (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; +nfs4_put_stateowner (&lo->lo_owner); +} + +static const struct file_lock_operations nfsd4_fl_lock_ops = { + .fl_copy_lock = nfsd4_fl_copy_lock, + .fl_release_private = nfsd4_fl_release_lock, +}; +static inline void nfs4_set_lock_denied (struct file_lock *fl,struct nfsd4_lock_denied *deny) {@@ -5233,10 +5256,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = lock->lk_offset; file_lock->fl_end =last_byte_offset (lock->lk_offset, lock->lk_length);nfs4_transform_lock_offset (file_lock);@@ -5399,6 +5424,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5420,6 +5446,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);@@ -5428,10 +5456,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }locks_init_lock (file_lock);fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5466
Quoted 10 lines
fs/nfsd/nfs4state.c +2
-1file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX |FL_NFSD ; + file_lock->fl_ops = &nfsd4_fl_lock_ops; file_lock->fl_start = locku->lu_offset; file_lock->fl_end = last_byte_offset(locku->lu_offset,(Sorry I didn't respond to these before -- I no longer work for Red
Hat, so emails to [email protected] don't get to me).This looks really wrong. In this case, knfsd is acting as a (server-side) lock manager, not a filesystem:
const struct
file_lock_operations*fl_ops; /* Callbacks for filesystems */
const structlock_manager_operations*fl_lmops; /* Callbacks for lockmanagers */So really, taking and putting of lockowner references is really the purview of the lockmanager. If you had a filesystem that set
fl_opsand was exportable, then this will likely break it.The fact that the file locking code uses struct
file_lockfor lock requests and for tracking the locks themselves makes for a horribly confusing interface. If I were designing this from scratch I would have made those two distinct structures. Maybe we should do that anyway sometime.
Quoted 3 lines
What you probably ought want to do is to declare some new
fl_lmopsfor taking and putting lockowner references and add hooks to call them at the appropriate places.
Sorry for my fault, a new resolve as v2 has be send. Please help have a check, thank you very much.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to a message not in the archiveQuoted 61 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-9@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl)
fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 10 lines
fs/locks.c +0
-7-{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }
(cc'ing Joe Perches)
Ok, so you're basically just reverting 1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them to locks_copy_lock.
The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from lm_grant since the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that __locks_copy_lock call altogether.
Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
Quoted 46 lines
fs/locks.c +2
-3-EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -718,7 +705,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -921,7 +908,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-6@@ -941,7 +941,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1001,11 +1000,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
Signature · 5 lines
Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to a message not in the archiveQuoted 72 lines · Jeff Layton
Quoted 69 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-16@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;
Quoted 4 lines
fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 2 lines
fs/locks.c +0
-0locks_copy_private (new, fl); }(cc'ing Joe Perches)
(cc'ing Andrew Morton too)
Quoted 7 lines
Ok, so you're basically just reverting
1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them tolocks_copy_lock.The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
Quoted 7 lines
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from
lm_grantsince the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that__locks_copy_lockcall altogether.Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
I believe Andrew is merging it.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3 v2] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 12 lines · On Sun, 10 Aug 2014 23:43:57 +0800 Kinglong Mee…
v2: Fix bad using of struct
file_lock_operationsfor handle the owner.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)fs/nfsd/nfs4state.c +0
-0
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4875
Quoted 9 lines
fs/nfsd/nfs4state.c +6
-0@@ -4867,9 +4867,33 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } +static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} +
The other places that increment the so_count on a lockowner should probably be changed to use get_lockowner.
Or what may be better is to make a nfs4_get_stateowner call and change all of the places that bump the so_count to use it. Then you could just do something like this in the right spot below:
file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(lock_sop));
...
Quoted 8 lines
fs/nfsd/nfs4state.c +8
-0+static void nfsd4_fl_copy_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )get_lockowner (lo); +} + +static void nfsd4_fl_release_owner (struct file_lock *fl) +{
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4893
Quoted 10 lines
fs/nfsd/nfs4state.c +8
-0+struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +/* Hack!: For now, we're defining this just so we can use a pointer to it * as a unique cookie to identify our (NFSv4's) posix locks. */
The above comment should be removed now.
Quoted 42 lines
static const struct
lock_manager_operationsnfsd_posix_mng_ops= {fs/nfsd/nfs4state.c +8
-2+ .lm_copy_owner = nfsd4_fl_copy_owner, + .lm_release_owner = nfsd4_fl_release_owner, }; static inline void@@ -5238,7 +5262,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;@@ -5405,6 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5426,6 +5452,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);@@ -5434,7 +5462,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }locks_init_lock (file_lock); file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Signature · 5 lines
Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to a message not in the archiveQuoted 77 lines · Jeff Layton
Quoted 61 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-9@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl)fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 10 lines
fs/locks.c +0
-7-{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }(cc'ing Joe Perches)
Quoted 6 lines
Ok, so you're basically just reverting
1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them tolocks_copy_lock.The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
I don't think so.locks_alloc_lock() has initialize the file_lock struct, the same as locks_init_lock().
I will clean the duplicate initialize for file_lock in nfs4state.c in v3.
Quoted 7 lines
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from
lm_grantsince the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that__locks_copy_lockcall altogether.Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
I will update this patch based on that patch and your new patch for locks.c.
thanks,
Kinglong Mee
Quoted 39 lines
Quoted 39 lines
fs/locks.c +2
-3-EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -718,7 +705,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -921,7 +908,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -941,7 +941,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1001,11 +1000,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; }
Quoted 10 lines
include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1005
Quoted 8 lines
include/linux/fs.h +0
-5-static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3 v2] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 18 lines · Jeff Layton
Quoted 15 lines · On Sun, 10 Aug 2014 23:43:57 +0800 Kinglong Mee…
v2: Fix bad using of struct
file_lock_operationsfor handle the owner.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)fs/nfsd/nfs4state.c +0
-0@@ -4867,9 +4867,33 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; }
Quoted 9 lines
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4875
Quoted 6 lines
fs/nfsd/nfs4state.c +6
-0+static inline struct nfs4_lockowner *get_lockowner (struct nfs4_lockowner *lo) +{ +atomic_inc (&lo->lo_owner.so_count); +return lo; +} +The other places that increment the
so_counton a lockowner should probably be changed to useget_lockowner.
Got it, thanks.
Quoted 6 lines
Or what may be better is to make a
nfs4_get_stateownercall and change all of the places that bump theso_countto use it. Then you could just do something like this in the right spot below:file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(lock_sop));
Yes, nfs4_get_stateowner corresponds with nfs4_put_stateowner.
Quoted 12 lines
Quoted 12 lines
fs/nfsd/nfs4state.c +12
-0+static void nfsd4_fl_copy_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )get_lockowner (lo); +} + +static void nfsd4_fl_release_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner);
Quoted 8 lines
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4893
Quoted 6 lines
fs/nfsd/nfs4state.c +4
-0+ fl->fl_owner =NULL ; + } +} +/* Hack!: For now, we're defining this just so we can use a pointer to it * as a unique cookie to identify our (NFSv4's) posix locks. */ The above comment should be removed now.
OK, will remove it in next version.
thanks,
Kinglong Mee
Quoted 35 lines
Quoted 35 lines
fs/nfsd/nfs4state.c +7
-1static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_copy_owner = nfsd4_fl_copy_owner, + .lm_release_owner = nfsd4_fl_release_owner, }; static inline void@@ -5238,7 +5262,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;@@ -5405,6 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5426,6 +5452,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);@@ -5434,7 +5462,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
Quoted 10 lines
fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5468
Quoted 8 lines
fs/nfsd/nfs4state.c +1
-1}locks_init_lock (file_lock); file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to Joe PerchesQuoted 92 lines · Joe Perches
Quoted 72 lines · Jeff Layton
Quoted 69 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-16@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;Quoted 4 lines
fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 2 lines
fs/locks.c +0
-0locks_copy_private (new, fl); }(cc'ing Joe Perches)
(cc'ing Andrew Morton too)
Quoted 12 lines
Ok, so you're basically just reverting
1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them tolocks_copy_lock.The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from
lm_grantsince the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that__locks_copy_lockcall altogether.
Quoted 4 lines
Quoted 2 lines
Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
I believe Andrew is merging it.
Sorry for I don't known Andrew's git tree,
Can you offer me? Thank you very much.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to Kinglong MeeQuoted 82 lines · On Thu, 14 Aug 2014 20:26:03 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 81 lines · Jeff Layton
Quoted 61 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-9@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl)fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 10 lines
fs/locks.c +0
-7-{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }(cc'ing Joe Perches)
Ok, so you're basically just reverting
1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them tolocks_copy_lock.
Quoted 9 lines
Quoted 2 lines
The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
I don't think so.
locks_alloc_lock()has initialize thefile_lockstruct, the same aslocks_init_lock().I will clean the duplicate initialize for
file_lockinnfs4state.cin v3.
Ahh, you're correct. Yes, please just remove that instead. You might also want to look for other places in the kernel that call locks_init_lock unnecessarily. We might as well get rid of all of them while we're looking.
Quoted 5 lines
Quoted 5 lines
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from
lm_grantsince the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that__locks_copy_lockcall altogether.
Quoted 8 lines
Quoted 2 lines
Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
I will update this patch based on that patch and your new patch for
locks.c.thanks,
Kinglong Mee
Thanks. I wiggled Joe's patch on top of my current set of locking patches and will plan to merge it for v3.18 unless there are any objections.
Quoted 53 lines
Quoted 39 lines
Quoted 39 lines
fs/locks.c +2
-3-EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -718,7 +705,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -921,7 +908,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -941,7 +941,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1001,11 +1000,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; }Quoted 10 lines
include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1005
Quoted 8 lines
include/linux/fs.h +0
-5-static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Jeff Layton <[email protected]>
Re: [PATCH 1/3 v2] fs/locks.c: Copy all information for conflock
In reply to a message not in the archiveQuoted 92 lines · Jeff Layton
Quoted 89 lines · On Thu, 14 Aug 2014 20:26:03 +0800 Kinglong Mee…
Quoted 77 lines · Jeff Layton
Quoted 61 lines · On Sun, 10 Aug 2014 23:38:25 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.v2: Only change the order from 3/3 to 1/3 now.
Signed-off-by Kinglong Mee <[email protected]>--- fs/lockd/svclock.c | 2 +- fs/locks.c | 25 ++++++------------------- include/linux/fs.h | 6 ------ 3 files changed, 7 insertions(+), 26 deletions(-)fs/lockd/svclock.c +1
-1@@ -677,7 +677,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, block->b_flags |=B_TIMED_OUT ;if (conf) {if (block->b_fl) -__locks_copy_lock (block->b_fl, conf); +locks_copy_lock (block->b_fl, conf); } }fs/locks.c +4
-9@@ -266,35 +266,22 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_lmops = fl->fl_lmops; } -/* -* Initialize a new lock from an existing file_lock structure. -*/ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +locks_release_private (new); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl)fs/locks.c static void locks_copy_private(struct file_lock *new, struct file_lock *fl) · line 284
Quoted 10 lines
fs/locks.c +0
-7-{ -locks_release_private (new); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); }(cc'ing Joe Perches)
Quoted 6 lines
Ok, so you're basically just reverting
1a747ee0cc11a19. The catch there is that you now need to ensure that any conflock structures are properly initialized before passing them tolocks_copy_lock.The nfsv4 server code currently doesn't do that and it will need to be fixed to do so or that will be a regression.
I don't think so.
locks_alloc_lock()has initialize thefile_lockstruct, the same aslocks_init_lock().
Quoted 7 lines
Quoted 2 lines
I will clean the duplicate initialize for
file_lockinnfs4state.cin v3.Ahh, you're correct. Yes, please just remove that instead. You might also want to look for other places in the kernel that call
locks_init_lockunnecessarily. We might as well get rid of all of them while we're looking.
OK, I will review those codes where calling locks_init_lock().
Quoted 11 lines
Quoted 11 lines
Quoted 8 lines
For the NLM code, Joe Perches has proposed a patch to remove the conflock parameter from
lm_grantsince the callers always pass in NULL anyway. You may want to pull in his patch and rebase yours on top of it since it'll remove that__locks_copy_lockcall altogether.Joe, is Andrew merging that patch or do I need to pull it into the locks tree?
I will update this patch based on that patch and your new patch for
locks.c.
Quoted 7 lines
Quoted 3 lines
thanks,
Kinglong MeeThanks. I wiggled Joe's patch on top of my current set of locking patches and will plan to merge it for v3.18 unless there are any objections.
I saw your patch, thank you very much.
thanks,
Kinglong Mee
Quoted 50 lines
Quoted 50 lines
Quoted 50 lines
Quoted 48 lines
fs/locks.c +2
-3-EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -718,7 +705,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -921,7 +908,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-6@@ -941,7 +941,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1001,11 +1000,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
Quoted 6 lines
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 1/5 NFSD: Remove duplicate initialization of file_lock
In reply to a message not in the archivelocks_alloc_lock() has initialize struct file_lock, don't need re-initialize it by locks_init_lock().
v3: A new patch isn't exit in v2/v1.
--- fs/nfsd/nfs4state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +2 -4
@@ -3759,7 +3759,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) fl =locks_alloc_lock ();if (!fl)return NULL ; -locks_init_lock (fl); fl->fl_lmops = &nfsd_lease_mng_ops; fl->fl_flags =FL_DELEG ; fl->fl_type = flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK ;
@@ -5210,7 +5209,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } fp = lock_stp->st_stid.sc_file; -locks_init_lock (file_lock);switch (lock->lk_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5354,7 +5352,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto out; } -locks_init_lock (file_lock); +switch (lockt->lt_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5432,7 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto fput; } -locks_init_lock (file_lock); + file_lock->fl_type =F_UNLCK ; file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 2/5 locks: Copy all infomation for conflock
In reply to Kinglong MeeCommit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock always be NULL too.
Make sure copy the private information by fl_copy_lock() in struct file_lock_operations, merge __locks_copy_lock() to fl_copy_lock().
v3: Update based on Joe and Jeff's patch.
--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)
fs/locks.c +7 -17
@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {
@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else
@@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
include/linux/fs.h +0 -6
@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
Signature · 1 line
1.9.3
PATCH v3 3/5 locks: New ops in file_lock_operations for copy/release owner
In reply to a message not in the archiveNFSD or other lockmanager may increase the owner's reference, so adds two new options for copying and releasing owner.
v3: same as v2, isn't exist in v1.
--- fs/locks.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-)
fs/locks.c +10 -2
@@ -230,8 +230,12 @@ void locks_release_private(struct file_lock *fl) fl->fl_ops->fl_release_private (fl); fl->fl_ops =NULL ; } - fl->fl_lmops =NULL ; +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_release_owner) + fl->fl_lmops->lm_release_owner (fl); + fl->fl_lmops =NULL ; + } }EXPORT_SYMBOL_GPL (locks_release_private);
@@ -274,8 +278,12 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) fl->fl_ops->fl_copy_lock (new, fl); new->fl_ops = fl->fl_ops; } -if (fl->fl_lmops) + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_copy_owner) + fl->fl_lmops->lm_copy_owner (new, fl); new->fl_lmops = fl->fl_lmops; + } }/*
include/linux/fs.h +2 -0
@@ -868,6 +868,8 @@ struct file_lock_operations {struct lock_manager_operations {int (*lm_compare_owner)(struct file_lock *,struct file_lock *);unsigned long (*lm_owner_key)(struct file_lock *); +void (*lm_copy_owner)(struct file_lock *,struct file_lock *); +void (*lm_release_owner)(struct file_lock *);void (*lm_notify)(struct file_lock *);/* unblock callback */ int (*lm_grant)(struct file_lock *,int );void (*lm_break)(struct file_lock *);
Signature · 7 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 4/5 NFSD: New helper nfs4_get_stateowner() for atomic_inc reference
In reply to Kinglong Meev3: new patch isn't exist in v2/v1.
--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
fs/nfsd/nfs4state.c +16 -16
@@ -216,6 +216,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses)spin_unlock (&nn->client_lock); } +static inline struct nfs4_stateowner * +nfs4_get_stateowner (struct nfs4_stateowner *sop) +{ +atomic_inc (&sop->so_count); +return sop; +} +static int same_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner) {
@@ -235,10 +242,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, so_strhash) {if (!so->so_is_open_owner)continue ; -if (same_owner_str (so, &open->op_owner)) { -atomic_inc (&so->so_count); -return openowner (so); - } +if (same_owner_str (so, &open->op_owner)) +return openowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -1644,7 +1649,7 @@ __destroy_client(struct nfs4_client *clp) }while (!list_empty (&clp->cl_openowners)) { oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); -atomic_inc (&oo->oo_owner.so_count); +nfs4_get_stateowner (&oo->oo_owner);release_openowner (oo); }nfsd4_shutdown_callback (clp);
@@ -3125,8 +3130,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate, {if (!nfsd4_has_session (cstate)) {mutex_lock (&so->so_replay.rp_mutex); - cstate->replay_owner = so; -atomic_inc (&so->so_count); + cstate->replay_owner =nfs4_get_stateowner (so); } }
@@ -3225,8 +3229,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_OPEN_STID ;INIT_LIST_HEAD (&stp->st_locks); - stp->st_stateowner = &oo->oo_owner; -atomic_inc (&stp->st_stateowner->so_count); + stp->st_stateowner =nfs4_get_stateowner (&oo->oo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_access_bmap =0 ;
@@ -4914,10 +4917,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner, so_strhash) {if (so->so_is_open_owner)continue ; -if (!same_owner_str (so, owner)) -continue ; -atomic_inc (&so->so_count); -return lockowner (so); +if (same_owner_str (so, owner)) +return lockowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -4996,8 +4997,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_LOCK_STID ; - stp->st_stateowner = &lo->lo_owner; -atomic_inc (&lo->lo_owner.so_count); + stp->st_stateowner =nfs4_get_stateowner (&lo->lo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_stid.sc_free = nfs4_free_lock_stateid;
@@ -5539,7 +5539,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, } } -atomic_inc (&sop->so_count); +nfs4_get_stateowner (sop);break ; }spin_unlock (&clp->cl_lock);
Signature · 1 line
1.9.3
PATCH v3 5/5 NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archivev3: Update based on Jeff's comments
v2: Fix bad using of struct file_lock_operations for handle the owner.
--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +30 -4
@@ -4869,9 +4869,31 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static inline struct nfs4_lockowner * +nfs4_get_lockowner (struct nfs4_lockowner *lo) +{ +return lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} + +static void nfsd4_fl_copy_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )nfs4_get_lockowner (lo); +} + +static void nfsd4_fl_release_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_copy_owner = nfsd4_fl_copy_owner, + .lm_release_owner = nfsd4_fl_release_owner, }; static inline void
@@ -5236,7 +5258,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
@@ -5403,6 +5426,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);
@@ -5424,6 +5448,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);
@@ -5432,7 +5458,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Signature · 7 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Jeff Layton
Reviewed-byRe: [PATCH 1/5 v3] NFSD: Remove duplicate initialization of file_lock
In reply to a message not in the archiveQuoted 40 lines · On Fri, 15 Aug 2014 08:02:55 +0800 Kinglong Mee…
locks_alloc_lock()has initialize structfile_lock, don't need re-initialize it bylocks_init_lock().v3: A new patch isn't exit in v2/v1.
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)fs/nfsd/nfs4state.c +1
-3@@ -3759,7 +3759,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) fl =locks_alloc_lock ();if (!fl)return NULL ; -locks_init_lock (fl); fl->fl_lmops = &nfsd_lease_mng_ops; fl->fl_flags =FL_DELEG ; fl->fl_type = flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK ;@@ -5210,7 +5209,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } fp = lock_stp->st_stid.sc_file; -locks_init_lock (file_lock);switch (lock->lk_type) {case NFS4_READ_LT :case NFS4_READW_LT :@@ -5354,7 +5352,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto out; } -locks_init_lock (file_lock); +switch (lockt->lt_type) {case NFS4_READ_LT :case NFS4_READW_LT :
fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5436
Quoted 8 lines
fs/nfsd/nfs4state.c +1
-1@@ -5432,7 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto fput; } -locks_init_lock (file_lock); + file_lock->fl_type =F_UNLCK ; file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid;
Bruce, since this is an nfsd patch, do you mind picking this one up?
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
In reply to a message not in the archiveQuoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;
include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;
I'm not sure this is really what you want to do. Calling fl_copy_lock for a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing with fl_ops for a conflock.
Also in the case of fcntl_getlk, the struct file_lock lives on the stack, and locks_release_private is never called on it. You'll need to audit all of the current callers of __locks_copy_lock to ensure that any resources you end up taking references on when copying the conflock are eventually released.
Signature · 5 lines
Jeff Layton <jlayton-7I+n7zu2hftEKMMhf/[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
In reply to a message not in the archiveQuoted 115 lines · Jeff Layton
Quoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;I'm not sure this is really what you want to do. Calling
fl_copy_lockfor a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing withfl_opsfor a conflock.
Quoted 5 lines
Also in the case of
fcntl_getlk, the structfile_locklives on the stack, andlocks_release_privateis never called on it. You'll need to audit all of the current callers of__locks_copy_lockto ensure that any resources you end up taking references on when copying the conflock are eventually released.
Sorry for my no further think about it.
I will check that again next day.
Thanks for your comment again.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5 v3] NFSD: Remove duplicate initialization of file_lock
In reply to a message not in the archiveQuoted 54 lines · Jeff Layton
Quoted 40 lines · On Fri, 15 Aug 2014 08:02:55 +0800 Kinglong Mee…
locks_alloc_lock()has initialize structfile_lock, don't need re-initialize it bylocks_init_lock().v3: A new patch isn't exit in v2/v1.
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)fs/nfsd/nfs4state.c +1
-3@@ -3759,7 +3759,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) fl =locks_alloc_lock ();if (!fl)return NULL ; -locks_init_lock (fl); fl->fl_lmops = &nfsd_lease_mng_ops; fl->fl_flags =FL_DELEG ; fl->fl_type = flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK ;@@ -5210,7 +5209,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } fp = lock_stp->st_stid.sc_file; -locks_init_lock (file_lock);switch (lock->lk_type) {case NFS4_READ_LT :case NFS4_READW_LT :@@ -5354,7 +5352,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto out; } -locks_init_lock (file_lock); +switch (lockt->lt_type) {case NFS4_READ_LT :case NFS4_READW_LT :fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5436
Quoted 8 lines
fs/nfsd/nfs4state.c +1
-1@@ -5432,7 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto fput; } -locks_init_lock (file_lock); + file_lock->fl_type =F_UNLCK ; file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid;Bruce, since this is an nfsd patch, do you mind picking this one up?
Quoted 1 line
Yep, got it, thanks!
--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
In reply to a message not in the archiveQuoted 116 lines · Kinglong Mee
Quoted 115 lines · Jeff Layton
Quoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;I'm not sure this is really what you want to do. Calling
fl_copy_lockfor a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing withfl_opsfor a conflock.
Quoted 8 lines
Quoted 5 lines
Also in the case of
fcntl_getlk, the structfile_locklives on the stack, andlocks_release_privateis never called on it. You'll need to audit all of the current callers of__locks_copy_lockto ensure that any resources you end up taking references on when copying the conflock are eventually released.Sorry for my no further think about it.
I will check that again next day.
I think we should not change the logical of coping lock, leave fl_ops and fl_lmops as private data as right now.
I have plan to,
1. move fl_owner assign from __locks_copy_lock() to locks_copy_private(), I think it should be a private data, am I right?
2. call locks_copy_private() coping private data specifically. a. add an argument for posix_test_lock() and __posix_lock_file() and etc, to point whether coping private data.
b. hack the conflock's fl_flags to do the same thing as a,
adds FL_NEED_PRIV fl_flags only valid for conflock.
I don't think 2.a is a nice resolve, because it changes the interface and many caller don't care the private data (I think contains fl_owner) for conflock except nfsd.
So, I'd like *2.b*. A draft is appended as following,
thanks,
Kinglong Mee
------------------snip--------------------------
fs/locks.c +12 -3
@@ -282,6 +282,8 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)if (fl->fl_lmops) {if (fl->fl_lmops->lm_copy_owner) fl->fl_lmops->lm_copy_owner (new, fl); +else + new->fl_owner = fl->fl_owner; new->fl_lmops = fl->fl_lmops; } }
@@ -291,7 +293,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)*/ void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) { - new->fl_owner = fl->fl_owner; + new->fl_owner =NULL ; new->fl_pid = fl->fl_pid; new->fl_file =NULL ; new->fl_flags = fl->fl_flags;
@@ -734,6 +736,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl) {struct file_lock *cfl;struct inode *inode =file_inode (filp); +bool need_priv = !!(fl->fl_flags &FL_NEED_PRIV );spin_lock (&inode->i_lock);for (cfl =file_inode (filp)->i_flock; cfl; cfl = cfl->fl_next) {
@@ -746,6 +749,8 @@ posix_test_lock(struct file *filp, struct file_lock *fl)__locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); +if (need_priv) +locks_copy_private (fl, cfl); }else fl->fl_type =F_UNLCK ;spin_unlock (&inode->i_lock);
@@ -919,7 +924,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strstruct file_lock *right =NULL ;struct file_lock **before;int error; -bool added = false; +bool added = false, need_priv = false;LIST_HEAD (dispose);/*
@@ -948,8 +953,12 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strcontinue ;if (!posix_locks_conflict (request, fl))continue ; -if (conflock) +if (conflock) { + need_priv = !!(conflock->fl_flags &FL_NEED_PRIV );__locks_copy_lock (conflock, fl); +if (need_priv) +locks_copy_private (conflock, fl); + } error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
fs/nfsd/nfs4state.c +2 -1
@@ -5275,6 +5275,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; } + conflock->fl_flags =FL_NEED_PRIV ; err =vfs_lock_file (filp,F_SETLK , file_lock, conflock);switch (-err) {case 0 :/* success! */
@@ -5396,7 +5397,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NEED_PRIV ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);
include/linux/fs.h +1 -0
@@ -844,6 +844,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NEED_PRIV 2048/* Need copy private data from conflock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
In reply to a message not in the archiveQuoted 138 lines · Kinglong Mee
Quoted 116 lines · Kinglong Mee
Quoted 115 lines · Jeff Layton
Quoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;I'm not sure this is really what you want to do. Calling
fl_copy_lockfor a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing withfl_opsfor a conflock.Quoted 8 lines
Quoted 5 lines
Also in the case of
fcntl_getlk, the structfile_locklives on the stack, andlocks_release_privateis never called on it. You'll need to audit all of the current callers of__locks_copy_lockto ensure that any resources you end up taking references on when copying the conflock are eventually released.Sorry for my no further think about it.
I will check that again next day.I think we should not change the logical of coping lock, leave
fl_opsandfl_lmopsas private data as right now.I have plan to,
1. movefl_ownerassign from__locks_copy_lock()tolocks_copy_private(), I think it should be a private data, am I right?
2. calllocks_copy_private()coping private data specifically. a. add an argument forposix_test_lock()and__posix_lock_file()and etc, to point whether coping private data.
b. hack the conflock'sfl_flagsto do the same thing as a,
addsFL_NEED_PRIVfl_flagsonly valid for conflock.
Quoted 5 lines
I don't think 2.a is a nice resolve, because it changes the interface and many caller don't care the private data (I think contains
fl_owner) for conflock except nfsd.So, I'd like *2.b*. A draft is appended as following,
I'm so sorry for the first draft, there is a bug of it. Please using the new draft.
thanks,
Kinglong Mee
------------------snip---------------------------------------------------------
fs/locks.c +11 -3
@@ -279,6 +279,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_ops = fl->fl_ops; } + new->fl_owner = fl->fl_owner;if (fl->fl_lmops) {if (fl->fl_lmops->lm_copy_owner) fl->fl_lmops->lm_copy_owner (new, fl);
@@ -291,7 +292,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)*/ void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) { - new->fl_owner = fl->fl_owner; + new->fl_owner =NULL ; new->fl_pid = fl->fl_pid; new->fl_file =NULL ; new->fl_flags = fl->fl_flags;
@@ -734,6 +735,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl) {struct file_lock *cfl;struct inode *inode =file_inode (filp); +bool need_priv = !!(fl->fl_flags &FL_NEED_PRIV );spin_lock (&inode->i_lock);for (cfl =file_inode (filp)->i_flock; cfl; cfl = cfl->fl_next) {
@@ -746,6 +748,8 @@ posix_test_lock(struct file *filp, struct file_lock *fl)__locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); +if (need_priv) +locks_copy_private (fl, cfl); }else fl->fl_type =F_UNLCK ;spin_unlock (&inode->i_lock);
@@ -919,7 +923,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strstruct file_lock *right =NULL ;struct file_lock **before;int error; -bool added = false; +bool added = false, need_priv = false;LIST_HEAD (dispose);/*
@@ -948,8 +952,12 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strcontinue ;if (!posix_locks_conflict (request, fl))continue ; -if (conflock) +if (conflock) { + need_priv = !!(conflock->fl_flags &FL_NEED_PRIV );__locks_copy_lock (conflock, fl); +if (need_priv) +locks_copy_private (conflock, fl); + } error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
fs/nfsd/nfs4state.c +2 -1
@@ -5275,6 +5275,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; } + conflock->fl_flags =FL_NEED_PRIV ; err =vfs_lock_file (filp,F_SETLK , file_lock, conflock);switch (-err) {case 0 :/* success! */
@@ -5396,7 +5397,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NEED_PRIV ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);
include/linux/fs.h +1 -0
@@ -844,6 +844,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NEED_PRIV 2048/* Need copy private data from conflock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
In reply to a message not in the archiveQuoted 124 lines · On Sun, 17 Aug 2014 21:42:21 +0800 Kinglong Mee…
Quoted 123 lines · Kinglong Mee
Quoted 122 lines · Kinglong Mee
Quoted 120 lines · Jeff Layton
Quoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee…
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;I'm not sure this is really what you want to do. Calling
fl_copy_lockfor a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing withfl_opsfor a conflock.Also in the case of
fcntl_getlk, the structfile_locklives on the stack, andlocks_release_privateis never called on it. You'll need to audit all of the current callers of__locks_copy_lockto ensure that any resources you end up taking references on when copying the conflock are eventually released.
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Sorry for my no further think about it.
I will check that again next day.I think we should not change the logical of coping lock, leave
fl_opsandfl_lmopsas private data as right now.
Why not? I think we'd benefit from making conflock creation a more distinct operation.
Quoted 14 lines
Quoted 14 lines
I have plan to,
1. movefl_ownerassign from__locks_copy_lock()tolocks_copy_private(), I think it should be a private data, am I right?
2. calllocks_copy_private()coping private data specifically. a. add an argument forposix_test_lock()and__posix_lock_file()and etc, to point whether coping private data.
b. hack the conflock'sfl_flagsto do the same thing as a,
addsFL_NEED_PRIVfl_flagsonly valid for conflock.I don't think 2.a is a nice resolve, because it changes the interface and many caller don't care the private data (I think contains
fl_owner) for conflock except nfsd.
Quoted 8 lines
Quoted 1 line
So, I'd like *2.b*. A draft is appended as following,
I'm so sorry for the first draft, there is a bug of it. Please using the new draft.
thanks,
Kinglong Mee
Personally, I'm not a fan of the approach below. I don't think we need a new flag for this and it doesn't do anything to solve the problem where the lockowner could go away while you're operating on it in a conflock.
I think we need several smaller changes:
1. Right now __locks_copy_lock is only used to copy conflocks. It would be good to rename that to something more distinct (i.e. locks_copy_conflock), to make it clear that we're generating a conflock there.
2. Set fl_lmops on conflocks, but don't set fl_ops. fl_ops are superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by the fl_lmops. So you really do want to copy the fl_lmops for conflocks I think.
3. Add the operations you added before to fl_lmops to copy and release the owner (maybe even rename them lm_get_owner/lm_put_owner?), and ensure that the places that copy conflocks call those operations appropriately.
That should be all that's required here.
Quoted 101 lines
------------------snip---------------------------------------------------------
fs/locks.c +11
-3@@ -279,6 +279,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) new->fl_ops = fl->fl_ops; } + new->fl_owner = fl->fl_owner;if (fl->fl_lmops) {if (fl->fl_lmops->lm_copy_owner) fl->fl_lmops->lm_copy_owner (new, fl);@@ -291,7 +292,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)*/ void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) { - new->fl_owner = fl->fl_owner; + new->fl_owner =NULL ; new->fl_pid = fl->fl_pid; new->fl_file =NULL ; new->fl_flags = fl->fl_flags;@@ -734,6 +735,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl) {struct file_lock *cfl;struct inode *inode =file_inode (filp); +bool need_priv = !!(fl->fl_flags &FL_NEED_PRIV );spin_lock (&inode->i_lock);for (cfl =file_inode (filp)->i_flock; cfl; cfl = cfl->fl_next) {@@ -746,6 +748,8 @@ posix_test_lock(struct file *filp, struct file_lock *fl)__locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); +if (need_priv) +locks_copy_private (fl, cfl); }else fl->fl_type =F_UNLCK ;spin_unlock (&inode->i_lock);@@ -919,7 +923,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strstruct file_lock *right =NULL ;struct file_lock **before;int error; -bool added = false; +bool added = false, need_priv = false;LIST_HEAD (dispose);/* @@ -948,8 +952,12 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strcontinue ;if (!posix_locks_conflict (request, fl))continue ; -if (conflock) +if (conflock) { + need_priv = !!(conflock->fl_flags &FL_NEED_PRIV );__locks_copy_lock (conflock, fl); +if (need_priv) +locks_copy_private (conflock, fl); + } error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;fs/nfsd/nfs4state.c +2
-1@@ -5275,6 +5275,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; } + conflock->fl_flags =FL_NEED_PRIV ; err =vfs_lock_file (filp,F_SETLK , file_lock, conflock);switch (-err) {case 0 :/* success! */ @@ -5396,7 +5397,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (lo) file_lock->fl_owner = (fl_owner_t )lo; file_lock->fl_pid = current->tgid; - file_lock->fl_flags =FL_POSIX ; + file_lock->fl_flags =FL_POSIX |FL_NEED_PRIV ; file_lock->fl_start = lockt->lt_offset; file_lock->fl_end =last_byte_offset (lockt->lt_offset, lockt->lt_length);include/linux/fs.h +1
-1@@ -844,6 +844,7 @@ static inline struct file *get_file(struct file *f)#define FL_DOWNGRADE_PENDING 256/* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512/* Lease is being broken */ #define FL_OFDLCK 1024/* lock is "owned" by struct file */ +#define FL_NEED_PRIV 2048/* Need copy private data from conflock */ /* * Special return value from posix_lock_file() and vfs_lock_file() for -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 5 lines
Jeff Layton <[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5 v3] locks: Copy all infomation for conflock
Quoted 155 lines · Jeff Layton
Quoted 124 lines · On Sun, 17 Aug 2014 21:42:21 +0800 Kinglong Mee <[email protected]> wrote:
Quoted 123 lines · Kinglong Mee
Quoted 122 lines · Kinglong Mee
Quoted 120 lines · Jeff Layton
Quoted 95 lines · On Fri, 15 Aug 2014 08:07:12 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().v3: Update based on Joe and Jeff's patch.
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 24 +++++++----------------- include/linux/fs.h | 6 ------ 2 files changed, 7 insertions(+), 23 deletions(-)fs/locks.c +7
-17@@ -281,33 +281,23 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_lock (struct file_lock *new,struct file_lock *fl) { +/* "new" must be a freshly-initialized lock */ +WARN_ON_ONCE (new->fl_ops); + new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file =NULL ; + new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; new->fl_ops =NULL ; new->fl_lmops =NULL ; -} -EXPORT_SYMBOL (__locks_copy_lock); - -void locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -/* "new" must be a freshly-initialized lock */ -WARN_ON_ONCE (new->fl_ops); - -__locks_copy_lock (new, fl); - new->fl_file = fl->fl_file; - new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops;locks_copy_private (new, fl); } -EXPORT_SYMBOL (locks_copy_lock);static inline int flock_translate_cmd (int cmd) {@@ -735,7 +725,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_lock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -941,7 +931,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_lock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +0
-1@@ -966,7 +966,6 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);@@ -1026,11 +1025,6 @@ static inline void locks_init_lock(struct file_lock *fl)return ;include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1030
Quoted 10 lines
include/linux/fs.h +0
-5} -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) -{ -return ; -} -static inline void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {return ;I'm not sure this is really what you want to do. Calling
fl_copy_lockfor a conflock looks relatively harmless for nfs and nlm. AFS though seems to add the lock to a list associated with the inode. That seems a little suspicious for a conflock and could be problematic. It may be best to avoid dealing withfl_opsfor a conflock.Also in the case of
fcntl_getlk, the structfile_locklives on the stack, andlocks_release_privateis never called on it. You'll need to audit all of the current callers of__locks_copy_lockto ensure that any resources you end up taking references on when copying the conflock are eventually released.Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Sorry for my no further think about it.
I will check that again next day.I think we should not change the logical of coping lock, leave
fl_opsandfl_lmopsas private data as right now.Why not? I think we'd benefit from making conflock creation a more distinct operation.
Quoted 19 lines
Quoted 10 lines
I have plan to,
1. movefl_ownerassign from__locks_copy_lock()tolocks_copy_private(), I think it should be a private data, am I right?
2. calllocks_copy_private()coping private data specifically. a. add an argument forposix_test_lock()and__posix_lock_file()and etc, to point whether coping private data.
b. hack the conflock'sfl_flagsto do the same thing as a,
addsFL_NEED_PRIVfl_flagsonly valid for conflock.Quoted 5 lines
I don't think 2.a is a nice resolve, because it changes the interface and many caller don't care the private data (I think contains
fl_owner) for conflock except nfsd.So, I'd like *2.b*. A draft is appended as following,
I'm so sorry for the first draft, there is a bug of it. Please using the new draft.
Quoted 8 lines
Quoted 3 lines
thanks,
Kinglong MeePersonally, I'm not a fan of the approach below. I don't think we need a new flag for this and it doesn't do anything to solve the problem where the lockowner could go away while you're operating on it in a conflock.
I just want fix the bug with minimal code change.
But, I known my fault now.
Quoted 15 lines
I think we need several smaller changes:
1. Right now
__locks_copy_lockis only used to copy conflocks. It would be good to rename that to something more distinct (i.e.locks_copy_conflock), to make it clear that we're generating a conflock there.2. Set
fl_lmopson conflocks, but don't setfl_ops.fl_opsare superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by thefl_lmops. So you really do want to copy thefl_lmopsfor conflocks I think.
Quoted 6 lines
3. Add the operations you added before to
fl_lmopsto copy and release the owner (maybe even rename them lm_get_owner/lm_put_owner?), and ensure that the places that copy conflocks call those operations appropriately.That should be all that's required here.
I think I know what you are advice.
I will send an update patch as v4.
thanks,
Kinglong Mee
PATCH v4 1/6 NFSD: Remove the duplicate initialize of file_lock
In reply to a message not in the archivelocks_alloc_lock() has initialize the struct file_lock, so, don't need re-initialize it by locks_init_lock().
v4: same as v3, only cleanup
--- fs/nfsd/nfs4state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +2 -4
@@ -3759,7 +3759,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) fl =locks_alloc_lock ();if (!fl)return NULL ; -locks_init_lock (fl); fl->fl_lmops = &nfsd_lease_mng_ops; fl->fl_flags =FL_DELEG ; fl->fl_type = flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK ;
@@ -5210,7 +5209,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } fp = lock_stp->st_stid.sc_file; -locks_init_lock (file_lock);switch (lock->lk_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5354,7 +5352,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto out; } -locks_init_lock (file_lock); +switch (lockt->lt_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5432,7 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto fput; } -locks_init_lock (file_lock); + file_lock->fl_type =F_UNLCK ; file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v4 2/6 locks: New ops in file_lock_operations for get/put owner
In reply to Kinglong MeeNFSD or other lockmanager may increase the owner's reference, so adds two new options for copying and releasing owner.
v4: rename lm_copy_owner/lm_release_owner to lm_get_owner/lm_put_owner
--- fs/locks.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-)
fs/locks.c +10 -2
@@ -230,8 +230,12 @@ void locks_release_private(struct file_lock *fl) fl->fl_ops->fl_release_private (fl); fl->fl_ops =NULL ; } - fl->fl_lmops =NULL ; +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_put_owner) + fl->fl_lmops->lm_put_owner (fl); + fl->fl_lmops =NULL ; + } }EXPORT_SYMBOL_GPL (locks_release_private);
@@ -274,8 +278,12 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) fl->fl_ops->fl_copy_lock (new, fl); new->fl_ops = fl->fl_ops; } -if (fl->fl_lmops) + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); new->fl_lmops = fl->fl_lmops; + } }/*
include/linux/fs.h +2 -0
@@ -868,6 +868,8 @@ struct file_lock_operations {struct lock_manager_operations {int (*lm_compare_owner)(struct file_lock *,struct file_lock *);unsigned long (*lm_owner_key)(struct file_lock *); +void (*lm_get_owner)(struct file_lock *,struct file_lock *); +void (*lm_put_owner)(struct file_lock *);void (*lm_notify)(struct file_lock *);/* unblock callback */ int (*lm_grant)(struct file_lock *,int );void (*lm_break)(struct file_lock *);
Signature · 1 line
1.9.3
PATCH v4 3/6 locks: Rename __locks_copy_lock() to locks_copy_conflock()
In reply to Kinglong MeeJeff advice, " Right now __locks_copy_lock is only used to copy conflocks. It would be good to rename that to something more distinct (i.e.locks_copy_conflock), to make it clear that we're generating a conflock there."
v4: a new patch only rename
--- fs/locks.c | 10 +++++----- include/linux/fs.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)
fs/locks.c +5 -5
@@ -289,7 +289,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) { new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid;
@@ -301,14 +301,14 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_ops =NULL ; new->fl_lmops =NULL ; } -EXPORT_SYMBOL (__locks_copy_lock); +EXPORT_SYMBOL (locks_copy_conflock);void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {/* "new" must be a freshly-initialized lock */ WARN_ON_ONCE (new->fl_ops); -__locks_copy_lock (new, fl); +locks_copy_conflock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; new->fl_lmops = fl->fl_lmops;
@@ -743,7 +743,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_conflock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else
@@ -949,7 +949,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_conflock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
include/linux/fs.h +2 -2
@@ -968,7 +968,7 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *); +extern void locks_copy_conflock (struct file_lock *,struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
@@ -1028,7 +1028,7 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) +static inline void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) {return ; }
Signature · 1 line
1.9.3
PATCH v4 4/6 locks: Copy fl_lmops information for conflock in, locks_copy_conflock()
In reply to a message not in the archiveCommit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock always be NULL too.
Make sure copy the private information by fl_copy_lock() in struct file_lock_operations, merge __locks_copy_lock() to fl_copy_lock().
Jeff advice, "Set fl_lmops on conflocks, but don't set fl_ops. fl_ops are superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by the fl_lmops. So you really do want to copy the fl_lmops for conflocks I think."
v4: only copy fl_lmops for conflock, don't copy fl_ops
--- fs/locks.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)
fs/locks.c +16 -20
@@ -271,21 +271,6 @@ void locks_init_lock(struct file_lock *fl)EXPORT_SYMBOL (locks_init_lock); -static void locks_copy_private (struct file_lock *new,struct file_lock *fl) -{ -if (fl->fl_ops) { -if (fl->fl_ops->fl_copy_lock) - fl->fl_ops->fl_copy_lock (new, fl); - new->fl_ops = fl->fl_ops; - } - -if (fl->fl_lmops) { -if (fl->fl_lmops->lm_get_owner) - fl->fl_lmops->lm_get_owner (new, fl); - new->fl_lmops = fl->fl_lmops; - } -} -/* * Initialize a new lock from an existing file_lock structure. */
@@ -298,8 +283,13 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; + new->fl_lmops = fl->fl_lmops; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); + } }EXPORT_SYMBOL (locks_copy_conflock);
@@ -309,11 +299,14 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)WARN_ON_ONCE (new->fl_ops);locks_copy_conflock (new, fl); + new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops; -locks_copy_private (new, fl); +if (fl->fl_ops) { +if (fl->fl_ops->fl_copy_lock) + fl->fl_ops->fl_copy_lock (new, fl); + } }EXPORT_SYMBOL (locks_copy_lock);
@@ -1989,11 +1982,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)if (file_lock.fl_type !=F_UNLCK ) { error =posix_lock_to_flock (&flock, &file_lock);if (error) - goto out; + goto rel_priv; } error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; +rel_priv: +locks_release_private (&file_lock); out:return error; }
@@ -2214,7 +2209,8 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; - + +locks_release_private (&file_lock); out:return error; }
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v4 5/6 NFSD: New helper nfs4_get_stateowner() for atomic_inc sop reference
In reply to Kinglong Meev4: same as v3
--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
fs/nfsd/nfs4state.c +16 -16
@@ -216,6 +216,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses)spin_unlock (&nn->client_lock); } +static inline struct nfs4_stateowner * +nfs4_get_stateowner (struct nfs4_stateowner *sop) +{ +atomic_inc (&sop->so_count); +return sop; +} +static int same_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner) {
@@ -235,10 +242,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, so_strhash) {if (!so->so_is_open_owner)continue ; -if (same_owner_str (so, &open->op_owner)) { -atomic_inc (&so->so_count); -return openowner (so); - } +if (same_owner_str (so, &open->op_owner)) +return openowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -1644,7 +1649,7 @@ __destroy_client(struct nfs4_client *clp) }while (!list_empty (&clp->cl_openowners)) { oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); -atomic_inc (&oo->oo_owner.so_count); +nfs4_get_stateowner (&oo->oo_owner);release_openowner (oo); }nfsd4_shutdown_callback (clp);
@@ -3125,8 +3130,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate, {if (!nfsd4_has_session (cstate)) {mutex_lock (&so->so_replay.rp_mutex); - cstate->replay_owner = so; -atomic_inc (&so->so_count); + cstate->replay_owner =nfs4_get_stateowner (so); } }
@@ -3225,8 +3229,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_OPEN_STID ;INIT_LIST_HEAD (&stp->st_locks); - stp->st_stateowner = &oo->oo_owner; -atomic_inc (&stp->st_stateowner->so_count); + stp->st_stateowner =nfs4_get_stateowner (&oo->oo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_access_bmap =0 ;
@@ -4914,10 +4917,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner, so_strhash) {if (so->so_is_open_owner)continue ; -if (!same_owner_str (so, owner)) -continue ; -atomic_inc (&so->so_count); -return lockowner (so); +if (same_owner_str (so, owner)) +return lockowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -4996,8 +4997,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_LOCK_STID ; - stp->st_stateowner = &lo->lo_owner; -atomic_inc (&lo->lo_owner.so_count); + stp->st_stateowner =nfs4_get_stateowner (&lo->lo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_stid.sc_free = nfs4_free_lock_stateid;
@@ -5539,7 +5539,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, } } -atomic_inc (&sop->so_count); +nfs4_get_stateowner (sop);break ; }spin_unlock (&clp->cl_lock);
Signature · 1 line
1.9.3
PATCH v4 6/6 NFSD: Increase the reference of lockowner when coping file_lock
In reply to Kinglong Meev4: same as v3, no change
v3: Update based on Jeff's comments
v2: Fix bad using of struct file_lock_operations for handle the owner.
--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +30 -4
@@ -4869,9 +4869,31 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static inline struct nfs4_lockowner * +nfs4_get_lockowner (struct nfs4_lockowner *lo) +{ +return lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} + +static void nfsd4_fl_get_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )nfs4_get_lockowner (lo); +} + +static void nfsd4_fl_put_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_get_owner = nfsd4_fl_get_owner, + .lm_put_owner = nfsd4_fl_put_owner, }; static inline void
@@ -5236,7 +5258,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
@@ -5403,6 +5426,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);
@@ -5424,6 +5448,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);
@@ -5432,7 +5458,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Signature · 1 line
1.9.3
Jeff Layton
Reviewed-byRe: [PATCH 2/6 v4] locks: New ops in file_lock_operations for get/put owner
In reply to a message not in the archiveQuoted 48 lines · On Tue, 19 Aug 2014 23:18:58 +0800 Kinglong Mee…
NFSD or other lockmanager may increase the owner's reference, so adds two new options for copying and releasing owner.
v4: rename lm_copy_owner/lm_release_owner to lm_get_owner/lm_put_owner
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-)fs/locks.c +10
-2@@ -230,8 +230,12 @@ void locks_release_private(struct file_lock *fl) fl->fl_ops->fl_release_private (fl); fl->fl_ops =NULL ; } - fl->fl_lmops =NULL ; +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_put_owner) + fl->fl_lmops->lm_put_owner (fl); + fl->fl_lmops =NULL ; + } }EXPORT_SYMBOL_GPL (locks_release_private);@@ -274,8 +278,12 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) fl->fl_ops->fl_copy_lock (new, fl); new->fl_ops = fl->fl_ops; } -if (fl->fl_lmops) + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); new->fl_lmops = fl->fl_lmops; + } }/* include/linux/fs.h +0
-0
include/linux/fs.h struct file_lock_operations { · line 875
Quoted 8 lines
include/linux/fs.h +2
-0@@ -868,6 +868,8 @@ struct file_lock_operations {struct lock_manager_operations {int (*lm_compare_owner)(struct file_lock *,struct file_lock *);unsigned long (*lm_owner_key)(struct file_lock *); +void (*lm_get_owner)(struct file_lock *,struct file_lock *); +void (*lm_put_owner)(struct file_lock *);void (*lm_notify)(struct file_lock *);/* unblock callback */ int (*lm_grant)(struct file_lock *,int );void (*lm_break)(struct file_lock *);
Looks good. I'd probably move patch #3 before this one but that's just a minor nit.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/6 v4] locks: Rename __locks_copy_lock() to locks_copy_conflock()
In reply to Kinglong MeeQuoted 75 lines · On Tue, 19 Aug 2014 23:21:19 +0800 Kinglong Mee <[email protected]> wrote:
Jeff advice, " Right now
__locks_copy_lockis only used to copy conflocks. It would be good to rename that to something more distinct (i.e.locks_copy_conflock), to make it clear that we're generating a conflock there."v4: a new patch only rename
Signed-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 10 +++++----- include/linux/fs.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)fs/locks.c +5
-5@@ -289,7 +289,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) { new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid;@@ -301,14 +301,14 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_ops =NULL ; new->fl_lmops =NULL ; } -EXPORT_SYMBOL (__locks_copy_lock); +EXPORT_SYMBOL (locks_copy_conflock);void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {/* "new" must be a freshly-initialized lock */ WARN_ON_ONCE (new->fl_ops); -__locks_copy_lock (new, fl); +locks_copy_conflock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; new->fl_lmops = fl->fl_lmops;@@ -743,7 +743,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_conflock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else @@ -949,7 +949,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_conflock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;include/linux/fs.h +1
-1@@ -968,7 +968,7 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *); +extern void locks_copy_conflock (struct file_lock *,struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
include/linux/fs.h static inline void locks_init_lock(struct file_lock *fl) · line 1034
Quoted 8 lines
include/linux/fs.h +1
-1@@ -1028,7 +1028,7 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) +static inline void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) {return ; }
Re: [PATCH 4/6 v4] locks: Copy fl_lmops information for conflock in, locks_copy_conflock()
In reply to Kinglong MeeQuoted 100 lines · On Tue, 19 Aug 2014 23:24:23 +0800 Kinglong Mee <[email protected]> wrote:
Commit
d5b9026a67([PATCH] knfsd: locks: flag NFSv4-owned locks) usingfl_lmopsfield infile_lockfor checking nfsd4 lockowner.But, commit
1a747ee0cc(locks: don't call ->copy_lock methods on return of conflicting locks) causes thefl_lmopsof conflock always be NULL.Also, commit
0996905f93(lockd:posix_test_lock()should not calllocks_copy_lock()) caused thefl_lmopsof conflock always be NULL too.Make sure copy the private information by
fl_copy_lock()in structfile_lock_operations, merge__locks_copy_lock()tofl_copy_lock().Jeff advice, "Set
fl_lmopson conflocks, but don't setfl_ops.fl_opsare superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by thefl_lmops. So you really do want to copy thefl_lmopsfor conflocks I think."v4: only copy
fl_lmopsfor conflock, don't copyfl_opsSigned-off-by Kinglong Mee <[email protected]>--- fs/locks.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)fs/locks.c +14
-19@@ -271,21 +271,6 @@ void locks_init_lock(struct file_lock *fl)EXPORT_SYMBOL (locks_init_lock); -static void locks_copy_private (struct file_lock *new,struct file_lock *fl) -{ -if (fl->fl_ops) { -if (fl->fl_ops->fl_copy_lock) - fl->fl_ops->fl_copy_lock (new, fl); - new->fl_ops = fl->fl_ops; - } - -if (fl->fl_lmops) { -if (fl->fl_lmops->lm_get_owner) - fl->fl_lmops->lm_get_owner (new, fl); - new->fl_lmops = fl->fl_lmops; - } -} -/* * Initialize a new lock from an existing file_lock structure. */ @@ -298,8 +283,13 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; + new->fl_lmops = fl->fl_lmops; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); + } }EXPORT_SYMBOL (locks_copy_conflock);@@ -309,11 +299,14 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)WARN_ON_ONCE (new->fl_ops);locks_copy_conflock (new, fl); + new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops; -locks_copy_private (new, fl); +if (fl->fl_ops) { +if (fl->fl_ops->fl_copy_lock) + fl->fl_ops->fl_copy_lock (new, fl); + } }EXPORT_SYMBOL (locks_copy_lock);@@ -1989,11 +1982,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)if (file_lock.fl_type !=F_UNLCK ) { error =posix_lock_to_flock (&flock, &file_lock);if (error) - goto out; + goto rel_priv; } error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; +rel_priv: +locks_release_private (&file_lock); out:return error; }
fs/locks.c int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) · line 2216
Quoted 9 lines
fs/locks.c +2
-1@@ -2214,7 +2209,8 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; - + +locks_release_private (&file_lock); out:return error; }
Looks good for the most part. I think there is one small piece missing though.
There is a vfs_test_lock call in nlmsvc_testlock. The conflock in that case is embedded inside a nlm_lock and locks_release_private is not called on it (AFAICT). You're not planning to set these new lmops for lockd, but someone could in the future.
I think it would be good to go ahead and plumb in a call to locks_release_private there as well to help ensure that no one will break this in the future. It'll be a no-op for the time being of course.
Signature · 1 line
Jeff Layton <[email protected]>
Re: [PATCH 5/6 v4] NFSD: New helper nfs4_get_stateowner() for atomic_inc sop reference
In reply to Kinglong MeeQuoted 91 lines · On Tue, 19 Aug 2014 23:25:32 +0800 Kinglong Mee <[email protected]> wrote:
v4: same as v3
Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)fs/nfsd/nfs4state.c +15
-15@@ -216,6 +216,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses)spin_unlock (&nn->client_lock); } +static inline struct nfs4_stateowner * +nfs4_get_stateowner (struct nfs4_stateowner *sop) +{ +atomic_inc (&sop->so_count); +return sop; +} +static int same_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner) {@@ -235,10 +242,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, so_strhash) {if (!so->so_is_open_owner)continue ; -if (same_owner_str (so, &open->op_owner)) { -atomic_inc (&so->so_count); -return openowner (so); - } +if (same_owner_str (so, &open->op_owner)) +return openowner (nfs4_get_stateowner (so)); }return NULL ; }@@ -1644,7 +1649,7 @@ __destroy_client(struct nfs4_client *clp) }while (!list_empty (&clp->cl_openowners)) { oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); -atomic_inc (&oo->oo_owner.so_count); +nfs4_get_stateowner (&oo->oo_owner);release_openowner (oo); }nfsd4_shutdown_callback (clp);@@ -3125,8 +3130,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate, {if (!nfsd4_has_session (cstate)) {mutex_lock (&so->so_replay.rp_mutex); - cstate->replay_owner = so; -atomic_inc (&so->so_count); + cstate->replay_owner =nfs4_get_stateowner (so); } }@@ -3225,8 +3229,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_OPEN_STID ;INIT_LIST_HEAD (&stp->st_locks); - stp->st_stateowner = &oo->oo_owner; -atomic_inc (&stp->st_stateowner->so_count); + stp->st_stateowner =nfs4_get_stateowner (&oo->oo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_access_bmap =0 ;@@ -4914,10 +4917,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner, so_strhash) {if (so->so_is_open_owner)continue ; -if (!same_owner_str (so, owner)) -continue ; -atomic_inc (&so->so_count); -return lockowner (so); +if (same_owner_str (so, owner)) +return lockowner (nfs4_get_stateowner (so)); }return NULL ; }@@ -4996,8 +4997,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_LOCK_STID ; - stp->st_stateowner = &lo->lo_owner; -atomic_inc (&lo->lo_owner.so_count); + stp->st_stateowner =nfs4_get_stateowner (&lo->lo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_stid.sc_free = nfs4_free_lock_stateid;
fs/nfsd/nfs4state.c nfsd4_release_lockowner(struct svc_rqst *rqstp, · line 5545
Quoted 8 lines
fs/nfsd/nfs4state.c +1
-1@@ -5539,7 +5539,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, } } -atomic_inc (&sop->so_count); +nfs4_get_stateowner (sop);break ; }spin_unlock (&clp->cl_lock);
Jeff Layton
Acked-byRe: [PATCH 6/6 v4] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 15 lines · On Tue, 19 Aug 2014 23:26:45 +0800 Kinglong Mee…
v4: same as v3, no change
v3: Update based on Jeff's comments
v2: Fix bad using of structfile_lock_operationsfor handle the owner.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)fs/nfsd/nfs4state.c +0
-0@@ -4869,9 +4869,31 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ;
fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4877
Quoted 10 lines
fs/nfsd/nfs4state.c +6
-2} -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static inline struct nfs4_lockowner * +nfs4_get_lockowner (struct nfs4_lockowner *lo) +{ +return lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} +
I'd probably not bother with this inline function. Just open code that into the callers.
Quoted 33 lines
fs/nfsd/nfs4state.c +20
-1+static void nfsd4_fl_get_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )nfs4_get_lockowner (lo); +} + +static void nfsd4_fl_put_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_get_owner = nfsd4_fl_get_owner, + .lm_put_owner = nfsd4_fl_put_owner, }; static inline void@@ -5236,7 +5258,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5429
Quoted 4 lines
fs/nfsd/nfs4state.c +1
-0@@ -5403,6 +5426,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;
nit: Probably no need to initialize lock_sop to NULL. Even better, I'd just drop that and change the fl_owner assignment below.
Quoted 13 lines
fs/nfsd/nfs4state.c +2
-0__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5424,6 +5448,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);
fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5461
Quoted 5 lines
fs/nfsd/nfs4state.c +1
-1@@ -5432,7 +5458,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop);
I'd do this instead and not bother with a nfs4_get_lockowner at all...
file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(stp->st_stateowner));
fs/nfsd/nfs4state.c nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5265
Quoted 3 lines
fs/nfsd/nfs4state.c +0
-0file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
But those are minor nits. This looks fine otherwise.
Bruce, if it's OK by you, I'll just take the whole series once Kinglong respins. It does touch some nfsd code, but it hopefully shouldn't cause much in the way of conflicts with anything you have queued for v3.18.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/6 v4] NFSD: Increase the reference of lockowner when coping file_lock
Quoted 100 lines · Jeff Layton
Quoted 15 lines · On Tue, 19 Aug 2014 23:26:45 +0800 Kinglong Mee <[email protected]> wrote:
v4: same as v3, no change
v3: Update based on Jeff's comments
v2: Fix bad using of structfile_lock_operationsfor handle the owner.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)fs/nfsd/nfs4state.c +0
-0@@ -4869,9 +4869,31 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ;fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4877
Quoted 10 lines
fs/nfsd/nfs4state.c +6
-2} -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static inline struct nfs4_lockowner * +nfs4_get_lockowner (struct nfs4_lockowner *lo) +{ +return lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} +I'd probably not bother with this inline function. Just open code that into the callers.
Quoted 33 lines
fs/nfsd/nfs4state.c +20
-1+static void nfsd4_fl_get_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )nfs4_get_lockowner (lo); +} + +static void nfsd4_fl_put_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_get_owner = nfsd4_fl_get_owner, + .lm_put_owner = nfsd4_fl_put_owner, }; static inline void@@ -5236,7 +5258,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5429
Quoted 4 lines
fs/nfsd/nfs4state.c +1
-0@@ -5403,6 +5426,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;nit: Probably no need to initialize
lock_sopto NULL. Even better, I'd just drop that and change thefl_ownerassignment below.Quoted 13 lines
fs/nfsd/nfs4state.c +2
-0__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5424,6 +5448,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5461
Quoted 5 lines
fs/nfsd/nfs4state.c +1
-1@@ -5432,7 +5458,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop);I'd do this instead and not bother with a
nfs4_get_lockownerat all...file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(stp->st_stateowner));fs/nfsd/nfs4state.c nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5265
Quoted 3 lines
fs/nfsd/nfs4state.c +0
-0file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Quoted 5 lines
But those are minor nits. This looks fine otherwise.
Bruce, if it's OK by you, I'll just take the whole series once Kinglong respins. It does touch some nfsd code, but it hopefully shouldn't cause much in the way of conflicts with anything you have queued for v3.18.
That's fine by me.
--b.
PATCH v5 1/6 NFSD: Remove the duplicate initialize of file_lock
In reply to Kinglong Meelocks_alloc_lock() has initialize the struct file_lock, so, don't need re-initialize it by locks_init_lock().
v5: same the first version, only cleanup
--- fs/nfsd/nfs4state.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +2 -4
@@ -3759,7 +3759,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) fl =locks_alloc_lock ();if (!fl)return NULL ; -locks_init_lock (fl); fl->fl_lmops = &nfsd_lease_mng_ops; fl->fl_flags =FL_DELEG ; fl->fl_type = flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK ;
@@ -5210,7 +5209,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } fp = lock_stp->st_stid.sc_file; -locks_init_lock (file_lock);switch (lock->lk_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5354,7 +5352,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto out; } -locks_init_lock (file_lock); +switch (lockt->lt_type) {case NFS4_READ_LT :case NFS4_READW_LT :
@@ -5432,7 +5430,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_jukebox; goto fput; } -locks_init_lock (file_lock); + file_lock->fl_type =F_UNLCK ; file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); file_lock->fl_pid = current->tgid;
Signature · 1 line
1.9.3
PATCH v5 2/6 locks: Rename __locks_copy_lock() to locks_copy_conflock()
In reply to a message not in the archiveJeff advice, " Right now __locks_copy_lock is only used to copy conflocks. It would be good to rename that to something more distinct (i.e.locks_copy_conflock), to make it clear that we're generating a conflock there."
v5: change order from 3/6 to 2/6
v4: new patch only renaming function name
--- fs/locks.c | 10 +++++----- include/linux/fs.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)
fs/locks.c +5 -5
@@ -281,7 +281,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)/* * Initialize a new lock from an existing file_lock structure. */ -void __locks_copy_lock (struct file_lock *new,const struct file_lock *fl) +void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) { new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid;
@@ -293,14 +293,14 @@ void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) new->fl_ops =NULL ; new->fl_lmops =NULL ; } -EXPORT_SYMBOL (__locks_copy_lock); +EXPORT_SYMBOL (locks_copy_conflock);void locks_copy_lock (struct file_lock *new,struct file_lock *fl) {/* "new" must be a freshly-initialized lock */ WARN_ON_ONCE (new->fl_ops); -__locks_copy_lock (new, fl); +locks_copy_conflock (new, fl); new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; new->fl_lmops = fl->fl_lmops;
@@ -735,7 +735,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)break ; }if (cfl) { -__locks_copy_lock (fl, cfl); +locks_copy_conflock (fl, cfl);if (cfl->fl_nspid) fl->fl_pid =pid_vnr (cfl->fl_nspid); }else
@@ -941,7 +941,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, strif (!posix_locks_conflict (request, fl))continue ;if (conflock) -__locks_copy_lock (conflock, fl); +locks_copy_conflock (conflock, fl); error = -EAGAIN ;if (!(request->fl_flags &FL_SLEEP )) goto out;
include/linux/fs.h +2 -2
@@ -966,7 +966,7 @@ void locks_free_lock(struct file_lock *fl);extern void locks_init_lock (struct file_lock *);extern struct file_lock *locks_alloc_lock (void );extern void locks_copy_lock (struct file_lock *,struct file_lock *); -extern void __locks_copy_lock (struct file_lock *,const struct file_lock *); +extern void locks_copy_conflock (struct file_lock *,struct file_lock *);extern void locks_remove_posix (struct file *,fl_owner_t );extern void locks_remove_file (struct file *);extern void locks_release_private (struct file_lock *);
@@ -1026,7 +1026,7 @@ static inline void locks_init_lock(struct file_lock *fl)return ; } -static inline void __locks_copy_lock (struct file_lock *new,struct file_lock *fl) +static inline void locks_copy_conflock (struct file_lock *new,struct file_lock *fl) {return ; }
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v5 3/6 locks: New ops in file_lock_operations for get/put owner
In reply to a message not in the archiveNFSD or other lockmanager may increase the owner's reference, so adds two new options for copying and releasing owner.
v5: change order from 2/6 to 3/6
v4: rename lm_copy_owner/lm_release_owner to lm_get_owner/lm_put_owner
--- fs/locks.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-)
fs/locks.c +10 -2
@@ -230,8 +230,12 @@ void locks_release_private(struct file_lock *fl) fl->fl_ops->fl_release_private (fl); fl->fl_ops =NULL ; } - fl->fl_lmops =NULL ; +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_put_owner) + fl->fl_lmops->lm_put_owner (fl); + fl->fl_lmops =NULL ; + } }EXPORT_SYMBOL_GPL (locks_release_private);
@@ -274,8 +278,12 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl) fl->fl_ops->fl_copy_lock (new, fl); new->fl_ops = fl->fl_ops; } -if (fl->fl_lmops) + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); new->fl_lmops = fl->fl_lmops; + } }/*
include/linux/fs.h +2 -0
@@ -868,6 +868,8 @@ struct file_lock_operations {struct lock_manager_operations {int (*lm_compare_owner)(struct file_lock *,struct file_lock *);unsigned long (*lm_owner_key)(struct file_lock *); +void (*lm_get_owner)(struct file_lock *,struct file_lock *); +void (*lm_put_owner)(struct file_lock *);void (*lm_notify)(struct file_lock *);/* unblock callback */ int (*lm_grant)(struct file_lock *,int );void (*lm_break)(struct file_lock *);
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v5 4/6 locks: Copy fl_lmops information for conflock in locks_copy_conflock()
In reply to Kinglong MeeCommit d5b9026a67 ([PATCH] knfsd: locks: flag NFSv4-owned locks) using fl_lmops field in file_lock for checking nfsd4 lockowner.
But, commit 1a747ee0cc (locks: don't call ->copy_lock methods on return of conflicting locks) causes the fl_lmops of conflock always be NULL.
Also, commit 0996905f93 (lockd: posix_test_lock() should not call locks_copy_lock()) caused the fl_lmops of conflock always be NULL too.
Make sure copy the private information by fl_copy_lock() in struct file_lock_operations, merge __locks_copy_lock() to fl_copy_lock().
Jeff advice, "Set fl_lmops on conflocks, but don't set fl_ops. fl_ops are superfluous, since they are callbacks into the filesystem. There should be no need to bother the filesystem at all with info in a conflock. But, lock _ownership_ matters for conflocks and that's indicated by the fl_lmops. So you really do want to copy the fl_lmops for conflocks I think."
v5: add missing calling of locks_release_private() in nlmsvc_testlock()
v4: only copy fl_lmops for conflock, don't copy fl_ops
--- fs/lockd/svclock.c | 1 + fs/locks.c | 36 ++++++++++++++++-------------------- 2 files changed, 17 insertions(+), 20 deletions(-)
fs/lockd/svclock.c +1 -0
@@ -570,6 +570,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, conflock->fl.fl_type = lock->fl.fl_type; conflock->fl.fl_start = lock->fl.fl_start; conflock->fl.fl_end = lock->fl.fl_end; +locks_release_private (&lock->fl); ret = nlm_lck_denied; out:if (block)
fs/locks.c +16 -20
@@ -271,21 +271,6 @@ void locks_init_lock(struct file_lock *fl)EXPORT_SYMBOL (locks_init_lock); -static void locks_copy_private (struct file_lock *new,struct file_lock *fl) -{ -if (fl->fl_ops) { -if (fl->fl_ops->fl_copy_lock) - fl->fl_ops->fl_copy_lock (new, fl); - new->fl_ops = fl->fl_ops; - } - -if (fl->fl_lmops) { -if (fl->fl_lmops->lm_get_owner) - fl->fl_lmops->lm_get_owner (new, fl); - new->fl_lmops = fl->fl_lmops; - } -} -/* * Initialize a new lock from an existing file_lock structure. */
@@ -298,8 +283,13 @@ void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; + new->fl_lmops = fl->fl_lmops; new->fl_ops =NULL ; - new->fl_lmops =NULL ; + +if (fl->fl_lmops) { +if (fl->fl_lmops->lm_get_owner) + fl->fl_lmops->lm_get_owner (new, fl); + } }EXPORT_SYMBOL (locks_copy_conflock);
@@ -309,11 +299,14 @@ void locks_copy_lock(struct file_lock *new, struct file_lock *fl)WARN_ON_ONCE (new->fl_ops);locks_copy_conflock (new, fl); + new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; - new->fl_lmops = fl->fl_lmops; -locks_copy_private (new, fl); +if (fl->fl_ops) { +if (fl->fl_ops->fl_copy_lock) + fl->fl_ops->fl_copy_lock (new, fl); + } }EXPORT_SYMBOL (locks_copy_lock);
@@ -1989,11 +1982,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)if (file_lock.fl_type !=F_UNLCK ) { error =posix_lock_to_flock (&flock, &file_lock);if (error) - goto out; + goto rel_priv; } error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; +rel_priv: +locks_release_private (&file_lock); out:return error; }
@@ -2214,7 +2209,8 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) error = -EFAULT ;if (!copy_to_user (l, &flock,sizeof (flock))) error =0 ; - + +locks_release_private (&file_lock); out:return error; }
Signature · 1 line
1.9.3
PATCH v5 5/6 NFSD: New helper nfs4_get_stateowner() for atomic_inc sop reference
In reply to a message not in the archivev5: same as the first version
--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
fs/nfsd/nfs4state.c +16 -16
@@ -216,6 +216,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses)spin_unlock (&nn->client_lock); } +static inline struct nfs4_stateowner * +nfs4_get_stateowner (struct nfs4_stateowner *sop) +{ +atomic_inc (&sop->so_count); +return sop; +} +static int same_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner) {
@@ -235,10 +242,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, so_strhash) {if (!so->so_is_open_owner)continue ; -if (same_owner_str (so, &open->op_owner)) { -atomic_inc (&so->so_count); -return openowner (so); - } +if (same_owner_str (so, &open->op_owner)) +return openowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -1644,7 +1649,7 @@ __destroy_client(struct nfs4_client *clp) }while (!list_empty (&clp->cl_openowners)) { oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); -atomic_inc (&oo->oo_owner.so_count); +nfs4_get_stateowner (&oo->oo_owner);release_openowner (oo); }nfsd4_shutdown_callback (clp);
@@ -3125,8 +3130,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate, {if (!nfsd4_has_session (cstate)) {mutex_lock (&so->so_replay.rp_mutex); - cstate->replay_owner = so; -atomic_inc (&so->so_count); + cstate->replay_owner =nfs4_get_stateowner (so); } }
@@ -3225,8 +3229,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_OPEN_STID ;INIT_LIST_HEAD (&stp->st_locks); - stp->st_stateowner = &oo->oo_owner; -atomic_inc (&stp->st_stateowner->so_count); + stp->st_stateowner =nfs4_get_stateowner (&oo->oo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_access_bmap =0 ;
@@ -4914,10 +4917,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner, so_strhash) {if (so->so_is_open_owner)continue ; -if (!same_owner_str (so, owner)) -continue ; -atomic_inc (&so->so_count); -return lockowner (so); +if (same_owner_str (so, owner)) +return lockowner (nfs4_get_stateowner (so)); }return NULL ; }
@@ -4996,8 +4997,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,atomic_inc (&stp->st_stid.sc_count); stp->st_stid.sc_type =NFS4_LOCK_STID ; - stp->st_stateowner = &lo->lo_owner; -atomic_inc (&lo->lo_owner.so_count); + stp->st_stateowner =nfs4_get_stateowner (&lo->lo_owner);get_nfs4_file (fp); stp->st_stid.sc_file = fp; stp->st_stid.sc_free = nfs4_free_lock_stateid;
@@ -5539,7 +5539,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, } } -atomic_inc (&sop->so_count); +nfs4_get_stateowner (sop);break ; }spin_unlock (&clp->cl_lock);
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v5 6/6 NFSD: Get reference of lockowner when coping file_lock
In reply to a message not in the archivev5: using nfs4_get_stateowner() instead of an inline function
v3: Update based on Jeff's comments
v2: Fix bad using of struct file_lock_operations for handle the owner
--- fs/nfsd/nfs4state.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
fs/nfsd/nfs4state.c +21 -4
@@ -4869,9 +4869,25 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ; } -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static void nfsd4_fl_get_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *)src->fl_owner; + dst->fl_owner = (fl_owner_t )lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} + +static void nfsd4_fl_put_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_get_owner = nfsd4_fl_get_owner, + .lm_put_owner = nfsd4_fl_put_owner, }; static inline void
@@ -5236,7 +5252,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )lockowner (nfs4_get_stateowner (&lock_sop->lo_owner)); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
@@ -5432,7 +5449,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )lockowner (nfs4_get_stateowner (stp->st_stateowner)); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Signature · 6 lines
1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/6 v4] NFSD: Increase the reference of lockowner when coping file_lock
In reply to a message not in the archiveQuoted 100 lines · Jeff Layton
Quoted 15 lines · On Tue, 19 Aug 2014 23:26:45 +0800 Kinglong Mee…
v4: same as v3, no change
v3: Update based on Jeff's comments
v2: Fix bad using of structfile_lock_operationsfor handle the owner.Signed-off-by Kinglong Mee <[email protected]>--- fs/nfsd/nfs4state.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)fs/nfsd/nfs4state.c +0
-0@@ -4869,9 +4869,31 @@ nfs4_transform_lock_offset(struct file_lock *lock) lock->fl_end =OFFSET_MAX ;fs/nfsd/nfs4state.c nfs4_transform_lock_offset(struct file_lock *lock) · line 4877
Quoted 10 lines
fs/nfsd/nfs4state.c +6
-2} -/* Hack!: For now, we're defining this just so we can use a pointer to it -* as a unique cookie to identify our (NFSv4's) posix locks. */ +static inline struct nfs4_lockowner * +nfs4_get_lockowner (struct nfs4_lockowner *lo) +{ +return lockowner (nfs4_get_stateowner (&lo->lo_owner)); +} +I'd probably not bother with this inline function. Just open code that into the callers.
Quoted 33 lines
fs/nfsd/nfs4state.c +20
-1+static void nfsd4_fl_get_owner (struct file_lock *dst,struct file_lock *src) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) src->fl_owner; + dst->fl_owner = (fl_owner_t )nfs4_get_lockowner (lo); +} + +static void nfsd4_fl_put_owner (struct file_lock *fl) +{ +struct nfs4_lockowner *lo = (struct nfs4_lockowner *) fl->fl_owner; + +if (lo) { +nfs4_put_stateowner (&lo->lo_owner); + fl->fl_owner =NULL ; + } +} +static const struct lock_manager_operations nfsd_posix_mng_ops = { + .lm_get_owner = nfsd4_fl_get_owner, + .lm_put_owner = nfsd4_fl_put_owner, }; static inline void@@ -5236,7 +5258,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_openmode; goto out; } - file_lock->fl_owner = (fl_owner_t )lock_sop; + + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop); file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5429
Quoted 4 lines
fs/nfsd/nfs4state.c +1
-0@@ -5403,6 +5426,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfs4_ol_stateid *stp;struct file *filp =NULL ;struct file_lock *file_lock =NULL ; +struct nfs4_lockowner *lock_sop =NULL ;nit: Probably no need to initialize
lock_sopto NULL. Even better, I'd just drop that and change thefl_ownerassignment below.Quoted 13 lines
fs/nfsd/nfs4state.c +2
-0__be32 status;int err;struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);@@ -5424,6 +5448,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_lock_range; goto put_stateid; } + + lock_sop =lockowner (stp->st_stateowner); file_lock =locks_alloc_lock ();if (!file_lock) {dprintk ("NFSD: %s: unable to allocate lock!\n" , __func__);fs/nfsd/nfs4state.c nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5461
Quoted 5 lines
fs/nfsd/nfs4state.c +1
-1@@ -5432,7 +5458,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } file_lock->fl_type =F_UNLCK ; - file_lock->fl_owner = (fl_owner_t )lockowner (stp->st_stateowner); + file_lock->fl_owner = (fl_owner_t )nfs4_get_lockowner (lock_sop);I'd do this instead and not bother with a
nfs4_get_lockownerat all...file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(stp->st_stateowner));fs/nfsd/nfs4state.c nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · line 5265
Quoted 3 lines
fs/nfsd/nfs4state.c +0
-0file_lock->fl_pid = current->tgid; file_lock->fl_file = filp; file_lock->fl_flags =FL_POSIX ;
Quoted 5 lines
But those are minor nits. This looks fine otherwise.
Bruce, if it's OK by you, I'll just take the whole series once Kinglong respins. It does touch some nfsd code, but it hopefully shouldn't cause much in the way of conflicts with anything you have queued for v3.18.
Thank you very much for your all comments before. A new version have be sent, please have a check again.
thanks,
Kinglong Mee
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html