Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull nfsd updates from Bruce Fields:
- Handle some loose ends from the vfs read delegation support.
(For example nfsd can stop breaking leases on its own in a
fewer places where it can now depend on the vfs to.)
- Make life a little easier for NFSv4-only configurations
(thanks to Kinglong Mee).
- Fix some gss-proxy problems (thanks Jeff Layton).
- miscellaneous bug fixes and cleanup

* 'for-3.14' of git://linux-nfs.org/~bfields/linux: (38 commits)
nfsd: consider CLAIM_FH when handing out delegation
nfsd4: fix delegation-unlink/rename race
nfsd4: delay setting current_fh in open
nfsd4: minor nfs4_setlease cleanup
gss_krb5: use lcm from kernel lib
nfsd4: decrease nfsd4_encode_fattr stack usage
nfsd: fix encode_entryplus_baggage stack usage
nfsd4: simplify xdr encoding of nfsv4 names
nfsd4: encode_rdattr_error cleanup
nfsd4: nfsd4_encode_fattr cleanup
minor svcauth_gss.c cleanup
nfsd4: better VERIFY comment
nfsd4: break only delegations when appropriate
NFSD: Fix a memory leak in nfsd4_create_session
sunrpc: get rid of use_gssp_lock
sunrpc: fix potential race between setting use_gss_proxy and the upcall rpc_clnt
sunrpc: don't wait for write before allowing reads from use-gss-proxy file
nfsd: get rid of unused function definition
Define op_iattr for nfsd4_open instead using macro
NFSD: fix compile warning without CONFIG_NFSD_V3
...

