Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d4262f9

Browse files
Darrick J. Wonghbirth
authored andcommitted
fuse: flush pending fuse events before aborting the connection
generic/488 fails with fuse2fs in the following fashion: generic/488 _check_generic_filesystem: filesystem on /dev/sdf is inconsistent (see /var/tmp/fstests/generic/488.full for details) This test opens a large number of files, unlinks them (which really just renames them to fuse hidden files), closes the program, unmounts the filesystem, and runs fsck to check that there aren't any inconsistencies in the filesystem. Unfortunately, the 488.full file shows that there are a lot of hidden files left over in the filesystem, with incorrect link counts. Tracing fuse_request_* shows that there are a large number of FUSE_RELEASE commands that are queued up on behalf of the unlinked files at the time that fuse_conn_destroy calls fuse_abort_conn. Had the connection not aborted, the fuse server would have responded to the RELEASE commands by removing the hidden files; instead they stick around. Create a function to push all the background requests to the queue and then wait for the number of pending events to hit zero, and call this before fuse_abort_conn. That way, all the pending events are processed by the fuse server and we don't end up with a corrupt filesystem. Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 391f71c commit d4262f9

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

fs/fuse/dev.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/swap.h>
2424
#include <linux/splice.h>
2525
#include <linux/sched.h>
26+
#include <linux/nmi.h>
2627

2728
#define CREATE_TRACE_POINTS
2829
#include "fuse_trace.h"
@@ -2147,6 +2148,43 @@ static void end_polls(struct fuse_conn *fc)
21472148
}
21482149
}
21492150

2151+
/*
2152+
* Flush all pending requests and wait for them. Only call this function when
2153+
* it is no longer possible for other threads to add requests.
2154+
*/
2155+
void fuse_flush_requests(struct fuse_conn *fc, unsigned long timeout)
2156+
{
2157+
unsigned long deadline;
2158+
2159+
spin_lock(&fc->lock);
2160+
if (!fc->connected) {
2161+
spin_unlock(&fc->lock);
2162+
return;
2163+
}
2164+
2165+
/* Push all the background requests to the queue. */
2166+
spin_lock(&fc->bg_lock);
2167+
fc->blocked = 0;
2168+
fc->max_background = UINT_MAX;
2169+
flush_bg_queue(fc);
2170+
spin_unlock(&fc->bg_lock);
2171+
spin_unlock(&fc->lock);
2172+
2173+
/*
2174+
* Wait 30s for all the events to complete or abort. Touch the
2175+
* watchdog once per second so that we don't trip the hangcheck timer
2176+
* while waiting for the fuse server.
2177+
*/
2178+
deadline = jiffies + timeout;
2179+
smp_mb();
2180+
while (fc->connected &&
2181+
(!timeout || time_before(jiffies, deadline)) &&
2182+
wait_event_timeout(fc->blocked_waitq,
2183+
!fc->connected || atomic_read(&fc->num_waiting) == 0,
2184+
HZ) == 0)
2185+
touch_softlockup_watchdog();
2186+
}
2187+
21502188
/*
21512189
* Abort all requests.
21522190
*

fs/fuse/fuse_i.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,12 @@ void fuse_request_end(struct fuse_req *req);
12031203
void fuse_abort_conn(struct fuse_conn *fc);
12041204
void fuse_wait_aborted(struct fuse_conn *fc);
12051205

1206+
/**
1207+
* Flush all pending requests and wait for them. Takes an optional timeout
1208+
* in jiffies.
1209+
*/
1210+
void fuse_flush_requests(struct fuse_conn *fc, unsigned long timeout);
1211+
12061212
/**
12071213
* Invalidate inode attributes
12081214
*/

fs/fuse/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,7 @@ void fuse_conn_destroy(struct fuse_mount *fm)
20232023
{
20242024
struct fuse_conn *fc = fm->fc;
20252025

2026+
fuse_flush_requests(fc, 30 * HZ);
20262027
if (fc->destroy)
20272028
fuse_send_destroy(fm);
20282029

0 commit comments

Comments
 (0)