aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/cache.c197
-rw-r--r--fs/9p/cache.h54
-rw-r--r--fs/9p/v9fs.c58
-rw-r--r--fs/9p/v9fs.h37
-rw-r--r--fs/9p/v9fs_vfs.h4
-rw-r--r--fs/9p/vfs_inode.c36
-rw-r--r--fs/9p/vfs_inode_dotl.c14
-rw-r--r--fs/9p/vfs_super.c4
8 files changed, 184 insertions, 220 deletions
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 610913d42a28..5b335c5086a1 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -33,67 +33,11 @@
33 33
34#define CACHETAG_LEN 11 34#define CACHETAG_LEN 11
35 35
36struct kmem_cache *vcookie_cache;
37
38struct fscache_netfs v9fs_cache_netfs = { 36struct fscache_netfs v9fs_cache_netfs = {
39 .name = "9p", 37 .name = "9p",
40 .version = 0, 38 .version = 0,
41}; 39};
42 40
43static void init_once(void *foo)
44{
45 struct v9fs_cookie *vcookie = (struct v9fs_cookie *) foo;
46 vcookie->fscache = NULL;
47 vcookie->qid = NULL;
48 inode_init_once(&vcookie->inode);
49}
50
51/**
52 * v9fs_init_vcookiecache - initialize a cache for vcookies to maintain
53 * vcookie to inode mapping
54 *
55 * Returns 0 on success.
56 */
57
58static int v9fs_init_vcookiecache(void)
59{
60 vcookie_cache = kmem_cache_create("vcookie_cache",
61 sizeof(struct v9fs_cookie),
62 0, (SLAB_RECLAIM_ACCOUNT|
63 SLAB_MEM_SPREAD),
64 init_once);
65 if (!vcookie_cache)
66 return -ENOMEM;
67
68 return 0;
69}
70
71/**
72 * v9fs_destroy_vcookiecache - destroy the cache of vcookies
73 *
74 */
75
76static void v9fs_destroy_vcookiecache(void)
77{
78 kmem_cache_destroy(vcookie_cache);
79}
80
81int __v9fs_cache_register(void)
82{
83 int ret;
84 ret = v9fs_init_vcookiecache();
85 if (ret < 0)
86 return ret;
87
88 return fscache_register_netfs(&v9fs_cache_netfs);
89}
90
91void __v9fs_cache_unregister(void)
92{
93 v9fs_destroy_vcookiecache();
94 fscache_unregister_netfs(&v9fs_cache_netfs);
95}
96
97/** 41/**
98 * v9fs_random_cachetag - Generate a random tag to be associated 42 * v9fs_random_cachetag - Generate a random tag to be associated
99 * with a new cache session. 43 * with a new cache session.
@@ -133,9 +77,9 @@ static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data,
133} 77}
134 78
135const struct fscache_cookie_def v9fs_cache_session_index_def = { 79const struct fscache_cookie_def v9fs_cache_session_index_def = {
136 .name = "9P.session", 80 .name = "9P.session",
137 .type = FSCACHE_COOKIE_TYPE_INDEX, 81 .type = FSCACHE_COOKIE_TYPE_INDEX,
138 .get_key = v9fs_cache_session_get_key, 82 .get_key = v9fs_cache_session_get_key,
139}; 83};
140 84
141void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses) 85void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
@@ -163,33 +107,33 @@ void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
163static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data, 107static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
164 void *buffer, uint16_t bufmax) 108 void *buffer, uint16_t bufmax)
165{ 109{
166 const struct v9fs_cookie *vcookie = cookie_netfs_data; 110 const struct v9fs_inode *v9inode = cookie_netfs_data;
167 memcpy(buffer, &vcookie->qid->path, sizeof(vcookie->qid->path)); 111 memcpy(buffer, &v9inode->fscache_key->path,
168 112 sizeof(v9inode->fscache_key->path));
169 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &vcookie->inode, 113 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &v9inode->vfs_inode,
170 vcookie->qid->path); 114 v9inode->fscache_key->path);
171 return sizeof(vcookie->qid->path); 115 return sizeof(v9inode->fscache_key->path);
172} 116}
173 117
174static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data, 118static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
175 uint64_t *size) 119 uint64_t *size)
176{ 120{
177 const struct v9fs_cookie *vcookie = cookie_netfs_data; 121 const struct v9fs_inode *v9inode = cookie_netfs_data;
178 *size = i_size_read(&vcookie->inode); 122 *size = i_size_read(&v9inode->vfs_inode);
179 123
180 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get attr %llu", &vcookie->inode, 124 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get attr %llu", &v9inode->vfs_inode,
181 *size); 125 *size);
182} 126}
183 127
184static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data, 128static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
185 void *buffer, uint16_t buflen) 129 void *buffer, uint16_t buflen)
186{ 130{
187 const struct v9fs_cookie *vcookie = cookie_netfs_data; 131 const struct v9fs_inode *v9inode = cookie_netfs_data;
188 memcpy(buffer, &vcookie->qid->version, sizeof(vcookie->qid->version)); 132 memcpy(buffer, &v9inode->fscache_key->version,
189 133 sizeof(v9inode->fscache_key->version));
190 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &vcookie->inode, 134 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &v9inode->vfs_inode,
191 vcookie->qid->version); 135 v9inode->fscache_key->version);
192 return sizeof(vcookie->qid->version); 136 return sizeof(v9inode->fscache_key->version);
193} 137}
194 138
195static enum 139static enum
@@ -197,13 +141,13 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
197 const void *buffer, 141 const void *buffer,
198 uint16_t buflen) 142 uint16_t buflen)
199{ 143{
200 const struct v9fs_cookie *vcookie = cookie_netfs_data; 144 const struct v9fs_inode *v9inode = cookie_netfs_data;
201 145
202 if (buflen != sizeof(vcookie->qid->version)) 146 if (buflen != sizeof(v9inode->fscache_key->version))
203 return FSCACHE_CHECKAUX_OBSOLETE; 147 return FSCACHE_CHECKAUX_OBSOLETE;
204 148
205 if (memcmp(buffer, &vcookie->qid->version, 149 if (memcmp(buffer, &v9inode->fscache_key->version,
206 sizeof(vcookie->qid->version))) 150 sizeof(v9inode->fscache_key->version)))
207 return FSCACHE_CHECKAUX_OBSOLETE; 151 return FSCACHE_CHECKAUX_OBSOLETE;
208 152
209 return FSCACHE_CHECKAUX_OKAY; 153 return FSCACHE_CHECKAUX_OKAY;
@@ -211,7 +155,7 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
211 155
212static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data) 156static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
213{ 157{
214 struct v9fs_cookie *vcookie = cookie_netfs_data; 158 struct v9fs_inode *v9inode = cookie_netfs_data;
215 struct pagevec pvec; 159 struct pagevec pvec;
216 pgoff_t first; 160 pgoff_t first;
217 int loop, nr_pages; 161 int loop, nr_pages;
@@ -220,7 +164,7 @@ static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
220 first = 0; 164 first = 0;
221 165
222 for (;;) { 166 for (;;) {
223 nr_pages = pagevec_lookup(&pvec, vcookie->inode.i_mapping, 167 nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping,
224 first, 168 first,
225 PAGEVEC_SIZE - pagevec_count(&pvec)); 169 PAGEVEC_SIZE - pagevec_count(&pvec));
226 if (!nr_pages) 170 if (!nr_pages)
@@ -249,115 +193,114 @@ const struct fscache_cookie_def v9fs_cache_inode_index_def = {
249 193
250void v9fs_cache_inode_get_cookie(struct inode *inode) 194void v9fs_cache_inode_get_cookie(struct inode *inode)
251{ 195{
252 struct v9fs_cookie *vcookie; 196 struct v9fs_inode *v9inode;
253 struct v9fs_session_info *v9ses; 197 struct v9fs_session_info *v9ses;
254 198
255 if (!S_ISREG(inode->i_mode)) 199 if (!S_ISREG(inode->i_mode))
256 return; 200 return;
257 201
258 vcookie = v9fs_inode2cookie(inode); 202 v9inode = V9FS_I(inode);
259 if (vcookie->fscache) 203 if (v9inode->fscache)
260 return; 204 return;
261 205
262 v9ses = v9fs_inode2v9ses(inode); 206 v9ses = v9fs_inode2v9ses(inode);
263 vcookie->fscache = fscache_acquire_cookie(v9ses->fscache, 207 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
264 &v9fs_cache_inode_index_def, 208 &v9fs_cache_inode_index_def,
265 vcookie); 209 v9inode);
266 210
267 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get cookie %p", inode, 211 P9_DPRINTK(P9_DEBUG_FSC, "inode %p get cookie %p", inode,
268 vcookie->fscache); 212 v9inode->fscache);
269} 213}
270 214
271void v9fs_cache_inode_put_cookie(struct inode *inode) 215void v9fs_cache_inode_put_cookie(struct inode *inode)
272{ 216{
273 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 217 struct v9fs_inode *v9inode = V9FS_I(inode);
274 218
275 if (!vcookie->fscache) 219 if (!v9inode->fscache)
276 return; 220 return;
277 P9_DPRINTK(P9_DEBUG_FSC, "inode %p put cookie %p", inode, 221 P9_DPRINTK(P9_DEBUG_FSC, "inode %p put cookie %p", inode,
278 vcookie->fscache); 222 v9inode->fscache);
279 223
280 fscache_relinquish_cookie(vcookie->fscache, 0); 224 fscache_relinquish_cookie(v9inode->fscache, 0);
281 vcookie->fscache = NULL; 225 v9inode->fscache = NULL;
282} 226}
283 227
284void v9fs_cache_inode_flush_cookie(struct inode *inode) 228void v9fs_cache_inode_flush_cookie(struct inode *inode)
285{ 229{
286 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 230 struct v9fs_inode *v9inode = V9FS_I(inode);
287 231
288 if (!vcookie->fscache) 232 if (!v9inode->fscache)
289 return; 233 return;
290 P9_DPRINTK(P9_DEBUG_FSC, "inode %p flush cookie %p", inode, 234 P9_DPRINTK(P9_DEBUG_FSC, "inode %p flush cookie %p", inode,
291 vcookie->fscache); 235 v9inode->fscache);
292 236
293 fscache_relinquish_cookie(vcookie->fscache, 1); 237 fscache_relinquish_cookie(v9inode->fscache, 1);
294 vcookie->fscache = NULL; 238 v9inode->fscache = NULL;
295} 239}
296 240
297void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp) 241void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
298{ 242{
299 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 243 struct v9fs_inode *v9inode = V9FS_I(inode);
300 struct p9_fid *fid; 244 struct p9_fid *fid;
301 245
302 if (!vcookie->fscache) 246 if (!v9inode->fscache)
303 return; 247 return;
304 248
305 spin_lock(&vcookie->lock); 249 spin_lock(&v9inode->fscache_lock);
306 fid = filp->private_data; 250 fid = filp->private_data;
307 if ((filp->f_flags & O_ACCMODE) != O_RDONLY) 251 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
308 v9fs_cache_inode_flush_cookie(inode); 252 v9fs_cache_inode_flush_cookie(inode);
309 else 253 else
310 v9fs_cache_inode_get_cookie(inode); 254 v9fs_cache_inode_get_cookie(inode);
311 255
312 spin_unlock(&vcookie->lock); 256 spin_unlock(&v9inode->fscache_lock);
313} 257}
314 258
315void v9fs_cache_inode_reset_cookie(struct inode *inode) 259void v9fs_cache_inode_reset_cookie(struct inode *inode)
316{ 260{
317 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 261 struct v9fs_inode *v9inode = V9FS_I(inode);
318 struct v9fs_session_info *v9ses; 262 struct v9fs_session_info *v9ses;
319 struct fscache_cookie *old; 263 struct fscache_cookie *old;
320 264
321 if (!vcookie->fscache) 265 if (!v9inode->fscache)
322 return; 266 return;
323 267
324 old = vcookie->fscache; 268 old = v9inode->fscache;
325 269
326 spin_lock(&vcookie->lock); 270 spin_lock(&v9inode->fscache_lock);
327 fscache_relinquish_cookie(vcookie->fscache, 1); 271 fscache_relinquish_cookie(v9inode->fscache, 1);
328 272
329 v9ses = v9fs_inode2v9ses(inode); 273 v9ses = v9fs_inode2v9ses(inode);
330 vcookie->fscache = fscache_acquire_cookie(v9ses->fscache, 274 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
331 &v9fs_cache_inode_index_def, 275 &v9fs_cache_inode_index_def,
332 vcookie); 276 v9inode);
333
334 P9_DPRINTK(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p", 277 P9_DPRINTK(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p",
335 inode, old, vcookie->fscache); 278 inode, old, v9inode->fscache);
336 279
337 spin_unlock(&vcookie->lock); 280 spin_unlock(&v9inode->fscache_lock);
338} 281}
339 282
340int __v9fs_fscache_release_page(struct page *page, gfp_t gfp) 283int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
341{ 284{
342 struct inode *inode = page->mapping->host; 285 struct inode *inode = page->mapping->host;
343 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 286 struct v9fs_inode *v9inode = V9FS_I(inode);
344 287
345 BUG_ON(!vcookie->fscache); 288 BUG_ON(!v9inode->fscache);
346 289
347 return fscache_maybe_release_page(vcookie->fscache, page, gfp); 290 return fscache_maybe_release_page(v9inode->fscache, page, gfp);
348} 291}
349 292
350void __v9fs_fscache_invalidate_page(struct page *page) 293void __v9fs_fscache_invalidate_page(struct page *page)
351{ 294{
352 struct inode *inode = page->mapping->host; 295 struct inode *inode = page->mapping->host;
353 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 296 struct v9fs_inode *v9inode = V9FS_I(inode);
354 297
355 BUG_ON(!vcookie->fscache); 298 BUG_ON(!v9inode->fscache);
356 299
357 if (PageFsCache(page)) { 300 if (PageFsCache(page)) {
358 fscache_wait_on_page_write(vcookie->fscache, page); 301 fscache_wait_on_page_write(v9inode->fscache, page);
359 BUG_ON(!PageLocked(page)); 302 BUG_ON(!PageLocked(page));
360 fscache_uncache_page(vcookie->fscache, page); 303 fscache_uncache_page(v9inode->fscache, page);
361 } 304 }
362} 305}
363 306
@@ -380,13 +323,13 @@ static void v9fs_vfs_readpage_complete(struct page *page, void *data,
380int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page) 323int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
381{ 324{
382 int ret; 325 int ret;
383 const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 326 const struct v9fs_inode *v9inode = V9FS_I(inode);
384 327
385 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page); 328 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page);
386 if (!vcookie->fscache) 329 if (!v9inode->fscache)
387 return -ENOBUFS; 330 return -ENOBUFS;
388 331
389 ret = fscache_read_or_alloc_page(vcookie->fscache, 332 ret = fscache_read_or_alloc_page(v9inode->fscache,
390 page, 333 page,
391 v9fs_vfs_readpage_complete, 334 v9fs_vfs_readpage_complete,
392 NULL, 335 NULL,
@@ -418,13 +361,13 @@ int __v9fs_readpages_from_fscache(struct inode *inode,
418 unsigned *nr_pages) 361 unsigned *nr_pages)
419{ 362{
420 int ret; 363 int ret;
421 const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 364 const struct v9fs_inode *v9inode = V9FS_I(inode);
422 365
423 P9_DPRINTK(P9_DEBUG_FSC, "inode %p pages %u", inode, *nr_pages); 366 P9_DPRINTK(P9_DEBUG_FSC, "inode %p pages %u", inode, *nr_pages);
424 if (!vcookie->fscache) 367 if (!v9inode->fscache)
425 return -ENOBUFS; 368 return -ENOBUFS;
426 369
427 ret = fscache_read_or_alloc_pages(vcookie->fscache, 370 ret = fscache_read_or_alloc_pages(v9inode->fscache,
428 mapping, pages, nr_pages, 371 mapping, pages, nr_pages,
429 v9fs_vfs_readpage_complete, 372 v9fs_vfs_readpage_complete,
430 NULL, 373 NULL,
@@ -453,10 +396,10 @@ int __v9fs_readpages_from_fscache(struct inode *inode,
453void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page) 396void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
454{ 397{
455 int ret; 398 int ret;
456 const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 399 const struct v9fs_inode *v9inode = V9FS_I(inode);
457 400
458 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page); 401 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page);
459 ret = fscache_write_page(vcookie->fscache, page, GFP_KERNEL); 402 ret = fscache_write_page(v9inode->fscache, page, GFP_KERNEL);
460 P9_DPRINTK(P9_DEBUG_FSC, "ret = %d", ret); 403 P9_DPRINTK(P9_DEBUG_FSC, "ret = %d", ret);
461 if (ret != 0) 404 if (ret != 0)
462 v9fs_uncache_page(inode, page); 405 v9fs_uncache_page(inode, page);
@@ -467,8 +410,8 @@ void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
467 */ 410 */
468void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page) 411void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
469{ 412{
470 const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 413 const struct v9fs_inode *v9inode = V9FS_I(inode);
471 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page); 414 P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page);
472 if (PageFsCache(page)) 415 if (PageFsCache(page))
473 fscache_wait_on_page_write(vcookie->fscache, page); 416 fscache_wait_on_page_write(v9inode->fscache, page);
474} 417}
diff --git a/fs/9p/cache.h b/fs/9p/cache.h
index ec16fcdc3a67..049507a5b01c 100644
--- a/fs/9p/cache.h
+++ b/fs/9p/cache.h
@@ -25,20 +25,6 @@
25#include <linux/fscache.h> 25#include <linux/fscache.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27 27
28extern struct kmem_cache *vcookie_cache;
29
30struct v9fs_cookie {
31 spinlock_t lock;
32 struct inode inode;
33 struct fscache_cookie *fscache;
34 struct p9_qid *qid;
35};
36
37static inline struct v9fs_cookie *v9fs_inode2cookie(const struct inode *inode)
38{
39 return container_of(inode, struct v9fs_cookie, inode);
40}
41
42extern struct fscache_netfs v9fs_cache_netfs; 28extern struct fscache_netfs v9fs_cache_netfs;
43extern const struct fscache_cookie_def v9fs_cache_session_index_def; 29extern const struct fscache_cookie_def v9fs_cache_session_index_def;
44extern const struct fscache_cookie_def v9fs_cache_inode_index_def; 30extern const struct fscache_cookie_def v9fs_cache_inode_index_def;
@@ -66,21 +52,6 @@ extern int __v9fs_readpages_from_fscache(struct inode *inode,
66extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page); 52extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page);
67extern void __v9fs_fscache_wait_on_page_write(struct inode *inode, 53extern void __v9fs_fscache_wait_on_page_write(struct inode *inode,
68 struct page *page); 54 struct page *page);
69/**
70 * v9fs_cache_register - Register v9fs file system with the cache
71 */
72static inline int v9fs_cache_register(void)
73{
74 return __v9fs_cache_register();
75}
76
77/**
78 * v9fs_cache_unregister - Unregister v9fs from the cache
79 */
80static inline void v9fs_cache_unregister(void)
81{
82 __v9fs_cache_unregister();
83}
84 55
85static inline int v9fs_fscache_release_page(struct page *page, 56static inline int v9fs_fscache_release_page(struct page *page,
86 gfp_t gfp) 57 gfp_t gfp)
@@ -117,18 +88,18 @@ static inline void v9fs_readpage_to_fscache(struct inode *inode,
117 88
118static inline void v9fs_uncache_page(struct inode *inode, struct page *page) 89static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
119{ 90{
120 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 91 struct v9fs_inode *v9inode = V9FS_I(inode);
121 fscache_uncache_page(vcookie->fscache, page); 92 fscache_uncache_page(v9inode->fscache, page);
122 BUG_ON(PageFsCache(page)); 93 BUG_ON(PageFsCache(page));
123} 94}
124 95
125static inline void v9fs_vcookie_set_qid(struct inode *inode, 96static inline void v9fs_fscache_set_key(struct inode *inode,
126 struct p9_qid *qid) 97 struct p9_qid *qid)
127{ 98{
128 struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); 99 struct v9fs_inode *v9inode = V9FS_I(inode);
129 spin_lock(&vcookie->lock); 100 spin_lock(&v9inode->fscache_lock);
130 vcookie->qid = qid; 101 v9inode->fscache_key = qid;
131 spin_unlock(&vcookie->lock); 102 spin_unlock(&v9inode->fscache_lock);
132} 103}
133 104
134static inline void v9fs_fscache_wait_on_page_write(struct inode *inode, 105static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
@@ -139,13 +110,6 @@ static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
139 110
140#else /* CONFIG_9P_FSCACHE */ 111#else /* CONFIG_9P_FSCACHE */
141 112
142static inline int v9fs_cache_register(void)
143{
144 return 1;
145}
146
147static inline void v9fs_cache_unregister(void) {}
148
149static inline int v9fs_fscache_release_page(struct page *page, 113static inline int v9fs_fscache_release_page(struct page *page,
150 gfp_t gfp) { 114 gfp_t gfp) {
151 return 1; 115 return 1;
@@ -174,10 +138,6 @@ static inline void v9fs_readpage_to_fscache(struct inode *inode,
174static inline void v9fs_uncache_page(struct inode *inode, struct page *page) 138static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
175{} 139{}
176 140
177static inline void v9fs_vcookie_set_qid(struct inode *inode,
178 struct p9_qid *qid)
179{}
180
181static inline void v9fs_fscache_wait_on_page_write(struct inode *inode, 141static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
182 struct page *page) 142 struct page *page)
183{ 143{
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 738be8f6994f..c82b017f51f3 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -39,6 +39,7 @@
39 39
40static DEFINE_SPINLOCK(v9fs_sessionlist_lock); 40static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
41static LIST_HEAD(v9fs_sessionlist); 41static LIST_HEAD(v9fs_sessionlist);
42struct kmem_cache *v9fs_inode_cache;
42 43
43/* 44/*
44 * Option Parsing (code inspired by NFS code) 45 * Option Parsing (code inspired by NFS code)
@@ -481,6 +482,63 @@ static void v9fs_sysfs_cleanup(void)
481 kobject_put(v9fs_kobj); 482 kobject_put(v9fs_kobj);
482} 483}
483 484
485static void v9fs_inode_init_once(void *foo)
486{
487 struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
488#ifdef CONFIG_9P_FSCACHE
489 v9inode->fscache = NULL;
490 v9inode->fscache_key = NULL;
491#endif
492 inode_init_once(&v9inode->vfs_inode);
493}
494
495/**
496 * v9fs_init_inode_cache - initialize a cache for 9P
497 * Returns 0 on success.
498 */
499static int v9fs_init_inode_cache(void)
500{
501 v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
502 sizeof(struct v9fs_inode),
503 0, (SLAB_RECLAIM_ACCOUNT|
504 SLAB_MEM_SPREAD),
505 v9fs_inode_init_once);
506 if (!v9fs_inode_cache)
507 return -ENOMEM;
508
509 return 0;
510}
511
512/**
513 * v9fs_destroy_inode_cache - destroy the cache of 9P inode
514 *
515 */
516static void v9fs_destroy_inode_cache(void)
517{
518 kmem_cache_destroy(v9fs_inode_cache);
519}
520
521static int v9fs_cache_register(void)
522{
523 int ret;
524 ret = v9fs_init_inode_cache();
525 if (ret < 0)
526 return ret;
527#ifdef CONFIG_9P_FSCACHE
528 return fscache_register_netfs(&v9fs_cache_netfs);
529#else
530 return ret;
531#endif
532}
533
534static void v9fs_cache_unregister(void)
535{
536 v9fs_destroy_inode_cache();
537#ifdef CONFIG_9P_FSCACHE
538 fscache_unregister_netfs(&v9fs_cache_netfs);
539#endif
540}
541
484/** 542/**
485 * init_v9fs - Initialize module 543 * init_v9fs - Initialize module
486 * 544 *
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 21bd803a3cc0..ce59d1512062 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -116,6 +116,20 @@ struct v9fs_session_info {
116 struct p9_fid *root_fid; /* Used for file system sync */ 116 struct p9_fid *root_fid; /* Used for file system sync */
117}; 117};
118 118
119struct v9fs_inode {
120#ifdef CONFIG_9P_FSCACHE
121 spinlock_t fscache_lock;
122 struct fscache_cookie *fscache;
123 struct p9_qid *fscache_key;
124#endif
125 struct inode vfs_inode;
126};
127
128static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
129{
130 return container_of(inode, struct v9fs_inode, vfs_inode);
131}
132
119struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, 133struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
120 char *); 134 char *);
121extern void v9fs_session_close(struct v9fs_session_info *v9ses); 135extern void v9fs_session_close(struct v9fs_session_info *v9ses);
@@ -129,16 +143,15 @@ extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
129 struct inode *new_dir, struct dentry *new_dentry); 143 struct inode *new_dir, struct dentry *new_dentry);
130extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, 144extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
131 void *p); 145 void *p);
132extern struct inode *v9fs_inode(struct v9fs_session_info *v9ses, 146extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
133 struct p9_fid *fid, 147 struct p9_fid *fid,
134 struct super_block *sb); 148 struct super_block *sb);
135
136extern const struct inode_operations v9fs_dir_inode_operations_dotl; 149extern const struct inode_operations v9fs_dir_inode_operations_dotl;
137extern const struct inode_operations v9fs_file_inode_operations_dotl; 150extern const struct inode_operations v9fs_file_inode_operations_dotl;
138extern const struct inode_operations v9fs_symlink_inode_operations_dotl; 151extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
139extern struct inode *v9fs_inode_dotl(struct v9fs_session_info *v9ses, 152extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
140 struct p9_fid *fid, 153 struct p9_fid *fid,
141 struct super_block *sb); 154 struct super_block *sb);
142 155
143/* other default globals */ 156/* other default globals */
144#define V9FS_PORT 564 157#define V9FS_PORT 564
@@ -163,7 +176,7 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
163} 176}
164 177
165/** 178/**
166 * v9fs_inode_from_fid - Helper routine to populate an inode by 179 * v9fs_get_inode_from_fid - Helper routine to populate an inode by
167 * issuing a attribute request 180 * issuing a attribute request
168 * @v9ses: session information 181 * @v9ses: session information
169 * @fid: fid to issue attribute request for 182 * @fid: fid to issue attribute request for
@@ -171,11 +184,11 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
171 * 184 *
172 */ 185 */
173static inline struct inode * 186static inline struct inode *
174v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 187v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
175 struct super_block *sb) 188 struct super_block *sb)
176{ 189{
177 if (v9fs_proto_dotl(v9ses)) 190 if (v9fs_proto_dotl(v9ses))
178 return v9fs_inode_dotl(v9ses, fid, sb); 191 return v9fs_inode_from_fid_dotl(v9ses, fid, sb);
179 else 192 else
180 return v9fs_inode(v9ses, fid, sb); 193 return v9fs_inode_from_fid(v9ses, fid, sb);
181} 194}
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index ab72e66c2e0c..ed9fd00566f2 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -47,12 +47,10 @@ extern const struct dentry_operations v9fs_dentry_operations;
47extern const struct dentry_operations v9fs_cached_dentry_operations; 47extern const struct dentry_operations v9fs_cached_dentry_operations;
48extern const struct file_operations v9fs_cached_file_operations; 48extern const struct file_operations v9fs_cached_file_operations;
49extern const struct file_operations v9fs_cached_file_operations_dotl; 49extern const struct file_operations v9fs_cached_file_operations_dotl;
50extern struct kmem_cache *v9fs_inode_cache;
50 51
51#ifdef CONFIG_9P_FSCACHE
52struct inode *v9fs_alloc_inode(struct super_block *sb); 52struct inode *v9fs_alloc_inode(struct super_block *sb);
53void v9fs_destroy_inode(struct inode *inode); 53void v9fs_destroy_inode(struct inode *inode);
54#endif
55
56struct inode *v9fs_get_inode(struct super_block *sb, int mode); 54struct inode *v9fs_get_inode(struct super_block *sb, int mode);
57int v9fs_init_inode(struct v9fs_session_info *v9ses, 55int v9fs_init_inode(struct v9fs_session_info *v9ses,
58 struct inode *inode, int mode); 56 struct inode *inode, int mode);
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 304904b40610..411c70a88b36 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -203,26 +203,23 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
203 wstat->extension = NULL; 203 wstat->extension = NULL;
204} 204}
205 205
206#ifdef CONFIG_9P_FSCACHE
207/** 206/**
208 * v9fs_alloc_inode - helper function to allocate an inode 207 * v9fs_alloc_inode - helper function to allocate an inode
209 * This callback is executed before setting up the inode so that we
210 * can associate a vcookie with each inode.
211 * 208 *
212 */ 209 */
213
214struct inode *v9fs_alloc_inode(struct super_block *sb) 210struct inode *v9fs_alloc_inode(struct super_block *sb)
215{ 211{
216 struct v9fs_cookie *vcookie; 212 struct v9fs_inode *v9inode;
217 vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache, 213 v9inode = (struct v9fs_inode *)kmem_cache_alloc(v9fs_inode_cache,
218 GFP_KERNEL); 214 GFP_KERNEL);
219 if (!vcookie) 215 if (!v9inode)
220 return NULL; 216 return NULL;
221 217#ifdef CONFIG_9P_FSCACHE
222 vcookie->fscache = NULL; 218 v9inode->fscache = NULL;
223 vcookie->qid = NULL; 219 v9inode->fscache_key = NULL;
224 spin_lock_init(&vcookie->lock); 220 spin_lock_init(&v9inode->fscache_lock);
225 return &vcookie->inode; 221#endif
222 return &v9inode->vfs_inode;
226} 223}
227 224
228/** 225/**
@@ -234,14 +231,13 @@ static void v9fs_i_callback(struct rcu_head *head)
234{ 231{
235 struct inode *inode = container_of(head, struct inode, i_rcu); 232 struct inode *inode = container_of(head, struct inode, i_rcu);
236 INIT_LIST_HEAD(&inode->i_dentry); 233 INIT_LIST_HEAD(&inode->i_dentry);
237 kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode)); 234 kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
238} 235}
239 236
240void v9fs_destroy_inode(struct inode *inode) 237void v9fs_destroy_inode(struct inode *inode)
241{ 238{
242 call_rcu(&inode->i_rcu, v9fs_i_callback); 239 call_rcu(&inode->i_rcu, v9fs_i_callback);
243} 240}
244#endif
245 241
246int v9fs_init_inode(struct v9fs_session_info *v9ses, 242int v9fs_init_inode(struct v9fs_session_info *v9ses,
247 struct inode *inode, int mode) 243 struct inode *inode, int mode)
@@ -459,7 +455,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
459 455
460 v9fs_stat2inode(st, inode, sb); 456 v9fs_stat2inode(st, inode, sb);
461#ifdef CONFIG_9P_FSCACHE 457#ifdef CONFIG_9P_FSCACHE
462 v9fs_vcookie_set_qid(ret, &st->qid); 458 v9fs_fscache_set_key(inode, &st->qid);
463 v9fs_cache_inode_get_cookie(inode); 459 v9fs_cache_inode_get_cookie(inode);
464#endif 460#endif
465 unlock_new_inode(inode); 461 unlock_new_inode(inode);
@@ -472,8 +468,8 @@ error:
472} 468}
473 469
474struct inode * 470struct inode *
475v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid, 471v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
476 struct super_block *sb) 472 struct super_block *sb)
477{ 473{
478 struct p9_wstat *st; 474 struct p9_wstat *st;
479 struct inode *inode = NULL; 475 struct inode *inode = NULL;
@@ -572,7 +568,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
572 } 568 }
573 569
574 /* instantiate inode and assign the unopened fid to the dentry */ 570 /* instantiate inode and assign the unopened fid to the dentry */
575 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 571 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
576 if (IS_ERR(inode)) { 572 if (IS_ERR(inode)) {
577 err = PTR_ERR(inode); 573 err = PTR_ERR(inode);
578 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 574 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -747,7 +743,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
747 return ERR_PTR(result); 743 return ERR_PTR(result);
748 } 744 }
749 745
750 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 746 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
751 if (IS_ERR(inode)) { 747 if (IS_ERR(inode)) {
752 result = PTR_ERR(inode); 748 result = PTR_ERR(inode);
753 inode = NULL; 749 inode = NULL;
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index a2a3d7edb17c..21523f27f5d1 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -113,7 +113,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
113 113
114 v9fs_stat2inode_dotl(st, inode); 114 v9fs_stat2inode_dotl(st, inode);
115#ifdef CONFIG_9P_FSCACHE 115#ifdef CONFIG_9P_FSCACHE
116 v9fs_vcookie_set_qid(inode, &st->qid); 116 v9fs_fscache_set_key(inode, &st->qid);
117 v9fs_cache_inode_get_cookie(inode); 117 v9fs_cache_inode_get_cookie(inode);
118#endif 118#endif
119 retval = v9fs_get_acl(inode, fid); 119 retval = v9fs_get_acl(inode, fid);
@@ -130,8 +130,8 @@ error:
130} 130}
131 131
132struct inode * 132struct inode *
133v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 133v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
134 struct super_block *sb) 134 struct super_block *sb)
135{ 135{
136 struct p9_stat_dotl *st; 136 struct p9_stat_dotl *st;
137 struct inode *inode = NULL; 137 struct inode *inode = NULL;
@@ -228,7 +228,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
228 fid = NULL; 228 fid = NULL;
229 goto error; 229 goto error;
230 } 230 }
231 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 231 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
232 if (IS_ERR(inode)) { 232 if (IS_ERR(inode)) {
233 err = PTR_ERR(inode); 233 err = PTR_ERR(inode);
234 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 234 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -341,7 +341,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
341 goto error; 341 goto error;
342 } 342 }
343 343
344 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 344 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
345 if (IS_ERR(inode)) { 345 if (IS_ERR(inode)) {
346 err = PTR_ERR(inode); 346 err = PTR_ERR(inode);
347 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 347 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -588,7 +588,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
588 } 588 }
589 589
590 /* instantiate inode and assign the unopened fid to dentry */ 590 /* instantiate inode and assign the unopened fid to dentry */
591 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 591 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
592 if (IS_ERR(inode)) { 592 if (IS_ERR(inode)) {
593 err = PTR_ERR(inode); 593 err = PTR_ERR(inode);
594 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 594 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -747,7 +747,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
747 goto error; 747 goto error;
748 } 748 }
749 749
750 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 750 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
751 if (IS_ERR(inode)) { 751 if (IS_ERR(inode)) {
752 err = PTR_ERR(inode); 752 err = PTR_ERR(inode);
753 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 753 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 6985e2a7a118..6c812d1c58f1 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -292,10 +292,8 @@ static int v9fs_sync_fs(struct super_block *sb, int wait)
292} 292}
293 293
294static const struct super_operations v9fs_super_ops = { 294static const struct super_operations v9fs_super_ops = {
295#ifdef CONFIG_9P_FSCACHE
296 .alloc_inode = v9fs_alloc_inode, 295 .alloc_inode = v9fs_alloc_inode,
297 .destroy_inode = v9fs_destroy_inode, 296 .destroy_inode = v9fs_destroy_inode,
298#endif
299 .statfs = simple_statfs, 297 .statfs = simple_statfs,
300 .evict_inode = v9fs_evict_inode, 298 .evict_inode = v9fs_evict_inode,
301 .show_options = generic_show_options, 299 .show_options = generic_show_options,
@@ -303,10 +301,8 @@ static const struct super_operations v9fs_super_ops = {
303}; 301};
304 302
305static const struct super_operations v9fs_super_ops_dotl = { 303static const struct super_operations v9fs_super_ops_dotl = {
306#ifdef CONFIG_9P_FSCACHE
307 .alloc_inode = v9fs_alloc_inode, 304 .alloc_inode = v9fs_alloc_inode,
308 .destroy_inode = v9fs_destroy_inode, 305 .destroy_inode = v9fs_destroy_inode,
309#endif
310 .sync_fs = v9fs_sync_fs, 306 .sync_fs = v9fs_sync_fs,
311 .statfs = v9fs_statfs, 307 .statfs = v9fs_statfs,
312 .evict_inode = v9fs_evict_inode, 308 .evict_inode = v9fs_evict_inode,