Commit 0d9f9e122c74583de15a86d1c660c08dc298f2c8

Authored by Linus Torvalds

Merge branch 'for-2.6.36' of git://linux-nfs.org/~bfields/linux

* 'for-2.6.36' of git://linux-nfs.org/~bfields/linux: (34 commits)
  nfsd4: fix file open accounting for RDWR opens
  nfsd: don't allow setting maxblksize after svc created
  nfsd: initialize nfsd versions before creating svc
  net: sunrpc: removed duplicated #include
  nfsd41: Fix a crash when a callback is retried
  nfsd: fix startup/shutdown order bug
  nfsd: minor nfsd read api cleanup
  gcc-4.6: nfsd: fix initialized but not read warnings
  nfsd4: share file descriptors between stateid's
  nfsd4: fix openmode checking on IO using lock stateid
  nfsd4: miscellaneous process_open2 cleanup
  nfsd4: don't pretend to support write delegations
  nfsd: bypass readahead cache when have struct file
  nfsd: minor nfsd_svc() cleanup
  nfsd: move more into nfsd_startup()
  nfsd: just keep single lockd reference for nfsd
  nfsd: clean up nfsd_create_serv error handling
  nfsd: fix error handling in __write_ports_addxprt
  nfsd: fix error handling when starting nfsd with rpcbind down
  nfsd4: fix v4 state shutdown error paths
  ...

Showing 14 changed files Side-by-side Diff

... ... @@ -168,7 +168,7 @@
168 168 svc_reserve_auth(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
169 169  
170 170 fh_copy(&resp->fh, &argp->fh);
171   - nfserr = nfsd_read(rqstp, &resp->fh, NULL,
  171 + nfserr = nfsd_read(rqstp, &resp->fh,
172 172 argp->offset,
173 173 rqstp->rq_vec, argp->vlen,
174 174 &resp->count);
... ... @@ -271,7 +271,7 @@
271 271 fh_init(&resp->fh, NFS3_FHSIZE);
272 272 nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
273 273 &argp->attrs, S_IFDIR, 0, &resp->fh);
274   -
  274 + fh_unlock(&resp->dirfh);
275 275 RETURN_STATUS(nfserr);
276 276 }
277 277  
... ... @@ -327,7 +327,7 @@
327 327 type = nfs3_ftypes[argp->ftype];
328 328 nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
329 329 &argp->attrs, type, rdev, &resp->fh);
330   -
  330 + fh_unlock(&resp->dirfh);
331 331 RETURN_STATUS(nfserr);
332 332 }
333 333  
... ... @@ -348,6 +348,7 @@
348 348 /* Unlink. -S_IFDIR means file must not be a directory */
349 349 fh_copy(&resp->fh, &argp->fh);
350 350 nfserr = nfsd_unlink(rqstp, &resp->fh, -S_IFDIR, argp->name, argp->len);
  351 + fh_unlock(&resp->fh);
351 352 RETURN_STATUS(nfserr);
352 353 }
353 354  
... ... @@ -367,6 +368,7 @@
367 368  
368 369 fh_copy(&resp->fh, &argp->fh);
369 370 nfserr = nfsd_unlink(rqstp, &resp->fh, S_IFDIR, argp->name, argp->len);
  371 + fh_unlock(&resp->fh);
370 372 RETURN_STATUS(nfserr);
371 373 }
372 374  
fs/nfsd/nfs4callback.c
... ... @@ -143,8 +143,6 @@
143 143 u32 minorversion;
144 144 /* res */
145 145 int status;
146   - u32 taglen;
147   - char *tag;
148 146 };
149 147  
150 148 static struct {
... ... @@ -205,6 +203,16 @@
205 203 */
206 204  
207 205 static void
  206 +encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
  207 +{
  208 + __be32 *p;
  209 +
  210 + RESERVE_SPACE(sizeof(stateid_t));
  211 + WRITE32(sid->si_generation);
  212 + WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
  213 +}
  214 +
  215 +static void
208 216 encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
209 217 {
210 218 __be32 * p;
211 219  
... ... @@ -229,10 +237,10 @@
229 237 __be32 *p;
230 238 int len = dp->dl_fh.fh_size;
231 239  
232   - RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len);
  240 + RESERVE_SPACE(4);
233 241 WRITE32(OP_CB_RECALL);
234   - WRITE32(dp->dl_stateid.si_generation);
235   - WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t));
  242 + encode_stateid(xdr, &dp->dl_stateid);
  243 + RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2));
236 244 WRITE32(0); /* truncate optimization not implemented */
237 245 WRITE32(len);
238 246 WRITEMEM(&dp->dl_fh.fh_base, len);
239 247  
... ... @@ -293,13 +301,14 @@
293 301 static int
294 302 decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
295 303 __be32 *p;
  304 + u32 taglen;
296 305  
297 306 READ_BUF(8);
298 307 READ32(hdr->status);
299   - READ32(hdr->taglen);
300   - READ_BUF(hdr->taglen + 4);
301   - hdr->tag = (char *)p;
302   - p += XDR_QUADLEN(hdr->taglen);
  308 + /* We've got no use for the tag; ignore it: */
  309 + READ32(taglen);
  310 + READ_BUF(taglen + 4);
  311 + p += XDR_QUADLEN(taglen);
303 312 READ32(hdr->nops);
304 313 return 0;
305 314 }
306 315  
307 316  
308 317  
... ... @@ -667,28 +676,28 @@
667 676 }
668 677  
669 678 switch (task->tk_status) {
670   - case -EIO:
  679 + case 0:
  680 + return;
  681 + case -EBADHANDLE:
  682 + case -NFS4ERR_BAD_STATEID:
  683 + /* Race: client probably got cb_recall
  684 + * before open reply granting delegation */
  685 + break;
  686 + default:
671 687 /* Network partition? */
672 688 atomic_set(&clp->cl_cb_set, 0);
673 689 warn_no_callback_path(clp, task->tk_status);
674 690 if (current_rpc_client != task->tk_client) {
675 691 /* queue a callback on the new connection: */
  692 + atomic_inc(&dp->dl_count);
676 693 nfsd4_cb_recall(dp);
677 694 return;
678 695 }
679   - case -EBADHANDLE:
680   - case -NFS4ERR_BAD_STATEID:
681   - /* Race: client probably got cb_recall
682   - * before open reply granting delegation */
683   - break;
684   - default:
685   - /* success, or error we can't handle */
686   - return;
687 696 }
688 697 if (dp->dl_retries--) {
689 698 rpc_delay(task, 2*HZ);
690 699 task->tk_status = 0;
691   - rpc_restart_call(task);
  700 + rpc_restart_call_prepare(task);
692 701 return;
693 702 } else {
694 703 atomic_set(&clp->cl_cb_set, 0);
695 704  
696 705  
697 706  
... ... @@ -752,18 +761,16 @@
752 761 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
753 762 .rpc_cred = callback_cred
754 763 };
755   - int status;
756 764  
757   - if (clnt == NULL)
  765 + if (clnt == NULL) {
  766 + nfs4_put_delegation(dp);
758 767 return; /* Client is shutting down; give up. */
  768 + }
