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-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()

+27 -7
+2 -1
fs/cachefiles/ondemand.c
··· 21 21 * anon_fd. 22 22 */ 23 23 xas_for_each(&xas, req, ULONG_MAX) { 24 - if (req->msg.opcode == CACHEFILES_OP_READ) { 24 + if (req->msg.object_id == object_id && 25 + req->msg.opcode == CACHEFILES_OP_READ) { 25 26 req->error = -EIO; 26 27 complete(&req->done); 27 28 xas_store(&xas, NULL);
+22 -4
fs/fscache/cookie.c
··· 372 372 return NULL; 373 373 } 374 374 375 + static inline bool fscache_cookie_is_dropped(struct fscache_cookie *cookie) 376 + { 377 + return READ_ONCE(cookie->state) == FSCACHE_COOKIE_STATE_DROPPED; 378 + } 379 + 375 380 static void fscache_wait_on_collision(struct fscache_cookie *candidate, 376 381 struct fscache_cookie *wait_for) 377 382 { 378 383 enum fscache_cookie_state *statep = &wait_for->state; 379 384 380 - wait_var_event_timeout(statep, READ_ONCE(*statep) == FSCACHE_COOKIE_STATE_DROPPED, 385 + wait_var_event_timeout(statep, fscache_cookie_is_dropped(wait_for), 381 386 20 * HZ); 382 - if (READ_ONCE(*statep) != FSCACHE_COOKIE_STATE_DROPPED) { 387 + if (!fscache_cookie_is_dropped(wait_for)) { 383 388 pr_notice("Potential collision c=%08x old: c=%08x", 384 389 candidate->debug_id, wait_for->debug_id); 385 - wait_var_event(statep, READ_ONCE(*statep) == FSCACHE_COOKIE_STATE_DROPPED); 390 + wait_var_event(statep, fscache_cookie_is_dropped(wait_for)); 386 391 } 387 392 } 388 393 ··· 522 517 } 523 518 524 519 fscache_see_cookie(cookie, fscache_cookie_see_active); 525 - fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE); 520 + spin_lock(&cookie->lock); 521 + if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags)) 522 + __fscache_set_cookie_state(cookie, 523 + FSCACHE_COOKIE_STATE_INVALIDATING); 524 + else 525 + __fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE); 526 + spin_unlock(&cookie->lock); 527 + wake_up_cookie_state(cookie); 526 528 trace = fscache_access_lookup_cookie_end; 527 529 528 530 out: ··· 763 751 cookie->volume->cache->ops->withdraw_cookie(cookie); 764 752 spin_lock(&cookie->lock); 765 753 } 754 + 755 + if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags)) 756 + fscache_end_cookie_access(cookie, fscache_access_invalidate_cookie_end); 766 757 767 758 switch (state) { 768 759 case FSCACHE_COOKIE_STATE_RELINQUISHING: ··· 1063 1048 return; 1064 1049 1065 1050 case FSCACHE_COOKIE_STATE_LOOKING_UP: 1051 + __fscache_begin_cookie_access(cookie, fscache_access_invalidate_cookie); 1052 + set_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags); 1053 + fallthrough; 1066 1054 case FSCACHE_COOKIE_STATE_CREATING: 1067 1055 spin_unlock(&cookie->lock); 1068 1056 _leave(" [look %x]", cookie->inval_counter);
+2 -2
fs/fscache/volume.c
··· 143 143 { 144 144 wait_var_event_timeout(&candidate->flags, 145 145 !fscache_is_acquire_pending(candidate), 20 * HZ); 146 - if (!fscache_is_acquire_pending(candidate)) { 146 + if (fscache_is_acquire_pending(candidate)) { 147 147 pr_notice("Potential volume collision new=%08x old=%08x", 148 148 candidate->debug_id, collidee_debug_id); 149 149 fscache_stat(&fscache_n_volumes_collision); ··· 182 182 hlist_bl_add_head(&candidate->hash_link, h); 183 183 hlist_bl_unlock(h); 184 184 185 - if (test_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &candidate->flags)) 185 + if (fscache_is_acquire_pending(candidate)) 186 186 fscache_wait_on_volume_collision(candidate, collidee_debug_id); 187 187 return true; 188 188
+1
include/linux/fscache.h
··· 130 130 #define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */ 131 131 #define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */ 132 132 #define FSCACHE_COOKIE_IS_HASHED 14 /* T if this cookie is hashed */ 133 + #define FSCACHE_COOKIE_DO_INVALIDATE 15 /* T if cookie needs invalidation */ 133 134 134 135 enum fscache_cookie_state state; 135 136 u8 advice; /* FSCACHE_ADV_* */