Commit e6251ab4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfs-for-5.17-2' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client fixes from Anna Schumaker:
 "Stable Fixes:

   - Fix initialization of nfs_client cl_flags

  Other Fixes:

   - Fix performance issues with uncached readdir calls

   - Fix potential pointer dereferences in rpcrdma_ep_create

   - Fix nfs4_proc_get_locations() kernel-doc comment

   - Fix locking during sunrpc sysfs reads

   - Update my email address in the MAINTAINERS file to my new
     kernel.org email"

* tag 'nfs-for-5.17-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  SUNRPC: lock against ->sock changing during sysfs read
  MAINTAINERS: Update my email address
  NFS: Fix nfs4_proc_get_locations() kernel-doc comment
  xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create
  NFS: Fix initialisation of nfs_client cl_flags field
  NFS: Avoid duplicate uncached readdir calls on eof
  NFS: Don't skip directory entries when doing uncached readdir
  NFS: Don't overfill uncached readdir pages
parents 555f3d7b b49ea673
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13571,7 +13571,7 @@ F: tools/testing/selftests/nci/
NFS, SUNRPC, AND LOCKD CLIENTS
M:	Trond Myklebust <trond.myklebust@hammerspace.com>
M:	Anna Schumaker <anna.schumaker@netapp.com>
M:	Anna Schumaker <anna@kernel.org>
L:	linux-nfs@vger.kernel.org
S:	Maintained
W:	http://client.linux-nfs.org
+1 −1
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
	INIT_LIST_HEAD(&clp->cl_superblocks);
	clp->cl_rpcclient = ERR_PTR(-EINVAL);

	clp->cl_flags = cl_init->init_flags;
	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;
@@ -423,7 +424,6 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
			list_add_tail(&new->cl_share_link,
					&nn->nfs_client_list);
			spin_unlock(&nn->nfs_client_lock);
			new->cl_flags = cl_init->init_flags;
			return rpc_ops->init_client(new, cl_init);
		}

+18 −6
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
		ctx->dir_cookie = 0;
		ctx->dup_cookie = 0;
		ctx->page_index = 0;
		ctx->eof = false;
		spin_lock(&dir->i_lock);
		if (list_empty(&nfsi->open_files) &&
		    (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
@@ -168,6 +169,7 @@ struct nfs_readdir_descriptor {
	unsigned int	cache_entry_index;
	signed char duped;
	bool plus;
	bool eob;
	bool eof;
};

@@ -867,7 +869,8 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,

		status = nfs_readdir_page_filler(desc, entry, pages, pglen,
						 arrays, narrays);
	} while (!status && nfs_readdir_page_needs_filling(page));
	} while (!status && nfs_readdir_page_needs_filling(page) &&
		page_mapping(page));

	nfs_readdir_free_pages(pages, array_size);
out:
@@ -988,7 +991,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
		ent = &array->array[i];
		if (!dir_emit(desc->ctx, ent->name, ent->name_len,
		    nfs_compat_user_ino64(ent->ino), ent->d_type)) {
			desc->eof = true;
			desc->eob = true;
			break;
		}
		memcpy(desc->verf, verf, sizeof(desc->verf));
@@ -1004,7 +1007,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
			desc->duped = 1;
	}
	if (array->page_is_eof)
		desc->eof = true;
		desc->eof = !desc->eob;

	kunmap(desc->page);
	dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %llu\n",
@@ -1041,12 +1044,13 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
		goto out;

	desc->page_index = 0;
	desc->cache_entry_index = 0;
	desc->last_cookie = desc->dir_cookie;
	desc->duped = 0;

	status = nfs_readdir_xdr_to_array(desc, desc->verf, verf, arrays, sz);

	for (i = 0; !desc->eof && i < sz && arrays[i]; i++) {
	for (i = 0; !desc->eob && i < sz && arrays[i]; i++) {
		desc->page = arrays[i];
		nfs_do_filldir(desc, verf);
	}
@@ -1105,9 +1109,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
	desc->duped = dir_ctx->duped;
	page_index = dir_ctx->page_index;
	desc->attr_gencount = dir_ctx->attr_gencount;
	desc->eof = dir_ctx->eof;
	memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));
	spin_unlock(&file->f_lock);

	if (desc->eof) {
		res = 0;
		goto out_free;
	}

	if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) &&
	    list_is_singular(&nfsi->open_files))
		invalidate_mapping_pages(inode->i_mapping, page_index + 1, -1);
@@ -1141,7 +1151,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)

		nfs_do_filldir(desc, nfsi->cookieverf);
		nfs_readdir_page_unlock_and_put_cached(desc);
	} while (!desc->eof);
	} while (!desc->eob && !desc->eof);

	spin_lock(&file->f_lock);
	dir_ctx->dir_cookie = desc->dir_cookie;
@@ -1149,9 +1159,10 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
	dir_ctx->duped = desc->duped;
	dir_ctx->attr_gencount = desc->attr_gencount;
	dir_ctx->page_index = desc->page_index;
	dir_ctx->eof = desc->eof;
	memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf));
	spin_unlock(&file->f_lock);

out_free:
	kfree(desc);

out:
@@ -1193,6 +1204,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
		if (offset == 0)
			memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf));
		dir_ctx->duped = 0;
		dir_ctx->eof = false;
	}
	spin_unlock(&filp->f_lock);
	return offset;
+2 −1
Original line number Diff line number Diff line
@@ -8032,7 +8032,8 @@ static int _nfs41_proc_get_locations(struct nfs_server *server,

/**
 * nfs4_proc_get_locations - discover locations for a migrated FSID
 * @inode: inode on FSID that is migrating
 * @server: pointer to nfs_server to process
 * @fhandle: pointer to the kernel NFS client file handle
 * @locations: result of query
 * @page: buffer
 * @cred: credential to use for this operation
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ struct nfs_open_dir_context {
	__u64 dup_cookie;
	pgoff_t page_index;
	signed char duped;
	bool eof;
};

/*
Loading