759 769  
760 770 args->args_op = dp;
761 771 msg.rpc_argp = args;
762 772 dp->dl_retries = 1;
763   - status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
764   - &nfsd4_cb_recall_ops, dp);
765   - if (status)
766   - nfs4_put_delegation(dp);
  773 + rpc_call_async(clnt, &msg, RPC_TASK_SOFT, &nfsd4_cb_recall_ops, dp);
767 774 }
768 775  
769 776 void nfsd4_do_callback_rpc(struct work_struct *w)
... ... @@ -51,7 +51,6 @@
51 51 static u32 current_ownerid = 1;
52 52 static u32 current_fileid = 1;
53 53 static u32 current_delegid = 1;
54   -static u32 nfs4_init;
55 54 static stateid_t zerostateid; /* bits all 0 */
56 55 static stateid_t onestateid; /* bits all 1 */
57 56 static u64 current_sessionid = 1;
... ... @@ -163,6 +162,46 @@
163 162 static struct list_head file_hashtbl[FILE_HASH_SIZE];
164 163 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
165 164  
  165 +static 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 +
  171 +static void nfs4_file_get_access(struct nfs4_file *fp, int oflag)
  172 +{
  173 + if (oflag == O_RDWR) {
  174 + __nfs4_file_get_access(fp, O_RDONLY);
  175 + __nfs4_file_get_access(fp, O_WRONLY);
  176 + } else
  177 + __nfs4_file_get_access(fp, oflag);
  178 +}
  179 +
  180 +static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
  181 +{
  182 + if (fp->fi_fds[oflag]) {
  183 + fput(fp->fi_fds[oflag]);
  184 + fp->fi_fds[oflag] = NULL;
  185 + }
  186 +}
  187 +
  188 +static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
  189 +{
  190 + if (atomic_dec_and_test(&fp->fi_access[oflag])) {
  191 + nfs4_file_put_fd(fp, O_RDWR);
  192 + nfs4_file_put_fd(fp, oflag);
  193 + }
  194 +}
  195 +
  196 +static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
  197 +{
  198 + if (oflag == O_RDWR) {
  199 + __nfs4_file_put_access(fp, O_RDONLY);
  200 + __nfs4_file_put_access(fp, O_WRONLY);
  201 + } else
  202 + __nfs4_file_put_access(fp, oflag);
  203 +}
  204 +
166 205 static struct nfs4_delegation *
167 206 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type)
168 207 {
... ... @@ -171,6 +210,13 @@
171 210 struct nfs4_cb_conn *cb = &stp->st_stateowner->so_client->cl_cb_conn;
172 211  
173 212 dprintk("NFSD alloc_init_deleg\n");
  213 + /*
  214 + * Major work on the lease subsystem (for example, to support
  215 + * calbacks on stat) will be required before we can support
  216 + * write delegations properly.
  217 + */
  218 + if (type != NFS4_OPEN_DELEGATE_READ)
  219 + return NULL;
174 220 if (fp->fi_had_conflict)
175 221 return NULL;
176 222 if (num_delegations > max_delegations)
177 223  
... ... @@ -185,9 +231,8 @@
185 231 dp->dl_client = clp;
186 232 get_nfs4_file(fp);
187 233 dp->dl_file = fp;
  234 + nfs4_file_get_access(fp, O_RDONLY);
188 235 dp->dl_flock = NULL;
189   - get_file(stp->st_vfs_file);
190   - dp->dl_vfs_file = stp->st_vfs_file;
191 236 dp->dl_type = type;
192 237 dp->dl_ident = cb->cb_ident;
193 238 dp->dl_stateid.si_boot = boot_time;
194 239  
195 240  
... ... @@ -222,15 +267,12 @@
222 267 static void
223 268 nfs4_close_delegation(struct nfs4_delegation *dp)
224 269 {
225   - struct file *filp = dp->dl_vfs_file;
  270 + struct file *filp = find_readable_file(dp->dl_file);
226 271  
227 272 dprintk("NFSD: close_delegation dp %p\n",dp);
228   - dp->dl_vfs_file = NULL;
229   - /* The following nfsd_close may not actually close the file,
230   - * but we want to remove the lease in any case. */
231 273 if (dp->dl_flock)
232 274 vfs_setlease(filp, F_UNLCK, &dp->dl_flock);
233   - nfsd_close(filp);
  275 + nfs4_file_put_access(dp->dl_file, O_RDONLY);
234 276 }
235 277  
236 278 /* Called under the state lock. */
237 279  
... ... @@ -302,8 +344,12 @@
302 344  
303 345 static void release_lock_stateid(struct nfs4_stateid *stp)
304 346 {
  347 + struct file *file;
  348 +
305 349 unhash_generic_stateid(stp);
306   - locks_remove_posix(stp->st_vfs_file, (fl_owner_t)stp->st_stateowner);
  350 + file = find_any_file(stp->st_file);
  351 + if (file)
  352 + locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
307 353 free_generic_stateid(stp);
308 354 }
309 355  
310 356  
311 357  
... ... @@ -341,11 +387,85 @@
341 387 }
342 388 }
343 389  
  390 +/*
  391 + * We store the NONE, READ, WRITE, and BOTH bits separately in the
  392 + * st_{access,deny}_bmap field of the stateid, in order to track not
  393 + * only what share bits are currently in force, but also what
  394 + * combinations of share bits previous opens have used. This allows us
  395 + * to enforce the recommendation of rfc 3530 14.2.19 that the server
  396 + * return an error if the client attempt to downgrade to a combination
  397 + * of share bits not explicable by closing some of its previous opens.
  398 + *
  399 + * XXX: This enforcement is actually incomplete, since we don't keep
  400 + * track of access/deny bit combinations; so, e.g., we allow:
  401 + *
  402 + * OPEN allow read, deny write
  403 + * OPEN allow both, deny none
  404 + * DOWNGRADE allow read, deny none
  405 + *
  406 + * which we should reject.
  407 + */
  408 +static void
  409 +set_access(unsigned int *access, unsigned long bmap) {
  410 + int i;
  411 +
  412 + *access = 0;
  413 + for (i = 1; i < 4; i++) {
  414 + if (test_bit(i, &bmap))
  415 + *access |= i;
  416 + }
  417 +}
  418 +
  419 +static void
  420 +set_deny(unsigned int *deny, unsigned long bmap) {
  421 + int i;
  422 +
  423 + *deny = 0;
  424 + for (i = 0; i < 4; i++) {
  425 + if (test_bit(i, &bmap))
  426 + *deny |= i ;
  427 + }
  428 +}
  429 +
  430 +static int
  431 +test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
  432 + unsigned int access, deny;
  433 +
  434 + set_access(&access, stp->st_access_bmap);
  435 + set_deny(&deny, stp->st_deny_bmap);
  436 + if ((access & open->op_share_deny) || (deny & open->op_share_access))
  437 + return 0;
  438 + return 1;
  439 +}
  440 +
  441 +static int nfs4_access_to_omode(u32 access)
  442 +{
  443 + switch (access) {
  444 + case NFS4_SHARE_ACCESS_READ:
  445 + return O_RDONLY;
  446 + case NFS4_SHARE_ACCESS_WRITE:
  447 + return O_WRONLY;
  448 + case NFS4_SHARE_ACCESS_BOTH:
  449 + return O_RDWR;
  450 + }
  451 + BUG();
  452 +}
  453 +
  454 +static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
  455 +{
  456 + unsigned int access;
  457 +
  458 + set_access(&access, stp->st_access_bmap);
  459 + return nfs4_access_to_omode(access);
  460 +}
  461 +
