18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  linux/fs/nfs/blocklayout/blocklayout.h
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Module for the NFSv4.1 pNFS block layout driver.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  Copyright (c) 2006 The Regents of the University of Michigan.
78c2ecf20Sopenharmony_ci *  All rights reserved.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci *  Andy Adamson <andros@citi.umich.edu>
108c2ecf20Sopenharmony_ci *  Fred Isaman <iisaman@umich.edu>
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * permission is granted to use, copy, create derivative works and
138c2ecf20Sopenharmony_ci * redistribute this software and such derivative works for any purpose,
148c2ecf20Sopenharmony_ci * so long as the name of the university of michigan is not used in
158c2ecf20Sopenharmony_ci * any advertising or publicity pertaining to the use or distribution
168c2ecf20Sopenharmony_ci * of this software without specific, written prior authorization.  if
178c2ecf20Sopenharmony_ci * the above copyright notice or any other identification of the
188c2ecf20Sopenharmony_ci * university of michigan is included in any copy of any portion of
198c2ecf20Sopenharmony_ci * this software, then the disclaimer below must also be included.
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * this software is provided as is, without representation from the
228c2ecf20Sopenharmony_ci * university of michigan as to its fitness for any purpose, and without
238c2ecf20Sopenharmony_ci * warranty by the university of michigan of any kind, either express
248c2ecf20Sopenharmony_ci * or implied, including without limitation the implied warranties of
258c2ecf20Sopenharmony_ci * merchantability and fitness for a particular purpose.  the regents
268c2ecf20Sopenharmony_ci * of the university of michigan shall not be liable for any damages,
278c2ecf20Sopenharmony_ci * including special, indirect, incidental, or consequential damages,
288c2ecf20Sopenharmony_ci * with respect to any claim arising out or in connection with the use
298c2ecf20Sopenharmony_ci * of the software, even if it has been or is hereafter advised of the
308c2ecf20Sopenharmony_ci * possibility of such damages.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#ifndef FS_NFS_NFS4BLOCKLAYOUT_H
338c2ecf20Sopenharmony_ci#define FS_NFS_NFS4BLOCKLAYOUT_H
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#include <linux/device-mapper.h>
368c2ecf20Sopenharmony_ci#include <linux/nfs_fs.h>
378c2ecf20Sopenharmony_ci#include <linux/sunrpc/rpc_pipe_fs.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#include "../nfs4_fs.h"
408c2ecf20Sopenharmony_ci#include "../pnfs.h"
418c2ecf20Sopenharmony_ci#include "../netns.h"
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define PAGE_CACHE_SECTORS (PAGE_SIZE >> SECTOR_SHIFT)
448c2ecf20Sopenharmony_ci#define PAGE_CACHE_SECTOR_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
458c2ecf20Sopenharmony_ci#define SECTOR_SIZE (1 << SECTOR_SHIFT)
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistruct pnfs_block_dev;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#define PNFS_BLOCK_MAX_UUIDS	4
508c2ecf20Sopenharmony_ci#define PNFS_BLOCK_MAX_DEVICES	64
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * Random upper cap for the uuid length to avoid unbounded allocation.
548c2ecf20Sopenharmony_ci * Not actually limited by the protocol.
558c2ecf20Sopenharmony_ci */
568c2ecf20Sopenharmony_ci#define PNFS_BLOCK_UUID_LEN	128
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistruct pnfs_block_volume {
598c2ecf20Sopenharmony_ci	enum pnfs_block_volume_type	type;
608c2ecf20Sopenharmony_ci	union {
618c2ecf20Sopenharmony_ci		struct {
628c2ecf20Sopenharmony_ci			int		len;
638c2ecf20Sopenharmony_ci			int		nr_sigs;
648c2ecf20Sopenharmony_ci			struct {
658c2ecf20Sopenharmony_ci				u64		offset;
668c2ecf20Sopenharmony_ci				u32		sig_len;
678c2ecf20Sopenharmony_ci				u8		sig[PNFS_BLOCK_UUID_LEN];
688c2ecf20Sopenharmony_ci			} sigs[PNFS_BLOCK_MAX_UUIDS];
698c2ecf20Sopenharmony_ci		} simple;
708c2ecf20Sopenharmony_ci		struct {
718c2ecf20Sopenharmony_ci			u64		start;
728c2ecf20Sopenharmony_ci			u64		len;
738c2ecf20Sopenharmony_ci			u32		volume;
748c2ecf20Sopenharmony_ci		} slice;
758c2ecf20Sopenharmony_ci		struct {
768c2ecf20Sopenharmony_ci			u32		volumes_count;
778c2ecf20Sopenharmony_ci			u32		volumes[PNFS_BLOCK_MAX_DEVICES];
788c2ecf20Sopenharmony_ci		} concat;
798c2ecf20Sopenharmony_ci		struct {
808c2ecf20Sopenharmony_ci			u64		chunk_size;
818c2ecf20Sopenharmony_ci			u32		volumes_count;
828c2ecf20Sopenharmony_ci			u32		volumes[PNFS_BLOCK_MAX_DEVICES];
838c2ecf20Sopenharmony_ci		} stripe;
848c2ecf20Sopenharmony_ci		struct {
858c2ecf20Sopenharmony_ci			enum scsi_code_set		code_set;
868c2ecf20Sopenharmony_ci			enum scsi_designator_type	designator_type;
878c2ecf20Sopenharmony_ci			int				designator_len;
888c2ecf20Sopenharmony_ci			u8				designator[256];
898c2ecf20Sopenharmony_ci			u64				pr_key;
908c2ecf20Sopenharmony_ci		} scsi;
918c2ecf20Sopenharmony_ci	};
928c2ecf20Sopenharmony_ci};
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistruct pnfs_block_dev_map {
958c2ecf20Sopenharmony_ci	u64			start;
968c2ecf20Sopenharmony_ci	u64			len;
978c2ecf20Sopenharmony_ci	u64			disk_offset;
988c2ecf20Sopenharmony_ci	struct block_device		*bdev;
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistruct pnfs_block_dev {
1028c2ecf20Sopenharmony_ci	struct nfs4_deviceid_node	node;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	u64				start;
1058c2ecf20Sopenharmony_ci	u64				len;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	u32				nr_children;
1088c2ecf20Sopenharmony_ci	struct pnfs_block_dev		*children;
1098c2ecf20Sopenharmony_ci	u64				chunk_size;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	struct block_device		*bdev;
1128c2ecf20Sopenharmony_ci	u64				disk_offset;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	u64				pr_key;
1158c2ecf20Sopenharmony_ci	bool				pr_registered;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	bool (*map)(struct pnfs_block_dev *dev, u64 offset,
1188c2ecf20Sopenharmony_ci			struct pnfs_block_dev_map *map);
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci/* sector_t fields are all in 512-byte sectors */
1228c2ecf20Sopenharmony_cistruct pnfs_block_extent {
1238c2ecf20Sopenharmony_ci	union {
1248c2ecf20Sopenharmony_ci		struct rb_node	be_node;
1258c2ecf20Sopenharmony_ci		struct list_head be_list;
1268c2ecf20Sopenharmony_ci	};
1278c2ecf20Sopenharmony_ci	struct nfs4_deviceid_node *be_device;
1288c2ecf20Sopenharmony_ci	sector_t	be_f_offset;	/* the starting offset in the file */
1298c2ecf20Sopenharmony_ci	sector_t	be_length;	/* the size of the extent */
1308c2ecf20Sopenharmony_ci	sector_t	be_v_offset;	/* the starting offset in the volume */
1318c2ecf20Sopenharmony_ci	enum pnfs_block_extent_state be_state;	/* the state of this extent */
1328c2ecf20Sopenharmony_ci#define EXTENT_WRITTEN		1
1338c2ecf20Sopenharmony_ci#define EXTENT_COMMITTING	2
1348c2ecf20Sopenharmony_ci	unsigned int	be_tag;
1358c2ecf20Sopenharmony_ci};
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_cistruct pnfs_block_layout {
1388c2ecf20Sopenharmony_ci	struct pnfs_layout_hdr	bl_layout;
1398c2ecf20Sopenharmony_ci	struct rb_root		bl_ext_rw;
1408c2ecf20Sopenharmony_ci	struct rb_root		bl_ext_ro;
1418c2ecf20Sopenharmony_ci	spinlock_t		bl_ext_lock;   /* Protects list manipulation */
1428c2ecf20Sopenharmony_ci	bool			bl_scsi_layout;
1438c2ecf20Sopenharmony_ci	u64			bl_lwb;
1448c2ecf20Sopenharmony_ci};
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic inline struct pnfs_block_layout *
1478c2ecf20Sopenharmony_ciBLK_LO2EXT(struct pnfs_layout_hdr *lo)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	return container_of(lo, struct pnfs_block_layout, bl_layout);
1508c2ecf20Sopenharmony_ci}
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_cistatic inline struct pnfs_block_layout *
1538c2ecf20Sopenharmony_ciBLK_LSEG2EXT(struct pnfs_layout_segment *lseg)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	return BLK_LO2EXT(lseg->pls_layout);
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistruct bl_pipe_msg {
1598c2ecf20Sopenharmony_ci	struct rpc_pipe_msg msg;
1608c2ecf20Sopenharmony_ci	wait_queue_head_t *bl_wq;
1618c2ecf20Sopenharmony_ci};
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistruct bl_msg_hdr {
1648c2ecf20Sopenharmony_ci	u8  type;
1658c2ecf20Sopenharmony_ci	u16 totallen; /* length of entire message, including hdr itself */
1668c2ecf20Sopenharmony_ci};
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci#define BL_DEVICE_UMOUNT               0x0 /* Umount--delete devices */
1698c2ecf20Sopenharmony_ci#define BL_DEVICE_MOUNT                0x1 /* Mount--create devices*/
1708c2ecf20Sopenharmony_ci#define BL_DEVICE_REQUEST_INIT         0x0 /* Start request */
1718c2ecf20Sopenharmony_ci#define BL_DEVICE_REQUEST_PROC         0x1 /* User level process succeeds */
1728c2ecf20Sopenharmony_ci#define BL_DEVICE_REQUEST_ERR          0x2 /* User level process fails */
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/* dev.c */
1758c2ecf20Sopenharmony_cistruct nfs4_deviceid_node *bl_alloc_deviceid_node(struct nfs_server *server,
1768c2ecf20Sopenharmony_ci		struct pnfs_device *pdev, gfp_t gfp_mask);
1778c2ecf20Sopenharmony_civoid bl_free_deviceid_node(struct nfs4_deviceid_node *d);
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci/* extent_tree.c */
1808c2ecf20Sopenharmony_ciint ext_tree_insert(struct pnfs_block_layout *bl,
1818c2ecf20Sopenharmony_ci		struct pnfs_block_extent *new);
1828c2ecf20Sopenharmony_ciint ext_tree_remove(struct pnfs_block_layout *bl, bool rw, sector_t start,
1838c2ecf20Sopenharmony_ci		sector_t end);
1848c2ecf20Sopenharmony_ciint ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start,
1858c2ecf20Sopenharmony_ci		sector_t len, u64 lwb);
1868c2ecf20Sopenharmony_cibool ext_tree_lookup(struct pnfs_block_layout *bl, sector_t isect,
1878c2ecf20Sopenharmony_ci		struct pnfs_block_extent *ret, bool rw);
1888c2ecf20Sopenharmony_ciint ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg);
1898c2ecf20Sopenharmony_civoid ext_tree_mark_committed(struct nfs4_layoutcommit_args *arg, int status);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci/* rpc_pipefs.c */
1928c2ecf20Sopenharmony_cidev_t bl_resolve_deviceid(struct nfs_server *server,
1938c2ecf20Sopenharmony_ci		struct pnfs_block_volume *b, gfp_t gfp_mask);
1948c2ecf20Sopenharmony_ciint __init bl_init_pipefs(void);
1958c2ecf20Sopenharmony_civoid bl_cleanup_pipefs(void);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci#endif /* FS_NFS_NFS4BLOCKLAYOUT_H */
198