25 Jan, 2021

1 commit


09 Jan, 2021

1 commit

  • [ Upstream commit 5d069dbe8aaf2a197142558b6fb2978189ba3454 ]

    Jan Kara's analysis of the syzbot report (edited):

    The reproducer opens a directory on FUSE filesystem, it then attaches
    dnotify mark to the open directory. After that a fuse_do_getattr() call
    finds that attributes returned by the server are inconsistent, and calls
    make_bad_inode() which, among other things does:

    inode->i_mode = S_IFREG;

    This then confuses dnotify which doesn't tear down its structures
    properly and eventually crashes.

    Avoid calling make_bad_inode() on a live inode: switch to a private flag on
    the fuse inode. Also add the test to ops which the bad_inode_ops would
    have caught.

    This bug goes back to the initial merge of fuse in 2.6.14...

    Reported-by: syzbot+f427adf9324b92652ccc@syzkaller.appspotmail.com
    Signed-off-by: Miklos Szeredi
    Tested-by: Jan Kara
    Cc:
    Signed-off-by: Sasha Levin

    Miklos Szeredi
     

03 Nov, 2020

2 commits

  • All the read and write operations performed on fuse_files which have the
    passthrough feature enabled are forwarded to the associated lower file
    system file via VFS.

    Sending the request directly to the lower file system avoids the userspace
    round-trip that, because of possible context switches and additional
    operations might reduce the overall performance, especially in those cases
    where caching doesn't help, for example in reads at random offsets.

    Verifying if a fuse_file has a lower file system file associated with can
    be done by checking the validity of its passthrough_filp pointer. This
    pointer is not NULL only if passthrough has been successfully enabled via
    the appropriate ioctl().
    When a read/write operation is requested for a FUSE file with passthrough
    enabled, a new equivalent VFS request is generated, which instead targets
    the lower file system file.
    The VFS layer performs additional checks that allow for safer operations
    but may cause the operation to fail if the process accessing the FUSE file
    system does not have access to the lower file system.

    This change only implements synchronous requests in passthrough, returning
    an error in the case of asynchronous operations, yet covering the majority
    of the use cases.

    Bug: 168023149
    Link: https://lore.kernel.org/lkml/20201026125016.1905945-4-balsini@android.com/
    Signed-off-by: Alessio Balsini
    Signed-off-by: Alessio Balsini
    Change-Id: If76bb8725e1ac567f9dbe3edb79ebb4d43d77dfb

    Alessio Balsini
     
  • Expose the FUSE_PASSTHROUGH interface to userspace and declare all the
    basic data structures and functions as the skeleton on top of which the
    FUSE passthrough functionality will be built.

    As part of this, introduce the new FUSE passthrough ioctl(), which
    allows
    the FUSE daemon to specify a direct connection between a FUSE file and a
    lower file system file. Such ioctl() requires userspace to pass the file
    descriptor of one of its opened files through the fuse_passthrough_out
    data
    structure introduced in this patch. This structure includes extra fields
    for possible future extensions.
    Also, add the passthrough functions for the set-up and tear-down of the
    data structures and locks that will be used both when fuse_conns and
    fuse_files are created/deleted.

    Bug: 168023149
    Link: https://lore.kernel.org/lkml/20201026125016.1905945-2-balsini@android.com/
    Signed-off-by: Alessio Balsini
    Signed-off-by: Alessio Balsini
    Change-Id: I6dd150b93607e10ed53f7e7975b35b6090080fa2

    Alessio Balsini
     

20 Oct, 2020