344 462 static void release_open_stateid(struct nfs4_stateid *stp)
345 463 {
  464 + int oflag = nfs4_access_bmap_to_omode(stp);
  465 +
346 466 unhash_generic_stateid(stp);
347 467 release_stateid_lockowners(stp);
348   - nfsd_close(stp->st_vfs_file);
  468 + nfs4_file_put_access(stp->st_file, oflag);
349 469 free_generic_stateid(stp);
350 470 }
351 471  
... ... @@ -457,7 +577,7 @@
457 577 spin_unlock(&nfsd_drc_lock);
458 578  
459 579 if (fchan->maxreqs == 0)
460   - return nfserr_serverfault;
  580 + return nfserr_jukebox;
461 581  
462 582 fchan->maxresp_cached = size + NFSD_MIN_HDR_SEQ_SZ;
463 583 return 0;
... ... @@ -542,7 +662,7 @@
542 662 BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot)
543 663 + sizeof(struct nfsd4_session) > PAGE_SIZE);
544 664  
545   - status = nfserr_serverfault;
  665 + status = nfserr_jukebox;
546 666 /* allocate struct nfsd4_session and slot table pointers in one piece */
547 667 slotsize = tmp.se_fchannel.maxreqs * sizeof(struct nfsd4_slot *);
548 668 new = kzalloc(sizeof(*new) + slotsize, GFP_KERNEL);
549 669  
... ... @@ -591,10 +711,8 @@
591 711  
592 712 dump_sessionid(__func__, sessionid);
593 713 idx = hash_sessionid(sessionid);
594   - dprintk("%s: idx is %d\n", __func__, idx);
595 714 /* Search in the appropriate list */
596 715 list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) {
597   - dump_sessionid("list traversal", &elem->se_sessionid);
598 716 if (!memcmp(elem->se_sessionid.data, sessionid->data,
599 717 NFS4_MAX_SESSIONID_LEN)) {
600 718 return elem;
... ... @@ -714,7 +832,6 @@
714 832 } else
715 833 renew_client_locked(clp);
716 834 spin_unlock(&client_lock);
717   - nfsd4_put_session(session);
718 835 }
719 836  
720 837 /* must be called under the client_lock */
... ... @@ -1220,7 +1337,7 @@
1220 1337 /* Normal case */
1221 1338 new = create_client(exid->clname, dname, rqstp, &verf);
1222 1339 if (new == NULL) {
1223   - status = nfserr_serverfault;
  1340 + status = nfserr_jukebox;
1224 1341 goto out;
1225 1342 }
1226 1343  
... ... @@ -1760,6 +1877,8 @@
1760 1877 fp->fi_inode = igrab(ino);
1761 1878 fp->fi_id = current_fileid++;
1762 1879 fp->fi_had_conflict = false;
  1880 + memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
  1881 + memset(fp->fi_access, 0, sizeof(fp->fi_access));
1763 1882 spin_lock(&recall_lock);
1764 1883 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
1765 1884 spin_unlock(&recall_lock);
... ... @@ -1971,57 +2090,6 @@
1971 2090 }
1972 2091  
1973 2092 /*
1974   - * We store the NONE, READ, WRITE, and BOTH bits separately in the
1975   - * st_{access,deny}_bmap field of the stateid, in order to track not
1976   - * only what share bits are currently in force, but also what
1977   - * combinations of share bits previous opens have used. This allows us
1978   - * to enforce the recommendation of rfc 3530 14.2.19 that the server
1979   - * return an error if the client attempt to downgrade to a combination
1980   - * of share bits not explicable by closing some of its previous opens.
1981   - *
1982   - * XXX: This enforcement is actually incomplete, since we don't keep
1983   - * track of access/deny bit combinations; so, e.g., we allow:
1984   - *
1985   - * OPEN allow read, deny write
1986   - * OPEN allow both, deny none
1987   - * DOWNGRADE allow read, deny none
1988   - *
1989   - * which we should reject.
1990   - */
1991   -static void
1992   -set_access(unsigned int *access, unsigned long bmap) {
1993   - int i;
1994   -
1995   - *access = 0;
1996   - for (i = 1; i < 4; i++) {
1997   - if (test_bit(i, &bmap))
1998   - *access |= i;
1999   - }
2000   -}
2001   -
2002   -static void
2003   -set_deny(unsigned int *deny, unsigned long bmap) {
2004   - int i;
2005   -
2006   - *deny = 0;
2007   - for (i = 0; i < 4; i++) {
2008   - if (test_bit(i, &bmap))
2009   - *deny |= i ;
2010   - }
2011   -}
2012   -
2013   -static int
2014   -test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
2015   - unsigned int access, deny;
2016   -
2017   - set_access(&access, stp->st_access_bmap);
2018   - set_deny(&deny, stp->st_deny_bmap);
2019   - if ((access & open->op_share_deny) || (deny & open->op_share_access))
2020   - return 0;
2021   - return 1;
2022   -}
2023   -
2024   -/*
2025 2093 * Called to check deny when READ with all zero stateid or
2026 2094 * WRITE with all zero or all one stateid
2027 2095 */
2028 2096  
... ... @@ -2052,14 +2120,12 @@
2052 2120 }
2053 2121  
2054 2122 static inline void
2055   -nfs4_file_downgrade(struct file *filp, unsigned int share_access)
  2123 +nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
