mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
smb: client: split cached_fid bitfields to avoid shared-byte RMW races
is_open, has_lease and on_list are stored in the same bitfield byte in
struct cached_fid but are updated in different code paths that may run
concurrently. Bitfield assignments generate byte read–modify–write
operations (e.g. `orb $mask, addr` on x86_64), so updating one flag can
restore stale values of the others.
A possible interleaving is:
CPU1: load old byte (has_lease=1, on_list=1)
CPU2: clear both flags (store 0)
CPU1: RMW store (old | IS_OPEN) -> reintroduces cleared bits
To avoid this class of races, convert these flags to separate bool
fields.
Cc: stable@vger.kernel.org
Fixes: ebe98f1447 ("cifs: enable caching of directories for which a lease is held")
Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
96c4af4185
commit
ec306600d5
|
|
@ -36,10 +36,10 @@ struct cached_fid {
|
|||
struct list_head entry;
|
||||
struct cached_fids *cfids;
|
||||
const char *path;
|
||||
bool has_lease:1;
|
||||
bool is_open:1;
|
||||
bool on_list:1;
|
||||
bool file_all_info_is_valid:1;
|
||||
bool has_lease;
|
||||
bool is_open;
|
||||
bool on_list;
|
||||
bool file_all_info_is_valid;
|
||||
unsigned long time; /* jiffies of when lease was taken */
|
||||
unsigned long last_access_time; /* jiffies of when last accessed */
|
||||
struct kref refcount;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user