1 commit

  • Pull fuse updates from Miklos Szeredi:

    - Support directly accessing host page cache from virtiofs. This can
    improve I/O performance for various workloads, as well as reducing
    the memory requirement by eliminating double caching. Thanks to Vivek
    Goyal for doing most of the work on this.

    - Allow automatic submounting inside virtiofs. This allows unique
    st_dev/ st_ino values to be assigned inside the guest to files
    residing on different filesystems on the host. Thanks to Max Reitz
    for the patches.

    - Fix an old use after free bug found by Pradeep P V K.

    * tag 'fuse-update-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (25 commits)
    virtiofs: calculate number of scatter-gather elements accurately
    fuse: connection remove fix
    fuse: implement crossmounts
    fuse: Allow fuse_fill_super_common() for submounts
    fuse: split fuse_mount off of fuse_conn
    fuse: drop fuse_conn parameter where possible
    fuse: store fuse_conn in fuse_req
    fuse: add submount support to
    fuse: fix page dereference after free
    virtiofs: add logic to free up a memory range
    virtiofs: maintain a list of busy elements
    virtiofs: serialize truncate/punch_hole and dax fault path
    virtiofs: define dax address space operations
    virtiofs: add DAX mmap support
    virtiofs: implement dax read/write operations
    virtiofs: introduce setupmapping/removemapping commands
    virtiofs: implement FUSE_INIT map_alignment field
    virtiofs: keep a list of free dax memory ranges
    virtiofs: add a mount option to enable dax
    virtiofs: set up virtio_fs dax_device
    ...

    Linus Torvalds
     

18 Sep, 2020

2 commits

  • We want to allow submounts for the same fuse_conn, but with different
    superblocks so that each of the submounts has its own device ID. To do
    so, we need to split all mount-specific information off of fuse_conn
    into a new fuse_mount structure, so that multiple mounts can share a
    single fuse_conn.

    We need to take care only to perform connection-level actions once (i.e.
    when the fuse_conn and thus the first fuse_mount are established, or
    when the last fuse_mount and thus the fuse_conn are destroyed). For
    example, fuse_sb_destroy() must invoke fuse_send_destroy() until the
    last superblock is released.

    To do so, we keep track of which fuse_mount is the root mount and
    perform all fuse_conn-level actions only when this fuse_mount is
    involved.

    Signed-off-by: Max Reitz
    Reviewed-by: Stefan Hajnoczi
    Signed-off-by: Miklos Szeredi

    Max Reitz
     
  • the callers rely upon having any iov_iter_truncate() done inside
    ->direct_IO() countered by iov_iter_reexpand().

    Reported-by: Qian Cai
    Tested-by: Qian Cai
    Signed-off-by: Al Viro

    Al Viro
     

10 Sep, 2020

3 commits

  • Currently in fuse we don't seem have any lock which can serialize fault
    path with truncate/punch_hole path. With dax support I need one for
    following reasons.

    1. Dax requirement

    DAX fault code relies on inode size being stable for the duration of
    fault and want to serialize with truncate/punch_hole and they explicitly
    mention it.

    static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
    const struct iomap_ops *ops)
    /*
    * Check whether offset isn't beyond end of file now. Caller is
    * supposed to hold locks serializing us with truncate / punch hole so
    * this is a reliable test.
    */
    max_pgoff = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);

    2. Make sure there are no users of pages being truncated/punch_hole

    get_user_pages() might take references to page and then do some DMA
    to said pages. Filesystem might truncate those pages without knowing
    that a DMA is in progress or some I/O is in progress. So use
    dax_layout_busy_page() to make sure there are no such references
    and I/O is not in progress on said pages before moving ahead with
    truncation.

    3. Limitation of kvm page fault error reporting

    If we are truncating file on host first and then removing mappings in
    guest lateter (truncate page cache etc), then this could lead to a
    problem with KVM. Say a mapping is in place in guest and truncation
    happens on host. Now if guest accesses that mapping, then host will
    take a fault and kvm will either exit to qemu or spin infinitely.

    IOW, before we do truncation on host, we need to make sure that guest
    inode does not have any mapping in that region or whole file.

    4. virtiofs memory range reclaim

    Soon I will introduce the notion of being able to reclaim dax memory
    ranges from a fuse dax inode. There also I need to make sure that
    no I/O or fault is going on in the reclaimed range and nobody is using
    it so that range can be reclaimed without issues.

    Currently if we take inode lock, that serializes read/write. But it does
    not do anything for faults. So I add another semaphore fuse_inode->i_mmap_sem
    for this purpose. It can be used to serialize with faults.

    As of now, I am adding taking this semaphore only in dax fault path and
    not regular fault path because existing code does not have one. May
    be existing code can benefit from it as well to take care of some
    races, but that we can fix later if need be. For now, I am just focussing
    only on DAX path which is new path.

    Also added logic to take fuse_inode->i_mmap_sem in
    truncate/punch_hole/open(O_TRUNC) path to make sure file truncation and
    fuse dax fault are mutually exlusive and avoid all the above problems.

    Signed-off-by: Vivek Goyal
    Cc: Dave Chinner
    Signed-off-by: Miklos Szeredi

    Vivek Goyal
     
  • Add DAX mmap() support.

    Signed-off-by: Stefan Hajnoczi
    Signed-off-by: Miklos Szeredi

    Stefan Hajnoczi
     
  • This patch implements basic DAX support. mmap() is not implemented
    yet and will come in later patches. This patch looks into implemeting
    read/write.

    We make use of interval tree to keep track of per inode dax mappings.

    Do not use dax for file extending writes, instead just send WRITE message
    to daemon (like we do for direct I/O path). This will keep write and
    i_size change atomic w.r.t crash.

    Signed-off-by: Stefan Hajnoczi
    Signed-off-by: Dr. David Alan Gilbert
    Signed-off-by: Vivek Goyal
    Signed-off-by: Liu Bo
    Signed-off-by: Peng Tao
    Cc: Dave Chinner
    Signed-off-by: Miklos Szeredi

    Vivek Goyal
     

