From: Miklos S. <mi...@sz...> - 2004-09-14 07:20:10
|
> After thinking about it quite a bit, it's a LOOKUP that's being interrupted > when the FORGET is issued on an inode required to completely the LOOKUP. > > Why not have the LOOKUP code in the library detect the situation and have > the ability to abort without an error? Yes, that could be done. However if you look at the backtraces of this problem it was not only in LOOKUP. > In any case, I applied your patch, and that abort in get_path_name() has > discontinued. > > Now the FUSE mounts run much longer before it core dumps in do_getdir(). > > I'll post the stack dumps and log files shortly. OK, I had a look at the logs, and it's probably caused by tmpfile() returning NULL in do_getdir(). The patch at the end should fix this. I think you should get a medal "Master Tester and Bugfinder" for your work :) Thanks, Miklos Index: lib/fuse.c =================================================================== RCS file: /cvsroot/avf/fuse/lib/fuse.c,v retrieving revision 1.43.2.5 diff -u -r1.43.2.5 fuse.c --- lib/fuse.c 11 Sep 2004 07:37:45 -0000 1.43.2.5 +++ lib/fuse.c 14 Sep 2004 07:09:59 -0000 @@ -589,20 +589,27 @@ dh.fuse = f; dh.fp = tmpfile(); dh.dir = in->ino; - res = -ENOENT; - path = get_path(f, in->ino); - if(path != NULL) { - res = -ENOSYS; - if(f->op.getdir) - res = f->op.getdir(path, &dh, (fuse_dirfil_t) fill_dir); - free(path); + res = -EIO; + + if (dh.fp == NULL) + perror("fuse: failed to create temporary file"); + else { + res = -ENOENT; + path = get_path(f, in->ino); + if(path != NULL) { + res = -ENOSYS; + if(f->op.getdir) + res = f->op.getdir(path, &dh, (fuse_dirfil_t) fill_dir); + free(path); + } + fflush(dh.fp); } - fflush(dh.fp); - memset(&arg, 0, sizeof(struct fuse_getdir_out)); - arg.fd = fileno(dh.fp); + if (res == 0) + arg.fd = fileno(dh.fp); send_reply(f, in, res, &arg, sizeof(arg)); - fclose(dh.fp); + if (dh.fp != NULL) + fclose(dh.fp); } static void do_mknod(struct fuse *f, struct fuse_in_header *in, |