aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2005-05-12 14:56:34 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2005-05-12 14:56:34 +0000
commitf94e0100733292563be8699b502bebaa5c170dd6 (patch)
treecb83df7f4f7f22bb58b5812fbf024529967cf138 /kernel
parent0fc4abe9e8a0768118b5cb338691563ef173e6b8 (diff)
fix
Diffstat (limited to 'kernel')
-rw-r--r--kernel/configure.ac2
-rw-r--r--kernel/dev.c73
-rw-r--r--kernel/dir.c36
-rw-r--r--kernel/file.c35
-rw-r--r--kernel/fuse_i.h12
-rw-r--r--kernel/inode.c2
6 files changed, 47 insertions, 113 deletions
diff --git a/kernel/configure.ac b/kernel/configure.ac
index 55c876f..f7f2a60 100644
--- a/kernel/configure.ac
+++ b/kernel/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(fuse-kernel, 2.3-pre7)
+AC_INIT(fuse-kernel, 2.3-pre8)
AC_CONFIG_HEADERS([config.h])
AC_PROG_INSTALL
diff --git a/kernel/dev.c b/kernel/dev.c
index d64423e..0bad236 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -139,20 +139,9 @@ static struct fuse_req *do_get_request(struct fuse_conn *fc)
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;
@@ -277,43 +266,20 @@ static void background_request(struct fuse_conn *fc, struct fuse_req *req)
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
@@ -366,8 +332,10 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
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);
@@ -381,26 +349,11 @@ static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
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);
diff --git a/kernel/dir.c b/kernel/dir.c
index 078d517..99192c3 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -52,12 +52,12 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
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)) {
@@ -107,7 +107,7 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
@@ -201,7 +201,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int 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;
@@ -227,7 +227,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int 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;
@@ -252,7 +252,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
req->in.h.opcode = FUSE_SYMLINK;
req->in.numargs = 2;
@@ -269,7 +269,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
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);
@@ -300,7 +300,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
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);
@@ -327,7 +327,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
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);
@@ -372,7 +372,7 @@ static int fuse_link(struct dentry *entry, struct inode *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);
@@ -402,7 +402,7 @@ int fuse_do_getattr(struct inode *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);
@@ -562,7 +562,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
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;
@@ -592,7 +592,7 @@ static char *read_link(struct dentry *dentry)
char *link;
if (!req)
- return ERR_PTR(-ERESTARTNOINTR);
+ return ERR_PTR(-EINTR);
link = (char *) __get_free_page(GFP_KERNEL);
if (!link) {
@@ -738,7 +738,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.valid = iattr_to_fattr(attr, &inarg.attr);
@@ -871,7 +871,7 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
@@ -911,7 +911,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
@@ -961,7 +961,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTNOINTR;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
@@ -1007,7 +1007,7 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
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);
diff --git a/kernel/file.c b/kernel/file.c
index 6fee83e..5ebf025 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -24,9 +24,6 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
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)
@@ -40,12 +37,9 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
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);
@@ -69,10 +63,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
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 && !(fc->flags & FUSE_KERNEL_CACHE))
#ifdef KERNEL_2_6
@@ -137,7 +128,7 @@ static int fuse_flush(struct file *file)
if (fc->no_flush)
return 0;
- req = fuse_get_request_nonint(fc);
+ req = fuse_get_request(fc);
if (!req)
return -EINTR;
@@ -150,7 +141,7 @@ static int fuse_flush(struct file *file)
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) {
@@ -175,7 +166,7 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh;
@@ -228,7 +219,7 @@ size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
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;
}
@@ -244,7 +235,7 @@ static int fuse_readpage(struct file *file, struct page *page)
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;
@@ -318,7 +309,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
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;
@@ -411,7 +402,7 @@ static int fuse_file_bigread(struct file *file, struct inode *inode,
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
for (; starti < endi; starti = nexti) {
nexti = starti + (FUSE_BLOCK_SIZE >> PAGE_CACHE_SHIFT);
@@ -452,7 +443,7 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
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;
}
@@ -472,7 +463,7 @@ static int fuse_commit_write(struct file *file, struct page *page,
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;
@@ -546,7 +537,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
ssize_t res = 0;
struct fuse_req *req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
while (count) {
size_t tmp;
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index 6ba851e..c579a69 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -486,27 +486,17 @@ void fuse_reset_request(struct fuse_req *req);
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);
diff --git a/kernel/inode.c b/kernel/inode.c
index 4c36ad0..ed14602 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -299,7 +299,7 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
req = fuse_get_request(fc);
if (!req)
- return -ERESTARTSYS;
+ return -EINTR;
req->in.numargs = 0;
req->in.h.opcode = FUSE_STATFS;