|
@@ -58,7 +58,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
|
|
|
}
|
|
|
|
|
|
INIT_LIST_HEAD(&ff->write_entry);
|
|
|
- atomic_set(&ff->count, 1);
|
|
|
+ refcount_set(&ff->count, 1);
|
|
|
RB_CLEAR_NODE(&ff->polled_node);
|
|
|
init_waitqueue_head(&ff->poll_wait);
|
|
|
|
|
@@ -77,7 +77,7 @@ void fuse_file_free(struct fuse_file *ff)
|
|
|
|
|
|
static struct fuse_file *fuse_file_get(struct fuse_file *ff)
|
|
|
{
|
|
|
- atomic_inc(&ff->count);
|
|
|
+ refcount_inc(&ff->count);
|
|
|
return ff;
|
|
|
}
|
|
|
|
|
@@ -88,7 +88,7 @@ static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
|
|
|
|
|
|
static void fuse_file_put(struct fuse_file *ff, bool sync)
|
|
|
{
|
|
|
- if (atomic_dec_and_test(&ff->count)) {
|
|
|
+ if (refcount_dec_and_test(&ff->count)) {
|
|
|
struct fuse_req *req = ff->reserved_req;
|
|
|
|
|
|
if (ff->fc->no_open) {
|
|
@@ -293,7 +293,7 @@ static int fuse_release(struct inode *inode, struct file *file)
|
|
|
|
|
|
void fuse_sync_release(struct fuse_file *ff, int flags)
|
|
|
{
|
|
|
- WARN_ON(atomic_read(&ff->count) != 1);
|
|
|
+ WARN_ON(refcount_read(&ff->count) > 1);
|
|
|
fuse_prepare_release(ff, flags, FUSE_RELEASE);
|
|
|
/*
|
|
|
* iput(NULL) is a no-op and since the refcount is 1 and everything's
|
|
@@ -2083,7 +2083,8 @@ static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
return generic_file_mmap(file, vma);
|
|
|
}
|
|
|
|
|
|
-static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
|
|
|
+static int convert_fuse_file_lock(struct fuse_conn *fc,
|
|
|
+ const struct fuse_file_lock *ffl,
|
|
|
struct file_lock *fl)
|
|
|
{
|
|
|
switch (ffl->type) {
|
|
@@ -2098,7 +2099,14 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
|
|
|
|
|
|
fl->fl_start = ffl->start;
|
|
|
fl->fl_end = ffl->end;
|
|
|
- fl->fl_pid = ffl->pid;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Convert pid into the caller's pid namespace. If the pid
|
|
|
+ * does not map into the namespace fl_pid will get set to 0.
|
|
|
+ */
|
|
|
+ rcu_read_lock();
|
|
|
+ fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns));
|
|
|
+ rcu_read_unlock();
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -2147,7 +2155,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
|
|
|
args.out.args[0].value = &outarg;
|
|
|
err = fuse_simple_request(fc, &args);
|
|
|
if (!err)
|
|
|
- err = convert_fuse_file_lock(&outarg.lk, fl);
|
|
|
+ err = convert_fuse_file_lock(fc, &outarg.lk, fl);
|
|
|
|
|
|
return err;
|
|
|
}
|
|
@@ -2159,7 +2167,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
|
|
|
FUSE_ARGS(args);
|
|
|
struct fuse_lk_in inarg;
|
|
|
int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
|
|
|
- pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
|
|
|
+ struct pid *pid = fl->fl_type != F_UNLCK ? task_tgid(current) : NULL;
|
|
|
+ pid_t pid_nr = pid_nr_ns(pid, fc->pid_ns);
|
|
|
int err;
|
|
|
|
|
|
if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
|
|
@@ -2171,7 +2180,10 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
|
|
|
if (fl->fl_flags & FL_CLOSE)
|
|
|
return 0;
|
|
|
|
|
|
- fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg);
|
|
|
+ if (pid && pid_nr == 0)
|
|
|
+ return -EOVERFLOW;
|
|
|
+
|
|
|
+ fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
|
|
|
err = fuse_simple_request(fc, &args);
|
|
|
|
|
|
/* locking is restartable */
|