1. 28 4月, 2014 6 次提交
  2. 02 4月, 2014 2 次提交
    • M
      fuse: Trust kernel i_mtime only · b0aa7606
      Maxim Patlasov 提交于
      Let the kernel maintain i_mtime locally:
       - clear S_NOCMTIME
       - implement i_op->update_time()
       - flush mtime on fsync and last close
       - update i_mtime explicitly on truncate and fallocate
      
      Fuse inode flag FUSE_I_MTIME_DIRTY serves as indication that local i_mtime
      should be flushed to the server eventually.
      Signed-off-by: NMaxim Patlasov <MPatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      b0aa7606
    • P
      fuse: Trust kernel i_size only · 8373200b
      Pavel Emelyanov 提交于
      Make fuse think that when writeback is on the inode's i_size is always
      up-to-date and not update it with the value received from the userspace.
      This is done because the page cache code may update i_size without letting
      the FS know.
      
      This assumption implies fixing the previously introduced short-read helper --
      when a short read occurs the 'hole' is filled with zeroes.
      
      fuse_file_fallocate() is also fixed because now we should keep i_size up to
      date, so it must be updated if FUSE_FALLOCATE request succeeded.
      Signed-off-by: NMaxim V. Patlasov <MPatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      8373200b
  3. 23 1月, 2014 1 次提交
  4. 25 10月, 2013 1 次提交
  5. 01 10月, 2013 3 次提交
  6. 13 9月, 2013 1 次提交
  7. 06 9月, 2013 3 次提交
  8. 03 9月, 2013 3 次提交
    • M
      fuse: readdir: check for slash in names · efeb9e60
      Miklos Szeredi 提交于
      Userspace can add names containing a slash character to the directory
      listing.  Don't allow this as it could cause all sorts of trouble.
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Cc: stable@vger.kernel.org
      efeb9e60
    • M
      fuse: hotfix truncate_pagecache() issue · 06a7c3c2
      Maxim Patlasov 提交于
      The way how fuse calls truncate_pagecache() from fuse_change_attributes()
      is completely wrong. Because, w/o i_mutex held, we never sure whether
      'oldsize' and 'attr->size' are valid by the time of execution of
      truncate_pagecache(inode, oldsize, attr->size). In fact, as soon as we
      released fc->lock in the middle of fuse_change_attributes(), we completely
      loose control of actions which may happen with given inode until we reach
      truncate_pagecache. The list of potentially dangerous actions includes
      mmap-ed reads and writes, ftruncate(2) and write(2) extending file size.
      
      The typical outcome of doing truncate_pagecache() with outdated arguments
      is data corruption from user point of view. This is (in some sense)
      acceptable in cases when the issue is triggered by a change of the file on
      the server (i.e. externally wrt fuse operation), but it is absolutely
      intolerable in scenarios when a single fuse client modifies a file without
      any external intervention. A real life case I discovered by fsx-linux
      looked like this:
      
      1. Shrinking ftruncate(2) comes to fuse_do_setattr(). The latter sends
      FUSE_SETATTR to the server synchronously, but before getting fc->lock ...
      2. fuse_dentry_revalidate() is asynchronously called. It sends FUSE_LOOKUP
      to the server synchronously, then calls fuse_change_attributes(). The
      latter updates i_size, releases fc->lock, but before comparing oldsize vs
      attr->size..
      3. fuse_do_setattr() from the first step proceeds by acquiring fc->lock and
      updating attributes and i_size, but now oldsize is equal to
      outarg.attr.size because i_size has just been updated (step 2). Hence,
      fuse_do_setattr() returns w/o calling truncate_pagecache().
      4. As soon as ftruncate(2) completes, the user extends file size by
      write(2) making a hole in the middle of file, then reads data from the hole
      either by read(2) or mmap-ed read. The user expects to get zero data from
      the hole, but gets stale data because truncate_pagecache() is not executed
      yet.
      
      The scenario above illustrates one side of the problem: not truncating the
      page cache even though we should. Another side corresponds to truncating
      page cache too late, when the state of inode changed significantly.
      Theoretically, the following is possible:
      
      1. As in the previous scenario fuse_dentry_revalidate() discovered that
      i_size changed (due to our own fuse_do_setattr()) and is going to call
      truncate_pagecache() for some 'new_size' it believes valid right now. But
      by the time that particular truncate_pagecache() is called ...
      2. fuse_do_setattr() returns (either having called truncate_pagecache() or
      not -- it doesn't matter).
      3. The file is extended either by write(2) or ftruncate(2) or fallocate(2).
      4. mmap-ed write makes a page in the extended region dirty.
      
      The result will be the lost of data user wrote on the fourth step.
      
      The patch is a hotfix resolving the issue in a simplistic way: let's skip
      dangerous i_size update and truncate_pagecache if an operation changing
      file size is in progress. This simplistic approach looks correct for the
      cases w/o external changes. And to handle them properly, more sophisticated
      and intrusive techniques (e.g. NFS-like one) would be required. I'd like to
      postpone it until the issue is well discussed on the mailing list(s).
      
      Changed in v2:
       - improved patch description to cover both sides of the issue.
      Signed-off-by: NMaxim Patlasov <mpatlasov@parallels.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Cc: stable@vger.kernel.org
      06a7c3c2
    • A
      fuse: invalidate inode attributes on xattr modification · d331a415
      Anand Avati 提交于
      Calls like setxattr and removexattr result in updation of ctime.
      Therefore invalidate inode attributes to force a refresh.
      Signed-off-by: NAnand Avati <avati@redhat.com>
      Reviewed-by: NBrian Foster <bfoster@redhat.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      Cc: stable@vger.kernel.org
      d331a415
  9. 17 7月, 2013 5 次提交
  10. 29 6月, 2013 1 次提交
  11. 03 6月, 2013 1 次提交
    • M
      fuse: fix readdirplus Oops in fuse_dentry_revalidate · 28420dad
      Miklos Szeredi 提交于
      Fix bug introduced by commit 4582a4ab "FUSE: Adapt readdirplus to application
      usage patterns".
      
      We need to check for a positive dentry; negative dentries are not added by
      readdirplus.  Secondly we need to advise the use of readdirplus on the *parent*,
      otherwise the whole thing is useless.  Thirdly all this is only relevant if
      "readdirplus_auto" mode is selected by the filesystem.
      
      We advise the use of readdirplus only if the dentry was still valid.  If we had
      to redo the lookup then there was no use in doing the -plus version.
      Reported-by: NBernd Schubert <bernd.schubert@itwm.fraunhofer.de>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      CC: Feng Shuo <steve.shuo.feng@gmail.com>
      CC: stable@vger.kernel.org
      28420dad
  12. 18 4月, 2013 1 次提交
  13. 23 2月, 2013 1 次提交
  14. 07 2月, 2013 1 次提交
    • E
      fuse: allow control of adaptive readdirplus use · 634734b6
      Eric Wong 提交于
      For some filesystems (e.g. GlusterFS), the cost of performing a
      normal readdir and readdirplus are identical.  Since adaptively
      using readdirplus has no benefit for those systems, give
      users/filesystems the option to control adaptive readdirplus use.
      
      v2 of this patch incorporates Miklos's suggestion to simplify the code,
      as well as improving consistency of macro names and documentation.
      Signed-off-by: NEric Wong <normalperson@yhbt.net>
      Signed-off-by: NMiklos Szeredi <mszeredi@suse.cz>
      634734b6
  15. 04 2月, 2013 1 次提交
  16. 01 2月, 2013 2 次提交
  17. 24 1月, 2013 3 次提交
    • 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: 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
    • 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
  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. 15 8月, 2012 1 次提交
  20. 14 7月, 2012 2 次提交