aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-04-22 12:04:55 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2005-04-22 12:04:55 +0000
commit0111f9dbe43a8c4ae516d3eb470186770894c5bf (patch)
tree6112c59cbfcebc262d88ae10d1e06d92e0fcd142 /kernel
parentd001bf9915e651dd301c29aafe0b7e777a1ae7cf (diff)
downloadlibfuse-0111f9dbe43a8c4ae516d3eb470186770894c5bf.tar.gz
fix
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dev.c14
-rw-r--r--kernel/dir.c7
-rw-r--r--kernel/fuse_i.h17
-rw-r--r--kernel/inode.c32
4 files changed, 26 insertions, 44 deletions
diff --git a/kernel/dev.c b/kernel/dev.c
index 29a9b63..d64423e 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -24,7 +24,7 @@ static inline struct fuse_conn *fuse_get_conn(struct file *file)
struct fuse_conn *fc;
spin_lock(&fuse_lock);
fc = file->private_data;
- if (fc && !fc->sb)
+ if (fc && !fc->mounted)
fc = NULL;
spin_unlock(&fuse_lock);
return fc;
@@ -214,7 +214,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
spin_unlock(&fuse_lock);
if (req->background) {
down_read(&fc->sbput_sem);
- if (fc->sb)
+ if (fc->mounted)
fuse_release_background(req);
up_read(&fc->sbput_sem);
}
@@ -371,7 +371,7 @@ static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
{
req->isreply = 1;
spin_lock(&fuse_lock);
- if (!fc->file)
+ if (!fc->connected)
req->out.h.error = -ENOTCONN;
else if (fc->conn_error)
req->out.h.error = -ECONNREFUSED;
@@ -404,7 +404,7 @@ void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req)
static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
{
spin_lock(&fuse_lock);
- if (fc->file) {
+ if (fc->connected) {
queue_request(fc, req);
spin_unlock(&fuse_lock);
} else {
@@ -659,7 +659,7 @@ static void request_wait(struct fuse_conn *fc)
DECLARE_WAITQUEUE(wait, current);
add_wait_queue_exclusive(&fc->waitq, &wait);
- while (fc->sb && list_empty(&fc->pending)) {
+ while (fc->mounted && list_empty(&fc->pending)) {
set_current_state(TASK_INTERRUPTIBLE);
if (signal_pending(current))
break;
@@ -709,7 +709,7 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
goto err_unlock;
request_wait(fc);
err = -ENODEV;
- if (!fc->sb)
+ if (!fc->mounted)
goto err_unlock;
err = -ERESTARTSYS;
if (list_empty(&fc->pending))
@@ -917,7 +917,7 @@ static int fuse_dev_release(struct inode *inode, struct file *file)
spin_lock(&fuse_lock);
fc = file->private_data;
if (fc) {
- fc->file = NULL;
+ fc->connected = 0;
end_requests(fc, &fc->pending);
end_requests(fc, &fc->processing);
fuse_release_conn(fc);
diff --git a/kernel/dir.c b/kernel/dir.c
index 6ae498c..947d538 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -441,9 +441,7 @@ static int fuse_revalidate(struct dentry *entry)
if (get_node_id(inode) == FUSE_ROOT_ID) {
if (!(fc->flags & FUSE_ALLOW_OTHER) &&
- current->fsuid != fc->user_id &&
- (!(fc->flags & FUSE_ALLOW_ROOT) ||
- !capable(CAP_DAC_OVERRIDE)))
+ current->fsuid != fc->user_id)
return -EACCES;
} else if (time_before_eq(jiffies, fi->i_time))
return 0;
@@ -455,8 +453,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->user_id &&
- (!(fc->flags & FUSE_ALLOW_ROOT) || !capable(CAP_DAC_OVERRIDE)))
+ if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->user_id)
return -EACCES;
else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
#ifdef KERNEL_2_6_10_PLUS
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index 373f36d..164eaa7 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -101,10 +101,6 @@ static inline void set_page_dirty_lock(struct page *page)
/** Bypass the page cache for read and write operations */
#define FUSE_DIRECT_IO (1 << 3)
-/** Allow root and setuid-root programs to access fuse-mounted
- filesystems */
-#define FUSE_ALLOW_ROOT (1 << 4)
-
/** FUSE inode */
struct fuse_inode {
/** Inode data */
@@ -260,11 +256,8 @@ struct fuse_req {
* unmounted.
*/
struct fuse_conn {
- /** The superblock of the mounted filesystem */
- struct super_block *sb;
-
- /** The opened client device */
- struct file *file;
+ /** Reference count */
+ int count;
/** The user id for this mount */
uid_t user_id;
@@ -307,6 +300,12 @@ struct fuse_conn {
/** The next unique request id */
int reqctr;
+ /** Mount is active */
+ unsigned mounted : 1;
+
+ /** Connection established */
+ unsigned connected : 1;
+
/** Connection failed (version mismatch) */
unsigned conn_error : 1;
diff --git a/kernel/inode.c b/kernel/inode.c
index 1feaba9..9b894f5 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -99,8 +99,8 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
static void fuse_clear_inode(struct inode *inode)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
- if (fc && (inode->i_sb->s_flags & MS_ACTIVE)) {
+ if (inode->i_sb->s_flags & MS_ACTIVE) {
+ struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
fuse_send_forget(fc, fi->forget_req, fi->nodeid, inode->i_version);
fi->forget_req = NULL;
@@ -260,14 +260,13 @@ static void fuse_put_super(struct super_block *sb)
struct fuse_req, bg_entry));
spin_lock(&fuse_lock);
- fc->sb = NULL;
+ fc->mounted = 0;
fc->user_id = 0;
fc->flags = 0;
/* Flush all readers on this fs */
wake_up_all(&fc->waitq);
up_write(&fc->sbput_sem);
fuse_release_conn(fc);
- *get_fuse_conn_super_p(sb) = NULL;
spin_unlock(&fuse_lock);
}
@@ -314,7 +313,6 @@ enum {
OPT_USER_ID,
OPT_DEFAULT_PERMISSIONS,
OPT_ALLOW_OTHER,
- OPT_ALLOW_ROOT,
OPT_KERNEL_CACHE,
#ifndef KERNEL_2_6
OPT_LARGE_READ,
@@ -330,7 +328,6 @@ static match_table_t tokens = {
{OPT_USER_ID, "user_id=%u"},
{OPT_DEFAULT_PERMISSIONS, "default_permissions"},
{OPT_ALLOW_OTHER, "allow_other"},
- {OPT_ALLOW_ROOT, "allow_root"},
{OPT_KERNEL_CACHE, "kernel_cache"},
#ifndef KERNEL_2_6
{OPT_LARGE_READ, "large_read"},
@@ -382,10 +379,6 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
d->flags |= FUSE_ALLOW_OTHER;
break;
- case OPT_ALLOW_ROOT:
- d->flags |= FUSE_ALLOW_ROOT;
- break;
-
case OPT_KERNEL_CACHE:
d->flags |= FUSE_KERNEL_CACHE;
break;
@@ -424,8 +417,6 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_puts(m, ",default_permissions");
if (fc->flags & FUSE_ALLOW_OTHER)
seq_puts(m, ",allow_other");
- if (fc->flags & FUSE_ALLOW_ROOT)
- seq_puts(m, ",allow_root");
if (fc->flags & FUSE_KERNEL_CACHE)
seq_puts(m, ",kernel_cache");
#ifndef KERNEL_2_6
@@ -453,7 +444,8 @@ static void free_conn(struct fuse_conn *fc)
/* Must be called with the fuse lock held */
void fuse_release_conn(struct fuse_conn *fc)
{
- if (!fc->sb && !fc->file)
+ fc->count--;
+ if (!fc->count)
free_conn(fc);
}
@@ -465,10 +457,6 @@ static struct fuse_conn *new_conn(void)
if (fc != NULL) {
int i;
memset(fc, 0, sizeof(*fc));
- fc->sb = NULL;
- fc->file = NULL;
- fc->flags = 0;
- fc->user_id = 0;
init_waitqueue_head(&fc->waitq);
INIT_LIST_HEAD(&fc->pending);
INIT_LIST_HEAD(&fc->processing);
@@ -508,8 +496,10 @@ static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
fc = ERR_PTR(-EINVAL);
} else {
file->private_data = fc;
- fc->sb = sb;
- fc->file = file;
+ *get_fuse_conn_super_p(sb) = fc;
+ fc->mounted = 1;
+ fc->connected = 1;
+ fc->count = 2;
}
spin_unlock(&fuse_lock);
return fc;
@@ -636,8 +626,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
#endif
fc->max_write = FUSE_MAX_IN / 2;
- *get_fuse_conn_super_p(sb) = fc;
-
err = -ENOMEM;
root = get_root_inode(sb, d.rootmode);
if (root == NULL)
@@ -653,10 +641,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
err:
spin_lock(&fuse_lock);
- fc->sb = NULL;
fuse_release_conn(fc);
spin_unlock(&fuse_lock);
- *get_fuse_conn_super_p(sb) = NULL;
return err;
}