Skip to content
  • David Howells's avatar
    FS-Cache: The operation cancellation method needs calling in more places · d3b97ca4
    David Howells authored
    
    
    Any time an incomplete operation is cancelled, the operation cancellation
    function needs to be called to clean up.  This is currently being passed
    directly to some of the functions that might want to call it, but not all.
    
    Instead, pass the cancellation method pointer to the fscache_operation_init()
    and have that cache it in the operation struct.  Further, plug in a dummy
    cancellation handler if the caller declines to set one as this allows us to
    call the function unconditionally (the extra overhead isn't worth bothering
    about as we don't expect to be calling this typically).
    
    The cancellation method must thence be called everywhere the CANCELLED state
    is set.  Note that we call it *before* setting the CANCELLED state such that
    the method can use the old state value to guide its operation.
    
    fscache_do_cancel_retrieval() needs moving higher up in the sources so that
    the init function can use it now.
    
    Without this, the following oops may be seen:
    
    	FS-Cache: Assertion failed
    	FS-Cache: 3 == 0 is false
    	------------[ cut here ]------------
    	kernel BUG at ../fs/fscache/page.c:261!
    	...
    	RIP: 0010:[<ffffffffa0089c1b>]  fscache_release_retrieval_op+0x77/0x100
    	 [<ffffffffa008853d>] fscache_put_operation+0x114/0x2da
    	 [<ffffffffa008b8c2>] __fscache_read_or_alloc_pages+0x358/0x3b3
    	 [<ffffffffa00b761f>] __nfs_readpages_from_fscache+0x59/0xbf [nfs]
    	 [<ffffffffa00b06c5>] nfs_readpages+0x10c/0x185 [nfs]
    	 [<ffffffff81124925>] ? alloc_pages_current+0x119/0x13e
    	 [<ffffffff810ee5fd>] ? __page_cache_alloc+0xfb/0x10a
    	 [<ffffffff810f87f8>] __do_page_cache_readahead+0x188/0x22c
    	 [<ffffffff810f8b3a>] ondemand_readahead+0x29e/0x2af
    	 [<ffffffff810f8c92>] page_cache_sync_readahead+0x38/0x3a
    	 [<ffffffff810ef337>] generic_file_read_iter+0x1a2/0x55a
    	 [<ffffffffa00a9dff>] ? nfs_revalidate_mapping+0xd6/0x288 [nfs]
    	 [<ffffffffa00a6a23>] nfs_file_read+0x49/0x70 [nfs]
    	 [<ffffffff811363be>] new_sync_read+0x78/0x9c
    	 [<ffffffff81137164>] __vfs_read+0x13/0x38
    	 [<ffffffff8113721e>] vfs_read+0x95/0x121
    	 [<ffffffff811372f6>] SyS_read+0x4c/0x8a
    	 [<ffffffff81557a52>] system_call_fastpath+0x12/0x17
    
    The assertion is showing that the remaining number of pages (n_pages) is not 0
    when the operation is being released.
    
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Reviewed-by: default avatarSteve Dickson <steved@redhat.com>
    Acked-by: default avatarJeff Layton <jeff.layton@primarydata.com>
    d3b97ca4