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: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Benjamin Coddington <bcodding@redhat.com> Tested-by: Benjamin Coddington <bcodding@redhat.com> Tested-by: Dave Wysochanski <dwysocha@redhat.com>
This commit is contained in:
parent
ed09222d65
commit
a52a8a6ada
46
fs/nfs/dir.c
46
fs/nfs/dir.c
|
@ -133,7 +133,8 @@ nfs_closedir(struct inode *inode, struct file *filp)
|
||||||
struct nfs_cache_array_entry {
|
struct nfs_cache_array_entry {
|
||||||
u64 cookie;
|
u64 cookie;
|
||||||
u64 ino;
|
u64 ino;
|
||||||
struct qstr string;
|
const char *name;
|
||||||
|
unsigned int name_len;
|
||||||
unsigned char d_type;
|
unsigned char d_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,7 +193,7 @@ void nfs_readdir_clear_array(struct page *page)
|
||||||
|
|
||||||
array = kmap_atomic(page);
|
array = kmap_atomic(page);
|
||||||
for (i = 0; i < array->size; i++)
|
for (i = 0; i < array->size; i++)
|
||||||
kfree(array->array[i].string.name);
|
kfree(array->array[i].name);
|
||||||
nfs_readdir_array_init(array);
|
nfs_readdir_array_init(array);
|
||||||
kunmap_atomic(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
|
* when called by nfs_readdir_add_to_array, the strings will be freed in
|
||||||
* nfs_clear_readdir_array()
|
* nfs_clear_readdir_array()
|
||||||
*/
|
*/
|
||||||
static
|
static const char *nfs_readdir_copy_name(const char *name, unsigned int len)
|
||||||
int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len)
|
|
||||||
{
|
{
|
||||||
string->len = len;
|
const char *ret = kmemdup_nul(name, len, GFP_KERNEL);
|
||||||
string->name = kmemdup_nul(name, len, GFP_KERNEL);
|
|
||||||
if (string->name == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
/*
|
/*
|
||||||
* Avoid a kmemleak false positive. The pointer to the name is stored
|
* Avoid a kmemleak false positive. The pointer to the name is stored
|
||||||
* in a page cache page which kmemleak does not scan.
|
* in a page cache page which kmemleak does not scan.
|
||||||
*/
|
*/
|
||||||
kmemleak_not_leak(string->name);
|
if (ret != NULL)
|
||||||
string->hash = full_name_hash(NULL, name, len);
|
kmemleak_not_leak(ret);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -249,27 +247,34 @@ static int nfs_readdir_array_can_expand(struct nfs_cache_array *array)
|
||||||
static
|
static
|
||||||
int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
|
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;
|
struct nfs_cache_array_entry *cache_entry;
|
||||||
|
const char *name;
|
||||||
int ret;
|
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);
|
ret = nfs_readdir_array_can_expand(array);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
kfree(name);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
cache_entry = &array->array[array->size];
|
cache_entry = &array->array[array->size];
|
||||||
cache_entry->cookie = entry->prev_cookie;
|
cache_entry->cookie = entry->prev_cookie;
|
||||||
cache_entry->ino = entry->ino;
|
cache_entry->ino = entry->ino;
|
||||||
cache_entry->d_type = entry->d_type;
|
cache_entry->d_type = entry->d_type;
|
||||||
ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
|
cache_entry->name_len = entry->len;
|
||||||
if (ret)
|
cache_entry->name = name;
|
||||||
goto out;
|
|
||||||
array->last_cookie = entry->cookie;
|
array->last_cookie = entry->cookie;
|
||||||
array->size++;
|
array->size++;
|
||||||
if (entry->eof != 0)
|
if (entry->eof != 0)
|
||||||
nfs_readdir_array_set_eof(array);
|
nfs_readdir_array_set_eof(array);
|
||||||
out:
|
out:
|
||||||
kunmap(page);
|
kunmap_atomic(array);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,9 +418,8 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
|
||||||
if (printk_ratelimit()) {
|
if (printk_ratelimit()) {
|
||||||
pr_notice("NFS: directory %pD2 contains a readdir loop."
|
pr_notice("NFS: directory %pD2 contains a readdir loop."
|
||||||
"Please contact your server vendor. "
|
"Please contact your server vendor. "
|
||||||
"The file: %.*s has duplicate cookie %llu\n",
|
"The file: %s has duplicate cookie %llu\n",
|
||||||
desc->file, array->array[i].string.len,
|
desc->file, array->array[i].name, desc->dir_cookie);
|
||||||
array->array[i].string.name, desc->dir_cookie);
|
|
||||||
}
|
}
|
||||||
status = -ELOOP;
|
status = -ELOOP;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -888,7 +892,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
|
||||||
struct nfs_cache_array_entry *ent;
|
struct nfs_cache_array_entry *ent;
|
||||||
|
|
||||||
ent = &array->array[i];
|
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)) {
|
nfs_compat_user_ino64(ent->ino), ent->d_type)) {
|
||||||
desc->eof = true;
|
desc->eof = true;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue