aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-04-11 01:55:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-11 09:18:51 -0400
commitd5b9026a670fdb404e6e2e2e0a1b447e9ea9c1f6 (patch)
treee657e09e5e1eb43f163775d1b8e599131516a67a /fs/nfsd
parent7775f4c85dcbd1175f21b2fbb7221c79ec70b722 (diff)
[PATCH] knfsd: locks: flag NFSv4-owned locks
Use the fl_lmops field to identify which locks are ours, instead of trying to look them up in our private hash. This is safer and more efficient. Earlier versions of this patch used a lock flag instead, but Trond pointed out that adding a new flag for each lock manager wasn't going to scale well, and suggested this approach instead; a separate patch converts lockd to using fl_lmops in the same way. In the NFSv4 case this looks like a bit of a hack, since the NFSv4 server isn't currently actually defining a lock_manager_operations struct, so we end up defining one *just* to serve as a cookie to identify our locks. But it works, and we actually do expect to start using the lock_manager_operations at some point anyway. Signed-off-by: Marc Eshel <eshel@almaden.ibm.com> Signed-off-by: Andy Adamson <andros@citi.umich.edu> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 47ec112b266c..ffedce08b4cb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2495,36 +2495,27 @@ nfs4_transform_lock_offset(struct file_lock *lock)
2495 lock->fl_end = OFFSET_MAX; 2495 lock->fl_end = OFFSET_MAX;
2496} 2496}
2497 2497
2498static int 2498/* Hack!: For now, we're defining this just so we can use a pointer to it
2499nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval) 2499 * as a unique cookie to identify our (NFSv4's) posix locks. */
2500{ 2500struct lock_manager_operations nfsd_posix_mng_ops = {
2501 struct nfs4_stateowner *local = NULL; 2501};
2502 int status = 0;
2503
2504 if (hashval >= LOCK_HASH_SIZE)
2505 goto out;
2506 list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
2507 if (local == sop) {
2508 status = 1;
2509 goto out;
2510 }
2511 }
2512out:
2513 return status;
2514}
2515
2516 2502
2517static inline void 2503static inline void
2518nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) 2504nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
2519{ 2505{
2520 struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner; 2506 struct nfs4_stateowner *sop;
2521 unsigned int hval = lockownerid_hashval(sop->so_id); 2507 unsigned int hval;
2522 2508
2523 deny->ld_sop = NULL; 2509 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
2524 if (nfs4_verify_lock_stateowner(sop, hval)) { 2510 sop = (struct nfs4_stateowner *) fl->fl_owner;
2511 hval = lockownerid_hashval(sop->so_id);
2525 kref_get(&sop->so_ref); 2512 kref_get(&sop->so_ref);
2526 deny->ld_sop = sop; 2513 deny->ld_sop = sop;
2527 deny->ld_clientid = sop->so_client->cl_clientid; 2514 deny->ld_clientid = sop->so_client->cl_clientid;
2515 } else {
2516 deny->ld_sop = NULL;
2517 deny->ld_clientid.cl_boot = 0;
2518 deny->ld_clientid.cl_id = 0;
2528 } 2519 }
2529 deny->ld_start = fl->fl_start; 2520 deny->ld_start = fl->fl_start;
2530 deny->ld_length = ~(u64)0; 2521 deny->ld_length = ~(u64)0;
@@ -2736,6 +2727,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2736 file_lock.fl_pid = current->tgid; 2727 file_lock.fl_pid = current->tgid;
2737 file_lock.fl_file = filp; 2728 file_lock.fl_file = filp;
2738 file_lock.fl_flags = FL_POSIX; 2729 file_lock.fl_flags = FL_POSIX;
2730 file_lock.fl_lmops = &nfsd_posix_mng_ops;
2739 2731
2740 file_lock.fl_start = lock->lk_offset; 2732 file_lock.fl_start = lock->lk_offset;
2741 if ((lock->lk_length == ~(u64)0) || 2733 if ((lock->lk_length == ~(u64)0) ||
@@ -2841,6 +2833,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2841 file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner; 2833 file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner;
2842 file_lock.fl_pid = current->tgid; 2834 file_lock.fl_pid = current->tgid;
2843 file_lock.fl_flags = FL_POSIX; 2835 file_lock.fl_flags = FL_POSIX;
2836 file_lock.fl_lmops = &nfsd_posix_mng_ops;
2844 2837
2845 file_lock.fl_start = lockt->lt_offset; 2838 file_lock.fl_start = lockt->lt_offset;
2846 if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length)) 2839 if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
@@ -2900,6 +2893,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2900 file_lock.fl_pid = current->tgid; 2893 file_lock.fl_pid = current->tgid;
2901 file_lock.fl_file = filp; 2894 file_lock.fl_file = filp;
2902 file_lock.fl_flags = FL_POSIX; 2895 file_lock.fl_flags = FL_POSIX;
2896 file_lock.fl_lmops = &nfsd_posix_mng_ops;
2903 file_lock.fl_start = locku->lu_offset; 2897 file_lock.fl_start = locku->lu_offset;
2904 2898
2905 if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length)) 2899 if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))