From: Andy Adamson <andros@xxxxxxxxxx> Export nfsd4_pnfs_dlm_layoutget for dlm cluster file system use. Use the number of data servers as a hash mask and hash inode i_ino to choose the layout's first_stripe_index. Always give out whole file layouts. Always give out IOMODE_READ layouts. DLM locking semantics want to stripe only READs with WRITEs going through the MDS. [was pnfsd: hardwire DLM file layout layoutget] [was pnfs-gfs2: initial LAYOUT* work for pNFS/GFS2 integration] Frank Filz's work on the layout_type() and layout_get() export operations, with stubs for layout_commit() and layout_return(). Tested at Connectathon. Signed-off-by: Frank Filz <ffilzlnx@xxxxxxxxxx> Signed-off-by: David M. Richter <richterd@xxxxxxxxxxxxxx> [pnfs-gfs2: convert to using new pnfs export api] Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> [pnfsd: gfs2 layout_type interface] Signed-off-by: Marc Eshel <eshel@xxxxxxxxxxxxxxx> [Since GFS2 only uses a stripe of one, changed lg_commit_through_mds from true to false.] [pnfsd: move and rename nfsd4_pnfs_fl_layoutget] Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> [pnfsd: get rid of layout encoding function vector] Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> Acked-by: Steven Whitehouse <swhiteho@xxxxxxxxxx> [pnfsd: rename deviceid_t struct pnfs_deviceid] [pnfsd: clean up layoutget export API] [add requried headers] [pnfsd: rename device fsid member to sbid] [pnfsd: fixup DLM layout_get return type to u32] [pnfsd: DLM file layout return only nfs errors on layout_get] [pnfsd: files layout: change layout_get return type to enum nfsstat4] Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> [pnfsd: fix DLM file layout no device return] Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> [pnfsd: dlm: fixup LAYOUT_NFSV4_1_FILES] Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxxxxxx> --- fs/nfsd/nfs4pnfsdlm.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/fs/nfsd/nfs4pnfsdlm.c b/fs/nfsd/nfs4pnfsdlm.c index 4c2ab87..7ed8156 100644 --- a/fs/nfsd/nfs4pnfsdlm.c +++ b/fs/nfsd/nfs4pnfsdlm.c @@ -28,6 +28,7 @@ #include <linux/nfsd/nfs4layoutxdr.h> #include <linux/sunrpc/addr.h> +#include "nfsfh.h" #include "nfsd.h" #define NFSDDBG_FACILITY NFSDDBG_FILELAYOUT @@ -351,9 +352,100 @@ static int nfsd4_pnfs_dlm_getdevinfo(struct super_block *sb, return err; } +static int get_stripe_unit(int blocksize) +{ + if (blocksize >= NFSSVC_MAXBLKSIZE) + return blocksize; + return NFSSVC_MAXBLKSIZE - (NFSSVC_MAXBLKSIZE % blocksize); +} + +/* + * Look up inode block device in pnfs_dlm_device list. + * Hash on the inode->i_ino and number of data servers. + */ +static int dlm_ino_hash(struct inode *ino) +{ + struct dlm_device_entry *de; + u32 hash_mask = 0; + + /* If can't find the inode block device in the pnfs_dlm_deivce list + * then don't hand out a layout + */ + de = nfsd4_find_pnfs_dlm_device(ino->i_sb); + if (!de) + return -1; + hash_mask = de->num_ds - 1; + return ino->i_ino & hash_mask; +} + +static enum nfsstat4 nfsd4_pnfs_dlm_layoutget(struct inode *inode, + struct exp_xdr_stream *xdr, + const struct nfsd4_pnfs_layoutget_arg *args, + struct nfsd4_pnfs_layoutget_res *res) +{ + struct pnfs_filelayout_layout *layout = NULL; + struct knfsd_fh *fhp = NULL; + int index; + enum nfsstat4 rc = NFS4_OK; + + dprintk("%s: LAYOUT_GET\n", __func__); + + index = dlm_ino_hash(inode); + dprintk("%s first stripe index %d i_ino %lu\n", __func__, index, + inode->i_ino); + if (index < 0) + return NFS4ERR_LAYOUTUNAVAILABLE; + + res->lg_seg.layout_type = LAYOUT_NFSV4_1_FILES; + /* Always give out whole file layouts */ + res->lg_seg.offset = 0; + res->lg_seg.length = NFS4_MAX_UINT64; + /* Always give out READ ONLY layouts */ + res->lg_seg.iomode = IOMODE_READ; + + layout = kzalloc(sizeof(*layout), GFP_KERNEL); + if (layout == NULL) { + rc = NFS4ERR_LAYOUTTRYLATER; + goto error; + } + + /* Set file layout response args */ + layout->lg_layout_type = LAYOUT_NFSV4_1_FILES; + layout->lg_stripe_type = STRIPE_SPARSE; + layout->lg_commit_through_mds = false; + layout->lg_stripe_unit = get_stripe_unit(inode->i_sb->s_blocksize); + layout->lg_fh_length = 1; + layout->device_id.sbid = args->lg_sbid; + layout->device_id.devid = 1; /*FSFTEMP*/ + layout->lg_first_stripe_index = index; /*FSFTEMP*/ + layout->lg_pattern_offset = 0; + + fhp = kmalloc(sizeof(*fhp), GFP_KERNEL); + if (fhp == NULL) { + rc = NFS4ERR_LAYOUTTRYLATER; + goto error; + } + + memcpy(fhp, args->lg_fh, sizeof(*fhp)); + pnfs_fh_mark_ds(fhp); + layout->lg_fh_list = fhp; + + /* Call nfsd to encode layout */ + rc = filelayout_encode_layout(xdr, layout); +exit: + kfree(layout); + kfree(fhp); + return rc; + +error: + res->lg_seg.length = 0; + goto exit; +} + /* For use by DLM cluster file systems exported by pNFSD */ const struct pnfs_export_operations pnfs_dlm_export_ops = { .get_device_info = nfsd4_pnfs_dlm_getdevinfo, .get_device_iter = nfsd4_pnfs_dlm_getdeviter, + .layout_get = nfsd4_pnfs_dlm_layoutget, }; EXPORT_SYMBOL(pnfs_dlm_export_ops); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html