05 Aug, 2020

1 commit

  • Pull uninitialized_var() macro removal from Kees Cook:
    "This is long overdue, and has hidden too many bugs over the years. The
    series has several "by hand" fixes, and then a trivial treewide
    replacement.

    - Clean up non-trivial uses of uninitialized_var()

    - Update documentation and checkpatch for uninitialized_var() removal

    - Treewide removal of uninitialized_var()"

    * tag 'uninit-macro-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
    compiler: Remove uninitialized_var() macro
    treewide: Remove uninitialized_var() usage
    checkpatch: Remove awareness of uninitialized_var() macro
    mm/debug_vm_pgtable: Remove uninitialized_var() usage
    f2fs: Eliminate usage of uninitialized_var() macro
    media: sur40: Remove uninitialized_var() usage
    KVM: PPC: Book3S PR: Remove uninitialized_var() usage
    clk: spear: Remove uninitialized_var() usage
    clk: st: Remove uninitialized_var() usage
    spi: davinci: Remove uninitialized_var() usage
    ide: Remove uninitialized_var() usage
    rtlwifi: rtl8192cu: Remove uninitialized_var() usage
    b43: Remove uninitialized_var() usage
    drbd: Remove uninitialized_var() usage
    x86/mm/numa: Remove uninitialized_var() usage
    docs: deprecated.rst: Add uninitialized_var()

    Linus Torvalds
     

17 Jul, 2020

