Skip to content

Commit b5329d5

Browse files
committed
Merge tag 'vfs-6.14-final.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner: "A final set of fixes for this cycle: VFS: - Ensure that the stable offset api doesn't return duplicate directory entries when userspace has to perform the getdents call multiple times on large directories afs: - Prevent invalid pointer dereference during get_link RCU pathwalk fuse: - Fix deadlock caused by uninitialized rings when using io_uring with fuse - Handle race condition when using io_uring with fuse to prevent NULL dereference libnetfs: - Ensure that invalidate_cache is only called if implemented - Fix collection of results during pause when collection is offloaded - Ensure rolling_buffer_load_from_ra() doesn't clear mark bits - Make netfs_unbuffered_read() return ssize_t rather than int" * tag 'vfs-6.14-final.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: libfs: Fix duplicate directory entry in offset_dir_lookup fuse: fix possible deadlock if rings are never initialized netfs: Fix netfs_unbuffered_read() to return ssize_t rather than int netfs: Fix rolling_buffer_load_from_ra() to not clear mark bits netfs: Call `invalidate_cache` only if implemented netfs: Fix collection of results during pause when collection offloaded fuse: fix uring race condition for null dereference of fc afs: Fix afs_atcell_get_link() to check if ws_cell is unset first
2 parents f45f8f0 + f70681e commit b5329d5

File tree

8 files changed

+22
-23
lines changed

8 files changed

+22
-23
lines changed

fs/afs/dynroot.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,9 @@ static const char *afs_atcell_get_link(struct dentry *dentry, struct inode *inod
314314
const char *name;
315315
bool dotted = vnode->fid.vnode == 3;
316316

317+
if (!rcu_access_pointer(net->ws_cell))
318+
return ERR_PTR(-ENOENT);
319+
317320
if (!dentry) {
318321
/* We're in RCU-pathwalk. */
319322
cell = rcu_dereference(net->ws_cell);
@@ -325,9 +328,6 @@ static const char *afs_atcell_get_link(struct dentry *dentry, struct inode *inod
325328
return name;
326329
}
327330

328-
if (!rcu_access_pointer(net->ws_cell))
329-
return ERR_PTR(-ENOENT);
330-
331331
down_read(&net->cells_lock);
332332

333333
cell = rcu_dereference_protected(net->ws_cell, lockdep_is_held(&net->cells_lock));

fs/fuse/dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void fuse_set_initialized(struct fuse_conn *fc)
7777
static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
7878
{
7979
return !fc->initialized || (for_background && fc->blocked) ||
80-
(fc->io_uring && !fuse_uring_ready(fc));
80+
(fc->io_uring && fc->connected && !fuse_uring_ready(fc));
8181
}
8282

8383
static void fuse_drop_waiting(struct fuse_conn *fc)

fs/fuse/dev_uring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,11 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
208208

209209
init_waitqueue_head(&ring->stop_waitq);
210210

211-
fc->ring = ring;
212211
ring->nr_queues = nr_queues;
213212
ring->fc = fc;
214213
ring->max_payload_sz = max_payload_size;
215214
atomic_set(&ring->queue_refs, 0);
215+
smp_store_release(&fc->ring, ring);
216216

217217
spin_unlock(&fc->lock);
218218
return ring;
@@ -1041,7 +1041,7 @@ static int fuse_uring_register(struct io_uring_cmd *cmd,
10411041
unsigned int issue_flags, struct fuse_conn *fc)
10421042
{
10431043
const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe_cmd(cmd->sqe);
1044-
struct fuse_ring *ring = fc->ring;
1044+
struct fuse_ring *ring = smp_load_acquire(&fc->ring);
10451045
struct fuse_ring_queue *queue;
10461046
struct fuse_ring_ent *ent;
10471047
int err;

fs/libfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ offset_dir_lookup(struct dentry *parent, loff_t offset)
496496
found = find_positive_dentry(parent, NULL, false);
497497
else {
498498
rcu_read_lock();
499-
child = mas_find(&mas, DIR_OFFSET_MAX);
499+
child = mas_find_rev(&mas, DIR_OFFSET_MIN);
500500
found = find_positive_dentry(parent, child, false);
501501
rcu_read_unlock();
502502
}

fs/netfs/direct_read.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ static int netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
125125
* Perform a read to an application buffer, bypassing the pagecache and the
126126
* local disk cache.
127127
*/
128-
static int netfs_unbuffered_read(struct netfs_io_request *rreq, bool sync)
128+
static ssize_t netfs_unbuffered_read(struct netfs_io_request *rreq, bool sync)
129129
{
130-
int ret;
130+
ssize_t ret;
131131

132132
_enter("R=%x %llx-%llx",
133133
rreq->debug_id, rreq->start, rreq->start + rreq->len - 1);
@@ -155,7 +155,7 @@ static int netfs_unbuffered_read(struct netfs_io_request *rreq, bool sync)
155155
else
156156
ret = -EIOCBQUEUED;
157157
out:
158-
_leave(" = %d", ret);
158+
_leave(" = %zd", ret);
159159
return ret;
160160
}
161161

fs/netfs/read_collect.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -682,14 +682,16 @@ void netfs_wait_for_pause(struct netfs_io_request *rreq)
682682
trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
683683
prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
684684

685-
subreq = list_first_entry_or_null(&stream->subrequests,
686-
struct netfs_io_subrequest, rreq_link);
687-
if (subreq &&
688-
(!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
689-
test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
690-
__set_current_state(TASK_RUNNING);
691-
netfs_read_collection(rreq);
692-
continue;
685+
if (!test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags)) {
686+
subreq = list_first_entry_or_null(&stream->subrequests,
687+
struct netfs_io_subrequest, rreq_link);
688+
if (subreq &&
689+
(!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
690+
test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
691+
__set_current_state(TASK_RUNNING);
692+
netfs_read_collection(rreq);
693+
continue;
694+
}
693695
}
694696

695697
if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags) ||

fs/netfs/rolling_buffer.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@ ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,
146146

147147
/* Store the counter after setting the slot. */
148148
smp_store_release(&roll->next_head_slot, to);
149-
150-
for (; ix < folioq_nr_slots(fq); ix++)
151-
folioq_clear(fq, ix);
152-
153149
return size;
154150
}
155151

fs/netfs/write_collect.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ void netfs_write_collection_worker(struct work_struct *work)
400400
trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
401401

402402
if (wreq->io_streams[1].active &&
403-
wreq->io_streams[1].failed) {
403+
wreq->io_streams[1].failed &&
404+
ictx->ops->invalidate_cache) {
404405
/* Cache write failure doesn't prevent writeback completion
405406
* unless we're in disconnected mode.
406407
*/

0 commit comments

Comments
 (0)