diff options
| -rw-r--r-- | fs/nfs/nfs4proc.c | 130 | ||||
| -rw-r--r-- | fs/nfs/nfs4state.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 5 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 2 |
4 files changed, 62 insertions, 77 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f0c849c98fe4..ec9f6ef6c5dd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -3575,8 +3575,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
| 3575 | } | 3575 | } |
| 3576 | if (npages > 1) { | 3576 | if (npages > 1) { |
| 3577 | /* for decoding across pages */ | 3577 | /* for decoding across pages */ |
| 3578 | args.acl_scratch = alloc_page(GFP_KERNEL); | 3578 | res.acl_scratch = alloc_page(GFP_KERNEL); |
| 3579 | if (!args.acl_scratch) | 3579 | if (!res.acl_scratch) |
| 3580 | goto out_free; | 3580 | goto out_free; |
| 3581 | } | 3581 | } |
| 3582 | args.acl_len = npages * PAGE_SIZE; | 3582 | args.acl_len = npages * PAGE_SIZE; |
| @@ -3612,8 +3612,8 @@ out_free: | |||
| 3612 | for (i = 0; i < npages; i++) | 3612 | for (i = 0; i < npages; i++) |
| 3613 | if (pages[i]) | 3613 | if (pages[i]) |
| 3614 | __free_page(pages[i]); | 3614 | __free_page(pages[i]); |
| 3615 | if (args.acl_scratch) | 3615 | if (res.acl_scratch) |
| 3616 | __free_page(args.acl_scratch); | 3616 | __free_page(res.acl_scratch); |
| 3617 | return ret; | 3617 | return ret; |
| 3618 | } | 3618 | } |
| 3619 | 3619 | ||
| @@ -4883,8 +4883,10 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 4883 | clp->cl_rpcclient->cl_auth->au_flavor); | 4883 | clp->cl_rpcclient->cl_auth->au_flavor); |
| 4884 | 4884 | ||
| 4885 | res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); | 4885 | res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); |
| 4886 | if (unlikely(!res.server_scope)) | 4886 | if (unlikely(!res.server_scope)) { |
| 4887 | return -ENOMEM; | 4887 | status = -ENOMEM; |
| 4888 | goto out; | ||
| 4889 | } | ||
| 4888 | 4890 | ||
| 4889 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 4891 | status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
| 4890 | if (!status) | 4892 | if (!status) |
| @@ -4901,12 +4903,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 4901 | clp->server_scope = NULL; | 4903 | clp->server_scope = NULL; |
| 4902 | } | 4904 | } |
| 4903 | 4905 | ||
| 4904 | if (!clp->server_scope) | 4906 | if (!clp->server_scope) { |
| 4905 | clp->server_scope = res.server_scope; | 4907 | clp->server_scope = res.server_scope; |
| 4906 | else | 4908 | goto out; |
| 4907 | kfree(res.server_scope); | 4909 | } |
| 4908 | } | 4910 | } |
| 4909 | 4911 | kfree(res.server_scope); | |
| 4912 | out: | ||
| 4910 | dprintk("<-- %s status= %d\n", __func__, status); | 4913 | dprintk("<-- %s status= %d\n", __func__, status); |
| 4911 | return status; | 4914 | return status; |
| 4912 | } | 4915 | } |
| @@ -5008,37 +5011,53 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo) | |||
| 5008 | return status; | 5011 | return status; |
| 5009 | } | 5012 | } |
| 5010 | 5013 | ||
| 5014 | static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags) | ||
| 5015 | { | ||
| 5016 | return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags); | ||
| 5017 | } | ||
| 5018 | |||
| 5019 | static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, | ||
| 5020 | struct nfs4_slot *new, | ||
| 5021 | u32 max_slots, | ||
| 5022 | u32 ivalue) | ||
| 5023 | { | ||
| 5024 | struct nfs4_slot *old = NULL; | ||
| 5025 | u32 i; | ||
| 5026 | |||
| 5027 | spin_lock(&tbl->slot_tbl_lock); | ||
| 5028 | if (new) { | ||
| 5029 | old = tbl->slots; | ||
| 5030 | tbl->slots = new; | ||
| 5031 | tbl->max_slots = max_slots; | ||
| 5032 | } | ||
| 5033 | tbl->highest_used_slotid = -1; /* no slot is currently used */ | ||
| 5034 | for (i = 0; i < tbl->max_slots; i++) | ||
| 5035 | tbl->slots[i].seq_nr = ivalue; | ||
| 5036 | spin_unlock(&tbl->slot_tbl_lock); | ||
| 5037 | kfree(old); | ||
| 5038 | } | ||
| 5039 | |||
| 5011 | /* | 5040 | /* |
| 5012 | * Reset a slot table | 5041 | * (re)Initialise a slot table |
| 5013 | */ | 5042 | */ |
| 5014 | static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, | 5043 | static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, |
| 5015 | int ivalue) | 5044 | u32 ivalue) |
| 5016 | { | 5045 | { |
| 5017 | struct nfs4_slot *new = NULL; | 5046 | struct nfs4_slot *new = NULL; |
| 5018 | int i; | 5047 | int ret = -ENOMEM; |
| 5019 | int ret = 0; | ||
| 5020 | 5048 | ||
| 5021 | dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__, | 5049 | dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__, |
| 5022 | max_reqs, tbl->max_slots); | 5050 | max_reqs, tbl->max_slots); |
| 5023 | 5051 | ||
| 5024 | /* Does the newly negotiated max_reqs match the existing slot table? */ | 5052 | /* Does the newly negotiated max_reqs match the existing slot table? */ |
| 5025 | if (max_reqs != tbl->max_slots) { | 5053 | if (max_reqs != tbl->max_slots) { |
| 5026 | ret = -ENOMEM; | 5054 | new = nfs4_alloc_slots(max_reqs, GFP_NOFS); |
| 5027 | new = kmalloc(max_reqs * sizeof(struct nfs4_slot), | ||
| 5028 | GFP_NOFS); | ||
| 5029 | if (!new) | 5055 | if (!new) |
| 5030 | goto out; | 5056 | goto out; |
| 5031 | ret = 0; | ||
| 5032 | kfree(tbl->slots); | ||
| 5033 | } | 5057 | } |
| 5034 | spin_lock(&tbl->slot_tbl_lock); | 5058 | ret = 0; |
| 5035 | if (new) { | 5059 | |
| 5036 | tbl->slots = new; | 5060 | nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue); |
| 5037 | tbl->max_slots = max_reqs; | ||
| 5038 | } | ||
| 5039 | for (i = 0; i < tbl->max_slots; ++i) | ||
| 5040 | tbl->slots[i].seq_nr = ivalue; | ||
| 5041 | spin_unlock(&tbl->slot_tbl_lock); | ||
| 5042 | dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, | 5061 | dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, |
| 5043 | tbl, tbl->slots, tbl->max_slots); | 5062 | tbl, tbl->slots, tbl->max_slots); |
| 5044 | out: | 5063 | out: |
| @@ -5061,36 +5080,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session) | |||
| 5061 | } | 5080 | } |
| 5062 | 5081 | ||
| 5063 | /* | 5082 | /* |
| 5064 | * Initialize slot table | ||
| 5065 | */ | ||
| 5066 | static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, | ||
| 5067 | int max_slots, int ivalue) | ||
| 5068 | { | ||
| 5069 | struct nfs4_slot *slot; | ||
| 5070 | int ret = -ENOMEM; | ||
| 5071 | |||
| 5072 | BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE); | ||
| 5073 | |||
| 5074 | dprintk("--> %s: max_reqs=%u\n", __func__, max_slots); | ||
| 5075 | |||
| 5076 | slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS); | ||
| 5077 | if (!slot) | ||
| 5078 | goto out; | ||
| 5079 | ret = 0; | ||
| 5080 | |||
| 5081 | spin_lock(&tbl->slot_tbl_lock); | ||
| 5082 | tbl->max_slots = max_slots; | ||
| 5083 | tbl->slots = slot; | ||
| 5084 | tbl->highest_used_slotid = -1; /* no slot is currently used */ | ||
| 5085 | spin_unlock(&tbl->slot_tbl_lock); | ||
| 5086 | dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, | ||
| 5087 | tbl, tbl->slots, tbl->max_slots); | ||
| 5088 | out: | ||
| 5089 | dprintk("<-- %s: return %d\n", __func__, ret); | ||
| 5090 | return ret; | ||
| 5091 | } | ||
| 5092 | |||
| 5093 | /* | ||
| 5094 | * Initialize or reset the forechannel and backchannel tables | 5083 | * Initialize or reset the forechannel and backchannel tables |
| 5095 | */ | 5084 | */ |
| 5096 | static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | 5085 | static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) |
| @@ -5101,25 +5090,16 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | |||
| 5101 | dprintk("--> %s\n", __func__); | 5090 | dprintk("--> %s\n", __func__); |
| 5102 | /* Fore channel */ | 5091 | /* Fore channel */ |
| 5103 | tbl = &ses->fc_slot_table; | 5092 | tbl = &ses->fc_slot_table; |
| 5104 | if (tbl->slots == NULL) { | 5093 | status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); |
| 5105 | status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1); | 5094 | if (status) /* -ENOMEM */ |
| 5106 | if (status) /* -ENOMEM */ | 5095 | return status; |
| 5107 | return status; | ||
| 5108 | } else { | ||
| 5109 | status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1); | ||
| 5110 | if (status) | ||
| 5111 | return status; | ||
| 5112 | } | ||
| 5113 | /* Back channel */ | 5096 | /* Back channel */ |
| 5114 | tbl = &ses->bc_slot_table; | 5097 | tbl = &ses->bc_slot_table; |
| 5115 | if (tbl->slots == NULL) { | 5098 | status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); |
| 5116 | status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0); | ||
