Skip to content

Commit 4b6b432

Browse files
committed
Merge tag 'fuse-update-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi: - Add mechanism for cleaning out unused, stale dentries; controlled via a module option (Luis Henriques) - Fix various bugs - Cleanups * tag 'fuse-update-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: Uninitialized variable in fuse_epoch_work() fuse: fix io-uring list corruption for terminated non-committed requests fuse: signal that a fuse inode should exhibit local fs behaviors fuse: Always flush the page cache before FOPEN_DIRECT_IO write fuse: Invalidate the page cache after FOPEN_DIRECT_IO write fuse: rename 'namelen' to 'namesize' fuse: use strscpy instead of strcpy fuse: refactor fuse_conn_put() to remove negative logic. fuse: new work queue to invalidate dentries from old epochs fuse: new work queue to periodically invalidate expired dentries dcache: export shrink_dentry_list() and add new helper d_dispose_if_unused() fuse: add WARN_ON and comment for RCU revalidate fuse: Fix whitespace for fuse_uring_args_to_ring() comment fuse: missing copy_finish in fuse-over-io-uring argument copies fuse: fix readahead reclaim deadlock
2 parents 7cd122b + 8da059f commit 4b6b432

10 files changed

Lines changed: 340 additions & 71 deletions

File tree

fs/dcache.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,15 @@ struct dentry *d_find_alias_rcu(struct inode *inode)
11041104
return de;
11051105
}
11061106

1107+
void d_dispose_if_unused(struct dentry *dentry, struct list_head *dispose)
1108+
{
1109+
spin_lock(&dentry->d_lock);
1110+
if (!dentry->d_lockref.count)
1111+
to_shrink_list(dentry, dispose);
1112+
spin_unlock(&dentry->d_lock);
1113+
}
1114+
EXPORT_SYMBOL(d_dispose_if_unused);
1115+
11071116
/*
11081117
* Try to kill dentries associated with this inode.
11091118
* WARNING: you must own a reference to inode.
@@ -1114,12 +1123,8 @@ void d_prune_aliases(struct inode *inode)
11141123
struct dentry *dentry;
11151124

11161125
spin_lock(&inode->i_lock);
1117-
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
1118-
spin_lock(&dentry->d_lock);
1119-
if (!dentry->d_lockref.count)
1120-
to_shrink_list(dentry, &dispose);
1121-
spin_unlock(&dentry->d_lock);
1122-
}
1126+
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias)
1127+
d_dispose_if_unused(dentry, &dispose);
11231128
spin_unlock(&inode->i_lock);
11241129
shrink_dentry_list(&dispose);
11251130
}
@@ -1159,6 +1164,7 @@ void shrink_dentry_list(struct list_head *list)
11591164
shrink_kill(dentry);
11601165
}
11611166
}
1167+
EXPORT_SYMBOL(shrink_dentry_list);
11621168

11631169
static enum lru_status dentry_lru_isolate(struct list_head *item,
11641170
struct list_lru_one *lru, void *arg)

fs/fuse/dev.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ void fuse_copy_init(struct fuse_copy_state *cs, bool write,
846846
}
847847

848848
/* Unmap and put previous page of userspace buffer */
849-
static void fuse_copy_finish(struct fuse_copy_state *cs)
849+
void fuse_copy_finish(struct fuse_copy_state *cs)
850850
{
851851
if (cs->currbuf) {
852852
struct pipe_buffer *buf = cs->currbuf;
@@ -2041,13 +2041,14 @@ static int fuse_notify_resend(struct fuse_conn *fc)
20412041

20422042
/*
20432043
* Increments the fuse connection epoch. This will result of dentries from
2044-
* previous epochs to be invalidated.
2045-
*
2046-
* XXX optimization: add call to shrink_dcache_sb()?
2044+
* previous epochs to be invalidated. Additionally, if inval_wq is set, a work
2045+
* queue is scheduled to trigger the invalidation.
20472046
*/
20482047
static int fuse_notify_inc_epoch(struct fuse_conn *fc)
20492048
{
20502049
atomic_inc(&fc->epoch);
2050+
if (inval_wq)
2051+
schedule_work(&fc->epoch_work);
20512052

20522053
return 0;
20532054
}

fs/fuse/dev_uring.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static void fuse_uring_req_end(struct fuse_ring_ent *ent, struct fuse_req *req,
8686
lockdep_assert_not_held(&queue->lock);
8787
spin_lock(&queue->lock);
8888
ent->fuse_req = NULL;
89+
list_del_init(&req->list);
8990
if (test_bit(FR_BACKGROUND, &req->flags)) {
9091
queue->active_background--;
9192
spin_lock(&fc->bg_lock);
@@ -598,12 +599,14 @@ static int fuse_uring_copy_from_ring(struct fuse_ring *ring,
598599
cs.is_uring = true;
599600
cs.req = req;
600601

601-
return fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
602+
err = fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
603+
fuse_copy_finish(&cs);
604+
return err;
602605
}
603606

604-
/*
605-
* Copy data from the req to the ring buffer
606-
*/
607+
/*
608+
* Copy data from the req to the ring buffer
609+
*/
607610
static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req,
608611
struct fuse_ring_ent *ent)
609612
{
@@ -649,6 +652,7 @@ static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req,
649652
/* copy the payload */
650653
err = fuse_copy_args(&cs, num_args, args->in_pages,
651654
(struct fuse_arg *)in_args, 0);
655+
fuse_copy_finish(&cs);
652656
if (err) {
653657
pr_info_ratelimited("%s fuse_copy_args failed\n", __func__);
654658
return err;

0 commit comments

Comments
 (0)