Commit 5abc7438 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-6.16-1' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS clent updates from Anna Schumaker:
 "New Features:

   - Implement the Sunrpc rfc2203 rpcsec_gss sequence number cache

   - Add support for FALLOC_FL_ZERO_RANGE on NFS v4.2

   - Add a localio sysfs attribute

  Stable Fixes:

   - Fix double-unlock bug in nfs_return_empty_folio()

   - Don't check for OPEN feature support in v4.1

   - Always probe for LOCALIO support asynchronously

   - Prevent hang on NFS mounts with xprtsec=[m]tls

  Other Bugfixes:

   - xattr handlers should check for absent nfs filehandles

   - Fix setattr caching of TIME_[MODIFY|ACCESS]_SET when timestamps are
     delegated

   - Fix listxattr to return selinux security labels

   - Connect to NFSv3 DS using TLS if MDS connection uses TLS

   - Clear SB_RDONLY before getting a superblock, and ignore when
     remounting

   - Fix incorrect handling of NFS error codes in nfs4_do_mkdir()

   - Various nfs_localio fixes from Neil Brown that include fixing an
     rcu compilation error found by older gcc versions.

   - Update stats on flexfiles pNFS DSes when receiving NFS4ERR_DELAY

  Cleanups:

   - Add a refcount tracker for struct net in the nfs_client

   - Allow FREE_STATEID to clean up delegations

   - Always set NLINK even if the server doesn't support it

   - Cleanups to the NFS folio writeback code

   - Remove dead code from xs_tcp_tls_setup_socket()"

* tag 'nfs-for-6.16-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (30 commits)
  flexfiles/pNFS: update stats on NFS4ERR_DELAY for v4.1 DSes
  nfs_localio: change nfsd_file_put_local() to take a pointer to __rcu pointer
  nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()
  nfs_localio: duplicate nfs_close_local_fh()
  nfs_localio: simplify interface to nfsd for getting nfsd_file
  nfs_localio: always hold nfsd net ref with nfsd_file ref
  nfs_localio: use cmpxchg() to install new nfs_file_localio
  SUNRPC: Remove dead code from xs_tcp_tls_setup_socket()
  SUNRPC: Prevent hang on NFS mount with xprtsec=[m]tls
  nfs: fix incorrect handling of large-number NFS errors in nfs4_do_mkdir()
  nfs: ignore SB_RDONLY when remounting nfs
  nfs: clear SB_RDONLY before getting superblock
  NFS: always probe for LOCALIO support asynchronously
  pnfs/flexfiles: connect to NFSv3 DS using TLS if MDS connection uses TLS
  NFS: add localio to sysfs
  nfs: use writeback_iter directly
  nfs: refactor nfs_do_writepage
  nfs: don't return AOP_WRITEPAGE_ACTIVATE from nfs_do_writepage
  nfs: fold nfs_page_async_flush into nfs_do_writepage
  NFSv4: Always set NLINK even if the server doesn't support it
  ...
parents 6d9b5f6b e3e37753
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
	clp->cl_proto = cl_init->proto;
	clp->cl_nconnect = cl_init->nconnect;
	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
	clp->cl_net = get_net(cl_init->net);
	clp->cl_net = get_net_track(cl_init->net, &clp->cl_ns_tracker, GFP_KERNEL);

#if IS_ENABLED(CONFIG_NFS_LOCALIO)
	seqlock_init(&clp->cl_boot_lock);
@@ -250,7 +250,7 @@ void nfs_free_client(struct nfs_client *clp)
	if (!IS_ERR(clp->cl_rpcclient))
		rpc_shutdown_client(clp->cl_rpcclient);

	put_net(clp->cl_net);
	put_net_track(clp->cl_net, &clp->cl_ns_tracker);
	put_nfs_version(clp->cl_nfs_mod);
	kfree(clp->cl_hostname);
	kfree(clp->cl_acceptor);
@@ -439,7 +439,7 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
			spin_unlock(&nn->nfs_client_lock);
			new = rpc_ops->init_client(new, cl_init);
			if (!IS_ERR(new))
				 nfs_local_probe(new);
				 nfs_local_probe_async(new);
			return new;
		}

+18 −7
Original line number Diff line number Diff line
@@ -1021,13 +1021,6 @@ static void nfs_revoke_delegation(struct inode *inode,
		nfs_inode_find_state_and_recover(inode, stateid);
}

void nfs_remove_bad_delegation(struct inode *inode,
		const nfs4_stateid *stateid)
{
	nfs_revoke_delegation(inode, stateid);
}
EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);

