diff options
author | J. Bruce Fields <bfields@redhat.com> | 2011-07-30 23:33:59 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-09-07 09:45:49 -0400 |
commit | fe0750e5c43189adb6e6fc59837af7d5a588f413 (patch) | |
tree | 88c5afe7a955f1e55e305639a4d6031237542b8d /fs/nfsd/nfs4state.c | |
parent | f4dee24cca98739a4190a00fa014cd1b7e2581a4 (diff) |
nfsd4: split stateowners into open and lockowners
The stateowner has some fields that only make sense for openowners, and
some that only make sense for lockowners, and I find it a lot clearer if
those are separated out.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 367 |
1 files changed, 186 insertions, 181 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index eb11626babc6..567130dccda0 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -63,7 +63,7 @@ static u64 current_sessionid = 1; | |||
63 | static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); | 63 | static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); |
64 | static struct nfs4_delegation * search_for_delegation(stateid_t *stid); | 64 | static struct nfs4_delegation * search_for_delegation(stateid_t *stid); |
65 | static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); | 65 | static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); |
66 | static int check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner); | 66 | static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); |
67 | 67 | ||
68 | /* Locking: */ | 68 | /* Locking: */ |
69 | 69 | ||
@@ -77,7 +77,8 @@ static DEFINE_MUTEX(client_mutex); | |||
77 | */ | 77 | */ |
78 | static DEFINE_SPINLOCK(recall_lock); | 78 | static DEFINE_SPINLOCK(recall_lock); |
79 | 79 | ||
80 | static struct kmem_cache *stateowner_slab = NULL; | 80 | static struct kmem_cache *openowner_slab = NULL; |
81 | static struct kmem_cache *lockowner_slab = NULL; | ||
81 | static struct kmem_cache *file_slab = NULL; | 82 | static struct kmem_cache *file_slab = NULL; |
82 | static struct kmem_cache *stateid_slab = NULL; | 83 | static struct kmem_cache *stateid_slab = NULL; |
83 | static struct kmem_cache *deleg_slab = NULL; | 84 | static struct kmem_cache *deleg_slab = NULL; |
@@ -432,41 +433,39 @@ static void release_lock_stateid(struct nfs4_stateid *stp) | |||
432 | unhash_generic_stateid(stp); | 433 | unhash_generic_stateid(stp); |
433 | file = find_any_file(stp->st_file); | 434 | file = find_any_file(stp->st_file); |
434 | if (file) | 435 | if (file) |
435 | locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); | 436 | locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner)); |
436 | free_generic_stateid(stp); | 437 | free_generic_stateid(stp); |
437 | } | 438 | } |
438 | 439 | ||
439 | static void unhash_lockowner(struct nfs4_stateowner *sop) | 440 | static void unhash_lockowner(struct nfs4_lockowner *lo) |
440 | { | 441 | { |
441 | struct nfs4_stateid *stp; | 442 | struct nfs4_stateid *stp; |
442 | 443 | ||
443 | list_del(&sop->so_idhash); | 444 | list_del(&lo->lo_owner.so_idhash); |
444 | list_del(&sop->so_strhash); | 445 | list_del(&lo->lo_owner.so_strhash); |
445 | list_del(&sop->so_perstateid); | 446 | list_del(&lo->lo_perstateid); |
446 | while (!list_empty(&sop->so_stateids)) { | 447 | while (!list_empty(&lo->lo_owner.so_stateids)) { |
447 | stp = list_first_entry(&sop->so_stateids, | 448 | stp = list_first_entry(&lo->lo_owner.so_stateids, |
448 | struct nfs4_stateid, st_perstateowner); | 449 | struct nfs4_stateid, st_perstateowner); |
449 | release_lock_stateid(stp); | 450 | release_lock_stateid(stp); |
450 | } | 451 | } |
451 | } | 452 | } |
452 | 453 | ||
453 | static void release_lockowner(struct nfs4_stateowner *sop) | 454 | static void release_lockowner(struct nfs4_lockowner *lo) |
454 | { | 455 | { |
455 | unhash_lockowner(sop); | 456 | unhash_lockowner(lo); |
456 | nfs4_free_stateowner(sop); | 457 | nfs4_free_lockowner(lo); |
457 | } | 458 | } |
458 | 459 | ||
459 | static void | 460 | static void |
460 | release_stateid_lockowners(struct nfs4_stateid *open_stp) | 461 | release_stateid_lockowners(struct nfs4_stateid *open_stp) |
461 | { | 462 | { |
462 | struct nfs4_stateowner *lock_sop; | 463 | struct nfs4_lockowner *lo; |
463 | 464 | ||
464 | while (!list_empty(&open_stp->st_lockowners)) { | 465 | while (!list_empty(&open_stp->st_lockowners)) { |
465 | lock_sop = list_entry(open_stp->st_lockowners.next, | 466 | lo = list_entry(open_stp->st_lockowners.next, |
466 | struct nfs4_stateowner, so_perstateid); | 467 | struct nfs4_lockowner, lo_perstateid); |
467 | /* list_del(&open_stp->st_lockowners); */ | 468 | release_lockowner(lo); |
468 | BUG_ON(lock_sop->so_is_open_owner); | ||
469 | release_lockowner(lock_sop); | ||
470 | } | 469 | } |
471 | } | 470 | } |
472 | 471 | ||
@@ -477,26 +476,25 @@ static void release_open_stateid(struct nfs4_stateid *stp) | |||
477 | free_generic_stateid(stp); | 476 | free_generic_stateid(stp); |
478 | } | 477 | } |
479 | 478 | ||
480 | static void unhash_openowner(struct nfs4_stateowner *sop) | 479 | static void unhash_openowner(struct nfs4_openowner *oo) |
481 | { | 480 | { |
482 | struct nfs4_stateid *stp; | 481 | struct nfs4_stateid *stp; |
483 | 482 | ||
484 | list_del(&sop->so_idhash); | 483 | list_del(&oo->oo_owner.so_idhash); |
485 | list_del(&sop->so_strhash); | 484 | list_del(&oo->oo_owner.so_strhash); |
486 | list_del(&sop->so_perclient); | 485 | list_del(&oo->oo_perclient); |
487 | list_del(&sop->so_perstateid); /* XXX: necessary? */ | 486 | while (!list_empty(&oo->oo_owner.so_stateids)) { |
488 | while (!list_empty(&sop->so_stateids)) { | 487 | stp = list_first_entry(&oo->oo_owner.so_stateids, |
489 | stp = list_first_entry(&sop->so_stateids, | ||
490 | struct nfs4_stateid, st_perstateowner); | 488 | struct nfs4_stateid, st_perstateowner); |
491 | release_open_stateid(stp); | 489 | release_open_stateid(stp); |
492 | } | 490 | } |
493 | } | 491 | } |
494 | 492 | ||
495 | static void release_openowner(struct nfs4_stateowner *sop) | 493 | static void release_openowner(struct nfs4_openowner *oo) |
496 | { | 494 | { |
497 | unhash_openowner(sop); | 495 | unhash_openowner(oo); |
498 | list_del(&sop->so_close_lru); | 496 | list_del(&oo->oo_close_lru); |
499 | nfs4_free_stateowner(sop); | 497 | nfs4_free_openowner(oo); |
500 | } | 498 | } |
501 | 499 | ||
502 | #define SESSION_HASH_SIZE 512 | 500 | #define SESSION_HASH_SIZE 512 |
@@ -961,7 +959,7 @@ unhash_client_locked(struct nfs4_client *clp) | |||
961 | static void | 959 | static void |
962 | expire_client(struct nfs4_client *clp) | 960 | expire_client(struct nfs4_client *clp) |
963 | { | 961 | { |
964 | struct nfs4_stateowner *sop; | 962 | struct nfs4_openowner *oo; |
965 | struct nfs4_delegation *dp; | 963 | struct nfs4_delegation *dp; |
966 | struct list_head reaplist; | 964 | struct list_head reaplist; |
967 | 965 | ||
@@ -979,8 +977,8 @@ expire_client(struct nfs4_client *clp) | |||
979 | unhash_delegation(dp); | 977 | unhash_delegation(dp); |
980 | } | 978 | } |
981 | while (!list_empty(&clp->cl_openowners)) { | 979 | while (!list_empty(&clp->cl_openowners)) { |
982 | sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient); | 980 | oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); |
983 | release_openowner(sop); | 981 | release_openowner(oo); |
984 | } | 982 | } |
985 | nfsd4_shutdown_callback(clp); | 983 | nfsd4_shutdown_callback(clp); |
986 | if (clp->cl_cb_conn.cb_xprt) | 984 | if (clp->cl_cb_conn.cb_xprt) |
@@ -2173,7 +2171,8 @@ nfsd4_free_slab(struct kmem_cache **slab) | |||
2173 | void | 2171 | void |
2174 | nfsd4_free_slabs(void) | 2172 | nfsd4_free_slabs(void) |
2175 | { | 2173 | { |
2176 | nfsd4_free_slab(&stateowner_slab); | 2174 | nfsd4_free_slab(&openowner_slab); |
2175 | nfsd4_free_slab(&lockowner_slab); | ||
2177 | nfsd4_free_slab(&file_slab); | 2176 | nfsd4_free_slab(&file_slab); |
2178 | nfsd4_free_slab(&stateid_slab); | 2177 | nfsd4_free_slab(&stateid_slab); |
2179 | nfsd4_free_slab(&deleg_slab); | 2178 | nfsd4_free_slab(&deleg_slab); |
@@ -2182,9 +2181,13 @@ nfsd4_free_slabs(void) | |||
2182 | static int | 2181 | static int |
2183 | nfsd4_init_slabs(void) | 2182 | nfsd4_init_slabs(void) |
2184 | { | 2183 | { |
2185 | stateowner_slab = kmem_cache_create("nfsd4_stateowners", | 2184 | openowner_slab = kmem_cache_create("nfsd4_openowners", |
2186 | sizeof(struct nfs4_stateowner), 0, 0, NULL); | 2185 | sizeof(struct nfs4_openowner), 0, 0, NULL); |
2187 | if (stateowner_slab == NULL) | 2186 | if (openowner_slab == NULL) |
2187 | goto out_nomem; | ||
2188 | lockowner_slab = kmem_cache_create("nfsd4_lockowners", | ||
2189 | sizeof(struct nfs4_openowner), 0, 0, NULL); | ||
2190 | if (lockowner_slab == NULL) | ||
2188 | goto out_nomem; | 2191 | goto out_nomem; |
2189 | file_slab = kmem_cache_create("nfsd4_files", | 2192 | file_slab = kmem_cache_create("nfsd4_files", |
2190 | sizeof(struct nfs4_file), 0, 0, NULL); | 2193 | sizeof(struct nfs4_file), 0, 0, NULL); |
@@ -2205,11 +2208,16 @@ out_nomem: | |||
2205 | return -ENOMEM; | 2208 | return -ENOMEM; |
2206 | } | 2209 | } |
2207 | 2210 | ||
2208 | void | 2211 | void nfs4_free_openowner(struct nfs4_openowner *oo) |
2209 | nfs4_free_stateowner(struct nfs4_stateowner *sop) | 2212 | { |
2213 | kfree(oo->oo_owner.so_owner.data); | ||
2214 | kmem_cache_free(openowner_slab, oo); | ||
2215 | } | ||
2216 | |||
2217 | void nfs4_free_lockowner(struct nfs4_lockowner *lo) | ||
2210 | { | 2218 | { |
2211 | kfree(sop->so_owner.data); | 2219 | kfree(lo->lo_owner.so_owner.data); |
2212 | kmem_cache_free(stateowner_slab, sop); | 2220 | kmem_cache_free(lockowner_slab, lo); |
2213 | } | 2221 | } |
2214 | 2222 | ||
2215 | static void init_nfs4_replay(struct nfs4_replay *rp) | 2223 | static void init_nfs4_replay(struct nfs4_replay *rp) |
@@ -2219,74 +2227,72 @@ static void init_nfs4_replay(struct nfs4_replay *rp) | |||
2219 | rp->rp_buf = rp->rp_ibuf; | 2227 | rp->rp_buf = rp->rp_ibuf; |
2220 | } | 2228 | } |
2221 | 2229 | ||
2222 | static inline struct nfs4_stateowner *alloc_stateowner(struct xdr_netobj *owner, struct nfs4_client *clp) | 2230 | static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp) |
2223 | { | 2231 | { |
2224 | struct nfs4_stateowner *sop; | 2232 | struct nfs4_stateowner *sop; |
2225 | 2233 | ||
2226 | sop = kmem_cache_alloc(stateowner_slab, GFP_KERNEL); | 2234 | sop = kmem_cache_alloc(slab, GFP_KERNEL); |
2227 | if (!sop) | 2235 | if (!sop) |
2228 | return NULL; | 2236 | return NULL; |
2229 | 2237 | ||
2230 | sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL); | 2238 | sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL); |
2231 | if (!sop->so_owner.data) { | 2239 | if (!sop->so_owner.data) { |
2232 | kmem_cache_free(stateowner_slab, sop); | 2240 | kmem_cache_free(slab, sop); |
2233 | return NULL; | 2241 | return NULL; |
2234 | } | 2242 | } |
2235 | sop->so_owner.len = owner->len; | 2243 | sop->so_owner.len = owner->len; |
2236 | 2244 | ||
2237 | INIT_LIST_HEAD(&sop->so_perclient); | ||
2238 | INIT_LIST_HEAD(&sop->so_stateids); | 2245 | INIT_LIST_HEAD(&sop->so_stateids); |
2239 | INIT_LIST_HEAD(&sop->so_perstateid); | ||
2240 | INIT_LIST_HEAD(&sop->so_close_lru); | ||
2241 | sop->so_id = current_ownerid++; | 2246 | sop->so_id = current_ownerid++; |
2242 | sop->so_time = 0; | ||
2243 | sop->so_client = clp; | 2247 | sop->so_client = clp; |
2244 | init_nfs4_replay(&sop->so_replay); | 2248 | init_nfs4_replay(&sop->so_replay); |
2245 | return sop; | 2249 | return sop; |
2246 | } | 2250 | } |
2247 | 2251 | ||
2248 | static void hash_openowner(struct nfs4_stateowner *sop, struct nfs4_client *clp, unsigned int strhashval) | 2252 | static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval) |
2249 | { | 2253 | { |
2250 | unsigned int idhashval; | 2254 | unsigned int idhashval; |
2251 | 2255 | ||
2252 | idhashval = open_ownerid_hashval(sop->so_id); | 2256 | idhashval = open_ownerid_hashval(oo->oo_owner.so_id); |
2253 | list_add(&sop->so_idhash, &open_ownerid_hashtbl[idhashval]); | 2257 | list_add(&oo->oo_owner.so_idhash, &open_ownerid_hashtbl[idhashval]); |
2254 | list_add(&sop->so_strhash, &open_ownerstr_hashtbl[strhashval]); | 2258 | list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]); |
2255 | list_add(&sop->so_perclient, &clp->cl_openowners); | 2259 | list_add(&oo->oo_perclient, &clp->cl_openowners); |
2256 | } | 2260 | } |
2257 | 2261 | ||
2258 | static struct nfs4_stateowner * | 2262 | static struct nfs4_openowner * |
2259 | alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { | 2263 | alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { |
2260 | struct nfs4_stateowner *sop; | 2264 | struct nfs4_openowner *oo; |
2261 | 2265 | ||
2262 | sop = alloc_stateowner(&open->op_owner, clp); | 2266 | oo = alloc_stateowner(openowner_slab, &open->op_owner, clp); |
2263 | if (!sop) | 2267 | if (!oo) |
2264 | return NULL; | 2268 | return NULL; |
2265 | sop->so_is_open_owner = 1; | 2269 | oo->oo_owner.so_is_open_owner = 1; |
2266 | sop->so_seqid = open->op_seqid; | 2270 | oo->oo_owner.so_seqid = open->op_seqid; |
2267 | sop->so_confirmed = 0; | 2271 | oo->oo_confirmed = 0; |
2268 | hash_openowner(sop, clp, strhashval); | 2272 | oo->oo_time = 0; |
2269 | return sop; | 2273 | INIT_LIST_HEAD(&oo->oo_close_lru); |
2274 | hash_openowner(oo, clp, strhashval); | ||
2275 | return oo; | ||
2270 | } | 2276 | } |
2271 | 2277 | ||
2272 | static inline void | 2278 | static inline void |
2273 | init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { | 2279 | init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { |
2274 | struct nfs4_stateowner *sop = open->op_stateowner; | 2280 | struct nfs4_openowner *oo = open->op_openowner; |
2275 | unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); | 2281 | unsigned int hashval = stateid_hashval(oo->oo_owner.so_id, fp->fi_id); |
2276 | 2282 | ||
2277 | INIT_LIST_HEAD(&stp->st_hash); | 2283 | INIT_LIST_HEAD(&stp->st_hash); |
2278 | INIT_LIST_HEAD(&stp->st_perstateowner); | 2284 | INIT_LIST_HEAD(&stp->st_perstateowner); |
2279 | INIT_LIST_HEAD(&stp->st_lockowners); | 2285 | INIT_LIST_HEAD(&stp->st_lockowners); |
2280 | INIT_LIST_HEAD(&stp->st_perfile); | 2286 | INIT_LIST_HEAD(&stp->st_perfile); |
2281 | list_add(&stp->st_hash, &stateid_hashtbl[hashval]); | 2287 | list_add(&stp->st_hash, &stateid_hashtbl[hashval]); |
2282 | list_add(&stp->st_perstateowner, &sop->so_stateids); | 2288 | list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); |
2283 | list_add(&stp->st_perfile, &fp->fi_stateids); | 2289 | list_add(&stp->st_perfile, &fp->fi_stateids); |
2284 | stp->st_type = NFS4_OPEN_STID; | 2290 | stp->st_type = NFS4_OPEN_STID; |
2285 | stp->st_stateowner = sop; | 2291 | stp->st_stateowner = &oo->oo_owner; |
2286 | get_nfs4_file(fp); | 2292 | get_nfs4_file(fp); |
2287 | stp->st_file = fp; | 2293 | stp->st_file = fp; |
2288 | stp->st_stateid.si_boot = boot_time; | 2294 | stp->st_stateid.si_boot = boot_time; |
2289 | stp->st_stateid.si_stateownerid = sop->so_id; | 2295 | stp->st_stateid.si_stateownerid = oo->oo_owner.so_id; |
2290 | stp->st_stateid.si_fileid = fp->fi_id; | 2296 | stp->st_stateid.si_fileid = fp->fi_id; |
2291 | /* note will be incremented before first return to client: */ | 2297 | /* note will be incremented before first return to client: */ |
2292 | stp->st_stateid.si_generation = 0; | 2298 | stp->st_stateid.si_generation = 0; |
@@ -2299,12 +2305,12 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open * | |||
2299 | } | 2305 | } |
2300 | 2306 | ||
2301 | static void | 2307 | static void |
2302 | move_to_close_lru(struct nfs4_stateowner *sop) | 2308 | move_to_close_lru(struct nfs4_openowner *oo) |
2303 | { | 2309 | { |
2304 | dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); | 2310 | dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo); |
2305 | 2311 | ||
2306 | list_move_tail(&sop->so_close_lru, &close_lru); | 2312 | list_move_tail(&oo->oo_close_lru, &close_lru); |
2307 | sop->so_time = get_seconds(); | 2313 | oo->oo_time = get_seconds(); |
2308 | } | 2314 | } |
2309 | 2315 | ||
2310 | static int | 2316 | static int |
@@ -2316,14 +2322,14 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, | |||
2316 | (sop->so_client->cl_clientid.cl_id == clid->cl_id); | 2322 | (sop->so_client->cl_clientid.cl_id == clid->cl_id); |
2317 | } | 2323 | } |
2318 | 2324 | ||
2319 | static struct nfs4_stateowner * | 2325 | static struct nfs4_openowner * |
2320 | find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) | 2326 | find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) |
2321 | { | 2327 | { |
2322 | struct nfs4_stateowner *so = NULL; | 2328 | struct nfs4_stateowner *so = NULL; |
2323 | 2329 | ||
2324 | list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) { | 2330 | list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) { |
2325 | if (same_owner_str(so, &open->op_owner, &open->op_clientid)) | 2331 | if (same_owner_str(so, &open->op_owner, &open->op_clientid)) |
2326 | return so; | 2332 | return container_of(so, struct nfs4_openowner, oo_owner); |
2327 | } | 2333 | } |
2328 | return NULL; | 2334 | return NULL; |
2329 | } | 2335 | } |
@@ -2474,7 +2480,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2474 | clientid_t *clientid = &open->op_clientid; | 2480 | clientid_t *clientid = &open->op_clientid; |
2475 | struct nfs4_client *clp = NULL; | 2481 | struct nfs4_client *clp = NULL; |
2476 | unsigned int strhashval; | 2482 | unsigned int strhashval; |
2477 | struct nfs4_stateowner *sop = NULL; | 2483 | struct nfs4_openowner *oo = NULL; |
2478 | __be32 status; | 2484 | __be32 status; |
2479 | 2485 | ||
2480 | if (!check_name(open->op_owner)) | 2486 | if (!check_name(open->op_owner)) |
@@ -2484,34 +2490,34 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate, | |||
2484 | return nfserr_stale_clientid; | 2490 | return nfserr_stale_clientid; |
2485 | 2491 | ||
2486 | strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); | 2492 | strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); |
2487 | sop = find_openstateowner_str(strhashval, open); | 2493 | oo = find_openstateowner_str(strhashval, open); |
2488 | open->op_stateowner = sop; | 2494 | open->op_openowner = oo; |
2489 | if (!sop) { | 2495 | if (!oo) { |
2490 | /* Make sure the client's lease hasn't expired. */ | 2496 | /* Make sure the client's lease hasn't expired. */ |
2491 | clp = find_confirmed_client(clientid); | 2497 | clp = find_confirmed_client(clientid); |
2492 | if (clp == NULL) | 2498 | if (clp == NULL) |
2493 | return nfserr_expired; | 2499 | return nfserr_expired; |
2494 | goto renew; | 2500 | goto renew; |
2495 | } | 2501 | } |
2496 | if (!sop->so_confirmed) { | 2502 | if (!oo->oo_confirmed) { |
2497 | /* Replace unconfirmed owners without checking for replay. */ | 2503 | /* Replace unconfirmed owners without checking for replay. */ |
2498 | clp = sop->so_client; | 2504 | clp = oo->oo_owner.so_client; |
2499 | release_openowner(sop); | 2505 | release_openowner(oo); |
2500 | open->op_stateowner = NULL; | 2506 | open->op_openowner = NULL; |
2501 | goto renew; | 2507 | goto renew; |
2502 | } | 2508 | } |
2503 | status = nfsd4_check_seqid(cstate, sop, open->op_seqid); | 2509 | status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid); |
2504 | if (status) | 2510 | if (status) |
2505 | return status; | 2511 | return status; |
2506 | renew: | 2512 | renew: |
2507 | if (open->op_stateowner == NULL) { | 2513 | if (open->op_openowner == NULL) { |
2508 | sop = alloc_init_open_stateowner(strhashval, clp, open); | 2514 | oo = alloc_init_open_stateowner(strhashval, clp, open); |
2509 | if (sop == NULL) | 2515 | if (oo == NULL) |
2510 | return nfserr_jukebox; | 2516 | return nfserr_jukebox; |
2511 | open->op_stateowner = sop; | 2517 | open->op_openowner = oo; |
2512 | } | 2518 | } |
2513 | list_del_init(&sop->so_close_lru); | 2519 | list_del_init(&oo->oo_close_lru); |
2514 | renew_client(sop->so_client); | 2520 | renew_client(oo->oo_owner.so_client); |
2515 | return nfs_ok; | 2521 | return nfs_ok; |
2516 | } | 2522 | } |
2517 | 2523 | ||
@@ -2565,7 +2571,7 @@ out: | |||
2565 | return nfs_ok; | 2571 | return nfs_ok; |
2566 | if (status) | 2572 | if (status) |
2567 | return status; | 2573 | return status; |
2568 | open->op_stateowner->so_confirmed = 1; | 2574 | open->op_openowner->oo_confirmed = 1; |
2569 | return nfs_ok; | 2575 | return nfs_ok; |
2570 | } | 2576 | } |
2571 | 2577 | ||
@@ -2573,14 +2579,14 @@ static __be32 | |||
2573 | nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) | 2579 | nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) |
2574 | { | 2580 | { |
2575 | struct nfs4_stateid *local; | 2581 | struct nfs4_stateid *local; |
2576 | struct nfs4_stateowner *sop = open->op_stateowner; | 2582 | struct nfs4_openowner *oo = open->op_openowner; |
2577 | 2583 | ||
2578 | list_for_each_entry(local, &fp->fi_stateids, st_perfile) { | 2584 | list_for_each_entry(local, &fp->fi_stateids, st_perfile) { |
2579 | /* ignore lock owners */ | 2585 | /* ignore lock owners */ |
2580 | if (local->st_stateowner->so_is_open_owner == 0) | 2586 | if (local->st_stateowner->so_is_open_owner == 0) |
2581 | continue; | 2587 | continue; |
2582 | /* remember if we have seen this open owner */ | 2588 | /* remember if we have seen this open owner */ |
2583 | if (local->st_stateowner == sop) | 2589 | if (local->st_stateowner == &oo->oo_owner) |
2584 | *stpp = local; | 2590 | *stpp = local; |
2585 | /* check for conflicting share reservations */ | 2591 | /* check for conflicting share reservations */ |
2586 | if (!test_share(local, open)) | 2592 | if (!test_share(local, open)) |
@@ -2698,8 +2704,8 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c | |||
2698 | static void | 2704 | static void |
2699 | nfs4_set_claim_prev(struct nfsd4_open *open) | 2705 | nfs4_set_claim_prev(struct nfsd4_open *open) |
2700 | { | 2706 | { |
2701 | open->op_stateowner->so_confirmed = 1; | 2707 | open->op_openowner->oo_confirmed = 1; |
2702 | open->op_stateowner->so_client->cl_firststate = 1; | 2708 | open->op_openowner->oo_owner.so_client->cl_firststate = 1; |
2703 | } | 2709 | } |
2704 | 2710 | ||
2705 | /* Should we give out recallable state?: */ | 2711 | /* Should we give out recallable state?: */ |
@@ -2782,11 +2788,11 @@ static void | |||
2782 | nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp) | 2788 | nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp) |
2783 | { | 2789 | { |
2784 | struct nfs4_delegation *dp; | 2790 | struct nfs4_delegation *dp; |
2785 | struct nfs4_stateowner *sop = stp->st_stateowner; | 2791 | struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); |
2786 | int cb_up; | 2792 | int cb_up; |
2787 | int status, flag = 0; | 2793 | int status, flag = 0; |
2788 | 2794 | ||
2789 | cb_up = nfsd4_cb_channel_good(sop->so_client); | 2795 | cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); |
2790 | flag = NFS4_OPEN_DELEGATE_NONE; | 2796 | flag = NFS4_OPEN_DELEGATE_NONE; |
2791 | open->op_recall = 0; | 2797 | open->op_recall = 0; |
2792 | switch (open->op_claim_type) { | 2798 | switch (open->op_claim_type) { |
@@ -2802,7 +2808,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
2802 | * had the chance to reclaim theirs.... */ | 2808 | * had the chance to reclaim theirs.... */ |
2803 | if (locks_in_grace()) | 2809 | if (locks_in_grace()) |
2804 | goto out; | 2810 | goto out; |
2805 | if (!cb_up || !sop->so_confirmed) | 2811 | if (!cb_up || !oo->oo_confirmed) |
2806 | goto out; | 2812 | goto out; |
2807 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | 2813 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) |
2808 | flag = NFS4_OPEN_DELEGATE_WRITE; | 2814 | flag = NFS4_OPEN_DELEGATE_WRITE; |
@@ -2813,7 +2819,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
2813 | goto out; | 2819 | goto out; |
2814 | } | 2820 | } |
2815 | 2821 | ||
2816 | dp = alloc_init_deleg(sop->so_client, stp, fh, flag); | 2822 | dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag); |
2817 | if (dp == NULL) | 2823 | if (dp == NULL) |
2818 | goto out_no_deleg; | 2824 | goto out_no_deleg; |
2819 | status = nfs4_set_delegation(dp, flag); | 2825 | status = nfs4_set_delegation(dp, flag); |
@@ -2901,7 +2907,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2901 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); | 2907 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); |
2902 | 2908 | ||
2903 | if (nfsd4_has_session(&resp->cstate)) | 2909 | if (nfsd4_has_session(&resp->cstate)) |
2904 | open->op_stateowner->so_confirmed = 1; | 2910 | open->op_openowner->oo_confirmed = 1; |
2905 | 2911 | ||
2906 | /* | 2912 | /* |
2907 | * Attempt to hand out a delegation. No error return, because the | 2913 | * Attempt to hand out a delegation. No error return, because the |
@@ -2922,7 +2928,7 @@ out: | |||
2922 | * To finish the open response, we just need to set the rflags. | 2928 | * To finish the open response, we just need to set the rflags. |
2923 | */ | 2929 | */ |
2924 | open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; | 2930 | open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; |
2925 | if (!open->op_stateowner->so_confirmed && | 2931 | if (!open->op_openowner->oo_confirmed && |
2926 | !nfsd4_has_session(&resp->cstate)) | 2932 | !nfsd4_has_session(&resp->cstate)) |
2927 | open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; | 2933 | open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; |
2928 | 2934 | ||
@@ -2981,7 +2987,7 @@ static time_t | |||
2981 | nfs4_laundromat(void) | 2987 | nfs4_laundromat(void) |
2982 | { | 2988 | { |
2983 | struct nfs4_client *clp; | 2989 | struct nfs4_client *clp; |
2984 | struct nfs4_stateowner *sop; | 2990 | struct nfs4_openowner *oo; |
2985 | struct nfs4_delegation *dp; | 2991 | struct nfs4_delegation *dp; |
2986 | struct list_head *pos, *next, reaplist; | 2992 | struct list_head *pos, *next, reaplist; |
2987 | time_t cutoff = get_seconds() - nfsd4_lease; | 2993 | time_t cutoff = get_seconds() - nfsd4_lease; |
@@ -3038,16 +3044,16 @@ nfs4_laundromat(void) | |||
3038 | } | 3044 | } |
3039 | test_val = nfsd4_lease; | 3045 | test_val = nfsd4_lease; |
3040 | list_for_each_safe(pos, next, &close_lru) { | 3046 | list_for_each_safe(pos, next, &close_lru) { |
3041 | sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); | 3047 | oo = container_of(pos, struct nfs4_openowner, oo_close_lru); |
3042 | if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { | 3048 | if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { |
3043 | u = sop->so_time - cutoff; | 3049 | u = oo->oo_time - cutoff; |
3044 | if (test_val > u) | 3050 | if (test_val > u) |
3045 | test_val = u; | 3051 | test_val = u; |
3046 | break; | 3052 | break; |
3047 | } | 3053 | } |
3048 | dprintk("NFSD: purging unused open stateowner (so_id %d)\n", | 3054 | dprintk("NFSD: purging unused open stateowner (so_id %d)\n", |
3049 | sop->so_id); | 3055 | oo->oo_owner.so_id); |
3050 | release_openowner(sop); | 3056 | release_openowner(oo); |
3051 | } | 3057 | } |
3052 | if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) | 3058 | if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) |
3053 | clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; | 3059 | clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; |
@@ -3069,13 +3075,12 @@ laundromat_main(struct work_struct *not_used) | |||
3069 | queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); | 3075 | queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); |
3070 | } | 3076 | } |
3071 | 3077 | ||
3072 | static struct nfs4_stateowner * | 3078 | static struct nfs4_openowner * search_close_lru(u32 st_id) |
3073 | search_close_lru(u32 st_id) | ||
3074 | { | 3079 | { |
3075 | struct nfs4_stateowner *local; | 3080 | struct nfs4_openowner *local; |
3076 | 3081 | ||
3077 | list_for_each_entry(local, &close_lru, so_close_lru) { | 3082 | list_for_each_entry(local, &close_lru, oo_close_lru) { |
3078 | if (local->so_id == st_id) | 3083 | if (local->oo_owner.so_id == st_id) |
3079 | return local; | 3084 | return local; |
3080 | } | 3085 | } |
3081 | return NULL; | 3086 | return NULL; |
@@ -3209,7 +3214,8 @@ __be32 nfs4_validate_stateid(stateid_t *stateid, bool has_session) | |||
3209 | goto out; | 3214 | goto out; |
3210 | status = nfserr_bad_stateid; | 3215 | status = nfserr_bad_stateid; |
3211 | 3216 | ||
3212 | if (!stp->st_stateowner->so_confirmed) | 3217 | if (stp->st_stateowner->so_is_open_owner |
3218 | && !openowner(stp->st_stateowner)->oo_confirmed) | ||
3213 | goto out; | 3219 | goto out; |
3214 | 3220 | ||
3215 | status = check_stateid_generation(stateid, &stp->st_stateid, has_session); | 3221 | status = check_stateid_generation(stateid, &stp->st_stateid, has_session); |
@@ -3274,7 +3280,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
3274 | status = nfserr_bad_stateid; | 3280 | status = nfserr_bad_stateid; |
3275 | if (nfs4_check_fh(current_fh, stp)) | 3281 | if (nfs4_check_fh(current_fh, stp)) |
3276 | goto out; | 3282 | goto out; |
3277 | if (!stp->st_stateowner->so_confirmed) | 3283 | if (stp->st_stateowner->so_is_open_owner |
3284 | && !openowner(stp->st_stateowner)->oo_confirmed) | ||
3278 | goto out; | 3285 | goto out; |
3279 | status = check_stateid_generation(stateid, &stp->st_stateid, | 3286 | status = check_stateid_generation(stateid, &stp->st_stateid, |
3280 | nfsd4_has_session(cstate)); | 3287 | nfsd4_has_session(cstate)); |
@@ -3308,7 +3315,7 @@ nfsd4_free_delegation_stateid(stateid_t *stateid) | |||
3308 | static __be32 | 3315 | static __be32 |
3309 | nfsd4_free_lock_stateid(struct nfs4_stateid *stp) | 3316 | nfsd4_free_lock_stateid(struct nfs4_stateid *stp) |
3310 | { | 3317 | { |
3311 | if (check_for_locks(stp->st_file, stp->st_stateowner)) | 3318 | if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner))) |
3312 | return nfserr_locks_held; | 3319 | return nfserr_locks_held; |
3313 | release_lock_stateid(stp); | 3320 | release_lock_stateid(stp); |
3314 | return nfs_ok; | 3321 | return nfs_ok; |
@@ -3417,7 +3424,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
3417 | if (status) | 3424 | if (status) |
3418 | return status; | 3425 | return status; |
3419 | 3426 | ||
3420 | if (!sop->so_confirmed && !(flags & CONFIRM)) { | 3427 | if (sop->so_is_open_owner && !openowner(sop)->oo_confirmed |
3428 | && !(flags & CONFIRM)) { | ||
3421 | dprintk("NFSD: preprocess_seqid_op: stateowner not" | 3429 | dprintk("NFSD: preprocess_seqid_op: stateowner not" |
3422 | " confirmed yet!\n"); | 3430 | " confirmed yet!\n"); |
3423 | return nfserr_bad_stateid; | 3431 | return nfserr_bad_stateid; |
@@ -3434,7 +3442,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3434 | struct nfsd4_open_confirm *oc) | 3442 | struct nfsd4_open_confirm *oc) |
3435 | { | 3443 | { |
3436 | __be32 status; | 3444 | __be32 status; |
3437 | struct nfs4_stateowner *sop; | 3445 | struct nfs4_openowner *oo; |
3438 | struct nfs4_stateid *stp; | 3446 | struct nfs4_stateid *stp; |
3439 | 3447 | ||
3440 | dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", | 3448 | dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", |
@@ -3452,17 +3460,17 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3452 | CONFIRM | OPEN_STATE, &stp); | 3460 | CONFIRM | OPEN_STATE, &stp); |
3453 | if (status) | 3461 | if (status) |
3454 | goto out; | 3462 | goto out; |
3455 | sop = stp->st_stateowner; | 3463 | oo = openowner(stp->st_stateowner); |
3456 | status = nfserr_bad_stateid; | 3464 | status = nfserr_bad_stateid; |
3457 | if (sop->so_confirmed) | 3465 | if (oo->oo_confirmed) |
3458 | goto out; | 3466 | goto out; |
3459 | sop->so_confirmed = 1; | 3467 | oo->oo_confirmed = 1; |
3460 | update_stateid(&stp->st_stateid); | 3468 | update_stateid(&stp->st_stateid); |
3461 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); | 3469 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); |
3462 | dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", | 3470 | dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", |
3463 | __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); | 3471 | __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); |
3464 | 3472 | ||
3465 | nfsd4_create_clid_dir(sop->so_client); | 3473 | nfsd4_create_clid_dir(oo->oo_owner.so_client); |
3466 | status = nfs_ok; | 3474 | status = nfs_ok; |
3467 | out: | 3475 | out: |
3468 | if (!cstate->replay_owner) | 3476 | if (!cstate->replay_owner) |
@@ -3513,7 +3521,6 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, | |||
3513 | &od->od_stateid, OPEN_STATE, &stp); | 3521 | &od->od_stateid, OPEN_STATE, &stp); |
3514 | if (status) | 3522 | if (status) |
3515 | goto out; | 3523 | goto out; |
3516 | |||
3517 | status = nfserr_inval; | 3524 | status = nfserr_inval; |
3518 | if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { | 3525 | if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { |
3519 | dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", | 3526 | dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", |
@@ -3546,8 +3553,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3546 | struct nfsd4_close *close) | 3553 | struct nfsd4_close *close) |
3547 | { | 3554 | { |
3548 | __be32 status; | 3555 | __be32 status; |
3556 | struct nfs4_openowner *oo; | ||
3549 | struct nfs4_stateid *stp; | 3557 | struct nfs4_stateid *stp; |
3550 | struct nfs4_stateowner *so; | ||
3551 | 3558 | ||
3552 | dprintk("NFSD: nfsd4_close on file %.*s\n", | 3559 | dprintk("NFSD: nfsd4_close on file %.*s\n", |
3553 | (int)cstate->current_fh.fh_dentry->d_name.len, | 3560 | (int)cstate->current_fh.fh_dentry->d_name.len, |
@@ -3563,19 +3570,19 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3563 | * Also, we should make sure this isn't just the result of | 3570 | * Also, we should make sure this isn't just the result of |
3564 | * a replayed close: | 3571 | * a replayed close: |
3565 | */ | 3572 | */ |
3566 | so = search_close_lru(close->cl_stateid.si_stateownerid); | 3573 | oo = search_close_lru(close->cl_stateid.si_stateownerid); |
3567 | /* It's not stale; let's assume it's expired: */ | 3574 | /* It's not stale; let's assume it's expired: */ |
3568 | if (so == NULL) | 3575 | if (oo == NULL) |
3569 | goto out; | 3576 | goto out; |
3570 | cstate->replay_owner = so; | 3577 | cstate->replay_owner = &oo->oo_owner; |
3571 | status = nfsd4_check_seqid(cstate, so, close->cl_seqid); | 3578 | status = nfsd4_check_seqid(cstate, &oo->oo_owner, close->cl_seqid); |
3572 | if (status) | 3579 | if (status) |
3573 | goto out; | 3580 | goto out; |
3574 | status = nfserr_bad_seqid; | 3581 | status = nfserr_bad_seqid; |
3575 | } | 3582 | } |
3576 | if (status) | 3583 | if (status) |
3577 | goto out; | 3584 | goto out; |
3578 | so = stp->st_stateowner; | 3585 | oo = openowner(stp->st_stateowner); |
3579 | status = nfs_ok; | 3586 | status = nfs_ok; |
3580 | update_stateid(&stp->st_stateid); | 3587 | update_stateid(&stp->st_stateid); |
3581 | memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); | 3588 | memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); |
@@ -3587,8 +3594,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3587 | * released by the laundromat service after the lease period | 3594 | * released by the laundromat service after the lease period |
3588 | * to enable us to handle CLOSE replay | 3595 | * to enable us to handle CLOSE replay |
3589 | */ | 3596 | */ |
3590 | if (list_empty(&so->so_stateids)) | 3597 | if (list_empty(&oo->oo_owner.so_stateids)) |
3591 | move_to_close_lru(so); | 3598 | move_to_close_lru(oo); |
3592 | out: | 3599 | out: |
3593 | if (!cstate->replay_owner) | 3600 | if (!cstate->replay_owner) |
3594 | nfs4_unlock_state(); | 3601 | nfs4_unlock_state(); |
@@ -3768,17 +3775,17 @@ static const struct lock_manager_operations nfsd_posix_mng_ops = { | |||
3768 | static inline void | 3775 | static inline void |
3769 | nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) | 3776 | nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) |
3770 | { | 3777 | { |
3771 | struct nfs4_stateowner *sop; | 3778 | struct nfs4_lockowner *lo; |
3772 | 3779 | ||
3773 | if (fl->fl_lmops == &nfsd_posix_mng_ops) { | 3780 | if (fl->fl_lmops == &nfsd_posix_mng_ops) { |
3774 | sop = (struct nfs4_stateowner *) fl->fl_owner; | 3781 | lo = (struct nfs4_lockowner *) fl->fl_owner; |
3775 | deny->ld_owner.data = kmemdup(sop->so_owner.data, | 3782 | deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data, |
3776 | sop->so_owner.len, GFP_KERNEL); | 3783 | lo->lo_owner.so_owner.len, GFP_KERNEL); |
3777 | if (!deny->ld_owner.data) | 3784 | if (!deny->ld_owner.data) |
3778 | /* We just don't care that much */ | 3785 | /* We just don't care that much */ |
3779 | goto nevermind; | 3786 | goto nevermind; |
3780 | deny->ld_owner.len = sop->so_owner.len; | 3787 | deny->ld_owner.len = lo->lo_owner.so_owner.len; |
3781 | deny->ld_clientid = sop->so_client->cl_clientid; | 3788 | deny->ld_clientid = lo->lo_owner.so_client->cl_clientid; |
3782 | } else { | 3789 | } else { |
3783 | nevermind: | 3790 | nevermind: |
3784 | deny->ld_owner.len = 0; | 3791 | deny->ld_owner.len = 0; |
@@ -3795,8 +3802,8 @@ nevermind: | |||
3795 | deny->ld_type = NFS4_WRITE_LT; | 3802 | deny->ld_type = NFS4_WRITE_LT; |
3796 | } | 3803 | } |
3797 | 3804 | ||
3798 | static struct nfs4_stateowner * | 3805 | static struct nfs4_lockowner * |
3799 | find_lockstateowner_str(struct inode *inode, clientid_t *clid, | 3806 | find_lockowner_str(struct inode *inode, clientid_t *clid, |
3800 | struct xdr_netobj *owner) | 3807 | struct xdr_netobj *owner) |
3801 | { | 3808 | { |
3802 | unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); | 3809 | unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); |
@@ -3804,19 +3811,19 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid, | |||
3804 | 3811 | ||
3805 | list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { | 3812 | list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { |
3806 | if (same_owner_str(op, owner, clid)) | 3813 | if (same_owner_str(op, owner, clid)) |
3807 | return op; | 3814 | return lockowner(op); |
3808 | } | 3815 | } |
3809 | return NULL; | 3816 | return NULL; |
3810 | } | 3817 | } |
3811 | 3818 | ||
3812 | static void hash_lockowner(struct nfs4_stateowner *sop, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp) | 3819 | static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp) |
3813 | { | 3820 | { |
3814 | unsigned int idhashval; | 3821 | unsigned int idhashval; |
3815 | 3822 | ||
3816 | idhashval = lockownerid_hashval(sop->so_id); | 3823 | idhashval = lockownerid_hashval(lo->lo_owner.so_id); |
3817 | list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]); | 3824 | list_add(&lo->lo_owner.so_idhash, &lock_ownerid_hashtbl[idhashval]); |
3818 | list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]); | 3825 | list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]); |
3819 | list_add(&sop->so_perstateid, &open_stp->st_lockowners); | 3826 | list_add(&lo->lo_perstateid, &open_stp->st_lockowners); |
3820 | } | 3827 | } |
3821 | 3828 | ||
3822 | /* | 3829 | /* |
@@ -3827,28 +3834,27 @@ static void hash_lockowner(struct nfs4_stateowner *sop, unsigned int strhashval, | |||
3827 | * strhashval = lock_ownerstr_hashval | 3834 | * strhashval = lock_ownerstr_hashval |
3828 | */ | 3835 | */ |
3829 | 3836 | ||
3830 | static struct nfs4_stateowner * | 3837 | static struct nfs4_lockowner * |
3831 | alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) { | 3838 | alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) { |
3832 | struct nfs4_stateowner *sop; | 3839 | struct nfs4_lockowner *lo; |
3833 | 3840 | ||
3834 | sop = alloc_stateowner(&lock->lk_new_owner, clp); | 3841 | lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp); |
3835 | if (!sop) | 3842 | if (!lo) |
3836 | return NULL; | 3843 | return NULL; |
3837 | INIT_LIST_HEAD(&sop->so_stateids); | 3844 | INIT_LIST_HEAD(&lo->lo_owner.so_stateids); |
3838 | sop->so_is_open_owner = 0; | 3845 | lo->lo_owner.so_is_open_owner = 0; |
3839 | /* It is the openowner seqid that will be incremented in encode in the | 3846 | /* It is the openowner seqid that will be incremented in encode in the |
3840 | * case of new lockowners; so increment the lock seqid manually: */ | 3847 | * case of new lockowners; so increment the lock seqid manually: */ |
3841 | sop->so_seqid = lock->lk_new_lock_seqid + 1; | 3848 | lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1; |
3842 | sop->so_confirmed = 1; | 3849 | hash_lockowner(lo, strhashval, clp, open_stp); |
3843 | hash_lockowner(sop, strhashval, clp, open_stp); | 3850 | return lo; |
3844 | return sop; | ||
3845 | } | 3851 | } |
3846 | 3852 | ||
3847 | static struct nfs4_stateid * | 3853 | static struct nfs4_stateid * |
3848 | alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp) | 3854 | alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_stateid *open_stp) |
3849 | { | 3855 | { |
3850 | struct nfs4_stateid *stp; | 3856 | struct nfs4_stateid *stp; |
3851 | unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); | 3857 | unsigned int hashval = stateid_hashval(lo->lo_owner.so_id, fp->fi_id); |
3852 | 3858 | ||
3853 | stp = nfs4_alloc_stateid(); | 3859 | stp = nfs4_alloc_stateid(); |
3854 | if (stp == NULL) | 3860 | if (stp == NULL) |
@@ -3859,13 +3865,13 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc | |||
3859 | INIT_LIST_HEAD(&stp->st_lockowners); /* not used */ | 3865 | INIT_LIST_HEAD(&stp->st_lockowners); /* not used */ |
3860 | list_add(&stp->st_hash, &stateid_hashtbl[hashval]); | 3866 | list_add(&stp->st_hash, &stateid_hashtbl[hashval]); |
3861 | list_add(&stp->st_perfile, &fp->fi_stateids); | 3867 | list_add(&stp->st_perfile, &fp->fi_stateids); |
3862 | list_add(&stp->st_perstateowner, &sop->so_stateids); | 3868 | list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); |
3863 | stp->st_stateowner = sop; | 3869 | stp->st_stateowner = &lo->lo_owner; |
3864 | stp->st_type = NFS4_LOCK_STID; | 3870 | stp->st_type = NFS4_LOCK_STID; |
3865 | get_nfs4_file(fp); | 3871 | get_nfs4_file(fp); |
3866 | stp->st_file = fp; | 3872 | stp->st_file = fp; |
3867 | stp->st_stateid.si_boot = boot_time; | 3873 | stp->st_stateid.si_boot = boot_time; |
3868 | stp->st_stateid.si_stateownerid = sop->so_id; | 3874 | stp->st_stateid.si_stateownerid = lo->lo_owner.so_id; |
3869 | stp->st_stateid.si_fileid = fp->fi_id; | 3875 | stp->st_stateid.si_fileid = fp->fi_id; |
3870 | /* note will be incremented before first return to client: */ | 3876 | /* note will be incremented before first return to client: */ |
3871 | stp->st_stateid.si_generation = 0; | 3877 | stp->st_stateid.si_generation = 0; |
@@ -3902,8 +3908,8 @@ __be32 | |||
3902 | nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 3908 | nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
3903 | struct nfsd4_lock *lock) | 3909 | struct nfsd4_lock *lock) |
3904 | { | 3910 | { |
3905 | struct nfs4_stateowner *open_sop = NULL; | 3911 | struct nfs4_openowner *open_sop = NULL; |
3906 | struct nfs4_stateowner *lock_sop = NULL; | 3912 | struct nfs4_lockowner *lock_sop = NULL; |
3907 | struct nfs4_stateid *lock_stp; | 3913 | struct nfs4_stateid *lock_stp; |
3908 | struct nfs4_file *fp; | 3914 | struct nfs4_file *fp; |
3909 | struct file *filp = NULL; | 3915 | struct file *filp = NULL; |
@@ -3949,23 +3955,23 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3949 | OPEN_STATE, &open_stp); | 3955 | OPEN_STATE, &open_stp); |
3950 | if (status) | 3956 | if (status) |
3951 | goto out; | 3957 | goto out; |
3958 | open_sop = openowner(open_stp->st_stateowner); | ||
3952 | status = nfserr_bad_stateid; | 3959 | status = nfserr_bad_stateid; |
3953 | open_sop = open_stp->st_stateowner; | ||
3954 | if (!nfsd4_has_session(cstate) && | 3960 | if (!nfsd4_has_session(cstate) && |
3955 | !same_clid(&open_sop->so_client->cl_clientid, | 3961 | !same_clid(&open_sop->oo_owner.so_client->cl_clientid, |
3956 | &lock->v.new.clientid)) | 3962 | &lock->v.new.clientid)) |
3957 | goto out; | 3963 | goto out; |
3958 | /* create lockowner and lock stateid */ | 3964 | /* create lockowner and lock stateid */ |
3959 | fp = open_stp->st_file; | 3965 | fp = open_stp->st_file; |
3960 | strhashval = lock_ownerstr_hashval(fp->fi_inode, | 3966 | strhashval = lock_ownerstr_hashval(fp->fi_inode, |
3961 | open_sop->so_client->cl_clientid.cl_id, | 3967 | open_sop->oo_owner.so_client->cl_clientid.cl_id, |
3962 | &lock->v.new.owner); | 3968 | &lock->v.new.owner); |
3963 | /* XXX: Do we need to check for duplicate stateowners on | 3969 | /* XXX: Do we need to check for duplicate stateowners on |
3964 | * the same file, or should they just be allowed (and | 3970 | * the same file, or should they just be allowed (and |
3965 | * create new stateids)? */ | 3971 | * create new stateids)? */ |
3966 | status = nfserr_jukebox; | 3972 | status = nfserr_jukebox; |
3967 | lock_sop = alloc_init_lock_stateowner(strhashval, | 3973 | lock_sop = alloc_init_lock_stateowner(strhashval, |
3968 | open_sop->so_client, open_stp, lock); | 3974 | open_sop->oo_owner.so_client, open_stp, lock); |
3969 | if (lock_sop == NULL) | 3975 | if (lock_sop == NULL) |
3970 | goto out; | 3976 | goto out; |
3971 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); | 3977 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); |
@@ -3974,12 +3980,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3974 | } else { | 3980 | } else { |
3975 | /* lock (lock owner + lock stateid) already exists */ | 3981 | /* lock (lock owner + lock stateid) already exists */ |
3976 | status = nfs4_preprocess_seqid_op(cstate, | 3982 | status = nfs4_preprocess_seqid_op(cstate, |
3977 | lock->lk_old_lock_seqid, | 3983 | lock->lk_old_lock_seqid, |
3978 | &lock->lk_old_lock_stateid, | 3984 | &lock->lk_old_lock_stateid, |
3979 | LOCK_STATE, &lock_stp); | 3985 | LOCK_STATE, &lock_stp); |
3980 | if (status) | 3986 | if (status) |
3981 | goto out; | 3987 | goto out; |
3982 | lock_sop = lock_stp->st_stateowner; | 3988 | lock_sop = lockowner(lock_stp->st_stateowner); |
3983 | fp = lock_stp->st_file; | 3989 | fp = lock_stp->st_file; |
3984 | } | 3990 | } |
3985 | /* lock_sop and lock_stp have been created or found */ | 3991 | /* lock_sop and lock_stp have been created or found */ |
@@ -4092,7 +4098,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
4092 | { | 4098 | { |
4093 | struct inode *inode; | 4099 | struct inode *inode; |
4094 | struct file_lock file_lock; | 4100 | struct file_lock file_lock; |
4095 | struct nfs4_stateowner *so; | 4101 | struct nfs4_lockowner *lo; |
4096 | int error; | 4102 | int error; |
4097 | __be32 status; | 4103 | __be32 status; |
4098 | 4104 | ||
@@ -4128,10 +4134,9 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
4128 | goto out; | 4134 | goto out; |
4129 | } | 4135 | } |
4130 | 4136 | ||
4131 | so = find_lockstateowner_str(inode, | 4137 | lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner); |
4132 | &lockt->lt_clientid, &lockt->lt_owner); | 4138 | if (lo) |
4133 | if (so) | 4139 | file_lock.fl_owner = (fl_owner_t)lo; |
4134 | file_lock.fl_owner = (fl_owner_t)so; | ||
4135 | file_lock.fl_pid = current->tgid; | 4140 | file_lock.fl_pid = current->tgid; |
4136 | file_lock.fl_flags = FL_POSIX; | 4141 | file_lock.fl_flags = FL_POSIX; |
4137 | 4142 | ||
@@ -4186,7 +4191,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
4186 | BUG_ON(!filp); | 4191 | BUG_ON(!filp); |
4187 | locks_init_lock(&file_lock); | 4192 | locks_init_lock(&file_lock); |
4188 | file_lock.fl_type = F_UNLCK; | 4193 | file_lock.fl_type = F_UNLCK; |
4189 | file_lock.fl_owner = (fl_owner_t) stp->st_stateowner; | 4194 | file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner); |
4190 | file_lock.fl_pid = current->tgid; | 4195 | file_lock.fl_pid = current->tgid; |
4191 | file_lock.fl_file = filp; | 4196 | file_lock.fl_file = filp; |
4192 | file_lock.fl_flags = FL_POSIX; | 4197 | file_lock.fl_flags = FL_POSIX; |
@@ -4225,7 +4230,7 @@ out_nfserr: | |||
4225 | * 0: no locks held by lockowner | 4230 | * 0: no locks held by lockowner |
4226 | */ | 4231 | */ |
4227 | static int | 4232 | static int |
4228 | check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner) | 4233 | check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) |
4229 | { | 4234 | { |
4230 | struct file_lock **flpp; | 4235 | struct file_lock **flpp; |
4231 | struct inode *inode = filp->fi_inode; | 4236 | struct inode *inode = filp->fi_inode; |
@@ -4250,6 +4255,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, | |||
4250 | { | 4255 | { |
4251 | clientid_t *clid = &rlockowner->rl_clientid; | 4256 | clientid_t *clid = &rlockowner->rl_clientid; |
4252 | struct nfs4_stateowner *sop; | 4257 | struct nfs4_stateowner *sop; |
4258 | struct nfs4_lockowner *lo; | ||
4253 | struct nfs4_stateid *stp; | 4259 | struct nfs4_stateid *stp; |
4254 | struct xdr_netobj *owner = &rlockowner->rl_owner; | 4260 | struct xdr_netobj *owner = &rlockowner->rl_owner; |
4255 | struct list_head matches; | 4261 | struct list_head matches; |
@@ -4279,11 +4285,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, | |||
4279 | continue; | 4285 | continue; |
4280 | list_for_each_entry(stp, &sop->so_stateids, | 4286 | list_for_each_entry(stp, &sop->so_stateids, |
4281 | st_perstateowner) { | 4287 | st_perstateowner) { |
4282 | if (check_for_locks(stp->st_file, sop)) | 4288 | lo = lockowner(sop); |
4289 | if (check_for_locks(stp->st_file, lo)) | ||
4283 | goto out; | 4290 | goto out; |
4284 | /* Note: so_perclient unused for lockowners, | 4291 | list_add(&lo->lo_list, &matches); |
4285 | * so it's OK to fool with here. */ | ||
4286 | list_add(&sop->so_perclient, &matches); | ||
4287 | } | 4292 | } |
4288 | } | 4293 | } |
4289 | } | 4294 | } |
@@ -4292,12 +4297,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, | |||
4292 | * have been checked. */ | 4297 | * have been checked. */ |
4293 | status = nfs_ok; | 4298 | status = nfs_ok; |
4294 | while (!list_empty(&matches)) { | 4299 | while (!list_empty(&matches)) { |
4295 | sop = list_entry(matches.next, struct nfs4_stateowner, | 4300 | lo = list_entry(matches.next, struct nfs4_lockowner, |
4296 | so_perclient); | 4301 | lo_list); |
4297 | /* unhash_stateowner deletes so_perclient only | 4302 | /* unhash_stateowner deletes so_perclient only |
4298 | * for openowners. */ | 4303 | * for openowners. */ |
4299 | list_del(&sop->so_perclient); | 4304 | list_del(&lo->lo_list); |
4300 | release_lockowner(sop); | 4305 | release_lockowner(lo); |
4301 | } | 4306 | } |
4302 | out: | 4307 | out: |
4303 | nfs4_unlock_state(); | 4308 | nfs4_unlock_state(); |