diff options
| -rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 2 | ||||
| -rw-r--r-- | fs/nfs/blocklayout/rpc_pipefs.c | 14 | ||||
| -rw-r--r-- | fs/nfs/delegation.c | 25 | ||||
| -rw-r--r-- | fs/nfs/delegation.h | 1 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 1 | ||||
| -rw-r--r-- | fs/nfs/direct.c | 1 | ||||
| -rw-r--r-- | fs/nfs/filelayout/filelayout.c | 3 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 2 | ||||
| -rw-r--r-- | fs/nfs/netns.h | 1 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 95 | ||||
| -rw-r--r-- | fs/nfs/write.c | 2 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 11 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 35 |
13 files changed, 124 insertions, 69 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 5228f201d3d5..4f46f7a05289 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c | |||
| @@ -378,7 +378,7 @@ bl_write_pagelist(struct nfs_pgio_header *header, int sync) | |||
| 378 | loff_t offset = header->args.offset; | 378 | loff_t offset = header->args.offset; |
| 379 | size_t count = header->args.count; | 379 | size_t count = header->args.count; |
| 380 | struct page **pages = header->args.pages; | 380 | struct page **pages = header->args.pages; |
| 381 | int pg_index = pg_index = header->args.pgbase >> PAGE_CACHE_SHIFT; | 381 | int pg_index = header->args.pgbase >> PAGE_CACHE_SHIFT; |
| 382 | unsigned int pg_len; | 382 | unsigned int pg_len; |
| 383 | struct blk_plug plug; | 383 | struct blk_plug plug; |
| 384 | int i; | 384 | int i; |
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)) |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 5853f53db732..7f3f60641344 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
| @@ -125,6 +125,8 @@ again: | |||
| 125 | continue; | 125 | continue; |
| 126 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) | 126 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) |
| 127 | continue; | 127 | continue; |
| 128 | if (!nfs4_valid_open_stateid(state)) | ||
| 129 | continue; | ||
| 128 | if (!nfs4_stateid_match(&state->stateid, stateid)) | 130 | if (!nfs4_stateid_match(&state->stateid, stateid)) |
| 129 | continue; | 131 | continue; |
| 130 | get_nfs_open_context(ctx); | 132 | get_nfs_open_context(ctx); |
| @@ -193,7 +195,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * | |||
| 193 | { | 195 | { |
| 194 | int res = 0; | 196 | int res = 0; |
| 195 | 197 | ||
| 196 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync); | 198 | if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) |
| 199 | res = nfs4_proc_delegreturn(inode, | ||
| 200 | delegation->cred, | ||
| 201 | &delegation->stateid, | ||
| 202 | issync); | ||
| 197 | nfs_free_delegation(delegation); | 203 | nfs_free_delegation(delegation); |
| 198 | return res; | 204 | return res; |
| 199 | } | 205 | } |
| @@ -380,11 +386,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation | |||
| 380 | { | 386 | { |
| 381 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | 387 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 382 | struct nfs_inode *nfsi = NFS_I(inode); | 388 | struct nfs_inode *nfsi = NFS_I(inode); |
| 383 | int err; | 389 | int err = 0; |
| 384 | 390 | ||
| 385 | if (delegation == NULL) | 391 | if (delegation == NULL) |
| 386 | return 0; | 392 | return 0; |
| 387 | do { | 393 | do { |
| 394 | if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) | ||
| 395 | break; | ||
| 388 | err = nfs_delegation_claim_opens(inode, &delegation->stateid); | 396 | err = nfs_delegation_claim_opens(inode, &delegation->stateid); |
| 389 | if (!issync || err != -EAGAIN) | 397 | if (!issync || err != -EAGAIN) |
| 390 | break; | 398 | break; |
| @@ -605,10 +613,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl | |||
| 605 | rcu_read_unlock(); | 613 | rcu_read_unlock(); |
| 606 | } | 614 | } |
| 607 | 615 | ||
| 616 | static void nfs_revoke_delegation(struct inode *inode) | ||
| 617 | { | ||
| 618 | struct nfs_delegation *delegation; | ||
| 619 | rcu_read_lock(); | ||
| 620 | delegation = rcu_dereference(NFS_I(inode)->delegation); | ||
| 621 | if (delegation != NULL) { | ||
| 622 | set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); | ||
| 623 | nfs_mark_return_delegation(NFS_SERVER(inode), delegation); | ||
| 624 | } | ||
| 625 | rcu_read_unlock(); | ||
| 626 | } | ||
| 627 | |||
| 608 | void nfs_remove_bad_delegation(struct inode *inode) | 628 | void nfs_remove_bad_delegation(struct inode *inode) |
| 609 | { | 629 | { |
| 610 | struct nfs_delegation *delegation; | 630 | struct nfs_delegation *delegation; |
| 611 | 631 | ||
| 632 | nfs_revoke_delegation(inode); | ||
| 612 | delegation = nfs_inode_detach_delegation(inode); | 633 | delegation = nfs_inode_detach_delegation(inode); |
| 613 | if (delegation) { | 634 | if (delegation) { |
| 614 | nfs_inode_find_state_and_recover(inode, &delegation->stateid); | 635 | nfs_inode_find_state_and_recover(inode, &delegation->stateid); |
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 5c1cce39297f..e3c20a3ccc93 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
| @@ -31,6 +31,7 @@ enum { | |||
| 31 | NFS_DELEGATION_RETURN_IF_CLOSED, | 31 | NFS_DELEGATION_RETURN_IF_CLOSED, |
| 32 | NFS_DELEGATION_REFERENCED, | 32 | NFS_DELEGATION_REFERENCED, |
| 33 | NFS_DELEGATION_RETURNING, | 33 | NFS_DELEGATION_RETURNING, |
| 34 | NFS_DELEGATION_REVOKED, | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); | 37 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 06e8cfcbb670..6e62155abf26 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1527,6 +1527,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
| 1527 | case -ENOENT: | 1527 | case -ENOENT: |
| 1528 | d_drop(dentry); | 1528 | d_drop(dentry); |
| 1529 | d_add(dentry, NULL); | 1529 | d_add(dentry, NULL); |
| 1530 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | ||
| 1530 | break; | 1531 | break; |
| 1531 | case -EISDIR: | 1532 | case -EISDIR: |
| 1532 | case -ENOTDIR: | 1533 | case -ENOTDIR: |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 20cffc830468..10bf07280f4a 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -266,6 +266,7 @@ static void nfs_direct_req_free(struct kref *kref) | |||
| 266 | { | 266 | { |
| 267 | struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref); | 267 | struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref); |
| 268 | 268 | ||
| 269 | nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo); | ||
| 269 | if (dreq->l_ctx != NULL) | 270 | if (dreq->l_ctx != NULL) |
| 270 | nfs_put_lock_context(dreq->l_ctx); | 271 | nfs_put_lock_context(dreq->l_ctx); |
| 271 | if (dreq->ctx != NULL) | 272 | if (dreq->ctx != NULL) |
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 46fab1cb455a..7afb52f6a25a 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c | |||
| @@ -145,9 +145,6 @@ static int filelayout_async_handle_error(struct rpc_task *task, | |||
| 145 | case -NFS4ERR_DELEG_REVOKED: | 145 | case -NFS4ERR_DELEG_REVOKED: |
| 146 | case -NFS4ERR_ADMIN_REVOKED: | 146 | case -NFS4ERR_ADMIN_REVOKED: |
| 147 | case -NFS4ERR_BAD_STATEID: | 147 | case -NFS4ERR_BAD_STATEID: |
| 148 | if (state == NULL) | ||
| 149 | break; | ||
| 150 | nfs_remove_bad_delegation(state->inode); | ||
| 151 | case -NFS4ERR_OPENMODE: | 148 | case -NFS4ERR_OPENMODE: |
| 152 | if (state == NULL) | 149 | if (state == NULL) |
| 153 | break; | 150 | break; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6388a59f2add..00689a8a85e4 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -626,7 +626,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
| 626 | { | 626 | { |
| 627 | struct inode *inode = dentry->d_inode; | 627 | struct inode *inode = dentry->d_inode; |
| 628 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; | 628 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
| 629 | int err; | 629 | int err = 0; |
| 630 | 630 | ||
| 631 | trace_nfs_getattr_enter(inode); | 631 | trace_nfs_getattr_enter(inode); |
| 632 | /* Flush out writes to the server in order to update c/mtime. */ | 632 | /* Flush out writes to the server in order to update c/mtime. */ |
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h index ef221fb8a183..f0e06e4acbef 100644 --- a/fs/nfs/netns.h +++ b/fs/nfs/netns.h | |||
| @@ -19,6 +19,7 @@ struct nfs_net { | |||
| 19 | struct rpc_pipe *bl_device_pipe; | 19 | struct rpc_pipe *bl_device_pipe; |
| 20 | struct bl_dev_msg bl_mount_reply; | 20 | struct bl_dev_msg bl_mount_reply; |
| 21 | wait_queue_head_t bl_wq; | 21 | wait_queue_head_t bl_wq; |
| 22 | struct mutex bl_mutex; | ||
| 22 | struct list_head nfs_client_list; | 23 | struct list_head nfs_client_list; |
| 23 | struct list_head nfs_volume_list; | 24 | struct list_head nfs_volume_list; |
| 24 | #if IS_ENABLED(CONFIG_NFS_V4) | 25 | #if IS_ENABLED(CONFIG_NFS_V4) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 405bd95c1f58..69dc20a743f9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -370,11 +370,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
| 370 | case -NFS4ERR_DELEG_REVOKED: | 370 | case -NFS4ERR_DELEG_REVOKED: |
| 371 | case -NFS4ERR_ADMIN_REVOKED: | 371 | case -NFS4ERR_ADMIN_REVOKED: |
| 372 | case -NFS4ERR_BAD_STATEID: | 372 | case -NFS4ERR_BAD_STATEID: |
| 373 | if (inode != NULL && nfs4_have_delegation(inode, FMODE_READ)) { | ||
| 374 | nfs_remove_bad_delegation(inode); | ||
| 375 | exception->retry = 1; | ||
| 376 | break; | ||
| 377 | } | ||
| 378 | if (state == NULL) | 373 | if (state == NULL) |
| 379 | break; | 374 | break; |
| 380 | ret = nfs4_schedule_stateid_recovery(server, state); | 375 | ret = nfs4_schedule_stateid_recovery(server, state); |
| @@ -1654,7 +1649,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct | |||
| 1654 | nfs_inode_find_state_and_recover(state->inode, | 1649 | nfs_inode_find_state_and_recover(state->inode, |
| 1655 | stateid); | 1650 | stateid); |
| 1656 | nfs4_schedule_stateid_recovery(server, state); | 1651 | nfs4_schedule_stateid_recovery(server, state); |
| 1657 | return 0; | 1652 | return -EAGAIN; |
| 1658 | case -NFS4ERR_DELAY: | 1653 | case -NFS4ERR_DELAY: |
| 1659 | case -NFS4ERR_GRACE: | 1654 | case -NFS4ERR_GRACE: |
| 1660 | set_bit(NFS_DELEGATED_STATE, &state->flags); | 1655 | set_bit(NFS_DELEGATED_STATE, &state->flags); |
| @@ -2109,46 +2104,60 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
| 2109 | return ret; | 2104 | return ret; |
| 2110 | } | 2105 | } |
| 2111 | 2106 | ||
| 2107 | static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state) | ||
| 2108 | { | ||
| 2109 | nfs_remove_bad_delegation(state->inode); | ||
| 2110 | write_seqlock(&state->seqlock); | ||
| 2111 | nfs4_stateid_copy(&state->stateid, &state->open_stateid); | ||
| 2112 | write_sequnlock(&state->seqlock); | ||
| 2113 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
| 2114 | } | ||
| 2115 | |||
| 2116 | static void nfs40_clear_delegation_stateid(struct nfs4_state *state) | ||
| 2117 | { | ||
| 2118 | if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL) | ||
| 2119 | nfs_finish_clear_delegation_stateid(state); | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) | ||
| 2123 | { | ||
| 2124 | /* NFSv4.0 doesn't allow for delegation recovery on open expire */ | ||
| 2125 | nfs40_clear_delegation_stateid(state); | ||
| 2126 | return nfs4_open_expired(sp, state); | ||
| 2127 | } | ||
| 2128 | |||
| 2112 | #if defined(CONFIG_NFS_V4_1) | 2129 | #if defined(CONFIG_NFS_V4_1) |
| 2113 | static void nfs41_clear_delegation_stateid(struct nfs4_state *state) | 2130 | static void nfs41_check_delegation_stateid(struct nfs4_state *state) |
| 2114 | { | 2131 | { |
| 2115 | struct nfs_server *server = NFS_SERVER(state->inode); | 2132 | struct nfs_server *server = NFS_SERVER(state->inode); |
| 2116 | nfs4_stateid *stateid = &state->stateid; | 2133 | nfs4_stateid stateid; |
| 2117 | struct nfs_delegation *delegation; | 2134 | struct nfs_delegation *delegation; |
| 2118 | struct rpc_cred *cred = NULL; | 2135 | struct rpc_cred *cred; |
| 2119 | int status = -NFS4ERR_BAD_STATEID; | 2136 | int status; |
| 2120 | |||
| 2121 | /* If a state reset has been done, test_stateid is unneeded */ | ||
| 2122 | if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) | ||
| 2123 | return; | ||
| 2124 | 2137 | ||
| 2125 | /* Get the delegation credential for use by test/free_stateid */ | 2138 | /* Get the delegation credential for use by test/free_stateid */ |
| 2126 | rcu_read_lock(); | 2139 | rcu_read_lock(); |
| 2127 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); | 2140 | delegation = rcu_dereference(NFS_I(state->inode)->delegation); |
| 2128 | if (delegation != NULL && | 2141 | if (delegation == NULL) { |
| 2129 | nfs4_stateid_match(&delegation->stateid, stateid)) { | ||
| 2130 | cred = get_rpccred(delegation->cred); | ||
| 2131 | rcu_read_unlock(); | ||
| 2132 | status = nfs41_test_stateid(server, stateid, cred); | ||
| 2133 | trace_nfs4_test_delegation_stateid(state, NULL, status); | ||
| 2134 | } else | ||
| 2135 | rcu_read_unlock(); | 2142 | rcu_read_unlock(); |
| 2143 | return; | ||
| 2144 | } | ||
| 2145 | |||
| 2146 | nfs4_stateid_copy(&stateid, &delegation->stateid); | ||
| 2147 | cred = get_rpccred(delegation->cred); | ||
| 2148 | rcu_read_unlock(); | ||
| 2149 | status = nfs41_test_stateid(server, &stateid, cred); | ||
| 2150 | trace_nfs4_test_delegation_stateid(state, NULL, status); | ||
| 2136 | 2151 | ||
| 2137 | if (status != NFS_OK) { | 2152 | if (status != NFS_OK) { |
| 2138 | /* Free the stateid unless the server explicitly | 2153 | /* Free the stateid unless the server explicitly |
| 2139 | * informs us the stateid is unrecognized. */ | 2154 | * informs us the stateid is unrecognized. */ |
| 2140 | if (status != -NFS4ERR_BAD_STATEID) | 2155 | if (status != -NFS4ERR_BAD_STATEID) |
| 2141 | nfs41_free_stateid(server, stateid, cred); | 2156 | nfs41_free_stateid(server, &stateid, cred); |
| 2142 | nfs_remove_bad_delegation(state->inode); | 2157 | nfs_finish_clear_delegation_stateid(state); |
| 2143 | |||
| 2144 | write_seqlock(&state->seqlock); | ||
| 2145 | nfs4_stateid_copy(&state->stateid, &state->open_stateid); | ||
| 2146 | write_sequnlock(&state->seqlock); | ||
| 2147 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
| 2148 | } | 2158 | } |
| 2149 | 2159 | ||
| 2150 | if (cred != NULL) | 2160 | put_rpccred(cred); |
| 2151 | put_rpccred(cred); | ||
| 2152 | } | 2161 | } |
| 2153 | 2162 | ||
| 2154 | /** | 2163 | /** |
| @@ -2192,7 +2201,7 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st | |||
| 2192 | { | 2201 | { |
| 2193 | int status; | 2202 | int status; |
| 2194 | 2203 | ||
| 2195 | nfs41_clear_delegation_stateid(state); | 2204 | nfs41_check_delegation_stateid(state); |
| 2196 | status = nfs41_check_open_stateid(state); | 2205 | status = nfs41_check_open_stateid(state); |
| 2197 | if (status != NFS_OK) | 2206 | if (status != NFS_OK) |
| 2198 | status = nfs4_open_expired(sp, state); | 2207 | status = nfs4_open_expired(sp, state); |
| @@ -2231,19 +2240,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | |||
| 2231 | seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); | 2240 | seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); |
| 2232 | 2241 | ||
| 2233 | ret = _nfs4_proc_open(opendata); | 2242 | ret = _nfs4_proc_open(opendata); |
| 2234 | if (ret != 0) { | 2243 | if (ret != 0) |
| 2235 | if (ret == -ENOENT) { | ||
| 2236 | dentry = opendata->dentry; | ||
| 2237 | if (dentry->d_inode) | ||
| 2238 | d_delete(dentry); | ||
| 2239 | else if (d_unhashed(dentry)) | ||
| 2240 | d_add(dentry, NULL); | ||
| 2241 | |||
| 2242 | nfs_set_verifier(dentry, | ||
| 2243 | nfs_save_change_attribute(opendata->dir->d_inode)); | ||
| 2244 | } | ||
| 2245 | goto out; | 2244 | goto out; |
| 2246 | } | ||
| 2247 | 2245 | ||
| 2248 | state = nfs4_opendata_to_nfs4_state(opendata); | 2246 | state = nfs4_opendata_to_nfs4_state(opendata); |
| 2249 | ret = PTR_ERR(state); | 2247 | ret = PTR_ERR(state); |
| @@ -4841,9 +4839,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
| 4841 | case -NFS4ERR_DELEG_REVOKED: | 4839 | case -NFS4ERR_DELEG_REVOKED: |
| 4842 | case -NFS4ERR_ADMIN_REVOKED: | 4840 | case -NFS4ERR_ADMIN_REVOKED: |
| 4843 | case -NFS4ERR_BAD_STATEID: | 4841 | case -NFS4ERR_BAD_STATEID: |
| 4844 | if (state == NULL) | ||
| 4845 | break; | ||
| 4846 | nfs_remove_bad_delegation(state->inode); | ||
| 4847 | case -NFS4ERR_OPENMODE: | 4842 | case -NFS4ERR_OPENMODE: |
| 4848 | if (state == NULL) | 4843 | if (state == NULL) |
| 4849 | break; | 4844 | break; |
| @@ -8341,7 +8336,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = { | |||
| 8341 | static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { | 8336 | static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { |
| 8342 | .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, | 8337 | .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, |
| 8343 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, | 8338 | .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, |
| 8344 | .recover_open = nfs4_open_expired, | 8339 | .recover_open = nfs40_open_expired, |
| 8345 | .recover_lock = nfs4_lock_expired, | 8340 | .recover_lock = nfs4_lock_expired, |
| 8346 | .establish_clid = nfs4_init_clientid, | 8341 | .establish_clid = nfs4_init_clientid, |
| 8347 | }; | 8342 | }; |
| @@ -8408,8 +8403,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { | |||
| 8408 | | NFS_CAP_CHANGE_ATTR | 8403 | | NFS_CAP_CHANGE_ATTR |
| 8409 | | NFS_CAP_POSIX_LOCK | 8404 | | NFS_CAP_POSIX_LOCK |
| 8410 | | NFS_CAP_STATEID_NFSV41 | 8405 | | NFS_CAP_STATEID_NFSV41 |
| 8411 | | NFS_CAP_ATOMIC_OPEN_V1 | 8406 | | NFS_CAP_ATOMIC_OPEN_V1, |
| 8412 | | NFS_CAP_SEEK, | ||
| 8413 | .init_client = nfs41_init_client, | 8407 | .init_client = nfs41_init_client, |
| 8414 | .shutdown_client = nfs41_shutdown_client, | 8408 | .shutdown_client = nfs41_shutdown_client, |
| 8415 | .match_stateid = nfs41_match_stateid, | 8409 | .match_stateid = nfs41_match_stateid, |
| @@ -8431,7 +8425,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | |||
| 8431 | | NFS_CAP_CHANGE_ATTR | 8425 | | NFS_CAP_CHANGE_ATTR |
| 8432 | | NFS_CAP_POSIX_LOCK | 8426 | | NFS_CAP_POSIX_LOCK |
| 8433 | | NFS_CAP_STATEID_NFSV41 | 8427 | | NFS_CAP_STATEID_NFSV41 |
| 8434 | | NFS_CAP_ATOMIC_OPEN_V1, | 8428 | | NFS_CAP_ATOMIC_OPEN_V1 |
| 8429 | | NFS_CAP_SEEK, | ||
| 8435 | .init_client = nfs41_init_client, | 8430 | .init_client = nfs41_init_client, |
| 8436 | .shutdown_client = nfs41_shutdown_client, | 8431 | .shutdown_client = nfs41_shutdown_client, |
| 8437 | .match_stateid = nfs41_match_stateid, | 8432 | .match_stateid = nfs41_match_stateid, |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 12493846a2d3..f83b02dc9166 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -715,8 +715,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
| 715 | 715 | ||
| 716 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) | 716 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) |
| 717 | nfs_release_request(req); | 717 | nfs_release_request(req); |
| 718 | else | ||
| 719 | WARN_ON_ONCE(1); | ||
| 720 | } | 718 | } |
| 721 | 719 | ||
| 722 | static void | 720 | static void |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 983876f24aed..47ebb4fafd87 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -1224,11 +1224,22 @@ struct nfs41_free_stateid_res { | |||
| 1224 | unsigned int status; | 1224 | unsigned int status; |
| 1225 | }; | 1225 | }; |
| 1226 | 1226 | ||
| 1227 | static inline void | ||
| 1228 | nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo) | ||
| 1229 | { | ||
| 1230 | kfree(cinfo->buckets); | ||
| 1231 | } | ||
| 1232 | |||
| 1227 | #else | 1233 | #else |
| 1228 | 1234 | ||
| 1229 | struct pnfs_ds_commit_info { | 1235 | struct pnfs_ds_commit_info { |
| 1230 | }; | 1236 | }; |
| 1231 | 1237 | ||
| 1238 | static inline void | ||
| 1239 | nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo) | ||
| 1240 | { | ||
| 1241 | } | ||
| 1242 | |||
| 1232 | #endif /* CONFIG_NFS_V4_1 */ | 1243 | #endif /* CONFIG_NFS_V4_1 */ |
| 1233 | 1244 | ||
| 1234 | #ifdef CONFIG_NFS_V4_2 | 1245 | #ifdef CONFIG_NFS_V4_2 |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index afb292cd797d..53ed8d3f8897 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -1353,6 +1353,7 @@ gss_stringify_acceptor(struct rpc_cred *cred) | |||
| 1353 | char *string = NULL; | 1353 | char *string = NULL; |
| 1354 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); | 1354 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); |
| 1355 | struct gss_cl_ctx *ctx; | 1355 | struct gss_cl_ctx *ctx; |
| 1356 | unsigned int len; | ||
| 1356 | struct xdr_netobj *acceptor; | 1357 | struct xdr_netobj *acceptor; |
| 1357 | 1358 | ||
| 1358 | rcu_read_lock(); | 1359 | rcu_read_lock(); |
| @@ -1360,15 +1361,39 @@ gss_stringify_acceptor(struct rpc_cred *cred) | |||
| 1360 | if (!ctx) | 1361 | if (!ctx) |
| 1361 | goto out; | 1362 | goto out; |
| 1362 | 1363 | ||
| 1363 | acceptor = &ctx->gc_acceptor; | 1364 | len = ctx->gc_acceptor.len; |
| 1365 | rcu_read_unlock(); | ||
| 1364 | 1366 | ||
| 1365 | /* no point if there's no string */ | 1367 | /* no point if there's no string */ |
| 1366 | if (!acceptor->len) | 1368 | if (!len) |
| 1367 | goto out; | 1369 | return NULL; |
| 1368 | 1370 | realloc: | |
| 1369 | string = kmalloc(acceptor->len + 1, GFP_KERNEL); | 1371 | string = kmalloc(len + 1, GFP_KERNEL); |
| 1370 | if (!string) | 1372 | if (!string) |
| 1373 | return NULL; | ||
| 1374 | |||
| 1375 | rcu_read_lock(); | ||
| 1376 | ctx = rcu_dereference(gss_cred->gc_ctx); | ||
| 1377 | |||
| 1378 | /* did the ctx disappear or was it replaced by one with no acceptor? */ | ||
| 1379 | if (!ctx || !ctx->gc_acceptor.len) { | ||
| 1380 | kfree(string); | ||
| 1381 | string = NULL; | ||
| 1371 | goto out; | 1382 | goto out; |
| 1383 | } | ||
| 1384 | |||
| 1385 | acceptor = &ctx->gc_acceptor; | ||
| 1386 | |||
| 1387 | /* | ||
| 1388 | * Did we find a new acceptor that's longer than the original? Allocate | ||
| 1389 | * a longer buffer and try again. | ||
| 1390 | */ | ||
| 1391 | if (len < acceptor->len) { | ||
| 1392 | len = acceptor->len; | ||
| 1393 | rcu_read_unlock(); | ||
| 1394 | kfree(string); | ||
| 1395 | goto realloc; | ||
| 1396 | } | ||
| 1372 | 1397 | ||
| 1373 | memcpy(string, acceptor->data, acceptor->len); | 1398 | memcpy(string, acceptor->data, acceptor->len); |
| 1374 | string[acceptor->len] = '\0'; | 1399 | string[acceptor->len] = '\0'; |
