Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSv4.1/flexfiles: Mark layout for return if the mirrors are invalid

If a read-write layout has an invalid mirror, then we should
mark it as invalid, and return it.
If a read-only layout has an invalid mirror, then mark it as invalid
and check if there is still at least one valid mirror before we return
it.

Note: Also fix incorrect use of pnfs_generic_mark_devid_invalid().
We really want nfs4_mark_deviceid_unavailable().

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

+30 -15
+30 -15
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 172 172 return NULL; 173 173 } 174 174 175 + static void ff_layout_mark_devid_invalid(struct pnfs_layout_segment *lseg, 176 + struct nfs4_deviceid_node *devid) 177 + { 178 + nfs4_mark_deviceid_unavailable(devid); 179 + if (!ff_layout_has_available_ds(lseg)) 180 + pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode, 181 + lseg); 182 + } 183 + 184 + static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg, 185 + struct nfs4_ff_layout_mirror *mirror) 186 + { 187 + if (mirror == NULL || mirror->mirror_ds == NULL) { 188 + pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode, 189 + lseg); 190 + return false; 191 + } 192 + if (mirror->mirror_ds->ds == NULL) { 193 + struct nfs4_deviceid_node *devid; 194 + devid = &mirror->mirror_ds->id_node; 195 + ff_layout_mark_devid_invalid(lseg, devid); 196 + return false; 197 + } 198 + return true; 199 + } 200 + 175 201 static u64 176 202 end_offset(u64 start, u64 len) 177 203 { ··· 362 336 { 363 337 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx); 364 338 struct nfs_fh *fh = NULL; 365 - struct nfs4_deviceid_node *devid; 366 339 367 - if (mirror == NULL || mirror->mirror_ds == NULL || 368 - mirror->mirror_ds->ds == NULL) { 369 - printk(KERN_ERR "NFS: %s: No data server for mirror offset index %d\n", 340 + if (!ff_layout_mirror_valid(lseg, mirror)) { 341 + pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n", 370 342 __func__, mirror_idx); 371 - if (mirror && mirror->mirror_ds) { 372 - devid = &mirror->mirror_ds->id_node; 373 - nfs4_mark_deviceid_unavailable(devid); 374 - } 375 343 goto out; 376 344 } 377 345 ··· 388 368 unsigned int max_payload; 389 369 rpc_authflavor_t flavor; 390 370 391 - if (mirror == NULL || mirror->mirror_ds == NULL || 392 - mirror->mirror_ds->ds == NULL) { 393 - printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", 371 + if (!ff_layout_mirror_valid(lseg, mirror)) { 372 + pr_err_ratelimited("NFS: %s: No data server for offset index %d\n", 394 373 __func__, ds_idx); 395 - if (mirror && mirror->mirror_ds) { 396 - devid = &mirror->mirror_ds->id_node; 397 - nfs4_mark_deviceid_unavailable(devid); 398 - } 399 374 goto out; 400 375 } 401 376