#if IS_ENABLED(CONFIG_NFS_LOCALIO)
struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
- return nfs_local_open_fh(clp, cred, fh, &mirror->nfl, mode);
+ return nfs_local_open_fh(clp, cred, fh, &mirror->dss[0].nfl, mode);
#else
return NULL;
#endif
{
int i, j;
- if (m1->fh_versions_cnt != m2->fh_versions_cnt)
+ if (m1->dss[0].fh_versions_cnt != m2->dss[0].fh_versions_cnt)
return false;
- for (i = 0; i < m1->fh_versions_cnt; i++) {
+ for (i = 0; i < m1->dss[0].fh_versions_cnt; i++) {
bool found_fh = false;
- for (j = 0; j < m2->fh_versions_cnt; j++) {
- if (nfs_compare_fh(&m1->fh_versions[i],
- &m2->fh_versions[j]) == 0) {
+ for (j = 0; j < m2->dss[0].fh_versions_cnt; j++) {
+ if (nfs_compare_fh(&m1->dss[0].fh_versions[i],
+ &m2->dss[0].fh_versions[j]) == 0) {
found_fh = true;
break;
}
spin_lock(&inode->i_lock);
list_for_each_entry(pos, &ff_layout->mirrors, mirrors) {
- if (memcmp(&mirror->devid, &pos->devid, sizeof(pos->devid)) != 0)
+ if (memcmp(&mirror->dss[0].devid, &pos->dss[0].devid,
+ sizeof(pos->dss[0].devid)) != 0)
continue;
if (!ff_mirror_match_fh(mirror, pos))
continue;
spin_lock_init(&mirror->lock);
refcount_set(&mirror->ref, 1);
INIT_LIST_HEAD(&mirror->mirrors);
- nfs_localio_file_init(&mirror->nfl);
+ nfs_localio_file_init(&mirror->dss[0].nfl);
}
return mirror;
}
static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror)
{
- const struct cred *cred;
+ const struct cred *cred;
+ int dss_id = 0;
ff_layout_remove_mirror(mirror);
- kfree(mirror->fh_versions);
- nfs_close_local_fh(&mirror->nfl);
- cred = rcu_access_pointer(mirror->ro_cred);
+
+ kfree(mirror->dss[dss_id].fh_versions);
+ nfs_close_local_fh(&mirror->dss[dss_id].nfl);
+ cred = rcu_access_pointer(mirror->dss[dss_id].ro_cred);
put_cred(cred);
- cred = rcu_access_pointer(mirror->rw_cred);
+ cred = rcu_access_pointer(mirror->dss[dss_id].rw_cred);
put_cred(cred);
- nfs4_ff_layout_put_deviceid(mirror->mirror_ds);
+ nfs4_ff_layout_put_deviceid(mirror->dss[dss_id].mirror_ds);
+
+ kfree(mirror->dss);
kfree(mirror);
}
for (i = 0; i < fls->mirror_array_cnt - 1; i++) {
for (j = i + 1; j < fls->mirror_array_cnt; j++)
- if (fls->mirror_array[i]->efficiency <
- fls->mirror_array[j]->efficiency)
+ if (fls->mirror_array[i]->dss[0].efficiency <
+ fls->mirror_array[j]->dss[0].efficiency)
swap(fls->mirror_array[i],
fls->mirror_array[j]);
}
fls->mirror_array_cnt = mirror_array_cnt;
fls->stripe_unit = stripe_unit;
+ u32 dss_count = 0;
for (i = 0; i < fls->mirror_array_cnt; i++) {
struct nfs4_ff_layout_mirror *mirror;
struct cred *kcred;
const struct cred __rcu *cred;
kuid_t uid;
kgid_t gid;
- u32 ds_count, fh_count, id;
- int j;
+ u32 fh_count, id;
+ int j, dss_id = 0;
rc = -EIO;
p = xdr_inline_decode(&stream, 4);
if (!p)
goto out_err_free;
- ds_count = be32_to_cpup(p);
+
+ dss_count = be32_to_cpup(p);
/* FIXME: allow for striping? */
- if (ds_count != 1)
+ if (dss_count != 1)
goto out_err_free;
fls->mirror_array[i] = ff_layout_alloc_mirror(gfp_flags);
goto out_err_free;
}
- fls->mirror_array[i]->ds_count = ds_count;
+ fls->mirror_array[i]->dss_count = dss_count;
+ fls->mirror_array[i]->dss =
+ kcalloc(dss_count, sizeof(struct nfs4_ff_layout_ds_stripe),
+ gfp_flags);
/* deviceid */
- rc = decode_deviceid(&stream, &fls->mirror_array[i]->devid);
+ rc = decode_deviceid(&stream, &fls->mirror_array[i]->dss[dss_id].devid);
if (rc)
goto out_err_free;
p = xdr_inline_decode(&stream, 4);
if (!p)
goto out_err_free;
- fls->mirror_array[i]->efficiency = be32_to_cpup(p);
+ fls->mirror_array[i]->dss[dss_id].efficiency = be32_to_cpup(p);
/* stateid */
- rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->stateid);
+ rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->dss[dss_id].stateid);
if (rc)
goto out_err_free;
goto out_err_free;
fh_count = be32_to_cpup(p);
- fls->mirror_array[i]->fh_versions =
- kcalloc(fh_count, sizeof(struct nfs_fh),
- gfp_flags);
- if (fls->mirror_array[i]->fh_versions == NULL) {
+ fls->mirror_array[i]->dss[dss_id].fh_versions =
+ kcalloc(fh_count, sizeof(struct nfs_fh),
+ gfp_flags);
+ if (fls->mirror_array[i]->dss[dss_id].fh_versions == NULL) {
rc = -ENOMEM;
goto out_err_free;
}
for (j = 0; j < fh_count; j++) {
rc = decode_nfs_fh(&stream,
- &fls->mirror_array[i]->fh_versions[j]);
+ &fls->mirror_array[i]->dss[dss_id].fh_versions[j]);
if (rc)
goto out_err_free;
}
- fls->mirror_array[i]->fh_versions_cnt = fh_count;
+ fls->mirror_array[i]->dss[dss_id].fh_versions_cnt = fh_count;
/* user */
rc = decode_name(&stream, &id);
cred = RCU_INITIALIZER(kcred);
if (lgr->range.iomode == IOMODE_READ)
- rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
+ rcu_assign_pointer(fls->mirror_array[i]->dss[dss_id].ro_cred, cred);
else
- rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
+ rcu_assign_pointer(fls->mirror_array[i]->dss[dss_id].rw_cred, cred);
mirror = ff_layout_add_mirror(lh, fls->mirror_array[i]);
if (mirror != fls->mirror_array[i]) {
/* swap cred ptrs so free_mirror will clean up old */
if (lgr->range.iomode == IOMODE_READ) {
- cred = xchg(&mirror->ro_cred, fls->mirror_array[i]->ro_cred);
- rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
+ cred = xchg(&mirror->dss[dss_id].ro_cred,
+ fls->mirror_array[i]->dss[dss_id].ro_cred);
+ rcu_assign_pointer(fls->mirror_array[i]->dss[dss_id].ro_cred, cred);
} else {
- cred = xchg(&mirror->rw_cred, fls->mirror_array[i]->rw_cred);
- rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
+ cred = xchg(&mirror->dss[dss_id].rw_cred,
+ fls->mirror_array[i]->dss[dss_id].rw_cred);
+ rcu_assign_pointer(fls->mirror_array[i]->dss[dss_id].rw_cred, cred);
}
ff_layout_free_mirror(fls->mirror_array[i]);
fls->mirror_array[i] = mirror;
struct nfs4_flexfile_layout *ffl = FF_LAYOUT_FROM_HDR(mirror->layout);
nfs4_ff_start_busy_timer(&layoutstat->busy_timer, now);
- if (!mirror->start_time)
- mirror->start_time = now;
+ if (!mirror->dss[0].start_time)
+ mirror->dss[0].start_time = now;
if (mirror->report_interval != 0)
report_interval = (s64)mirror->report_interval * 1000LL;
else if (layoutstats_timer != 0)
bool report;
spin_lock(&mirror->lock);
- report = nfs4_ff_layoutstat_start_io(mirror, &mirror->read_stat, now);
- nfs4_ff_layout_stat_io_update_requested(&mirror->read_stat, requested);
+ report = nfs4_ff_layoutstat_start_io(mirror, &mirror->dss[0].read_stat, now);
+ nfs4_ff_layout_stat_io_update_requested(&mirror->dss[0].read_stat, requested);
set_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags);
spin_unlock(&mirror->lock);
__u64 completed)
{
spin_lock(&mirror->lock);
- nfs4_ff_layout_stat_io_update_completed(&mirror->read_stat,
+ nfs4_ff_layout_stat_io_update_completed(&mirror->dss[0].read_stat,
requested, completed,
ktime_get(), task->tk_start);
set_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags);
bool report;
spin_lock(&mirror->lock);
- report = nfs4_ff_layoutstat_start_io(mirror , &mirror->write_stat, now);
- nfs4_ff_layout_stat_io_update_requested(&mirror->write_stat, requested);
+ report = nfs4_ff_layoutstat_start_io(mirror, &mirror->dss[0].write_stat, now);
+ nfs4_ff_layout_stat_io_update_requested(&mirror->dss[0].write_stat, requested);
set_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags);
spin_unlock(&mirror->lock);
requested = completed = 0;
spin_lock(&mirror->lock);
- nfs4_ff_layout_stat_io_update_completed(&mirror->write_stat,
+ nfs4_ff_layout_stat_io_update_completed(&mirror->dss[0].write_stat,
requested, completed, ktime_get(), task->tk_start);
set_bit(NFS4_FF_MIRROR_STAT_AVAIL, &mirror->flags);
spin_unlock(&mirror->lock);
continue;
if (check_device &&
- nfs4_test_deviceid_unavailable(&mirror->mirror_ds->id_node)) {
+ nfs4_test_deviceid_unavailable(&mirror->dss[0].mirror_ds->id_node)) {
// reinitialize the error state in case if this is the last iteration
ds = ERR_PTR(-EINVAL);
continue;
mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx);
pgm = &pgio->pg_mirrors[0];
- pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
+ pgm->pg_bsize = mirror->dss[0].mirror_ds->ds_versions[0].rsize;
pgio->pg_mirror_idx = ds_idx;
return;
goto retry;
}
pgm = &pgio->pg_mirrors[i];
- pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize;
+ pgm->pg_bsize = mirror->dss[0].mirror_ds->ds_versions[0].wsize;
}
if (NFS_SERVER(pgio->pg_inode)->flags &
/* FIXME: Assume that there is only one NFS version available
* for the DS.
*/
- return &flseg->mirror_array[i]->fh_versions[0];
+ return &flseg->mirror_array[i]->dss[0].fh_versions[0];
}
static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
mirror = flseg->mirror_array[idx];
- mirror_ds = mirror->mirror_ds;
+ mirror_ds = mirror->dss[0].mirror_ds;
if (IS_ERR_OR_NULL(mirror_ds))
continue;
- ds = mirror->mirror_ds->ds;
+ ds = mirror->dss[0].mirror_ds->ds;
if (!ds)
continue;
ds_clp = ds->ds_clp;
struct nfs4_ff_layout_mirror *mirror)
{
struct nfs4_pnfs_ds_addr *da;
- struct nfs4_pnfs_ds *ds = mirror->mirror_ds->ds;
- struct nfs_fh *fh = &mirror->fh_versions[0];
+ struct nfs4_pnfs_ds *ds = mirror->dss[0].mirror_ds->ds;
+ struct nfs_fh *fh = &mirror->dss[0].fh_versions[0];
__be32 *p;
da = list_first_entry(&ds->ds_addrs, struct nfs4_pnfs_ds_addr, da_node);
xdr_encode_opaque(p, fh->data, fh->size);
/* ff_io_latency4 read */
spin_lock(&mirror->lock);
- ff_layout_encode_io_latency(xdr, &mirror->read_stat.io_stat);
+ ff_layout_encode_io_latency(xdr, &mirror->dss[0].read_stat.io_stat);
/* ff_io_latency4 write */
- ff_layout_encode_io_latency(xdr, &mirror->write_stat.io_stat);
+ ff_layout_encode_io_latency(xdr, &mirror->dss[0].write_stat.io_stat);
spin_unlock(&mirror->lock);
/* nfstime4 */
- ff_layout_encode_nfstime(xdr, ktime_sub(ktime_get(), mirror->start_time));
+ ff_layout_encode_nfstime(xdr, ktime_sub(ktime_get(), mirror->dss[0].start_time));
/* bool */
p = xdr_reserve_space(xdr, 4);
*p = cpu_to_be32(false);
list_for_each_entry(mirror, &ff_layout->mirrors, mirrors) {
if (i >= dev_limit)
break;
- if (IS_ERR_OR_NULL(mirror->mirror_ds))
+ if (IS_ERR_OR_NULL(mirror->dss[0].mirror_ds))
continue;
if (!test_and_clear_bit(NFS4_FF_MIRROR_STAT_AVAIL,
&mirror->flags) &&
/* mirror refcount put in cleanup_layoutstats */
if (!refcount_inc_not_zero(&mirror->ref))
continue;
- dev = &mirror->mirror_ds->id_node;
+ dev = &mirror->dss[0].mirror_ds->id_node;
memcpy(&devinfo->dev_id, &dev->deviceid, NFS4_DEVICEID4_SIZE);
devinfo->offset = 0;
devinfo->length = NFS4_MAX_UINT64;
spin_lock(&mirror->lock);
- devinfo->read_count = mirror->read_stat.io_stat.ops_completed;
- devinfo->read_bytes = mirror->read_stat.io_stat.bytes_completed;
- devinfo->write_count = mirror->write_stat.io_stat.ops_completed;
- devinfo->write_bytes = mirror->write_stat.io_stat.bytes_completed;
+ devinfo->read_count = mirror->dss[0].read_stat.io_stat.ops_completed;
+ devinfo->read_bytes = mirror->dss[0].read_stat.io_stat.bytes_completed;
+ devinfo->write_count = mirror->dss[0].write_stat.io_stat.ops_completed;
+ devinfo->write_bytes = mirror->dss[0].write_stat.io_stat.bytes_completed;
spin_unlock(&mirror->lock);
devinfo->layout_type = LAYOUT_FLEX_FILES;
devinfo->ld_private.ops = &layoutstat_ops;
if (status == 0)
return 0;
- if (IS_ERR_OR_NULL(mirror->mirror_ds))
+ if (IS_ERR_OR_NULL(mirror->dss[0].mirror_ds))
return -EINVAL;
dserr = kmalloc(sizeof(*dserr), gfp_flags);
dserr->length = length;
dserr->status = status;
dserr->opnum = opnum;
- nfs4_stateid_copy(&dserr->stateid, &mirror->stateid);
- memcpy(&dserr->deviceid, &mirror->mirror_ds->id_node.deviceid,
+ nfs4_stateid_copy(&dserr->stateid, &mirror->dss[0].stateid);
+ memcpy(&dserr->deviceid, &mirror->dss[0].mirror_ds->id_node.deviceid,
NFS4_DEVICEID4_SIZE);
spin_lock(&flo->generic_hdr.plh_inode->i_lock);
const struct cred *cred, __rcu **pcred;
if (iomode == IOMODE_READ)
- pcred = &mirror->ro_cred;
+ pcred = &mirror->dss[0].ro_cred;
else
- pcred = &mirror->rw_cred;
+ pcred = &mirror->dss[0].rw_cred;
rcu_read_lock();
do {
nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror)
{
/* FIXME: For now assume there is only 1 version available for the DS */
- return &mirror->fh_versions[0];
+ return &mirror->dss[0].fh_versions[0];
}
void
nfs4_stateid *stateid)
{
if (nfs4_ff_layout_ds_version(mirror) == 4)
- nfs4_stateid_copy(stateid, &mirror->stateid);
+ nfs4_stateid_copy(stateid, &mirror->dss[0].stateid);
}
static bool
{
if (mirror == NULL)
goto outerr;
- if (mirror->mirror_ds == NULL) {
+ if (mirror->dss[0].mirror_ds == NULL) {
struct nfs4_deviceid_node *node;
struct nfs4_ff_layout_ds *mirror_ds = ERR_PTR(-ENODEV);
node = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode),
- &mirror->devid, lo->plh_lc_cred,
+ &mirror->dss[0].devid, lo->plh_lc_cred,
GFP_KERNEL);
if (node)
mirror_ds = FF_LAYOUT_MIRROR_DS(node);
/* check for race with another call to this function */
- if (cmpxchg(&mirror->mirror_ds, NULL, mirror_ds) &&
+ if (cmpxchg(&mirror->dss[0].mirror_ds, NULL, mirror_ds) &&
mirror_ds != ERR_PTR(-ENODEV))
nfs4_put_deviceid_node(node);
}
- if (IS_ERR(mirror->mirror_ds))
+ if (IS_ERR(mirror->dss[0].mirror_ds))
goto outerr;
return true;
if (!ff_layout_init_mirror_ds(lseg->pls_layout, mirror))
goto noconnect;
- ds = mirror->mirror_ds->ds;
+ ds = mirror->dss[0].mirror_ds->ds;
if (READ_ONCE(ds->ds_clp))
goto out;
/* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
/* FIXME: For now we assume the server sent only one version of NFS
* to use for the DS.
*/
- status = nfs4_pnfs_ds_connect(s, ds, &mirror->mirror_ds->id_node,
+ status = nfs4_pnfs_ds_connect(s, ds, &mirror->dss[0].mirror_ds->id_node,
dataserver_timeo, dataserver_retrans,
- mirror->mirror_ds->ds_versions[0].version,
- mirror->mirror_ds->ds_versions[0].minor_version);
+ mirror->dss[0].mirror_ds->ds_versions[0].version,
+ mirror->dss[0].mirror_ds->ds_versions[0].minor_version);
/* connect success, check rsize/wsize limit */
if (!status) {
max_payload =
nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
NULL);
- if (mirror->mirror_ds->ds_versions[0].rsize > max_payload)
- mirror->mirror_ds->ds_versions[0].rsize = max_payload;
- if (mirror->mirror_ds->ds_versions[0].wsize > max_payload)
- mirror->mirror_ds->ds_versions[0].wsize = max_payload;
+ if (mirror->dss[0].mirror_ds->ds_versions[0].rsize > max_payload)
+ mirror->dss[0].mirror_ds->ds_versions[0].rsize = max_payload;
+ if (mirror->dss[0].mirror_ds->ds_versions[0].wsize > max_payload)
+ mirror->dss[0].mirror_ds->ds_versions[0].wsize = max_payload;
goto out;
}
noconnect:
{
const struct cred *cred;
- if (mirror && !mirror->mirror_ds->ds_versions[0].tightly_coupled) {
+ if (mirror && !mirror->dss[0].mirror_ds->ds_versions[0].tightly_coupled) {
cred = ff_layout_get_mirror_cred(mirror, range->iomode);
if (!cred)
cred = get_cred(mdscred);
nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror,
struct nfs_client *ds_clp, struct inode *inode)
{
- switch (mirror->mirror_ds->ds_versions[0].version) {
+ switch (mirror->dss[0].mirror_ds->ds_versions[0].version) {
case 3:
/* For NFSv3 DS, flavor is set when creating DS connections */
return ds_clp->cl_rpcclient;
for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) {
mirror = FF_LAYOUT_COMP(lseg, idx);
if (mirror) {
- if (!mirror->mirror_ds)
+ if (!mirror->dss[0].mirror_ds)
return true;
- if (IS_ERR(mirror->mirror_ds))
+ if (IS_ERR(mirror->dss[0].mirror_ds))
continue;
- devid = &mirror->mirror_ds->id_node;
+ devid = &mirror->dss[0].mirror_ds->id_node;
if (!nfs4_test_deviceid_unavailable(devid))
return true;
}
for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) {
mirror = FF_LAYOUT_COMP(lseg, idx);
- if (!mirror || IS_ERR(mirror->mirror_ds))
+ if (!mirror || IS_ERR(mirror->dss[0].mirror_ds))
return false;
- if (!mirror->mirror_ds)
+ if (!mirror->dss[0].mirror_ds)
continue;
- devid = &mirror->mirror_ds->id_node;
+ devid = &mirror->dss[0].mirror_ds->id_node;
if (nfs4_test_deviceid_unavailable(devid))
return false;
}