int (*read) (const char *, char *, size_t, off_t);
int (*write) (const char *, const char *, size_t, off_t);
int (*statfs) (struct fuse_statfs *);
- int (*release) (const char *);
+ int (*release) (const char *, int);
};
/** Extra context that may be needed by some filesystems */
{
struct fuse_conn *fc = INO_FC(inode);
struct fuse_in *in = NULL;
+ struct fuse_open_in *inarg = NULL;
in = kmalloc(sizeof(struct fuse_in), GFP_NOFS);
if(!in)
return -ENOMEM;
-
memset(in, 0, sizeof(struct fuse_in));
+
+ inarg = kmalloc(sizeof(struct fuse_open_in), GFP_NOFS);
+ if(!inarg)
+ goto out_free;
+ memset(inarg, 0, sizeof(struct fuse_open_in));
+
+ inarg->flags = file->f_flags & ~O_EXCL;
in->h.opcode = FUSE_RELEASE;
in->h.ino = inode->i_ino;
+ in->numargs = 1;
+ in->args[0].size = sizeof(struct fuse_open_in);
+ in->args[0].value = inarg;
if(!request_send_noreply(fc, in))
return 0;
+ out_free:
+ kfree(inarg);
kfree(in);
return 0;
}
if(path != NULL) {
/* The open syscall was interrupted, so it must be cancelled */
if(res == 0 && res2 == -ENOENT && f->op.release)
- f->op.release(path);
+ f->op.release(path, arg->flags);
free(path);
}
}
-static void do_release(struct fuse *f, struct fuse_in_header *in)
+static void do_release(struct fuse *f, struct fuse_in_header *in,
+ struct fuse_open_in *arg)
{
char *path;
path = get_path(f, in->ino);
if(path != NULL) {
if(f->op.release)
- f->op.release(path);
+ f->op.release(path, arg->flags);
free(path);
}
}
do_open(f, in, (struct fuse_open_in *) inarg);
break;
+ case FUSE_RELEASE:
+ do_release(f, in, (struct fuse_open_in *) inarg);
+ break;
+
case FUSE_READ:
do_read(f, in, (struct fuse_read_in *) inarg);
break;
do_statfs(f, in);
break;
- case FUSE_RELEASE:
- do_release(f, in);
- break;
-
default:
- fprintf(stderr, "Operation %i not implemented\n", in->opcode);
send_reply(f, in, -ENOSYS, NULL, 0);
}