<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:DengXian;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@DengXian";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-ligatures:none;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-SG" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Use correct lock to protect the kill_requests operation on all request<o:p></o:p></p>
<p class="MsoNormal">queues. Test of the FUSE_S_FAIL_IMMEDIATELY bit needs to be done with<o:p></o:p></p>
<p class="MsoNormal">corresponding lock to prevent new requests being added to a queue after<o:p></o:p></p>
<p class="MsoNormal">it has been killed.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Adjust the order of queues that kill_request operation is performed as<o:p></o:p></p>
<p class="MsoNormal">following:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">bg_queue -> [ kio queues ] -> input queue -> process queue.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This follows the order that a fuse request could be moved around among<o:p></o:p></p>
<p class="MsoNormal">queues. The most import part is that the bg_queue needs to be killed<o:p></o:p></p>
<p class="MsoNormal">first because otherwise requests from it could be flushed to input queue<o:p></o:p></p>
<p class="MsoNormal">after the input queue has been killed.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Signed-off-by: Liu Kui <Kui.Liu@acronis.com><o:p></o:p></p>
<p class="MsoNormal">---<o:p></o:p></p>
<p class="MsoNormal">fs/fuse/inode.c | 33 +++++++++++++++++++++++----------<o:p></o:p></p>
<p class="MsoNormal">1 file changed, 23 insertions(+), 10 deletions(-)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c<o:p></o:p></p>
<p class="MsoNormal">index 91b5591bbf49..c3777008b318 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/fs/fuse/inode.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/fs/fuse/inode.c<o:p></o:p></p>
<p class="MsoNormal">@@ -512,15 +512,14 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> fi = get_fuse_inode(inode);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">+ /* Mark that invalidate files is in progress */<o:p></o:p></p>
<p class="MsoNormal"> spin_lock(&fi->lock);<o:p></o:p></p>
<p class="MsoNormal">+ set_bit(FUSE_I_INVAL_FILES, &fi->state);<o:p></o:p></p>
<p class="MsoNormal"> list_for_each_entry(ff, &fi->rw_files, rw_entry) {<o:p></o:p></p>
<p class="MsoNormal"> set_bit(FUSE_S_FAIL_IMMEDIATELY, &ff->ff_state);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> spin_unlock(&fi->lock);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- /* Mark that invalidate files is in progress */<o:p></o:p></p>
<p class="MsoNormal">- set_bit(FUSE_I_INVAL_FILES, &fi->state);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal"> /* let them see FUSE_S_FAIL_IMMEDIATELY */<o:p></o:p></p>
<p class="MsoNormal"> wake_up_all(&fc->blocked_waitq);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">@@ -528,24 +527,38 @@ int fuse_invalidate_files(struct fuse_conn *fc, u64 nodeid)<o:p></o:p></p>
<p class="MsoNormal"> if (!err || err == -EIO) { /* AS_EIO might trigger -EIO */<o:p></o:p></p>
<p class="MsoNormal"> struct fuse_dev *fud;<o:p></o:p></p>
<p class="MsoNormal"> spin_lock(&fc->lock);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ /*<o:p></o:p></p>
<p class="MsoNormal">+ * Clean bg_queue first to prevent requests being flushed<o:p></o:p></p>
<p class="MsoNormal">+ * to an input queue after it has been cleaned .<o:p></o:p></p>
<p class="MsoNormal">+ */<o:p></o:p></p>
<p class="MsoNormal">+ spin_lock(&fc->bg_lock);<o:p></o:p></p>
<p class="MsoNormal">+ fuse_kill_requests(fc, inode, &fc->bg_queue);<o:p></o:p></p>
<p class="MsoNormal">+ spin_unlock(&fc->bg_lock);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (fc->kio.op && fc->kio.op->kill_requests)<o:p></o:p></p>
<p class="MsoNormal">+ fc->kio.op->kill_requests(fc, inode);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ spin_lock(&fc->main_iq.lock);<o:p></o:p></p>
<p class="MsoNormal">+ fuse_kill_requests(fc, inode, &fc->main_iq.pending);<o:p></o:p></p>
<p class="MsoNormal">+ spin_unlock(&fc->main_iq.lock);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"> list_for_each_entry(fud, &fc->devices, entry) {<o:p></o:p></p>
<p class="MsoNormal"> struct fuse_pqueue *fpq = &fud->pq;<o:p></o:p></p>
<p class="MsoNormal"> struct fuse_iqueue *fiq = fud->fiq;<o:p></o:p></p>
<p class="MsoNormal"> int i;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ spin_lock(&fiq->lock);<o:p></o:p></p>
<p class="MsoNormal">+ fuse_kill_requests(fc, inode, &fiq->pending);<o:p></o:p></p>
<p class="MsoNormal">+ spin_unlock(&fiq->lock);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"> spin_lock(&fpq->lock);<o:p></o:p></p>
<p class="MsoNormal"> for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)<o:p></o:p></p>
<p class="MsoNormal"> fuse_kill_requests(fc, inode, &fpq->processing[i]);<o:p></o:p></p>
<p class="MsoNormal"> fuse_kill_requests(fc, inode, &fpq->io);<o:p></o:p></p>
<p class="MsoNormal"> spin_unlock(&fpq->lock);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- spin_lock(&fiq->waitq.lock);<o:p></o:p></p>
<p class="MsoNormal">- fuse_kill_requests(fc, inode, &fiq->pending);<o:p></o:p></p>
<p class="MsoNormal">- spin_unlock(&fiq->waitq.lock);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal">- fuse_kill_requests(fc, inode, &fc->main_iq.pending);<o:p></o:p></p>
<p class="MsoNormal">- fuse_kill_requests(fc, inode, &fc->bg_queue);<o:p></o:p></p>
<p class="MsoNormal">- if (fc->kio.op && fc->kio.op->kill_requests)<o:p></o:p></p>
<p class="MsoNormal">- fc->kio.op->kill_requests(fc, inode);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> wake_up(&fi->page_waitq); /* readpage[s] can wait on fuse wb */<o:p></o:p></p>
<p class="MsoNormal"> spin_unlock(&fc->lock);<o:p></o:p></p>
<p class="MsoNormal">--<o:p></o:p></p>
<p class="MsoNormal">2.32.0 (Apple Git-132)<o:p></o:p></p>
</div>
</body>
</html>