mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
exportfs,nfsd: rework checking for layout-based block device access support
Currently NFSD hard codes checking support for block-style layouts. Lift the checks into a file system-helper and provide a exportfs-level helper to implement the typical checks. This prepares for supporting block layout export of multiple devices per file system. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260423181854.743150-5-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
61eb48f515
commit
da9baa5470
|
|
@ -735,7 +735,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
|
|||
goto out4;
|
||||
err = 0;
|
||||
|
||||
nfsd4_setup_layout_type(&exp);
|
||||
if (exp.ex_flags & NFSEXP_PNFS)
|
||||
nfsd4_setup_layout_type(&exp);
|
||||
}
|
||||
|
||||
expp = svc_export_lookup(&exp);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Christoph Hellwig.
|
||||
*/
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/exportfs_block.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/file.h>
|
||||
|
|
@ -128,28 +127,17 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
|
|||
|
||||
void nfsd4_setup_layout_type(struct svc_export *exp)
|
||||
{
|
||||
#if defined(CONFIG_NFSD_BLOCKLAYOUT) || defined(CONFIG_NFSD_SCSILAYOUT)
|
||||
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
|
||||
const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
|
||||
#endif
|
||||
expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
|
||||
|
||||
if (!(exp->ex_flags & NFSEXP_PNFS))
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_NFSD_FLEXFILELAYOUT
|
||||
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
|
||||
#endif
|
||||
#ifdef CONFIG_NFSD_BLOCKLAYOUT
|
||||
if (bops && bops->get_uuid && bops->map_blocks && bops->commit_blocks)
|
||||
if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
|
||||
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
|
||||
if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
|
||||
(block_supported & EXPFS_BLOCK_IN_BAND_ID))
|
||||
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
|
||||
#endif
|
||||
#ifdef CONFIG_NFSD_SCSILAYOUT
|
||||
if (bops && bops->map_blocks && bops->commit_blocks &&
|
||||
sb->s_bdev &&
|
||||
sb->s_bdev->bd_disk->fops->pr_ops &&
|
||||
sb->s_bdev->bd_disk->fops->get_unique_id)
|
||||
if (IS_ENABLED(CONFIG_NFSD_SCSILAYOUT) &&
|
||||
(block_supported & EXPFS_BLOCK_OUT_OF_BAND_ID))
|
||||
exp->ex_layout_types |= 1 << LAYOUT_SCSI;
|
||||
#endif
|
||||
}
|
||||
|
||||
void nfsd4_close_layout(struct nfs4_layout_stateid *ls)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "xfs_bmap.h"
|
||||
#include "xfs_iomap.h"
|
||||
#include "xfs_pnfs.h"
|
||||
#include <linux/exportfs_block.h>
|
||||
|
||||
/*
|
||||
* Ensure that we do not have any outstanding pNFS layouts that can be used by
|
||||
|
|
@ -45,6 +46,17 @@ xfs_break_leased_layouts(
|
|||
return error;
|
||||
}
|
||||
|
||||
static expfs_block_layouts_t
|
||||
xfs_fs_layouts_supported(
|
||||
struct super_block *sb)
|
||||
{
|
||||
expfs_block_layouts_t supported = EXPFS_BLOCK_IN_BAND_ID;
|
||||
|
||||
if (exportfs_bdev_supports_out_of_band_id(sb->s_bdev))
|
||||
supported |= EXPFS_BLOCK_OUT_OF_BAND_ID;
|
||||
return supported;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a unique ID including its location so that the client can identify
|
||||
* the exported device.
|
||||
|
|
@ -335,6 +347,7 @@ xfs_fs_commit_blocks(
|
|||
}
|
||||
|
||||
const struct exportfs_block_ops xfs_export_block_ops = {
|
||||
.layouts_supported = xfs_fs_layouts_supported,
|
||||
.get_uuid = xfs_fs_get_uuid,
|
||||
.map_blocks = xfs_fs_map_blocks,
|
||||
.commit_blocks = xfs_fs_commit_blocks,
|
||||
|
|
|
|||
|
|
@ -7,13 +7,35 @@
|
|||
#ifndef LINUX_EXPORTFS_BLOCK_H
|
||||
#define LINUX_EXPORTFS_BLOCK_H 1
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/exportfs.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
struct inode;
|
||||
struct iomap;
|
||||
struct super_block;
|
||||
|
||||
/*
|
||||
* There are the two types of block-style layout support:
|
||||
* - In-band implies a device identified by a unique cookie inside the actual
|
||||
* device address space checked by the ->get_uuid method as used by the pNFS
|
||||
* block layout. This is a bit dangerous and deprecated.
|
||||
* - Out of band implies identification by out of band unique identifiers
|
||||
* specified by the storage protocol, which is much safer and used by the
|
||||
* pNFS SCSI/NVMe layouts.
|
||||
*/
|
||||
typedef unsigned int __bitwise expfs_block_layouts_t;
|
||||
#define EXPFS_BLOCK_FLAG(__bit) \
|
||||
((__force expfs_block_layouts_t)(1u << __bit))
|
||||
#define EXPFS_BLOCK_IN_BAND_ID EXPFS_BLOCK_FLAG(0)
|
||||
#define EXPFS_BLOCK_OUT_OF_BAND_ID EXPFS_BLOCK_FLAG(1)
|
||||
|
||||
struct exportfs_block_ops {
|
||||
/*
|
||||
* Returns the EXPFS_BLOCK_* bitmap of supported layout types.
|
||||
*/
|
||||
expfs_block_layouts_t (*layouts_supported)(struct super_block *sb);
|
||||
|
||||
/*
|
||||
* Get the in-band device unique signature exposed to clients.
|
||||
*/
|
||||
|
|
@ -35,4 +57,32 @@ struct exportfs_block_ops {
|
|||
int nr_iomaps, loff_t new_size);
|
||||
};
|
||||
|
||||
static inline bool
|
||||
exportfs_bdev_supports_out_of_band_id(struct block_device *bdev)
|
||||
{
|
||||
return bdev->bd_disk->fops->pr_ops &&
|
||||
bdev->bd_disk->fops->get_unique_id;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXPORTFS_BLOCK_OPS
|
||||
static inline expfs_block_layouts_t
|
||||
exportfs_layouts_supported(struct super_block *sb)
|
||||
{
|
||||
const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
|
||||
|
||||
if (!bops ||
|
||||
!bops->layouts_supported ||
|
||||
WARN_ON_ONCE(!bops->map_blocks) ||
|
||||
WARN_ON_ONCE(!bops->commit_blocks))
|
||||
return 0;
|
||||
return bops->layouts_supported(sb);
|
||||
}
|
||||
#else
|
||||
static inline expfs_block_layouts_t
|
||||
exportfs_layouts_supported(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_EXPORTFS_BLOCK_OPS */
|
||||
|
||||
#endif /* LINUX_EXPORTFS_BLOCK_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user