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

Configure Feed

Select the types of activity you want to include in your feed.

NFSv4/flexfiles: Update low level helper functions to be DS stripe aware.

Updates common helper functions to be dss_id aware. Most cases simply
add a dss_id parameter. The has_available functions have been updated
with a loop.

Signed-off-by: Jonathan Curley <jcurley@purestorage.com>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>

authored by

Jonathan Curley and committed by
Anna Schumaker
a1491919 d442670c

+115 -85
+28 -28
fs/nfs/flexfilelayout/flexfilelayout.c
··· 164 164 } 165 165 166 166 static struct nfsd_file * 167 - ff_local_open_fh(struct pnfs_layout_segment *lseg, u32 ds_idx, 167 + ff_local_open_fh(struct pnfs_layout_segment *lseg, u32 ds_idx, u32 dss_id, 168 168 struct nfs_client *clp, const struct cred *cred, 169 169 struct nfs_fh *fh, fmode_t mode) 170 170 { 171 171 #if IS_ENABLED(CONFIG_NFS_LOCALIO) 172 172 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx); 173 173 174 - return nfs_local_open_fh(clp, cred, fh, &mirror->dss[0].nfl, mode); 174 + return nfs_local_open_fh(clp, cred, fh, &mirror->dss[dss_id].nfl, mode); 175 175 #else 176 176 return NULL; 177 177 #endif ··· 752 752 static void 753 753 ff_layout_mark_ds_unreachable(struct pnfs_layout_segment *lseg, u32 idx) 754 754 { 755 - struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); 755 + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx, 0); 756 756 757 757 if (devid) 758 758 nfs4_mark_deviceid_unavailable(devid); ··· 761 761 static void 762 762 ff_layout_mark_ds_reachable(struct pnfs_layout_segment *lseg, u32 idx) 763 763 { 764 - struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); 764 + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx, 0); 765 765 766 766 if (devid) 767 767 nfs4_mark_deviceid_available(devid); ··· 780 780 /* mirrors are initially sorted by efficiency */ 781 781 for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { 782 782 mirror = FF_LAYOUT_COMP(lseg, idx); 783 - ds = nfs4_ff_layout_prepare_ds(lseg, mirror, false); 783 + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, 0, false); 784 784 if (IS_ERR(ds)) 785 785 continue; 786 786 ··· 956 956 957 957 for (i = 0; i < pgio->pg_mirror_count; i++) { 958 958 mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); 959 - ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, mirror, true); 959 + ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, mirror, 0, true); 960 960 if (IS_ERR(ds)) { 961 961 if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) 962 962 goto out_mds; ··· 1130 1130 { 1131 1131 struct pnfs_layout_hdr *lo = lseg->pls_layout; 1132 1132 struct inode *inode = lo->plh_inode; 1133 - struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); 1133 + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx, 0); 1134 1134 struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table; 1135 1135 1136 1136 switch (op_status) { ··· 1229 1229 struct pnfs_layout_segment *lseg, 1230 1230 u32 idx) 1231 1231 { 1232 - struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); 1232 + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx, 0); 1233 1233 1234 1234 switch (op_status) { 1235 1235 case NFS_OK: ··· 1359 1359 1360 1360 mirror = FF_LAYOUT_COMP(lseg, idx); 1361 1361 err = ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), 1362 - mirror, offset, length, status, opnum, 1362 + mirror, 0, offset, length, status, opnum, 1363 1363 nfs_io_gfp_mask()); 1364 1364 1365 1365 switch (status) { ··· 1891 1891 hdr->args.pgbase, (size_t)hdr->args.count, offset); 1892 1892 1893 1893 mirror = FF_LAYOUT_COMP(lseg, idx); 1894 - ds = nfs4_ff_layout_prepare_ds(lseg, mirror, false); 1894 + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, 0, false); 1895 1895 if (IS_ERR(ds)) { 1896 1896 ds_fatal_error = nfs_error_is_fatal(PTR_ERR(ds)); 1897 1897 goto out_failed; 1898 1898 } 1899 1899 1900 1900 ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, 1901 - hdr->inode); 1901 + hdr->inode, 0); 1902 1902 if (IS_ERR(ds_clnt)) 1903 1903 goto out_failed; 1904 1904 1905 - ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred); 1905 + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred, 0); 1906 1906 if (!ds_cred) 1907 1907 goto out_failed; 1908 1908 1909 - vers = nfs4_ff_layout_ds_version(mirror); 1909 + vers = nfs4_ff_layout_ds_version(mirror, 0); 1910 1910 1911 1911 dprintk("%s USE DS: %s cl_count %d vers %d\n", __func__, 1912 1912 ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count), vers); ··· 1914 1914 hdr->pgio_done_cb = ff_layout_read_done_cb; 1915 1915 refcount_inc(&ds->ds_clp->cl_count); 1916 1916 hdr->ds_clp = ds->ds_clp; 1917 - fh = nfs4_ff_layout_select_ds_fh(mirror); 1917 + fh = nfs4_ff_layout_select_ds_fh(mirror, 0); 1918 1918 if (fh) 1919 1919 hdr->args.fh = fh; 1920 1920 1921 - nfs4_ff_layout_select_ds_stateid(mirror, &hdr->args.stateid); 1921 + nfs4_ff_layout_select_ds_stateid(mirror, 0, &hdr->args.stateid); 1922 1922 1923 1923 /* 1924 1924 * Note that if we ever decide to split across DSes, ··· 1928 1928 hdr->mds_offset = offset; 1929 1929 1930 1930 /* Start IO accounting for local read */ 1931 - localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, FMODE_READ); 1931 + localio = ff_local_open_fh(lseg, idx, 0, ds->ds_clp, ds_cred, fh, FMODE_READ); 1932 1932 if (localio) { 1933 1933 hdr->task.tk_start = ktime_get(); 1934 1934 ff_layout_read_record_layoutstats_start(&hdr->task, hdr); ··· 1968 1968 bool ds_fatal_error = false; 1969 1969 1970 1970 mirror = FF_LAYOUT_COMP(lseg, idx); 1971 - ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true); 1971 + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, 0, true); 1972 1972 if (IS_ERR(ds)) { 1973 1973 ds_fatal_error = nfs_error_is_fatal(PTR_ERR(ds)); 1974 1974 goto out_failed; 1975 1975 } 1976 1976 1977 1977 ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, 1978 - hdr->inode); 1978 + hdr->inode, 0); 1979 1979 if (IS_ERR(ds_clnt)) 1980 1980 goto out_failed; 1981 1981 1982 - ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred); 1982 + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred, 0); 1983 1983 if (!ds_cred) 1984 1984 goto out_failed; 1985 1985 1986 - vers = nfs4_ff_layout_ds_version(mirror); 1986 + vers = nfs4_ff_layout_ds_version(mirror, 0); 1987 1987 1988 1988 dprintk("%s ino %lu sync %d req %zu@%llu DS: %s cl_count %d vers %d\n", 1989 1989 __func__, hdr->inode->i_ino, sync, (size_t) hdr->args.count, ··· 1994 1994 refcount_inc(&ds->ds_clp->cl_count); 1995 1995 hdr->ds_clp = ds->ds_clp; 1996 1996 hdr->ds_commit_idx = idx; 1997 - fh = nfs4_ff_layout_select_ds_fh(mirror); 1997 + fh = nfs4_ff_layout_select_ds_fh(mirror, 0); 1998 1998 if (fh) 1999 1999 hdr->args.fh = fh; 2000 2000 2001 - nfs4_ff_layout_select_ds_stateid(mirror, &hdr->args.stateid); 2001 + nfs4_ff_layout_select_ds_stateid(mirror, 0, &hdr->args.stateid); 2002 2002 2003 2003 /* 2004 2004 * Note that if we ever decide to split across DSes, ··· 2007 2007 hdr->args.offset = offset; 2008 2008 2009 2009 /* Start IO accounting for local write */ 2010 - localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, 2010 + localio = ff_local_open_fh(lseg, idx, 0, ds->ds_clp, ds_cred, fh, 2011 2011 FMODE_READ|FMODE_WRITE); 2012 2012 if (localio) { 2013 2013 hdr->task.tk_start = ktime_get(); ··· 2065 2065 2066 2066 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); 2067 2067 mirror = FF_LAYOUT_COMP(lseg, idx); 2068 - ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true); 2068 + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, 0, true); 2069 2069 if (IS_ERR(ds)) 2070 2070 goto out_err; 2071 2071 2072 2072 ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, 2073 - data->inode); 2073 + data->inode, 0); 2074 2074 if (IS_ERR(ds_clnt)) 2075 2075 goto out_err; 2076 2076 2077 - ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, data->cred); 2077 + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, data->cred, 0); 2078 2078 if (!ds_cred) 2079 2079 goto out_err; 2080 2080 2081 - vers = nfs4_ff_layout_ds_version(mirror); 2081 + vers = nfs4_ff_layout_ds_version(mirror, 0); 2082 2082 2083 2083 dprintk("%s ino %lu, how %d cl_count %d vers %d\n", __func__, 2084 2084 data->inode->i_ino, how, refcount_read(&ds->ds_clp->cl_count), ··· 2092 2092 data->args.fh = fh; 2093 2093 2094 2094 /* Start IO accounting for local commit */ 2095 - localio = ff_local_open_fh(lseg, idx, ds->ds_clp, ds_cred, fh, 2095 + localio = ff_local_open_fh(lseg, idx, 0, ds->ds_clp, ds_cred, fh, 2096 2096 FMODE_READ|FMODE_WRITE); 2097 2097 if (localio) { 2098 2098 data->task.tk_start = ktime_get();
+28 -11
fs/nfs/flexfilelayout/flexfilelayout.h
··· 157 157 } 158 158 159 159 static inline struct nfs4_deviceid_node * 160 - FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx) 160 + FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx, u32 dss_id) 161 161 { 162 162 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, idx); 163 163 164 164 if (mirror != NULL) { 165 - struct nfs4_ff_layout_ds *mirror_ds = mirror->dss[0].mirror_ds; 165 + struct nfs4_ff_layout_ds *mirror_ds = mirror->dss[dss_id].mirror_ds; 166 166 167 167 if (!IS_ERR_OR_NULL(mirror_ds)) 168 168 return &mirror_ds->id_node; ··· 189 189 } 190 190 191 191 static inline int 192 - nfs4_ff_layout_ds_version(const struct nfs4_ff_layout_mirror *mirror) 192 + nfs4_ff_layout_ds_version(const struct nfs4_ff_layout_mirror *mirror, u32 dss_id) 193 193 { 194 - return mirror->dss[0].mirror_ds->ds_versions[0].version; 194 + return mirror->dss[dss_id].mirror_ds->ds_versions[0].version; 195 + } 196 + 197 + static inline u32 198 + nfs4_ff_layout_calc_dss_id(const u64 stripe_unit, const u32 dss_count, const loff_t offset) 199 + { 200 + u64 tmp = offset; 201 + 202 + if (dss_count == 1 || stripe_unit == 0) 203 + return 0; 204 + 205 + do_div(tmp, stripe_unit); 206 + 207 + return do_div(tmp, dss_count); 195 208 } 196 209 197 210 struct nfs4_ff_layout_ds * ··· 213 200 void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds); 214 201 void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds); 215 202 int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo, 216 - struct nfs4_ff_layout_mirror *mirror, u64 offset, 217 - u64 length, int status, enum nfs_opnum4 opnum, 218 - gfp_t gfp_flags); 203 + struct nfs4_ff_layout_mirror *mirror, 204 + u32 dss_id, u64 offset, u64 length, int status, 205 + enum nfs_opnum4 opnum, gfp_t gfp_flags); 219 206 void ff_layout_send_layouterror(struct pnfs_layout_segment *lseg); 220 207 int ff_layout_encode_ds_ioerr(struct xdr_stream *xdr, const struct list_head *head); 221 208 void ff_layout_free_ds_ioerr(struct list_head *head); ··· 224 211 struct list_head *head, 225 212 unsigned int maxnum); 226 213 struct nfs_fh * 227 - nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror); 214 + nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror, u32 dss_id); 228 215 void 229 216 nfs4_ff_layout_select_ds_stateid(const struct nfs4_ff_layout_mirror *mirror, 230 - nfs4_stateid *stateid); 217 + u32 dss_id, 218 + nfs4_stateid *stateid); 231 219 232 220 struct nfs4_pnfs_ds * 233 221 nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, 234 222 struct nfs4_ff_layout_mirror *mirror, 223 + u32 dss_id, 235 224 bool fail_return); 236 225 237 226 struct rpc_clnt * 238 227 nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror, 239 228 struct nfs_client *ds_clp, 240 - struct inode *inode); 229 + struct inode *inode, 230 + u32 dss_id); 241 231 const struct cred *ff_layout_get_ds_cred(struct nfs4_ff_layout_mirror *mirror, 242 232 const struct pnfs_layout_range *range, 243 - const struct cred *mdscred); 233 + const struct cred *mdscred, 234 + u32 dss_id); 244 235 bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment *lseg); 245 236 bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment *lseg); 246 237
+59 -46
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 250 250 } 251 251 252 252 int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo, 253 - struct nfs4_ff_layout_mirror *mirror, u64 offset, 254 - u64 length, int status, enum nfs_opnum4 opnum, 255 - gfp_t gfp_flags) 253 + struct nfs4_ff_layout_mirror *mirror, 254 + u32 dss_id, u64 offset, u64 length, int status, 255 + enum nfs_opnum4 opnum, gfp_t gfp_flags) 256 256 { 257 257 struct nfs4_ff_layout_ds_err *dserr; 258 258 259 259 if (status == 0) 260 260 return 0; 261 261 262 - if (IS_ERR_OR_NULL(mirror->dss[0].mirror_ds)) 262 + if (IS_ERR_OR_NULL(mirror->dss[dss_id].mirror_ds)) 263 263 return -EINVAL; 264 264 265 265 dserr = kmalloc(sizeof(*dserr), gfp_flags); ··· 271 271 dserr->length = length; 272 272 dserr->status = status; 273 273 dserr->opnum = opnum; 274 - nfs4_stateid_copy(&dserr->stateid, &mirror->dss[0].stateid); 275 - memcpy(&dserr->deviceid, &mirror->dss[0].mirror_ds->id_node.deviceid, 274 + nfs4_stateid_copy(&dserr->stateid, &mirror->dss[dss_id].stateid); 275 + memcpy(&dserr->deviceid, &mirror->dss[dss_id].mirror_ds->id_node.deviceid, 276 276 NFS4_DEVICEID4_SIZE); 277 277 278 278 spin_lock(&flo->generic_hdr.plh_inode->i_lock); ··· 282 282 } 283 283 284 284 static const struct cred * 285 - ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode) 285 + ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode, u32 dss_id) 286 286 { 287 287 const struct cred *cred, __rcu **pcred; 288 288 289 289 if (iomode == IOMODE_READ) 290 - pcred = &mirror->dss[0].ro_cred; 290 + pcred = &mirror->dss[dss_id].ro_cred; 291 291 else 292 - pcred = &mirror->dss[0].rw_cred; 292 + pcred = &mirror->dss[dss_id].rw_cred; 293 293 294 294 rcu_read_lock(); 295 295 do { ··· 304 304 } 305 305 306 306 struct nfs_fh * 307 - nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror) 307 + nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror, u32 dss_id) 308 308 { 309 309 /* FIXME: For now assume there is only 1 version available for the DS */ 310 - return &mirror->dss[0].fh_versions[0]; 310 + return &mirror->dss[dss_id].fh_versions[0]; 311 311 } 312 312 313 313 void 314 314 nfs4_ff_layout_select_ds_stateid(const struct nfs4_ff_layout_mirror *mirror, 315 - nfs4_stateid *stateid) 315 + u32 dss_id, 316 + nfs4_stateid *stateid) 316 317 { 317 - if (nfs4_ff_layout_ds_version(mirror) == 4) 318 - nfs4_stateid_copy(stateid, &mirror->dss[0].stateid); 318 + if (nfs4_ff_layout_ds_version(mirror, dss_id) == 4) 319 + nfs4_stateid_copy(stateid, &mirror->dss[dss_id].stateid); 319 320 } 320 321 321 322 static bool 322 323 ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo, 323 - struct nfs4_ff_layout_mirror *mirror) 324 + struct nfs4_ff_layout_mirror *mirror, 325 + u32 dss_id) 324 326 { 325 327 if (mirror == NULL) 326 328 goto outerr; 327 - if (mirror->dss[0].mirror_ds == NULL) { 329 + if (mirror->dss[dss_id].mirror_ds == NULL) { 328 330 struct nfs4_deviceid_node *node; 329 331 struct nfs4_ff_layout_ds *mirror_ds = ERR_PTR(-ENODEV); 330 332 331 333 node = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), 332 - &mirror->dss[0].devid, lo->plh_lc_cred, 334 + &mirror->dss[dss_id].devid, lo->plh_lc_cred, 333 335 GFP_KERNEL); 334 336 if (node) 335 337 mirror_ds = FF_LAYOUT_MIRROR_DS(node); 336 338 337 339 /* check for race with another call to this function */ 338 - if (cmpxchg(&mirror->dss[0].mirror_ds, NULL, mirror_ds) && 340 + if (cmpxchg(&mirror->dss[dss_id].mirror_ds, NULL, mirror_ds) && 339 341 mirror_ds != ERR_PTR(-ENODEV)) 340 342 nfs4_put_deviceid_node(node); 341 343 } 342 344 343 - if (IS_ERR(mirror->dss[0].mirror_ds)) 345 + if (IS_ERR(mirror->dss[dss_id].mirror_ds)) 344 346 goto outerr; 345 347 346 348 return true; ··· 354 352 * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call 355 353 * @lseg: the layout segment we're operating on 356 354 * @mirror: layout mirror describing the DS to use 355 + * @dss_id: DS stripe id to select stripe to use 357 356 * @fail_return: return layout on connect failure? 358 357 * 359 358 * Try to prepare a DS connection to accept an RPC call. This involves ··· 371 368 struct nfs4_pnfs_ds * 372 369 nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, 373 370 struct nfs4_ff_layout_mirror *mirror, 371 + u32 dss_id, 374 372 bool fail_return) 375 373 { 376 374 struct nfs4_pnfs_ds *ds; ··· 380 376 unsigned int max_payload; 381 377 int status = -EAGAIN; 382 378 383 - if (!ff_layout_init_mirror_ds(lseg->pls_layout, mirror)) 379 + if (!ff_layout_init_mirror_ds(lseg->pls_layout, mirror, dss_id)) 384 380 goto noconnect; 385 381 386 - ds = mirror->dss[0].mirror_ds->ds; 382 + ds = mirror->dss[dss_id].mirror_ds->ds; 387 383 if (READ_ONCE(ds->ds_clp)) 388 384 goto out; 389 385 /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */ ··· 392 388 /* FIXME: For now we assume the server sent only one version of NFS 393 389 * to use for the DS. 394 390 */ 395 - status = nfs4_pnfs_ds_connect(s, ds, &mirror->dss[0].mirror_ds->id_node, 391 + status = nfs4_pnfs_ds_connect(s, ds, &mirror->dss[dss_id].mirror_ds->id_node, 396 392 dataserver_timeo, dataserver_retrans, 397 - mirror->dss[0].mirror_ds->ds_versions[0].version, 398 - mirror->dss[0].mirror_ds->ds_versions[0].minor_version); 393 + mirror->dss[dss_id].mirror_ds->ds_versions[0].version, 394 + mirror->dss[dss_id].mirror_ds->ds_versions[0].minor_version); 399 395 400 396 /* connect success, check rsize/wsize limit */ 401 397 if (!status) { ··· 408 404 max_payload = 409 405 nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient), 410 406 NULL); 411 - if (mirror->dss[0].mirror_ds->ds_versions[0].rsize > max_payload) 412 - mirror->dss[0].mirror_ds->ds_versions[0].rsize = max_payload; 413 - if (mirror->dss[0].mirror_ds->ds_versions[0].wsize > max_payload) 414 - mirror->dss[0].mirror_ds->ds_versions[0].wsize = max_payload; 407 + if (mirror->dss[dss_id].mirror_ds->ds_versions[0].rsize > max_payload) 408 + mirror->dss[dss_id].mirror_ds->ds_versions[0].rsize = max_payload; 409 + if (mirror->dss[dss_id].mirror_ds->ds_versions[0].wsize > max_payload) 410 + mirror->dss[dss_id].mirror_ds->ds_versions[0].wsize = max_payload; 415 411 goto out; 416 412 } 417 413 noconnect: 418 414 ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), 419 - mirror, lseg->pls_range.offset, 415 + mirror, dss_id, lseg->pls_range.offset, 420 416 lseg->pls_range.length, NFS4ERR_NXIO, 421 417 OP_ILLEGAL, GFP_NOIO); 422 418 ff_layout_send_layouterror(lseg); ··· 430 426 const struct cred * 431 427 ff_layout_get_ds_cred(struct nfs4_ff_layout_mirror *mirror, 432 428 const struct pnfs_layout_range *range, 433 - const struct cred *mdscred) 429 + const struct cred *mdscred, 430 + u32 dss_id) 434 431 { 435 432 const struct cred *cred; 436 433 437 - if (mirror && !mirror->dss[0].mirror_ds->ds_versions[0].tightly_coupled) { 438 - cred = ff_layout_get_mirror_cred(mirror, range->iomode); 434 + if (mirror && !mirror->dss[dss_id].mirror_ds->ds_versions[0].tightly_coupled) { 435 + cred = ff_layout_get_mirror_cred(mirror, range->iomode, dss_id); 439 436 if (!cred) 440 437 cred = get_cred(mdscred); 441 438 } else { ··· 450 445 * @mirror: pointer to the mirror 451 446 * @ds_clp: nfs_client for the DS 452 447 * @inode: pointer to inode 448 + * @dss_id: DS stripe id 453 449 * 454 450 * Find or create a DS rpc client with th MDS server rpc client auth flavor 455 451 * in the nfs_client cl_ds_clients list. 456 452 */ 457 453 struct rpc_clnt * 458 454 nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror, 459 - struct nfs_client *ds_clp, struct inode *inode) 455 + struct nfs_client *ds_clp, struct inode *inode, 456 + u32 dss_id) 460 457 { 461 - switch (mirror->dss[0].mirror_ds->ds_versions[0].version) { 458 + switch (mirror->dss[dss_id].mirror_ds->ds_versions[0].version) { 462 459 case 3: 463 460 /* For NFSv3 DS, flavor is set when creating DS connections */ 464 461 return ds_clp->cl_rpcclient; ··· 566 559 { 567 560 struct nfs4_ff_layout_mirror *mirror; 568 561 struct nfs4_deviceid_node *devid; 569 - u32 idx; 562 + u32 idx, dss_id; 570 563 571 564 for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) { 572 565 mirror = FF_LAYOUT_COMP(lseg, idx); 573 - if (mirror) { 574 - if (!mirror->dss[0].mirror_ds) 566 + if (!mirror) 567 + continue; 568 + for (dss_id = 0; dss_id < mirror->dss_count; dss_id++) { 569 + if (!mirror->dss[dss_id].mirror_ds) 575 570 return true; 576 - if (IS_ERR(mirror->dss[0].mirror_ds)) 571 + if (IS_ERR(mirror->dss[dss_id].mirror_ds)) 577 572 continue; 578 - devid = &mirror->dss[0].mirror_ds->id_node; 573 + devid = &mirror->dss[dss_id].mirror_ds->id_node; 579 574 if (!nfs4_test_deviceid_unavailable(devid)) 580 575 return true; 581 576 } ··· 590 581 { 591 582 struct nfs4_ff_layout_mirror *mirror; 592 583 struct nfs4_deviceid_node *devid; 593 - u32 idx; 584 + u32 idx, dss_id; 594 585 595 586 for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) { 596 587 mirror = FF_LAYOUT_COMP(lseg, idx); 597 - if (!mirror || IS_ERR(mirror->dss[0].mirror_ds)) 588 + if (!mirror) 598 589 return false; 599 - if (!mirror->dss[0].mirror_ds) 600 - continue; 601 - devid = &mirror->dss[0].mirror_ds->id_node; 602 - if (nfs4_test_deviceid_unavailable(devid)) 603 - return false; 590 + for (dss_id = 0; dss_id < mirror->dss_count; dss_id++) { 591 + if (IS_ERR(mirror->dss[dss_id].mirror_ds)) 592 + return false; 593 + if (!mirror->dss[dss_id].mirror_ds) 594 + continue; 595 + devid = &mirror->dss[dss_id].mirror_ds->id_node; 596 + if (nfs4_test_deviceid_unavailable(devid)) 597 + return false; 598 + } 604 599 } 605 600 606 601 return FF_LAYOUT_MIRROR_COUNT(lseg) != 0;