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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
NFS: NFSv4 readdir loses entries
NFS: Micro-optimize nfs4_decode_dirent()
NFS: Fix an NFS client lockdep issue
NFS construct consistent co_ownerid for v4.1
NFS: nfs_wcc_update_inode() should set nfsi->attr_gencount
NFS improve pnfs_put_deviceid_cache debug print
NFS fix cb_sequence error processing
NFS do not find client in NFSv4 pg_authenticate
NLM: Fix "kernel BUG at fs/lockd/host.c:417!" or ".../host.c:283!"
NFS: Prevent memory allocation failure in nfsacl_encode()
NFS: nfsacl_{encode,decode} should return signed integer
NFS: Fix "kernel BUG at fs/nfs/nfs3xdr.c:1338!"
NFS: Fix "kernel BUG at fs/aio.c:554!"
NFS4: Avoid potential NULL pointer dereference in decode_and_add_ds().
NFS: fix handling of malloc failure during nfs_flush_multi()

+175 -211
+5 -4
fs/lockd/host.c
··· 520 520 struct nsm_handle *nsm, 521 521 const struct nlm_reboot *info) 522 522 { 523 - struct nlm_host *host = NULL; 523 + struct nlm_host *host; 524 524 struct hlist_head *chain; 525 525 struct hlist_node *pos; 526 526 ··· 532 532 host->h_state++; 533 533 534 534 nlm_get_host(host); 535 - goto out; 535 + mutex_unlock(&nlm_host_mutex); 536 + return host; 536 537 } 537 538 } 538 - out: 539 + 539 540 mutex_unlock(&nlm_host_mutex); 540 - return host; 541 + return NULL; 541 542 } 542 543 543 544 /**
+29 -80
fs/nfs/callback.c
··· 135 135 136 136 #if defined(CONFIG_NFS_V4_1) 137 137 /* 138 - * * CB_SEQUENCE operations will fail until the callback sessionid is set. 139 - * */ 140 - int nfs4_set_callback_sessionid(struct nfs_client *clp) 141 - { 142 - struct svc_serv *serv = clp->cl_rpcclient->cl_xprt->bc_serv; 143 - struct nfs4_sessionid *bc_sid; 144 - 145 - if (!serv->sv_bc_xprt) 146 - return -EINVAL; 147 - 148 - /* on success freed in xprt_free */ 149 - bc_sid = kmalloc(sizeof(struct nfs4_sessionid), GFP_KERNEL); 150 - if (!bc_sid) 151 - return -ENOMEM; 152 - memcpy(bc_sid->data, &clp->cl_session->sess_id.data, 153 - NFS4_MAX_SESSIONID_LEN); 154 - spin_lock_bh(&serv->sv_cb_lock); 155 - serv->sv_bc_xprt->xpt_bc_sid = bc_sid; 156 - spin_unlock_bh(&serv->sv_cb_lock); 157 - dprintk("%s set xpt_bc_sid=%u:%u:%u:%u for sv_bc_xprt %p\n", __func__, 158 - ((u32 *)bc_sid->data)[0], ((u32 *)bc_sid->data)[1], 159 - ((u32 *)bc_sid->data)[2], ((u32 *)bc_sid->data)[3], 160 - serv->sv_bc_xprt); 161 - return 0; 162 - } 163 - 164 - /* 165 138 * The callback service for NFSv4.1 callbacks 166 139 */ 167 140 static int ··· 239 266 struct nfs_callback_data *cb_info) 240 267 { 241 268 } 242 - int nfs4_set_callback_sessionid(struct nfs_client *clp) 243 - { 244 - return 0; 245 - } 246 269 #endif /* CONFIG_NFS_V4_1 */ 247 270 248 271 /* ··· 328 359 mutex_unlock(&nfs_callback_mutex); 329 360 } 330 361 331 - static int check_gss_callback_principal(struct nfs_client *clp, 332 - struct svc_rqst *rqstp) 362 + /* Boolean check of RPC_AUTH_GSS principal */ 363 + int 364 + check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 333 365 { 334 366 struct rpc_clnt *r = clp->cl_rpcclient; 335 367 char *p = svc_gss_principal(rqstp); 336 368 369 + if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 370 + return 1; 371 + 337 372 /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ 338 373 if (clp->cl_minorversion != 0) 339 - return SVC_DROP; 374 + return 0; 340 375 /* 341 376 * It might just be a normal user principal, in which case 342 377 * userspace won't bother to tell us the name at all. 343 378 */ 344 379 if (p == NULL) 345 - return SVC_DENIED; 380 + return 0; 346 381 347 382 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ 348 383 349 384 if (memcmp(p, "nfs@", 4) != 0) 350 - return SVC_DENIED; 385 + return 0; 351 386 p += 4; 352 387 if (strcmp(p, r->cl_server) != 0) 353 - return SVC_DENIED; 354 - return SVC_OK; 388 + return 0; 389 + return 1; 355 390 } 356 391 357 - /* pg_authenticate method helper */ 358 - static struct nfs_client *nfs_cb_find_client(struct svc_rqst *rqstp) 359 - { 360 - struct nfs4_sessionid *sessionid = bc_xprt_sid(rqstp); 361 - int is_cb_compound = rqstp->rq_proc == CB_COMPOUND ? 1 : 0; 362 - 363 - dprintk("--> %s rq_proc %d\n", __func__, rqstp->rq_proc); 364 - if (svc_is_backchannel(rqstp)) 365 - /* Sessionid (usually) set after CB_NULL ping */ 366 - return nfs4_find_client_sessionid(svc_addr(rqstp), sessionid, 367 - is_cb_compound); 368 - else 369 - /* No callback identifier in pg_authenticate */ 370 - return nfs4_find_client_no_ident(svc_addr(rqstp)); 371 - } 372 - 373 - /* pg_authenticate method for nfsv4 callback threads. */ 392 + /* 393 + * pg_authenticate method for nfsv4 callback threads. 394 + * 395 + * The authflavor has been negotiated, so an incorrect flavor is a server 396 + * bug. Drop packets with incorrect authflavor. 397 + * 398 + * All other checking done after NFS decoding where the nfs_client can be 399 + * found in nfs4_callback_compound 400 + */ 374 401 static int nfs_callback_authenticate(struct svc_rqst *rqstp) 375 402 { 376 - struct nfs_client *clp; 377 - RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 378 - int ret = SVC_OK; 379 - 380 - /* Don't talk to strangers */ 381 - clp = nfs_cb_find_client(rqstp); 382 - if (clp == NULL) 383 - return SVC_DROP; 384 - 385 - dprintk("%s: %s NFSv4 callback!\n", __func__, 386 - svc_print_addr(rqstp, buf, sizeof(buf))); 387 - 388 403 switch (rqstp->rq_authop->flavour) { 389 - case RPC_AUTH_NULL: 390 - if (rqstp->rq_proc != CB_NULL) 391 - ret = SVC_DENIED; 392 - break; 393 - case RPC_AUTH_UNIX: 394 - break; 395 - case RPC_AUTH_GSS: 396 - ret = check_gss_callback_principal(clp, rqstp); 397 - break; 398 - default: 399 - ret = SVC_DENIED; 404 + case RPC_AUTH_NULL: 405 + if (rqstp->rq_proc != CB_NULL) 406 + return SVC_DROP; 407 + break; 408 + case RPC_AUTH_GSS: 409 + /* No RPC_AUTH_GSS support yet in NFSv4.1 */ 410 + if (svc_is_backchannel(rqstp)) 411 + return SVC_DROP; 400 412 } 401 - nfs_put_client(clp); 402 - return ret; 413 + return SVC_OK; 403 414 } 404 415 405 416 /*
+2 -2
fs/nfs/callback.h
··· 7 7 */ 8 8 #ifndef __LINUX_FS_NFS_CALLBACK_H 9 9 #define __LINUX_FS_NFS_CALLBACK_H 10 + #include <linux/sunrpc/svc.h> 10 11 11 12 #define NFS4_CALLBACK 0x40000000 12 13 #define NFS4_CALLBACK_XDRSIZE 2048 ··· 38 37 struct cb_process_state { 39 38 __be32 drc_status; 40 39 struct nfs_client *clp; 41 - struct nfs4_sessionid *svc_sid; /* v4.1 callback service sessionid */ 42 40 }; 43 41 44 42 struct cb_compound_hdr_arg { ··· 168 168 extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); 169 169 extern void nfs4_cb_take_slot(struct nfs_client *clp); 170 170 #endif /* CONFIG_NFS_V4_1 */ 171 - 171 + extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); 172 172 extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, 173 173 struct cb_getattrres *res, 174 174 struct cb_process_state *cps);
+3 -9
fs/nfs/callback_proc.c
··· 373 373 { 374 374 struct nfs_client *clp; 375 375 int i; 376 - __be32 status; 376 + __be32 status = htonl(NFS4ERR_BADSESSION); 377 377 378 378 cps->clp = NULL; 379 379 380 - status = htonl(NFS4ERR_BADSESSION); 381 - /* Incoming session must match the callback session */ 382 - if (memcmp(&args->csa_sessionid, cps->svc_sid, NFS4_MAX_SESSIONID_LEN)) 383 - goto out; 384 - 385 - clp = nfs4_find_client_sessionid(args->csa_addr, 386 - &args->csa_sessionid, 1); 380 + clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); 387 381 if (clp == NULL) 388 382 goto out; 389 383 ··· 408 414 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 409 415 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; 410 416 nfs4_cb_take_slot(clp); 411 - cps->clp = clp; /* put in nfs4_callback_compound */ 412 417 413 418 out: 419 + cps->clp = clp; /* put in nfs4_callback_compound */ 414 420 for (i = 0; i < args->csa_nrclists; i++) 415 421 kfree(args->csa_rclists[i].rcl_refcalls); 416 422 kfree(args->csa_rclists);
+2 -3
fs/nfs/callback_xdr.c
··· 794 794 795 795 if (hdr_arg.minorversion == 0) { 796 796 cps.clp = nfs4_find_client_ident(hdr_arg.cb_ident); 797 - if (!cps.clp) 797 + if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) 798 798 return rpc_drop_reply; 799 - } else 800 - cps.svc_sid = bc_xprt_sid(rqstp); 799 + } 801 800 802 801 hdr_res.taglen = hdr_arg.taglen; 803 802 hdr_res.tag = hdr_arg.tag;
+5 -10
fs/nfs/client.c
··· 1206 1206 * For CB_COMPOUND calls, find a client by IP address, protocol version, 1207 1207 * minorversion, and sessionID 1208 1208 * 1209 - * CREATE_SESSION triggers a CB_NULL ping from servers. The callback service 1210 - * sessionid can only be set after the CREATE_SESSION return, so a CB_NULL 1211 - * can arrive before the callback sessionid is set. For CB_NULL calls, 1212 - * find a client by IP address protocol version, and minorversion. 1213 - * 1214 1209 * Returns NULL if no such client 1215 1210 */ 1216 1211 struct nfs_client * 1217 1212 nfs4_find_client_sessionid(const struct sockaddr *addr, 1218 - struct nfs4_sessionid *sid, int is_cb_compound) 1213 + struct nfs4_sessionid *sid) 1219 1214 { 1220 1215 struct nfs_client *clp; 1221 1216 ··· 1222 1227 if (!nfs4_has_session(clp)) 1223 1228 continue; 1224 1229 1225 - /* Match sessionid unless cb_null call*/ 1226 - if (is_cb_compound && (memcmp(clp->cl_session->sess_id.data, 1227 - sid->data, NFS4_MAX_SESSIONID_LEN) != 0)) 1230 + /* Match sessionid*/ 1231 + if (memcmp(clp->cl_session->sess_id.data, 1232 + sid->data, NFS4_MAX_SESSIONID_LEN) != 0) 1228 1233 continue; 1229 1234 1230 1235 atomic_inc(&clp->cl_count); ··· 1239 1244 1240 1245 struct nfs_client * 1241 1246 nfs4_find_client_sessionid(const struct sockaddr *addr, 1242 - struct nfs4_sessionid *sid, int is_cb_compound) 1247 + struct nfs4_sessionid *sid) 1243 1248 { 1244 1249 return NULL; 1245 1250 }
+4 -2
fs/nfs/delegation.c
··· 23 23 24 24 static void nfs_do_free_delegation(struct nfs_delegation *delegation) 25 25 { 26 - if (delegation->cred) 27 - put_rpccred(delegation->cred); 28 26 kfree(delegation); 29 27 } 30 28 ··· 35 37 36 38 static void nfs_free_delegation(struct nfs_delegation *delegation) 37 39 { 40 + if (delegation->cred) { 41 + put_rpccred(delegation->cred); 42 + delegation->cred = NULL; 43 + } 38 44 call_rcu(&delegation->rcu, nfs_free_delegation_callback); 39 45 } 40 46
+20 -14
fs/nfs/direct.c
··· 407 407 pos += vec->iov_len; 408 408 } 409 409 410 + /* 411 + * If no bytes were started, return the error, and let the 412 + * generic layer handle the completion. 413 + */ 414 + if (requested_bytes == 0) { 415 + nfs_direct_req_release(dreq); 416 + return result < 0 ? result : -EIO; 417 + } 418 + 410 419 if (put_dreq(dreq)) 411 420 nfs_direct_complete(dreq); 412 - 413 - if (requested_bytes != 0) 414 - return 0; 415 - 416 - if (result < 0) 417 - return result; 418 - return -EIO; 421 + return 0; 419 422 } 420 423 421 424 static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, ··· 844 841 pos += vec->iov_len; 845 842 } 846 843 844 + /* 845 + * If no bytes were started, return the error, and let the 846 + * generic layer handle the completion. 847 + */ 848 + if (requested_bytes == 0) { 849 + nfs_direct_req_release(dreq); 850 + return result < 0 ? result : -EIO; 851 + } 852 + 847 853 if (put_dreq(dreq)) 848 854 nfs_direct_write_complete(dreq, dreq->inode); 849 - 850 - if (requested_bytes != 0) 851 - return 0; 852 - 853 - if (result < 0) 854 - return result; 855 - return -EIO; 855 + return 0; 856 856 } 857 857 858 858 static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
+17 -9
fs/nfs/inode.c
··· 881 881 return ret; 882 882 } 883 883 884 - static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) 884 + static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) 885 885 { 886 886 struct nfs_inode *nfsi = NFS_I(inode); 887 + unsigned long ret = 0; 887 888 888 889 if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) 889 890 && (fattr->valid & NFS_ATTR_FATTR_CHANGE) ··· 892 891 nfsi->change_attr = fattr->change_attr; 893 892 if (S_ISDIR(inode->i_mode)) 894 893 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 894 + ret |= NFS_INO_INVALID_ATTR; 895 895 } 896 896 /* If we have atomic WCC data, we may update some attributes */ 897 897 if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME) 898 898 && (fattr->valid & NFS_ATTR_FATTR_CTIME) 899 - && timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) 900 - memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 899 + && timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) { 900 + memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 901 + ret |= NFS_INO_INVALID_ATTR; 902 + } 901 903 902 904 if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME) 903 905 && (fattr->valid & NFS_ATTR_FATTR_MTIME) 904 906 && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { 905 - memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 906 - if (S_ISDIR(inode->i_mode)) 907 - nfsi->cache_validity |= NFS_INO_INVALID_DATA; 907 + memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 908 + if (S_ISDIR(inode->i_mode)) 909 + nfsi->cache_validity |= NFS_INO_INVALID_DATA; 910 + ret |= NFS_INO_INVALID_ATTR; 908 911 } 909 912 if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) 910 913 && (fattr->valid & NFS_ATTR_FATTR_SIZE) 911 914 && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) 912 - && nfsi->npages == 0) 913 - i_size_write(inode, nfs_size_to_loff_t(fattr->size)); 915 + && nfsi->npages == 0) { 916 + i_size_write(inode, nfs_size_to_loff_t(fattr->size)); 917 + ret |= NFS_INO_INVALID_ATTR; 918 + } 919 + return ret; 914 920 } 915 921 916 922 /** ··· 1231 1223 | NFS_INO_REVAL_PAGECACHE); 1232 1224 1233 1225 /* Do atomic weak cache consistency updates */ 1234 - nfs_wcc_update_inode(inode, fattr); 1226 + invalid |= nfs_wcc_update_inode(inode, fattr); 1235 1227 1236 1228 /* More cache consistency checks */ 1237 1229 if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
+1 -2
fs/nfs/internal.h
··· 133 133 extern struct nfs_client *nfs4_find_client_no_ident(const struct sockaddr *); 134 134 extern struct nfs_client *nfs4_find_client_ident(int); 135 135 extern struct nfs_client * 136 - nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *, 137 - int); 136 + nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *); 138 137 extern struct nfs_server *nfs_create_server( 139 138 const struct nfs_parsed_mount_data *, 140 139 struct nfs_fh *);
+2 -2
fs/nfs/nfs3acl.c
··· 311 311 if (!nfs_server_capable(inode, NFS_CAP_ACLS)) 312 312 goto out; 313 313 314 - /* We are doing this here, because XDR marshalling can only 315 - return -ENOMEM. */ 314 + /* We are doing this here because XDR marshalling does not 315 + * return any results, it BUGs. */ 316 316 status = -ENOSPC; 317 317 if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES) 318 318 goto out;
+5 -2
fs/nfs/nfs3xdr.c
··· 1328 1328 1329 1329 encode_nfs_fh3(xdr, NFS_FH(args->inode)); 1330 1330 encode_uint32(xdr, args->mask); 1331 - if (args->npages != 0) 1332 - xdr_write_pages(xdr, args->pages, 0, args->len); 1333 1331 1334 1332 base = req->rq_slen; 1333 + if (args->npages != 0) 1334 + xdr_write_pages(xdr, args->pages, 0, args->len); 1335 + else 1336 + xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE); 1337 + 1335 1338 error = nfsacl_encode(xdr->buf, base, args->inode, 1336 1339 (args->mask & NFS_ACL) ? 1337 1340 args->acl_access : NULL, 1, 0);
+7 -2
fs/nfs/nfs4filelayoutdev.c
··· 214 214 215 215 /* ipv6 length plus port is legal */ 216 216 if (rlen > INET6_ADDRSTRLEN + 8) { 217 - dprintk("%s Invalid address, length %d\n", __func__, 217 + dprintk("%s: Invalid address, length %d\n", __func__, 218 218 rlen); 219 219 goto out_err; 220 220 } ··· 225 225 /* replace the port dots with dashes for the in4_pton() delimiter*/ 226 226 for (i = 0; i < 2; i++) { 227 227 char *res = strrchr(buf, '.'); 228 + if (!res) { 229 + dprintk("%s: Failed finding expected dots in port\n", 230 + __func__); 231 + goto out_free; 232 + } 228 233 *res = '-'; 229 234 } 230 235 ··· 245 240 port = htons((tmp[0] << 8) | (tmp[1])); 246 241 247 242 ds = nfs4_pnfs_ds_add(inode, ip_addr, port); 248 - dprintk("%s Decoded address and port %s\n", __func__, buf); 243 + dprintk("%s: Decoded address and port %s\n", __func__, buf); 249 244 out_free: 250 245 kfree(buf); 251 246 out_err:
+10 -20
fs/nfs/nfs4proc.c
··· 50 50 #include <linux/module.h> 51 51 #include <linux/sunrpc/bc_xprt.h> 52 52 #include <linux/xattr.h> 53 + #include <linux/utsname.h> 53 54 54 55 #include "nfs4_fs.h" 55 56 #include "delegation.h" ··· 4573 4572 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4574 4573 args.verifier = &verifier; 4575 4574 4576 - while (1) { 4577 - args.id_len = scnprintf(args.id, sizeof(args.id), 4578 - "%s/%s %u", 4579 - clp->cl_ipaddr, 4580 - rpc_peeraddr2str(clp->cl_rpcclient, 4581 - RPC_DISPLAY_ADDR), 4582 - clp->cl_id_uniquifier); 4575 + args.id_len = scnprintf(args.id, sizeof(args.id), 4576 + "%s/%s.%s/%u", 4577 + clp->cl_ipaddr, 4578 + init_utsname()->nodename, 4579 + init_utsname()->domainname, 4580 + clp->cl_rpcclient->cl_auth->au_flavor); 4583 4581 4584 - status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 4585 - 4586 - if (status != -NFS4ERR_CLID_INUSE) 4587 - break; 4588 - 4589 - if (signalled()) 4590 - break; 4591 - 4592 - if (++clp->cl_id_uniquifier == 0) 4593 - break; 4594 - } 4595 - 4596 - status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 4582 + status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 4583 + if (!status) 4584 + status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 4597 4585 dprintk("<-- %s status= %d\n", __func__, status); 4598 4586 return status; 4599 4587 }
-6
fs/nfs/nfs4state.c
··· 232 232 status = nfs4_proc_create_session(clp); 233 233 if (status != 0) 234 234 goto out; 235 - status = nfs4_set_callback_sessionid(clp); 236 - if (status != 0) { 237 - printk(KERN_WARNING "Sessionid not set. No callback service\n"); 238 - nfs_callback_down(1); 239 - status = 0; 240 - } 241 235 nfs41_setup_state_renewal(clp); 242 236 nfs_mark_client_ready(clp, NFS_CS_READY); 243 237 out:
+3 -6
fs/nfs/nfs4xdr.c
··· 6086 6086 __be32 *p = xdr_inline_decode(xdr, 4); 6087 6087 if (unlikely(!p)) 6088 6088 goto out_overflow; 6089 - if (!ntohl(*p++)) { 6089 + if (*p == xdr_zero) { 6090 6090 p = xdr_inline_decode(xdr, 4); 6091 6091 if (unlikely(!p)) 6092 6092 goto out_overflow; 6093 - if (!ntohl(*p++)) 6093 + if (*p == xdr_zero) 6094 6094 return -EAGAIN; 6095 6095 entry->eof = 1; 6096 6096 return -EBADCOOKIE; ··· 6101 6101 goto out_overflow; 6102 6102 entry->prev_cookie = entry->cookie; 6103 6103 p = xdr_decode_hyper(p, &entry->cookie); 6104 - entry->len = ntohl(*p++); 6104 + entry->len = be32_to_cpup(p); 6105 6105 6106 6106 p = xdr_inline_decode(xdr, entry->len); 6107 6107 if (unlikely(!p)) ··· 6131 6131 entry->d_type = DT_UNKNOWN; 6132 6132 if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE) 6133 6133 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); 6134 - 6135 - if (verify_attr_len(xdr, p, len) < 0) 6136 - goto out_overflow; 6137 6134 6138 6135 return 0; 6139 6136
+1 -1
fs/nfs/pnfs.c
··· 951 951 { 952 952 struct pnfs_deviceid_cache *local = clp->cl_devid_cache; 953 953 954 - dprintk("--> %s cl_devid_cache %p\n", __func__, clp->cl_devid_cache); 954 + dprintk("--> %s ({%d})\n", __func__, atomic_read(&local->dc_ref)); 955 955 if (atomic_dec_and_lock(&local->dc_ref, &clp->cl_lock)) { 956 956 int i; 957 957 /* Verify cache is empty */
+1 -1
fs/nfs/write.c
··· 932 932 while (!list_empty(&list)) { 933 933 data = list_entry(list.next, struct nfs_write_data, pages); 934 934 list_del(&data->pages); 935 - nfs_writedata_release(data); 935 + nfs_writedata_free(data); 936 936 } 937 937 nfs_redirty_request(req); 938 938 return -ENOMEM;
+41 -13
fs/nfs_common/nfsacl.c
··· 42 42 gid_t gid; 43 43 }; 44 44 45 + struct nfsacl_simple_acl { 46 + struct posix_acl acl; 47 + struct posix_acl_entry ace[4]; 48 + }; 49 + 45 50 static int 46 51 xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) 47 52 { ··· 77 72 return 0; 78 73 } 79 74 80 - unsigned int 81 - nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, 82 - struct posix_acl *acl, int encode_entries, int typeflag) 75 + /** 76 + * nfsacl_encode - Encode an NFSv3 ACL 77 + * 78 + * @buf: destination xdr_buf to contain XDR encoded ACL 79 + * @base: byte offset in xdr_buf where XDR'd ACL begins 80 + * @inode: inode of file whose ACL this is 81 + * @acl: posix_acl to encode 82 + * @encode_entries: whether to encode ACEs as well 83 + * @typeflag: ACL type: NFS_ACL_DEFAULT or zero 84 + * 85 + * Returns size of encoded ACL in bytes or a negative errno value. 86 + */ 87 + int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, 88 + struct posix_acl *acl, int encode_entries, int typeflag) 83 89 { 84 90 int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0; 85 91 struct nfsacl_encode_desc nfsacl_desc = { ··· 104 88 .uid = inode->i_uid, 105 89 .gid = inode->i_gid, 106 90 }; 91 + struct nfsacl_simple_acl aclbuf; 107 92 int err; 108 - struct posix_acl *acl2 = NULL; 109 93 110 94 if (entries > NFS_ACL_MAX_ENTRIES || 111 95 xdr_encode_word(buf, base, entries)) 112 96 return -EINVAL; 113 97 if (encode_entries && acl && acl->a_count == 3) { 114 - /* Fake up an ACL_MASK entry. */ 115 - acl2 = posix_acl_alloc(4, GFP_KERNEL); 116 - if (!acl2) 117 - return -ENOMEM; 98 + struct posix_acl *acl2 = &aclbuf.acl; 99 + 100 + /* Avoid the use of posix_acl_alloc(). nfsacl_encode() is 101 + * invoked in contexts where a memory allocation failure is 102 + * fatal. Fortunately this fake ACL is small enough to 103 + * construct on the stack. */ 104 + memset(acl2, 0, sizeof(acl2)); 105 + posix_acl_init(acl2, 4); 106 + 118 107 /* Insert entries in canonical order: other orders seem 119 108 to confuse Solaris VxFS. */ 120 109 acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */ ··· 130 109 nfsacl_desc.acl = acl2; 131 110 } 132 111 err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc); 133 - if (acl2) 134 - posix_acl_release(acl2); 135 112 if (!err) 136 113 err = 8 + nfsacl_desc.desc.elem_size * 137 114 nfsacl_desc.desc.array_len; ··· 243 224 return 0; 244 225 } 245 226 246 - unsigned int 247 - nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, 248 - struct posix_acl **pacl) 227 + /** 228 + * nfsacl_decode - Decode an NFSv3 ACL 229 + * 230 + * @buf: xdr_buf containing XDR'd ACL data to decode 231 + * @base: byte offset in xdr_buf where XDR'd ACL begins 232 + * @aclcnt: count of ACEs in decoded posix_acl 233 + * @pacl: buffer in which to place decoded posix_acl 234 + * 235 + * Returns the length of the decoded ACL in bytes, or a negative errno value. 236 + */ 237 + int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, 238 + struct posix_acl **pacl) 249 239 { 250 240 struct nfsacl_decode_desc nfsacl_desc = { 251 241 .desc = {
+13 -4
fs/posix_acl.c
··· 22 22 23 23 #include <linux/errno.h> 24 24 25 + EXPORT_SYMBOL(posix_acl_init); 25 26 EXPORT_SYMBOL(posix_acl_alloc); 26 27 EXPORT_SYMBOL(posix_acl_clone); 27 28 EXPORT_SYMBOL(posix_acl_valid); ··· 33 32 EXPORT_SYMBOL(posix_acl_permission); 34 33 35 34 /* 35 + * Init a fresh posix_acl 36 + */ 37 + void 38 + posix_acl_init(struct posix_acl *acl, int count) 39 + { 40 + atomic_set(&acl->a_refcount, 1); 41 + acl->a_count = count; 42 + } 43 + 44 + /* 36 45 * Allocate a new ACL with the specified number of entries. 37 46 */ 38 47 struct posix_acl * ··· 51 40 const size_t size = sizeof(struct posix_acl) + 52 41 count * sizeof(struct posix_acl_entry); 53 42 struct posix_acl *acl = kmalloc(size, flags); 54 - if (acl) { 55 - atomic_set(&acl->a_refcount, 1); 56 - acl->a_count = count; 57 - } 43 + if (acl) 44 + posix_acl_init(acl, count); 58 45 return acl; 59 46 } 60 47
+2 -2
include/linux/nfsacl.h
··· 51 51 return w; 52 52 } 53 53 54 - extern unsigned int 54 + extern int 55 55 nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, 56 56 struct posix_acl *acl, int encode_entries, int typeflag); 57 - extern unsigned int 57 + extern int 58 58 nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, 59 59 struct posix_acl **pacl); 60 60
+1
include/linux/posix_acl.h
··· 71 71 72 72 /* posix_acl.c */ 73 73 74 + extern void posix_acl_init(struct posix_acl *, int); 74 75 extern struct posix_acl *posix_acl_alloc(int, gfp_t); 75 76 extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t); 76 77 extern int posix_acl_valid(const struct posix_acl *);
-13
include/linux/sunrpc/bc_xprt.h
··· 47 47 return 1; 48 48 return 0; 49 49 } 50 - static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp) 51 - { 52 - if (svc_is_backchannel(rqstp)) 53 - return (struct nfs4_sessionid *) 54 - rqstp->rq_server->sv_bc_xprt->xpt_bc_sid; 55 - return NULL; 56 - } 57 - 58 50 #else /* CONFIG_NFS_V4_1 */ 59 51 static inline int xprt_setup_backchannel(struct rpc_xprt *xprt, 60 52 unsigned int min_reqs) ··· 57 65 static inline int svc_is_backchannel(const struct svc_rqst *rqstp) 58 66 { 59 67 return 0; 60 - } 61 - 62 - static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp) 63 - { 64 - return NULL; 65 68 } 66 69 67 70 static inline void xprt_free_bc_request(struct rpc_rqst *req)
-1
include/linux/sunrpc/svc_xprt.h
··· 77 77 size_t xpt_remotelen; /* length of address */ 78 78 struct rpc_wait_queue xpt_bc_pending; /* backchannel wait queue */ 79 79 struct list_head xpt_users; /* callbacks on free */ 80 - void *xpt_bc_sid; /* back channel session ID */ 81 80 82 81 struct net *xpt_net; 83 82 struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */
+1 -3
net/sunrpc/svcsock.c
··· 1609 1609 */ 1610 1610 static void svc_bc_sock_free(struct svc_xprt *xprt) 1611 1611 { 1612 - if (xprt) { 1613 - kfree(xprt->xpt_bc_sid); 1612 + if (xprt) 1614 1613 kfree(container_of(xprt, struct svc_sock, sk_xprt)); 1615 - } 1616 1614 } 1617 1615 #endif /* CONFIG_NFS_V4_1 */