Reply with ENOMEM in case of failure to allocate request
authorMiklos Szeredi <mszeredi@suse.cz>
Sun, 23 Oct 2011 08:07:20 +0000 (10:07 +0200)
committerMiklos Szeredi <mszeredi@suse.cz>
Sun, 23 Oct 2011 08:07:20 +0000 (10:07 +0200)
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
lib/fuse_lowlevel.c

index eedab2f1d62845ace76963e50f63f70b26746950..955813baf0e47e1105a8008b628f0ad3b438bb23 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-10-13  Miklos Szeredi <miklos@szeredi.hu>
+
+       * 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-23  Miklos Szeredi <miklos@szeredi.hu>
 
        * Replace daemon() function with fork().  Patch by Anatol Pomozov
index b1015236c15f0a599da7e9e84973d880a20777fd..e778faa723bfa66f78bd2635e6d766525a7c8fc0 100644 (file)
@@ -2273,9 +2273,28 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
                in = buf->mem;
        }
 
+       if (f->debug) {
+               fprintf(stderr,
+                       "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu, pid: %u\n",
+                       (unsigned long long) in->unique,
+                       opname((enum fuse_opcode) in->opcode), in->opcode,
+                       (unsigned long) in->nodeid, buf->size, in->pid);
+       }
+
        req = fuse_ll_alloc_req(f);
-       if (req == NULL)
+       if (req == NULL) {
+               struct fuse_out_header out = {
+                       .unique = in->unique,
+                       .error = -ENOMEM,
+               };
+               struct iovec iov = {
+                       .iov_base = &out,
+                       .iov_len = sizeof(struct fuse_out_header),
+               };
+
+               fuse_send_msg(f, ch, &iov, 1);
                goto clear_pipe;
+       }
 
        req->unique = in->unique;
        req->ctx.uid = in->uid;
@@ -2283,14 +2302,6 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
        req->ctx.pid = in->pid;
        req->ch = ch;
 
-       if (f->debug)
-               fprintf(stderr,
-                       "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu, pid: %u\n",
-                       (unsigned long long) in->unique,
-                       opname((enum fuse_opcode) in->opcode), in->opcode,
-                       (unsigned long) in->nodeid, buf->size, in->pid);
-
-
        err = EIO;
        if (!f->got_init) {
                enum fuse_opcode expected;