aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcookies.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcookies.c')
-rw-r--r--fs/dcookies.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/fs/dcookies.c b/fs/dcookies.c
index 855d4b1d619a..a21cabdbd87b 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -93,10 +93,15 @@ static struct dcookie_struct *alloc_dcookie(struct path *path)
93{ 93{
94 struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache, 94 struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache,
95 GFP_KERNEL); 95 GFP_KERNEL);
96 struct dentry *d;
96 if (!dcs) 97 if (!dcs)
97 return NULL; 98 return NULL;
98 99
99 path->dentry->d_cookie = dcs; 100 d = path->dentry;
101 spin_lock(&d->d_lock);
102 d->d_flags |= DCACHE_COOKIE;
103 spin_unlock(&d->d_lock);
104
100 dcs->path = *path; 105 dcs->path = *path;
101 path_get(path); 106 path_get(path);
102 hash_dcookie(dcs); 107 hash_dcookie(dcs);
@@ -119,14 +124,14 @@ int get_dcookie(struct path *path, unsigned long *cookie)
119 goto out; 124 goto out;
120 } 125 }
121 126
122 dcs = path->dentry->d_cookie; 127 if (path->dentry->d_flags & DCACHE_COOKIE) {
123 128 dcs = find_dcookie((unsigned long)path->dentry);
124 if (!dcs) 129 } else {
125 dcs = alloc_dcookie(path); 130 dcs = alloc_dcookie(path);
126 131 if (!dcs) {
127 if (!dcs) { 132 err = -ENOMEM;
128 err = -ENOMEM; 133 goto out;
129 goto out; 134 }
130 } 135 }
131 136
132 *cookie = dcookie_value(dcs); 137 *cookie = dcookie_value(dcs);
@@ -140,7 +145,7 @@ out:
140/* And here is where the userspace process can look up the cookie value 145/* And here is where the userspace process can look up the cookie value
141 * to retrieve the path. 146 * to retrieve the path.
142 */ 147 */
143asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) 148SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
144{ 149{
145 unsigned long cookie = (unsigned long)cookie64; 150 unsigned long cookie = (unsigned long)cookie64;
146 int err = -EINVAL; 151 int err = -EINVAL;
@@ -193,7 +198,13 @@ out:
193 mutex_unlock(&dcookie_mutex); 198 mutex_unlock(&dcookie_mutex);
194 return err; 199 return err;
195} 200}
196 201#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
202asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len)
203{
204 return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len);
205}
206SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie);
207#endif
197 208
198static int dcookie_init(void) 209static int dcookie_init(void)
199{ 210{
@@ -251,7 +262,12 @@ out_kmem:
251 262
252static void free_dcookie(struct dcookie_struct * dcs) 263static void free_dcookie(struct dcookie_struct * dcs)
253{ 264{
254 dcs->path.dentry->d_cookie = NULL; 265 struct dentry *d = dcs->path.dentry;
266
267 spin_lock(&d->d_lock);
268 d->d_flags &= ~DCACHE_COOKIE;
269 spin_unlock(&d->d_lock);
270
255 path_put(&dcs->path); 271 path_put(&dcs->path);
256 kmem_cache_free(dcookie_cache, dcs); 272 kmem_cache_free(dcookie_cache, dcs);
257} 273}