2056 2124 {
2057   - if (share_access & NFS4_SHARE_ACCESS_WRITE) {
2058   - drop_file_write_access(filp);
2059   - spin_lock(&filp->f_lock);
2060   - filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
2061   - spin_unlock(&filp->f_lock);
2062   - }
  2125 + if (share_access & NFS4_SHARE_ACCESS_WRITE)
  2126 + nfs4_file_put_access(fp, O_WRONLY);
  2127 + if (share_access & NFS4_SHARE_ACCESS_READ)
  2128 + nfs4_file_put_access(fp, O_RDONLY);
2063 2129 }
2064 2130  
2065 2131 /*
... ... @@ -2255,6 +2321,13 @@
2255 2321 return NULL;
2256 2322 }
2257 2323  
  2324 +int share_access_to_flags(u32 share_access)
  2325 +{
  2326 + share_access &= ~NFS4_SHARE_WANT_MASK;
  2327 +
  2328 + return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
  2329 +}
  2330 +
2258 2331 static __be32
2259 2332 nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
2260 2333 struct nfs4_delegation **dp)
... ... @@ -2265,8 +2338,7 @@
2265 2338 *dp = find_delegation_file(fp, &open->op_delegate_stateid);
2266 2339 if (*dp == NULL)
2267 2340 goto out;
2268   - flags = open->op_share_access == NFS4_SHARE_ACCESS_READ ?
2269   - RD_STATE : WR_STATE;
  2341 + flags = share_access_to_flags(open->op_share_access);
2270 2342 status = nfs4_check_delegmode(*dp, flags);
2271 2343 if (status)
2272 2344 *dp = NULL;
2273 2345  
2274 2346  
2275 2347  
... ... @@ -2308,30 +2380,53 @@
2308 2380 return kmem_cache_alloc(stateid_slab, GFP_KERNEL);
2309 2381 }
2310 2382  
  2383 +static inline int nfs4_access_to_access(u32 nfs4_access)
  2384 +{
  2385 + int flags = 0;
  2386 +
  2387 + if (nfs4_access & NFS4_SHARE_ACCESS_READ)
  2388 + flags |= NFSD_MAY_READ;
  2389 + if (nfs4_access & NFS4_SHARE_ACCESS_WRITE)
  2390 + flags |= NFSD_MAY_WRITE;
  2391 + return flags;
  2392 +}
  2393 +
  2394 +static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
  2395 +*fp, struct svc_fh *cur_fh, u32 nfs4_access)
  2396 +{
  2397 + __be32 status;
  2398 + int oflag = nfs4_access_to_omode(nfs4_access);
  2399 + int access = nfs4_access_to_access(nfs4_access);
  2400 +
  2401 + if (!fp->fi_fds[oflag]) {
  2402 + status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
  2403 + &fp->fi_fds[oflag]);
  2404 + if (status == nfserr_dropit)
  2405 + status = nfserr_jukebox;
  2406 + if (status)
  2407 + return status;
  2408 + }
  2409 + nfs4_file_get_access(fp, oflag);
  2410 +
  2411 + return nfs_ok;
  2412 +}
  2413 +
2311 2414 static __be32
2312 2415 nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
2313   - struct nfs4_delegation *dp,
2314   - struct svc_fh *cur_fh, int flags)
  2416 + struct nfs4_file *fp, struct svc_fh *cur_fh,
  2417 + struct nfsd4_open *open)
2315 2418 {
2316 2419 struct nfs4_stateid *stp;
  2420 + __be32 status;
2317 2421  
2318 2422 stp = nfs4_alloc_stateid();
2319 2423 if (stp == NULL)
2320 2424 return nfserr_resource;
2321 2425  
2322   - if (dp) {
2323   - get_file(dp->dl_vfs_file);
2324   - stp->st_vfs_file = dp->dl_vfs_file;
2325   - } else {
2326   - __be32 status;
2327   - status = nfsd_open(rqstp, cur_fh, S_IFREG, flags,
2328   - &stp->st_vfs_file);
2329   - if (status) {
2330   - if (status == nfserr_dropit)
2331   - status = nfserr_jukebox;
2332   - kmem_cache_free(stateid_slab, stp);
2333   - return status;
2334   - }
  2426 + status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access);
  2427 + if (status) {
  2428 + kmem_cache_free(stateid_slab, stp);
  2429 + return status;
2335 2430 }
2336 2431 *stpp = stp;
2337 2432 return 0;
2338 2433  
2339 2434  
2340 2435  
2341 2436  
2342 2437  
... ... @@ -2353,35 +2448,30 @@
2353 2448 }
2354 2449  
2355 2450 static __be32
2356   -nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
  2451 +nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
2357 2452 {
2358   - struct file *filp = stp->st_vfs_file;
2359   - struct inode *inode = filp->f_path.dentry->d_inode;
2360   - unsigned int share_access, new_writer;
  2453 + u32 op_share_access, new_access;
2361 2454 __be32 status;
2362 2455  
2363   - set_access(&share_access, stp->st_access_bmap);
2364   - new_writer = (~share_access) & open->op_share_access
2365   - & NFS4_SHARE_ACCESS_WRITE;
  2456 + set_access(&new_access, stp->st_access_bmap);
  2457 + new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK;
2366 2458  
2367   - if (new_writer) {
2368   - int err = get_write_access(inode);
2369   - if (err)
2370   - return nfserrno(err);
2371   - err = mnt_want_write(cur_fh->fh_export->ex_path.mnt);
2372   - if (err)
2373   - return nfserrno(err);
2374   - file_take_write(filp);
  2459 + if (new_access) {
  2460 + status = nfs4_get_vfs_file(rqstp, fp, cur_fh, new_access);
  2461 + if (status)
  2462 + return status;
2375 2463 }
2376 2464 status = nfsd4_truncate(rqstp, cur_fh, open);
2377 2465 if (status) {
2378   - if (new_writer)
2379   - put_write_access(inode);
  2466 + if (new_access) {
  2467 + int oflag = nfs4_access_to_omode(new_access);
  2468 + nfs4_file_put_access(fp, oflag);
  2469 + }
2380 2470 return status;
2381 2471 }
2382 2472 /* remember the open */
2383   - filp->f_mode |= open->op_share_access;
2384   - __set_bit(open->op_share_access, &stp->st_access_bmap);
  2473 + op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
  2474 + __set_bit(op_share_access, &stp->st_access_bmap);
2385 2475 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2386 2476  
2387 2477 return nfs_ok;
2388 2478  
... ... @@ -2444,13 +2534,14 @@
2444 2534 fl.fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK;
2445 2535 fl.fl_end = OFFSET_MAX;
2446 2536 fl.fl_owner = (fl_owner_t)dp;
2447   - fl.fl_file = stp->st_vfs_file;
  2537 + fl.fl_file = find_readable_file(stp->st_file);
  2538 + BUG_ON(!fl.fl_file);
