• David Howells's avatar
    FS-Cache: Permit fscache_cancel_op() to cancel in-progress operations too · 418b7eb9
    David Howells authored
    Currently, fscache_cancel_op() only cancels pending operations - attempts to
    cancel in-progress operations are ignored.  This leads to a problem in
    fscache_wait_for_operation_activation() whereby the wait is terminated, but
    the object has been killed.
    
    The check at the end of the function now triggers because it's no longer
    contingent on the cache having produced an I/O error since the commit that
    fixed the logic error in fscache_object_is_dead().
    
    The result of the check is that it tries to cancel the operation - but since
    the object may not be pending by this point, the cancellation request may be
    ignored - with the result that the the object is just put by the caller and
    fscache_put_operation has an assertion failure because the operation isn't in
    either the COMPLETE or the CANCELLED states.
    
    To fix this, we permit in-progress ops to be cancelled under some
    circumstances.
    
    The bug results in an oops that looks something like this:
    
    	FS-Cache: fscache_wait_for_operation_activation() = -ENOBUFS [obj dead 3]
    	FS-Cache:
    	FS-Cache: Assertion failed
    	FS-Cache: 3 == 5 is false
    	------------[ cut here ]------------
    	kernel BUG at ../fs/fscache/operation.c:432!
    	...
    	RIP: 0010:[<ffffffffa0088574>] fscache_put_operation+0xf2/0x2cd
    	Call Trace:
    	 [<ffffffffa008b92a>] __fscache_read_or_alloc_pages+0x2ec/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
    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>
    418b7eb9
page.c 31.1 KB