hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/nfs/callback_proc.c
....@@ -26,7 +26,6 @@
2626 struct cb_getattrargs *args = argp;
2727 struct cb_getattrres *res = resp;
2828 struct nfs_delegation *delegation;
29
- struct nfs_inode *nfsi;
3029 struct inode *inode;
3130
3231 res->status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
....@@ -47,17 +46,16 @@
4746 -ntohl(res->status));
4847 goto out;
4948 }
50
- nfsi = NFS_I(inode);
5149 rcu_read_lock();
52
- delegation = rcu_dereference(nfsi->delegation);
50
+ delegation = nfs4_get_valid_delegation(inode);
5351 if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
5452 goto out_iput;
5553 res->size = i_size_read(inode);
5654 res->change_attr = delegation->change_attr;
5755 if (nfs_have_writebacks(inode))
5856 res->change_attr++;
59
- res->ctime = timespec64_to_timespec(inode->i_ctime);
60
- res->mtime = timespec64_to_timespec(inode->i_mtime);
57
+ res->ctime = inode->i_ctime;
58
+ res->mtime = inode->i_mtime;
6159 res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
6260 args->bitmap[0];
6361 res->bitmap[1] = (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) &
....@@ -123,33 +121,31 @@
123121 */
124122 static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp,
125123 const nfs4_stateid *stateid)
124
+ __must_hold(RCU)
126125 {
127126 struct nfs_server *server;
128127 struct inode *inode;
129128 struct pnfs_layout_hdr *lo;
130129
130
+ rcu_read_lock();
131131 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
132
- list_for_each_entry(lo, &server->layouts, plh_layouts) {
132
+ list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
133133 if (!pnfs_layout_is_valid(lo))
134134 continue;
135
- if (stateid != NULL &&
136
- !nfs4_stateid_match_other(stateid, &lo->plh_stateid))
135
+ if (!nfs4_stateid_match_other(stateid, &lo->plh_stateid))
137136 continue;
138
- inode = igrab(lo->plh_inode);
139
- if (!inode)
140
- return ERR_PTR(-EAGAIN);
141
- if (!nfs_sb_active(inode->i_sb)) {
142
- rcu_read_unlock();
143
- spin_unlock(&clp->cl_lock);
144
- iput(inode);
145
- spin_lock(&clp->cl_lock);
146
- rcu_read_lock();
147
- return ERR_PTR(-EAGAIN);
148
- }
149
- return inode;
137
+ if (nfs_sb_active(server->super))
138
+ inode = igrab(lo->plh_inode);
139
+ else
140
+ inode = ERR_PTR(-EAGAIN);
141
+ rcu_read_unlock();
142
+ if (inode)
143
+ return inode;
144
+ nfs_sb_deactive(server->super);
145
+ return ERR_PTR(-EAGAIN);
150146 }
151147 }
152
-
148
+ rcu_read_unlock();
153149 return ERR_PTR(-ENOENT);
154150 }
155151
....@@ -167,28 +163,26 @@
167163 struct inode *inode;
168164 struct pnfs_layout_hdr *lo;
169165
166
+ rcu_read_lock();
170167 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
171
- list_for_each_entry(lo, &server->layouts, plh_layouts) {
168
+ list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
172169 nfsi = NFS_I(lo->plh_inode);
173170 if (nfs_compare_fh(fh, &nfsi->fh))
174171 continue;
175172 if (nfsi->layout != lo)
176173 continue;
177
- inode = igrab(lo->plh_inode);
178
- if (!inode)
179
- return ERR_PTR(-EAGAIN);
180
- if (!nfs_sb_active(inode->i_sb)) {
181
- rcu_read_unlock();
182
- spin_unlock(&clp->cl_lock);
183
- iput(inode);
184
- spin_lock(&clp->cl_lock);
185
- rcu_read_lock();
186
- return ERR_PTR(-EAGAIN);
187
- }
188
- return inode;
174
+ if (nfs_sb_active(server->super))
175
+ inode = igrab(lo->plh_inode);
176
+ else
177
+ inode = ERR_PTR(-EAGAIN);
178
+ rcu_read_unlock();
179
+ if (inode)
180
+ return inode;
181
+ nfs_sb_deactive(server->super);
182
+ return ERR_PTR(-EAGAIN);
189183 }
190184 }
191
-
185
+ rcu_read_unlock();
192186 return ERR_PTR(-ENOENT);
193187 }
194188
....@@ -198,14 +192,9 @@
198192 {
199193 struct inode *inode;
200194
201
- spin_lock(&clp->cl_lock);
202
- rcu_read_lock();
203195 inode = nfs_layout_find_inode_by_stateid(clp, stateid);
204196 if (inode == ERR_PTR(-ENOENT))
205197 inode = nfs_layout_find_inode_by_fh(clp, fh);
206
- rcu_read_unlock();
207
- spin_unlock(&clp->cl_lock);
208
-
209198 return inode;
210199 }
211200
....@@ -284,7 +273,7 @@
284273 goto unlock;
285274 }
286275
287
- pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
276
+ pnfs_set_layout_stateid(lo, &args->cbl_stateid, NULL, true);
288277 switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
289278 &args->cbl_range,
290279 be32_to_cpu(args->cbl_stateid.seqid))) {
....@@ -294,6 +283,7 @@
294283 rv = NFS4_OK;
295284 break;
296285 case -ENOENT:
286
+ set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags);
297287 /* Embrace your forgetfulness! */
298288 rv = NFS4ERR_NOMATCHING_LAYOUT;
299289
....@@ -364,12 +354,11 @@
364354 struct cb_process_state *cps)
365355 {
366356 struct cb_devicenotifyargs *args = argp;
357
+ const struct pnfs_layoutdriver_type *ld = NULL;
367358 uint32_t i;
368359 __be32 res = 0;
369
- struct nfs_client *clp = cps->clp;
370
- struct nfs_server *server = NULL;
371360
372
- if (!clp) {
361
+ if (!cps->clp) {
373362 res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION);
374363 goto out;
375364 }
....@@ -377,23 +366,15 @@
377366 for (i = 0; i < args->ndevs; i++) {
378367 struct cb_devicenotifyitem *dev = &args->devs[i];
379368
380
- if (!server ||
381
- server->pnfs_curr_ld->id != dev->cbd_layout_type) {
382
- rcu_read_lock();
383
- list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
384
- if (server->pnfs_curr_ld &&
385
- server->pnfs_curr_ld->id == dev->cbd_layout_type) {
386
- rcu_read_unlock();
387
- goto found;
388
- }
389
- rcu_read_unlock();
390
- continue;
369
+ if (!ld || ld->id != dev->cbd_layout_type) {
370
+ pnfs_put_layoutdriver(ld);
371
+ ld = pnfs_find_layoutdriver(dev->cbd_layout_type);
372
+ if (!ld)
373
+ continue;
391374 }
392
-
393
- found:
394
- nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id);
375
+ nfs4_delete_deviceid(ld, cps->clp, &dev->cbd_dev_id);
395376 }
396
-
377
+ pnfs_put_layoutdriver(ld);
397378 out:
398379 kfree(args->devs);
399380 return res;
....@@ -416,27 +397,39 @@
416397 validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot,
417398 const struct cb_sequenceargs * args)
418399 {
400
+ __be32 ret;
401
+
402
+ ret = cpu_to_be32(NFS4ERR_BADSLOT);
419403 if (args->csa_slotid > tbl->server_highest_slotid)
420
- return htonl(NFS4ERR_BADSLOT);
404
+ goto out_err;
421405
422406 /* Replay */
423407 if (args->csa_sequenceid == slot->seq_nr) {
408
+ ret = cpu_to_be32(NFS4ERR_DELAY);
424409 if (nfs4_test_locked_slot(tbl, slot->slot_nr))
425
- return htonl(NFS4ERR_DELAY);
410
+ goto out_err;
411
+
426412 /* Signal process_op to set this error on next op */
413
+ ret = cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP);
427414 if (args->csa_cachethis == 0)
428
- return htonl(NFS4ERR_RETRY_UNCACHED_REP);
415
+ goto out_err;
429416
430417 /* Liar! We never allowed you to set csa_cachethis != 0 */
431
- return htonl(NFS4ERR_SEQ_FALSE_RETRY);
418
+ ret = cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY);
419
+ goto out_err;
432420 }
433421
434422 /* Note: wraparound relies on seq_nr being of type u32 */
435
- if (likely(args->csa_sequenceid == slot->seq_nr + 1))
436
- return htonl(NFS4_OK);
437
-
438423 /* Misordered request */
439
- return htonl(NFS4ERR_SEQ_MISORDERED);
424
+ ret = cpu_to_be32(NFS4ERR_SEQ_MISORDERED);
425
+ if (args->csa_sequenceid != slot->seq_nr + 1)
426
+ goto out_err;
427
+
428
+ return cpu_to_be32(NFS4_OK);
429
+
430
+out_err:
431
+ trace_nfs4_cb_seqid_err(args, ret);
432
+ return ret;
440433 }
441434
442435 /*
....@@ -597,6 +590,7 @@
597590 struct cb_recallanyargs *args = argp;
598591 __be32 status;
599592 fmode_t flags = 0;
593
+ bool schedule_manager = false;
600594
601595 status = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION);
602596 if (!cps->clp) /* set in cb_sequence */
....@@ -619,6 +613,18 @@
619613
620614 if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_FILE_LAYOUT))
621615 pnfs_recall_all_layouts(cps->clp);
616
+
617
+ if (args->craa_type_mask & BIT(PNFS_FF_RCA4_TYPE_MASK_READ)) {
618
+ set_bit(NFS4CLNT_RECALL_ANY_LAYOUT_READ, &cps->clp->cl_state);
619
+ schedule_manager = true;
620
+ }
621
+ if (args->craa_type_mask & BIT(PNFS_FF_RCA4_TYPE_MASK_RW)) {
622
+ set_bit(NFS4CLNT_RECALL_ANY_LAYOUT_RW, &cps->clp->cl_state);
623
+ schedule_manager = true;
624
+ }
625
+ if (schedule_manager)
626
+ nfs4_schedule_state_manager(cps->clp);
627
+
622628 out:
623629 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
624630 return status;