Commit 6bc986ab authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client updates from Trond Myklebust:
 "Bugfixes:

   - SUNRPC:
       - re-probe the target RPC port after an ECONNRESET error
       - handle allocation errors from rpcb_call_async()
       - fix a use-after-free condition in rpc_pipefs
       - fix up various checks for timeouts

   - NFSv4.1:
       - Handle NFS4ERR_DELAY errors during session trunking
       - fix SP4_MACH_CRED protection for pnfs IO

   - NFSv4:
       - Ensure that we test all delegations when the server notifies
         us that it may have revoked some of them

  Features:

   - Allow knfsd processes to break out of NFS4ERR_DELAY loops when
     re-exporting NFSv4.x by setting appropriate values for the
     'delay_retrans' module parameter

   - nfs: Convert nfs_symlink() to use a folio"

* tag 'nfs-for-6.7-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  nfs: Convert nfs_symlink() to use a folio
  SUNRPC: Fix RPC client cleaned up the freed pipefs dentries
  NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO
  SUNRPC: Add an IS_ERR() check back to where it was
  NFSv4.1: fix handling NFS4ERR_DELAY when testing for session trunking
  nfs41: drop dependency between flexfiles layout driver and NFSv3 modules
  NFSv4: fairly test all delegations on a SEQ4_ revocation
  SUNRPC: SOFTCONN tasks should time out when on the sending list
  SUNRPC: Force close the socket when a hard error is reported
  SUNRPC: Don't skip timeout checks in call_connect_status()
  SUNRPC: ECONNRESET might require a rebind
  NFSv4/pnfs: Allow layoutget to return EAGAIN for softerr mounts
  NFSv4: Add a parameter to limit the number of retries after NFS4ERR_DELAY
parents 67c0afb6 f003a717
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3596,6 +3596,13 @@
			[NFS] set the TCP port on which the NFSv4 callback
			channel should listen.

	nfs.delay_retrans=
			[NFS] specifies the number of times the NFSv4 client
			retries the request before returning an EAGAIN error,
			after a reply of NFS4ERR_DELAY from the server.
			Only applies if the softerr mount option is enabled,
			and the specified value is >= 0.

	nfs.enable_ino64=
			[NFS] enable 64-bit inode numbers.
			If zero, the NFS client will fake up a 32-bit inode
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ config PNFS_BLOCK

config PNFS_FLEXFILE_LAYOUT
	tristate
	depends on NFS_V4_1 && NFS_V3
	depends on NFS_V4_1
	default NFS_V4

config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
+6 −1
Original line number Diff line number Diff line
@@ -448,6 +448,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
	delegation->cred = get_cred(cred);
	delegation->inode = inode;
	delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
	delegation->test_gen = 0;
	spin_lock_init(&delegation->lock);

	spin_lock(&clp->cl_lock);
@@ -1294,6 +1295,8 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
	struct inode *inode;
	const struct cred *cred;
	nfs4_stateid stateid;
	unsigned long gen = ++server->delegation_gen;

restart:
	rcu_read_lock();
restart_locked:
@@ -1303,7 +1306,8 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
		    test_bit(NFS_DELEGATION_RETURNING,
					&delegation->flags) ||
		    test_bit(NFS_DELEGATION_TEST_EXPIRED,
					&delegation->flags) == 0)
					&delegation->flags) == 0 ||
			delegation->test_gen == gen)
			continue;
		inode = nfs_delegation_grab_inode(delegation);
		if (inode == NULL)
@@ -1312,6 +1316,7 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
		cred = get_cred_rcu(delegation->cred);
		nfs4_stateid_copy(&stateid, &delegation->stateid);
		spin_unlock(&delegation->lock);
		delegation->test_gen = gen;
		clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
		rcu_read_unlock();
		nfs_delegation_test_free_expired(inode, &stateid, cred);
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ struct nfs_delegation {
	fmode_t type;
	unsigned long pagemod_limit;
	__u64 change_attr;
	unsigned long test_gen;
	unsigned long flags;
	refcount_t refcount;
	spinlock_t lock;
+12 −17
Original line number Diff line number Diff line
@@ -2532,7 +2532,7 @@ EXPORT_SYMBOL_GPL(nfs_unlink);
int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
		struct dentry *dentry, const char *symname)
{
	struct page *page;
	struct folio *folio;
	char *kaddr;
	struct iattr attr;
	unsigned int pathlen = strlen(symname);
@@ -2547,24 +2547,24 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
	attr.ia_mode = S_IFLNK | S_IRWXUGO;
	attr.ia_valid = ATTR_MODE;

	page = alloc_page(GFP_USER);
	if (!page)
	folio = folio_alloc(GFP_USER, 0);
	if (!folio)
		return -ENOMEM;

	kaddr = page_address(page);
	kaddr = folio_address(folio);
	memcpy(kaddr, symname, pathlen);
	if (pathlen < PAGE_SIZE)
		memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);

	trace_nfs_symlink_enter(dir, dentry);
	error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
	error = NFS_PROTO(dir)->symlink(dir, dentry, folio, pathlen, &attr);
	trace_nfs_symlink_exit(dir, dentry, error);
	if (error != 0) {
		dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s) error %d\n",
			dir->i_sb->s_id, dir->i_ino,
			dentry, symname, error);
		d_drop(dentry);
		__free_page(page);
		folio_put(folio);
		return error;
	}

@@ -2574,18 +2574,13 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
	 * No big deal if we can't add this page to the page cache here.
	 * READLINK will get the missing page from the server if needed.
	 */
	if (!add_to_page_cache_lru(page, d_inode(dentry)->i_mapping, 0,
							GFP_KERNEL)) {
		SetPageUptodate(page);
		unlock_page(page);
		/*
		 * add_to_page_cache_lru() grabs an extra page refcount.
		 * Drop it here to avoid leaking this page later.
		 */
		put_page(page);
	} else
		__free_page(page);
	if (filemap_add_folio(d_inode(dentry)->i_mapping, folio, 0,
							GFP_KERNEL) == 0) {
		folio_mark_uptodate(folio);
		folio_unlock(folio);
	}

	folio_put(folio);
	return 0;
}
EXPORT_SYMBOL_GPL(nfs_symlink);
Loading