2448 2539 fl.fl_pid = current->tgid;
2449 2540  
2450 2541 /* vfs_setlease checks to see if delegation should be handed out.
2451 2542 * the lock_manager callbacks fl_mylease and fl_change are used
2452 2543 */
2453   - if ((status = vfs_setlease(stp->st_vfs_file, fl.fl_type, &flp))) {
  2544 + if ((status = vfs_setlease(fl.fl_file, fl.fl_type, &flp))) {
2454 2545 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
2455 2546 unhash_delegation(dp);
2456 2547 flag = NFS4_OPEN_DELEGATE_NONE;
2457 2548  
... ... @@ -2514,18 +2605,12 @@
2514 2605 */
2515 2606 if (stp) {
2516 2607 /* Stateid was found, this is an OPEN upgrade */
2517   - status = nfs4_upgrade_open(rqstp, current_fh, stp, open);
  2608 + status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
2518 2609 if (status)
2519 2610 goto out;
2520 2611 update_stateid(&stp->st_stateid);
2521 2612 } else {
2522   - /* Stateid was not found, this is a new OPEN */
2523   - int flags = 0;
2524   - if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
2525   - flags |= NFSD_MAY_READ;
2526   - if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
2527   - flags |= NFSD_MAY_WRITE;
2528   - status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags);
  2613 + status = nfs4_new_open(rqstp, &stp, fp, current_fh, open);
2529 2614 if (status)
2530 2615 goto out;
2531 2616 init_stateid(stp, fp, open);
... ... @@ -2727,7 +2812,7 @@
2727 2812 static inline int
2728 2813 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
2729 2814 {
2730   - return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode;
  2815 + return fhp->fh_dentry->d_inode != stp->st_file->fi_inode;
2731 2816 }
2732 2817  
2733 2818 static int
... ... @@ -2760,6 +2845,9 @@
2760 2845 {
2761 2846 __be32 status = nfserr_openmode;
2762 2847  
  2848 + /* For lock stateid's, we test the parent open, not the lock: */
  2849 + if (stp->st_openstp)
  2850 + stp = stp->st_openstp;
2763 2851 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
2764 2852 goto out;
2765 2853 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
... ... @@ -2872,7 +2960,8 @@
2872 2960 goto out;
2873 2961 renew_client(dp->dl_client);
2874 2962 if (filpp)
2875   - *filpp = dp->dl_vfs_file;
  2963 + *filpp = find_readable_file(dp->dl_file);
  2964 + BUG_ON(!*filpp);
2876 2965 } else { /* open or lock stateid */
2877 2966 stp = find_stateid(stateid, flags);
2878 2967 if (!stp)
... ... @@ -2889,8 +2978,13 @@
2889 2978 if (status)
2890 2979 goto out;
2891 2980 renew_client(stp->st_stateowner->so_client);
2892   - if (filpp)
2893   - *filpp = stp->st_vfs_file;
  2981 + if (filpp) {
  2982 + if (flags & RD_STATE)
  2983 + *filpp = find_readable_file(stp->st_file);
  2984 + else
  2985 + *filpp = find_writeable_file(stp->st_file);
  2986 + BUG_ON(!*filpp); /* assured by check_openmode */
  2987 + }
2894 2988 }
2895 2989 status = nfs_ok;
2896 2990 out:
... ... @@ -3126,8 +3220,7 @@
3126 3220 goto out;
3127 3221 }
3128 3222 set_access(&share_access, stp->st_access_bmap);
3129   - nfs4_file_downgrade(stp->st_vfs_file,
3130   - share_access & ~od->od_share_access);
  3223 + nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access);
3131 3224  
3132 3225 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
3133 3226 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
3134 3227  
... ... @@ -3346,11 +3439,9 @@
3346 3439 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3347 3440 {
3348 3441 struct nfs4_stateowner *sop;
3349   - unsigned int hval;
3350 3442  
3351 3443 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
3352 3444 sop = (struct nfs4_stateowner *) fl->fl_owner;
3353   - hval = lockownerid_hashval(sop->so_id);
3354 3445 kref_get(&sop->so_ref);
3355 3446 deny->ld_sop = sop;
3356 3447 deny->ld_clientid = sop->so_client->cl_clientid;
... ... @@ -3446,8 +3537,6 @@
3446 3537 stp->st_stateid.si_stateownerid = sop->so_id;
3447 3538 stp->st_stateid.si_fileid = fp->fi_id;
3448 3539 stp->st_stateid.si_generation = 0;
3449   - stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
3450   - stp->st_access_bmap = open_stp->st_access_bmap;
3451 3540 stp->st_deny_bmap = open_stp->st_deny_bmap;
3452 3541 stp->st_openstp = open_stp;
3453 3542  
... ... @@ -3547,7 +3636,6 @@
3547 3636 lock_sop = lock->lk_replay_owner;
3548 3637 }
3549 3638 /* lock->lk_replay_owner and lock_stp have been created or found */
3550   - filp = lock_stp->st_vfs_file;
3551 3639  
3552 3640 status = nfserr_grace;
3553 3641 if (locks_in_grace() && !lock->lk_reclaim)
3554 3642  
... ... @@ -3560,11 +3648,13 @@
3560 3648 switch (lock->lk_type) {
3561 3649 case NFS4_READ_LT:
3562 3650 case NFS4_READW_LT:
  3651 + filp = find_readable_file(lock_stp->st_file);
3563 3652 file_lock.fl_type = F_RDLCK;
3564 3653 cmd = F_SETLK;
3565 3654 break;
3566 3655 case NFS4_WRITE_LT:
3567 3656 case NFS4_WRITEW_LT:
  3657 + filp = find_writeable_file(lock_stp->st_file);
3568 3658 file_lock.fl_type = F_WRLCK;
3569 3659 cmd = F_SETLK;
3570 3660 break;
... ... @@ -3572,6 +3662,10 @@
3572 3662 status = nfserr_inval;
3573 3663 goto out;
3574 3664 }
  3665 + if (!filp) {
  3666 + status = nfserr_openmode;
  3667 + goto out;
  3668 + }
3575 3669 file_lock.fl_owner = (fl_owner_t)lock_sop;
3576 3670 file_lock.fl_pid = current->tgid;
3577 3671 file_lock.fl_file = filp;
... ... @@ -3740,7 +3834,11 @@
3740 3834 &locku->lu_stateowner, &stp, NULL)))
3741 3835 goto out;
3742 3836  
3743   - filp = stp->st_vfs_file;
  3837 + filp = find_any_file(stp->st_file);
  3838 + if (!filp) {
  3839 + status = nfserr_lock_range;
  3840 + goto out;
  3841 + }
3744 3842 BUG_ON(!filp);
3745 3843 locks_init_lock(&file_lock);
3746 3844 file_lock.fl_type = F_UNLCK;
3747 3845  
... ... @@ -3787,10 +3885,10 @@
3787 3885 * 0: no locks held by lockowner
3788 3886 */
3789 3887 static int
3790   -check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
  3888 +check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
3791 3889 {
3792 3890 struct file_lock **flpp;
3793   - struct inode *inode = filp->f_path.dentry->d_inode;
  3891 + struct inode *inode = filp->fi_inode;
3794 3892 int status = 0;
3795 3893  
3796 3894 lock_kernel();
... ... @@ -3841,7 +3939,7 @@
3841 3939 continue;
3842 3940 list_for_each_entry(stp, &sop->so_stateids,
3843 3941 st_perstateowner) {
3844   - if (check_for_locks(stp->st_vfs_file, sop))
  3942 + if (check_for_locks(stp->st_file, sop))
3845 3943 goto out;
3846 3944 /* Note: so_perclient unused for lockowners,
3847 3945 * so it's OK to fool with here. */
3848 3946  
... ... @@ -4066,16 +4164,8 @@
4066 4164 int
4067 4165 nfs4_state_start(void)
4068 4166 {
4069   - int ret;
4070   -
4071   - if (nfs4_init)
4072   - return 0;
4073 4167 nfsd4_load_reboot_recovery_data();
4074   - ret = __nfs4_state_start();
4075   - if (ret)
4076   - return ret;
4077   - nfs4_init = 1;
4078   - return 0;
  4168 + return __nfs4_state_start();
4079 4169 }
4080 4170  
4081 4171 static void
... ... @@ -4110,7 +4200,6 @@
4110 4200 }
4111 4201  
4112 4202 nfsd4_shutdown_recdir();
4113   - nfs4_init = 0;
4114 4203 }
4115 4204  
4116 4205 void
... ... @@ -2630,7 +2630,7 @@
2630 2630 }
2631 2631 read->rd_vlen = v;
2632 2632  
2633   - nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,
  2633 + nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2634 2634 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2635 2635 &maxcount);
