fuse: fix leaked aux requests
authorMiklos Szeredi <mszeredi@redhat.com>
Thu, 24 Jan 2019 09:40:15 +0000 (10:40 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 13 Feb 2019 12:15:12 +0000 (13:15 +0100)
Auxiliary requests chained on req->misc.write.next may be leaked on
truncate.  Free these as well if the parent request was truncated off.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c

index b0c32a7..ee59599 100644 (file)
@@ -1494,6 +1494,7 @@ static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req,
 __releases(fc->lock)
 __acquires(fc->lock)
 {
+       struct fuse_req *aux, *next;
        struct fuse_inode *fi = get_fuse_inode(req->inode);
        struct fuse_write_in *inarg = &req->misc.write.in;
        __u64 data_size = req->num_pages * PAGE_SIZE;
@@ -1520,6 +1521,15 @@ __acquires(fc->lock)
  out_free:
        fuse_writepage_finish(fc, req);
        spin_unlock(&fc->lock);
+
+       /* After fuse_writepage_finish() aux request list is private */
+       for (aux = req->misc.write.next; aux; aux = next) {
+               next = aux->misc.write.next;
+               aux->misc.write.next = NULL;
+               fuse_writepage_free(fc, aux);
+               fuse_put_request(fc, aux);
+       }
+
        fuse_writepage_free(fc, req);
        fuse_put_request(fc, req);
        spin_lock(&fc->lock);