+288 -397
+14 -28
Documentation/filesystems/nfs/nfs41-server.txt
··· 5 5 by reading this file will contain either "+4.1" or "-4.1" 6 6 correspondingly. 7 7 8 - Currently, server support for minorversion 1 is disabled by default. 9 - It can be enabled at run time by writing the string "+4.1" to 8 + Currently, server support for minorversion 1 is enabled by default. 9 + It can be disabled at run time by writing the string "-4.1" to 10 10 the /proc/fs/nfsd/versions control file. Note that to write this 11 - control file, the nfsd service must be taken down. Use your user-mode 12 - nfs-utils to set this up; see rpc.nfsd(8) 11 + control file, the nfsd service must be taken down. You can use rpc.nfsd 12 + for this; see rpc.nfsd(8). 13 13 14 14 (Warning: older servers will interpret "+4.1" and "-4.1" as "+4" and 15 15 "-4", respectively. Therefore, code meant to work on both new and old ··· 28 28 are still under development out of tree. 29 29 See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design 30 30 for more information. 31 - 32 - The current implementation is intended for developers only: while it 33 - does support ordinary file operations on clients we have tested against 34 - (including the linux client), it is incomplete in ways which may limit 35 - features unexpectedly, cause known bugs in rare cases, or cause 36 - interoperability problems with future clients. Known issues: 37 - 38 - - gss support is questionable: currently mounts with kerberos 39 - from a linux client are possible, but we aren't really 40 - conformant with the spec (for example, we don't use kerberos 41 - on the backchannel correctly). 42 - - We do not support SSV, which provides security for shared 43 - client-server state (thus preventing unauthorized tampering 44 - with locks and opens, for example). It is mandatory for 45 - servers to support this, though no clients use it yet. 46 - 47 - In addition, some limitations are inherited from the current NFSv4 48 - implementation: 49 - 50 - - Incomplete delegation enforcement: if a file is renamed or 51 - unlinked by a local process, a client holding a delegation may 52 - continue to indefinitely allow opens of the file under the old 53 - name. 54 31 55 32 The table below, taken from the NFSv4.1 document, lists 56 33 the operations that are mandatory to implement (REQ), optional ··· 146 169 147 170 Implementation notes: 148 171 172 + SSV: 173 + * The spec claims this is mandatory, but we don't actually know of any 174 + implementations, so we're ignoring it for now. The server returns 175 + NFS4ERR_ENCR_ALG_UNSUPP on EXCHANGE_ID, which should be future-proof. 176 + 177 + GSS on the backchannel: 178 + * Again, theoretically required but not widely implemented (in 179 + particular, the current Linux client doesn't request it). We return 180 + NFS4ERR_ENCR_ALG_UNSUPP on CREATE_SESSION. 181 + 149 182 DELEGPURGE: 150 183 * mandatory only for servers that support CLAIM_DELEGATE_PREV and/or 151 184 CLAIM_DELEG_PREV_FH (which allows clients to keep delegations that ··· 163 176 now. 164 177 165 178 EXCHANGE_ID: 166 - * only SP4_NONE state protection supported 167 179 * implementation ids are ignored 168 180 169 181 CREATE_SESSION:
+1 -1
fs/nfsd/acl.h
··· 45 45 46 46 struct nfs4_acl *nfs4_acl_new(int); 47 47 int nfs4_acl_get_whotype(char *, u32); 48 - int nfs4_acl_write_who(int who, char *p); 48 + __be32 nfs4_acl_write_who(int who, __be32 **p, int *len); 49 49 50 50 int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, 51 51 struct nfs4_acl **acl);
-8
fs/nfsd/cache.h
··· 84 84 void nfsd_cache_update(struct svc_rqst *, int, __be32 *); 85 85 int nfsd_reply_cache_stats_open(struct inode *, struct file *); 86 86 87 - #ifdef CONFIG_NFSD_V4 88 - void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp); 89 - #else /* CONFIG_NFSD_V4 */ 90 - static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp) 91 - { 92 - } 93 - #endif /* CONFIG_NFSD_V4 */ 94 - 95 87 #endif /* NFSCACHE_H */
+2 -2
fs/nfsd/idmap.h
··· 56 56 57 57 __be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *); 58 58 __be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *); 59 - int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *); 60 - int nfsd_map_gid_to_name(struct svc_rqst *, kgid_t, char *); 59 + __be32 nfsd4_encode_user(struct svc_rqst *, kuid_t, __be32 **, int *); 60 + __be32 nfsd4_encode_group(struct svc_rqst *, kgid_t, __be32 **, int *); 61 61 62 62 #endif /* LINUX_NFSD_IDMAP_H */
+1
fs/nfsd/netns.h
··· 95 95 time_t nfsd4_grace; 96 96 97 97 bool nfsd_net_up; 98 + bool lockd_up; 98 99 99 100 /* 100 101 * Time of server startup
+7 -7
fs/nfsd/nfs3xdr.c
··· 168 168 struct kstat *stat) 169 169 { 170 170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 171 - *p++ = htonl((u32) stat->mode); 171 + *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 172 172 *p++ = htonl((u32) stat->nlink); 173 173 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 174 174 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); ··· 842 842 843 843 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) 844 844 { 845 - struct svc_fh fh; 845 + struct svc_fh *fh = &cd->scratch; 846 846 __be32 err; 847 847 848 - fh_init(&fh, NFS3_FHSIZE); 849 - err = compose_entry_fh(cd, &fh, name, namlen); 848 + fh_init(fh, NFS3_FHSIZE); 849 + err = compose_entry_fh(cd, fh, name, namlen); 850 850 if (err) { 851 851 *p++ = 0; 852 852 *p++ = 0; 853 853 goto out; 854 854 } 855 - p = encode_post_op_attr(cd->rqstp, p, &fh); 855 + p = encode_post_op_attr(cd->rqstp, p, fh); 856 856 *p++ = xdr_one; /* yes, a file handle follows */ 857 - p = encode_fh(p, &fh); 857 + p = encode_fh(p, fh); 858 858 out: 859 - fh_put(&fh); 859 + fh_put(fh); 860 860 return p; 861 861 } 862 862
+13 -7
fs/nfsd/nfs4acl.c
··· 38 38 #include <linux/nfs_fs.h> 39 39 #include <linux/export.h> 40 40 #include "nfsfh.h" 41 + #include "nfsd.h" 41 42 #include "acl.h" 42 43 #include "vfs.h" 43 44 ··· 917 916 return NFS4_ACL_WHO_NAMED; 918 917 } 919 918 920 - int 921 - nfs4_acl_write_who(int who, char *p) 919 + __be32 nfs4_acl_write_who(int who, __be32 **p, int *len) 922 920 { 923 921 int i; 922 + int bytes; 924 923 925 924 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 926 - if (s2t_map[i].type == who) { 927 - memcpy(p, s2t_map[i].string, s2t_map[i].stringlen); 928 - return s2t_map[i].stringlen; 929 - } 925 + if (s2t_map[i].type != who) 926 + continue; 927 + bytes = 4 + (XDR_QUADLEN(s2t_map[i].stringlen) << 2); 928 + if (bytes > *len) 929 + return nfserr_resource; 930 + *p = xdr_encode_opaque(*p, s2t_map[i].string, 931 + s2t_map[i].stringlen); 932 + *len -= bytes; 933 + return 0; 930 934 } 931 - BUG(); 935 + WARN_ON_ONCE(1); 932 936 return -1; 933 937 }
+33 -17
fs/nfsd/nfs4idmap.c
··· 551 551 return 0; 552 552 } 553 553 554 - static int 555 - idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) 554 + static __be32 encode_ascii_id(u32 id, __be32 **p, int *buflen) 555 + { 556 + char buf[11]; 557 + int len; 558 + int bytes; 559 + 560 + len = sprintf(buf, "%u", id); 561 + bytes = 4 + (XDR_QUADLEN(len) << 2); 562 + if (bytes > *buflen) 563 + return nfserr_resource; 564 + *p = xdr_encode_opaque(*p, buf, len); 565 + *buflen -= bytes; 566 + return 0; 567 + } 568 + 569 + static __be32 idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) 556 570 { 557 571 struct ent *item, key = { 558 572 .id = id, 559 573 .type = type, 560 574 }; 561 575 int ret; 576 + int bytes; 562 577 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 563 578 564 579 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 565 580 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); 566 581 if (ret == -ENOENT) 567 - return sprintf(name, "%u", id); 582 + return encode_ascii_id(id, p, buflen); 568 583 if (ret) 569 - return ret; 584 + return nfserrno(ret); 570 585 ret = strlen(item->name); 571 - BUG_ON(ret > IDMAP_NAMESZ); 572 - memcpy(name, item->name, ret); 586 + WARN_ON_ONCE(ret > IDMAP_NAMESZ); 587 + bytes = 4 + (XDR_QUADLEN(ret) << 2); 588 + if (bytes > *buflen) 589 + return nfserr_resource; 590 + *p = xdr_encode_opaque(*p, item->name, ret); 591 + *buflen -= bytes; 573 592 cache_put(&item->h, nn->idtoname_cache); 574 - return ret; 593 + return 0; 575 594 } 576 595 577 596 static bool ··· 622 603 return idmap_name_to_id(rqstp, type, name, namelen, id); 623 604 } 624 605 625 - static int 626 - do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) 606 + static __be32 encode_name_from_id(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) 627 607 { 628 608 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 629 - return sprintf(name, "%u", id); 630 - return idmap_id_to_name(rqstp, type, id, name); 609 + return encode_ascii_id(id, p, buflen); 610 + return idmap_id_to_name(rqstp, type, id, p, buflen); 631 611 } 632 612 633 613 __be32 ··· 655 637 return status; 656 638 } 657 639 658 - int 659 - nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name) 640 + __be32 nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t uid, __be32 **p, int *buflen) 660 641 { 661 642 u32 id = from_kuid(&init_user_ns, uid); 662 - return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 643 + return encode_name_from_id(rqstp, IDMAP_TYPE_USER, id, p, buflen); 663 644 } 664 645 665 - int 666 - nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name) 646 + __be32 nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t gid, __be32 **p, int *buflen) 667 647 { 668 648 u32 id = from_kgid(&init_user_ns, gid); 669 - return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 649 + return encode_name_from_id(rqstp, IDMAP_TYPE_GROUP, id, p, buflen); 670 650 }
+34 -23
fs/nfsd/nfs4proc.c
··· 231 231 } 232 232 233 233 static __be32 234 - do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 234 + do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh) 235 235 { 236 236 struct svc_fh *current_fh = &cstate->current_fh; 237 - struct svc_fh *resfh; 238 237 int accmode; 239 238 __be32 status; 240 239 241 - resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 242 - if (!resfh) 240 + *resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 241 + if (!*resfh) 243 242 return nfserr_jukebox; 244 - fh_init(resfh, NFS4_FHSIZE); 243 + fh_init(*resfh, NFS4_FHSIZE); 245 244 open->op_truncate = 0; 246 245 247 246 if (open->op_create) { ··· 265 266 */ 266 267 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 267 268 open->op_fname.len, &open->op_iattr, 268 - resfh, open->op_createmode, 269 + *resfh, open->op_createmode, 269 270 (u32 *)open->op_verf.data, 270 271 &open->op_truncate, &open->op_created); 271 272 272 273 if (!status && open->op_label.len) 273 - nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval); 274 + nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval); 274 275 275 276 /* 276 277 * Following rfc 3530 14.2.16, use the returned bitmask ··· 280 281 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) 281 282 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | 282 283 FATTR4_WORD1_TIME_MODIFY); 283 - } else { 284 + } else 285 + /* 286 + * Note this may exit with the parent still locked. 287 + * We will hold the lock until nfsd4_open's final 288 + * lookup, to prevent renames or unlinks until we've had 289 + * a chance to an acquire a delegation if appropriate. 290 + */ 284 291 status = nfsd_lookup(rqstp, current_fh, 285 - open->op_fname.data, open->op_fname.len, resfh); 286 - fh_unlock(current_fh); 287 - } 292 + open->op_fname.data, open->op_fname.len, *resfh); 288 293 if (status) 289 294 goto out; 290 - status = nfsd_check_obj_isreg(resfh); 295 + status = nfsd_check_obj_isreg(*resfh); 291 296 if (status) 292 297 goto out; 293 298 294 299 if (is_create_with_attrs(open) && open->op_acl != NULL) 295 - do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval); 300 + do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval); 296 301 297 - nfsd4_set_open_owner_reply_cache(cstate, open, resfh); 302 + nfsd4_set_open_owner_reply_cache(cstate, open, *resfh); 298 303 accmode = NFSD_MAY_NOP; 299 304 if (open->op_created || 300 305 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 301 306 accmode |= NFSD_MAY_OWNER_OVERRIDE; 302 - status = do_open_permission(rqstp, resfh, open, accmode); 307 + status = do_open_permission(rqstp, *resfh, open, accmode); 303 308 set_change_info(&open->op_cinfo, current_fh); 304 - fh_dup2(current_fh, resfh); 305 309 out: 306 - fh_put(resfh); 307 - kfree(resfh); 308 310 return status; 309 311 } 310 312 ··· 358 358 struct nfsd4_open *open) 359 359 { 360 360 __be32 status; 361 + struct svc_fh *resfh = NULL; 361 362 struct nfsd4_compoundres *resp; 362 363 struct net *net = SVC_NET(rqstp); 363 364 struct nfsd_net *nn = net_generic(net, nfsd_net_id); ··· 425 424 switch (open->op_claim_type) { 426 425 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 427 426 case NFS4_OPEN_CLAIM_NULL: 428 - status = do_open_lookup(rqstp, cstate, open); 427 + status = do_open_lookup(rqstp, cstate, open, &resfh); 429 428 if (status) 430 429 goto out; 431 430 break; ··· 441 440 status = do_open_fhandle(rqstp, cstate, open); 442 441 if (status) 443 442 goto out; 443 + resfh = &cstate->current_fh; 444 444 break; 445 445 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 446 446 case NFS4_OPEN_CLAIM_DELEGATE_PREV: ··· 461 459 * successful, it (1) truncates the file if open->op_truncate was 462 460 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 463 461 */ 464 - status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 462 + status = nfsd4_process_open2(rqstp, resfh, open); 465 463 WARN_ON(status && open->op_created); 466 464 out: 465 + if (resfh && resfh != &cstate->current_fh) { 466 + fh_dup2(&cstate->current_fh, resfh); 467 + fh_put(resfh); 468 + kfree(resfh); 469 + } 467 470 nfsd4_cleanup_open_state(open, status); 468 471 if (open->op_openowner && !nfsd4_has_session(cstate)) 469 472 cstate->replay_owner = &open->op_openowner->oo_owner; ··· 1077 1070 cstate->current_fh.fh_dentry, &p, 1078 1071 count, verify->ve_bmval, 1079 1072 rqstp, 0); 1080 - 1081 - /* this means that nfsd4_encode_fattr() ran out of space */ 1073 + /* 1074 + * If nfsd4_encode_fattr() ran out of space, assume that's because 1075 + * the attributes are longer (hence different) than those given: 1076 + */ 1082 1077 if (status == nfserr_resource) 1083 1078 status = nfserr_not_same; 1084 1079 if (status) ··· 1534 1525 static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1535 1526 { 1536 1527 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1537 - 1 + 1 + 2 + /* eir_flags, spr_how, spo_must_enforce & _allow */\ 1528 + 1 + 1 + /* eir_flags, spr_how */\ 1529 + 4 + /* spo_must_enforce & _allow with bitmap */\ 1538 1530 2 + /*eir_server_owner.so_minor_id */\ 1539 1531 /* eir_server_owner.so_major_id<> */\ 1540 1532 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ ··· 1892 1882 .vs_proc = nfsd_procedures4, 1893 1883 .vs_dispatch = nfsd_dispatch, 1894 1884 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1885 + .vs_rpcb_optnl = 1, 1895 1886 }; 1896 1887 1897 1888 /*
+25 -15
fs/nfsd/nfs4state.c
··· 832 832 spin_unlock(&nfsd_drc_lock); 833 833 } 834 834 835 - static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs) 835 + static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs, 836 + struct nfsd4_channel_attrs *battrs) 836 837 { 837 - int numslots = attrs->maxreqs; 838 - int slotsize = slot_bytes(attrs); 838 + int numslots = fattrs->maxreqs; 839 + int slotsize = slot_bytes(fattrs); 839 840 struct nfsd4_session *new; 840 841 int mem, i; 841 842 ··· 853 852 if (!new->se_slots[i]) 854 853 goto out_free; 855 854 } 855 + 856 + memcpy(&new->se_fchannel, fattrs, sizeof(struct nfsd4_channel_attrs)); 857 + memcpy(&new->se_bchannel, battrs, sizeof(struct nfsd4_channel_attrs)); 858 + 856 859 return new; 857 860 out_free: 858 861 while (i--) ··· 1002 997 list_add(&new->se_perclnt, &clp->cl_sessions); 1003 998 spin_unlock(&clp->cl_lock); 1004 999 spin_unlock(&nn->client_lock); 1005 - memcpy(&new->se_fchannel, &cses->fore_channel, 1006 - sizeof(struct nfsd4_channel_attrs)); 1000 + 1007 1001 if (cses->flags & SESSION4_BACK_CHAN) { 1008 1002 struct sockaddr *sa = svc_addr(rqstp); 1009 1003 /* ··· 1855 1851 return nfs_ok; 1856 1852 } 1857 1853 1854 + #define NFSD_CB_MAX_REQ_SZ ((NFS4_enc_cb_recall_sz + \ 1855 + RPC_MAX_HEADER_WITH_AUTH) * sizeof(__be32)) 1856 + #define NFSD_CB_MAX_RESP_SZ ((NFS4_dec_cb_recall_sz + \ 1857 + RPC_MAX_REPHEADER_WITH_AUTH) * sizeof(__be32)) 1858 + 1858 1859 static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca) 1859 1860 { 1860 1861 ca->headerpadsz = 0; ··· 1870 1861 * less than 1k. Tighten up this estimate in the unlikely event 1871 1862 * it turns out to be a problem for some client: 1872 1863 */ 1873 - if (ca->maxreq_sz < NFS4_enc_cb_recall_sz + RPC_MAX_HEADER_WITH_AUTH) 1864 + if (ca->maxreq_sz < NFSD_CB_MAX_REQ_SZ) 1874 1865 return nfserr_toosmall; 1875 - if (ca->maxresp_sz < NFS4_dec_cb_recall_sz + RPC_MAX_REPHEADER_WITH_AUTH) 1866 + if (ca->maxresp_sz < NFSD_CB_MAX_RESP_SZ) 1876 1867 return nfserr_toosmall; 1877 1868 ca->maxresp_cached = 0; 1878 1869 if (ca->maxops < 2) ··· 1922 1913 return status; 1923 1914 status = check_backchannel_attrs(&cr_ses->back_channel); 1924 1915 if (status) 1925 - return status; 1916 + goto out_release_drc_mem; 1926 1917 status = nfserr_jukebox; 1927 - new = alloc_session(&cr_ses->fore_channel); 1918 + new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel); 1928 1919 if (!new) 1929 1920 goto out_release_drc_mem; 1930 1921 conn = alloc_conn_from_crses(rqstp, cr_ses); ··· 3043 3034 if (!fl) 3044 3035 return -ENOMEM; 3045 3036 fl->fl_file = find_readable_file(fp); 3046 - list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 3047 3037 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); 3048 - if (status) { 3049 - list_del_init(&dp->dl_perclnt); 3050 - locks_free_lock(fl); 3051 - return status; 3052 - } 3038 + if (status) 3039 + goto out_free; 3040 + list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 3053 3041 fp->fi_lease = fl; 3054 3042 fp->fi_deleg_file = get_file(fl->fl_file); 3055 3043 atomic_set(&fp->fi_delegees, 1); 3056 3044 list_add(&dp->dl_perfile, &fp->fi_delegations); 3057 3045 return 0; 3046 + out_free: 3047 + locks_free_lock(fl); 3048 + return status; 3058 3049 } 3059 3050 3060 3051 static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp) ··· 3134 3125 goto out_no_deleg; 3135 3126 break; 3136 3127 case NFS4_OPEN_CLAIM_NULL: 3128 + case NFS4_OPEN_CLAIM_FH: 3137 3129 /* 3138 3130 * Let's not give out any delegations till everyone's 3139 3131 * had the chance to reclaim theirs....
+62 -116
fs/nfsd/nfs4xdr.c
··· 103 103 (x) = (u64)ntohl(*p++) << 32; \ 104 104 (x) |= ntohl(*p++); \ 105 105 } while (0) 106 - #define READTIME(x) do { \ 107 - p++; \ 108 - (x) = ntohl(*p++); \ 109 - p++; \ 110 - } while (0) 111 106 #define READMEM(x,nbytes) do { \ 112 107 x = (char *)p; \ 113 108 p += XDR_QUADLEN(nbytes); \ ··· 185 190 return (clid->cl_boot == 0) && (clid->cl_id == 0); 186 191 } 187 192 193 + /** 194 + * defer_free - mark an allocation as deferred freed 195 + * @argp: NFSv4 compound argument structure to be freed with 196 + * @release: release callback to free @p, typically kfree() 197 + * @p: pointer to be freed 198 + * 199 + * Marks @p to be freed when processing the compound operation 200 + * described in @argp finishes. 201 + */ 188 202 static int 189 203 defer_free(struct nfsd4_compoundargs *argp, 190 204 void (*release)(const void *), void *p) ··· 210 206 return 0; 211 207 } 212 208 209 + /** 210 + * savemem - duplicate a chunk of memory for later processing 211 + * @argp: NFSv4 compound argument structure to be freed with 212 + * @p: pointer to be duplicated 213 + * @nbytes: length to be duplicated 214 + * 215 + * Returns a pointer to a copy of @nbytes bytes of memory at @p 216 + * that are preserved until processing of the NFSv4 compound 217 + * operation described by @argp finishes. 218 + */ 213 219 static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) 214 220 { 215 221 if (p == argp->tmp) { ··· 271 257 int expected_len, len = 0; 272 258 u32 dummy32; 273 259 char *buf; 274 - int host_err; 275 260 276 261 DECODE_HEAD; 277 262 iattr->ia_valid = 0; ··· 297 284 return nfserr_resource; 298 285 299 286 *acl = nfs4_acl_new(nace); 300 - if (*acl == NULL) { 301 - host_err = -ENOMEM; 302 - goto out_nfserr; 303 - } 287 + if (*acl == NULL) 288 + return nfserr_jukebox; 289 + 304 290 defer_free(argp, kfree, *acl); 305 291 306 292 (*acl)->naces = nace; ··· 437 425 goto xdr_error; 438 426 439 427 DECODE_TAIL; 440 - 441 - out_nfserr: 442 - status = nfserrno(host_err); 443 - goto out; 444 428 } 445 429 446 430 static __be32 ··· 1965 1957 }; 1966 1958 } 1967 1959 1968 - static __be32 1969 - nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid, 1970 - __be32 **p, int *buflen) 1971 - { 1972 - int status; 1973 - 1974 - if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4) 1975 - return nfserr_resource; 1976 - if (whotype != NFS4_ACL_WHO_NAMED) 1977 - status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); 1978 - else if (gid_valid(gid)) 1979 - status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1)); 1980 - else 1981 - status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1)); 1982 - if (status < 0) 1983 - return nfserrno(status); 1984 - *p = xdr_encode_opaque(*p, NULL, status); 1985 - *buflen -= (XDR_QUADLEN(status) << 2) + 4; 1986 - BUG_ON(*buflen < 0); 1987 - return 0; 1988 - } 1989 - 1990 - static inline __be32 1991 - nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen) 1992 - { 1993 - return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID, 1994 - p, buflen); 1995 - } 1996 - 1997 - static inline __be32 1998 - nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen) 1999 - { 2000 - return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group, 2001 - p, buflen); 2002 - } 2003 - 2004 1960 static inline __be32 2005 1961 nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace, 2006 1962 __be32 **p, int *buflen) 2007 1963 { 2008 - kuid_t uid = INVALID_UID; 2009 - kgid_t gid = INVALID_GID; 2010 - 2011 - if (ace->whotype == NFS4_ACL_WHO_NAMED) { 2012 - if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 2013 - gid = ace->who_gid; 2014 - else 2015 - uid = ace->who_uid; 2016 - } 2017 - return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen); 1964 + if (ace->whotype != NFS4_ACL_WHO_NAMED) 1965 + return nfs4_acl_write_who(ace->whotype, p, buflen); 1966 + else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 1967 + return nfsd4_encode_group(rqstp, ace->who_gid, p, buflen); 1968 + else 1969 + return nfsd4_encode_user(rqstp, ace->who_uid, p, buflen); 2018 1970 } 2019 1971 2020 1972 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ ··· 2058 2090 u32 bmval1 = bmval[1]; 2059 2091 u32 bmval2 = bmval[2]; 2060 2092 struct kstat stat; 2061 - struct svc_fh tempfh; 2093 + struct svc_fh *tempfh = NULL; 2062 2094 struct kstatfs statfs; 2063 2095 int buflen = count << 2; 2064 2096 __be32 *attrlenp; ··· 2105 2137 goto out_nfserr; 2106 2138 } 2107 2139 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { 2108 - fh_init(&tempfh, NFS4_FHSIZE); 2109 - status = fh_compose(&tempfh, exp, dentry, NULL); 2140 + tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 2141 + status = nfserr_jukebox; 2142 + if (!tempfh) 2143 + goto out; 2144 + fh_init(tempfh, NFS4_FHSIZE); 2145 + status = fh_compose(tempfh, exp, dentry, NULL); 2110 2146 if (status) 2111 2147 goto out; 2112 - fhp = &tempfh; 2148 + fhp = tempfh; 2113 2149 } 2114 2150 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT 2115 2151 | FATTR4_WORD0_SUPPORTED_ATTRS)) { ··· 2194 2222 if ((buflen -= 4) < 0) 2195 2223 goto out_resource; 2196 2224 dummy = nfs4_file_type(stat.mode); 2197 - if (dummy == NF4BAD) 2198 - goto out_serverfault; 2225 + if (dummy == NF4BAD) { 2226 + status = nfserr_serverfault; 2227 + goto out; 2228 + } 2199 2229 WRITE32(dummy); 2200 2230 } 2201 2231 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { ··· 2291 2317 WRITE32(ace->flag); 2292 2318 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 2293 2319 status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen); 2294 - if (status == nfserr_resource) 2295 - goto out_resource; 2296 2320 if (status) 2297 2321 goto out; 2298 2322 } ··· 2351 2379 } 2352 2380 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 2353 2381 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); 2354 - if (status == nfserr_resource) 2355 - goto out_resource; 2356 2382 if (status) 2357 2383 goto out; 2358 2384 } ··· 2401 2431 } 2402 2432 if (bmval1 & FATTR4_WORD1_OWNER) { 2403 2433 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); 2404 - if (status == nfserr_resource) 2405 - goto out_resource; 2406 2434 if (status) 2407 2435 goto out; 2408 2436 } 2409 2437 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { 2410 2438 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); 2411 - if (status == nfserr_resource) 2412 - goto out_resource; 2413 2439 if (status) 2414 2440 goto out; 2415 2441 } ··· 2499 2533 security_release_secctx(context, contextlen); 2500 2534 #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ 2501 2535 kfree(acl); 2502 - if (fhp == &tempfh) 2503 - fh_put(&tempfh); 2536 + if (tempfh) 2537 + fh_put(tempfh); 2504 2538 return status; 2505 2539 out_nfserr: 2506 2540 status = nfserrno(err); 2507 2541 goto out; 2508 2542 out_resource: 2509 2543 status = nfserr_resource; 2510 - goto out; 2511 - out_serverfault: 2512 - status = nfserr_serverfault; 2513 2544 goto out; 2514 2545 } 2515 2546 ··· 2584 2621 static __be32 * 2585 2622 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) 2586 2623 { 2587 - __be32 *attrlenp; 2588 - 2589 2624 if (buflen < 6) 2590 2625 return NULL; 2591 2626 *p++ = htonl(2); 2592 2627 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */ 2593 2628 *p++ = htonl(0); /* bmval1 */ 2594 2629 2595 - attrlenp = p++; 2630 + *p++ = htonl(4); /* attribute length */ 2596 2631 *p++ = nfserr; /* no htonl */ 2597 - *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2598 2632 return p; 2599 2633 } 2600 2634 ··· 3204 3244 3205 3245 if (rpcauth_get_gssinfo(pf, &info) == 0) { 3206 3246 supported++; 3207 - RESERVE_SPACE(4 + 4 + info.oid.len + 4 + 4); 3247 + RESERVE_SPACE(4 + 4 + XDR_LEN(info.oid.len) + 4 + 4); 3208 3248 WRITE32(RPC_AUTH_GSS); 3209 3249 WRITE32(info.oid.len); 3210 3250 WRITEMEM(info.oid.data, info.oid.len); ··· 3339 3379 8 /* eir_clientid */ + 3340 3380 4 /* eir_sequenceid */ + 3341 3381 4 /* eir_flags */ + 3342 - 4 /* spr_how */ + 3343 - 8 /* spo_must_enforce, spo_must_allow */ + 3344 - 8 /* so_minor_id */ + 3345 - 4 /* so_major_id.len */ + 3346 - (XDR_QUADLEN(major_id_sz) * 4) + 3347 - 4 /* eir_server_scope.len */ + 3348 - (XDR_QUADLEN(server_scope_sz) * 4) + 3349 - 4 /* eir_server_impl_id.count (0) */); 3382 + 4 /* spr_how */); 3350 3383 3351 3384 WRITEMEM(&exid->clientid, 8); 3352 3385 WRITE32(exid->seqid); 3353 3386 WRITE32(exid->flags); 3354 3387 3355 3388 WRITE32(exid->spa_how); 3389 + ADJUST_ARGS(); 3390 + 3356 3391 switch (exid->spa_how) { 3357 3392 case SP4_NONE: 3358 3393 break; 3359 3394 case SP4_MACH_CRED: 3395 + /* spo_must_enforce, spo_must_allow */ 3396 + RESERVE_SPACE(16); 3397 + 3360 3398 /* spo_must_enforce bitmap: */ 3361 3399 WRITE32(2); 3362 3400 WRITE32(nfs4_minimal_spo_must_enforce[0]); 3363 3401 WRITE32(nfs4_minimal_spo_must_enforce[1]); 3364 3402 /* empty spo_must_allow bitmap: */ 3365 3403 WRITE32(0); 3404 + 3405 + ADJUST_ARGS(); 3366 3406 break; 3367 3407 default: 3368 3408 WARN_ON_ONCE(1); 3369 3409 } 3410 + 3411 + RESERVE_SPACE( 3412 + 8 /* so_minor_id */ + 3413 + 4 /* so_major_id.len */ + 3414 + (XDR_QUADLEN(major_id_sz) * 4) + 3415 + 4 /* eir_server_scope.len */ + 3416 + (XDR_QUADLEN(server_scope_sz) * 4) + 3417 + 4 /* eir_server_impl_id.count (0) */); 3370 3418 3371 3419 /* The server_owner struct */ 3372 3420 WRITE64(minor_id); /* Minor id */ ··· 3439 3471 ADJUST_ARGS(); 3440 3472 } 3441 3473 return 0; 3442 - } 3443 - 3444 - static __be32 3445 - nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr, 3446 - struct nfsd4_destroy_session *destroy_session) 3447 - { 3448 - return nfserr; 3449 - } 3450 - 3451 - static __be32 3452 - nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, 3453 - struct nfsd4_free_stateid *free_stateid) 3454 - { 3455 - __be32 *p; 3456 - 3457 - if (nfserr) 3458 - return nfserr; 3459 - 3460 - RESERVE_SPACE(4); 3461 - *p++ = nfserr; 3462 - ADJUST_ARGS(); 3463 - return nfserr; 3464 3474 } 3465 3475 3466 3476 static __be32 ··· 3539 3593 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, 3540 3594 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3541 3595 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3542 - [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3543 - [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_free_stateid, 3596 + [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop, 3597 + [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3544 3598 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3545 3599 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, 3546 3600 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
+4 -32
fs/nfsd/nfscache.c
··· 132 132 } 133 133 134 134 static void 135 - nfsd_reply_cache_unhash(struct svc_cacherep *rp) 136 - { 137 - hlist_del_init(&rp->c_hash); 138 - list_del_init(&rp->c_lru); 139 - } 140 - 141 - static void 142 135 nfsd_reply_cache_free_locked(struct svc_cacherep *rp) 143 136 { 144 137 if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) { ··· 409 416 410 417 /* 411 418 * Since the common case is a cache miss followed by an insert, 412 - * preallocate an entry. First, try to reuse the first entry on the LRU 413 - * if it works, then go ahead and prune the LRU list. 419 + * preallocate an entry. 414 420 */ 415 - spin_lock(&cache_lock); 416 - if (!list_empty(&lru_head)) { 417 - rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru); 418 - if (nfsd_cache_entry_expired(rp) || 419 - num_drc_entries >= max_drc_entries) { 420 - nfsd_reply_cache_unhash(rp); 421 - prune_cache_entries(); 422 - goto search_cache; 423 - } 424 - } 425 - 426 - /* No expired ones available, allocate a new one. */ 427 - spin_unlock(&cache_lock); 428 421 rp = nfsd_reply_cache_alloc(); 429 422 spin_lock(&cache_lock); 430 423 if (likely(rp)) { ··· 418 439 drc_mem_usage += sizeof(*rp); 419 440 } 420 441 421 - search_cache: 442 + /* go ahead and prune the cache */ 443 + prune_cache_entries(); 444 + 422 445 found = nfsd_cache_search(rqstp, csum); 423 446 if (found) { 424 447 if (likely(rp)) ··· 433 452 dprintk("nfsd: unable to allocate DRC entry!\n"); 434 453 goto out; 435 454 } 436 - 437 - /* 438 - * We're keeping the one we just allocated. Are we now over the 439 - * limit? Prune one off the tip of the LRU in trade for the one we 440 - * just allocated if so. 441 - */ 442 - if (num_drc_entries >= max_drc_entries) 443 - nfsd_reply_cache_free_locked(list_first_entry(&lru_head, 444 - struct svc_cacherep, c_lru)); 445 455 446 456 nfsdstats.rcmisses++; 447 457 rqstp->rq_cacherep = rp;
+25 -5
fs/nfsd/nfssvc.c
··· 241 241 nfsd_racache_shutdown(); 242 242 } 243 243 244 + static bool nfsd_needs_lockd(void) 245 + { 246 + #if defined(CONFIG_NFSD_V3) 247 + return (nfsd_versions[2] != NULL) || (nfsd_versions[3] != NULL); 248 + #else 249 + return (nfsd_versions[2] != NULL); 250 + #endif 251 + } 252 + 244 253 static int nfsd_startup_net(int nrservs, struct net *net) 245 254 { 246 255 struct nfsd_net *nn = net_generic(net, nfsd_net_id); ··· 264 255 ret = nfsd_init_socks(net); 265 256 if (ret) 266 257 goto out_socks; 267 - ret = lockd_up(net); 268 - if (ret) 269 - goto out_socks; 258 + 259 + if (nfsd_needs_lockd() && !nn->lockd_up) { 260 + ret = lockd_up(net); 261 + if (ret) 262 + goto out_socks; 263 + nn->lockd_up = 1; 264 + } 265 + 270 266 ret = nfs4_state_start_net(net); 271 267 if (ret) 272 268 goto out_lockd; ··· 280 266 return 0; 281 267 282 268 out_lockd: 283 - lockd_down(net); 269 + if (nn->lockd_up) { 270 + lockd_down(net); 271 + nn->lockd_up = 0; 272 + } 284 273 out_socks: 285 274 nfsd_shutdown_generic(); 286 275 return ret; ··· 294 277 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 295 278 296 279 nfs4_state_shutdown_net(net); 297 - lockd_down(net); 280 + if (nn->lockd_up) { 281 + lockd_down(net); 282 + nn->lockd_up = 0; 283 + } 298 284 nn->nfsd_net_up = false; 299 285 nfsd_shutdown_generic(); 300 286 }
+1 -1
fs/nfsd/nfsxdr.c
··· 152 152 type = (stat->mode & S_IFMT); 153 153 154 154 *p++ = htonl(nfs_ftypes[type >> 12]); 155 - *p++ = htonl((u32) stat->mode); 155 + *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 156 156 *p++ = htonl((u32) stat->nlink); 157 157 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 158 158 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
+7 -33
fs/nfsd/vfs.c
··· 207 207 goto out_nfserr; 208 208 } 209 209 } else { 210 - fh_lock(fhp); 210 + /* 211 + * In the nfsd4_open() case, this may be held across 212 + * subsequent open and delegation acquisition which may 213 + * need to take the child's i_mutex: 214 + */ 215 + fh_lock_nested(fhp, I_MUTEX_PARENT); 211 216 dentry = lookup_one_len(name, dparent, len); 212 217 host_err = PTR_ERR(dentry); 213 218 if (IS_ERR(dentry)) ··· 276 271 dput(dentry); 277 272 exp_put(exp); 278 273 return err; 279 - } 280 - 281 - static int nfsd_break_lease(struct inode *inode) 282 - { 283 - if (!S_ISREG(inode->i_mode)) 284 - return 0; 285 - return break_lease(inode, O_WRONLY | O_NONBLOCK); 286 274 } 287 275 288 276 /* ··· 346 348 347 349 /* Revoke setuid/setgid on chown */ 348 350 if (!S_ISDIR(inode->i_mode) && 349 - (((iap->ia_valid & ATTR_UID) && !uid_eq(iap->ia_uid, inode->i_uid)) || 350 - ((iap->ia_valid & ATTR_GID) && !gid_eq(iap->ia_gid, inode->i_gid)))) { 351 + ((iap->ia_valid & ATTR_UID) || (iap->ia_valid & ATTR_GID))) { 351 352 iap->ia_valid |= ATTR_KILL_PRIV; 352 353 if (iap->ia_valid & ATTR_MODE) { 353 354 /* we're setting mode too, just clear the s*id bits */ ··· 446 449 goto out_put_write_access; 447 450 } 448 451 449 - host_err = nfsd_break_lease(inode); 450 - if (host_err) 451 - goto out_put_write_access_nfserror; 452 - 453 452 fh_lock(fhp); 454 453 host_err = notify_change(dentry, iap, NULL); 455 454 fh_unlock(fhp); 456 455 457 - out_put_write_access_nfserror: 458 - err = nfserrno(host_err); 459 456 out_put_write_access: 460 457 if (size_change) 461 458 put_write_access(inode); ··· 1600 1609 err = nfserr_noent; 1601 1610 if (!dold->d_inode) 1602 1611 goto out_dput; 1603 - host_err = nfsd_break_lease(dold->d_inode); 1604 - if (host_err) { 1605 - err = nfserrno(host_err); 1606 - goto out_dput; 1607 - } 1608 1612 host_err = vfs_link(dold, dirp, dnew, NULL); 1609 1613 if (!host_err) { 1610 1614 err = nfserrno(commit_metadata(ffhp)); ··· 1693 1707 if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) 1694 1708 goto out_dput_new; 1695 1709 1696 - host_err = nfsd_break_lease(odentry->d_inode); 1697 - if (host_err) 1698 - goto out_dput_new; 1699 - if (ndentry->d_inode) { 1700 - host_err = nfsd_break_lease(ndentry->d_inode); 1701 - if (host_err) 1702 - goto out_dput_new; 1703 - } 1704 1710 host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); 1705 1711 if (!host_err) { 1706 1712 host_err = commit_metadata(tfhp); ··· 1762 1784 if (!type) 1763 1785 type = rdentry->d_inode->i_mode & S_IFMT; 1764 1786 1765 - host_err = nfsd_break_lease(rdentry->d_inode); 1766 - if (host_err) 1767 - goto out_put; 1768 1787 if (type != S_IFDIR) 1769 1788 host_err = vfs_unlink(dirp, rdentry, NULL); 1770 1789 else 1771 1790 host_err = vfs_rmdir(dirp, rdentry); 1772 1791 if (!host_err) 1773 1792 host_err = commit_metadata(fhp); 1774 - out_put: 1775 1793 dput(rdentry); 1776 1794 1777 1795 out_nfserr:
-2
fs/nfsd/vfs.h
··· 86 86 __be32 nfsd_rename(struct svc_rqst *, 87 87 struct svc_fh *, char *, int, 88 88 struct svc_fh *, char *, int); 89 - __be32 nfsd_remove(struct svc_rqst *, 90 - struct svc_fh *, char *, int); 91 89 __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, 92 90 char *name, int len); 93 91 __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
+3
fs/nfsd/xdr3.h
··· 174 174 struct nfsd3_readdirres { 175 175 __be32 status; 176 176 struct svc_fh fh; 177 + /* Just to save kmalloc on every readdirplus entry (svc_fh is a 178 + * little large for the stack): */ 179 + struct svc_fh scratch; 177 180 int count; 178 181 __be32 verf[2]; 179 182
+1 -3
fs/nfsd/xdr4.h
··· 228 228 u32 op_create; /* request */ 229 229 u32 op_createmode; /* request */ 230 230 u32 op_bmval[3]; /* request */ 231 - struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ 231 + struct iattr op_iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ 232 232 nfs4_verifier op_verf __attribute__((aligned(32))); 233 233 /* EXCLUSIVE4 */ 234 234 clientid_t op_clientid; /* request */ ··· 250 250 struct nfs4_acl *op_acl; 251 251 struct xdr_netobj op_label; 252 252 }; 253 - #define op_iattr iattr 254 253 255 254 struct nfsd4_open_confirm { 256 255 stateid_t oc_req_stateid /* request */; ··· 373 374 374 375 struct nfsd4_free_stateid { 375 376 stateid_t fr_stateid; /* request */ 376 - __be32 fr_status; /* response */ 377 377 }; 378 378 379 379 /* also used for NVERIFY */
+4 -2
include/linux/sunrpc/svc.h
··· 368 368 struct svc_program * pg_next; /* other programs (same xprt) */ 369 369 u32 pg_prog; /* program number */ 370 370 unsigned int pg_lovers; /* lowest version */ 371 - unsigned int pg_hivers; /* lowest version */ 371 + unsigned int pg_hivers; /* highest version */ 372 372 unsigned int pg_nvers; /* number of versions */ 373 373 struct svc_version ** pg_vers; /* version array */ 374 374 char * pg_name; /* service name */ ··· 386 386 struct svc_procedure * vs_proc; /* per-procedure info */ 387 387 u32 vs_xdrsize; /* xdrsize needed for this version */ 388 388 389 - unsigned int vs_hidden : 1; /* Don't register with portmapper. 389 + unsigned int vs_hidden : 1, /* Don't register with portmapper. 390 390 * Only used for nfsacl so far. */ 391 + vs_rpcb_optnl:1;/* Don't care the result of register. 392 + * Only used for nfsv4. */ 391 393 392 394 /* Override dispatch function (e.g. when caching replies). 393 395 * A return value of 0 means drop the request.
+4 -13
net/sunrpc/auth_gss/gss_krb5_keys.c
··· 59 59 #include <linux/crypto.h> 60 60 #include <linux/sunrpc/gss_krb5.h> 61 61 #include <linux/sunrpc/xdr.h> 62 + #include <linux/lcm.h> 62 63 63 64 #ifdef RPC_DEBUG 64 65 # define RPCDBG_FACILITY RPCDBG_AUTH ··· 73 72 static void krb5_nfold(u32 inbits, const u8 *in, 74 73 u32 outbits, u8 *out) 75 74 { 76 - int a, b, c, lcm; 75 + unsigned long ulcm; 77 76 int byte, i, msbit; 78 77 79 78 /* the code below is more readable if I make these bytes ··· 83 82 outbits >>= 3; 84 83 85 84 /* first compute lcm(n,k) */ 86 - 87 - a = outbits; 88 - b = inbits; 89 - 90 - while (b != 0) { 91 - c = b; 92 - b = a%b; 93 - a = c; 94 - } 95 - 96 - lcm = outbits*inbits/a; 85 + ulcm = lcm(inbits, outbits); 97 86 98 87 /* now do the real work */ 99 88 ··· 92 101 93 102 /* this will end up cycling through k lcm(k,n)/k times, which 94 103 is correct */ 95 - for (i = lcm-1; i >= 0; i--) { 104 + for (i = ulcm-1; i >= 0; i--) { 96 105 /* compute the msbit in k which gets added into this byte */ 97 106 msbit = ( 98 107 /* first, start with the msbit in the first,
-2
net/sunrpc/auth_gss/gss_rpc_upcall.c
··· 137 137 { 138 138 mutex_init(&sn->gssp_lock); 139 139 sn->gssp_clnt = NULL; 140 - init_waitqueue_head(&sn->gssp_wq); 141 140 } 142 141 143 142 int set_gssp_clnt(struct net *net) ··· 153 154 sn->gssp_clnt = clnt; 154 155 } 155 156 mutex_unlock(&sn->gssp_lock); 156 - wake_up(&sn->gssp_wq); 157 157 return ret; 158 158 } 159 159
+26 -64
net/sunrpc/auth_gss/svcauth_gss.c
··· 1263 1263 return ret; 1264 1264 } 1265 1265 1266 - DEFINE_SPINLOCK(use_gssp_lock); 1266 + /* 1267 + * Try to set the sn->use_gss_proxy variable to a new value. We only allow 1268 + * it to be changed if it's currently undefined (-1). If it's any other value 1269 + * then return -EBUSY unless the type wouldn't have changed anyway. 1270 + */ 1271 + static int set_gss_proxy(struct net *net, int type) 1272 + { 1273 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1274 + int ret; 1275 + 1276 + WARN_ON_ONCE(type != 0 && type != 1); 1277 + ret = cmpxchg(&sn->use_gss_proxy, -1, type); 1278 + if (ret != -1 && ret != type) 1279 + return -EBUSY; 1280 + return 0; 1281 + } 1267 1282 1268 1283 static bool use_gss_proxy(struct net *net) 1269 1284 { 1270 1285 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1271 1286 1272 - if (sn->use_gss_proxy != -1) 1273 - return sn->use_gss_proxy; 1274 - spin_lock(&use_gssp_lock); 1275 - /* 1276 - * If you wanted gss-proxy, you should have said so before 1277 - * starting to accept requests: 1278 - */ 1279 - sn->use_gss_proxy = 0; 1280 - spin_unlock(&use_gssp_lock); 1281 - return 0; 1287 + /* If use_gss_proxy is still undefined, then try to disable it */ 1288 + if (sn->use_gss_proxy == -1) 1289 + set_gss_proxy(net, 0); 1290 + return sn->use_gss_proxy; 1282 1291 } 1283 1292 1284 1293 #ifdef CONFIG_PROC_FS 1285 - 1286 - static int set_gss_proxy(struct net *net, int type) 1287 - { 1288 - struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1289 - int ret = 0; 1290 - 1291 - WARN_ON_ONCE(type != 0 && type != 1); 1292 - spin_lock(&use_gssp_lock); 1293 - if (sn->use_gss_proxy == -1 || sn->use_gss_proxy == type) 1294 - sn->use_gss_proxy = type; 1295 - else 1296 - ret = -EBUSY; 1297 - spin_unlock(&use_gssp_lock); 1298 - wake_up(&sn->gssp_wq); 1299 - return ret; 1300 - } 1301 - 1302 - static inline bool gssp_ready(struct sunrpc_net *sn) 1303 - { 1304 - switch (sn->use_gss_proxy) { 1305 - case -1: 1306 - return false; 1307 - case 0: 1308 - return true; 1309 - case 1: 1310 - return sn->gssp_clnt; 1311 - } 1312 - WARN_ON_ONCE(1); 1313 - return false; 1314 - } 1315 - 1316 - static int wait_for_gss_proxy(struct net *net, struct file *file) 1317 - { 1318 - struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1319 - 1320 - if (file->f_flags & O_NONBLOCK && !gssp_ready(sn)) 1321 - return -EAGAIN; 1322 - return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn)); 1323 - } 1324 - 1325 1294 1326 1295 static ssize_t write_gssp(struct file *file, const char __user *buf, 1327 1296 size_t count, loff_t *ppos) ··· 1311 1342 return res; 1312 1343 if (i != 1) 1313 1344 return -EINVAL; 1314 - res = set_gss_proxy(net, 1); 1345 + res = set_gssp_clnt(net); 1315 1346 if (res) 1316 1347 return res; 1317 - res = set_gssp_clnt(net); 1348 + res = set_gss_proxy(net, 1); 1318 1349 if (res) 1319 1350 return res; 1320 1351 return count; ··· 1324 1355 size_t count, loff_t *ppos) 1325 1356 { 1326 1357 struct net *net = PDE_DATA(file_inode(file)); 1358 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1327 1359 unsigned long p = *ppos; 1328 1360 char tbuf[10]; 1329 1361 size_t len; 1330 - int ret; 1331 1362 1332 - ret = wait_for_gss_proxy(net, file); 1333 - if (ret) 1334 - return ret; 1335 - 1336 - snprintf(tbuf, sizeof(tbuf), "%d\n", use_gss_proxy(net)); 1363 + snprintf(tbuf, sizeof(tbuf), "%d\n", sn->use_gss_proxy); 1337 1364 len = strlen(tbuf); 1338 1365 if (p >= len) 1339 1366 return 0; ··· 1591 1626 BUG_ON(integ_len % 4); 1592 1627 *p++ = htonl(integ_len); 1593 1628 *p++ = htonl(gc->gc_seq); 1594 - if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, 1595 - integ_len)) 1629 + if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, integ_len)) 1596 1630 BUG(); 1597 1631 if (resbuf->tail[0].iov_base == NULL) { 1598 1632 if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) ··· 1599 1635 resbuf->tail[0].iov_base = resbuf->head[0].iov_base 1600 1636 + resbuf->head[0].iov_len; 1601 1637 resbuf->tail[0].iov_len = 0; 1602 - resv = &resbuf->tail[0]; 1603 - } else { 1604 - resv = &resbuf->tail[0]; 1605 1638 } 1639 + resv = &resbuf->tail[0]; 1606 1640 mic.data = (u8 *)resv->iov_base + resv->iov_len + 4; 1607 1641 if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic)) 1608 1642 goto out_err;
+1 -3
net/sunrpc/cache.c
··· 1111 1111 *bp++ = 'x'; 1112 1112 len -= 2; 1113 1113 while (blen && len >= 2) { 1114 - unsigned char c = *buf++; 1115 - *bp++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1); 1116 - *bp++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1); 1114 + bp = hex_byte_pack(bp, *buf++); 1117 1115 len -= 2; 1118 1116 blen--; 1119 1117 }
-1
net/sunrpc/netns.h
··· 27 27 unsigned int rpcb_is_af_local : 1; 28 28 29 29 struct mutex gssp_lock; 30 - wait_queue_head_t gssp_wq; 31 30 struct rpc_clnt *gssp_clnt; 32 31 int use_gss_proxy; 33 32 int pipe_version;
+17 -8
net/sunrpc/svc.c
··· 916 916 #endif 917 917 } 918 918 919 - if (error < 0) 920 - printk(KERN_WARNING "svc: failed to register %sv%u RPC " 921 - "service (errno %d).\n", progname, version, -error); 922 919 return error; 923 920 } 924 921 ··· 934 937 const unsigned short port) 935 938 { 936 939 struct svc_program *progp; 940 + struct svc_version *vers; 937 941 unsigned int i; 938 942 int error = 0; 939 943 ··· 944 946 945 947 for (progp = serv->sv_program; progp; progp = progp->pg_next) { 946 948 for (i = 0; i < progp->pg_nvers; i++) { 947 - if (progp->pg_vers[i] == NULL) 949 + vers = progp->pg_vers[i]; 950 + if (vers == NULL) 948 951 continue; 949 952 950 953 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", ··· 954 955 proto == IPPROTO_UDP? "udp" : "tcp", 955 956 port, 956 957 family, 957 - progp->pg_vers[i]->vs_hidden? 958 - " (but not telling portmap)" : ""); 958 + vers->vs_hidden ? 959 + " (but not telling portmap)" : ""); 959 960 960 - if (progp->pg_vers[i]->vs_hidden) 961 + if (vers->vs_hidden) 961 962 continue; 962 963 963 964 error = __svc_register(net, progp->pg_name, progp->pg_prog, 964 965 i, family, proto, port); 965 - if (error < 0) 966 + 967 + if (vers->vs_rpcb_optnl) { 968 + error = 0; 969 + continue; 970 + } 971 + 972 + if (error < 0) { 973 + printk(KERN_WARNING "svc: failed to register " 974 + "%sv%u RPC service (errno %d).\n", 975 + progp->pg_name, i, -error); 966 976 break; 977 + } 967 978 } 968 979 } 969 980
+3 -4
net/sunrpc/xprtsock.c
··· 2964 2964 2965 2965 /* 2966 2966 * Once we've associated a backchannel xprt with a connection, 2967 - * we want to keep it around as long as long as the connection 2968 - * lasts, in case we need to start using it for a backchannel 2969 - * again; this reference won't be dropped until bc_xprt is 2970 - * destroyed. 2967 + * we want to keep it around as long as the connection lasts, 2968 + * in case we need to start using it for a backchannel again; 2969 + * this reference won't be dropped until bc_xprt is destroyed. 2971 2970 */ 2972 2971 xprt_get(xprt); 2973 2972 args->bc_xprt->xpt_bc_xprt = xprt;