NFSv4: Reduce the footprint of the idmapper (Closes: #657078)

svn path=/dists/sid/linux/; revision=19096
This commit is contained in:
Ben Hutchings 2012-06-07 13:57:50 +00:00
parent de6102258b
commit 1f51066386
4 changed files with 190 additions and 0 deletions

1
debian/changelog vendored
View File

@ -22,6 +22,7 @@ linux (3.2.19-2) UNRELEASED; urgency=low
* filter: Allow to create sk-unattached filters
* net: Backport team driver from Linux 3.5-rc1
* proc: Backport hidepid mount option from Linux 3.4 (Closes: #669028)
* NFSv4: Reduce the footprint of the idmapper (Closes: #657078)
-- Ben Hutchings <ben@decadent.org.uk> Sat, 02 Jun 2012 20:31:53 +0100

View File

@ -0,0 +1,124 @@
From: Trond Myklebust <Trond.Myklebust@netapp.com>
Date: Wed, 8 Feb 2012 13:39:15 -0500
Subject: [2/2] NFSv4: Further reduce the footprint of the idmapper
commit 685f50f9188ac1e8244d0340a9d6ea36b6136cec upstream.
Don't allocate the legacy idmapper tables until we actually need
them.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
[bwh: Backported to 3.2: adjust context in nfs_idmap_delete()]
---
fs/nfs/idmap.c | 42 ++++++++++++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 6 deletions(-)
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -323,7 +323,7 @@
struct idmap_hashtable {
__u8 h_type;
- struct idmap_hashent h_entries[IDMAP_HASH_SZ];
+ struct idmap_hashent *h_entries;
};
struct idmap {
@@ -378,20 +378,39 @@
return 0;
}
+static void
+idmap_alloc_hashtable(struct idmap_hashtable *h)
+{
+ if (h->h_entries != NULL)
+ return;
+ h->h_entries = kcalloc(IDMAP_HASH_SZ,
+ sizeof(*h->h_entries),
+ GFP_KERNEL);
+}
+
+static void
+idmap_free_hashtable(struct idmap_hashtable *h)
+{
+ int i;
+
+ if (h->h_entries == NULL)
+ return;
+ for (i = 0; i < IDMAP_HASH_SZ; i++)
+ kfree(h->h_entries[i].ih_name);
+ kfree(h->h_entries);
+}
+
void
nfs_idmap_delete(struct nfs_client *clp)
{
struct idmap *idmap = clp->cl_idmap;
- int i;
if (!idmap)
return;
rpc_unlink(idmap->idmap_dentry);
clp->cl_idmap = NULL;
- for (i = 0; i < ARRAY_SIZE(idmap->idmap_user_hash.h_entries); i++)
- kfree(idmap->idmap_user_hash.h_entries[i].ih_name);
- for (i = 0; i < ARRAY_SIZE(idmap->idmap_group_hash.h_entries); i++)
- kfree(idmap->idmap_group_hash.h_entries[i].ih_name);
+ idmap_free_hashtable(&idmap->idmap_user_hash);
+ idmap_free_hashtable(&idmap->idmap_group_hash);
kfree(idmap);
}
@@ -401,6 +420,8 @@
static inline struct idmap_hashent *
idmap_name_hash(struct idmap_hashtable* h, const char *name, size_t len)
{
+ if (h->h_entries == NULL)
+ return NULL;
return &h->h_entries[fnvhash32(name, len) % IDMAP_HASH_SZ];
}
@@ -409,6 +430,8 @@
{
struct idmap_hashent *he = idmap_name_hash(h, name, len);
+ if (he == NULL)
+ return NULL;
if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
return NULL;
if (time_after(jiffies, he->ih_expires))
@@ -419,6 +442,8 @@
static inline struct idmap_hashent *
idmap_id_hash(struct idmap_hashtable* h, __u32 id)
{
+ if (h->h_entries == NULL)
+ return NULL;
return &h->h_entries[fnvhash32(&id, sizeof(id)) % IDMAP_HASH_SZ];
}
@@ -426,6 +451,9 @@
idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
{
struct idmap_hashent *he = idmap_id_hash(h, id);
+
+ if (he == NULL)
+ return NULL;
if (he->ih_id != id || he->ih_namelen == 0)
return NULL;
if (time_after(jiffies, he->ih_expires))
@@ -441,12 +469,14 @@
static inline struct idmap_hashent *
idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len)
{
+ idmap_alloc_hashtable(h);
return idmap_name_hash(h, name, len);
}
static inline struct idmap_hashent *
idmap_alloc_id(struct idmap_hashtable *h, __u32 id)
{
+ idmap_alloc_hashtable(h);
return idmap_id_hash(h, id);
}

View File

@ -0,0 +1,62 @@
From: Trond Myklebust <Trond.Myklebust@netapp.com>
Date: Tue, 7 Feb 2012 14:59:05 -0500
Subject: [1/2] NFSv4: Reduce the footprint of the idmapper
commit d073e9b541e1ac3f52d72c3a153855d9a9ee3278 upstream.
Instead of pre-allocating the storage for all the strings, we can
significantly reduce the size of that table by doing the allocation
when we do the downcall.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
[bwh: Backported to 3.2: adjust context in nfs_idmap_delete()]
---
fs/nfs/idmap.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -318,7 +318,7 @@
unsigned long ih_expires;
__u32 ih_id;
size_t ih_namelen;
- char ih_name[IDMAP_NAMESZ];
+ const char *ih_name;
};
struct idmap_hashtable {
@@ -382,11 +382,16 @@
nfs_idmap_delete(struct nfs_client *clp)
{
struct idmap *idmap = clp->cl_idmap;
+ int i;
if (!idmap)
return;
rpc_unlink(idmap->idmap_dentry);
clp->cl_idmap = NULL;
+ for (i = 0; i < ARRAY_SIZE(idmap->idmap_user_hash.h_entries); i++)
+ kfree(idmap->idmap_user_hash.h_entries[i].ih_name);
+ for (i = 0; i < ARRAY_SIZE(idmap->idmap_group_hash.h_entries); i++)
+ kfree(idmap->idmap_group_hash.h_entries[i].ih_name);
kfree(idmap);
}
@@ -449,9 +454,14 @@
idmap_update_entry(struct idmap_hashent *he, const char *name,
size_t namelen, __u32 id)
{
+ char *str = kmalloc(namelen + 1, GFP_KERNEL);
+ if (str == NULL)
+ return;
+ kfree(he->ih_name);
he->ih_id = id;
- memcpy(he->ih_name, name, namelen);
- he->ih_name[namelen] = '\0';
+ memcpy(str, name, namelen);
+ str[namelen] = '\0';
+ he->ih_name = str;
he->ih_namelen = namelen;
he->ih_expires = jiffies + nfs_idmap_cache_timeout;
}

View File

@ -343,3 +343,6 @@ features/all/hidepid/0001-procfs-parse-mount-options.patch
features/all/hidepid/0002-procfs-add-hidepid-and-gid-mount-options.patch
features/all/hidepid/0003-proc-fix-null-pointer-deref-in-proc_pid_permission.patch
features/all/hidepid/0004-proc-fix-mount-t-proc-o-AAA.patch
bugfix/all/NFSv4-Reduce-the-footprint-of-the-idmapper.patch
bugfix/all/NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch