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