Commit 6d69b6c1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client updates from Trond Myklebust:
 "Stable fixes:
   - nfs: fix undefined behavior in nfs_block_bits()
   - NFSv4.2: Fix READ_PLUS when server doesn't support OP_READ_PLUS

  Bugfixes:
   - Fix mixing of the lock/nolock and local_lock mount options
   - NFSv4: Fixup smatch warning for ambiguous return
   - NFSv3: Fix remount when using the legacy binary mount api
   - SUNRPC: Fix the handling of expired RPCSEC_GSS contexts
   - SUNRPC: fix the NFSACL RPC retries when soft mounts are enabled
   - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL

  Features and cleanups:
   - NFSv3: Use the atomic_open API to fix open(O_CREAT|O_TRUNC)
   - pNFS/filelayout: S layout segment range in LAYOUTGET
   - pNFS: rework pnfs_generic_pg_check_layout to check IO range
   - NFSv2: Turn off enabling of NFS v2 by default"

* tag 'nfs-for-6.10-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  nfs: fix undefined behavior in nfs_block_bits()
  pNFS: rework pnfs_generic_pg_check_layout to check IO range
  pNFS/filelayout: check layout segment range
  pNFS/filelayout: fixup pNfs allocation modes
  rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL
  NFS: Don't enable NFS v2 by default
  NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS
  sunrpc: fix NFSACL RPC retry on soft mount
  SUNRPC: fix handling expired GSS context
  nfs: keep server info for remounts
  NFSv4: Fixup smatch warning for ambiguous return
  NFS: make sure lock/nolock overriding local_lock mount option
  NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly.
  pNFS/filelayout: Specify the layout segment range in LAYOUTGET
  pNFS/filelayout: Remove the whole file layout requirement
parents b4d88a60 3c0a2e0b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -33,12 +33,12 @@ config NFS_FS
config NFS_V2
	tristate "NFS client support for NFS version 2"
	depends on NFS_FS
	default y
	default n
	help
	  This option enables support for version 2 of the NFS protocol
	  (RFC 1094) in the kernel's NFS client.

	  If unsure, say Y.
	  If unsure, say N.

config NFS_V3
	tristate "NFS client support for NFS version 3"
+51 −3
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ static int nfs_readdir(struct file *, struct dir_context *);
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
static void nfs_readdir_clear_array(struct folio *);
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, int open_flags);

const struct file_operations nfs_dir_operations = {
	.llseek		= nfs_llseek_dir,
@@ -2243,6 +2245,41 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)

#endif /* CONFIG_NFSV4 */

int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
			struct file *file, unsigned int open_flags,
			umode_t mode)
{

	/* Same as look+open from lookup_open(), but with different O_TRUNC
	 * handling.
	 */
	int error = 0;

	if (open_flags & O_CREAT) {
		file->f_mode |= FMODE_CREATED;
		error = nfs_do_create(dir, dentry, mode, open_flags);
		if (error)
			return error;
		return finish_open(file, dentry, NULL);
	} else if (d_in_lookup(dentry)) {
		/* The only flags nfs_lookup considers are
		 * LOOKUP_EXCL and LOOKUP_RENAME_TARGET, and
		 * we want those to be zero so the lookup isn't skipped.
		 */
		struct dentry *res = nfs_lookup(dir, dentry, 0);

		d_lookup_done(dentry);
		if (unlikely(res)) {
			if (IS_ERR(res))
				return PTR_ERR(res);
			return finish_no_open(file, res);
		}
	}
	return finish_no_open(file, NULL);

}
EXPORT_SYMBOL_GPL(nfs_atomic_open_v23);

struct dentry *
nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
				struct nfs_fattr *fattr)
@@ -2303,18 +2340,23 @@ EXPORT_SYMBOL_GPL(nfs_instantiate);
 * that the operation succeeded on the server, but an error in the
 * reply path made it appear to have failed.
 */
int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
	       struct dentry *dentry, umode_t mode, bool excl)
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, int open_flags)
{
	struct iattr attr;
	int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT;
	int error;

	open_flags |= O_CREAT;

	dfprintk(VFS, "NFS: create(%s/%lu), %pd\n",
			dir->i_sb->s_id, dir->i_ino, dentry);

	attr.ia_mode = mode;
	attr.ia_valid = ATTR_MODE;
	if (open_flags & O_TRUNC) {
		attr.ia_size = 0;
		attr.ia_valid |= ATTR_SIZE;
	}

	trace_nfs_create_enter(dir, dentry, open_flags);
	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
@@ -2326,6 +2368,12 @@ int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
	d_drop(dentry);
	return error;
}

