Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'fscache-fixes-20181130' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull fscache and cachefiles fixes from David Howells:
"Misc fixes:

- Fix an assertion failure at fs/cachefiles/xattr.c:138 caused by a
race between a cache object lookup failing and someone attempting
to reenable that object, thereby triggering an update of the
object's attributes.

- Fix an assertion failure at fs/fscache/operation.c:449 caused by a
split atomic subtract and atomic read that allows a race to happen.

- Fix a leak of backing pages when simultaneously reading the same
page from the same object from two or more threads.

- Fix a hang due to a race between a cache object being discarded and
the corresponding cookie being reenabled.

There are also some minor cleanups:

- Cast an enum value to a different enum type to prevent clang from
generating a warning. This shouldn't cause any sort of change in
the emitted code.

- Use ktime_get_real_seconds() instead of get_seconds(). This is just
used to uniquify a filename for an object to be placed in the
graveyard. Objects placed there are deleted by cachfilesd in
userspace immediately thereafter.

- Remove an initialised, but otherwise unused variable. This should
have been entirely optimised away anyway"

* tag 'fscache-fixes-20181130' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
fscache, cachefiles: remove redundant variable 'cache'
cachefiles: avoid deprecated get_seconds()
cachefiles: Explicitly cast enumerated type in put_object
fscache: fix race between enablement and dropping of object
cachefiles: Fix page leak in cachefiles_read_backing_file while vmscan is active
fscache: Fix race in fscache_op_complete() due to split atomic_sub & read
cachefiles: Fix an assertion failure when trying to update a failed object

+17 -9
+5 -3
fs/cachefiles/namei.c
··· 244 244 245 245 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); 246 246 247 - cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry); 247 + cache->cache.ops->put_object(&xobject->fscache, 248 + (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_retry); 248 249 goto try_again; 249 250 250 251 requeue: 251 - cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo); 252 + cache->cache.ops->put_object(&xobject->fscache, 253 + (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_timeo); 252 254 _leave(" = -ETIMEDOUT"); 253 255 return -ETIMEDOUT; 254 256 } ··· 338 336 try_again: 339 337 /* first step is to make up a grave dentry in the graveyard */ 340 338 sprintf(nbuffer, "%08x%08x", 341 - (uint32_t) get_seconds(), 339 + (uint32_t) ktime_get_real_seconds(), 342 340 (uint32_t) atomic_inc_return(&cache->gravecounter)); 343 341 344 342 /* do the multiway lock magic */
+6 -3
fs/cachefiles/rdwr.c
··· 535 535 netpage->index, cachefiles_gfp); 536 536 if (ret < 0) { 537 537 if (ret == -EEXIST) { 538 + put_page(backpage); 539 + backpage = NULL; 538 540 put_page(netpage); 541 + netpage = NULL; 539 542 fscache_retrieval_complete(op, 1); 540 543 continue; 541 544 } ··· 611 608 netpage->index, cachefiles_gfp); 612 609 if (ret < 0) { 613 610 if (ret == -EEXIST) { 611 + put_page(backpage); 612 + backpage = NULL; 614 613 put_page(netpage); 614 + netpage = NULL; 615 615 fscache_retrieval_complete(op, 1); 616 616 continue; 617 617 } ··· 968 962 __releases(&object->fscache.cookie->lock) 969 963 { 970 964 struct cachefiles_object *object; 971 - struct cachefiles_cache *cache; 972 965 973 966 object = container_of(_object, struct cachefiles_object, fscache); 974 - cache = container_of(object->fscache.cache, 975 - struct cachefiles_cache, cache); 976 967 977 968 _enter("%p,{%lu}", object, page->index); 978 969
+2 -1
fs/cachefiles/xattr.c
··· 135 135 struct dentry *dentry = object->dentry; 136 136 int ret; 137 137 138 - ASSERT(dentry); 138 + if (!dentry) 139 + return -ESTALE; 139 140 140 141 _enter("%p,#%d", object, auxdata->len); 141 142
+3
fs/fscache/object.c
··· 730 730 731 731 if (awaken) 732 732 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING); 733 + if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags)) 734 + wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP); 735 + 733 736 734 737 /* Prevent a race with our last child, which has to signal EV_CLEARED 735 738 * before dropping our spinlock.
+1 -2
include/linux/fscache-cache.h
··· 196 196 static inline void fscache_retrieval_complete(struct fscache_retrieval *op, 197 197 int n_pages) 198 198 { 199 - atomic_sub(n_pages, &op->n_pages); 200 - if (atomic_read(&op->n_pages) <= 0) 199 + if (atomic_sub_return_relaxed(n_pages, &op->n_pages) <= 0) 201 200 fscache_op_complete(&op->op, false); 202 201 } 203 202