aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:57 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:58 -0500
commit58df095b732529ade8f4051b41d7c29731afecd6 (patch)
tree917819b96bac91e5daea7a31eb6eba66268952d9 /fs
parent0065db328533c390fbfb0fe0c46bcf9a278fb99e (diff)
NFSv4: Allow entries in the idmap cache to expire
If someone changes the uid/gid mapping in userland, then we do eventually want those changes to be propagated to the kernel. Currently the kernel assumes that it may cache entries forever. Add an expiration time + garbage collector for idmap entries. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/idmap.c9
-rw-r--r--fs/nfs/inode.c14
-rw-r--r--fs/nfs/sysctl.c10
3 files changed, 33 insertions, 0 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index ffb8df91dc34..821edd30333b 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -54,7 +54,11 @@
54 54
55#define IDMAP_HASH_SZ 128 55#define IDMAP_HASH_SZ 128
56 56
57/* Default cache timeout is 10 minutes */
58unsigned int nfs_idmap_cache_timeout = 600 * HZ;
59
57struct idmap_hashent { 60struct idmap_hashent {
61 unsigned long ih_expires;
58 __u32 ih_id; 62 __u32 ih_id;
59 int ih_namelen; 63 int ih_namelen;
60 char ih_name[IDMAP_NAMESZ]; 64 char ih_name[IDMAP_NAMESZ];
@@ -149,6 +153,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
149 153
150 if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0) 154 if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
151 return NULL; 155 return NULL;
156 if (time_after(jiffies, he->ih_expires))
157 return NULL;
152 return he; 158 return he;
153} 159}
154 160
@@ -164,6 +170,8 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
164 struct idmap_hashent *he = idmap_id_hash(h, id); 170 struct idmap_hashent *he = idmap_id_hash(h, id);
165 if (he->ih_id != id || he->ih_namelen == 0) 171 if (he->ih_id != id || he->ih_namelen == 0)
166 return NULL; 172 return NULL;
173 if (time_after(jiffies, he->ih_expires))
174 return NULL;
167 return he; 175 return he;
168} 176}
169 177
@@ -192,6 +200,7 @@ idmap_update_entry(struct idmap_hashent *he, const char *name,
192 memcpy(he->ih_name, name, namelen); 200 memcpy(he->ih_name, name, namelen);
193 he->ih_name[namelen] = '\0'; 201 he->ih_name[namelen] = '\0';
194 he->ih_namelen = namelen; 202 he->ih_namelen = namelen;
203 he->ih_expires = jiffies + nfs_idmap_cache_timeout;
195} 204}
196 205
197/* 206/*
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 4625479a6b62..e7bd0d92600f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -2050,6 +2050,20 @@ static int param_set_port(const char *val, struct kernel_param *kp)
2050module_param_call(callback_tcpport, param_set_port, param_get_int, 2050module_param_call(callback_tcpport, param_set_port, param_get_int,
2051 &nfs_callback_set_tcpport, 0644); 2051 &nfs_callback_set_tcpport, 0644);
2052 2052
2053static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
2054{
2055 char *endp;
2056 int num = simple_strtol(val, &endp, 0);
2057 int jif = num * HZ;
2058 if (endp == val || *endp || num < 0 || jif < num)
2059 return -EINVAL;
2060 *((int *)kp->arg) = jif;
2061 return 0;
2062}
2063
2064module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
2065 &nfs_idmap_cache_timeout, 0644);
2066
2053#define nfs4_init_once(nfsi) \ 2067#define nfs4_init_once(nfsi) \
2054 do { \ 2068 do { \
2055 INIT_LIST_HEAD(&(nfsi)->open_states); \ 2069 INIT_LIST_HEAD(&(nfsi)->open_states); \
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index fdc64b59a4ee..4c486eb867ca 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -11,6 +11,7 @@
11#include <linux/sysctl.h> 11#include <linux/sysctl.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/nfs4.h> 13#include <linux/nfs4.h>
14#include <linux/nfs_idmap.h>
14 15
15#include "callback.h" 16#include "callback.h"
16 17
@@ -35,6 +36,15 @@ static ctl_table nfs_cb_sysctls[] = {
35 .extra1 = (int *)&nfs_set_port_min, 36 .extra1 = (int *)&nfs_set_port_min,
36 .extra2 = (int *)&nfs_set_port_max, 37 .extra2 = (int *)&nfs_set_port_max,
37 }, 38 },
39 {
40 .ctl_name = CTL_UNNUMBERED,
41 .procname = "idmap_cache_timeout",
42 .data = &nfs_idmap_cache_timeout,
43 .maxlen = sizeof(int),
44 .mode = 0644,
45 .proc_handler = &proc_dointvec_jiffies,
46 .strategy = &sysctl_jiffies,
47 },
38#endif 48#endif
39 { .ctl_name = 0 } 49 { .ctl_name = 0 }
40}; 50};