int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
	       struct dentry *dentry, umode_t mode, bool excl)
{
	return nfs_do_create(dir, dentry, mode, excl ? O_EXCL : 0);
}
EXPORT_SYMBOL_GPL(nfs_create);

/*
+8 −16
Original line number Diff line number Diff line
@@ -605,14 +605,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,

	dprintk("--> %s\n", __func__);

	/* FIXME: remove this check when layout segment support is added */
	if (lgr->range.offset != 0 ||
	    lgr->range.length != NFS4_MAX_UINT64) {
		dprintk("%s Only whole file layouts supported. Use MDS i/o\n",
			__func__);
		goto out;
	}

	if (fl->pattern_offset > lgr->range.offset) {
		dprintk("%s pattern_offset %lld too large\n",
				__func__, fl->pattern_offset);
@@ -875,15 +867,15 @@ static void
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
			struct nfs_page *req)
{
	pnfs_generic_pg_check_layout(pgio);
	pnfs_generic_pg_check_layout(pgio, req);
	if (!pgio->pg_lseg) {
		pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
						      nfs_req_openctx(req),
						      0,
						      NFS4_MAX_UINT64,
						      req_offset(req),
						      req->wb_bytes,
						      IOMODE_READ,
						      false,
						      GFP_KERNEL);
						      nfs_io_gfp_mask());
		if (IS_ERR(pgio->pg_lseg)) {
			pgio->pg_error = PTR_ERR(pgio->pg_lseg);
			pgio->pg_lseg = NULL;
@@ -899,15 +891,15 @@ static void
filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
			 struct nfs_page *req)
{
	pnfs_generic_pg_check_layout(pgio);
	pnfs_generic_pg_check_layout(pgio, req);
	if (!pgio->pg_lseg) {
		pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
						      nfs_req_openctx(req),
						      0,
						      NFS4_MAX_UINT64,
						      req_offset(req),
						      req->wb_bytes,
						      IOMODE_RW,
						      false,
						      GFP_NOFS);
						      nfs_io_gfp_mask());
		if (IS_ERR(pgio->pg_lseg)) {
			pgio->pg_error = PTR_ERR(pgio->pg_lseg);
			pgio->pg_lseg = NULL;
+2 −10
Original line number Diff line number Diff line
@@ -822,14 +822,6 @@ ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
	}
}

static void
ff_layout_pg_check_layout(struct nfs_pageio_descriptor *pgio,
			  struct nfs_page *req)
{
	pnfs_generic_pg_check_layout(pgio);
	pnfs_generic_pg_check_range(pgio, req);
}

static void
ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
			struct nfs_page *req)
@@ -840,7 +832,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
	u32 ds_idx;

retry:
	ff_layout_pg_check_layout(pgio, req);
	pnfs_generic_pg_check_layout(pgio, req);
	/* Use full layout for now */
	if (!pgio->pg_lseg) {
		ff_layout_pg_get_read(pgio, req, false);
@@ -895,7 +887,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
	u32 i;

retry:
	ff_layout_pg_check_layout(pgio, req);
	pnfs_generic_pg_check_layout(pgio, req);
	if (!pgio->pg_lseg) {
		pgio->pg_lseg =
			pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
+8 −3
Original line number Diff line number Diff line
@@ -600,9 +600,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
		break;
	case Opt_lock:
		if (result.negated) {
			ctx->lock_status = NFS_LOCK_NOLOCK;
			ctx->flags |= NFS_MOUNT_NONLM;
			ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
		} else {
			ctx->lock_status = NFS_LOCK_LOCK;
			ctx->flags &= ~NFS_MOUNT_NONLM;
			ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
		}
@@ -1112,9 +1114,12 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
		ctx->acdirmax	= data->acdirmax;
		ctx->need_mount	= false;

		if (!is_remount_fc(fc)) {
			memcpy(sap, &data->addr, sizeof(data->addr));
			ctx->nfs_server.addrlen = sizeof(data->addr);
			ctx->nfs_server.port = ntohs(data->addr.sin_port);
		}

		if (sap->ss_family != AF_INET ||
		    !nfs_verify_server_address(sap))
			goto out_no_address;
Loading