|
@@ -516,3 +516,70 @@ nfs4_fl_find_get_deviceid(struct nfs_client *clp, struct nfs4_deviceid *id)
|
|
return (d == NULL) ? NULL :
|
|
return (d == NULL) ? NULL :
|
|
container_of(d, struct nfs4_file_layout_dsaddr, deviceid);
|
|
container_of(d, struct nfs4_file_layout_dsaddr, deviceid);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Want res = (offset - layout->pattern_offset)/ layout->stripe_unit
|
|
|
|
+ * Then: ((res + fsi) % dsaddr->stripe_count)
|
|
|
|
+ */
|
|
|
|
+u32
|
|
|
|
+nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset)
|
|
|
|
+{
|
|
|
|
+ struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
|
|
|
|
+ u64 tmp;
|
|
|
|
+
|
|
|
|
+ tmp = offset - flseg->pattern_offset;
|
|
|
|
+ do_div(tmp, flseg->stripe_unit);
|
|
|
|
+ tmp += flseg->first_stripe_index;
|
|
|
|
+ return do_div(tmp, flseg->dsaddr->stripe_count);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+u32
|
|
|
|
+nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j)
|
|
|
|
+{
|
|
|
|
+ return FILELAYOUT_LSEG(lseg)->dsaddr->stripe_indices[j];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+struct nfs_fh *
|
|
|
|
+nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j)
|
|
|
|
+{
|
|
|
|
+ struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
|
|
|
|
+ u32 i;
|
|
|
|
+
|
|
|
|
+ if (flseg->stripe_type == STRIPE_SPARSE) {
|
|
|
|
+ if (flseg->num_fh == 1)
|
|
|
|
+ i = 0;
|
|
|
|
+ else if (flseg->num_fh == 0)
|
|
|
|
+ /* Use the MDS OPEN fh set in nfs_read_rpcsetup */
|
|
|
|
+ return NULL;
|
|
|
|
+ else
|
|
|
|
+ i = nfs4_fl_calc_ds_index(lseg, j);
|
|
|
|
+ } else
|
|
|
|
+ i = j;
|
|
|
|
+ return flseg->fh_array[i];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+struct nfs4_pnfs_ds *
|
|
|
|
+nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
|
|
|
|
+{
|
|
|
|
+ struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
|
|
|
|
+ struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
|
|
|
|
+
|
|
|
|
+ if (ds == NULL) {
|
|
|
|
+ printk(KERN_ERR "%s: No data server for offset index %d\n",
|
|
|
|
+ __func__, ds_idx);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!ds->ds_clp) {
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ err = nfs4_ds_connect(NFS_SERVER(lseg->pls_layout->plh_inode),
|
|
|
|
+ dsaddr->ds_list[ds_idx]);
|
|
|
|
+ if (err) {
|
|
|
|
+ printk(KERN_ERR "%s nfs4_ds_connect error %d\n",
|
|
|
|
+ __func__, err);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ds;
|
|
|
|
+}
|