1. 06 4月, 2018 1 次提交
  2. 04 4月, 2018 1 次提交
    • D
      fscache: Attach the index key and aux data to the cookie · 402cb8dd
      David Howells 提交于
      Attach copies of the index key and auxiliary data to the fscache cookie so
      that:
      
       (1) The callbacks to the netfs for this stuff can be eliminated.  This
           can simplify things in the cache as the information is still
           available, even after the cache has relinquished the cookie.
      
       (2) Simplifies the locking requirements of accessing the information as we
           don't have to worry about the netfs object going away on us.
      
       (3) The cache can do lazy updating of the coherency information on disk.
           As long as the cache is flushed before reboot/poweroff, there's no
           need to update the coherency info on disk every time it changes.
      
       (4) Cookies can be hashed or put in a tree as the index key is easily
           available.  This allows:
      
           (a) Checks for duplicate cookies can be made at the top fscache layer
           	 rather than down in the bowels of the cache backend.
      
           (b) Caching can be added to a netfs object that has a cookie if the
           	 cache is brought online after the netfs object is allocated.
      
      A certain amount of space is made in the cookie for inline copies of the
      data, but if it won't fit there, extra memory will be allocated for it.
      
      The downside of this is that live cache operation requires more memory.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NAnna Schumaker <anna.schumaker@netapp.com>
      Tested-by: NSteve Dickson <steved@redhat.com>
      402cb8dd
  3. 28 9月, 2013 1 次提交
    • D
      NFS: Use i_writecount to control whether to get an fscache cookie in nfs_open() · f1fe29b4
      David Howells 提交于
      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: NMark Moseley <moseleymark@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      f1fe29b4
  4. 22 12月, 2012 1 次提交
  5. 21 12月, 2012 1 次提交
    • D
      NFS: Use FS-Cache invalidation · de242c0b
      David Howells 提交于
      Use the new FS-Cache invalidation facility from NFS to deal with foreign
      changes being detected on the server rather than attempting to retire the old
      cookie and get a new one.
      
      The problem with the old method was that NFS did not wait for all outstanding
      storage and retrieval ops on the cache to complete.  There was no automatic
      wait between the calls to ->readpages() and calls to invalidate_inode_pages2()
      as the latter can only wait on locked pages that have been added to the
      pagecache (which they haven't yet on entry to ->readpages()).
      
      This was leading to oopses like the one below when an outstanding read got cut
      off from its cookie by a premature release.
      
      BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8
      IP: [<ffffffffa0075118>] __fscache_read_or_alloc_pages+0x1dd/0x315 [fscache]
      PGD 15889067 PUD 15890067 PMD 0
      Oops: 0000 [#1] SMP
      CPU 0
      Modules linked in: cachefiles nfs fscache auth_rpcgss nfs_acl lockd sunrpc
      
      Pid: 4544, comm: tar Not tainted 3.1.0-rc4-fsdevel+ #1064                  /DG965RY
      RIP: 0010:[<ffffffffa0075118>]  [<ffffffffa0075118>] __fscache_read_or_alloc_pages+0x1dd/0x315 [fscache]
      RSP: 0018:ffff8800158799e8  EFLAGS: 00010246
      RAX: 0000000000000000 RBX: ffff8800070d41e0 RCX: ffff8800083dc1b0
      RDX: 0000000000000000 RSI: ffff880015879960 RDI: ffff88003e627b90
      RBP: ffff880015879a28 R08: 0000000000000002 R09: 0000000000000002
      R10: 0000000000000001 R11: ffff880015879950 R12: ffff880015879aa4
      R13: 0000000000000000 R14: ffff8800083dc158 R15: ffff880015879be8
      FS:  00007f671e9d87c0(0000) GS:ffff88003bc00000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      CR2: 00000000000000a8 CR3: 000000001587f000 CR4: 00000000000006f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      Process tar (pid: 4544, threadinfo ffff880015878000, task ffff880015875040)
      Stack:
       ffffffffa00b1759 ffff8800070dc158 ffff8800000213da ffff88002a286508
       ffff880015879aa4 ffff880015879be8 0000000000000001 ffff88002a2866e8
       ffff880015879a88 ffffffffa00b20be 00000000000200da ffff880015875040
      Call Trace:
       [<ffffffffa00b1759>] ? nfs_fscache_wait_bit+0xd/0xd [nfs]
       [<ffffffffa00b20be>] __nfs_readpages_from_fscache+0x7e/0x13f [nfs]
       [<ffffffff81095fe7>] ? __alloc_pages_nodemask+0x156/0x662
       [<ffffffffa0098763>] nfs_readpages+0xee/0x187 [nfs]
       [<ffffffff81098a5e>] __do_page_cache_readahead+0x1be/0x267
       [<ffffffff81098942>] ? __do_page_cache_readahead+0xa2/0x267
       [<ffffffff81098d7b>] ra_submit+0x1c/0x20
       [<ffffffff8109900a>] ondemand_readahead+0x28b/0x29a
       [<ffffffff810990ce>] page_cache_sync_readahead+0x38/0x3a
       [<ffffffff81091d8a>] generic_file_aio_read+0x2ab/0x67e
       [<ffffffffa008cfbe>] nfs_file_read+0xa4/0xc9 [nfs]
       [<ffffffff810c22c4>] do_sync_read+0xba/0xfa
       [<ffffffff810a62c9>] ? might_fault+0x4e/0x9e
       [<ffffffff81177a47>] ? security_file_permission+0x7b/0x84
       [<ffffffff810c25dd>] ? rw_verify_area+0xab/0xc8
       [<ffffffff810c29a4>] vfs_read+0xaa/0x13a
       [<ffffffff810c2a79>] sys_read+0x45/0x6c
       [<ffffffff813ac37b>] system_call_fastpath+0x16/0x1b
      Reported-by: NMark Moseley <moseleymark@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      de242c0b
  6. 17 5月, 2012 1 次提交
  7. 15 5月, 2012 1 次提交
  8. 24 9月, 2009 1 次提交
    • D
      NFS: Propagate 'fsc' mount option through automounts · 2df54806
      David Howells 提交于
      Propagate the NFS 'fsc' mount option through NFS automounts of various types.
      
      This is now required as commit:
      
      	commit c02d7adf
      	Author: Trond Myklebust <Trond.Myklebust@netapp.com>
      	Date:   Mon Jun 22 15:09:14 2009 -0400
      
      	NFSv4: Replace nfs4_path_walk() with VFS path lookup in a private namespace
      
      uses VFS-driven automounting to reach all submounts barring the root, thus
      preventing fscaching from being enabled on any submount other than the root.
      
      This patch gets around that by propagating the NFS_OPTION_FSCACHE flag across
      automounts.  If a uniquifier is supplied to a mount then this is propagated to
      all automounts of that mount too.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      [Trond: Fixed up the definition of nfs_fscache_get_super_cookie for the
              case of #undef CONFIG_NFS_FSCACHE]
      Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
      2df54806
  9. 03 4月, 2009 9 次提交