diff options
| -rw-r--r-- | fs/nfsd/nfs4state.c | 125 |
1 files changed, 61 insertions, 64 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c4f2b0f63e46..84d2dd327b2d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -316,64 +316,6 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; | |||
| 316 | static struct list_head client_lru; | 316 | static struct list_head client_lru; |
| 317 | static struct list_head close_lru; | 317 | static struct list_head close_lru; |
| 318 | 318 | ||
| 319 | static void unhash_generic_stateid(struct nfs4_stateid *stp) | ||
| 320 | { | ||
| 321 | list_del(&stp->st_hash); | ||
| 322 | list_del(&stp->st_perfile); | ||
| 323 | list_del(&stp->st_perstateowner); | ||
| 324 | } | ||
| 325 | |||
| 326 | static void free_generic_stateid(struct nfs4_stateid *stp) | ||
| 327 | { | ||
| 328 | put_nfs4_file(stp->st_file); | ||
| 329 | kmem_cache_free(stateid_slab, stp); | ||
| 330 | } | ||
| 331 | |||
| 332 | static void release_lock_stateid(struct nfs4_stateid *stp) | ||
| 333 | { | ||
| 334 | struct file *file; | ||
| 335 | |||
| 336 | unhash_generic_stateid(stp); | ||
| 337 | file = find_any_file(stp->st_file); | ||
| 338 | if (file) | ||
| 339 | locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); | ||
| 340 | free_generic_stateid(stp); | ||
| 341 | } | ||
| 342 | |||
| 343 | static void unhash_lockowner(struct nfs4_stateowner *sop) | ||
| 344 | { | ||
| 345 | struct nfs4_stateid *stp; | ||
| 346 | |||
| 347 | list_del(&sop->so_idhash); | ||
| 348 | list_del(&sop->so_strhash); | ||
| 349 | list_del(&sop->so_perstateid); | ||
| 350 | while (!list_empty(&sop->so_stateids)) { | ||
| 351 | stp = list_first_entry(&sop->so_stateids, | ||
| 352 | struct nfs4_stateid, st_perstateowner); | ||
| 353 | release_lock_stateid(stp); | ||
| 354 | } | ||
| 355 | } | ||
| 356 | |||
| 357 | static void release_lockowner(struct nfs4_stateowner *sop) | ||
| 358 | { | ||
| 359 | unhash_lockowner(sop); | ||
| 360 | nfs4_put_stateowner(sop); | ||
| 361 | } | ||
| 362 | |||
| 363 | static void | ||
| 364 | release_stateid_lockowners(struct nfs4_stateid *open_stp) | ||
| 365 | { | ||
| 366 | struct nfs4_stateowner *lock_sop; | ||
| 367 | |||
| 368 | while (!list_empty(&open_stp->st_lockowners)) { | ||
| 369 | lock_sop = list_entry(open_stp->st_lockowners.next, | ||
| 370 | struct nfs4_stateowner, so_perstateid); | ||
| 371 | /* list_del(&open_stp->st_lockowners); */ | ||
| 372 | BUG_ON(lock_sop->so_is_open_owner); | ||
| 373 | release_lockowner(lock_sop); | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | /* | 319 | /* |
| 378 | * We store the NONE, READ, WRITE, and BOTH bits separately in the | 320 | * We store the NONE, READ, WRITE, and BOTH bits separately in the |
| 379 | * st_{access,deny}_bmap field of the stateid, in order to track not | 321 | * st_{access,deny}_bmap field of the stateid, in order to track not |
| @@ -446,6 +388,64 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp) | |||
| 446 | return nfs4_access_to_omode(access); | 388 | return nfs4_access_to_omode(access); |
| 447 | } | 389 | } |
| 448 | 390 | ||
| 391 | static void unhash_generic_stateid(struct nfs4_stateid *stp) | ||
| 392 | { | ||
| 393 | list_del(&stp->st_hash); | ||
| 394 | list_del(&stp->st_perfile); | ||
| 395 | list_del(&stp->st_perstateowner); | ||
| 396 | } | ||
| 397 | |||
| 398 | static void free_generic_stateid(struct nfs4_stateid *stp) | ||
| 399 | { | ||
| 400 | put_nfs4_file(stp->st_file); | ||
| 401 | kmem_cache_free(stateid_slab, stp); | ||
| 402 | } | ||
| 403 | |||
| 404 | static void release_lock_stateid(struct nfs4_stateid *stp) | ||
| 405 | { | ||
| 406 | struct file *file; | ||
| 407 | |||
| 408 | unhash_generic_stateid(stp); | ||
| 409 | file = find_any_file(stp->st_file); | ||
| 410 | if (file) | ||
| 411 | locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); | ||
| 412 | free_generic_stateid(stp); | ||
| 413 | } | ||
| 414 | |||
| 415 | static void unhash_lockowner(struct nfs4_stateowner *sop) | ||
| 416 | { | ||
| 417 | struct nfs4_stateid *stp; | ||
| 418 | |||
| 419 | list_del(&sop->so_idhash); | ||
| 420 | list_del(&sop->so_strhash); | ||
| 421 | list_del(&sop->so_perstateid); | ||
| 422 | while (!list_empty(&sop->so_stateids)) { | ||
| 423 | stp = list_first_entry(&sop->so_stateids, | ||
| 424 | struct nfs4_stateid, st_perstateowner); | ||
| 425 | release_lock_stateid(stp); | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | static void release_lockowner(struct nfs4_stateowner *sop) | ||
| 430 | { | ||
| 431 | unhash_lockowner(sop); | ||
| 432 | nfs4_put_stateowner(sop); | ||
| 433 | } | ||
| 434 | |||
| 435 | static void | ||
| 436 | release_stateid_lockowners(struct nfs4_stateid *open_stp) | ||
| 437 | { | ||
| 438 | struct nfs4_stateowner *lock_sop; | ||
| 439 | |||
| 440 | while (!list_empty(&open_stp->st_lockowners)) { | ||
| 441 | lock_sop = list_entry(open_stp->st_lockowners.next, | ||
| 442 | struct nfs4_stateowner, so_perstateid); | ||
| 443 | /* list_del(&open_stp->st_lockowners); */ | ||
| 444 | BUG_ON(lock_sop->so_is_open_owner); | ||
| 445 | release_lockowner(lock_sop); | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | static void release_open_stateid(struct nfs4_stateid *stp) | 449 | static void release_open_stateid(struct nfs4_stateid *stp) |
| 450 | { | 450 | { |
| 451 | int oflag = nfs4_access_bmap_to_omode(stp); | 451 | int oflag = nfs4_access_bmap_to_omode(stp); |
| @@ -3764,7 +3764,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3764 | struct file_lock conflock; | 3764 | struct file_lock conflock; |
| 3765 | __be32 status = 0; | 3765 | __be32 status = 0; |
| 3766 | unsigned int strhashval; | 3766 | unsigned int strhashval; |
| 3767 | unsigned int cmd; | ||
| 3768 | int err; | 3767 | int err; |
| 3769 | 3768 | ||
| 3770 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", | 3769 | dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", |
| @@ -3851,8 +3850,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3851 | filp = find_readable_file(lock_stp->st_file); | 3850 | filp = find_readable_file(lock_stp->st_file); |
| 3852 | } | 3851 | } |
| 3853 | file_lock.fl_type = F_RDLCK; | 3852 | file_lock.fl_type = F_RDLCK; |
| 3854 | cmd = F_SETLK; | 3853 | break; |
| 3855 | break; | ||
| 3856 | case NFS4_WRITE_LT: | 3854 | case NFS4_WRITE_LT: |
| 3857 | case NFS4_WRITEW_LT: | 3855 | case NFS4_WRITEW_LT: |
| 3858 | if (find_writeable_file(lock_stp->st_file)) { | 3856 | if (find_writeable_file(lock_stp->st_file)) { |
| @@ -3860,8 +3858,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3860 | filp = find_writeable_file(lock_stp->st_file); | 3858 | filp = find_writeable_file(lock_stp->st_file); |
| 3861 | } | 3859 | } |
| 3862 | file_lock.fl_type = F_WRLCK; | 3860 | file_lock.fl_type = F_WRLCK; |
| 3863 | cmd = F_SETLK; | 3861 | break; |
| 3864 | break; | ||
| 3865 | default: | 3862 | default: |
| 3866 | status = nfserr_inval; | 3863 | status = nfserr_inval; |
| 3867 | goto out; | 3864 | goto out; |
| @@ -3885,7 +3882,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3885 | * Note: locks.c uses the BKL to protect the inode's lock list. | 3882 | * Note: locks.c uses the BKL to protect the inode's lock list. |
| 3886 | */ | 3883 | */ |
| 3887 | 3884 | ||
| 3888 | err = vfs_lock_file(filp, cmd, &file_lock, &conflock); | 3885 | err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock); |
| 3889 | switch (-err) { | 3886 | switch (-err) { |
| 3890 | case 0: /* success! */ | 3887 | case 0: /* success! */ |
| 3891 | update_stateid(&lock_stp->st_stateid); | 3888 | update_stateid(&lock_stp->st_stateid); |
