nfsd: allow nfsd to advertise multiple layout types

If the underlying filesystem supports multiple layout types, then there
is little reason not to advertise that fact to clients and let them
choose what type to use.

Turn the ex_layout_type field into a bitfield. For each supported
layout type, we set a bit in that field. When the client requests a
layout, ensure that the bit for that layout type is set. When the
client requests attributes, send back a list of supported types.

Signed-off-by: Jeff Layton <jlayton@poochiereds.net>
Reviewed-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Jeff Layton 2016-07-10 15:55:58 -04:00 коммит произвёл J. Bruce Fields
Родитель 885848186f
Коммит 8a4c392688
5 изменённых файлов: 22 добавлений и 24 удалений

Просмотреть файл

@ -706,7 +706,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
new->ex_fslocs.locations = NULL; new->ex_fslocs.locations = NULL;
new->ex_fslocs.locations_count = 0; new->ex_fslocs.locations_count = 0;
new->ex_fslocs.migrated = 0; new->ex_fslocs.migrated = 0;
new->ex_layout_type = 0; new->ex_layout_types = 0;
new->ex_uuid = NULL; new->ex_uuid = NULL;
new->cd = item->cd; new->cd = item->cd;
} }
@ -731,7 +731,7 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
item->ex_fslocs.locations_count = 0; item->ex_fslocs.locations_count = 0;
new->ex_fslocs.migrated = item->ex_fslocs.migrated; new->ex_fslocs.migrated = item->ex_fslocs.migrated;
item->ex_fslocs.migrated = 0; item->ex_fslocs.migrated = 0;
new->ex_layout_type = item->ex_layout_type; new->ex_layout_types = item->ex_layout_types;
new->ex_nflavors = item->ex_nflavors; new->ex_nflavors = item->ex_nflavors;
for (i = 0; i < MAX_SECINFO_LIST; i++) { for (i = 0; i < MAX_SECINFO_LIST; i++) {
new->ex_flavors[i] = item->ex_flavors[i]; new->ex_flavors[i] = item->ex_flavors[i];

Просмотреть файл

@ -57,7 +57,7 @@ struct svc_export {
struct nfsd4_fs_locations ex_fslocs; struct nfsd4_fs_locations ex_fslocs;
uint32_t ex_nflavors; uint32_t ex_nflavors;
struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST]; struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST];
enum pnfs_layouttype ex_layout_type; u32 ex_layout_types;
struct nfsd4_deviceid_map *ex_devid_map; struct nfsd4_deviceid_map *ex_devid_map;
struct cache_detail *cd; struct cache_detail *cd;
}; };

Просмотреть файл

@ -139,21 +139,21 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
* otherwise advertise the block layout. * otherwise advertise the block layout.
*/ */
#ifdef CONFIG_NFSD_FLEXFILELAYOUT #ifdef CONFIG_NFSD_FLEXFILELAYOUT
exp->ex_layout_type = LAYOUT_FLEX_FILES; exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
#endif #endif
#ifdef CONFIG_NFSD_BLOCKLAYOUT #ifdef CONFIG_NFSD_BLOCKLAYOUT
/* overwrite flex file layout selection if needed */ /* overwrite flex file layout selection if needed */
if (sb->s_export_op->get_uuid && if (sb->s_export_op->get_uuid &&
sb->s_export_op->map_blocks && sb->s_export_op->map_blocks &&
sb->s_export_op->commit_blocks) sb->s_export_op->commit_blocks)
exp->ex_layout_type = LAYOUT_BLOCK_VOLUME; exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
#endif #endif
#ifdef CONFIG_NFSD_SCSILAYOUT #ifdef CONFIG_NFSD_SCSILAYOUT
/* overwrite block layout selection if needed */ /* overwrite block layout selection if needed */
if (sb->s_export_op->map_blocks && if (sb->s_export_op->map_blocks &&
sb->s_export_op->commit_blocks && sb->s_export_op->commit_blocks &&
sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops) sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops)
exp->ex_layout_type = LAYOUT_SCSI; exp->ex_layout_types |= 1 << LAYOUT_SCSI;
#endif #endif
} }

Просмотреть файл

@ -1219,12 +1219,12 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
static const struct nfsd4_layout_ops * static const struct nfsd4_layout_ops *
nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type) nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)
{ {
if (!exp->ex_layout_type) { if (!exp->ex_layout_types) {
dprintk("%s: export does not support pNFS\n", __func__); dprintk("%s: export does not support pNFS\n", __func__);
return NULL; return NULL;
} }
if (exp->ex_layout_type != layout_type) { if (!(exp->ex_layout_types & (1 << layout_type))) {
dprintk("%s: layout type %d not supported\n", dprintk("%s: layout type %d not supported\n",
__func__, layout_type); __func__, layout_type);
return NULL; return NULL;

Просмотреть файл

@ -2162,22 +2162,20 @@ nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
} }
static inline __be32 static inline __be32
nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type) nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types)
{ {
__be32 *p; __be32 *p;
unsigned long i = hweight_long(layout_types);
if (layout_type) { p = xdr_reserve_space(xdr, 4 + 4 * i);
p = xdr_reserve_space(xdr, 8); if (!p)
if (!p) return nfserr_resource;
return nfserr_resource;
*p++ = cpu_to_be32(1); *p++ = cpu_to_be32(i);
*p++ = cpu_to_be32(layout_type);
} else { for (i = LAYOUT_NFSV4_1_FILES; i < LAYOUT_TYPE_MAX; ++i)
p = xdr_reserve_space(xdr, 4); if (layout_types & (1 << i))
if (!p) *p++ = cpu_to_be32(i);
return nfserr_resource;
*p++ = cpu_to_be32(0);
}
return 0; return 0;
} }
@ -2752,13 +2750,13 @@ out_acl:
} }
#ifdef CONFIG_NFSD_PNFS #ifdef CONFIG_NFSD_PNFS
if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
if (status) if (status)
goto out; goto out;
} }
if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) { if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
if (status) if (status)
goto out; goto out;
} }