Commit a52a8a6a authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Simplify struct nfs_cache_array_entry



We don't need to store a hash, so replace struct qstr with a simple
const char pointer and length.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Reviewed-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Tested-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Tested-by: default avatarDave Wysochanski <dwysocha@redhat.com>
parent ed09222d
Loading
Loading
Loading
Loading
+25 −21
Original line number Diff line number Diff line
@@ -133,7 +133,8 @@ nfs_closedir(struct inode *inode, struct file *filp)
struct nfs_cache_array_entry {
	u64 cookie;
	u64 ino;
	struct qstr string;
	const char *name;
	unsigned int name_len;
	unsigned char d_type;
};

@@ -192,7 +193,7 @@ void nfs_readdir_clear_array(struct page *page)

	array = kmap_atomic(page);
	for (i = 0; i < array->size; i++)
		kfree(array->array[i].string.name);
		kfree(array->array[i].name);
	nfs_readdir_array_init(array);
	kunmap_atomic(array);
}
@@ -213,20 +214,17 @@ static bool nfs_readdir_array_is_full(struct nfs_cache_array *array)
 * when called by nfs_readdir_add_to_array, the strings will be freed in
 * nfs_clear_readdir_array()
 */
static
int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len)
static const char *nfs_readdir_copy_name(const char *name, unsigned int len)
{
	string->len = len;
	string->name = kmemdup_nul(name, len, GFP_KERNEL);
	if (string->name == NULL)
		return -ENOMEM;
	const char *ret = kmemdup_nul(name, len, GFP_KERNEL);

	/*
	 * Avoid a kmemleak false positive. The pointer to the name is stored
	 * in a page cache page which kmemleak does not scan.
	 */
	kmemleak_not_leak(string->name);
	string->hash = full_name_hash(NULL, name, len);
	return 0;
	if (ret != NULL)
		kmemleak_not_leak(ret);
	return ret;
}

/*
@@ -249,27 +247,34 @@ static int nfs_readdir_array_can_expand(struct nfs_cache_array *array)
static
int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
{
	struct nfs_cache_array *array = kmap(page);
	struct nfs_cache_array *array;
	struct nfs_cache_array_entry *cache_entry;
	const char *name;
	int ret;

	name = nfs_readdir_copy_name(entry->name, entry->len);
	if (!name)
		return -ENOMEM;

	array = kmap_atomic(page);
	ret = nfs_readdir_array_can_expand(array);
	if (ret)
	if (ret) {
		kfree(name);
		goto out;
	}

	cache_entry = &array->array[array->size];
	cache_entry->cookie = entry->prev_cookie;
	cache_entry->ino = entry->ino;
	cache_entry->d_type = entry->d_type;
	ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
	if (ret)
		goto out;
	cache_entry->name_len = entry->len;
	cache_entry->name = name;
	array->last_cookie = entry->cookie;
	array->size++;
	if (entry->eof != 0)
		nfs_readdir_array_set_eof(array);
out:
	kunmap(page);
	kunmap_atomic(array);
	return ret;
}

@@ -413,9 +418,8 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
					if (printk_ratelimit()) {
						pr_notice("NFS: directory %pD2 contains a readdir loop."
								"Please contact your server vendor.  "
								"The file: %.*s has duplicate cookie %llu\n",
								desc->file, array->array[i].string.len,
								array->array[i].string.name, desc->dir_cookie);
								"The file: %s has duplicate cookie %llu\n",
								desc->file, array->array[i].name, desc->dir_cookie);
					}
					status = -ELOOP;
					goto out;
@@ -888,7 +892,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
		struct nfs_cache_array_entry *ent;

		ent = &array->array[i];
		if (!dir_emit(desc->ctx, ent->string.name, ent->string.len,
		if (!dir_emit(desc->ctx, ent->name, ent->name_len,
		    nfs_compat_user_ino64(ent->ino), ent->d_type)) {
			desc->eof = true;
			break;