# --- SDE-COPYRIGHT-NOTE-BEGIN --- # This copyright note is auto-generated by ./scripts/Create-CopyPatch. # # Filename: package/.../fuse/fuse-2.8.6-upstream-bugfixes.patch # Copyright (C) 2011 The OpenSDE Project # # More information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # --- SDE-COPYRIGHT-NOTE-END --- From 9294657fb966c685cf6a99f4bbe73a91eb2b8f3c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sun, 23 Oct 2011 10:07:20 +0200 Subject: [PATCH 1/3] Reply with ENOMEM in case of failure to allocate request Reply to request with ENOMEM in case of failure to allocate request structure. Otherwise the task issuing the request will just freeze up until the filesystem daemon is killed. Reported by Stephan Kulow --- ChangeLog | 7 +++++++ lib/fuse_lowlevel.c | 11 +++++++++++ 2 files changed, 18 insertions(+), 0 deletions(-) diff --git fuse-2.8.6/ChangeLog fuse-2.8.6-bugfix/ChangeLog index 4be41e3..77a9b9e 100644 --- fuse-2.8.6/ChangeLog +++ fuse-2.8.6-bugfix/ChangeLog @@ -1,3 +1,10 @@ +2011-10-13 Miklos Szeredi + + * Reply to request with ENOMEM in case of failure to allocate + request structure. Otherwise the task issuing the request will + just freeze up until the filesystem daemon is killed. Reported by + Stephan Kulow + 2011-09-13 Miklos Szeredi * Released 2.8.6 diff --git fuse-2.8.6/lib/fuse_lowlevel.c fuse-2.8.6-bugfix/lib/fuse_lowlevel.c index c519bfb..c86a910 100644 --- fuse-2.8.6/lib/fuse_lowlevel.c +++ fuse-2.8.6-bugfix/lib/fuse_lowlevel.c @@ -1467,7 +1467,18 @@ static void fuse_ll_process(void *data, const char *buf, size_t len, req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req)); if (req == NULL) { + struct fuse_out_header out = { + .unique = in->unique, + .error = -ENOMEM, + .len = sizeof(struct fuse_out_header), + }; + struct iovec iov = { + .iov_base = &out, + .iov_len = sizeof(struct fuse_out_header), + }; + fprintf(stderr, "fuse: failed to allocate request\n"); + fuse_chan_send(ch, &iov, 1); return; } -- 1.7.2.3 From 655794f4a1515f1eb5b00b2fcc32d3f31f56839b Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 17 Nov 2011 12:36:38 +0100 Subject: [PATCH 2/3] Fix the following compile error fusermount.c: In function 'clone_newns': fusermount.c:315:2: warning: implicit declaration of function 'clone' [-Wimplicit-function-declaration] fusermount.c:315:44: error: 'CLONE_NEWNS' undeclared (first use in this function) fusermount.c:315:44: note: each undeclared identifier is reported only once for each function it appears in fusermount.c:317:1: warning: control reaches end of non-void function [-Wreturn-type] --- util/fusermount.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git fuse-2.8.6/util/fusermount.c fuse-2.8.6-bugfix/util/fusermount.c index 70c18b7..6855b7e 100644 --- fuse-2.8.6/util/fusermount.c +++ fuse-2.8.6-bugfix/util/fusermount.c @@ -7,6 +7,7 @@ */ /* This program does the mounting and unmounting of FUSE filesystems */ +#define _GNU_SOURCE /* for clone */ #include #include "mount_util.h" -- 1.7.2.3 From 3743f3fe52cfd52bb1d75bcb8324a00f153dc9f8 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 9 Dec 2011 16:07:55 +0100 Subject: [PATCH 3/3] Fix hang in wait_on_path() Ville Silventoinen reported that fs_racer in LTP triggered a hang in wait_on_path(). This bug was caused by try_get_path() not resetting "ticket" on permanent failure. --- ChangeLog | 4 ++++ lib/fuse.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git fuse-2.8.6/ChangeLog fuse-2.8.6-bugfix/ChangeLog index 77a9b9e..2c25c0b 100644 --- fuse-2.8.6/ChangeLog +++ fuse-2.8.6-bugfix/ChangeLog @@ -1,3 +1,7 @@ +2011-12-09 Miklos Szeredi + + * Fix hang in wait_on_path(). Reported by Ville Silventoinen + 2011-10-13 Miklos Szeredi * Reply to request with ENOMEM in case of failure to allocate diff --git fuse-2.8.6/lib/fuse.c fuse-2.8.6-bugfix/lib/fuse.c index 95cf50b..d511964 100644 --- fuse-2.8.6/lib/fuse.c +++ fuse-2.8.6-bugfix/lib/fuse.c @@ -495,6 +495,26 @@ static void unlock_path(struct fuse *f, fuse_ino_t nodeid, struct node *wnode, } } +static void release_tickets(struct fuse *f, fuse_ino_t nodeid, + struct node *wnode, int ticket) +{ + struct node *node; + + if (wnode) { + if (wnode->ticket != ticket) + return; + + wnode->ticket = 0; + } + + for (node = get_node(f, nodeid); + node->nodeid != FUSE_ROOT_ID; node = node->parent) { + if (node->ticket != ticket) + return; + node->ticket = 0; + } +} + static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name, char **path, struct node **wnodep, int ticket) { @@ -507,9 +527,10 @@ static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name, *path = NULL; + err = -ENOMEM; buf = malloc(bufsize); if (buf == NULL) - return -ENOMEM; + goto out_err; s = buf + bufsize - 1; *s = '\0'; @@ -577,6 +598,10 @@ static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name, out_free: free(buf); + out_err: + if (ticket && err != -EAGAIN) + release_tickets(f, nodeid, wnode, ticket); + return err; } @@ -711,9 +736,14 @@ static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1, err = try_get_path(f, nodeid1, name1, path1, wnode1, ticket); if (!err) { err = try_get_path(f, nodeid2, name2, path2, wnode2, ticket); - if (err) - unlock_path(f, nodeid1, wnode1 ? *wnode1 : NULL, NULL, - ticket); + if (err) { + struct node *wn1 = wnode1 ? *wnode1 : NULL; + + unlock_path(f, nodeid1, wn1, NULL, ticket); + free(path1); + if (ticket && err != -EAGAIN) + release_tickets(f, nodeid1, wn1, ticket); + } } return err; } -- 1.7.2.3