return req;
}
+/* This can return NULL, but only in case it's interrupted by a SIGKILL */
struct fuse_req *fuse_get_request(struct fuse_conn *fc)
{
- if (down_interruptible(&fc->outstanding_sem))
- return NULL;
- return do_get_request(fc);
-}
-
-/*
- * Non-interruptible version of the above function is for operations
- * which can't legally return -ERESTART{SYS,NOINTR}. This can still
- * return NULL, but only in case the signal is SIGKILL.
- */
-struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
-{
int intr;
sigset_t oldset;
get_file(req->file);
}
-static int request_wait_answer_nonint(struct fuse_req *req)
-{
- int err;
- sigset_t oldset;
- block_sigs(&oldset);
- err = wait_event_interruptible(req->waitq, req->finished);
- restore_sigs(&oldset);
- return err;
-}
-
/* Called with fuse_lock held. Releases, and then reacquires it. */
-static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req,
- int interruptible)
+static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
{
- int intr;
+ sigset_t oldset;
spin_unlock(&fuse_lock);
- if (interruptible)
- intr = wait_event_interruptible(req->waitq, req->finished);
- else
- intr = request_wait_answer_nonint(req);
+ block_sigs(&oldset);
+ wait_event_interruptible(req->waitq, req->finished);
+ restore_sigs(&oldset);
spin_lock(&fuse_lock);
- if (intr && interruptible && req->sent) {
- /* If request is already in userspace, only allow KILL
- signal to interrupt */
- spin_unlock(&fuse_lock);
- intr = request_wait_answer_nonint(req);
- spin_lock(&fuse_lock);
- }
- if (!intr)
+ if (req->finished)
return;
- if (!interruptible || req->sent)
- req->out.h.error = -EINTR;
- else
- req->out.h.error = -ERESTARTNOINTR;
-
+ req->out.h.error = -EINTR;
req->interrupted = 1;
if (req->locked) {
/* This is uninterruptible sleep, because data is
wake_up(&fc->waitq);
}
-static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
- int interruptible)
+/*
+ * This can only be interrupted by a SIGKILL
+ */
+void request_send(struct fuse_conn *fc, struct fuse_req *req)
{
req->isreply = 1;
spin_lock(&fuse_lock);
after request_end() */
__fuse_get_request(req);
- request_wait_answer(fc, req, interruptible);
+ request_wait_answer(fc, req);
}
spin_unlock(&fuse_lock);
}
-void request_send(struct fuse_conn *fc, struct fuse_req *req)
-{
- request_send_wait(fc, req, 1);
-}
-
-/*
- * Non-interruptible version of the above function is for operations
- * which can't legally return -ERESTART{SYS,NOINTR}. This can still
- * be interrupted but only with SIGKILL.
- */
-void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req)
-{
- request_send_wait(fc, req, 0);
-}
-
static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
{
spin_lock(&fuse_lock);
struct inode *inode = entry->d_inode;
struct fuse_inode *fi = get_fuse_inode(inode);
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req = fuse_get_request_nonint(fc);
+ struct fuse_req *req = fuse_get_request(fc);
if (!req)
return 0;
fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
- request_send_nonint(fc, req);
+ request_send(fc, req);
err = req->out.h.error;
if (!err) {
if (outarg.nodeid != get_node_id(inode)) {
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.mode = mode;
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.mode = mode;
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_SYMLINK;
req->in.numargs = 2;
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_UNLINK;
req->in.h.nodeid = get_node_id(dir);
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_RMDIR;
req->in.h.nodeid = get_node_id(dir);
struct fuse_conn *fc = get_fuse_conn(olddir);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.newdir = get_node_id(newdir);
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.oldnodeid = get_node_id(inode);
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_GETATTR;
req->in.h.nodeid = get_node_id(inode);
struct page *page;
struct inode *inode = file->f_dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req = fuse_get_request_nonint(fc);
+ struct fuse_req *req = fuse_get_request(fc);
if (!req)
return -EINTR;
char *link;
if (!req)
- return ERR_PTR(-ERESTARTNOINTR);
+ return ERR_PTR(-EINTR);
link = (char *) __get_free_page(GFP_KERNEL);
if (!link) {
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.valid = iattr_to_fattr(attr, &inarg.attr);
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_REMOVEXATTR;
req->in.h.nodeid = get_node_id(inode);
struct fuse_open_out outarg;
struct fuse_file *ff;
int err;
- /* Restarting the syscall is not allowed if O_CREAT and O_EXCL
- are both set, because creation will fail on the restart */
- int excl = (file->f_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL);
err = generic_file_open(inode, file);
if (err)
return err;
}
- if (excl)
- req = fuse_get_request_nonint(fc);
- else
- req = fuse_get_request(fc);
+ req = fuse_get_request(fc);
if (!req)
- return excl ? -EINTR : -ERESTARTSYS;
+ return -EINTR;
err = -ENOMEM;
ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
req->out.numargs = 1;
req->out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg;
- if (excl)
- request_send_nonint(fc, req);
- else
- request_send(fc, req);
+ request_send(fc, req);
err = req->out.h.error;
if (err) {
fuse_request_free(ff->release_req);
if (fc->no_flush)
return 0;
- req = fuse_get_request_nonint(fc);
+ req = fuse_get_request(fc);
if (!req)
return -EINTR;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
- request_send_nonint(fc, req);
+ request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
if (err == -ENOSYS) {
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh;
req->out.argvar = 1;
req->out.numargs = 1;
req->out.args[0].size = count;
- request_send_nonint(fc, req);
+ request_send(fc, req);
return req->out.args[0].size;
}
struct inode *inode = page->mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
- struct fuse_req *req = fuse_get_request_nonint(fc);
+ struct fuse_req *req = fuse_get_request(fc);
int err = -EINTR;
if (!req)
goto out;
int err;
data.file = file;
data.inode = inode;
- data.req = fuse_get_request_nonint(fc);
+ data.req = fuse_get_request(fc);
if (!data.req)
return -EINTR;
req->out.numargs = 1;
req->out.args[0].size = sizeof(struct fuse_write_out);
req->out.args[0].value = &outarg;
- request_send_nonint(fc, req);
+ request_send(fc, req);
return outarg.size;
}
struct inode *inode = page->mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
- struct fuse_req *req = fuse_get_request_nonint(fc);
+ struct fuse_req *req = fuse_get_request(fc);
if (!req)
return -EINTR;
ssize_t res = 0;
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
while (count) {
size_t tmp;
struct fuse_req *fuse_get_request(struct fuse_conn *fc);
/**
- * Reserve a preallocated request, only interruptible by SIGKILL
- */
-struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
-
-/**
* Decrement reference count of a request. If count goes to zero put
* on unused list (preallocated) or free reqest (not preallocated).
*/
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
/**
- * Send a request (synchronous, interruptible)
+ * Send a request (synchronous)
*/
void request_send(struct fuse_conn *fc, struct fuse_req *req);
/**
- * Send a request (synchronous, non-interruptible except by SIGKILL)
- */
-void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req);
-
-/**
* Send a request with no reply
*/
void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
req->in.numargs = 0;
req->in.h.opcode = FUSE_STATFS;