1 commit

  • Using uninitialized_var() is dangerous as it papers over real bugs[1]
    (or can in the future), and suppresses unrelated compiler warnings
    (e.g. "unused variable"). If the compiler thinks it is uninitialized,
    either simply initialize the variable or make compiler changes.

    In preparation for removing[2] the[3] macro[4], remove all remaining
    needless uses with the following script:

    git grep '\buninitialized_var\b' | cut -d: -f1 | sort -u | \
    xargs perl -pi -e \
    's/\buninitialized_var\(([^\)]+)\)/\1/g;
    s:\s*/\* (GCC be quiet|to make compiler happy) \*/$::g;'

    drivers/video/fbdev/riva/riva_hw.c was manually tweaked to avoid
    pathological white-space.

    No outstanding warnings were found building allmodconfig with GCC 9.3.0
    for x86_64, i386, arm64, arm, powerpc, powerpc64le, s390x, mips, sparc64,
    alpha, and m68k.

    [1] https://lore.kernel.org/lkml/20200603174714.192027-1-glider@google.com/
    [2] https://lore.kernel.org/lkml/CA+55aFw+Vbj0i=1TGqCR5vQkCzWJ0QxK6CernOU6eedsudAixw@mail.gmail.com/
    [3] https://lore.kernel.org/lkml/CA+55aFwgbgqhbp1fkxvRKEpzyR5J8n1vKT1VZdz9knmPuXhOeg@mail.gmail.com/
    [4] https://lore.kernel.org/lkml/CA+55aFz2500WfbKXAx8s67wrm9=yVJu65TpLgN_ybYNv0VEOKA@mail.gmail.com/

    Reviewed-by: Leon Romanovsky # drivers/infiniband and mlx4/mlx5
    Acked-by: Jason Gunthorpe # IB
    Acked-by: Kalle Valo # wireless drivers
    Reviewed-by: Chao Yu # erofs
    Signed-off-by: Kees Cook

    Kees Cook
     

15 Jul, 2020

1 commit

  • The ioctl encoding for this parameter is a long but the documentation says
    it should be an int and the kernel drivers expect it to be an int. If the
    fuse driver treats this as a long it might end up scribbling over the stack
    of a userspace process that only allocated enough space for an int.

    This was previously discussed in [1] and a patch for fuse was proposed in
    [2]. From what I can tell the patch in [2] was nacked in favor of adding
    new, "fixed" ioctls and using those from userspace. However there is still
    no "fixed" version of these ioctls and the fact is that it's sometimes
    infeasible to change all userspace to use the new one.

    Handling the ioctls specially in the fuse driver seems like the most
    pragmatic way for fuse servers to support them without causing crashes in
    userspace applications that call them.

    [1]: https://lore.kernel.org/linux-fsdevel/20131126200559.GH20559@hall.aurel32.net/T/
    [2]: https://sourceforge.net/p/fuse/mailman/message/31771759/

    Signed-off-by: Chirantan Ekbote
    Fixes: 59efec7b9039 ("fuse: implement ioctl support")
    Cc:
    Signed-off-by: Miklos Szeredi

    Chirantan Ekbote
     

14 Jul, 2020

4 commits

  • fuse_writepages() ignores some errors taken from fuse_writepages_fill() I
    believe it is a bug: if .writepages is called with WB_SYNC_ALL it should
    either guarantee that all data was successfully saved or return error.

    Fixes: 26d614df1da9 ("fuse: Implement writepages callback")
    Signed-off-by: Vasily Averin
    Signed-off-by: Miklos Szeredi

    Vasily Averin
     
  • fuse_writepages_fill uses following construction:

    if (wpa && ap->num_pages &&
    (A || B || C)) {
    action;
    } else if (wpa && D) {
    if (E) {
    the same action;
    }
    }

    - ap->num_pages check is always true and can be removed

    - "if" and "else if" calls the same action and can be merged.

    Move checking A, B, C, D, E conditions to a helper, add comments.

    Original-patch-by: Vasily Averin
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • fuse_writepages_fill() calls tree_insert() with ap->num_pages = 0 which
    triggers the following warning:

    WARNING: CPU: 1 PID: 17211 at fs/fuse/file.c:1728 tree_insert+0xab/0xc0 [fuse]
    RIP: 0010:tree_insert+0xab/0xc0 [fuse]
    Call Trace:
    fuse_writepages_fill+0x5da/0x6a0 [fuse]
    write_cache_pages+0x171/0x470
    fuse_writepages+0x8a/0x100 [fuse]
    do_writepages+0x43/0xe0

    Fix up the warning and clean up the code around rb-tree insertion:

    - Rename tree_insert() to fuse_insert_writeback() and make it return the
    conflicting entry in case of failure

    - Re-add tree_insert() as a wrapper around fuse_insert_writeback()

    - Rename fuse_writepage_in_flight() to fuse_writepage_add() and reverse
    the meaning of the return value to mean

    + "true" in case the writepage entry was successfully added

    + "false" in case it was in-fligt queued on an existing writepage
    entry's auxiliary list or the existing writepage entry's temporary
    page updated

    Switch from fuse_find_writeback() + tree_insert() to
    fuse_insert_writeback()

    - Move setting orig_pages to before inserting/updating the entry; this may
    result in the orig_pages value being discarded later in case of an
    in-flight request

    - In case of a new writepage entry use fuse_writepage_add()
    unconditionally, only set data->wpa if the entry was added.

    Fixes: 6b2fb79963fb ("fuse: optimize writepages search")
    Reported-by: kernel test robot
    Original-path-by: Vasily Averin
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • In fuse_writepage_end() the old writepages entry needs to be removed from
    the rbtree before inserting the new one, otherwise tree_insert() would
    fail. This is a very rare codepath and no reproducer exists.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