2636 2636  
... ... @@ -3325,6 +3325,7 @@
3325 3325 }
3326 3326 /* Renew the clientid on success and on replay */
3327 3327 release_session_client(cs->session);
  3328 + nfsd4_put_session(cs->session);
3328 3329 }
3329 3330 return 1;
3330 3331 }
... ... @@ -949,15 +949,12 @@
949 949 if (err != 0)
950 950 return err;
951 951  
952   - err = lockd_up();
953   - if (err != 0)
954   - goto out;
955   -
956 952 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
957   - if (err < 0)
958   - lockd_down();
  953 + if (err < 0) {
  954 + svc_destroy(nfsd_serv);
  955 + return err;
  956 + }
959 957  
960   -out:
961 958 /* Decrease the count, but don't shut down the service */
962 959 nfsd_serv->sv_nrthreads--;
963 960 return err;
... ... @@ -978,9 +975,6 @@
978 975 if (nfsd_serv != NULL)
979 976 len = svc_sock_names(nfsd_serv, buf,
980 977 SIMPLE_TRANSACTION_LIMIT, toclose);
981   - if (len >= 0)
982   - lockd_down();
983   -
984 978 kfree(toclose);
985 979 return len;
986 980 }
... ... @@ -1014,6 +1008,9 @@
1014 1008 PF_INET6, port, SVC_SOCK_ANONYMOUS);
1015 1009 if (err < 0 && err != -EAFNOSUPPORT)
1016 1010 goto out_close;
  1011 +
  1012 + /* Decrease the count, but don't shut down the service */
  1013 + nfsd_serv->sv_nrthreads--;
1017 1014 return 0;
1018 1015 out_close:
1019 1016 xprt = svc_find_xprt(nfsd_serv, transport, PF_INET, port);
... ... @@ -1022,8 +1019,7 @@
1022 1019 svc_xprt_put(xprt);
1023 1020 }
1024 1021 out_err:
1025   - /* Decrease the count, but don't shut down the service */
1026   - nfsd_serv->sv_nrthreads--;
  1022 + svc_destroy(nfsd_serv);
1027 1023 return err;
1028 1024 }
1029 1025  
... ... @@ -1194,7 +1190,7 @@
1194 1190 bsize = NFSSVC_MAXBLKSIZE;
1195 1191 bsize &= ~(1024-1);
1196 1192 mutex_lock(&nfsd_mutex);
1197   - if (nfsd_serv && nfsd_serv->sv_nrthreads) {
  1193 + if (nfsd_serv) {
1198 1194 mutex_unlock(&nfsd_mutex);
1199 1195 return -EBUSY;
1200 1196 }
... ... @@ -1310,6 +1306,8 @@
1310 1306 return -EINVAL;
1311 1307  
1312 1308 status = nfs4_reset_recoverydir(recdir);
  1309 + if (status)
  1310 + return status;
1313 1311 }
1314 1312  
1315 1313 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
... ... @@ -153,6 +153,7 @@
153 153 #define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID)
154 154 #define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK)
155 155 #define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME)
  156 +#define nfserr_lock_range cpu_to_be32(NFSERR_LOCK_RANGE)
156 157 #define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH)
157 158 #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP)
158 159 #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR)
... ... @@ -144,7 +144,7 @@
144 144 svc_reserve_auth(rqstp, (19<<2) + argp->count + 4);
145 145  
146 146 resp->count = argp->count;
147   - nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
  147 + nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh),
148 148 argp->offset,
149 149 rqstp->rq_vec, argp->vlen,
150 150 &resp->count);
... ... @@ -290,7 +290,6 @@
290 290 * gospel of sun micro
291 291 */
292 292 if (type != S_IFREG) {
293   - int is_borc = 0;
294 293 if (type != S_IFBLK && type != S_IFCHR) {
295 294 rdev = 0;
296 295 } else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
... ... @@ -298,7 +297,6 @@
298 297 type = S_IFIFO;
299 298 } else {
300 299 /* Okay, char or block special */
301   - is_borc = 1;
302 300 if (!rdev)
303 301 rdev = wanted;
304 302 }
... ... @@ -180,15 +180,80 @@
180 180 return rv;
181 181 }
182 182  
  183 +static int nfsd_init_socks(int port)
  184 +{
  185 + int error;
  186 + if (!list_empty(&nfsd_serv->sv_permsocks))
  187 + return 0;
  188 +
  189 + error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
  190 + SVC_SOCK_DEFAULTS);
  191 + if (error < 0)
  192 + return error;
  193 +
  194 + error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
  195 + SVC_SOCK_DEFAULTS);
  196 + if (error < 0)
  197 + return error;
  198 +
  199 + return 0;
  200 +}
  201 +
  202 +static bool nfsd_up = false;
  203 +
  204 +static int nfsd_startup(unsigned short port, int nrservs)
  205 +{
  206 + int ret;
  207 +
  208 + if (nfsd_up)
  209 + return 0;
  210 + /*
  211 + * Readahead param cache - will no-op if it already exists.
  212 + * (Note therefore results will be suboptimal if number of
  213 + * threads is modified after nfsd start.)
  214 + */
  215 + ret = nfsd_racache_init(2*nrservs);
  216 + if (ret)
  217 + return ret;
  218 + ret = nfsd_init_socks(port);
  219 + if (ret)
  220 + goto out_racache;
  221 + ret = lockd_up();
  222 + if (ret)
  223 + goto out_racache;
  224 + ret = nfs4_state_start();
  225 + if (ret)
  226 + goto out_lockd;
  227 + nfsd_up = true;
  228 + return 0;
  229 +out_lockd:
  230 + lockd_down();
  231 +out_racache:
  232 + nfsd_racache_shutdown();
  233 + return ret;
  234 +}
  235 +
  236 +static void nfsd_shutdown(void)
  237 +{
  238 + /*
  239 + * write_ports can create the server without actually starting
  240 + * any threads--if we get shut down before any threads are
  241 + * started, then nfsd_last_thread will be run before any of this
  242 + * other initialization has been done.
  243 + */
  244 + if (!nfsd_up)
  245 + return;
  246 + nfs4_state_shutdown();
  247 + lockd_down();
  248 + nfsd_racache_shutdown();
  249 + nfsd_up = false;
  250 +}
  251 +
183 252 static void nfsd_last_thread(struct svc_serv *serv)
184 253 {
185 254 /* When last nfsd thread exits we need to do some clean-up */
186   - struct svc_xprt *xprt;
187   - list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
188   - lockd_down();
189 255 nfsd_serv = NULL;
190   - nfsd_racache_shutdown();
191   - nfs4_state_shutdown();
  256 + nfsd_shutdown();
192 257  
193 258 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
194 259 "cache\n");
195 260  
196 261  
197 262  
... ... @@ -263,45 +328,18 @@
263 328 nfsd_max_blksize >= 8*1024*2)
264 329 nfsd_max_blksize /= 2;
265 330 }
  331 + nfsd_reset_versions();
266 332  
267 333 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
268 334 nfsd_last_thread, nfsd, THIS_MODULE);
269 335 if (nfsd_serv == NULL)
270   - err = -ENOMEM;
271   - else
272   - set_max_drc();
  336 + return -ENOMEM;
273 337  
  338 + set_max_drc();
274 339 do_gettimeofday(&nfssvc_boot); /* record boot time */
275 340 return err;
276 341 }
277 342  
278   -static int nfsd_init_socks(int port)
279   -{
280   - int error;
281   - if (!list_empty(&nfsd_serv->sv_permsocks))
282   - return 0;
283   -
284   - error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
285   - SVC_SOCK_DEFAULTS);
286   - if (error < 0)
287   - return error;
288   -
289   - error = lockd_up();
290   - if (error < 0)
291   - return error;
292   -
293   - error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
294   - SVC_SOCK_DEFAULTS);
295   - if (error < 0)
296   - return error;
297   -
298   - error = lockd_up();
299   - if (error < 0)
300   - return error;
301   -
302   - return 0;
303   -}
304   -
305 343 int nfsd_nrpools(void)
306 344 {
307 345 if (nfsd_serv == NULL)
308 346  
... ... @@ -376,10 +414,16 @@
376 414 return err;
377 415 }
378 416  
  417 +/*
  418 + * Adjust the number of threads and return the new number of threads.
  419 + * This is also the function that starts the server if necessary, if
  420 + * this is the first time nrservs is nonzero.
  421 + */
379 422 int
380 423 nfsd_svc(unsigned short port, int nrservs)
381 424 {
382 425 int error;
  426 + bool nfsd_up_before;
383 427  
384 428 mutex_lock(&nfsd_mutex);
385 429 dprintk("nfsd: creating service\n");
386 430  
387 431  
388 432  
389 433  
390 434  
... ... @@ -391,34 +435,29 @@
391 435 if (nrservs == 0 && nfsd_serv == NULL)
392 436 goto out;
393 437  
394   - /* Readahead param cache - will no-op if it already exists */
395   - error = nfsd_racache_init(2*nrservs);
396   - if (error<0)
397   - goto out;
398   - error = nfs4_state_start();
  438 + error = nfsd_create_serv();
399 439 if (error)
400 440 goto out;
401 441  
402   - nfsd_reset_versions();
  442 + nfsd_up_before = nfsd_up;
403 443  
404   - error = nfsd_create_serv();
405   -
  444 + error = nfsd_startup(port, nrservs);
406 445 if (error)
407   - goto out;
408   - error = nfsd_init_socks(port);
409   - if (error)
410   - goto failure;
411   -
  446 + goto out_destroy;
412 447 error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
413   - if (error == 0)
414   - /* We are holding a reference to nfsd_serv which
415   - * we don't want to count in the return value,
416   - * so subtract 1
417   - */
418   - error = nfsd_serv->sv_nrthreads - 1;
419   - failure:
  448 + if (error)
  449 + goto out_shutdown;
  450 + /* We are holding a reference to nfsd_serv which
  451 + * we don't want to count in the return value,
  452 + * so subtract 1
  453 + */
  454 + error = nfsd_serv->sv_nrthreads - 1;
  455 +out_shutdown:
  456 + if (error < 0 && !nfsd_up_before)
  457 + nfsd_shutdown();
  458 +out_destroy:
420 459 svc_destroy(nfsd_serv); /* Release server */
421   - out:
  460 +out:
422 461 mutex_unlock(&nfsd_mutex);
423 462 return error;
424 463 }
... ... @@ -88,7 +88,6 @@
88 88 struct nfs4_client *dl_client;
89 89 struct nfs4_file *dl_file;
90 90 struct file_lock *dl_flock;
91   - struct file *dl_vfs_file;
92 91 u32 dl_type;
93 92 time_t dl_time;
94 93 /* For recall: */
95 94  
... ... @@ -342,12 +341,50 @@
342 341 struct list_head fi_hash; /* hash by "struct inode *" */
343 342 struct list_head fi_stateids;
344 343 struct list_head fi_delegations;
  344 + /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
  345 + struct file * fi_fds[3];
  346 + /* One each for O_RDONLY, O_WRONLY: */
  347 + atomic_t fi_access[2];
  348 + /*
  349 + * Each open stateid contributes 1 to either fi_readers or
  350 + * fi_writers, or both, depending on the open mode. A
  351 + * delegation also takes an fi_readers reference. Lock
  352 + * stateid's take none.
  353 + */
  354 + atomic_t fi_readers;
  355 + atomic_t fi_writers;
345 356 struct inode *fi_inode;
346 357 u32 fi_id; /* used with stateowner->so_id
347 358 * for stateid_hashtbl hash */
348 359 bool fi_had_conflict;
349 360 };
350 361  
  362 +/* XXX: for first cut may fall back on returning file that doesn't work
  363 + * at all? */
  364 +static inline struct file *find_writeable_file(struct nfs4_file *f)
  365 +{
  366 + if (f->fi_fds[O_RDWR])
  367 + return f->fi_fds[O_RDWR];
  368 + return f->fi_fds[O_WRONLY];
  369 +}
  370 +
  371 +static inline struct file *find_readable_file(struct nfs4_file *f)
  372 +{
  373 + if (f->fi_fds[O_RDWR])
  374 + return f->fi_fds[O_RDWR];
  375 + return f->fi_fds[O_RDONLY];
  376 +}
  377 +
  378 +static inline struct file *find_any_file(struct nfs4_file *f)
  379 +{
  380 + if (f->fi_fds[O_RDWR])
  381 + return f->fi_fds[O_RDWR];
  382 + else if (f->fi_fds[O_RDWR])
  383 + return f->fi_fds[O_WRONLY];
  384 + else
  385 + return f->fi_fds[O_RDONLY];
  386 +}
  387 +
351 388 /*
352 389 * nfs4_stateid can either be an open stateid or (eventually) a lock stateid
353 390 *
... ... @@ -373,7 +410,6 @@
373 410 struct nfs4_stateowner * st_stateowner;
374 411 struct nfs4_file * st_file;
375 412 stateid_t st_stateid;
376   - struct file * st_vfs_file;
377 413 unsigned long st_access_bmap;
378 414 unsigned long st_deny_bmap;
379 415 struct nfs4_stateid * st_openstp;
... ... @@ -604,7 +604,7 @@
604 604 return error;
605 605 }
606 606  
607   -#endif /* defined(CONFIG_NFS_V4) */
  607 +#endif /* defined(CONFIG_NFSD_V4) */
