aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c303
1 files changed, 182 insertions, 121 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b996a4badeb8..7ab572f9f388 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -162,6 +162,28 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
162static struct list_head file_hashtbl[FILE_HASH_SIZE]; 162static struct list_head file_hashtbl[FILE_HASH_SIZE];
163static struct list_head stateid_hashtbl[STATEID_HASH_SIZE]; 163static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
164 164
165static inline void nfs4_file_get_access(struct nfs4_file *fp, int oflag)
166{
167 BUG_ON(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR]));
168 atomic_inc(&fp->fi_access[oflag]);
169}
170
171static inline void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
172{
173 if (fp->fi_fds[oflag]) {
174 fput(fp->fi_fds[oflag]);
175 fp->fi_fds[oflag] = NULL;
176 }
177}
178
179static inline void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
180{
181 if (atomic_dec_and_test(&fp->fi_access[oflag])) {
182 nfs4_file_put_fd(fp, O_RDWR);
183 nfs4_file_put_fd(fp, oflag);
184 }
185}
186
165static struct nfs4_delegation * 187static struct nfs4_delegation *
166alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type) 188alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type)
167{ 189{
@@ -191,9 +213,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
191 dp->dl_client = clp; 213 dp->dl_client = clp;
192 get_nfs4_file(fp); 214 get_nfs4_file(fp);
193 dp->dl_file = fp; 215 dp->dl_file = fp;
216 nfs4_file_get_access(fp, O_RDONLY);
194 dp->dl_flock = NULL; 217 dp->dl_flock = NULL;
195 get_file(stp->st_vfs_file);
196 dp->dl_vfs_file = stp->st_vfs_file;
197 dp->dl_type = type; 218 dp->dl_type = type;
198 dp->dl_ident = cb->cb_ident; 219 dp->dl_ident = cb->cb_ident;
199 dp->dl_stateid.si_boot = boot_time; 220 dp->dl_stateid.si_boot = boot_time;
@@ -228,15 +249,12 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
228static void 249static void
229nfs4_close_delegation(struct nfs4_delegation *dp) 250nfs4_close_delegation(struct nfs4_delegation *dp)
230{ 251{
231 struct file *filp = dp->dl_vfs_file; 252 struct file *filp = find_readable_file(dp->dl_file);
232 253
233 dprintk("NFSD: close_delegation dp %p\n",dp); 254 dprintk("NFSD: close_delegation dp %p\n",dp);
234 dp->dl_vfs_file = NULL;
235 /* The following nfsd_close may not actually close the file,
236 * but we want to remove the lease in any case. */
237 if (dp->dl_flock) 255 if (dp->dl_flock)
238 vfs_setlease(filp, F_UNLCK, &dp->dl_flock); 256 vfs_setlease(filp, F_UNLCK, &dp->dl_flock);
239 nfsd_close(filp); 257 nfs4_file_put_access(dp->dl_file, O_RDONLY);
240} 258}
241 259
242/* Called under the state lock. */ 260/* Called under the state lock. */
@@ -308,8 +326,12 @@ static void free_generic_stateid(struct nfs4_stateid *stp)
308 326
309static void release_lock_stateid(struct nfs4_stateid *stp) 327static void release_lock_stateid(struct nfs4_stateid *stp)
310{ 328{
329 struct file *file;
330
311 unhash_generic_stateid(stp); 331 unhash_generic_stateid(stp);
312 locks_remove_posix(stp->st_vfs_file, (fl_owner_t)stp->st_stateowner); 332 file = find_any_file(stp->st_file);
333 if (file)
334 locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
313 free_generic_stateid(stp); 335 free_generic_stateid(stp);
314} 336}
315 337
@@ -347,11 +369,85 @@ release_stateid_lockowners(struct nfs4_stateid *open_stp)
347 } 369 }
348} 370}
349 371
372/*
373 * We store the NONE, READ, WRITE, and BOTH bits separately in the
374 * st_{access,deny}_bmap field of the stateid, in order to track not
375 * only what share bits are currently in force, but also what
376 * combinations of share bits previous opens have used. This allows us
377 * to enforce the recommendation of rfc 3530 14.2.19 that the server
378 * return an error if the client attempt to downgrade to a combination
379 * of share bits not explicable by closing some of its previous opens.
380 *
381 * XXX: This enforcement is actually incomplete, since we don't keep
382 * track of access/deny bit combinations; so, e.g., we allow:
383 *
384 * OPEN allow read, deny write
385 * OPEN allow both, deny none
386 * DOWNGRADE allow read, deny none
387 *
388 * which we should reject.
389 */
390static void
391set_access(unsigned int *access, unsigned long bmap) {
392 int i;
393
394 *access = 0;
395 for (i = 1; i < 4; i++) {
396 if (test_bit(i, &bmap))
397 *access |= i;
398 }
399}
400
401static void
402set_deny(unsigned int *deny, unsigned long bmap) {
403 int i;
404
405 *deny = 0;
406 for (i = 0; i < 4; i++) {
407 if (test_bit(i, &bmap))
408 *deny |= i ;
409 }
410}
411
412static int
413test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
414 unsigned int access, deny;
415
416 set_access(&access, stp->st_access_bmap);
417 set_deny(&deny, stp->st_deny_bmap);
418 if ((access & open->op_share_deny) || (deny & open->op_share_access))
419 return 0;
420 return 1;
421}
422
423static int nfs4_access_to_omode(u32 access)
424{
425 switch (access) {
426 case NFS4_SHARE_ACCESS_READ:
427 return O_RDONLY;
428 case NFS4_SHARE_ACCESS_WRITE:
429 return O_WRONLY;
430 case NFS4_SHARE_ACCESS_BOTH:
431 return O_RDWR;
432 }
433 BUG();
434}
435
436static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
437{
438 unsigned int access;
439
440 set_access(&access, stp->st_access_bmap);
441 return nfs4_access_to_omode(access);
442}
443
350static void release_open_stateid(struct nfs4_stateid *stp) 444static void release_open_stateid(struct nfs4_stateid *stp)
351{ 445{
446 int oflag = nfs4_access_bmap_to_omode(stp);
447
352 unhash_generic_stateid(stp); 448 unhash_generic_stateid(stp);
353 release_stateid_lockowners(stp); 449 release_stateid_lockowners(stp);
354 nfsd_close(stp->st_vfs_file); 450 nfs4_file_put_access(stp->st_file, oflag);
355 free_generic_stateid(stp); 451 free_generic_stateid(stp);
356} 452}
357 453
@@ -1763,6 +1859,8 @@ alloc_init_file(struct inode *ino)
1763 fp->fi_inode = igrab(ino); 1859 fp->fi_inode = igrab(ino);
1764 fp->fi_id = current_fileid++; 1860 fp->fi_id = current_fileid++;
1765 fp->fi_had_conflict = false; 1861 fp->fi_had_conflict = false;
1862 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
1863 memset(fp->fi_access, 0, sizeof(fp->fi_access));
1766 spin_lock(&recall_lock); 1864 spin_lock(&recall_lock);
1767 list_add(&fp->fi_hash, &file_hashtbl[hashval]); 1865 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
1768 spin_unlock(&recall_lock); 1866 spin_unlock(&recall_lock);
@@ -1974,57 +2072,6 @@ static inline int deny_valid(u32 x)
1974} 2072}
1975 2073
1976/* 2074/*
1977 * We store the NONE, READ, WRITE, and BOTH bits separately in the
1978 * st_{access,deny}_bmap field of the stateid, in order to track not
1979 * only what share bits are currently in force, but also what
1980 * combinations of share bits previous opens have used. This allows us
1981 * to enforce the recommendation of rfc 3530 14.2.19 that the server
1982 * return an error if the client attempt to downgrade to a combination
1983 * of share bits not explicable by closing some of its previous opens.
1984 *
1985 * XXX: This enforcement is actually incomplete, since we don't keep
1986 * track of access/deny bit combinations; so, e.g., we allow:
1987 *
1988 * OPEN allow read, deny write
1989 * OPEN allow both, deny none
1990 * DOWNGRADE allow read, deny none
1991 *
1992 * which we should reject.
1993 */
1994static void
1995set_access(unsigned int *access, unsigned long bmap) {
1996 int i;
1997
1998 *access = 0;
1999 for (i = 1; i < 4; i++) {
2000 if (test_bit(i, &bmap))
2001 *access |= i;
2002 }
2003}
2004
2005static void
2006set_deny(unsigned int *deny, unsigned long bmap) {
2007 int i;
2008
2009 *deny = 0;
2010 for (i = 0; i < 4; i++) {
2011 if (test_bit(i, &bmap))
2012 *deny |= i ;
2013 }
2014}
2015
2016static int
2017test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
2018 unsigned int access, deny;
2019
2020 set_access(&access, stp->st_access_bmap);
2021 set_deny(&deny, stp->st_deny_bmap);
2022 if ((access & open->op_share_deny) || (deny & open->op_share_access))
2023 return 0;
2024 return 1;
2025}
2026
2027/*
2028 * Called to check deny when READ with all zero stateid or 2075 * Called to check deny when READ with all zero stateid or
2029 * WRITE with all zero or all one stateid 2076 * WRITE with all zero or all one stateid
2030 */ 2077 */
@@ -2055,14 +2102,12 @@ out:
2055} 2102}
2056 2103
2057static inline void 2104static inline void
2058nfs4_file_downgrade(struct file *filp, unsigned int share_access) 2105nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
2059{ 2106{
2060 if (share_access & NFS4_SHARE_ACCESS_WRITE) { 2107 if (share_access & NFS4_SHARE_ACCESS_WRITE)
2061 drop_file_write_access(filp); 2108 nfs4_file_put_access(fp, O_WRONLY);
2062 spin_lock(&filp->f_lock); 2109 if (share_access & NFS4_SHARE_ACCESS_READ)
2063 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; 2110 nfs4_file_put_access(fp, O_RDONLY);
2064 spin_unlock(&filp->f_lock);
2065 }
2066} 2111}
2067 2112
2068/* 2113/*
@@ -2328,32 +2373,42 @@ static inline int nfs4_access_to_access(u32 nfs4_access)
2328 return flags; 2373 return flags;
2329} 2374}
2330 2375
2376static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
2377*fp, struct svc_fh *cur_fh, u32 nfs4_access)
2378{
2379 __be32 status;
2380 int oflag = nfs4_access_to_omode(nfs4_access);
2381 int access = nfs4_access_to_access(nfs4_access);
2382
2383 if (!fp->fi_fds[oflag]) {
2384 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2385 &fp->fi_fds[oflag]);
2386 if (status == nfserr_dropit)
2387 status = nfserr_jukebox;
2388 if (status)
2389 return status;
2390 }
2391 nfs4_file_get_access(fp, oflag);
2392
2393 return nfs_ok;
2394}
2395
2331static __be32 2396static __be32
2332nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, 2397nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
2333 struct nfs4_delegation *dp, 2398 struct nfs4_file *fp, struct svc_fh *cur_fh,
2334 struct svc_fh *cur_fh, struct nfsd4_open *open) 2399 struct nfsd4_open *open)
2335{ 2400{
2336 struct nfs4_stateid *stp; 2401 struct nfs4_stateid *stp;
2402 __be32 status;
2337 2403
2338 stp = nfs4_alloc_stateid(); 2404 stp = nfs4_alloc_stateid();
2339 if (stp == NULL) 2405 if (stp == NULL)
2340 return nfserr_resource; 2406 return nfserr_resource;
2341 2407
2342 if (dp) { 2408 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access);
2343 get_file(dp->dl_vfs_file); 2409 if (status) {
2344 stp->st_vfs_file = dp->dl_vfs_file; 2410 kmem_cache_free(stateid_slab, stp);
2345 } else { 2411 return status;
2346 __be32 status;
2347 int access = nfs4_access_to_access(open->op_share_access);
2348
2349 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2350 &stp->st_vfs_file);
2351 if (status) {
2352 if (status == nfserr_dropit)
2353 status = nfserr_jukebox;
2354 kmem_cache_free(stateid_slab, stp);
2355 return status;
2356 }
2357 } 2412 }
2358 *stpp = stp; 2413 *stpp = stp;
2359 return 0; 2414 return 0;
@@ -2375,36 +2430,29 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
2375} 2430}
2376 2431
2377static __be32 2432static __be32
2378nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) 2433nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
2379{ 2434{
2380 struct file *filp = stp->st_vfs_file; 2435 u32 op_share_access, new_access;
2381 struct inode *inode = filp->f_path.dentry->d_inode;
2382 unsigned int share_access, new_writer;
2383 u32 op_share_access;
2384 __be32 status; 2436 __be32 status;
2385 2437
2386 set_access(&share_access, stp->st_access_bmap); 2438 set_access(&new_access, stp->st_access_bmap);
2387 new_writer = (~share_access) & open->op_share_access 2439 new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK;
2388 & NFS4_SHARE_ACCESS_WRITE; 2440
2389 2441 if (new_access) {
2390 if (new_writer) { 2442 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, new_access);
2391 int err = get_write_access(inode); 2443 if (status)
2392 if (err) 2444 return status;
2393 return nfserrno(err);
2394 err = mnt_want_write(cur_fh->fh_export->ex_path.mnt);
2395 if (err)
2396 return nfserrno(err);
2397 file_take_write(filp);
2398 } 2445 }
2399 status = nfsd4_truncate(rqstp, cur_fh, open); 2446 status = nfsd4_truncate(rqstp, cur_fh, open);
2400 if (status) { 2447 if (status) {
2401 if (new_writer) 2448 if (new_access) {
2402 put_write_access(inode); 2449 int oflag = nfs4_access_to_omode(new_access);
2450 nfs4_file_put_access(fp, oflag);
2451 }
2403 return status; 2452 return status;
2404 } 2453 }
2405 /* remember the open */ 2454 /* remember the open */
2406 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; 2455 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
2407 filp->f_mode |= op_share_access;
2408 __set_bit(op_share_access, &stp->st_access_bmap); 2456 __set_bit(op_share_access, &stp->st_access_bmap);
2409 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2457 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2410 2458
@@ -2468,13 +2516,14 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2468 fl.fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; 2516 fl.fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
2469 fl.fl_end = OFFSET_MAX; 2517 fl.fl_end = OFFSET_MAX;
2470 fl.fl_owner = (fl_owner_t)dp; 2518 fl.fl_owner = (fl_owner_t)dp;
2471 fl.fl_file = stp->st_vfs_file; 2519 fl.fl_file = find_readable_file(stp->st_file);
2520 BUG_ON(!fl.fl_file);
2472 fl.fl_pid = current->tgid; 2521 fl.fl_pid = current->tgid;
2473 2522
2474 /* vfs_setlease checks to see if delegation should be handed out. 2523 /* vfs_setlease checks to see if delegation should be handed out.
2475 * the lock_manager callbacks fl_mylease and fl_change are used 2524 * the lock_manager callbacks fl_mylease and fl_change are used
2476 */ 2525 */
2477 if ((status = vfs_setlease(stp->st_vfs_file, fl.fl_type, &flp))) { 2526 if ((status = vfs_setlease(fl.fl_file, fl.fl_type, &flp))) {
2478 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 2527 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
2479 unhash_delegation(dp); 2528 unhash_delegation(dp);
2480 flag = NFS4_OPEN_DELEGATE_NONE; 2529 flag = NFS4_OPEN_DELEGATE_NONE;
@@ -2538,13 +2587,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2538 */ 2587 */
2539 if (stp) { 2588 if (stp) {
2540 /* Stateid was found, this is an OPEN upgrade */ 2589 /* Stateid was found, this is an OPEN upgrade */
2541 status = nfs4_upgrade_open(rqstp, current_fh, stp, open); 2590 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
2542 if (status) 2591 if (status)
2543 goto out; 2592 goto out;
2544 update_stateid(&stp->st_stateid); 2593 update_stateid(&stp->st_stateid);
2545 } else { 2594 } else {
2546 /* Stateid was not found, this is a new OPEN */ 2595 status = nfs4_new_open(rqstp, &stp, fp, current_fh, open);
2547 status = nfs4_new_open(rqstp, &stp, dp, current_fh, open);
2548 if (status) 2596 if (status)
2549 goto out; 2597 goto out;
2550 init_stateid(stp, fp, open); 2598 init_stateid(stp, fp, open);
@@ -2746,7 +2794,7 @@ search_close_lru(u32 st_id, int flags)
2746static inline int 2794static inline int
2747nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp) 2795nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
2748{ 2796{
2749 return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode; 2797 return fhp->fh_dentry->d_inode != stp->st_file->fi_inode;
2750} 2798}
2751 2799
2752static int 2800static int
@@ -2894,7 +2942,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2894 goto out; 2942 goto out;
2895 renew_client(dp->dl_client); 2943 renew_client(dp->dl_client);
2896 if (filpp) 2944 if (filpp)
2897 *filpp = dp->dl_vfs_file; 2945 *filpp = find_readable_file(dp->dl_file);
2946 BUG_ON(!*filpp);
2898 } else { /* open or lock stateid */ 2947 } else { /* open or lock stateid */
2899 stp = find_stateid(stateid, flags); 2948 stp = find_stateid(stateid, flags);
2900 if (!stp) 2949 if (!stp)
@@ -2911,8 +2960,13 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
2911 if (status) 2960 if (status)
2912 goto out; 2961 goto out;
2913 renew_client(stp->st_stateowner->so_client); 2962 renew_client(stp->st_stateowner->so_client);
2914 if (filpp) 2963 if (filpp) {
2915 *filpp = stp->st_vfs_file; 2964 if (flags & RD_STATE)
2965 *filpp = find_readable_file(stp->st_file);
2966 else
2967 *filpp = find_writeable_file(stp->st_file);
2968 BUG_ON(!*filpp); /* assured by check_openmode */
2969 }
2916 } 2970 }
2917 status = nfs_ok; 2971 status = nfs_ok;
2918out: 2972out:
@@ -3148,8 +3202,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3148 goto out; 3202 goto out;
3149 } 3203 }
3150 set_access(&share_access, stp->st_access_bmap); 3204 set_access(&share_access, stp->st_access_bmap);
3151 nfs4_file_downgrade(stp->st_vfs_file, 3205 nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access);
3152 share_access & ~od->od_share_access);
3153 3206
3154 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap); 3207 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
3155 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3208 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
@@ -3468,7 +3521,6 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3468 stp->st_stateid.si_stateownerid = sop->so_id; 3521 stp->st_stateid.si_stateownerid = sop->so_id;
3469 stp->st_stateid.si_fileid = fp->fi_id; 3522 stp->st_stateid.si_fileid = fp->fi_id;
3470 stp->st_stateid.si_generation = 0; 3523 stp->st_stateid.si_generation = 0;
3471 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
3472 stp->st_deny_bmap = open_stp->st_deny_bmap; 3524 stp->st_deny_bmap = open_stp->st_deny_bmap;
3473 stp->st_openstp = open_stp; 3525 stp->st_openstp = open_stp;
3474 3526
@@ -3568,7 +3620,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3568 lock_sop = lock->lk_replay_owner; 3620 lock_sop = lock->lk_replay_owner;
3569 } 3621 }
3570 /* lock->lk_replay_owner and lock_stp have been created or found */ 3622 /* lock->lk_replay_owner and lock_stp have been created or found */
3571 filp = lock_stp->st_vfs_file;
3572 3623
3573 status = nfserr_grace; 3624 status = nfserr_grace;
3574 if (locks_in_grace() && !lock->lk_reclaim) 3625 if (locks_in_grace() && !lock->lk_reclaim)
@@ -3581,11 +3632,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3581 switch (lock->lk_type) { 3632 switch (lock->lk_type) {
3582 case NFS4_READ_LT: 3633 case NFS4_READ_LT:
3583 case NFS4_READW_LT: 3634 case NFS4_READW_LT:
3635 filp = find_readable_file(lock_stp->st_file);
3584 file_lock.fl_type = F_RDLCK; 3636 file_lock.fl_type = F_RDLCK;
3585 cmd = F_SETLK; 3637 cmd = F_SETLK;
3586 break; 3638 break;
3587 case NFS4_WRITE_LT: 3639 case NFS4_WRITE_LT:
3588 case NFS4_WRITEW_LT: 3640 case NFS4_WRITEW_LT:
3641 filp = find_writeable_file(lock_stp->st_file);
3589 file_lock.fl_type = F_WRLCK; 3642 file_lock.fl_type = F_WRLCK;
3590 cmd = F_SETLK; 3643 cmd = F_SETLK;
3591 break; 3644 break;
@@ -3593,6 +3646,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3593 status = nfserr_inval; 3646 status = nfserr_inval;
3594 goto out; 3647 goto out;
3595 } 3648 }
3649 if (!filp) {
3650 status = nfserr_openmode;
3651 goto out;
3652 }
3596 file_lock.fl_owner = (fl_owner_t)lock_sop; 3653 file_lock.fl_owner = (fl_owner_t)lock_sop;
3597 file_lock.fl_pid = current->tgid; 3654 file_lock.fl_pid = current->tgid;
3598 file_lock.fl_file = filp; 3655 file_lock.fl_file = filp;
@@ -3761,7 +3818,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3761 &locku->lu_stateowner, &stp, NULL))) 3818 &locku->lu_stateowner, &stp, NULL)))
3762 goto out; 3819 goto out;
3763 3820
3764 filp = stp->st_vfs_file; 3821 filp = find_any_file(stp->st_file);
3822 if (!filp) {
3823 status = nfserr_lock_range;
3824 goto out;
3825 }
3765 BUG_ON(!filp); 3826 BUG_ON(!filp);
3766 locks_init_lock(&file_lock); 3827 locks_init_lock(&file_lock);
3767 file_lock.fl_type = F_UNLCK; 3828 file_lock.fl_type = F_UNLCK;
@@ -3808,10 +3869,10 @@ out_nfserr:
3808 * 0: no locks held by lockowner 3869 * 0: no locks held by lockowner
3809 */ 3870 */
3810static int 3871static int
3811check_for_locks(struct file *filp, struct nfs4_stateowner *lowner) 3872check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
3812{ 3873{
3813 struct file_lock **flpp; 3874 struct file_lock **flpp;
3814 struct inode *inode = filp->f_path.dentry->d_inode; 3875 struct inode *inode = filp->fi_inode;
3815 int status = 0; 3876 int status = 0;
3816 3877
3817 lock_kernel(); 3878 lock_kernel();
@@ -3862,7 +3923,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
3862 continue; 3923 continue;
3863 list_for_each_entry(stp, &sop->so_stateids, 3924 list_for_each_entry(stp, &sop->so_stateids,
3864 st_perstateowner) { 3925 st_perstateowner) {
3865 if (check_for_locks(stp->st_vfs_file, sop)) 3926 if (check_for_locks(stp->st_file, sop))
3866 goto out; 3927 goto out;
3867 /* Note: so_perclient unused for lockowners, 3928 /* Note: so_perclient unused for lockowners,
3868 * so it's OK to fool with here. */ 3929 * so it's OK to fool with here. */