10 Jun, 2020

1 commit

  • Pull fuse updates from Miklos Szeredi:

    - Fix a rare deadlock in virtiofs

    - Fix st_blocks in writeback cache mode

    - Fix wrong checks in splice move causing spurious warnings

    - Fix a race between a GETATTR request and a FUSE_NOTIFY_INVAL_INODE
    notification

    - Use rb-tree instead of linear search for pages currently under
    writeout by userspace

    - Fix copy_file_range() inconsistencies

    * tag 'fuse-update-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
    fuse: copy_file_range should truncate cache
    fuse: fix copy_file_range cache issues
    fuse: optimize writepages search
    fuse: update attr_version counter on fuse_notify_inval_inode()
    fuse: don't check refcount after stealing page
    fuse: fix weird page warning
    fuse: use dump_page
    virtiofs: do not use fuse_fill_super_common() for device installation
    fuse: always allow query of st_dev
    fuse: always flush dirty data on close(2)
    fuse: invalidate inode attr in writeback cache mode
    fuse: Update stale comment in queue_interrupt()
    fuse: BUG_ON correction in fuse_dev_splice_write()
    virtiofs: Add mount option and atime behavior to the doc
    virtiofs: schedule blocking async replies in separate worker

    Linus Torvalds
     

03 Jun, 2020

1 commit

  • Implement the new readahead operation in fuse by using __readahead_batch()
    to fill the array of pages in fuse_args_pages directly. This lets us
    inline fuse_readpages_fill() into fuse_readahead().

    [willy@infradead.org: build fix]
    Link: http://lkml.kernel.org/r/20200415025938.GB5820@bombadil.infradead.org
    Signed-off-by: Matthew Wilcox (Oracle)
    Signed-off-by: Andrew Morton
    Reviewed-by: Dave Chinner
    Reviewed-by: William Kucharski
    Acked-by: Miklos Szeredi
    Cc: Chao Yu
    Cc: Christoph Hellwig
    Cc: Cong Wang
    Cc: Darrick J. Wong
    Cc: Eric Biggers
    Cc: Gao Xiang
    Cc: Jaegeuk Kim
    Cc: John Hubbard
    Cc: Joseph Qi
    Cc: Junxiao Bi
    Cc: Michal Hocko
    Cc: Zi Yan
    Cc: Johannes Thumshirn
    Link: http://lkml.kernel.org/r/20200414150233.24495-25-willy@infradead.org
    Signed-off-by: Linus Torvalds

    Matthew Wilcox (Oracle)
     

20 May, 2020

2 commits

  • After the copy operation completes the cache is not up-to-date. Truncate
    all pages in the interval that has successfully been copied.

    Truncating completely copied dirty pages is okay, since the data has been
    overwritten anyway. Truncating partially copied dirty pages is not okay;
    add a comment for now.

    Fixes: 88bc7d5097a1 ("fuse: add support for copy_file_range()")
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • a) Dirty cache needs to be written back not just in the writeback_cache
    case, since the dirty pages may come from memory maps.

    b) The fuse_writeback_range() helper takes an inclusive interval, so the
    end position needs to be pos+len-1 instead of pos+len.

    Fixes: 88bc7d5097a1 ("fuse: add support for copy_file_range()")
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