608 608  
609 609 #ifdef CONFIG_NFSD_V3
610 610 /*
... ... @@ -903,7 +903,6 @@
903 903 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
904 904 {
905 905 struct inode *inode;
906   - struct raparms *ra;
907 906 mm_segment_t oldfs;
908 907 __be32 err;
909 908 int host_err;
... ... @@ -914,12 +913,6 @@
914 913 if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
915 914 goto out;
916 915  
917   - /* Get readahead parameters */
918   - ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
919   -
920   - if (ra && ra->p_set)
921   - file->f_ra = ra->p_ra;
922   -
923 916 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
924 917 struct splice_desc sd = {
925 918 .len = 0,
... ... @@ -937,16 +930,6 @@
937 930 set_fs(oldfs);
938 931 }
939 932  
940   - /* Write back readahead params */
941   - if (ra) {
942   - struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
943   - spin_lock(&rab->pb_lock);
944   - ra->p_ra = file->f_ra;
945   - ra->p_set = 1;
946   - ra->p_count--;
947   - spin_unlock(&rab->pb_lock);
948   - }
949   -
950 933 if (host_err >= 0) {
951 934 nfsdstats.io_read += host_err;
952 935 *count = host_err;
953 936  
... ... @@ -1086,8 +1069,45 @@
1086 1069 * on entry. On return, *count contains the number of bytes actually read.
1087 1070 * N.B. After this call fhp needs an fh_put
1088 1071 */
  1072 +__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
  1073 + loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
  1074 +{
  1075 + struct file *file;
  1076 + struct inode *inode;
  1077 + struct raparms *ra;
  1078 + __be32 err;
  1079 +
  1080 + err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
  1081 + if (err)
  1082 + return err;
  1083 +
  1084 + inode = file->f_path.dentry->d_inode;
  1085 +
  1086 + /* Get readahead parameters */
  1087 + ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
  1088 +
  1089 + if (ra && ra->p_set)
  1090 + file->f_ra = ra->p_ra;
  1091 +
  1092 + err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
  1093 +
  1094 + /* Write back readahead params */
  1095 + if (ra) {
  1096 + struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
  1097 + spin_lock(&rab->pb_lock);
  1098 + ra->p_ra = file->f_ra;
  1099 + ra->p_set = 1;
  1100 + ra->p_count--;
  1101 + spin_unlock(&rab->pb_lock);
  1102 + }
  1103 +
  1104 + nfsd_close(file);
  1105 + return err;
  1106 +}
  1107 +
  1108 +/* As above, but use the provided file descriptor. */
1089 1109 __be32
1090   -nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
  1110 +nfsd_read_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1091 1111 loff_t offset, struct kvec *vec, int vlen,
1092 1112 unsigned long *count)
1093 1113 {
... ... @@ -1099,13 +1119,8 @@
1099 1119 if (err)
1100 1120 goto out;
1101 1121 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1102   - } else {
1103   - err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
1104   - if (err)
1105   - goto out;
1106   - err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1107   - nfsd_close(file);
1108   - }
  1122 + } else /* Note file may still be NULL in NFSv4 special stateid case: */
  1123 + err = nfsd_read(rqstp, fhp, offset, vec, vlen, count);
1109 1124 out:
1110 1125 return err;
1111 1126 }
... ... @@ -1631,7 +1646,7 @@
1631 1646 char *name, int len, struct svc_fh *tfhp)
1632 1647 {
1633 1648 struct dentry *ddir, *dnew, *dold;
1634   - struct inode *dirp, *dest;
  1649 + struct inode *dirp;
1635 1650 __be32 err;
1636 1651 int host_err;
1637 1652  
... ... @@ -1659,7 +1674,6 @@
1659 1674 goto out_nfserr;
1660 1675  
1661 1676 dold = tfhp->fh_dentry;
1662   - dest = dold->d_inode;
1663 1677  
1664 1678 host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt);
1665 1679 if (host_err) {
... ... @@ -2038,7 +2052,6 @@
2038 2052 struct dentry *dentry, int acc)
2039 2053 {
2040 2054 struct inode *inode = dentry->d_inode;
2041   - struct path path;
2042 2055 int err;
2043 2056  
2044 2057 if (acc == NFSD_MAY_NOP)
2045 2058  
... ... @@ -2111,15 +2124,7 @@
2111 2124 if (err == -EACCES && S_ISREG(inode->i_mode) &&
2112 2125 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE))
2113 2126 err = inode_permission(inode, MAY_EXEC);
2114   - if (err)
2115   - goto nfsd_out;
2116 2127  
2117   - /* Do integrity (permission) checking now, but defer incrementing
2118   - * IMA counts to the actual file open.
2119   - */
2120   - path.mnt = exp->ex_path.mnt;
2121   - path.dentry = dentry;
2122   -nfsd_out:
2123 2128 return err? nfserrno(err) : 0;
2124 2129 }
2125 2130  
... ... @@ -64,7 +64,9 @@
64 64 __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int,
65 65 int, struct file **);
66 66 void nfsd_close(struct file *);
67   -__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
  67 +__be32 nfsd_read(struct svc_rqst *, struct svc_fh *,
  68 + loff_t, struct kvec *, int, unsigned long *);
  69 +__be32 nfsd_read_file(struct svc_rqst *, struct svc_fh *, struct file *,
68 70 loff_t, struct kvec *, int, unsigned long *);
69 71 __be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
70 72 loff_t, struct kvec *,int, unsigned long *, int *);
include/linux/sunrpc/cache.h
... ... @@ -192,6 +192,7 @@
192 192 extern void cache_flush(void);
193 193 extern void cache_purge(struct cache_detail *detail);
194 194 #define NEVER (0x7FFFFFFF)
  195 +extern void __init cache_initialize(void);
195 196 extern int cache_register(struct cache_detail *cd);
196 197 extern void cache_unregister(struct cache_detail *cd);
197 198  
... ... @@ -34,7 +34,6 @@
34 34 #include <linux/sunrpc/cache.h>
35 35 #include <linux/sunrpc/stats.h>
36 36 #include <linux/sunrpc/rpc_pipe_fs.h>
37   -#include <linux/smp_lock.h>
38 37  
39 38 #define RPCDBG_FACILITY RPCDBG_CACHE
40 39  
... ... @@ -320,7 +319,7 @@
320 319 static int current_index;
321 320  
322 321 static void do_cache_clean(struct work_struct *work);
323   -static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean);
  322 +static struct delayed_work cache_cleaner;
324 323  
325 324 static void sunrpc_init_cache_detail(struct cache_detail *cd)
326 325 {
... ... @@ -1503,6 +1502,11 @@
1503 1502 return 0;
1504 1503 }
1505 1504 #endif
  1505 +
  1506 +void __init cache_initialize(void)
  1507 +{
  1508 + INIT_DELAYED_WORK_DEFERRABLE(&cache_cleaner, do_cache_clean);
  1509 +}
1506 1510  
1507 1511 int cache_register(struct cache_detail *cd)
1508 1512 {
net/sunrpc/sunrpc_syms.c
... ... @@ -44,6 +44,7 @@
44 44 #ifdef CONFIG_PROC_FS
45 45 rpc_proc_init();
46 46 #endif
  47 + cache_initialize();
47 48 cache_register(&ip_map_cache);
48 49 cache_register(&unix_gid_cache);
49 50 svc_init_xprt_sock(); /* svc sock transport */