diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-15 17:15:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-15 17:15:16 -0500 |
commit | 1afcb6ed0d34c5794a51fe325076f006c8babaf4 (patch) | |
tree | a39a9b36d96dca051c0506cfde57269a1cd1a31c /fs/nfs/blocklayout/rpc_pipefs.c | |
parent | 56c381f93d57b88a3e667a2f55137947315c17e2 (diff) | |
parent | b3ecba096729f521312d1863ad22530695527aed (diff) |
Merge tag 'nfs-for-3.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:
- stable patches to fix NFSv4.x delegation reclaim error paths
- fix a bug whereby we were advertising NFSv4.1 but using NFSv4.2
features
- fix a use-after-free problem with pNFS block layouts
- fix a memory leak in the pNFS files O_DIRECT code
- replace an intrusive and Oops-prone performance fix in the NFSv4
atomic open code with a safer one-line version and revert the two
original patches"
* tag 'nfs-for-3.18-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
sunrpc: fix sleeping under rcu_read_lock in gss_stringify_acceptor
NFS: Don't try to reclaim delegation open state if recovery failed
NFSv4: Ensure that we call FREE_STATEID when NFSv4.x stateids are revoked
NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return
NFSv4.1: nfs41_clear_delegation_stateid shouldn't trust NFS_DELEGATED_STATE
NFSv4: Ensure that we remove NFSv4.0 delegations when state has expired
NFS: SEEK is an NFS v4.2 feature
nfs: Fix use of uninitialized variable in nfs_getattr()
nfs: Remove bogus assignment
nfs: remove spurious WARN_ON_ONCE in write path
pnfs/blocklayout: serialize GETDEVICEINFO calls
nfs: fix pnfs direct write memory leak
Revert "NFS: nfs4_do_open should add negative results to the dcache."
Revert "NFS: remove BUG possibility in nfs4_open_and_get_state"
NFSv4: Ensure nfs_atomic_open set the dentry verifier on ENOENT
Diffstat (limited to 'fs/nfs/blocklayout/rpc_pipefs.c')
-rw-r--r-- | fs/nfs/blocklayout/rpc_pipefs.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/nfs/blocklayout/rpc_pipefs.c b/fs/nfs/blocklayout/rpc_pipefs.c index e966c023b1b7..acbf9ca4018c 100644 --- a/fs/nfs/blocklayout/rpc_pipefs.c +++ b/fs/nfs/blocklayout/rpc_pipefs.c | |||
@@ -65,17 +65,18 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b, | |||
65 | 65 | ||
66 | dprintk("%s CREATING PIPEFS MESSAGE\n", __func__); | 66 | dprintk("%s CREATING PIPEFS MESSAGE\n", __func__); |
67 | 67 | ||
68 | mutex_lock(&nn->bl_mutex); | ||
68 | bl_pipe_msg.bl_wq = &nn->bl_wq; | 69 | bl_pipe_msg.bl_wq = &nn->bl_wq; |
69 | 70 | ||
70 | b->simple.len += 4; /* single volume */ | 71 | b->simple.len += 4; /* single volume */ |
71 | if (b->simple.len > PAGE_SIZE) | 72 | if (b->simple.len > PAGE_SIZE) |
72 | return -EIO; | 73 | goto out_unlock; |
73 | 74 | ||
74 | memset(msg, 0, sizeof(*msg)); | 75 | memset(msg, 0, sizeof(*msg)); |
75 | msg->len = sizeof(*bl_msg) + b->simple.len; | 76 | msg->len = sizeof(*bl_msg) + b->simple.len; |
76 | msg->data = kzalloc(msg->len, gfp_mask); | 77 | msg->data = kzalloc(msg->len, gfp_mask); |
77 | if (!msg->data) | 78 | if (!msg->data) |
78 | goto out; | 79 | goto out_free_data; |
79 | 80 | ||
80 | bl_msg = msg->data; | 81 | bl_msg = msg->data; |
81 | bl_msg->type = BL_DEVICE_MOUNT, | 82 | bl_msg->type = BL_DEVICE_MOUNT, |
@@ -87,7 +88,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b, | |||
87 | rc = rpc_queue_upcall(nn->bl_device_pipe, msg); | 88 | rc = rpc_queue_upcall(nn->bl_device_pipe, msg); |
88 | if (rc < 0) { | 89 | if (rc < 0) { |
89 | remove_wait_queue(&nn->bl_wq, &wq); | 90 | remove_wait_queue(&nn->bl_wq, &wq); |
90 | goto out; | 91 | goto out_free_data; |
91 | } | 92 | } |
92 | 93 | ||
93 | set_current_state(TASK_UNINTERRUPTIBLE); | 94 | set_current_state(TASK_UNINTERRUPTIBLE); |
@@ -97,12 +98,14 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b, | |||
97 | if (reply->status != BL_DEVICE_REQUEST_PROC) { | 98 | if (reply->status != BL_DEVICE_REQUEST_PROC) { |
98 | printk(KERN_WARNING "%s failed to decode device: %d\n", | 99 | printk(KERN_WARNING "%s failed to decode device: %d\n", |
99 | __func__, reply->status); | 100 | __func__, reply->status); |
100 | goto out; | 101 | goto out_free_data; |
101 | } | 102 | } |
102 | 103 | ||
103 | dev = MKDEV(reply->major, reply->minor); | 104 | dev = MKDEV(reply->major, reply->minor); |
104 | out: | 105 | out_free_data: |
105 | kfree(msg->data); | 106 | kfree(msg->data); |
107 | out_unlock: | ||
108 | mutex_unlock(&nn->bl_mutex); | ||
106 | return dev; | 109 | return dev; |
107 | } | 110 | } |
108 | 111 | ||
@@ -232,6 +235,7 @@ static int nfs4blocklayout_net_init(struct net *net) | |||
232 | struct nfs_net *nn = net_generic(net, nfs_net_id); | 235 | struct nfs_net *nn = net_generic(net, nfs_net_id); |
233 | struct dentry *dentry; | 236 | struct dentry *dentry; |
234 | 237 | ||
238 | mutex_init(&nn->bl_mutex); | ||
235 | init_waitqueue_head(&nn->bl_wq); | 239 | init_waitqueue_head(&nn->bl_wq); |
236 | nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0); | 240 | nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0); |
237 | if (IS_ERR(nn->bl_device_pipe)) | 241 | if (IS_ERR(nn->bl_device_pipe)) |