19 May, 2020

3 commits

  • Re-work fi->writepages, replacing list with rb-tree. This improves
    performance because kernel fuse iterates through fi->writepages for each
    writeback page and typical number of entries is about 800 (for 100MB of
    fuse writeback).

    Before patch:

    10240+0 records in
    10240+0 records out
    10737418240 bytes (11 GB) copied, 41.3473 s, 260 MB/s

    2 1 0 57445400 40416 6323676 0 0 33 374743 8633 19210 1 8 88 3 0

    29.86% [kernel] [k] _raw_spin_lock
    26.62% [fuse] [k] fuse_page_is_writeback

    After patch:

    10240+0 records in
    10240+0 records out
    10737418240 bytes (11 GB) copied, 21.4954 s, 500 MB/s

    2 9 0 53676040 31744 10265984 0 0 64 854790 10956 48387 1 6 88 6 0

    23.55% [kernel] [k] copy_user_enhanced_fast_string
    9.87% [kernel] [k] __memcpy
    3.10% [kernel] [k] _raw_spin_lock

    Signed-off-by: Maxim Patlasov
    Signed-off-by: Vasily Averin
    Signed-off-by: Miklos Szeredi

    Maxim Patlasov
     
  • We want cached data to synced with the userspace filesystem on close(), for
    example to allow getting correct st_blocks value. Do this regardless of
    whether the userspace filesystem implements a FLUSH method or not.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Under writeback mode, inode->i_blocks is not updated, making utils du
    read st.blocks as 0.

    For example, when using virtiofs (cache=always & nondax mode) with
    writeback_cache enabled, writing a new file and check its disk usage
    with du, du reports 0 usage.

    # uname -r
    5.6.0-rc6+
    # mount -t virtiofs virtiofs /mnt/virtiofs
    # rm -f /mnt/virtiofs/testfile

    # create new file and do extend write
    # xfs_io -fc "pwrite 0 4k" /mnt/virtiofs/testfile
    wrote 4096/4096 bytes at offset 0
    4 KiB, 1 ops; 0.0001 sec (28.103 MiB/sec and 7194.2446 ops/sec)
    # du -k /mnt/virtiofs/testfile
    0
    Signed-off-by: Miklos Szeredi

    Eryu Guan
     

20 Apr, 2020

1 commit

  • In virtiofs (unlike in regular fuse) processing of async replies is
    serialized. This can result in a deadlock in rare corner cases when
    there's a circular dependency between the completion of two or more async
    replies.

    Such a deadlock can be reproduced with xfstests:generic/503 if TEST_DIR ==
    SCRATCH_MNT (which is a misconfiguration):

    - Process A is waiting for page lock in worker thread context and blocked
    (virtio_fs_requests_done_work()).
    - Process B is holding page lock and waiting for pending writes to
    finish (fuse_wait_on_page_writeback()).
    - Write requests are waiting in virtqueue and can't complete because
    worker thread is blocked on page lock (process A).

    Fix this by creating a unique work_struct for each async reply that can
    block (O_DIRECT read).

    Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
    Signed-off-by: Vivek Goyal
    Signed-off-by: Miklos Szeredi

    Vivek Goyal
     

06 Feb, 2020

