aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c115
1 files changed, 46 insertions, 69 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 87b9b91f76cf..ea7adfc868c2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3621,8 +3621,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3621 } 3621 }
3622 if (npages > 1) { 3622 if (npages > 1) {
3623 /* for decoding across pages */ 3623 /* for decoding across pages */
3624 args.acl_scratch = alloc_page(GFP_KERNEL); 3624 res.acl_scratch = alloc_page(GFP_KERNEL);
3625 if (!args.acl_scratch) 3625 if (!res.acl_scratch)
3626 goto out_free; 3626 goto out_free;
3627 } 3627 }
3628 args.acl_len = npages * PAGE_SIZE; 3628 args.acl_len = npages * PAGE_SIZE;
@@ -3658,8 +3658,8 @@ out_free:
3658 for (i = 0; i < npages; i++) 3658 for (i = 0; i < npages; i++)
3659 if (pages[i]) 3659 if (pages[i])
3660 __free_page(pages[i]); 3660 __free_page(pages[i]);
3661 if (args.acl_scratch) 3661 if (res.acl_scratch)
3662 __free_page(args.acl_scratch); 3662 __free_page(res.acl_scratch);
3663 return ret; 3663 return ret;
3664} 3664}
3665 3665
@@ -5104,37 +5104,53 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
5104 return status; 5104 return status;
5105} 5105}
5106 5106
5107static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags)
5108{
5109 return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags);
5110}
5111
5112static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
5113 struct nfs4_slot *new,
5114 u32 max_slots,
5115 u32 ivalue)
5116{
5117 struct nfs4_slot *old = NULL;
5118 u32 i;
5119
5120 spin_lock(&tbl->slot_tbl_lock);
5121 if (new) {
5122 old = tbl->slots;
5123 tbl->slots = new;
5124 tbl->max_slots = max_slots;
5125 }
5126 tbl->highest_used_slotid = -1; /* no slot is currently used */
5127 for (i = 0; i < tbl->max_slots; i++)
5128 tbl->slots[i].seq_nr = ivalue;
5129 spin_unlock(&tbl->slot_tbl_lock);
5130 kfree(old);
5131}
5132
5107/* 5133/*
5108 * Reset a slot table 5134 * (re)Initialise a slot table
5109 */ 5135 */
5110static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, 5136static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
5111 int ivalue) 5137 u32 ivalue)
5112{ 5138{
5113 struct nfs4_slot *new = NULL; 5139 struct nfs4_slot *new = NULL;
5114 int i; 5140 int ret = -ENOMEM;
5115 int ret = 0;
5116 5141
5117 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__, 5142 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
5118 max_reqs, tbl->max_slots); 5143 max_reqs, tbl->max_slots);
5119 5144
5120 /* Does the newly negotiated max_reqs match the existing slot table? */ 5145 /* Does the newly negotiated max_reqs match the existing slot table? */
5121 if (max_reqs != tbl->max_slots) { 5146 if (max_reqs != tbl->max_slots) {
5122 ret = -ENOMEM; 5147 new = nfs4_alloc_slots(max_reqs, GFP_NOFS);
5123 new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
5124 GFP_NOFS);
5125 if (!new) 5148 if (!new)
5126 goto out; 5149 goto out;
5127 ret = 0;
5128 kfree(tbl->slots);
5129 }
5130 spin_lock(&tbl->slot_tbl_lock);
5131 if (new) {
5132 tbl->slots = new;
5133 tbl->max_slots = max_reqs;
5134 } 5150 }
5135 for (i = 0; i < tbl->max_slots; ++i) 5151 ret = 0;
5136 tbl->slots[i].seq_nr = ivalue; 5152
5137 spin_unlock(&tbl->slot_tbl_lock); 5153 nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue);
5138 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 5154 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
5139 tbl, tbl->slots, tbl->max_slots); 5155 tbl, tbl->slots, tbl->max_slots);
5140out: 5156out:
@@ -5157,36 +5173,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
5157} 5173}
5158 5174
5159/* 5175/*
5160 * Initialize slot table
5161 */
5162static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
5163 int max_slots, int ivalue)
5164{
5165 struct nfs4_slot *slot;
5166 int ret = -ENOMEM;
5167
5168 BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
5169
5170 dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
5171
5172 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
5173 if (!slot)
5174 goto out;
5175 ret = 0;
5176
5177 spin_lock(&tbl->slot_tbl_lock);
5178 tbl->max_slots = max_slots;
5179 tbl->slots = slot;
5180 tbl->highest_used_slotid = NFS4_NO_SLOT; /* no slot is currently used */
5181 spin_unlock(&tbl->slot_tbl_lock);
5182 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
5183 tbl, tbl->slots, tbl->max_slots);
5184out:
5185 dprintk("<-- %s: return %d\n", __func__, ret);
5186 return ret;
5187}
5188
5189/*
5190 * Initialize or reset the forechannel and backchannel tables 5176 * Initialize or reset the forechannel and backchannel tables
5191 */ 5177 */
5192static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) 5178static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
@@ -5197,25 +5183,16 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
5197 dprintk("--> %s\n", __func__); 5183 dprintk("--> %s\n", __func__);
5198 /* Fore channel */ 5184 /* Fore channel */
5199 tbl = &ses->fc_slot_table; 5185 tbl = &ses->fc_slot_table;
5200 if (tbl->slots == NULL) { 5186 status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5201 status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1); 5187 if (status) /* -ENOMEM */
5202 if (status) /* -ENOMEM */ 5188 return status;
5203 return status;
5204 } else {
5205 status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
5206 if (status)
5207 return status;
5208 }
5209 /* Back channel */ 5189 /* Back channel */
5210 tbl = &ses->bc_slot_table; 5190 tbl = &ses->bc_slot_table;
5211 if (tbl->slots == NULL) { 5191 status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5212 status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0); 5192 if (status && tbl->slots == NULL)
5213 if (status) 5193 /* Fore and back channel share a connection so get
5214 /* Fore and back channel share a connection so get 5194 * both slot tables or neither */
5215 * both slot tables or neither */ 5195 nfs4_destroy_slot_tables(ses);
5216 nfs4_destroy_slot_tables(ses);
5217 } else
5218 status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
5219 return status; 5196 return status;
5220} 5197}
5221 5198