1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef LINUX_EXPORTFS_H 3*4882a593Smuzhiyun #define LINUX_EXPORTFS_H 1 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #include <linux/types.h> 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun struct dentry; 8*4882a593Smuzhiyun struct iattr; 9*4882a593Smuzhiyun struct inode; 10*4882a593Smuzhiyun struct iomap; 11*4882a593Smuzhiyun struct super_block; 12*4882a593Smuzhiyun struct vfsmount; 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun /* limit the handle size to NFSv4 handle size now */ 15*4882a593Smuzhiyun #define MAX_HANDLE_SZ 128 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun /* 18*4882a593Smuzhiyun * The fileid_type identifies how the file within the filesystem is encoded. 19*4882a593Smuzhiyun * In theory this is freely set and parsed by the filesystem, but we try to 20*4882a593Smuzhiyun * stick to conventions so we can share some generic code and don't confuse 21*4882a593Smuzhiyun * sniffers like ethereal/wireshark. 22*4882a593Smuzhiyun * 23*4882a593Smuzhiyun * The filesystem must not use the value '0' or '0xff'. 24*4882a593Smuzhiyun */ 25*4882a593Smuzhiyun enum fid_type { 26*4882a593Smuzhiyun /* 27*4882a593Smuzhiyun * The root, or export point, of the filesystem. 28*4882a593Smuzhiyun * (Never actually passed down to the filesystem. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun FILEID_ROOT = 0, 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* 33*4882a593Smuzhiyun * 32bit inode number, 32 bit generation number. 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun FILEID_INO32_GEN = 1, 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun * 32bit inode number, 32 bit generation number, 39*4882a593Smuzhiyun * 32 bit parent directory inode number. 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun FILEID_INO32_GEN_PARENT = 2, 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* 44*4882a593Smuzhiyun * 64 bit object ID, 64 bit root object ID, 45*4882a593Smuzhiyun * 32 bit generation number. 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun FILEID_BTRFS_WITHOUT_PARENT = 0x4d, 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /* 50*4882a593Smuzhiyun * 64 bit object ID, 64 bit root object ID, 51*4882a593Smuzhiyun * 32 bit generation number, 52*4882a593Smuzhiyun * 64 bit parent object ID, 32 bit parent generation. 53*4882a593Smuzhiyun */ 54*4882a593Smuzhiyun FILEID_BTRFS_WITH_PARENT = 0x4e, 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* 57*4882a593Smuzhiyun * 64 bit object ID, 64 bit root object ID, 58*4882a593Smuzhiyun * 32 bit generation number, 59*4882a593Smuzhiyun * 64 bit parent object ID, 32 bit parent generation, 60*4882a593Smuzhiyun * 64 bit parent root object ID. 61*4882a593Smuzhiyun */ 62*4882a593Smuzhiyun FILEID_BTRFS_WITH_PARENT_ROOT = 0x4f, 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* 65*4882a593Smuzhiyun * 32 bit block number, 16 bit partition reference, 66*4882a593Smuzhiyun * 16 bit unused, 32 bit generation number. 67*4882a593Smuzhiyun */ 68*4882a593Smuzhiyun FILEID_UDF_WITHOUT_PARENT = 0x51, 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun /* 71*4882a593Smuzhiyun * 32 bit block number, 16 bit partition reference, 72*4882a593Smuzhiyun * 16 bit unused, 32 bit generation number, 73*4882a593Smuzhiyun * 32 bit parent block number, 32 bit parent generation number 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun FILEID_UDF_WITH_PARENT = 0x52, 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* 78*4882a593Smuzhiyun * 64 bit checkpoint number, 64 bit inode number, 79*4882a593Smuzhiyun * 32 bit generation number. 80*4882a593Smuzhiyun */ 81*4882a593Smuzhiyun FILEID_NILFS_WITHOUT_PARENT = 0x61, 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun /* 84*4882a593Smuzhiyun * 64 bit checkpoint number, 64 bit inode number, 85*4882a593Smuzhiyun * 32 bit generation number, 32 bit parent generation. 86*4882a593Smuzhiyun * 64 bit parent inode number. 87*4882a593Smuzhiyun */ 88*4882a593Smuzhiyun FILEID_NILFS_WITH_PARENT = 0x62, 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* 91*4882a593Smuzhiyun * 32 bit generation number, 40 bit i_pos. 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun FILEID_FAT_WITHOUT_PARENT = 0x71, 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun /* 96*4882a593Smuzhiyun * 32 bit generation number, 40 bit i_pos, 97*4882a593Smuzhiyun * 32 bit parent generation number, 40 bit parent i_pos 98*4882a593Smuzhiyun */ 99*4882a593Smuzhiyun FILEID_FAT_WITH_PARENT = 0x72, 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* 102*4882a593Smuzhiyun * 128 bit child FID (struct lu_fid) 103*4882a593Smuzhiyun * 128 bit parent FID (struct lu_fid) 104*4882a593Smuzhiyun */ 105*4882a593Smuzhiyun FILEID_LUSTRE = 0x97, 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* 108*4882a593Smuzhiyun * 64 bit unique kernfs id 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun FILEID_KERNFS = 0xfe, 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /* 113*4882a593Smuzhiyun * Filesystems must not use 0xff file ID. 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun FILEID_INVALID = 0xff, 116*4882a593Smuzhiyun }; 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun struct fid { 119*4882a593Smuzhiyun union { 120*4882a593Smuzhiyun struct { 121*4882a593Smuzhiyun u32 ino; 122*4882a593Smuzhiyun u32 gen; 123*4882a593Smuzhiyun u32 parent_ino; 124*4882a593Smuzhiyun u32 parent_gen; 125*4882a593Smuzhiyun } i32; 126*4882a593Smuzhiyun struct { 127*4882a593Smuzhiyun u32 block; 128*4882a593Smuzhiyun u16 partref; 129*4882a593Smuzhiyun u16 parent_partref; 130*4882a593Smuzhiyun u32 generation; 131*4882a593Smuzhiyun u32 parent_block; 132*4882a593Smuzhiyun u32 parent_generation; 133*4882a593Smuzhiyun } udf; 134*4882a593Smuzhiyun __u32 raw[0]; 135*4882a593Smuzhiyun }; 136*4882a593Smuzhiyun }; 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun /** 139*4882a593Smuzhiyun * struct export_operations - for nfsd to communicate with file systems 140*4882a593Smuzhiyun * @encode_fh: encode a file handle fragment from a dentry 141*4882a593Smuzhiyun * @fh_to_dentry: find the implied object and get a dentry for it 142*4882a593Smuzhiyun * @fh_to_parent: find the implied object's parent and get a dentry for it 143*4882a593Smuzhiyun * @get_name: find the name for a given inode in a given directory 144*4882a593Smuzhiyun * @get_parent: find the parent of a given directory 145*4882a593Smuzhiyun * @commit_metadata: commit metadata changes to stable storage 146*4882a593Smuzhiyun * 147*4882a593Smuzhiyun * See Documentation/filesystems/nfs/exporting.rst for details on how to use 148*4882a593Smuzhiyun * this interface correctly. 149*4882a593Smuzhiyun * 150*4882a593Smuzhiyun * encode_fh: 151*4882a593Smuzhiyun * @encode_fh should store in the file handle fragment @fh (using at most 152*4882a593Smuzhiyun * @max_len bytes) information that can be used by @decode_fh to recover the 153*4882a593Smuzhiyun * file referred to by the &struct dentry @de. If the @connectable flag is 154*4882a593Smuzhiyun * set, the encode_fh() should store sufficient information so that a good 155*4882a593Smuzhiyun * attempt can be made to find not only the file but also it's place in the 156*4882a593Smuzhiyun * filesystem. This typically means storing a reference to de->d_parent in 157*4882a593Smuzhiyun * the filehandle fragment. encode_fh() should return the fileid_type on 158*4882a593Smuzhiyun * success and on error returns 255 (if the space needed to encode fh is 159*4882a593Smuzhiyun * greater than @max_len*4 bytes). On error @max_len contains the minimum 160*4882a593Smuzhiyun * size(in 4 byte unit) needed to encode the file handle. 161*4882a593Smuzhiyun * 162*4882a593Smuzhiyun * fh_to_dentry: 163*4882a593Smuzhiyun * @fh_to_dentry is given a &struct super_block (@sb) and a file handle 164*4882a593Smuzhiyun * fragment (@fh, @fh_len). It should return a &struct dentry which refers 165*4882a593Smuzhiyun * to the same file that the file handle fragment refers to. If it cannot, 166*4882a593Smuzhiyun * it should return a %NULL pointer if the file cannot be found, or an 167*4882a593Smuzhiyun * %ERR_PTR error code of %ENOMEM if a memory allocation failure occurred. 168*4882a593Smuzhiyun * Any other error code is treated like %NULL, and will cause an %ESTALE error 169*4882a593Smuzhiyun * for callers of exportfs_decode_fh(). 170*4882a593Smuzhiyun * Any suitable dentry can be returned including, if necessary, a new dentry 171*4882a593Smuzhiyun * created with d_alloc_root. The caller can then find any other extant 172*4882a593Smuzhiyun * dentries by following the d_alias links. 173*4882a593Smuzhiyun * 174*4882a593Smuzhiyun * fh_to_parent: 175*4882a593Smuzhiyun * Same as @fh_to_dentry, except that it returns a pointer to the parent 176*4882a593Smuzhiyun * dentry if it was encoded into the filehandle fragment by @encode_fh. 177*4882a593Smuzhiyun * 178*4882a593Smuzhiyun * get_name: 179*4882a593Smuzhiyun * @get_name should find a name for the given @child in the given @parent 180*4882a593Smuzhiyun * directory. The name should be stored in the @name (with the 181*4882a593Smuzhiyun * understanding that it is already pointing to a %NAME_MAX+1 sized 182*4882a593Smuzhiyun * buffer. get_name() should return %0 on success, a negative error code 183*4882a593Smuzhiyun * or error. @get_name will be called without @parent->i_mutex held. 184*4882a593Smuzhiyun * 185*4882a593Smuzhiyun * get_parent: 186*4882a593Smuzhiyun * @get_parent should find the parent directory for the given @child which 187*4882a593Smuzhiyun * is also a directory. In the event that it cannot be found, or storage 188*4882a593Smuzhiyun * space cannot be allocated, a %ERR_PTR should be returned. 189*4882a593Smuzhiyun * 190*4882a593Smuzhiyun * commit_metadata: 191*4882a593Smuzhiyun * @commit_metadata should commit metadata changes to stable storage. 192*4882a593Smuzhiyun * 193*4882a593Smuzhiyun * Locking rules: 194*4882a593Smuzhiyun * get_parent is called with child->d_inode->i_mutex down 195*4882a593Smuzhiyun * get_name is not (which is possibly inconsistent) 196*4882a593Smuzhiyun */ 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun struct export_operations { 199*4882a593Smuzhiyun int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len, 200*4882a593Smuzhiyun struct inode *parent); 201*4882a593Smuzhiyun struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid, 202*4882a593Smuzhiyun int fh_len, int fh_type); 203*4882a593Smuzhiyun struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid, 204*4882a593Smuzhiyun int fh_len, int fh_type); 205*4882a593Smuzhiyun int (*get_name)(struct dentry *parent, char *name, 206*4882a593Smuzhiyun struct dentry *child); 207*4882a593Smuzhiyun struct dentry * (*get_parent)(struct dentry *child); 208*4882a593Smuzhiyun int (*commit_metadata)(struct inode *inode); 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset); 211*4882a593Smuzhiyun int (*map_blocks)(struct inode *inode, loff_t offset, 212*4882a593Smuzhiyun u64 len, struct iomap *iomap, 213*4882a593Smuzhiyun bool write, u32 *device_generation); 214*4882a593Smuzhiyun int (*commit_blocks)(struct inode *inode, struct iomap *iomaps, 215*4882a593Smuzhiyun int nr_iomaps, struct iattr *iattr); 216*4882a593Smuzhiyun }; 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, 219*4882a593Smuzhiyun int *max_len, struct inode *parent); 220*4882a593Smuzhiyun extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, 221*4882a593Smuzhiyun int *max_len, int connectable); 222*4882a593Smuzhiyun extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid, 223*4882a593Smuzhiyun int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *), 224*4882a593Smuzhiyun void *context); 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun /* 227*4882a593Smuzhiyun * Generic helpers for filesystems. 228*4882a593Smuzhiyun */ 229*4882a593Smuzhiyun extern struct dentry *generic_fh_to_dentry(struct super_block *sb, 230*4882a593Smuzhiyun struct fid *fid, int fh_len, int fh_type, 231*4882a593Smuzhiyun struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen)); 232*4882a593Smuzhiyun extern struct dentry *generic_fh_to_parent(struct super_block *sb, 233*4882a593Smuzhiyun struct fid *fid, int fh_len, int fh_type, 234*4882a593Smuzhiyun struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen)); 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun #endif /* LINUX_EXPORTFS_H */ 237