* Acquire inode->i_sem before open and release methods to prevent
concurrent rename or unlink operations.
+ * Make __fuse_read_cmd() read only one command. This allows
+ multiplexing the fuse file descriptor with other event sources
+ using select() or poll() (patch by Jeff Harris)
+
+ * Export 'exited' flag with __fuse_exited() (patch by Jeff Harris)
+
2004-06-27 Miklos Szeredi <mszeredi@inf.bme.hu>
* Fix file offset wrap around at 4G when doing large reads
free_cmd(cmd);
}
+int __fuse_exited(struct fuse* f)
+{
+ return f->exited;
+}
+
struct fuse_cmd *__fuse_read_cmd(struct fuse *f)
{
ssize_t res;
in = (struct fuse_in_header *) cmd->buf;
inarg = cmd->buf + sizeof(struct fuse_in_header);
- do {
- res = read(f->fd, cmd->buf, FUSE_MAX_IN);
- if (res == -1) {
- free_cmd(cmd);
- if (f->exited || errno == EINTR)
- return NULL;
-
- /* ENODEV means we got unmounted, so we silenty return failure */
- if (errno != ENODEV) {
- /* BAD... This will happen again */
- perror("fuse: reading device");
- }
-
- fuse_exit(f);
- return NULL;
- }
- if ((size_t) res < sizeof(struct fuse_in_header)) {
- free_cmd(cmd);
- /* Cannot happen */
- fprintf(stderr, "short read on fuse device\n");
- fuse_exit(f);
+ res = read(f->fd, cmd->buf, FUSE_MAX_IN);
+ if (res == -1) {
+ free_cmd(cmd);
+ if (__fuse_exited(f) || errno == EINTR)
return NULL;
+
+ /* ENODEV means we got unmounted, so we silenty return failure */
+ if (errno != ENODEV) {
+ /* BAD... This will happen again */
+ perror("fuse: reading device");
}
- cmd->buflen = res;
- /* Forget is special, it can be done without messing with threads. */
- if (in->opcode == FUSE_FORGET)
- do_forget(f, in, (struct fuse_forget_in *) inarg);
-
- } while (in->opcode == FUSE_FORGET);
+ fuse_exit(f);
+ return NULL;
+ }
+ if ((size_t) res < sizeof(struct fuse_in_header)) {
+ free_cmd(cmd);
+ /* Cannot happen */
+ fprintf(stderr, "short read on fuse device\n");
+ fuse_exit(f);
+ return NULL;
+ }
+ cmd->buflen = res;
+
+ /* Forget is special, it can be done without messing with threads. */
+ if (in->opcode == FUSE_FORGET) {
+ do_forget(f, in, (struct fuse_forget_in *) inarg);
+ free_cmd(cmd);
+ return NULL;
+ }
return cmd;
}
while (1) {
struct fuse_cmd *cmd;
- if (f->exited)
+ if (__fuse_exited(f))
return;
cmd = __fuse_read_cmd(f);