1. 19 3月, 2015 1 次提交
    • T
      fuse: explicitly set /dev/fuse file's private_data · 94e4fe2c
      Tom Van Braeckel 提交于
      The misc subsystem (which is used for /dev/fuse) initializes private_data to
      point to the misc device when a driver has registered a custom open file
      operation, and initializes it to NULL when a custom open file operation has
      *not* been provided.
      
      This subtle quirk is confusing, to the point where kernel code registers
      *empty* file open operations to have private_data point to the misc device
      structure. And it leads to bugs, where the addition or removal of a custom open
      file operation surprisingly changes the initial contents of a file's
      private_data structure.
      
      So to simplify things in the misc subsystem, a patch [1] has been proposed to
      *always* set the private_data to point to the misc device, instead of only
      doing this when a custom open file operation has been registered.
      
      But before this patch can be applied we need to modify drivers that make the
      assumption that a misc device file's private_data is initialized to NULL
      because they didn't register a custom open file operation, so they don't rely
      on this assumption anymore. FUSE uses private_data to store the fuse_conn and
      errors out if this is not initialized to NULL at mount time.
      
      Hence, we now set a file's private_data to NULL explicitly, to be independent
      of whatever value the misc subsystem initializes it to by default.
      
      [1] https://lkml.org/lkml/2014/12/4/939Reported-by: NGiedrius Statkevicius <giedriuswork@gmail.com>
      Reported-by: NThierry Reding <thierry.reding@gmail.com>
      Signed-off-by: NTom Van Braeckel <tomvanbraeckel@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      94e4fe2c
  2. 26 2月, 2015 2 次提交
  3. 06 1月, 2015 2 次提交
    • M
      fuse: add memory barrier to INIT · 9759bd51
      Miklos Szeredi 提交于
      Theoretically we need to order setting of various fields in fc with
      fc->initialized.
      
      No known bug reports related to this yet.
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      9759bd51
    • M
      fuse: fix LOOKUP vs INIT compat handling · 21f62174
      Miklos Szeredi 提交于
      Analysis from Marc:
      
       "Commit 7078187a ("fuse: introduce fuse_simple_request() helper")
        from the above pull request triggers some EIO errors for me in some tests
        that rely on fuse
      
        Looking at the code changes and a bit of debugging info I think there's a
        general problem here that fuse_get_req checks and possibly waits for
        fc->initialized, and this was always called first.  But this commit
        changes the ordering and in many places fc->minor is now possibly used
        before fuse_get_req, and we can't be sure that fc has been initialized.
        In my case fuse_lookup_init sets req->out.args[0].size to the wrong size
        because fc->minor at that point is still 0, leading to the EIO error."
      
      Fix by moving the compat adjustments into fuse_simple_request() to after
      fuse_get_req().
      
      This is also more readable than the original, since now compatibility is
      handled in a single function instead of cluttering each operation.
      Reported-by: NMarc Dionne <marc.c.dionne@gmail.com>
      Tested-by: NMarc Dionne <marc.c.dionne@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Fixes: 7078187a ("fuse: introduce fuse_simple_request() helper")
      21f62174
  4. 12 12月, 2014 1 次提交
    • M
      fuse: introduce fuse_simple_request() helper · 7078187a
      Miklos Szeredi 提交于
      The following pattern is repeated many times:
      
      	req = fuse_get_req_nopages(fc);
      	/* Initialize req->(in|out).args */
      	fuse_request_send(fc, req);
      	err = req->out.h.error;
      	fuse_put_request(req);
      
      Create a new replacement helper:
      
      	/* Initialize args */
      	err = fuse_simple_request(fc, &args);
      
      In addition to reducing the code size, this will ease moving from the
      complex arg-based to a simpler page-based I/O on the fuse device.
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      7078187a
  5. 07 7月, 2014 1 次提交
    • M
      fuse: avoid scheduling while atomic · c55a01d3
      Miklos Szeredi 提交于
      As reported by Richard Sharpe, an attempt to use fuse_notify_inval_entry()
      triggers complains about scheduling while atomic:
      
        BUG: scheduling while atomic: fuse.hf/13976/0x10000001
      
      This happens because fuse_notify_inval_entry() attempts to allocate memory
      with GFP_KERNEL, holding "struct fuse_copy_state" mapped by kmap_atomic().
      
      Introduced by commit 58bda1da "fuse/dev: use atomic maps"
      
      Fix by moving the map/unmap to just cover the actual memcpy operation.
      
      Original patch from Maxim Patlasov <mpatlasov@parallels.com>
      Reported-by: NRichard Sharpe <realrichardsharpe@gmail.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Cc: <stable@vger.kernel.org> # v3.15+
      c55a01d3
  6. 05 6月, 2014 1 次提交
  7. 02 4月, 2014 2 次提交
  8. 23 1月, 2014 2 次提交
  9. 04 9月, 2013 1 次提交
  10. 08 5月, 2013 1 次提交
  11. 18 4月, 2013 2 次提交
  12. 17 4月, 2013 4 次提交
  13. 10 4月, 2013 1 次提交
    • A
      get rid of pipe->inode · 6447a3cf
      Al Viro 提交于
      it's used only as a flag to distinguish normal pipes/FIFOs from the
      internal per-task one used by file-to-file splice.  And pipe->files
      would work just as well for that purpose...
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      6447a3cf
  14. 28 2月, 2013 1 次提交
  15. 04 2月, 2013 1 次提交
    • E
      fuse: avoid out-of-scope stack access · 6a4e922c
      Eric Wong 提交于
      The all pointers within fuse_req must point to valid memory once
      fuse_force_forget() returns.
      
      This bug appeared in "fuse: implement NFS-like readdirplus support"
      and was never in any official Linux release.
      
      I tested the fuse_force_forget() code path by injecting to fake -ENOMEM and
      verified the FORGET operation was called properly in userspace.
      Signed-off-by: NEric Wong <normalperson@yhbt.net>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      6a4e922c
  16. 24 1月, 2013 6 次提交
    • M
      fuse: use req->page_descs[] for argpages cases · 85f40aec
      Maxim Patlasov 提交于
      Previously, anyone who set flag 'argpages' only filled req->pages[] and set
      per-request page_offset. This patch re-works all cases where argpages=1 to
      fill req->page_descs[] properly.
      
      Having req->page_descs[] filled properly allows to re-work fuse_copy_pages()
      to copy page fragments described by req->page_descs[]. This will be useful
      for next patches optimizing direct_IO.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      85f40aec
    • M
      fuse: add per-page descriptor <offset, length> to fuse_req · b2430d75
      Maxim Patlasov 提交于
      The ability to save page pointers along with lengths and offsets in fuse_req
      will be useful to cover several iovec-s with a single fuse_req.
      
      Per-request page_offset is removed because anybody who need it can use
      req->page_descs[0].offset instead.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      b2430d75
    • M
      fuse: rework fuse_retrieve() · 4d53dc99
      Maxim Patlasov 提交于
      The patch reworks fuse_retrieve() to allocate only so many page pointers
      as needed. The core part of the patch is the following calculation:
      
      	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
      
      (thanks Miklos for formula). All other changes are mostly shuffling lines.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      4d53dc99
    • M
      fuse: categorize fuse_get_req() · b111c8c0
      Maxim Patlasov 提交于
      The patch categorizes all fuse_get_req() invocations into two categories:
       - fuse_get_req_nopages(fc) - when caller doesn't care about req->pages
       - fuse_get_req(fc, n) - when caller need n page pointers (n > 0)
      
      Adding fuse_get_req_nopages() helps to avoid numerous fuse_get_req(fc, 0)
      scattered over code. Now it's clear from the first glance when a caller need
      fuse_req with page pointers.
      
      The patch doesn't make any logic changes. In multi-page case, it silly
      allocates array of FUSE_MAX_PAGES_PER_REQ page pointers. This will be amended
      by future patches.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      b111c8c0
    • M
      fuse: general infrastructure for pages[] of variable size · 4250c066
      Maxim Patlasov 提交于
      The patch removes inline array of FUSE_MAX_PAGES_PER_REQ page pointers from
      fuse_req. Instead of that, req->pages may now point either to small inline
      array or to an array allocated dynamically.
      
      This essentially means that all callers of fuse_request_alloc[_nofs] should
      pass the number of pages needed explicitly.
      
      The patch doesn't make any logic changes.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      4250c066
    • A
      fuse: implement NFS-like readdirplus support · 0b05b183
      Anand V. Avati 提交于
      This patch implements readdirplus support in FUSE, similar to NFS.
      The payload returned in the readdirplus call contains
      'fuse_entry_out' structure thereby providing all the necessary inputs
      for 'faking' a lookup() operation on the spot.
      
      If the dentry and inode already existed (for e.g. in a re-run of ls -l)
      then just the inode attributes timeout and dentry timeout are refreshed.
      
      With a simple client->network->server implementation of a FUSE based
      filesystem, the following performance observations were made:
      
      Test: Performing a filesystem crawl over 20,000 files with
      
      sh# time ls -lR /mnt
      
      Without readdirplus:
      Run 1: 18.1s
      Run 2: 16.0s
      Run 3: 16.2s
      
      With readdirplus:
      Run 1: 4.1s
      Run 2: 3.8s
      Run 3: 3.8s
      
      The performance improvement is significant as it avoided 20,000 upcalls
      calls (lookup). Cache consistency is no worse than what already is.
      Signed-off-by: NAnand V. Avati <avati@redhat.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      0b05b183
  17. 17 1月, 2013 1 次提交
  18. 15 11月, 2012 1 次提交
    • E
      userns: Support fuse interacting with multiple user namespaces · 499dcf20
      Eric W. Biederman 提交于
      Use kuid_t and kgid_t in struct fuse_conn and struct fuse_mount_data.
      
      The connection between between a fuse filesystem and a fuse daemon is
      established when a fuse filesystem is mounted and provided with a file
      descriptor the fuse daemon created by opening /dev/fuse.
      
      For now restrict the communication of uids and gids between the fuse
      filesystem and the fuse daemon to the initial user namespace.  Enforce
      this by verifying the file descriptor passed to the mount of fuse was
      opened in the initial user namespace.  Ensuring the mount happens in
      the initial user namespace is not necessary as mounts from non-initial
      user namespaces are not yet allowed.
      
      In fuse_req_init_context convert the currrent fsuid and fsgid into the
      initial user namespace for the request that will be sent to the fuse
      daemon.
      
      In fuse_fill_attr convert the uid and gid passed from the fuse daemon
      from the initial user namespace into kuids and kgids.
      
      In iattr_to_fattr called from fuse_setattr convert kuids and kgids
      into the uids and gids in the initial user namespace before passing
      them to the fuse filesystem.
      
      In fuse_change_attributes_common called from fuse_dentry_revalidate,
      fuse_permission, fuse_geattr, and fuse_setattr, and fuse_iget convert
      the uid and gid from the fuse daemon into a kuid and a kgid to store
      on the fuse inode.
      
      By default fuse mounts are restricted to task whose uid, suid, and
      euid matches the fuse user_id and whose gid, sgid, and egid matches
      the fuse group id.  Convert the user_id and group_id mount options
      into kuids and kgids at mount time, and use uid_eq and gid_eq to
      compare the in fuse_allow_task.
      
      Cc: Miklos Szeredi <miklos@szeredi.hu>
      Acked-by: NSerge Hallyn <serge.hallyn@canonical.com>
      Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
      499dcf20
  19. 27 9月, 2012 1 次提交
  20. 05 9月, 2012 1 次提交
  21. 20 3月, 2012 1 次提交
  22. 13 12月, 2011 2 次提交
    • J
      FUSE: Notifying the kernel of deletion. · 451d0f59
      John Muir 提交于
      Allows a FUSE file-system to tell the kernel when a file or directory is
      deleted. If the specified dentry has the specified inode number, the kernel will
      unhash it.
      
      The current 'fuse_notify_inval_entry' does not cause the kernel to clean up
      directories that are in use properly, and as a result the users of those
      directories see incorrect semantics from the file-system. The error condition
      seen when 'fuse_notify_inval_entry' is used to notify of a deleted directory is
      avoided when 'fuse_notify_delete' is used instead.
      
      The following scenario demonstrates the difference:
      1. User A chdirs into 'testdir' and starts reading 'testfile'.
      2. User B rm -rf 'testdir'.
      3. User B creates 'testdir'.
      4. User C chdirs into 'testdir'.
      
      If you run the above within the same machine on any file-system (including fuse
      file-systems), there is no problem: user C is able to chdir into the new
      testdir. The old testdir is removed from the dentry tree, but still open by user
      A.
      
      If operations 2 and 3 are performed via the network such that the fuse
      file-system uses one of the notify functions to tell the kernel that the nodes
      are gone, then the following error occurs for user C while user A holds the
      original directory open:
      
      muirj@empacher:~> ls /test/testdir
      ls: cannot access /test/testdir: No such file or directory
      
      The issue here is that the kernel still has a dentry for testdir, and so it is
      requesting the attributes for the old directory, while the file-system is
      responding that the directory no longer exists.
      
      If on the other hand, if the file-system can notify the kernel that the
      directory is deleted using the new 'fuse_notify_delete' function, then the above
      ls will find the new directory as expected.
      Signed-off-by: NJohn Muir <john@jmuir.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      451d0f59
    • M
      fuse: fix fuse_retrieve · 48706d0a
      Miklos Szeredi 提交于
      Fix two bugs in fuse_retrieve():
      
       - retrieving more than one page would yield repeated instances of the
         first page
      
       - if more than FUSE_MAX_PAGES_PER_REQ pages were requested than the
         request page array would overflow
      
      fuse_retrieve() was added in 2.6.36 and these bugs had been there since the
      beginning.
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      CC: stable@vger.kernel.org
      48706d0a
  23. 13 9月, 2011 1 次提交
    • M
      fuse: fix memory leak · 5dfcc87f
      Miklos Szeredi 提交于
      kmemleak is reporting that 32 bytes are being leaked by FUSE:
      
        unreferenced object 0xe373b270 (size 32):
        comm "fusermount", pid 1207, jiffies 4294707026 (age 2675.187s)
        hex dump (first 32 bytes):
          01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        backtrace:
          [<b05517d7>] kmemleak_alloc+0x27/0x50
          [<b0196435>] kmem_cache_alloc+0xc5/0x180
          [<b02455be>] fuse_alloc_forget+0x1e/0x20
          [<b0245670>] fuse_alloc_inode+0xb0/0xd0
          [<b01b1a8c>] alloc_inode+0x1c/0x80
          [<b01b290f>] iget5_locked+0x8f/0x1a0
          [<b0246022>] fuse_iget+0x72/0x1a0
          [<b02461da>] fuse_get_root_inode+0x8a/0x90
          [<b02465cf>] fuse_fill_super+0x3ef/0x590
          [<b019e56f>] mount_nodev+0x3f/0x90
          [<b0244e95>] fuse_mount+0x15/0x20
          [<b019d1bc>] mount_fs+0x1c/0xc0
          [<b01b5811>] vfs_kern_mount+0x41/0x90
          [<b01b5af9>] do_kern_mount+0x39/0xd0
          [<b01b7585>] do_mount+0x2e5/0x660
          [<b01b7966>] sys_mount+0x66/0xa0
      
      This leak report is consistent and happens once per boot on
      3.1.0-rc5-dirty.
      
      This happens if a FORGET request is queued after the fuse device was
      released.
      Reported-by: NSitsofe Wheeler <sitsofe@yahoo.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Tested-by: NSitsofe Wheeler <sitsofe@yahoo.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      5dfcc87f
  24. 24 8月, 2011 1 次提交
  25. 23 3月, 2011 1 次提交
  26. 21 3月, 2011 1 次提交