diff options
author | David Howells <dhowells@redhat.com> | 2013-09-27 06:20:03 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2013-09-27 13:40:25 -0400 |
commit | f1fe29b4a02d0805aa7d0ff6b73410a9f9316d69 (patch) | |
tree | 6dd4f1186b75f4549d7246fa7dbb4dbc3c057ddc /fs/nfs | |
parent | 94d30ae90a00cafe686c1057be57f4885f963abf (diff) |
NFS: Use i_writecount to control whether to get an fscache cookie in nfs_open()
Use i_writecount to control whether to get an fscache cookie in nfs_open() as
NFS does not do write caching yet. I *think* this is the cause of a problem
encountered by Mark Moseley whereby __fscache_uncache_page() gets a NULL
pointer dereference because cookie->def is NULL:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
IP: [<ffffffff812a1903>] __fscache_uncache_page+0x23/0x160
PGD 0
Thread overran stack, or stack corrupted
Oops: 0000 [#1] SMP
Modules linked in: ...
CPU: 7 PID: 18993 Comm: php Not tainted 3.11.1 #1
Hardware name: Dell Inc. PowerEdge R420/072XWF, BIOS 1.3.5 08/21/2012
task: ffff8804203460c0 ti: ffff880420346640
RIP: 0010:[<ffffffff812a1903>] __fscache_uncache_page+0x23/0x160
RSP: 0018:ffff8801053af878 EFLAGS: 00210286
RAX: 0000000000000000 RBX: ffff8800be2f8780 RCX: ffff88022ffae5e8
RDX: 0000000000004c66 RSI: ffffea00055ff440 RDI: ffff8800be2f8780
RBP: ffff8801053af898 R08: 0000000000000001 R09: 0000000000000003
R10: 0000000000000000 R11: 0000000000000000 R12: ffffea00055ff440
R13: 0000000000001000 R14: ffff8800c50be538 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88042fc60000(0063) knlGS:00000000e439c700
CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
CR2: 0000000000000010 CR3: 0000000001d8f000 CR4: 00000000000607f0
Stack:
...
Call Trace:
[<ffffffff81365a72>] __nfs_fscache_invalidate_page+0x42/0x70
[<ffffffff813553d5>] nfs_invalidate_page+0x75/0x90
[<ffffffff811b8f5e>] truncate_inode_page+0x8e/0x90
[<ffffffff811b90ad>] truncate_inode_pages_range.part.12+0x14d/0x620
[<ffffffff81d6387d>] ? __mutex_lock_slowpath+0x1fd/0x2e0
[<ffffffff811b95d3>] truncate_inode_pages_range+0x53/0x70
[<ffffffff811b969d>] truncate_inode_pages+0x2d/0x40
[<ffffffff811b96ff>] truncate_pagecache+0x4f/0x70
[<ffffffff81356840>] nfs_setattr_update_inode+0xa0/0x120
[<ffffffff81368de4>] nfs3_proc_setattr+0xc4/0xe0
[<ffffffff81357f78>] nfs_setattr+0xc8/0x150
[<ffffffff8122d95b>] notify_change+0x1cb/0x390
[<ffffffff8120a55b>] do_truncate+0x7b/0xc0
[<ffffffff8121f96c>] do_last+0xa4c/0xfd0
[<ffffffff8121ffbc>] path_openat+0xcc/0x670
[<ffffffff81220a0e>] do_filp_open+0x4e/0xb0
[<ffffffff8120ba1f>] do_sys_open+0x13f/0x2b0
[<ffffffff8126aaf6>] compat_SyS_open+0x36/0x50
[<ffffffff81d7204c>] sysenter_dispatch+0x7/0x24
The code at the instruction pointer was disassembled:
> (gdb) disas __fscache_uncache_page
> Dump of assembler code for function __fscache_uncache_page:
> ...
> 0xffffffff812a18ff <+31>: mov 0x48(%rbx),%rax
> 0xffffffff812a1903 <+35>: cmpb $0x0,0x10(%rax)
> 0xffffffff812a1907 <+39>: je 0xffffffff812a19cd <__fscache_uncache_page+237>
These instructions make up:
ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
That cmpb is the faulting instruction (%rax is 0). So cookie->def is NULL -
which presumably means that the cookie has already been at least partway
through __fscache_relinquish_cookie().
What I think may be happening is something like a three-way race on the same
file:
PROCESS 1 PROCESS 2 PROCESS 3
=============== =============== ===============
open(O_TRUNC|O_WRONLY)
open(O_RDONLY)
open(O_WRONLY)
-->nfs_open()
-->nfs_fscache_set_inode_cookie()
nfs_fscache_inode_lock()
nfs_fscache_disable_inode_cookie()
__fscache_relinquish_cookie()
nfs_inode->fscache = NULL
<--nfs_fscache_set_inode_cookie()
-->nfs_open()
-->nfs_fscache_set_inode_cookie()
nfs_fscache_inode_lock()
nfs_fscache_enable_inode_cookie()
__fscache_acquire_cookie()
nfs_inode->fscache = cookie
<--nfs_fscache_set_inode_cookie()
<--nfs_open()
-->nfs_setattr()
...
...
-->nfs_invalidate_page()
-->__nfs_fscache_invalidate_page()
cookie = nfsi->fscache
-->nfs_open()
-->nfs_fscache_set_inode_cookie()
nfs_fscache_inode_lock()
nfs_fscache_disable_inode_cookie()
-->__fscache_relinquish_cookie()
-->__fscache_uncache_page(cookie)
<crash>
<--__fscache_relinquish_cookie()
nfs_inode->fscache = NULL
<--nfs_fscache_set_inode_cookie()
What is needed is something to prevent process #2 from reacquiring the cookie
- and I think checking i_writecount should do the trick.
It's also possible to have a two-way race on this if the file is opened
O_TRUNC|O_RDONLY instead.
Reported-by: Mark Moseley <moseleymark@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 2 | ||||
-rw-r--r-- | fs/nfs/fscache.c | 198 | ||||
-rw-r--r-- | fs/nfs/fscache.h | 18 | ||||
-rw-r--r-- | fs/nfs/inode.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4file.c | 2 |
5 files changed, 68 insertions, 158 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 854a8f05a610..4c5edcc8b6e9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1381,7 +1381,7 @@ static struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, i | |||
1381 | 1381 | ||
1382 | static int do_open(struct inode *inode, struct file *filp) | 1382 | static int do_open(struct inode *inode, struct file *filp) |
1383 | { | 1383 | { |
1384 | nfs_fscache_set_inode_cookie(inode, filp); | 1384 | nfs_fscache_open_file(inode, filp); |
1385 | return 0; | 1385 | return 0; |
1386 | } | 1386 | } |
1387 | 1387 | ||
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index cd6e7efd4305..3ef01f0ba0bc 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -178,163 +178,79 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) | |||
178 | /* | 178 | /* |
179 | * Initialise the per-inode cache cookie pointer for an NFS inode. | 179 | * Initialise the per-inode cache cookie pointer for an NFS inode. |
180 | */ | 180 | */ |
181 | void nfs_fscache_init_inode_cookie(struct inode *inode) | 181 | void nfs_fscache_init_inode(struct inode *inode) |
182 | { | 182 | { |
183 | NFS_I(inode)->fscache = NULL; | ||
184 | if (S_ISREG(inode->i_mode)) | ||
185 | set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Get the per-inode cache cookie for an NFS inode. | ||
190 | */ | ||
191 | static void nfs_fscache_enable_inode_cookie(struct inode *inode) | ||
192 | { | ||
193 | struct super_block *sb = inode->i_sb; | ||
194 | struct nfs_inode *nfsi = NFS_I(inode); | 183 | struct nfs_inode *nfsi = NFS_I(inode); |
195 | 184 | ||
196 | if (nfsi->fscache || !NFS_FSCACHE(inode)) | 185 | nfsi->fscache = NULL; |
186 | if (!S_ISREG(inode->i_mode)) | ||
197 | return; | 187 | return; |
198 | 188 | nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, | |
199 | if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) { | 189 | &nfs_fscache_inode_object_def, |
200 | nfsi->fscache = fscache_acquire_cookie( | 190 | nfsi, false); |
201 | NFS_SB(sb)->fscache, | ||
202 | &nfs_fscache_inode_object_def, | ||
203 | nfsi, true); | ||
204 | |||
205 | dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n", | ||
206 | sb, nfsi, nfsi->fscache); | ||
207 | } | ||
208 | } | 191 | } |
209 | 192 | ||
210 | /* | 193 | /* |
211 | * Release a per-inode cookie. | 194 | * Release a per-inode cookie. |
212 | */ | 195 | */ |
213 | void nfs_fscache_release_inode_cookie(struct inode *inode) | 196 | void nfs_fscache_clear_inode(struct inode *inode) |
214 | { | 197 | { |
215 | struct nfs_inode *nfsi = NFS_I(inode); | 198 | struct nfs_inode *nfsi = NFS_I(inode); |
199 | struct fscache_cookie *cookie = nfs_i_fscache(inode); | ||
216 | 200 | ||
217 | dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", | 201 | dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); |
218 | nfsi, nfsi->fscache); | ||
219 | 202 | ||
220 | fscache_relinquish_cookie(nfsi->fscache, 0); | 203 | fscache_relinquish_cookie(cookie, false); |
221 | nfsi->fscache = NULL; | 204 | nfsi->fscache = NULL; |
222 | } | 205 | } |
223 | 206 | ||
224 | /* | 207 | static bool nfs_fscache_can_enable(void *data) |
225 | * Retire a per-inode cookie, destroying the data attached to it. | ||
226 | */ | ||
227 | void nfs_fscache_zap_inode_cookie(struct inode *inode) | ||
228 | { | 208 | { |
229 | struct nfs_inode *nfsi = NFS_I(inode); | 209 | struct inode *inode = data; |
230 | 210 | ||
231 | dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n", | 211 | return !inode_is_open_for_write(inode); |
232 | nfsi, nfsi->fscache); | ||
233 | |||
234 | fscache_relinquish_cookie(nfsi->fscache, 1); | ||
235 | nfsi->fscache = NULL; | ||
236 | } | 212 | } |
237 | 213 | ||
238 | /* | 214 | /* |
239 | * Turn off the cache with regard to a per-inode cookie if opened for writing, | 215 | * Enable or disable caching for a file that is being opened as appropriate. |
240 | * invalidating all the pages in the page cache relating to the associated | 216 | * The cookie is allocated when the inode is initialised, but is not enabled at |
241 | * inode to clear the per-page caching. | 217 | * that time. Enablement is deferred to file-open time to avoid stat() and |
242 | */ | 218 | * access() thrashing the cache. |
243 | static void nfs_fscache_disable_inode_cookie(struct inode *inode) | 219 | * |
244 | { | 220 | * For now, with NFS, only regular files that are open read-only will be able |
245 | clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); | 221 | * to use the cache. |
246 | 222 | * | |
247 | if (NFS_I(inode)->fscache) { | 223 | * We enable the cache for an inode if we open it read-only and it isn't |
248 | dfprintk(FSCACHE, | 224 | * currently open for writing. We disable the cache if the inode is open |
249 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); | 225 | * write-only. |
250 | 226 | * | |
251 | /* Need to uncache any pages attached to this inode that | 227 | * The caller uses the file struct to pin i_writecount on the inode before |
252 | * fscache knows about before turning off the cache. | 228 | * calling us when a file is opened for writing, so we can make use of that. |
253 | */ | 229 | * |
254 | fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); | 230 | * Note that this may be invoked multiple times in parallel by parallel |
255 | nfs_fscache_zap_inode_cookie(inode); | 231 | * nfs_open() functions. |
256 | } | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * wait_on_bit() sleep function for uninterruptible waiting | ||
261 | */ | ||
262 | static int nfs_fscache_wait_bit(void *flags) | ||
263 | { | ||
264 | schedule(); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Lock against someone else trying to also acquire or relinquish a cookie | ||
270 | */ | ||
271 | static inline void nfs_fscache_inode_lock(struct inode *inode) | ||
272 | { | ||
273 | struct nfs_inode *nfsi = NFS_I(inode); | ||
274 | |||
275 | while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags)) | ||
276 | wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK, | ||
277 | nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE); | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * Unlock cookie management lock | ||
282 | */ | ||
283 | static inline void nfs_fscache_inode_unlock(struct inode *inode) | ||
284 | { | ||
285 | struct nfs_inode *nfsi = NFS_I(inode); | ||
286 | |||
287 | smp_mb__before_clear_bit(); | ||
288 | clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags); | ||
289 | smp_mb__after_clear_bit(); | ||
290 | wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK); | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Decide if we should enable or disable local caching for this inode. | ||
295 | * - For now, with NFS, only regular files that are open read-only will be able | ||
296 | * to use the cache. | ||
297 | * - May be invoked multiple times in parallel by parallel nfs_open() functions. | ||
298 | */ | ||
299 | void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) | ||
300 | { | ||
301 | if (NFS_FSCACHE(inode)) { | ||
302 | nfs_fscache_inode_lock(inode); | ||
303 | if ((filp->f_flags & O_ACCMODE) != O_RDONLY) | ||
304 | nfs_fscache_disable_inode_cookie(inode); | ||
305 | else | ||
306 | nfs_fscache_enable_inode_cookie(inode); | ||
307 | nfs_fscache_inode_unlock(inode); | ||
308 | } | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(nfs_fscache_set_inode_cookie); | ||
311 | |||
312 | /* | ||
313 | * Replace a per-inode cookie due to revalidation detecting a file having | ||
314 | * changed on the server. | ||
315 | */ | 232 | */ |
316 | void nfs_fscache_reset_inode_cookie(struct inode *inode) | 233 | void nfs_fscache_open_file(struct inode *inode, struct file *filp) |
317 | { | 234 | { |
318 | struct nfs_inode *nfsi = NFS_I(inode); | 235 | struct nfs_inode *nfsi = NFS_I(inode); |
319 | struct nfs_server *nfss = NFS_SERVER(inode); | 236 | struct fscache_cookie *cookie = nfs_i_fscache(inode); |
320 | NFS_IFDEBUG(struct fscache_cookie *old = nfsi->fscache); | ||
321 | 237 | ||
322 | nfs_fscache_inode_lock(inode); | 238 | if (!fscache_cookie_valid(cookie)) |
323 | if (nfsi->fscache) { | 239 | return; |
324 | /* retire the current fscache cache and get a new one */ | ||
325 | fscache_relinquish_cookie(nfsi->fscache, 1); | ||
326 | |||
327 | nfsi->fscache = fscache_acquire_cookie( | ||
328 | nfss->nfs_client->fscache, | ||
329 | &nfs_fscache_inode_object_def, | ||
330 | nfsi, true); | ||
331 | 240 | ||
332 | dfprintk(FSCACHE, | 241 | if (inode_is_open_for_write(inode)) { |
333 | "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n", | 242 | dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); |
334 | nfss, nfsi, old, nfsi->fscache); | 243 | clear_bit(NFS_INO_FSCACHE, &nfsi->flags); |
244 | fscache_disable_cookie(cookie, true); | ||
245 | fscache_uncache_all_inode_pages(cookie, inode); | ||
246 | } else { | ||
247 | dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); | ||
248 | fscache_enable_cookie(cookie, nfs_fscache_can_enable, inode); | ||
249 | if (fscache_cookie_enabled(cookie)) | ||
250 | set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); | ||
335 | } | 251 | } |
336 | nfs_fscache_inode_unlock(inode); | ||
337 | } | 252 | } |
253 | EXPORT_SYMBOL_GPL(nfs_fscache_open_file); | ||
338 | 254 | ||
339 | /* | 255 | /* |
340 | * Release the caching state associated with a page, if the page isn't busy | 256 | * Release the caching state associated with a page, if the page isn't busy |
@@ -344,12 +260,11 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode) | |||
344 | int nfs_fscache_release_page(struct page *page, gfp_t gfp) | 260 | int nfs_fscache_release_page(struct page *page, gfp_t gfp) |
345 | { | 261 | { |
346 | if (PageFsCache(page)) { | 262 | if (PageFsCache(page)) { |
347 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); | 263 | struct fscache_cookie *cookie = nfs_i_fscache(page->mapping->host); |
348 | struct fscache_cookie *cookie = nfsi->fscache; | ||
349 | 264 | ||
350 | BUG_ON(!cookie); | 265 | BUG_ON(!cookie); |
351 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", | 266 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", |
352 | cookie, page, nfsi); | 267 | cookie, page, NFS_I(page->mapping->host)); |
353 | 268 | ||
354 | if (!fscache_maybe_release_page(cookie, page, gfp)) | 269 | if (!fscache_maybe_release_page(cookie, page, gfp)) |
355 | return 0; | 270 | return 0; |
@@ -367,13 +282,12 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp) | |||
367 | */ | 282 | */ |
368 | void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode) | 283 | void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode) |
369 | { | 284 | { |
370 | struct nfs_inode *nfsi = NFS_I(inode); | 285 | struct fscache_cookie *cookie = nfs_i_fscache(inode); |
371 | struct fscache_cookie *cookie = nfsi->fscache; | ||
372 | 286 | ||
373 | BUG_ON(!cookie); | 287 | BUG_ON(!cookie); |
374 | 288 | ||
375 | dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n", | 289 | dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n", |
376 | cookie, page, nfsi); | 290 | cookie, page, NFS_I(inode)); |
377 | 291 | ||
378 | fscache_wait_on_page_write(cookie, page); | 292 | fscache_wait_on_page_write(cookie, page); |
379 | 293 | ||
@@ -417,9 +331,9 @@ int __nfs_readpage_from_fscache(struct nfs_open_context *ctx, | |||
417 | 331 | ||
418 | dfprintk(FSCACHE, | 332 | dfprintk(FSCACHE, |
419 | "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n", | 333 | "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n", |
420 | NFS_I(inode)->fscache, page, page->index, page->flags, inode); | 334 | nfs_i_fscache(inode), page, page->index, page->flags, inode); |
421 | 335 | ||
422 | ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache, | 336 | ret = fscache_read_or_alloc_page(nfs_i_fscache(inode), |
423 | page, | 337 | page, |
424 | nfs_readpage_from_fscache_complete, | 338 | nfs_readpage_from_fscache_complete, |
425 | ctx, | 339 | ctx, |
@@ -459,9 +373,9 @@ int __nfs_readpages_from_fscache(struct nfs_open_context *ctx, | |||
459 | int ret; | 373 | int ret; |
460 | 374 | ||
461 | dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n", | 375 | dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n", |
462 | NFS_I(inode)->fscache, npages, inode); | 376 | nfs_i_fscache(inode), npages, inode); |
463 | 377 | ||
464 | ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache, | 378 | ret = fscache_read_or_alloc_pages(nfs_i_fscache(inode), |
465 | mapping, pages, nr_pages, | 379 | mapping, pages, nr_pages, |
466 | nfs_readpage_from_fscache_complete, | 380 | nfs_readpage_from_fscache_complete, |
467 | ctx, | 381 | ctx, |
@@ -506,15 +420,15 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync) | |||
506 | 420 | ||
507 | dfprintk(FSCACHE, | 421 | dfprintk(FSCACHE, |
508 | "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n", | 422 | "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n", |
509 | NFS_I(inode)->fscache, page, page->index, page->flags, sync); | 423 | nfs_i_fscache(inode), page, page->index, page->flags, sync); |
510 | 424 | ||
511 | ret = fscache_write_page(NFS_I(inode)->fscache, page, GFP_KERNEL); | 425 | ret = fscache_write_page(nfs_i_fscache(inode), page, GFP_KERNEL); |
512 | dfprintk(FSCACHE, | 426 | dfprintk(FSCACHE, |
513 | "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n", | 427 | "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n", |
514 | page, page->index, page->flags, ret); | 428 | page, page->index, page->flags, ret); |
515 | 429 | ||
516 | if (ret != 0) { | 430 | if (ret != 0) { |
517 | fscache_uncache_page(NFS_I(inode)->fscache, page); | 431 | fscache_uncache_page(nfs_i_fscache(inode), page); |
518 | nfs_add_fscache_stats(inode, | 432 | nfs_add_fscache_stats(inode, |
519 | NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1); | 433 | NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1); |
520 | nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1); | 434 | nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1); |
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h index 4ecb76652eba..d7fe3e799f2f 100644 --- a/fs/nfs/fscache.h +++ b/fs/nfs/fscache.h | |||
@@ -76,11 +76,9 @@ extern void nfs_fscache_release_client_cookie(struct nfs_client *); | |||
76 | extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int); | 76 | extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int); |
77 | extern void nfs_fscache_release_super_cookie(struct super_block *); | 77 | extern void nfs_fscache_release_super_cookie(struct super_block *); |
78 | 78 | ||
79 | extern void nfs_fscache_init_inode_cookie(struct inode *); | 79 | extern void nfs_fscache_init_inode(struct inode *); |
80 | extern void nfs_fscache_release_inode_cookie(struct inode *); | 80 | extern void nfs_fscache_clear_inode(struct inode *); |
81 | extern void nfs_fscache_zap_inode_cookie(struct inode *); | 81 | extern void nfs_fscache_open_file(struct inode *, struct file *); |
82 | extern void nfs_fscache_set_inode_cookie(struct inode *, struct file *); | ||
83 | extern void nfs_fscache_reset_inode_cookie(struct inode *); | ||
84 | 82 | ||
85 | extern void __nfs_fscache_invalidate_page(struct page *, struct inode *); | 83 | extern void __nfs_fscache_invalidate_page(struct page *, struct inode *); |
86 | extern int nfs_fscache_release_page(struct page *, gfp_t); | 84 | extern int nfs_fscache_release_page(struct page *, gfp_t); |
@@ -187,12 +185,10 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {} | |||
187 | 185 | ||
188 | static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} | 186 | static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} |
189 | 187 | ||
190 | static inline void nfs_fscache_init_inode_cookie(struct inode *inode) {} | 188 | static inline void nfs_fscache_init_inode(struct inode *inode) {} |
191 | static inline void nfs_fscache_release_inode_cookie(struct inode *inode) {} | 189 | static inline void nfs_fscache_clear_inode(struct inode *inode) {} |
192 | static inline void nfs_fscache_zap_inode_cookie(struct inode *inode) {} | 190 | static inline void nfs_fscache_open_file(struct inode *inode, |
193 | static inline void nfs_fscache_set_inode_cookie(struct inode *inode, | 191 | struct file *filp) {} |
194 | struct file *filp) {} | ||
195 | static inline void nfs_fscache_reset_inode_cookie(struct inode *inode) {} | ||
196 | 192 | ||
197 | static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) | 193 | static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) |
198 | { | 194 | { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index eda8879171c4..bb90bff0cb7a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -122,7 +122,7 @@ void nfs_clear_inode(struct inode *inode) | |||
122 | WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files)); | 122 | WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files)); |
123 | nfs_zap_acl_cache(inode); | 123 | nfs_zap_acl_cache(inode); |
124 | nfs_access_zap_cache(inode); | 124 | nfs_access_zap_cache(inode); |
125 | nfs_fscache_release_inode_cookie(inode); | 125 | nfs_fscache_clear_inode(inode); |
126 | } | 126 | } |
127 | EXPORT_SYMBOL_GPL(nfs_clear_inode); | 127 | EXPORT_SYMBOL_GPL(nfs_clear_inode); |
128 | 128 | ||
@@ -459,7 +459,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
459 | nfsi->attrtimeo_timestamp = now; | 459 | nfsi->attrtimeo_timestamp = now; |
460 | nfsi->access_cache = RB_ROOT; | 460 | nfsi->access_cache = RB_ROOT; |
461 | 461 | ||
462 | nfs_fscache_init_inode_cookie(inode); | 462 | nfs_fscache_init_inode(inode); |
463 | 463 | ||
464 | unlock_new_inode(inode); | 464 | unlock_new_inode(inode); |
465 | } else | 465 | } else |
@@ -854,7 +854,7 @@ int nfs_open(struct inode *inode, struct file *filp) | |||
854 | return PTR_ERR(ctx); | 854 | return PTR_ERR(ctx); |
855 | nfs_file_set_open_context(filp, ctx); | 855 | nfs_file_set_open_context(filp, ctx); |
856 | put_nfs_open_context(ctx); | 856 | put_nfs_open_context(ctx); |
857 | nfs_fscache_set_inode_cookie(inode, filp); | 857 | nfs_fscache_open_file(inode, filp); |
858 | return 0; | 858 | return 0; |
859 | } | 859 | } |
860 | 860 | ||
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index e5b804dd944c..5b8a618a0f7a 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
@@ -74,7 +74,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) | |||
74 | 74 | ||
75 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 75 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
76 | nfs_file_set_open_context(filp, ctx); | 76 | nfs_file_set_open_context(filp, ctx); |
77 | nfs_fscache_set_inode_cookie(inode, filp); | 77 | nfs_fscache_open_file(inode, filp); |
78 | err = 0; | 78 | err = 0; |
79 | 79 | ||
80 | out_put_ctx: | 80 | out_put_ctx: |