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

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: don't try to decode GETATTR if DELEGRETURN returned error
sunrpc: handle allocation errors from __rpc_lookup_create()
SUNRPC: Fix the return value of rpc_run_bc_task()
SUNRPC: Fix a use after free bug with the NFSv4.1 backchannel
SUNRPC: Fix a potential memory leak in auth_gss
NFS: Prevent another deadlock in nfs_release_page()

+22 -36
+2 -1
fs/nfs/file.c
··· 491 491 { 492 492 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 493 493 494 - if (gfp & __GFP_WAIT) 494 + /* Only do I/O if gfp is a superset of GFP_KERNEL */ 495 + if ((gfp & GFP_KERNEL) == GFP_KERNEL) 495 496 nfs_wb_page(page->mapping->host, page); 496 497 /* If PagePrivate() is set, then the page is not freeable */ 497 498 if (PagePrivate(page))
+2
fs/nfs/nfs4xdr.c
··· 5552 5552 if (status != 0) 5553 5553 goto out; 5554 5554 status = decode_delegreturn(&xdr); 5555 + if (status != 0) 5556 + goto out; 5555 5557 decode_getfattr(&xdr, res->fattr, res->server, 5556 5558 !RPC_IS_ASYNC(rqstp->rq_task)); 5557 5559 out:
+4 -1
include/linux/sunrpc/bc_xprt.h
··· 36 36 void xprt_free_bc_request(struct rpc_rqst *req); 37 37 int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); 38 38 void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs); 39 - void bc_release_request(struct rpc_task *); 40 39 int bc_send(struct rpc_rqst *req); 41 40 42 41 /* ··· 57 58 static inline int svc_is_backchannel(const struct svc_rqst *rqstp) 58 59 { 59 60 return 0; 61 + } 62 + 63 + static inline void xprt_free_bc_request(struct rpc_rqst *req) 64 + { 60 65 } 61 66 #endif /* CONFIG_NFS_V4_1 */ 62 67 #endif /* _LINUX_SUNRPC_BC_XPRT_H */
+2 -3
net/sunrpc/auth_gss/auth_gss.c
··· 1280 1280 rqstp->rq_release_snd_buf = priv_release_snd_buf; 1281 1281 return 0; 1282 1282 out_free: 1283 - for (i--; i >= 0; i--) { 1284 - __free_page(rqstp->rq_enc_pages[i]); 1285 - } 1283 + rqstp->rq_enc_pages_num = i; 1284 + priv_release_snd_buf(rqstp); 1286 1285 out: 1287 1286 return -EAGAIN; 1288 1287 }
-15
net/sunrpc/bc_svc.c
··· 37 37 38 38 #define RPCDBG_FACILITY RPCDBG_SVCDSP 39 39 40 - void bc_release_request(struct rpc_task *task) 41 - { 42 - struct rpc_rqst *req = task->tk_rqstp; 43 - 44 - dprintk("RPC: bc_release_request: task= %p\n", task); 45 - 46 - /* 47 - * Release this request only if it's a backchannel 48 - * preallocated request 49 - */ 50 - if (!bc_prealloc(req)) 51 - return; 52 - xprt_free_bc_request(req); 53 - } 54 - 55 40 /* Empty callback ops */ 56 41 static const struct rpc_call_ops nfs41_callback_ops = { 57 42 };
+1
net/sunrpc/clnt.c
··· 659 659 task = rpc_new_task(&task_setup_data); 660 660 if (!task) { 661 661 xprt_free_bc_request(req); 662 + task = ERR_PTR(-ENOMEM); 662 663 goto out; 663 664 } 664 665 task->tk_rqstp = req;
+2
net/sunrpc/rpc_pipe.c
··· 587 587 struct dentry *dentry; 588 588 589 589 dentry = __rpc_lookup_create(parent, name); 590 + if (IS_ERR(dentry)) 591 + return dentry; 590 592 if (dentry->d_inode == NULL) 591 593 return dentry; 592 594 dput(dentry);
+9 -13
net/sunrpc/xprt.c
··· 46 46 47 47 #include <linux/sunrpc/clnt.h> 48 48 #include <linux/sunrpc/metrics.h> 49 + #include <linux/sunrpc/bc_xprt.h> 49 50 50 51 #include "sunrpc.h" 51 52 ··· 1033 1032 if (req->rq_release_snd_buf) 1034 1033 req->rq_release_snd_buf(req); 1035 1034 1036 - /* 1037 - * Early exit if this is a backchannel preallocated request. 1038 - * There is no need to have it added to the RPC slot list. 1039 - */ 1040 - if (is_bc_request) 1041 - return; 1042 - 1043 - memset(req, 0, sizeof(*req)); /* mark unused */ 1044 - 1045 1035 dprintk("RPC: %5u release request %p\n", task->tk_pid, req); 1036 + if (likely(!is_bc_request)) { 1037 + memset(req, 0, sizeof(*req)); /* mark unused */ 1046 1038 1047 - spin_lock(&xprt->reserve_lock); 1048 - list_add(&req->rq_list, &xprt->free); 1049 - rpc_wake_up_next(&xprt->backlog); 1050 - spin_unlock(&xprt->reserve_lock); 1039 + spin_lock(&xprt->reserve_lock); 1040 + list_add(&req->rq_list, &xprt->free); 1041 + rpc_wake_up_next(&xprt->backlog); 1042 + spin_unlock(&xprt->reserve_lock); 1043 + } else 1044 + xprt_free_bc_request(req); 1051 1045 } 1052 1046 1053 1047 /**
-3
net/sunrpc/xprtsock.c
··· 2251 2251 .buf_free = rpc_free, 2252 2252 .send_request = xs_tcp_send_request, 2253 2253 .set_retrans_timeout = xprt_set_retrans_timeout_def, 2254 - #if defined(CONFIG_NFS_V4_1) 2255 - .release_request = bc_release_request, 2256 - #endif /* CONFIG_NFS_V4_1 */ 2257 2254 .close = xs_tcp_close, 2258 2255 .destroy = xs_destroy, 2259 2256 .print_stats = xs_tcp_print_stats,