162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef LINUX_NFSD_VFS_H 762306a36Sopenharmony_ci#define LINUX_NFSD_VFS_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/fs.h> 1062306a36Sopenharmony_ci#include <linux/posix_acl.h> 1162306a36Sopenharmony_ci#include "nfsfh.h" 1262306a36Sopenharmony_ci#include "nfsd.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * Flags for nfsd_permission 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci#define NFSD_MAY_NOP 0 1862306a36Sopenharmony_ci#define NFSD_MAY_EXEC 0x001 /* == MAY_EXEC */ 1962306a36Sopenharmony_ci#define NFSD_MAY_WRITE 0x002 /* == MAY_WRITE */ 2062306a36Sopenharmony_ci#define NFSD_MAY_READ 0x004 /* == MAY_READ */ 2162306a36Sopenharmony_ci#define NFSD_MAY_SATTR 0x008 2262306a36Sopenharmony_ci#define NFSD_MAY_TRUNC 0x010 2362306a36Sopenharmony_ci#define NFSD_MAY_LOCK 0x020 2462306a36Sopenharmony_ci#define NFSD_MAY_MASK 0x03f 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* extra hints to permission and open routines: */ 2762306a36Sopenharmony_ci#define NFSD_MAY_OWNER_OVERRIDE 0x040 2862306a36Sopenharmony_ci#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */ 2962306a36Sopenharmony_ci#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100 3062306a36Sopenharmony_ci#define NFSD_MAY_NOT_BREAK_LEASE 0x200 3162306a36Sopenharmony_ci#define NFSD_MAY_BYPASS_GSS 0x400 3262306a36Sopenharmony_ci#define NFSD_MAY_READ_IF_EXEC 0x800 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) 3762306a36Sopenharmony_ci#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct nfsd_file; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* 4262306a36Sopenharmony_ci * Callback function for readdir 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_citypedef int (*nfsd_filldir_t)(void *, const char *, int, loff_t, u64, unsigned); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* nfsd/vfs.c */ 4762306a36Sopenharmony_cistruct nfsd_attrs { 4862306a36Sopenharmony_ci struct iattr *na_iattr; /* input */ 4962306a36Sopenharmony_ci struct xdr_netobj *na_seclabel; /* input */ 5062306a36Sopenharmony_ci struct posix_acl *na_pacl; /* input */ 5162306a36Sopenharmony_ci struct posix_acl *na_dpacl; /* input */ 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci int na_labelerr; /* output */ 5462306a36Sopenharmony_ci int na_aclerr; /* output */ 5562306a36Sopenharmony_ci}; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic inline void nfsd_attrs_free(struct nfsd_attrs *attrs) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci posix_acl_release(attrs->na_pacl); 6062306a36Sopenharmony_ci posix_acl_release(attrs->na_dpacl); 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci__be32 nfserrno (int errno); 6462306a36Sopenharmony_ciint nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 6562306a36Sopenharmony_ci struct svc_export **expp); 6662306a36Sopenharmony_ci__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, 6762306a36Sopenharmony_ci const char *, unsigned int, struct svc_fh *); 6862306a36Sopenharmony_ci__be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, 6962306a36Sopenharmony_ci const char *, unsigned int, 7062306a36Sopenharmony_ci struct svc_export **, struct dentry **); 7162306a36Sopenharmony_ci__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, 7262306a36Sopenharmony_ci struct nfsd_attrs *, int, time64_t); 7362306a36Sopenharmony_ciint nfsd_mountpoint(struct dentry *, struct svc_export *); 7462306a36Sopenharmony_ci#ifdef CONFIG_NFSD_V4 7562306a36Sopenharmony_ci__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, 7662306a36Sopenharmony_ci struct file *, loff_t, loff_t, int); 7762306a36Sopenharmony_ci__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, 7862306a36Sopenharmony_ci struct nfsd_file *nf_src, u64 src_pos, 7962306a36Sopenharmony_ci struct nfsd_file *nf_dst, u64 dst_pos, 8062306a36Sopenharmony_ci u64 count, bool sync); 8162306a36Sopenharmony_ci#endif /* CONFIG_NFSD_V4 */ 8262306a36Sopenharmony_ci__be32 nfsd_create_locked(struct svc_rqst *, struct svc_fh *, 8362306a36Sopenharmony_ci struct nfsd_attrs *attrs, int type, dev_t rdev, 8462306a36Sopenharmony_ci struct svc_fh *res); 8562306a36Sopenharmony_ci__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, 8662306a36Sopenharmony_ci char *name, int len, struct nfsd_attrs *attrs, 8762306a36Sopenharmony_ci int type, dev_t rdev, struct svc_fh *res); 8862306a36Sopenharmony_ci__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); 8962306a36Sopenharmony_ci__be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 9062306a36Sopenharmony_ci struct svc_fh *resfhp, struct nfsd_attrs *iap); 9162306a36Sopenharmony_ci__be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp, 9262306a36Sopenharmony_ci struct nfsd_file *nf, u64 offset, u32 count, 9362306a36Sopenharmony_ci __be32 *verf); 9462306a36Sopenharmony_ci#ifdef CONFIG_NFSD_V4 9562306a36Sopenharmony_ci__be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 9662306a36Sopenharmony_ci char *name, void **bufp, int *lenp); 9762306a36Sopenharmony_ci__be32 nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 9862306a36Sopenharmony_ci char **bufp, int *lenp); 9962306a36Sopenharmony_ci__be32 nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 10062306a36Sopenharmony_ci char *name); 10162306a36Sopenharmony_ci__be32 nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 10262306a36Sopenharmony_ci char *name, void *buf, u32 len, u32 flags); 10362306a36Sopenharmony_ci#endif 10462306a36Sopenharmony_ciint nfsd_open_break_lease(struct inode *, int); 10562306a36Sopenharmony_ci__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, 10662306a36Sopenharmony_ci int, struct file **); 10762306a36Sopenharmony_ciint nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, 10862306a36Sopenharmony_ci int may_flags, struct file **filp); 10962306a36Sopenharmony_ci__be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, 11062306a36Sopenharmony_ci struct file *file, loff_t offset, 11162306a36Sopenharmony_ci unsigned long *count, 11262306a36Sopenharmony_ci u32 *eof); 11362306a36Sopenharmony_ci__be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp, 11462306a36Sopenharmony_ci struct file *file, loff_t offset, 11562306a36Sopenharmony_ci unsigned long *count, unsigned int base, 11662306a36Sopenharmony_ci u32 *eof); 11762306a36Sopenharmony_ci__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, 11862306a36Sopenharmony_ci loff_t offset, unsigned long *count, 11962306a36Sopenharmony_ci u32 *eof); 12062306a36Sopenharmony_ci__be32 nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t, 12162306a36Sopenharmony_ci struct kvec *, int, unsigned long *, 12262306a36Sopenharmony_ci int stable, __be32 *verf); 12362306a36Sopenharmony_ci__be32 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, 12462306a36Sopenharmony_ci struct nfsd_file *nf, loff_t offset, 12562306a36Sopenharmony_ci struct kvec *vec, int vlen, unsigned long *cnt, 12662306a36Sopenharmony_ci int stable, __be32 *verf); 12762306a36Sopenharmony_ci__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, 12862306a36Sopenharmony_ci char *, int *); 12962306a36Sopenharmony_ci__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, 13062306a36Sopenharmony_ci char *name, int len, char *path, 13162306a36Sopenharmony_ci struct nfsd_attrs *attrs, 13262306a36Sopenharmony_ci struct svc_fh *res); 13362306a36Sopenharmony_ci__be32 nfsd_link(struct svc_rqst *, struct svc_fh *, 13462306a36Sopenharmony_ci char *, int, struct svc_fh *); 13562306a36Sopenharmony_cissize_t nfsd_copy_file_range(struct file *, u64, 13662306a36Sopenharmony_ci struct file *, u64, u64); 13762306a36Sopenharmony_ci__be32 nfsd_rename(struct svc_rqst *, 13862306a36Sopenharmony_ci struct svc_fh *, char *, int, 13962306a36Sopenharmony_ci struct svc_fh *, char *, int); 14062306a36Sopenharmony_ci__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, 14162306a36Sopenharmony_ci char *name, int len); 14262306a36Sopenharmony_ci__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, 14362306a36Sopenharmony_ci loff_t *, struct readdir_cd *, nfsd_filldir_t); 14462306a36Sopenharmony_ci__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, 14562306a36Sopenharmony_ci struct kstatfs *, int access); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, 14862306a36Sopenharmony_ci struct dentry *, int); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic inline int fh_want_write(struct svc_fh *fh) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci int ret; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci if (fh->fh_want_write) 15562306a36Sopenharmony_ci return 0; 15662306a36Sopenharmony_ci ret = mnt_want_write(fh->fh_export->ex_path.mnt); 15762306a36Sopenharmony_ci if (!ret) 15862306a36Sopenharmony_ci fh->fh_want_write = true; 15962306a36Sopenharmony_ci return ret; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic inline void fh_drop_write(struct svc_fh *fh) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci if (fh->fh_want_write) { 16562306a36Sopenharmony_ci fh->fh_want_write = false; 16662306a36Sopenharmony_ci mnt_drop_write(fh->fh_export->ex_path.mnt); 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic inline __be32 fh_getattr(const struct svc_fh *fh, struct kstat *stat) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci u32 request_mask = STATX_BASIC_STATS; 17362306a36Sopenharmony_ci struct path p = {.mnt = fh->fh_export->ex_path.mnt, 17462306a36Sopenharmony_ci .dentry = fh->fh_dentry}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (fh->fh_maxsize == NFS4_FHSIZE) 17762306a36Sopenharmony_ci request_mask |= (STATX_BTIME | STATX_CHANGE_COOKIE); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci return nfserrno(vfs_getattr(&p, stat, request_mask, 18062306a36Sopenharmony_ci AT_STATX_SYNC_AS_STAT)); 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#endif /* LINUX_NFSD_VFS_H */ 184