diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 115 |
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 | ||
5107 | static 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 | |||
5112 | static 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 | */ |
5110 | static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs, | 5136 | static 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); |
5140 | out: | 5156 | out: |
@@ -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 | */ | ||
5162 | static 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); | ||
5184 | out: | ||
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 | */ |
5192 | static int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | 5178 | static 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 | ||