void nfs_delegation_mark_returned(struct inode *inode,
		const nfs4_stateid *stateid)
{
@@ -1069,6 +1062,24 @@ void nfs_delegation_mark_returned(struct inode *inode,
	nfs_inode_find_state_and_recover(inode, stateid);
}

/**
 * nfs_remove_bad_delegation - handle delegations that are unusable
 * @inode: inode to process
 * @stateid: the delegation's stateid
 *
 * If the server ACK-ed our FREE_STATEID then clean
 * up the delegation, else mark and keep the revoked state.
 */
void nfs_remove_bad_delegation(struct inode *inode,
		const nfs4_stateid *stateid)
{
	if (stateid && stateid->type == NFS4_FREED_STATEID_TYPE)
		nfs_delegation_mark_returned(inode, stateid);
	else
		nfs_revoke_delegation(inode, stateid);
}
EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);

/**
 * nfs_expire_unused_delegation_types
 * @clp: client to process
+2 −0
Original line number Diff line number Diff line
@@ -1129,6 +1129,8 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
		nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
		break;
	case -NFS4ERR_DELAY:
		nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY);
		fallthrough;
	case -NFS4ERR_GRACE:
		rpc_delay(task, FF_LAYOUT_POLL_RETRY_MAX);
		break;
+1 −1
Original line number Diff line number Diff line
@@ -400,7 +400,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
		 * keep ds_clp even if DS is local, so that if local IO cannot
		 * proceed somehow, we can fall back to NFS whenever we want.
		 */
		nfs_local_probe(ds->ds_clp);
		nfs_local_probe_async(ds->ds_clp);
		max_payload =
			nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
				       NULL);
+47 −4
Original line number Diff line number Diff line
@@ -557,6 +557,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
			set_nlink(inode, fattr->nlink);
		else if (fattr_supported & NFS_ATTR_FATTR_NLINK)
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
		else
			set_nlink(inode, 1);
		if (fattr->valid & NFS_ATTR_FATTR_OWNER)
			inode->i_uid = fattr->uid;
		else if (fattr_supported & NFS_ATTR_FATTR_OWNER)
@@ -633,6 +635,34 @@ nfs_fattr_fixup_delegated(struct inode *inode, struct nfs_fattr *fattr)
	}
}

static void nfs_set_timestamps_to_ts(struct inode *inode, struct iattr *attr)
{
	unsigned int cache_flags = 0;

	if (attr->ia_valid & ATTR_MTIME_SET) {
		struct timespec64 ctime = inode_get_ctime(inode);
		struct timespec64 mtime = inode_get_mtime(inode);
		struct timespec64 now;
		int updated = 0;

		now = inode_set_ctime_current(inode);
		if (!timespec64_equal(&now, &ctime))
			updated |= S_CTIME;

		inode_set_mtime_to_ts(inode, attr->ia_mtime);
		if (!timespec64_equal(&now, &mtime))
			updated |= S_MTIME;

		inode_maybe_inc_iversion(inode, updated);
		cache_flags |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME;
	}
	if (attr->ia_valid & ATTR_ATIME_SET) {
		inode_set_atime_to_ts(inode, attr->ia_atime);
		cache_flags |= NFS_INO_INVALID_ATIME;
	}
	NFS_I(inode)->cache_validity &= ~cache_flags;
}

static void nfs_update_timestamps(struct inode *inode, unsigned int ia_valid)
{
	enum file_time_flags time_flags = 0;
@@ -701,15 +731,28 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,

	if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) {
		spin_lock(&inode->i_lock);
		if (attr->ia_valid & ATTR_MTIME_SET) {
			nfs_set_timestamps_to_ts(inode, attr);
			attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET|
						ATTR_ATIME|ATTR_ATIME_SET);
		} else {
			nfs_update_timestamps(inode, attr->ia_valid);
		spin_unlock(&inode->i_lock);
			attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME);
		}
		spin_unlock(&inode->i_lock);
	} else if (nfs_have_delegated_atime(inode) &&
		   attr->ia_valid & ATTR_ATIME &&
		   !(attr->ia_valid & ATTR_MTIME)) {
		if (attr->ia_valid & ATTR_ATIME_SET) {
			spin_lock(&inode->i_lock);
			nfs_set_timestamps_to_ts(inode, attr);
			spin_unlock(&inode->i_lock);
			attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET);
		} else {
			nfs_update_delegated_atime(inode);
			attr->ia_valid &= ~ATTR_ATIME;
		}
	}

	/* Optimization: if the end result is no change, don't RPC */
	if (((attr->ia_valid & NFS_VALID_ATTRS) & ~(ATTR_FILE|ATTR_OPEN)) == 0)
Loading