3 commits

  • Fixes coccicheck warning:

    fs/fuse/readdir.c:335:1-19: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/file.c:1398:2-19: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/file.c:1400:2-20: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/cuse.c:454:1-20: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/cuse.c:455:1-19: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:497:2-17: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:504:2-23: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:511:2-22: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:518:2-23: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:522:2-26: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:526:2-18: WARNING: Assignment of 0/1 to bool variable
    fs/fuse/inode.c:1000:1-20: WARNING: Assignment of 0/1 to bool variable

    Reported-by: Hulk Robot
    Signed-off-by: zhengbin
    Signed-off-by: Miklos Szeredi

    zhengbin
     
  • Handle the special case of fuse_readpages() wanting to read the last page
    of a hugest file possible and overflowing the end offset in the process.

    This is basically to unbreak xfstests:generic/525 and prevent filesystems
    from doing bad things with an overflowing offset.

    Reported-by: Xiao Yang
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • fuse_direct_io() can end up advancing the iterator by more than the amount
    of data read or written. This case is handled by the generic code if going
    through ->direct_IO(), but not in the FOPEN_DIRECT_IO case.

    Fix by reverting the extra bytes from the iterator in case of error or a
    short count.

    To test: install lxcfs, then the following testcase
    int fd = open("/var/lib/lxcfs/proc/uptime", O_RDONLY);
    sendfile(1, fd, NULL, 16777216);
    sendfile(1, fd, NULL, 16777216);
    will spew WARN_ON() in iov_iter_pipe().

    Reported-by: Peter Geis
    Reported-by: Al Viro
    Fixes: 3c3db095b68c ("fuse: use iov_iter based generic splice helpers")
    Cc: # v5.1
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

16 Jan, 2020

1 commit

  • Buffered read in fuse normally goes via:

    -> generic_file_buffered_read()
    -> fuse_readpages()
    -> fuse_send_readpages()
    ->fuse_simple_request() [called since v5.4]

    In the case of a read request, fuse_simple_request() will return a
    non-negative bytecount on success or a negative error value. A positive
    bytecount was taken to be an error and the PG_error flag set on the page.
    This resulted in generic_file_buffered_read() falling back to ->readpage(),
    which would repeat the read request and succeed. Because of the repeated
    read succeeding the bug was not detected with regression tests or other use
    cases.

    The FTP module in GVFS however fails the second read due to the
    non-seekable nature of FTP downloads.

    Fix by checking and ignoring positive return value from
    fuse_simple_request().

    Reported-by: Ondrej Holy
    Link: https://gitlab.gnome.org/GNOME/gvfs/issues/441
    Fixes: 134831e36bbd ("fuse: convert readpages to simple api")
    Cc: # v5.4
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

27 Nov, 2019

1 commit

  • exit_aio() is sometimes stuck in wait_for_completion() after aio is issued
    with direct IO and the task receives a signal.

    The reason is failure to call ->ki_complete() due to a leaked reference to
    fuse_io_priv. This happens in fuse_async_req_send() if
    fuse_simple_background() returns an error (e.g. -EINTR).

    In this case the error value is propagated via io->err, so return success
    to not confuse callers.

    This issue is tracked as a virtio-fs issue:
    https://gitlab.com/virtio-fs/qemu/issues/14

    Reported-by: Masayoshi Mizuma
    Fixes: 45ac96ed7c36 ("fuse: convert direct_io to simple api")
    Cc: # v5.4
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

12 Nov, 2019

1 commit


23 Oct, 2019

2 commits


24 Sep, 2019

2 commits


10 Sep, 2019

5 commits

  • Page arrays are not allocated together with the request anymore. Get rid
    of the dead code

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Since we cannot reserve the request structure up-front, make sure that the
    request allocation doesn't fail using __GFP_NOFAIL.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Derive fuse_writepage_args from fuse_io_args.

    Sending the request is tricky since it was done with fi->lock held, hence
    we must either use atomic allocation or release the lock. Both are
    possible so try atomic first and if it fails, release the lock and do the
    regular allocation with GFP_NOFS and __GFP_NOFAIL. Both flags are
    necessary for correct operation.

    Move the page realloc function from dev.c to file.c and convert to using
    fuse_writepage_args.

    The last caller of fuse_write_fill() is gone, so get rid of it.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • The old fuse_read_fill() helper can be deleted, now that the last user is
    gone.

    The fuse_io_args struct is moved to fuse_i.h so it can be shared between
    readdir/read code.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Need to extend fuse_io_args with 'attr_ver' and 'ff' members, that take the
    functionality of the same named members in fuse_req.

    fuse_short_read() can now take struct fuse_args_pages.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi