forked from Minki/linux
fscache fixes
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEqG5UsNXhtOCrfGQP+7dXa6fLC2sFAmLInYwACgkQ+7dXa6fL C2tbmxAAlBkMvoIeyOlkMeAB3l1aK5CAYmgddjWOxY6UHNIGgXqWlGJCoxYngTmy j+5Uz1mMNh7TamSJpCTXUBbiLWxzoHI34oie+NT9VUXTTVw0/GQ//jQPlvE+HeJG Hmi0HR4lby1O6X9r63obzvDctJPhsVLdgJFtZ3UidwzgY2zYnScxwyCuwSfLUVnF YJACZWPFj1oWxOiS2bQZgnvCJpfJ6J0I5asmO0lI1tQDS0o4RoiRvDPTx8Z6K3KO 8CSm5tvu+vYrbZ5aNCN9f0MZfNl+YZiNQyxEiIP9Phu9iZFRe9UgXvDrE9346uQM /Vxa5nvyj+D0Hg+l1jBFXvwoKxLHTZ/BaK74h2/QzRKgxKrHTAyYOgxqt7U/YCsa S489eHOGNwbqIKACljBcMX9YZeCdeixt4aK/VIRr+d1f2Ui30Z05ExuYOfGn4wBq VcSsBgAALwcyqrpi61URYvKduHTa2D8ATKNKXNM/i1Wv6KQDeom5jyKj3mE7UNsI WAgWE2xy74kjYs1Lc0izsfieyZrt1MqZiyYFjS86Cnt0wVmdAQYrQ3wciN5D9IJN MiUYuienGRf1MNM2tmFK+N7e+pa/waKcl15/d3Zal94rlATpR2bFOI1zJ9qJ8rpi k8B/eydAZx+oUthxWvfIdLwIREJzA49jzBHgfAy/CMjqPCj7gZ8= =FDkz -----END PGP SIGNATURE----- Merge tag 'fscache-fixes-20220708' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs Pull fscache fixes from David Howells: - Fix a check in fscache_wait_on_volume_collision() in which the polarity is reversed. It should complain if a volume is still marked acquisition-pending after 20s, but instead complains if the mark has been cleared (ie. the condition has cleared). Also switch an open-coded test of the ACQUIRE_PENDING volume flag to use the helper function for consistency. - Not a fix per se, but neaten the code by using a helper to check for the DROPPED state. - Fix cachefiles's support for erofs to only flush requests associated with a released control file, not all requests. - Fix a race between one process invalidating an object in the cache and another process trying to look it up. * tag 'fscache-fixes-20220708' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: fscache: Fix invalidation/lookup race cachefiles: narrow the scope of flushed requests when releasing fd fscache: Introduce fscache_cookie_is_dropped() fscache: Fix if condition in fscache_wait_on_volume_collision()
This commit is contained in:
commit
e5524c2a1f
@ -21,7 +21,8 @@ static int cachefiles_ondemand_fd_release(struct inode *inode,
|
||||
* anon_fd.
|
||||
*/
|
||||
xas_for_each(&xas, req, ULONG_MAX) {
|
||||
if (req->msg.opcode == CACHEFILES_OP_READ) {
|
||||
if (req->msg.object_id == object_id &&
|
||||
req->msg.opcode == CACHEFILES_OP_READ) {
|
||||
req->error = -EIO;
|
||||
complete(&req->done);
|
||||
xas_store(&xas, NULL);
|
||||
|
@ -372,17 +372,22 @@ nomem:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool fscache_cookie_is_dropped(struct fscache_cookie *cookie)
|
||||
{
|
||||
return READ_ONCE(cookie->state) == FSCACHE_COOKIE_STATE_DROPPED;
|
||||
}
|
||||
|
||||
static void fscache_wait_on_collision(struct fscache_cookie *candidate,
|
||||
struct fscache_cookie *wait_for)
|
||||
{
|
||||
enum fscache_cookie_state *statep = &wait_for->state;
|
||||
|
||||
wait_var_event_timeout(statep, READ_ONCE(*statep) == FSCACHE_COOKIE_STATE_DROPPED,
|
||||
wait_var_event_timeout(statep, fscache_cookie_is_dropped(wait_for),
|
||||
20 * HZ);
|
||||
if (READ_ONCE(*statep) != FSCACHE_COOKIE_STATE_DROPPED) {
|
||||
if (!fscache_cookie_is_dropped(wait_for)) {
|
||||
pr_notice("Potential collision c=%08x old: c=%08x",
|
||||
candidate->debug_id, wait_for->debug_id);
|
||||
wait_var_event(statep, READ_ONCE(*statep) == FSCACHE_COOKIE_STATE_DROPPED);
|
||||
wait_var_event(statep, fscache_cookie_is_dropped(wait_for));
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,7 +522,14 @@ static void fscache_perform_lookup(struct fscache_cookie *cookie)
|
||||
}
|
||||
|
||||
fscache_see_cookie(cookie, fscache_cookie_see_active);
|
||||
fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
|
||||
spin_lock(&cookie->lock);
|
||||
if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
|
||||
__fscache_set_cookie_state(cookie,
|
||||
FSCACHE_COOKIE_STATE_INVALIDATING);
|
||||
else
|
||||
__fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
|
||||
spin_unlock(&cookie->lock);
|
||||
wake_up_cookie_state(cookie);
|
||||
trace = fscache_access_lookup_cookie_end;
|
||||
|
||||
out:
|
||||
@ -752,6 +764,9 @@ again_locked:
|
||||
spin_lock(&cookie->lock);
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
|
||||
fscache_end_cookie_access(cookie, fscache_access_invalidate_cookie_end);
|
||||
|
||||
switch (state) {
|
||||
case FSCACHE_COOKIE_STATE_RELINQUISHING:
|
||||
fscache_see_cookie(cookie, fscache_cookie_see_relinquish);
|
||||
@ -1048,6 +1063,9 @@ void __fscache_invalidate(struct fscache_cookie *cookie,
|
||||
return;
|
||||
|
||||
case FSCACHE_COOKIE_STATE_LOOKING_UP:
|
||||
__fscache_begin_cookie_access(cookie, fscache_access_invalidate_cookie);
|
||||
set_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags);
|
||||
fallthrough;
|
||||
case FSCACHE_COOKIE_STATE_CREATING:
|
||||
spin_unlock(&cookie->lock);
|
||||
_leave(" [look %x]", cookie->inval_counter);
|
||||
|
@ -143,7 +143,7 @@ static void fscache_wait_on_volume_collision(struct fscache_volume *candidate,
|
||||
{
|
||||
wait_var_event_timeout(&candidate->flags,
|
||||
!fscache_is_acquire_pending(candidate), 20 * HZ);
|
||||
if (!fscache_is_acquire_pending(candidate)) {
|
||||
if (fscache_is_acquire_pending(candidate)) {
|
||||
pr_notice("Potential volume collision new=%08x old=%08x",
|
||||
candidate->debug_id, collidee_debug_id);
|
||||
fscache_stat(&fscache_n_volumes_collision);
|
||||
@ -182,7 +182,7 @@ static bool fscache_hash_volume(struct fscache_volume *candidate)
|
||||
hlist_bl_add_head(&candidate->hash_link, h);
|
||||
hlist_bl_unlock(h);
|
||||
|
||||
if (test_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &candidate->flags))
|
||||
if (fscache_is_acquire_pending(candidate))
|
||||
fscache_wait_on_volume_collision(candidate, collidee_debug_id);
|
||||
return true;
|
||||
|
||||
|
@ -130,6 +130,7 @@ struct fscache_cookie {
|
||||
#define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */
|
||||
#define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */
|
||||
#define FSCACHE_COOKIE_IS_HASHED 14 /* T if this cookie is hashed */
|
||||
#define FSCACHE_COOKIE_DO_INVALIDATE 15 /* T if cookie needs invalidation */
|
||||
|
||||
enum fscache_cookie_state state;
|
||||
u8 advice; /* FSCACHE_ADV_* */
|
||||
|
Loading…
Reference in New Issue
Block a user