mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
FS-Cache fixes
-----BEGIN PGP SIGNATURE----- iQIVAwUAXAFfSPu3V2unywtrAQKPQRAAiHDs2d35Kc2qkTFLwGiP+wr+3+7Cyz7A hrWAvR7Oe7nBFVPmp6pwEnpBhf3mPsWlQpw3ZKZPo4fDQyRX+mDFC+2C7hkU1Q/J BkjTG4vYn1jiQGlL3SD1PfUxcWfwzoK4cz+V3hnFY5y0dsKiBZBR1Lw5G+UkaCnD 4VaC3VAG56Vh14o5qSF3TWLZFyZ+JN6YA/M/DnwRPl8y4jnj1tJLs1DjdpEcWv6r 15FKb2FRYaC7MRehpXd22JX6fv5ii2xazU3IfLucBrb4Vj+wAJrBY4wA3x/CFkAa as1VmxLkgoJEWa3M71tQOJBC8+QqkRb++PRUI3aadt2H4hXHfx3AmBuKkVroeS8o 0BDhWGiTW4AqXUajkQcTc/mKV2x6h83V3DLyBRL1iC3+7qaBVhPNtxW+v6ln0Ce1 FRG2I9LZp+RtWrVVyIPsa03V2V5OD7PTIBXK6TYtuqL+3uu7TNNc+UySvqDHWLL+ Zo2ogpq//kZbjMdntNVhDEj12LW3zG05dtNuFEeJeuPM28yiXXtoWDmI49RAUQ4v RN6SwEXnKWehwG+YITYavV6gfHWlXdZ7grgCMHyViF/s9khBp7AGxbRzR0JXgXqL ko1Ojpbq2mdvjwGFQfde4MAqAxM3FPxdxGVLrgi+lgGTsEKv6IzrTo28teyAM81O D6cH0ldY90w= =6y+F -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
fd3b3e0ec5
@ -244,11 +244,13 @@ wait_for_old_object:
|
|||||||
|
|
||||||
ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
|
ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
|
||||||
|
|
||||||
cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
|
cache->cache.ops->put_object(&xobject->fscache,
|
||||||
|
(enum fscache_obj_ref_trace)cachefiles_obj_put_wait_retry);
|
||||||
goto try_again;
|
goto try_again;
|
||||||
|
|
||||||
requeue:
|
requeue:
|
||||||
cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
|
cache->cache.ops->put_object(&xobject->fscache,
|
||||||
|
(enum fscache_obj_ref_trace)cachefiles_obj_put_wait_timeo);
|
||||||
_leave(" = -ETIMEDOUT");
|
_leave(" = -ETIMEDOUT");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
@ -336,7 +338,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
|
|||||||
try_again:
|
try_again:
|
||||||
/* first step is to make up a grave dentry in the graveyard */
|
/* first step is to make up a grave dentry in the graveyard */
|
||||||
sprintf(nbuffer, "%08x%08x",
|
sprintf(nbuffer, "%08x%08x",
|
||||||
(uint32_t) get_seconds(),
|
(uint32_t) ktime_get_real_seconds(),
|
||||||
(uint32_t) atomic_inc_return(&cache->gravecounter));
|
(uint32_t) atomic_inc_return(&cache->gravecounter));
|
||||||
|
|
||||||
/* do the multiway lock magic */
|
/* do the multiway lock magic */
|
||||||
|
@ -535,7 +535,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
|
|||||||
netpage->index, cachefiles_gfp);
|
netpage->index, cachefiles_gfp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -EEXIST) {
|
if (ret == -EEXIST) {
|
||||||
|
put_page(backpage);
|
||||||
|
backpage = NULL;
|
||||||
put_page(netpage);
|
put_page(netpage);
|
||||||
|
netpage = NULL;
|
||||||
fscache_retrieval_complete(op, 1);
|
fscache_retrieval_complete(op, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -608,7 +611,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
|
|||||||
netpage->index, cachefiles_gfp);
|
netpage->index, cachefiles_gfp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret == -EEXIST) {
|
if (ret == -EEXIST) {
|
||||||
|
put_page(backpage);
|
||||||
|
backpage = NULL;
|
||||||
put_page(netpage);
|
put_page(netpage);
|
||||||
|
netpage = NULL;
|
||||||
fscache_retrieval_complete(op, 1);
|
fscache_retrieval_complete(op, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -962,11 +968,8 @@ void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
|
|||||||
__releases(&object->fscache.cookie->lock)
|
__releases(&object->fscache.cookie->lock)
|
||||||
{
|
{
|
||||||
struct cachefiles_object *object;
|
struct cachefiles_object *object;
|
||||||
struct cachefiles_cache *cache;
|
|
||||||
|
|
||||||
object = container_of(_object, struct cachefiles_object, fscache);
|
object = container_of(_object, struct cachefiles_object, fscache);
|
||||||
cache = container_of(object->fscache.cache,
|
|
||||||
struct cachefiles_cache, cache);
|
|
||||||
|
|
||||||
_enter("%p,{%lu}", object, page->index);
|
_enter("%p,{%lu}", object, page->index);
|
||||||
|
|
||||||
|
@ -135,7 +135,8 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
|
|||||||
struct dentry *dentry = object->dentry;
|
struct dentry *dentry = object->dentry;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ASSERT(dentry);
|
if (!dentry)
|
||||||
|
return -ESTALE;
|
||||||
|
|
||||||
_enter("%p,#%d", object, auxdata->len);
|
_enter("%p,#%d", object, auxdata->len);
|
||||||
|
|
||||||
|
@ -730,6 +730,9 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
|
|||||||
|
|
||||||
if (awaken)
|
if (awaken)
|
||||||
wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
|
wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
|
||||||
|
if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags))
|
||||||
|
wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
|
||||||
|
|
||||||
|
|
||||||
/* Prevent a race with our last child, which has to signal EV_CLEARED
|
/* Prevent a race with our last child, which has to signal EV_CLEARED
|
||||||
* before dropping our spinlock.
|
* before dropping our spinlock.
|
||||||
|
@ -196,8 +196,7 @@ static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
|
|||||||
static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
|
static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
|
||||||
int n_pages)
|
int n_pages)
|
||||||
{
|
{
|
||||||
atomic_sub(n_pages, &op->n_pages);
|
if (atomic_sub_return_relaxed(n_pages, &op->n_pages) <= 0)
|
||||||
if (atomic_read(&op->n_pages) <= 0)
|
|
||||||
fscache_op_complete(&op->op, false);
|
fscache_op_complete(&op->op, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user