Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Mar 2017 20:14:13 +0000 (12:14 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Mar 2017 20:14:13 +0000 (12:14 -0800)
Pull fuse update from Miklos Szeredi:
 "A bugfix and cleanups"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: release: private_data cannot be NULL
  fuse: cleanup fuse_file refcounting
  fuse: add missing FR_FORCE

1  2 
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h

diff --combined fs/fuse/dir.c
index beb3d64f16e2919a486aa0a1a7b4a936abef5eb2,e816166ce42fa9778d04224461716e5a83feadbc..00800c07ba1c89bda7abd8f15aa760b9ddccc869
@@@ -473,7 -473,7 +473,7 @@@ static int fuse_create_open(struct inod
        if (err) {
                fuse_sync_release(ff, flags);
        } else {
-               file->private_data = fuse_file_get(ff);
+               file->private_data = ff;
                fuse_finish_open(inode, file);
        }
        return err;
@@@ -1777,10 -1777,10 +1777,10 @@@ static int fuse_setattr(struct dentry *
        return ret;
  }
  
 -static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
 -                      struct kstat *stat)
 +static int fuse_getattr(const struct path *path, struct kstat *stat,
 +                      u32 request_mask, unsigned int flags)
  {
 -      struct inode *inode = d_inode(entry);
 +      struct inode *inode = d_inode(path->dentry);
        struct fuse_conn *fc = get_fuse_conn(inode);
  
        if (!fuse_allow_current_process(fc))
diff --combined fs/fuse/file.c
index e80bfd06daf5fc760a16a4a4315a791a1bc347e5,7069ea232049332464427465fdef96dd7410e91d..ec238fb5a584b1c3cc5bc545806575160f78cde4
@@@ -58,7 -58,7 +58,7 @@@ struct fuse_file *fuse_file_alloc(struc
        }
  
        INIT_LIST_HEAD(&ff->write_entry);
-       atomic_set(&ff->count, 0);
+       atomic_set(&ff->count, 1);
        RB_CLEAR_NODE(&ff->polled_node);
        init_waitqueue_head(&ff->poll_wait);
  
@@@ -75,7 -75,7 +75,7 @@@ void fuse_file_free(struct fuse_file *f
        kfree(ff);
  }
  
- struct fuse_file *fuse_file_get(struct fuse_file *ff)
+ static struct fuse_file *fuse_file_get(struct fuse_file *ff)
  {
        atomic_inc(&ff->count);
        return ff;
@@@ -100,6 -100,7 +100,7 @@@ static void fuse_file_put(struct fuse_f
                        iput(req->misc.release.inode);
                        fuse_put_request(ff->fc, req);
                } else if (sync) {
+                       __set_bit(FR_FORCE, &req->flags);
                        __clear_bit(FR_BACKGROUND, &req->flags);
                        fuse_request_send(ff->fc, req);
                        iput(req->misc.release.inode);
@@@ -146,7 -147,7 +147,7 @@@ int fuse_do_open(struct fuse_conn *fc, 
                ff->open_flags &= ~FOPEN_DIRECT_IO;
  
        ff->nodeid = nodeid;
-       file->private_data = fuse_file_get(ff);
+       file->private_data = ff;
  
        return 0;
  }
@@@ -245,14 -246,9 +246,9 @@@ static void fuse_prepare_release(struc
  
  void fuse_release_common(struct file *file, int opcode)
  {
-       struct fuse_file *ff;
-       struct fuse_req *req;
-       ff = file->private_data;
-       if (unlikely(!ff))
-               return;
+       struct fuse_file *ff = file->private_data;
+       struct fuse_req *req = ff->reserved_req;
  
-       req = ff->reserved_req;
        fuse_prepare_release(ff, file->f_flags, opcode);
  
        if (ff->flock) {
@@@ -297,13 -293,13 +293,13 @@@ static int fuse_release(struct inode *i
  
  void fuse_sync_release(struct fuse_file *ff, int flags)
  {
-       WARN_ON(atomic_read(&ff->count) > 1);
+       WARN_ON(atomic_read(&ff->count) != 1);
        fuse_prepare_release(ff, flags, FUSE_RELEASE);
-       __set_bit(FR_FORCE, &ff->reserved_req->flags);
-       __clear_bit(FR_BACKGROUND, &ff->reserved_req->flags);
-       fuse_request_send(ff->fc, ff->reserved_req);
-       fuse_put_request(ff->fc, ff->reserved_req);
-       kfree(ff);
+       /*
+        * iput(NULL) is a no-op and since the refcount is 1 and everything's
+        * synchronous, we are fine with not doing igrab() here"
+        */
+       fuse_file_put(ff, true);
  }
  EXPORT_SYMBOL_GPL(fuse_sync_release);
  
@@@ -2043,12 -2039,12 +2039,12 @@@ static void fuse_vma_close(struct vm_ar
   * - sync(2)
   * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER
   */
 -static int fuse_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 +static int fuse_page_mkwrite(struct vm_fault *vmf)
  {
        struct page *page = vmf->page;
 -      struct inode *inode = file_inode(vma->vm_file);
 +      struct inode *inode = file_inode(vmf->vma->vm_file);
  
 -      file_update_time(vma->vm_file);
 +      file_update_time(vmf->vma->vm_file);
        lock_page(page);
        if (page->mapping != inode->i_mapping) {
                unlock_page(page);
diff --combined fs/fuse/fuse_i.h
index 052f8d3c41cb040405a63248ffebc613dcc893e6,83f797271aefb4c08d73f037350af6a1d0ab3b4b..32ac2c9b09c0302c99337c374263a6fa428b5cf4
@@@ -256,7 -256,7 +256,7 @@@ struct fuse_io_priv 
  
  #define FUSE_IO_PRIV_SYNC(f) \
  {                                     \
 -      .refcnt = { ATOMIC_INIT(1) },   \
 +      .refcnt = KREF_INIT(1),         \
        .async = 0,                     \
        .file = f,                      \
  }
@@@ -732,7 -732,6 +732,6 @@@ void fuse_read_fill(struct fuse_req *re
  int fuse_open_common(struct inode *inode, struct file *file, bool isdir);
  
  struct fuse_file *fuse_file_alloc(struct fuse_conn *fc);
- struct fuse_file *fuse_file_get(struct fuse_file *ff);
  void fuse_file_free(struct fuse_file *ff);
  void fuse_finish_open(struct inode *inode, struct file *file);