// SPDX-License-Identifier: GPL-2.0 /* * File operations used by nfsd. Some of these have been ripped from * other parts of the kernel because they weren't exported, others * are partial duplicates with added or changed functionality. * * Note that several functions dget() the dentry upon which they want * to act, most notably those that create directory entries. Response * dentry's are dput()'d if necessary in the release callback. * So if you notice code paths that apparently fail to dput() the * dentry, don't worry--they have been taken care of. * * Copyright (C) 1995-1999 Olaf Kirch <[email protected]> * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <[email protected]> */ #include <linux/fs.h> #include <linux/file.h> #include <linux/splice.h> #include <linux/falloc.h> #include <linux/fcntl.h> #include <linux/namei.h> #include <linux/delay.h> #include <linux/fsnotify.h> #include <linux/posix_acl_xattr.h> #include <linux/xattr.h> #include <linux/jhash.h> #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/exportfs.h> #include <linux/writeback.h> #include <linux/security.h> #include "xdr3.h" #ifdef CONFIG_NFSD_V4 #include "../internal.h" #include "acl.h" #include "idmap.h" #include "xdr4.h" #endif /* CONFIG_NFSD_V4 */ #include "nfsd.h" #include "vfs.h" #include "filecache.h" #include "trace.h" #define NFSDDBG_FACILITY … /** * nfserrno - Map Linux errnos to NFS errnos * @errno: POSIX(-ish) error code to be mapped * * Returns the appropriate (net-endian) nfserr_* (or nfs_ok if errno is 0). If * it's an error we don't expect, log it once and return nfserr_io. */ __be32 nfserrno (int errno) { … } /* * Called from nfsd_lookup and encode_dirent. Check if we have crossed * a mount point. * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged, * or nfs_ok having possibly changed *dpp and *expp */ int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, struct svc_export **expp) { … } static void follow_to_parent(struct path *path) { … } static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp) { … } /* * For nfsd purposes, we treat V4ROOT exports as though there was an * export at *every* directory. * We return: * '1' if this dentry *must* be an export point, * '2' if it might be, if there is really a mount here, and * '0' if there is no chance of an export point here. */ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) { … } __be32 nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, unsigned int len, struct svc_export **exp_ret, struct dentry **dentry_ret) { … } /** * nfsd_lookup - look up a single path component for nfsd * * @rqstp: the request context * @fhp: the file handle of the directory * @name: the component name, or %NULL to look up parent * @len: length of name to examine * @resfh: pointer to pre-initialised filehandle to hold result. * * Look up one component of a pathname. * N.B. After this call _both_ fhp and resfh need an fh_put * * If the lookup would cross a mountpoint, and the mounted filesystem * is exported to the client with NFSEXP_NOHIDE, then the lookup is * accepted as it stands and the mounted directory is * returned. Otherwise the covered directory is returned. * NOTE: this mountpoint crossing is not supported properly by all * clients and is explicitly disallowed for NFSv3 * */ __be32 nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, unsigned int len, struct svc_fh *resfh) { … } static void commit_reset_write_verifier(struct nfsd_net *nn, struct svc_rqst *rqstp, int err) { … } /* * Commit metadata changes to stable storage. */ static int commit_inode_metadata(struct inode *inode) { … } static int commit_metadata(struct svc_fh *fhp) { … } /* * Go over the attributes and take care of the small differences between * NFS semantics and what Linux expects. */ static void nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap) { … } static __be32 nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) { … } static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap) { … } /** * nfsd_setattr - Set various file attributes. * @rqstp: controlling RPC transaction * @fhp: filehandle of target * @attr: attributes to set * @guardtime: do not act if ctime.tv_sec does not match this timestamp * * This call may adjust the contents of @attr (in particular, this * call may change the bits in the na_iattr.ia_valid field). * * Returns nfs_ok on success, otherwise an NFS status code is * returned. Caller must release @fhp by calling fh_put in either * case. */ __be32 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_attrs *attr, const struct timespec64 *guardtime) { … } #if defined(CONFIG_NFSD_V4) /* * NFS junction information is stored in an extended attribute. */ #define NFSD_JUNCTION_XATTR_NAME … /** * nfsd4_is_junction - Test if an object could be an NFS junction * * @dentry: object to test * * Returns 1 if "dentry" appears to contain NFS junction information. * Otherwise 0 is returned. */ int nfsd4_is_junction(struct dentry *dentry) { … } static struct nfsd4_compound_state *nfsd4_get_cstate(struct svc_rqst *rqstp) { … } __be32 nfsd4_clone_file_range(struct svc_rqst *rqstp, struct nfsd_file *nf_src, u64 src_pos, struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync) { … } ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst, u64 dst_pos, u64 count) { … } __be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, loff_t len, int flags) { … } #endif /* defined(CONFIG_NFSD_V4) */ /* * Check server access rights to a file system object */ struct accessmap { … }; static struct accessmap nfs3_regaccess[] = …; static struct accessmap nfs3_diraccess[] = …; static struct accessmap nfs3_anyaccess[] = …; __be32 nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported) { … } int nfsd_open_break_lease(struct inode *inode, int access) { … } /* * Open an existing file or directory. * The may_flags argument indicates the type of open (read/write/lock) * and additional flags. * N.B. After this call fhp needs an fh_put */ static int __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int may_flags, struct file **filp) { … } __be32 nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int may_flags, struct file **filp) { … } /** * nfsd_open_verified - Open a regular file for the filecache * @rqstp: RPC request * @fhp: NFS filehandle of the file to open * @may_flags: internal permission flags * @filp: OUT: open "struct file *" * * Returns zero on success, or a negative errno value. */ int nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags, struct file **filp) { … } /* * Grab and keep cached pages associated with a file in the svc_rqst * so that they can be passed to the network sendmsg routines * directly. They will be released after the sending has completed. * * Return values: Number of bytes consumed, or -EIO if there are no * remaining pages in rqstp->rq_pages. */ static int nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd) { … } static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) { … } static u32 nfsd_eof_on_read(struct file *file, loff_t offset, ssize_t len, size_t expected) { … } static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, u32 *eof, ssize_t host_err) { … } /** * nfsd_splice_read - Perform a VFS read using a splice pipe * @rqstp: RPC transaction context * @fhp: file handle of file to be read * @file: opened struct file of file to be read * @offset: starting byte offset * @count: IN: requested number of bytes; OUT: number of bytes read * @eof: OUT: set non-zero if operation reached the end of the file * * Returns nfs_ok on success, otherwise an nfserr stat value is * returned. */ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, u32 *eof) { … } /** * nfsd_iter_read - Perform a VFS read using an iterator * @rqstp: RPC transaction context * @fhp: file handle of file to be read * @file: opened struct file of file to be read * @offset: starting byte offset * @count: IN: requested number of bytes; OUT: number of bytes read * @base: offset in first page of read buffer * @eof: OUT: set non-zero if operation reached the end of the file * * Some filesystems or situations cannot use nfsd_splice_read. This * function is the slightly less-performant fallback for those cases. * * Returns nfs_ok on success, otherwise an nfserr stat value is * returned. */ __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, unsigned int base, u32 *eof) { … } /* * Gathered writes: If another process is currently writing to the file, * there's a high chance this is another nfsd (triggered by a bulk write * from a client's biod). Rather than syncing the file with each write * request, we sleep for 10 msec. * * I don't know if this roughly approximates C. Juszak's idea of * gathered writes, but it's a nice and simple solution (IMHO), and it * seems to work:-) * * Note: we do this only in the NFSv2 case, since v3 and higher have a * better tool (separate unstable writes and commits) for solving this * problem. */ static int wait_for_concurrent_writes(struct file *file) { … } __be32 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, loff_t offset, struct kvec *vec, int vlen, unsigned long *cnt, int stable, __be32 *verf) { … } /** * nfsd_read_splice_ok - check if spliced reading is supported * @rqstp: RPC transaction context * * Return values: * %true: nfsd_splice_read() may be used * %false: nfsd_splice_read() must not be used * * NFS READ normally uses splice to send data in-place. However the * data in cache can change after the reply's MIC is computed but * before the RPC reply is sent. To prevent the client from * rejecting the server-computed MIC in this somewhat rare case, do * not use splice with the GSS integrity and privacy services. */ bool nfsd_read_splice_ok(struct svc_rqst *rqstp) { … } /** * nfsd_read - Read data from a file * @rqstp: RPC transaction context * @fhp: file handle of file to be read * @offset: starting byte offset * @count: IN: requested number of bytes; OUT: number of bytes read * @eof: OUT: set non-zero if operation reached the end of the file * * The caller must verify that there is enough space in @rqstp.rq_res * to perform this operation. * * N.B. After this call fhp needs an fh_put * * Returns nfs_ok on success, otherwise an nfserr stat value is * returned. */ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, unsigned long *count, u32 *eof) { … } /* * Write data to a file. * The stable flag requests synchronous writes. * N.B. After this call fhp needs an fh_put */ __be32 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, struct kvec *vec, int vlen, unsigned long *cnt, int stable, __be32 *verf) { … } /** * nfsd_commit - Commit pending writes to stable storage * @rqstp: RPC request being processed * @fhp: NFS filehandle * @nf: target file * @offset: raw offset from beginning of file * @count: raw count of bytes to sync * @verf: filled in with the server's current write verifier * * Note: we guarantee that data that lies within the range specified * by the 'offset' and 'count' parameters will be synced. The server * is permitted to sync data that lies outside this range at the * same time. * * Unfortunately we cannot lock the file to make sure we return full WCC * data to the client, as locking happens lower down in the filesystem. * * Return values: * An nfsstat value in network byte order. */ __be32 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, u64 offset, u32 count, __be32 *verf) { … } /** * nfsd_create_setattr - Set a created file's attributes * @rqstp: RPC transaction being executed * @fhp: NFS filehandle of parent directory * @resfhp: NFS filehandle of new object * @attrs: requested attributes of new object * * Returns nfs_ok on success, or an nfsstat in network byte order. */ __be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct svc_fh *resfhp, struct nfsd_attrs *attrs) { … } /* HPUX client sometimes creates a file in mode 000, and sets size to 0. * setting size to 0 may fail for some specific file systems by the permission * checking which requires WRITE permission but the mode is 000. * we ignore the resizing(to 0) on the just new created file, since the size is * 0 after file created. * * call this only after vfs_create() is called. * */ static void nfsd_check_ignore_resizing(struct iattr *iap) { … } /* The parent directory should already be locked: */ __be32 nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_attrs *attrs, int type, dev_t rdev, struct svc_fh *resfhp) { … } /* * Create a filesystem object (regular, directory, special). * Note that the parent directory is left locked. * * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp */ __be32 nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, struct nfsd_attrs *attrs, int type, dev_t rdev, struct svc_fh *resfhp) { … } /* * Read a symlink. On entry, *lenp must contain the maximum path length that * fits into the buffer. On return, it contains the true length. * N.B. After this call fhp needs an fh_put */ __be32 nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) { … } /** * nfsd_symlink - Create a symlink and look up its inode * @rqstp: RPC transaction being executed * @fhp: NFS filehandle of parent directory * @fname: filename of the new symlink * @flen: length of @fname * @path: content of the new symlink (NUL-terminated) * @attrs: requested attributes of new object * @resfhp: NFS filehandle of new object * * N.B. After this call _both_ fhp and resfhp need an fh_put * * Returns nfs_ok on success, or an nfsstat in network byte order. */ __be32 nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, char *path, struct nfsd_attrs *attrs, struct svc_fh *resfhp) { … } /* * Create a hardlink * N.B. After this call _both_ ffhp and tfhp need an fh_put */ __be32 nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *name, int len, struct svc_fh *tfhp) { … } static void nfsd_close_cached_files(struct dentry *dentry) { … } static bool nfsd_has_cached_files(struct dentry *dentry) { … } /* * Rename a file * N.B. After this call _both_ ffhp and tfhp need an fh_put */ __be32 nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct svc_fh *tfhp, char *tname, int tlen) { … } /* * Unlink a file or directory * N.B. After this call fhp needs an fh_put */ __be32 nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, char *fname, int flen) { … } /* * We do this buffering because we must not call back into the file * system's ->lookup() method from the filldir callback. That may well * deadlock a number of file systems. * * This is based heavily on the implementation of same in XFS. */ struct buffered_dirent { … }; struct readdir_data { … }; static bool nfsd_buffered_filldir(struct dir_context *ctx, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { … } static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp, nfsd_filldir_t func, struct readdir_cd *cdp, loff_t *offsetp) { … } /** * nfsd_readdir - Read entries from a directory * @rqstp: RPC transaction context * @fhp: NFS file handle of directory to be read * @offsetp: OUT: seek offset of final entry that was read * @cdp: OUT: an eof error value * @func: entry filler actor * * This implementation ignores the NFSv3/4 verifier cookie. * * NB: normal system calls hold file->f_pos_lock when calling * ->iterate_shared and ->llseek, but nfsd_readdir() does not. * Because the struct file acquired here is not visible to other * threads, it's internal state does not need mutex protection. * * Returns nfs_ok on success, otherwise an nfsstat code is * returned. */ __be32 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, struct readdir_cd *cdp, nfsd_filldir_t func) { … } /** * nfsd_filp_close: close a file synchronously * @fp: the file to close * * nfsd_filp_close() is similar in behaviour to filp_close(). * The difference is that if this is the final close on the * file, the that finalisation happens immediately, rather then * being handed over to a work_queue, as it the case for * filp_close(). * When a user-space process closes a file (even when using * filp_close() the finalisation happens before returning to * userspace, so it is effectively synchronous. When a kernel thread * uses file_close(), on the other hand, the handling is completely * asynchronous. This means that any cost imposed by that finalisation * is not imposed on the nfsd thread, and nfsd could potentually * close files more quickly than the work queue finalises the close, * which would lead to unbounded growth in the queue. * * In some contexts is it not safe to synchronously wait for * close finalisation (see comment for __fput_sync()), but nfsd * does not match those contexts. In partcilarly it does not, at the * time that this function is called, hold and locks and no finalisation * of any file, socket, or device driver would have any cause to wait * for nfsd to make progress. */ void nfsd_filp_close(struct file *fp) { … } /* * Get file system stats * N.B. After this call fhp needs an fh_put */ __be32 nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) { … } static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp) { … } #ifdef CONFIG_NFSD_V4 /* * Helper function to translate error numbers. In the case of xattr operations, * some error codes need to be translated outside of the standard translations. * * ENODATA needs to be translated to nfserr_noxattr. * E2BIG to nfserr_xattr2big. * * Additionally, vfs_listxattr can return -ERANGE. This means that the * file has too many extended attributes to retrieve inside an * XATTR_LIST_MAX sized buffer. This is a bug in the xattr implementation: * filesystems will allow the adding of extended attributes until they hit * their own internal limit. This limit may be larger than XATTR_LIST_MAX. * So, at that point, the attributes are present and valid, but can't * be retrieved using listxattr, since the upper level xattr code enforces * the XATTR_LIST_MAX limit. * * This bug means that we need to deal with listxattr returning -ERANGE. The * best mapping is to return TOOSMALL. */ static __be32 nfsd_xattr_errno(int err) { … } /* * Retrieve the specified user extended attribute. To avoid always * having to allocate the maximum size (since we are not getting * a maximum size from the RPC), do a probe + alloc. Hold a reader * lock on i_rwsem to prevent the extended attribute from changing * size while we're doing this. */ __be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, void **bufp, int *lenp) { … } /* * Retrieve the xattr names. Since we can't know how many are * user extended attributes, we must get all attributes here, * and have the XDR encode filter out the "user." ones. * * While this could always just allocate an XATTR_LIST_MAX * buffer, that's a waste, so do a probe + allocate. To * avoid any changes between the probe and allocate, wrap * this in inode_lock. */ __be32 nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp, int *lenp) { … } /** * nfsd_removexattr - Remove an extended attribute * @rqstp: RPC transaction being executed * @fhp: NFS filehandle of object with xattr to remove * @name: name of xattr to remove (NUL-terminate) * * Pass in a NULL pointer for delegated_inode, and let the client deal * with NFS4ERR_DELAY (same as with e.g. setattr and remove). * * Returns nfs_ok on success, or an nfsstat in network byte order. */ __be32 nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name) { … } __be32 nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, void *buf, u32 len, u32 flags) { … } #endif /* * Check for a user's access permissions to this inode. */ __be32 nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, struct dentry *dentry, int acc) { … }