Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 25553
b: refs/heads/master
c: 0720b31
h: refs/heads/master
i:
  25551: 3bc94be
v: v3
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Apr 11, 2006
1 parent 6513a8e commit 048704e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e5ac1d1e70a8c19a65a959d73650203df7a2e168
refs/heads/master: 0720b315976447cba3f0c3e211223b8cb82b0f93
31 changes: 11 additions & 20 deletions trunk/fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ static kmem_cache_t *fuse_req_cachep;

static struct fuse_conn *fuse_get_conn(struct file *file)
{
struct fuse_conn *fc;
spin_lock(&fuse_lock);
fc = file->private_data;
if (fc && !fc->connected)
fc = NULL;
spin_unlock(&fuse_lock);
return fc;
/*
* Lockless access is OK, because file->private data is set
* once during mount and is valid until the file is released.
*/
return file->private_data;
}

static void fuse_request_init(struct fuse_req *req)
Expand Down Expand Up @@ -607,19 +605,16 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t *off)
{
int err;
struct fuse_conn *fc;
struct fuse_req *req;
struct fuse_in *in;
struct fuse_copy_state cs;
unsigned reqsize;
struct fuse_conn *fc = fuse_get_conn(file);
if (!fc)
return -EPERM;

restart:
spin_lock(&fuse_lock);
fc = file->private_data;
err = -EPERM;
if (!fc)
goto err_unlock;

err = -EAGAIN;
if ((file->f_flags & O_NONBLOCK) && fc->connected &&
list_empty(&fc->pending))
Expand Down Expand Up @@ -915,17 +910,13 @@ void fuse_abort_conn(struct fuse_conn *fc)

static int fuse_dev_release(struct inode *inode, struct file *file)
{
struct fuse_conn *fc;

spin_lock(&fuse_lock);
fc = file->private_data;
struct fuse_conn *fc = fuse_get_conn(file);
if (fc) {
spin_lock(&fuse_lock);
fc->connected = 0;
end_requests(fc, &fc->pending);
end_requests(fc, &fc->processing);
}
spin_unlock(&fuse_lock);
if (fc) {
spin_unlock(&fuse_lock);
fasync_helper(-1, file, 0, &fc->fasync);
kobject_put(&fc->kobj);
}
Expand Down
64 changes: 22 additions & 42 deletions trunk/fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,37 +414,6 @@ static struct fuse_conn *new_conn(void)
return fc;
}

static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
{
struct fuse_conn *fc;
int err;

err = -EINVAL;
if (file->f_op != &fuse_dev_operations)
goto out_err;

err = -ENOMEM;
fc = new_conn();
if (!fc)
goto out_err;

spin_lock(&fuse_lock);
err = -EINVAL;
if (file->private_data)
goto out_unlock;

kobject_get(&fc->kobj);
file->private_data = fc;
spin_unlock(&fuse_lock);
return fc;

out_unlock:
spin_unlock(&fuse_lock);
kobject_put(&fc->kobj);
out_err:
return ERR_PTR(err);
}

static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
{
struct fuse_attr attr;
Expand Down Expand Up @@ -526,12 +495,9 @@ static void fuse_send_init(struct fuse_conn *fc)

static unsigned long long conn_id(void)
{
/* BKL is held for ->get_sb() */
static unsigned long long ctr = 1;
unsigned long long val;
spin_lock(&fuse_lock);
val = ctr++;
spin_unlock(&fuse_lock);
return val;
return ctr++;
}

static int fuse_fill_super(struct super_block *sb, void *data, int silent)
Expand All @@ -556,10 +522,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (!file)
return -EINVAL;

fc = get_conn(file, sb);
fput(file);
if (IS_ERR(fc))
return PTR_ERR(fc);
if (file->f_op != &fuse_dev_operations)
return -EINVAL;

/* Setting file->private_data can't race with other mount()
instances, since BKL is held for ->get_sb() */
if (file->private_data)
return -EINVAL;

fc = new_conn();
if (!fc)
return -ENOMEM;

fc->flags = d.flags;
fc->user_id = d.user_id;
Expand Down Expand Up @@ -589,10 +562,16 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
goto err_put_root;

sb->s_root = root_dentry;
spin_lock(&fuse_lock);
fc->mounted = 1;
fc->connected = 1;
spin_unlock(&fuse_lock);
kobject_get(&fc->kobj);
file->private_data = fc;
/*
* atomic_dec_and_test() in fput() provides the necessary
* memory barrier for file->private_data to be visible on all
* CPUs after this
*/
fput(file);

fuse_send_init(fc);

Expand All @@ -601,6 +580,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
err_put_root:
dput(root_dentry);
err:
fput(file);
kobject_put(&fc->kobj);
return err;
}
Expand Down

0 comments on commit 048704e

Please sign in to comment.