Commit 6bb34aff authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client updates from Trond Myklebust:
 "Bugfixes:
   - Fix 'nlink' attribute update races when unlinking a file
   - Add missing initialisers for the directory verifier in various
     places
   - Don't regress the NFSv4 open state due to misordered racing replies
   - Ensure the NFSv4.x callback server uses the correct transport
     connection
   - Fix potential use-after-free races when shutting down the NFSv4.x
     callback server
   - Fix a pNFS layout commit crash
   - Assorted fixes to ensure correct propagation of mount options when
     the client crosses a filesystem boundary and triggers the VFS
     automount code
   - More localio fixes

  Features and cleanups:
   - Add initial support for basic directory delegations
   - SunRPC back channel code cleanups"

* tag 'nfs-for-6.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (24 commits)
  NFSv4: Handle NFS4ERR_NOTSUPP errors for directory delegations
  nfs/localio: remove 61 byte hole from needless ____cacheline_aligned
  nfs/localio: remove alignment size checking in nfs_is_local_dio_possible
  NFS: Fix up the automount fs_context to use the correct cred
  NFS: Fix inheritance of the block sizes when automounting
  NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags
  Revert "nfs: ignore SB_RDONLY when mounting nfs"
  Revert "nfs: clear SB_RDONLY before getting superblock"
  Revert "nfs: ignore SB_RDONLY when remounting nfs"
  NFS: Add a module option to disable directory delegations
  NFS: Shortcut lookup revalidations if we have a directory delegation
  NFS: Request a directory delegation during RENAME
  NFS: Request a directory delegation on ACCESS, CREATE, and UNLINK
  NFS: Add support for sending GDD_GETATTR
  NFSv4/pNFS: Clear NFS_INO_LAYOUTCOMMIT in pnfs_mark_layout_stateid_invalid
  NFSv4.1: protect destroying and nullifying bc_serv structure
  SUNRPC: new helper function for stopping backchannel server
  SUNRPC: cleanup common code in backchannel request
  NFSv4.1: pass transport for callback shutdown
  NFSv4: ensure the open stateid seqid doesn't go backwards
  ...
parents d358e525 bd3b04b4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
/*
 * Kill the callback thread if it's no longer being used.
 */
void nfs_callback_down(int minorversion, struct net *net)
void nfs_callback_down(int minorversion, struct net *net, struct rpc_xprt *xprt)
{
	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
	struct svc_serv *serv;
@@ -270,7 +270,7 @@ void nfs_callback_down(int minorversion, struct net *net)
	if (cb_info->users == 0) {
		svc_set_num_threads(serv, NULL, 0);
		dprintk("nfs_callback_down: service destroyed\n");
		svc_destroy(&cb_info->serv);
		xprt_svc_destroy_nullify_bc(xprt, &cb_info->serv);
	}
	mutex_unlock(&nfs_callback_mutex);
}
+2 −1
Original line number Diff line number Diff line
@@ -188,7 +188,8 @@ extern __be32 nfs4_callback_recall(void *argp, void *resp,
				   struct cb_process_state *cps);
#if IS_ENABLED(CONFIG_NFS_V4)
extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
extern void nfs_callback_down(int minorversion, struct net *net);
extern void nfs_callback_down(int minorversion, struct net *net,
			      struct rpc_xprt *xprt);
#endif /* CONFIG_NFS_V4 */
/*
 * nfs41: Callbacks are expected to not cause substantial latency,
+17 −4
Original line number Diff line number Diff line
@@ -784,10 +784,18 @@ static int nfs_init_server(struct nfs_server *server,
		server->fattr_valid = NFS_ATTR_FATTR_V4;
	}

	if (ctx->rsize)
	if (ctx->bsize) {
		server->bsize = ctx->bsize;
		server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE;
	}
	if (ctx->rsize) {
		server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto);
	if (ctx->wsize)
		server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE;
	}
	if (ctx->wsize) {
		server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto);
		server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE;
	}

	server->acregmin = ctx->acregmin * HZ;
	server->acregmax = ctx->acregmax * HZ;
@@ -977,7 +985,12 @@ EXPORT_SYMBOL_GPL(nfs_probe_server);
void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
{
	target->flags = source->flags;
	target->automount_inherit = source->automount_inherit;
	if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE)
		target->bsize = source->bsize;
	if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_RSIZE)
		target->rsize = source->rsize;
	if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_WSIZE)
		target->wsize = source->wsize;
	target->acregmin = source->acregmin;
	target->acregmax = source->acregmax;
+8 −0
Original line number Diff line number Diff line
@@ -30,6 +30,11 @@
static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK;
module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);

bool directory_delegations = true;
module_param(directory_delegations, bool, 0644);
MODULE_PARM_DESC(directory_delegations,
		 "Enable the use of directory delegations, defaults to on.");

static struct hlist_head *nfs_delegation_hash(struct nfs_server *server,
		const struct nfs_fh *fhandle)
{
@@ -143,6 +148,8 @@ static int nfs4_do_check_delegation(struct inode *inode, fmode_t type,
 */
int nfs4_have_delegation(struct inode *inode, fmode_t type, int flags)
{
	if (S_ISDIR(inode->i_mode) && !directory_delegations)
		nfs_inode_evict_delegation(inode);
	return nfs4_do_check_delegation(inode, type, flags, true);
}

@@ -379,6 +386,7 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi,
	delegation->inode = NULL;
	rcu_assign_pointer(nfsi->delegation, NULL);
	spin_unlock(&delegation->lock);
	clear_bit(NFS_INO_REQ_DIR_DELEG, &nfsi->flags);
	return delegation;
}

+13 −0
Original line number Diff line number Diff line
@@ -124,6 +124,19 @@ static inline int nfs_have_delegated_mtime(struct inode *inode)
						 NFS_DELEGATION_FLAG_TIME);
}

extern bool directory_delegations;

static inline void nfs_request_directory_delegation(struct inode *inode)
{
	if (S_ISDIR(inode->i_mode))
		set_bit(NFS_INO_REQ_DIR_DELEG, &NFS_I(inode)->flags);
}

static inline bool nfs_have_directory_delegation(struct inode *inode)
{
	return S_ISDIR(inode->i_mode) && nfs_have_delegated_attributes(inode);
}

int nfs4_delegation_hash_alloc(struct nfs_server *server);

#endif
Loading