1. 13 Dec, 2019 19 commits
    • Anand Jain's avatar
      btrfs: send: remove WARN_ON for readonly mount · fbd54297
      Anand Jain authored
      We log warning if root::orphan_cleanup_state is not set to
      ORPHAN_CLEANUP_DONE in btrfs_ioctl_send(). However if the filesystem is
      mounted as readonly we skip the orphan item cleanup during the lookup
      and root::orphan_cleanup_state remains at the init state 0 instead of
      ORPHAN_CLEANUP_DONE (2). So during send in btrfs_ioctl_send() we hit the
      warning as below.
      
        WARN_ON(send_root->orphan_cleanup_state != ORPHAN_CLEANUP_DONE);
      
      WARNING: CPU: 0 PID: 2616 at /Volumes/ws/btrfs-devel/fs/btrfs/send.c:7090 btrfs_ioctl_send+0xb2f/0x18c0 [btrfs]
      ::
      RIP: 0010:btrfs_ioctl_send+0xb2f/0x18c0 [btrfs]
      ::
      Call Trace:
      ::
      _btrfs_ioctl_send+0x7b/0x110 [btrfs]
      btrfs_ioctl+0x150a/0x2b00 [btrfs]
      ::
      do_vfs_ioctl+0xa9/0x620
      ? __fget+0xac/0xe0
      ksys_ioctl+0x60/0x90
      __x64_sys_ioctl+0x16/0x20
      do_syscall_64+0x49/0x130
      entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      Reproducer:
        mkfs.btrfs -fq /dev/sdb
        mount /dev/sdb /btrfs
        btrfs subvolume create /btrfs/sv1
        btrfs subvolume snapshot -r /btrfs/sv1 /btrfs/ss1
        umount /btrfs
        mount -o ro /dev/sdb /btrfs
        btrfs send /btrfs/ss1 -f /tmp/f
      
      The warning exists because having orphan inodes could confuse send and
      cause it to fail or produce incorrect streams.  The two cases that would
      cause such send failures, which are already fixed are:
      
      1) Inodes that were unlinked - these are orphanized and remain with a
         link count of 0. These caused send operations to fail because it
         expected to always find at least one path for an inode. However this
         is no longer a problem since send is now able to deal with such
         inodes since commit 46b2f459 ("Btrfs: fix send failure when root
         has deleted files still open") and treats them as having been
         completely removed (the state after an orphan cleanup is performed).
      
      2) Inodes that were in the process of being truncated. These resulted in
         send not knowing about the truncation and potentially issue write
         operations full of zeroes for the range from the new file size to the
         old file size. This is no longer a problem because we no longer
         create orphan items for truncation since commit f7e9e8fc
      
       ("Btrfs:
         stop creating orphan items for truncate").
      
      As such before these commits, the WARN_ON here provided a clue in case
      something went wrong. Instead of being a warning against the
      root::orphan_cleanup_state value, it could have been more accurate by
      checking if there were actually any orphan items, and then issue a
      warning only if any exists, but that would be more expensive to check.
      Since orphanized inodes no longer cause problems for send, just remove
      the warning.
      
      Reported-by: default avatarChristoph Anton Mitterer <calestyo@scientia.net>
      Link: https://lore.kernel.org/linux-btrfs/21cb5e8d059f6e1496a903fa7bfc0a297e2f5370.camel@scientia.net/
      
      
      CC: stable@vger.kernel.org # 4.19+
      Suggested-by: default avatarFilipe Manana <fdmanana@suse.com>
      Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarAnand Jain <anand.jain@oracle.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      fbd54297
    • Josef Bacik's avatar
      btrfs: do not leak reloc root if we fail to read the fs root · ca1aa281
      Josef Bacik authored
      
      
      If we fail to read the fs root corresponding with a reloc root we'll
      just break out and free the reloc roots.  But we remove our current
      reloc_root from this list higher up, which means we'll leak this
      reloc_root.  Fix this by adding ourselves back to the reloc_roots list
      so we are properly cleaned up.
      
      CC: stable@vger.kernel.org # 4.4+
      Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
      Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      ca1aa281
    • Josef Bacik's avatar
      btrfs: skip log replay on orphaned roots · 9bc574de
      Josef Bacik authored
      
      
      My fsstress modifications coupled with generic/475 uncovered a failure
      to mount and replay the log if we hit a orphaned root.  We do not want
      to replay the log for an orphan root, but it's completely legitimate to
      have an orphaned root with a log attached.  Fix this by simply skipping
      replaying the log.  We still need to pin it's root node so that we do
      not overwrite it while replaying other logs, as we re-read the log root
      at every stage of the replay.
      
      CC: stable@vger.kernel.org # 4.4+
      Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      9bc574de
    • Josef Bacik's avatar
      btrfs: handle ENOENT in btrfs_uuid_tree_iterate · 714cd3e8
      Josef Bacik authored
      
      
      If we get an -ENOENT back from btrfs_uuid_iter_rem when iterating the
      uuid tree we'll just continue and do btrfs_next_item().  However we've
      done a btrfs_release_path() at this point and no longer have a valid
      path.  So increment the key and go back and do a normal search.
      
      CC: stable@vger.kernel.org # 4.4+
      Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
      Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      714cd3e8
    • Josef Bacik's avatar
      btrfs: abort transaction after failed inode updates in create_subvol · c7e54b51
      Josef Bacik authored
      
      
      We can just abort the transaction here, and in fact do that for every
      other failure in this function except these two cases.
      
      CC: stable@vger.kernel.org # 4.4+
      Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
      Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      c7e54b51
    • Filipe Manana's avatar
      Btrfs: fix hole extent items with a zero size after range cloning · 147271e3
      Filipe Manana authored
      Normally when cloning a file range if we find an implicit hole at the end
      of the range we assume it is because the NO_HOLES feature is enabled.
      However that is not always the case. One well known case [1] is when we
      have a power failure after mixing buffered and direct IO writes against
      the same file.
      
      In such cases we need to punch a hole in the destination file, and if
      the NO_HOLES feature is not enabled, we need to insert explicit file
      extent items to represent the hole. After commit 690a5dbf
      ("Btrfs: fix ENOSPC errors, leading to transaction aborts, when cloning
      extents"), we started to insert file extent items representing the hole
      with an item size of 0, which is invalid and should be 53 bytes (the size
      of a btrfs_file_extent_item structure), resulting in all sorts of
      corruptions and invalid memory accesses. This is detected by the tree
      checker when we attempt to write a leaf to disk.
      
      The problem can be sporadically triggered by test case generic/561 from
      fstests. That test case does not exercise power failure and creates a new
      filesystem when it starts, so it does not use a filesystem created by any
      previous test that tests power failure. However the test does both
      buffered and direct IO writes (through fsstress) and it's precisely that
      which is creating the implicit holes in files. That happens even before
      the commit mentioned earlier. I need to investigate why we get those
      implicit holes to check if there is a real problem or not. For now this
      change fixes the regression of introducing file extent items with an item
      size of 0 bytes.
      
      Fix the issue by calling btrfs_punch_hole_range() without passing a
      btrfs_clone_extent_info structure, which ensures file extent items are
      inserted to represent the hole with a correct item size. We were passing
      a btrfs_clone_extent_info with a value of 0 for its 'item_size' field,
      which was causing the insertion of file extent items with an item size
      of 0.
      
      [1] https://www.spinics.net/lists/linux-btrfs/msg75350.html
      
      
      
      Reported-by: default avatarDavid Sterba <dsterba@suse.com>
      Fixes: 690a5dbf
      
       ("Btrfs: fix ENOSPC errors, leading to transaction aborts, when cloning extents")
      Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
      Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      147271e3
    • Filipe Manana's avatar
      Btrfs: fix removal logic of the tree mod log that leads to use-after-free issues · 6609fee8
      Filipe Manana authored
      When a tree mod log user no longer needs to use the tree it calls
      btrfs_put_tree_mod_seq() to remove itself from the list of users and
      delete all no longer used elements of the tree's red black tree, which
      should be all elements with a sequence number less then our equals to
      the caller's sequence number. However the logic is broken because it
      can delete and free elements from the red black tree that have a
      sequence number greater then the caller's sequence number:
      
      1) At a point in time we have sequence numbers 1, 2, 3 and 4 in the
         tree mod log;
      
      2) The task which got assigned the sequence number 1 calls
         btrfs_put_tree_mod_seq();
      
      3) Sequence number 1 is deleted from the list of sequence numbers;
      
      4) The current minimum sequence number is computed to be the sequence
         number 2;
      
      5) A task using sequence number 2 is at tree_mod_log_rewind() and gets
         a pointer to one of its elements from the red black tree through
         a call to tree_mod_log_search();
      
      6) The task with sequence number 1 iterates the red black tree of tree
         modification elements and deletes (and frees) all elements with a
         sequence number less then or equals to 2 (the computed minimum sequence
         number) - it ends up only leaving elements with sequence numbers of 3
         and 4;
      
      7) The task with sequence number 2 now uses the pointer to its element,
         already freed by the other task, at __tree_mod_log_rewind(), resulting
         in a use-after-free issue. When CONFIG_DEBUG_PAGEALLOC=y it produces
         a trace like the following:
      
        [16804.546854] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI
        [16804.547451] CPU: 0 PID: 28257 Comm: pool Tainted: G        W         5.4.0-rc8-btrfs-next-51 #1
        [16804.548059] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014
        [16804.548666] RIP: 0010:rb_next+0x16/0x50
        (...)
        [16804.550581] RSP: 0018:ffffb948418ef9b0 EFLAGS: 00010202
        [16804.551227] RAX: 6b6b6b6b6b6b6b6b RBX: ffff90e0247f6600 RCX: 6b6b6b6b6b6b6b6b
        [16804.551873] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff90e0247f6600
        [16804.552504] RBP: ffff90dffe0d4688 R08: 0000000000000001 R09: 0000000000000000
        [16804.553136] R10: ffff90dffa4a0040 R11: 0000000000000000 R12: 000000000000002e
        [16804.553768] R13: ffff90e0247f6600 R14: 0000000000001663 R15: ffff90dff77862b8
        [16804.554399] FS:  00007f4b197ae700(0000) GS:ffff90e036a00000(0000) knlGS:0000000000000000
        [16804.555039] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
        [16804.555683] CR2: 00007f4b10022000 CR3: 00000002060e2004 CR4: 00000000003606f0
        [16804.556336] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
        [16804.556968] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
        [16804.557583] Call Trace:
        [16804.558207]  __tree_mod_log_rewind+0xbf/0x280 [btrfs]
        [16804.558835]  btrfs_search_old_slot+0x105/0xd00 [btrfs]
        [16804.559468]  resolve_indirect_refs+0x1eb/0xc70 [btrfs]
        [16804.560087]  ? free_extent_buffer.part.19+0x5a/0xc0 [btrfs]
        [16804.560700]  find_parent_nodes+0x388/0x1120 [btrfs]
        [16804.561310]  btrfs_check_shared+0x115/0x1c0 [btrfs]
        [16804.561916]  ? extent_fiemap+0x59d/0x6d0 [btrfs]
        [16804.562518]  extent_fiemap+0x59d/0x6d0 [btrfs]
        [16804.563112]  ? __might_fault+0x11/0x90
        [16804.563706]  do_vfs_ioctl+0x45a/0x700
        [16804.564299]  ksys_ioctl+0x70/0x80
        [16804.564885]  ? trace_hardirqs_off_thunk+0x1a/0x20
        [16804.565461]  __x64_sys_ioctl+0x16/0x20
        [16804.566020]  do_syscall_64+0x5c/0x250
        [16804.566580]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
        [16804.567153] RIP: 0033:0x7f4b1ba2add7
        (...)
        [16804.568907] RSP: 002b:00007f4b197adc88 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
        [16804.569513] RAX: ffffffffffffffda RBX: 00007f4b100210d8 RCX: 00007f4b1ba2add7
        [16804.570133] RDX: 00007f4b100210d8 RSI: 00000000c020660b RDI: 0000000000000003
        [16804.570726] RBP: 000055de05a6cfe0 R08: 0000000000000000 R09: 00007f4b197add44
        [16804.571314] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f4b197add48
        [16804.571905] R13: 00007f4b197add40 R14: 00007f4b100210d0 R15: 00007f4b197add50
        (...)
        [16804.575623] ---[ end trace 87317359aad4ba50 ]---
      
      Fix this by making btrfs_put_tree_mod_seq() skip deletion of elements that
      have a sequence number equals to the computed minimum sequence number, and
      not just elements with a sequence number greater then that minimum.
      
      Fixes: bd989ba3
      
       ("Btrfs: add tree modification log functions")
      CC: stable@vger.kernel.org # 4.4+
      Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      6609fee8
    • Filipe Manana's avatar
      Btrfs: make tree checker detect checksum items with overlapping ranges · ad1d8c43
      Filipe Manana authored
      Having checksum items, either on the checksums tree or in a log tree, that
      represent ranges that overlap each other is a sign of a corruption. Such
      case confuses the checksum lookup code and can result in not being able to
      find checksums or find stale checksums.
      
      So add a check for such case.
      
      This is motivated by a recent fix for a case where a log tree had checksum
      items covering ranges that overlap each other due to extent cloning, and
      resulted in missing checksums after replaying the log tree. It also helps
      detect past issues such as stale and outdated checksums due to overlapping,
      commit 27b9a812
      
       ("Btrfs: fix csum tree corruption, duplicate and
      outdated checksums").
      
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      ad1d8c43
    • Filipe Manana's avatar
      Btrfs: fix missing data checksums after replaying a log tree · 40e046ac
      Filipe Manana authored
      
      
      When logging a file that has shared extents (reflinked with other files or
      with itself), we can end up logging multiple checksum items that cover
      overlapping ranges. This confuses the search for checksums at log replay
      time causing some checksums to never be added to the fs/subvolume tree.
      
      Consider the following example of a file that shares the same extent at
      offsets 0 and 256Kb:
      
         [ bytenr 13893632, offset 64Kb, len 64Kb  ]
         0                                         64Kb
      
         [ bytenr 13631488, offset 64Kb, len 192Kb ]
         64Kb                                      256Kb
      
         [ bytenr 13893632, offset 0, len 256Kb    ]
         256Kb                                     512Kb
      
      When logging the inode, at tree-log.c:copy_items(), when processing the
      file extent item at offset 0, we log a checksum item covering the range
      13959168 to 14024704, which corresponds to 13893632 + 64Kb and 13893632 +
      64Kb + 64Kb, respectively.
      
      Later when processing the extent item at offset 256K, we log the checksums
      for the range from 13893632 to 14155776 (which corresponds to 13893632 +
      256Kb). These checksums get merged with the checksum item for the range
      from 13631488 to 13893632 (13631488 + 256Kb), logged by a previous fsync.
      So after this we get the two following checksum items in the log tree:
      
         (...)
         item 6 key (EXTENT_CSUM EXTENT_CSUM 13631488) itemoff 3095 itemsize 512
                 range start 13631488 end 14155776 length 524288
         item 7 key (EXTENT_CSUM EXTENT_CSUM 13959168) itemoff 3031 itemsize 64
                 range start 13959168 end 14024704 length 65536
      
      The first one covers the range from the second one, they overlap.
      
      So far this does not cause a problem after replaying the log, because
      when replaying the file extent item for offset 256K, we copy all the
      checksums for the extent 13893632 from the log tree to the fs/subvolume
      tree, since searching for an checksum item for bytenr 13893632 leaves us
      at the first checksum item, which covers the whole range of the extent.
      
      However if we write 64Kb to file offset 256Kb for example, we will
      not be able to find and copy the checksums for the last 128Kb of the
      extent at bytenr 13893632, referenced by the file range 384Kb to 512Kb.
      
      After writing 64Kb into file offset 256Kb we get the following extent
      layout for our file:
      
         [ bytenr 13893632, offset 64K, len 64Kb   ]
         0                                         64Kb
      
         [ bytenr 13631488, offset 64Kb, len 192Kb ]
         64Kb                                      256Kb
      
         [ bytenr 14155776, offset 0, len 64Kb     ]
         256Kb                                     320Kb
      
         [ bytenr 13893632, offset 64Kb, len 192Kb ]
         320Kb                                     512Kb
      
      After fsync'ing the file, if we have a power failure and then mount
      the filesystem to replay the log, the following happens:
      
      1) When replaying the file extent item for file offset 320Kb, we
         lookup for the checksums for the extent range from 13959168
         (13893632 + 64Kb) to 14155776 (13893632 + 256Kb), through a call
         to btrfs_lookup_csums_range();
      
      2) btrfs_lookup_csums_range() finds the checksum item that starts
         precisely at offset 13959168 (item 7 in the log tree, shown before);
      
      3) However that checksum item only covers 64Kb of data, and not 192Kb
         of data;
      
      4) As a result only the checksums for the first 64Kb of data referenced
         by the file extent item are found and copied to the fs/subvolume tree.
         The remaining 128Kb of data, file range 384Kb to 512Kb, doesn't get
         the corresponding data checksums found and copied to the fs/subvolume
         tree.
      
      5) After replaying the log userspace will not be able to read the file
         range from 384Kb to 512Kb, because the checksums are missing and
         resulting in an -EIO error.
      
      The following steps reproduce this scenario:
      
        $ mkfs.btrfs -f /dev/sdc
        $ mount /dev/sdc /mnt/sdc
      
        $ xfs_io -f -c "pwrite -S 0xa3 0 256K" /mnt/sdc/foobar
        $ xfs_io -c "fsync" /mnt/sdc/foobar
        $ xfs_io -c "pwrite -S 0xc7 256K 256K" /mnt/sdc/foobar
      
        $ xfs_io -c "reflink /mnt/sdc/foobar 320K 0 64K" /mnt/sdc/foobar
        $ xfs_io -c "fsync" /mnt/sdc/foobar
      
        $ xfs_io -c "pwrite -S 0xe5 256K 64K" /mnt/sdc/foobar
        $ xfs_io -c "fsync" /mnt/sdc/foobar
      
        <power failure>
      
        $ mount /dev/sdc /mnt/sdc
        $ md5sum /mnt/sdc/foobar
        md5sum: /mnt/sdc/foobar: Input/output error
      
        $ dmesg | tail
        [165305.003464] BTRFS info (device sdc): no csum found for inode 257 start 401408
        [165305.004014] BTRFS info (device sdc): no csum found for inode 257 start 405504
        [165305.004559] BTRFS info (device sdc): no csum found for inode 257 start 409600
        [165305.005101] BTRFS info (device sdc): no csum found for inode 257 start 413696
        [165305.005627] BTRFS info (device sdc): no csum found for inode 257 start 417792
        [165305.006134] BTRFS info (device sdc): no csum found for inode 257 start 421888
        [165305.006625] BTRFS info (device sdc): no csum found for inode 257 start 425984
        [165305.007278] BTRFS info (device sdc): no csum found for inode 257 start 430080
        [165305.008248] BTRFS warning (device sdc): csum failed root 5 ino 257 off 393216 csum 0x1337385e expected csum 0x00000000 mirror 1
        [165305.009550] BTRFS warning (device sdc): csum failed root 5 ino 257 off 393216 csum 0x1337385e expected csum 0x00000000 mirror 1
      
      Fix this simply by deleting first any checksums, from the log tree, for the
      range of the extent we are logging at copy_items(). This ensures we do not
      get checksum items in the log tree that have overlapping ranges.
      
      This is a long time issue that has been present since we have the clone
      (and deduplication) ioctl, and can happen both when an extent is shared
      between different files and within the same file.
      
      A test case for fstests follows soon.
      
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      40e046ac
    • Dan Carpenter's avatar
      btrfs: return error pointer from alloc_test_extent_buffer · b6293c82
      Dan Carpenter authored
      Callers of alloc_test_extent_buffer have not correctly interpreted the
      return value as error pointer, as alloc_test_extent_buffer should behave
      as alloc_extent_buffer. The self-tests were unaffected but
      btrfs_find_create_tree_block could call both functions and that would
      cause problems up in the call chain.
      
      Fixes: faa2dbf0
      
       ("Btrfs: add sanity tests for new qgroup accounting code")
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      b6293c82
    • David Sterba's avatar
      btrfs: fix devs_max constraints for raid1c3 and raid1c4 · cf93e15e
      David Sterba authored
      The value 0 for devs_max means to spread the allocated chunks over all
      available devices, eg. stripe for RAID0 or RAID5. This got mistakenly
      copied to the RAID1C3/4 profiles. The intention is to have exactly 3 and
      4 copies respectively.
      
      Fixes: 47e6f742 ("btrfs: add support for 3-copy replication (raid1c3)")
      Fixes: 8d6fac00
      
       ("btrfs: add support for 4-copy replication (raid1c4)")
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      cf93e15e
    • Andreas Färber's avatar
      btrfs: tree-checker: Fix error format string for size_t · 994bf9cd
      Andreas Färber authored
      Argument BTRFS_FILE_EXTENT_INLINE_DATA_START is defined as offsetof(),
      which returns type size_t, so we need %zu instead of %lu.
      
      This fixes a build warning on 32-bit ARM:
      
        ../fs/btrfs/tree-checker.c: In function 'check_extent_data_item':
        ../fs/btrfs/tree-checker.c:230:43: warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'unsigned int' [-Wformat=]
          230 |     "invalid item size, have %u expect [%lu, %u)",
              |                                         ~~^
              |                                           long unsigned int
              |                                         %u
      
      Fixes: 153a6d29
      
       ("btrfs: tree-checker: Check item size before reading file extent type")
      Acked-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: Andreas Färber's avatarAndreas Färber <afaerber@suse.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      994bf9cd
    • Josef Bacik's avatar
      btrfs: don't double lock the subvol_sem for rename exchange · 943eb3bf
      Josef Bacik authored
      If we're rename exchanging two subvols we'll try to lock this lock
      twice, which is bad.  Just lock once if either of the ino's are subvols.
      
      Fixes: cdd1fedf
      
       ("btrfs: add support for RENAME_EXCHANGE and RENAME_WHITEOUT")
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      943eb3bf
    • Josef Bacik's avatar
      btrfs: handle error in btrfs_cache_block_group · db8fe64f
      Josef Bacik authored
      
      
      We have a BUG_ON(ret < 0) in find_free_extent from
      btrfs_cache_block_group.  If we fail to allocate our ctl we'll just
      panic, which is not good.  Instead just go on to another block group.
      If we fail to find a block group we don't want to return ENOSPC, because
      really we got a ENOMEM and that's the root of the problem.  Save our
      return from btrfs_cache_block_group(), and then if we still fail to make
      our allocation return that ret so we get the right error back.
      
      Tested with inject-error.py from bcc.
      
      Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      db8fe64f
    • Josef Bacik's avatar
      btrfs: do not call synchronize_srcu() in inode_tree_del · f72ff01d
      Josef Bacik authored
      Testing with the new fsstress uncovered a pretty nasty deadlock with
      lookup and snapshot deletion.
      
      Process A
      unlink
       -> final iput
         -> inode_tree_del
           -> synchronize_srcu(subvol_srcu)
      
      Process B
      btrfs_lookup  <- srcu_read_lock() acquired here
        -> btrfs_iget
          -> find inode that has I_FREEING set
            -> __wait_on_freeing_inode()
      
      We're holding the srcu_read_lock() while doing the iget in order to make
      sure our fs root doesn't go away, and then we are waiting for the inode
      to finish freeing.  However because the free'ing process is doing a
      synchronize_srcu() we deadlock.
      
      Fix this by dropping the synchronize_srcu() in inode_tree_del().  We
      don't need people to stop accessing the fs root at this point, we're
      only adding our empty root to the dead roots list.
      
      A larger much more invasive fix is forthcoming to address how we deal
      with fs roots, but this fixes the immediate problem.
      
      Fixes: 76dda93c
      
       ("Btrfs: add snapshot/subvolume destroy ioctl")
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      f72ff01d
    • Filipe Manana's avatar
      Btrfs: fix cloning range with a hole when using the NO_HOLES feature · fcb97058
      Filipe Manana authored
      When using the NO_HOLES feature if we clone a range that contains a hole
      and a temporary ENOSPC happens while dropping extents from the target
      inode's range, we can end up failing and aborting the transaction with
      -EEXIST or with a corrupt file extent item, that has a length greater
      than it should and overlaps with other extents. For example when cloning
      the following range from inode A to inode B:
      
        Inode A:
      
          extent A1                                          extent A2
        [ ----------- ]  [ hole, implicit, 4MB length ]  [ ------------- ]
        0            1MB                                 5MB            6MB
      
        Range to clone: [1MB, 6MB)
      
        Inode B:
      
          extent B1       extent B2        extent B3         extent B4
        [ ---------- ]  [ --------- ]    [ ---------- ]    [ ---------- ]
        0           1MB 1MB        2MB   2MB        5MB    5MB         6MB
      
        Target range: [1MB, 6MB) (same as source, to make it easier to explain)
      
      The following can happen:
      
      1) btrfs_punch_hole_range() gets -ENOSPC from __btrfs_drop_extents();
      
      2) At that point, 'cur_offset' is set to 1MB and __btrfs_drop_extents()
         set 'drop_end' to 2MB, meaning it was able to drop only extent B2;
      
      3) We then compute 'clone_len' as 'drop_end' - 'cur_offset' = 2MB - 1MB =
         1MB;
      
      4) We then attempt to insert a file extent item at inode B with a file
         offset of 5MB, which is the value of clone_info->file_offset. This
         fails with error -EEXIST because there's already an extent at that
         offset (extent B4);
      
      5) We abort the current transaction with -EEXIST and return that error
         to user space as well.
      
      Another example, for extent corruption:
      
        Inode A:
      
          extent A1                                           extent A2
        [ ----------- ]   [ hole, implicit, 10MB length ]  [ ------------- ]
        0            1MB                                  11MB            12MB
      
        Inode B:
      
          extent B1         extent B2
        [ ----------- ]   [ --------- ]    [ ----------------------------- ]
        0            1MB 1MB         5MB  5MB                             12MB
      
        Target range: [1MB, 12MB) (same as source, to make it easier to explain)
      
      1) btrfs_punch_hole_range() gets -ENOSPC from __btrfs_drop_extents();
      
      2) At that point, 'cur_offset' is set to 1MB and __btrfs_drop_extents()
         set 'drop_end' to 5MB, meaning it was able to drop only extent B2;
      
      3) We then compute 'clone_len' as 'drop_end' - 'cur_offset' = 5MB - 1MB =
         4MB;
      
      4) We then insert a file extent item at inode B with a file offset of 11MB
         which is the value of clone_info->file_offset, and a length of 4MB (the
         value of 'clone_len'). So we get 2 extents items with ranges that
         overlap and an extent length of 4MB, larger then the extent A2 from
         inode A (1MB length);
      
      5) After that we end the transaction, balance the btree dirty pages and
         then start another or join the previous transaction. It might happen
         that the transaction which inserted the incorrect extent was committed
         by another task so we end up with extent corruption if a power failure
         happens.
      
      So fix this by making sure we attempt to insert the extent to clone at
      the destination inode only if we are past dropping the sub-range that
      corresponds to a hole.
      
      Fixes: 690a5dbf
      
       ("Btrfs: fix ENOSPC errors, leading to transaction aborts, when cloning extents")
      Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      fcb97058
    • Nikolay Borisov's avatar
      btrfs: Fix error messages in qgroup_rescan_init · 37d02592
      Nikolay Borisov authored
      
      
      The branch of qgroup_rescan_init which is executed from the mount
      path prints wrong errors messages. The textual print out in case
      BTRFS_QGROUP_STATUS_FLAG_RESCAN/BTRFS_QGROUP_STATUS_FLAG_ON are not
      set are transposed. Fix it by exchanging their place.
      
      Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      37d02592
    • Pavel Shilovsky's avatar
      CIFS: Close cached root handle only if it has a lease · d9191319
      Pavel Shilovsky authored
      
      
      SMB2_tdis() checks if a root handle is valid in order to decide
      whether it needs to close the handle or not. However if another
      thread has reference for the handle, it may end up with putting
      the reference twice. The extra reference that we want to put
      during the tree disconnect is the reference that has a directory
      lease. So, track the fact that we have a directory lease and
      close the handle only in that case.
      
      Signed-off-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
      Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
      Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
      d9191319
    • Steve French's avatar
      SMB3: Fix crash in SMB2_open_init due to uninitialized field in compounding path · e0fc5b11
      Steve French authored
      Ran into an intermittent crash in
      	SMB2_open_init+0x2f6/0x970
      due to oparms.cifs_sb not being initialized when called from:
      	smb2_compound_op+0x45d/0x1690
      Zero the whole oparms struct in the compounding path before setting up the
      oparms so we don't risk any uninitialized fields.
      
      Fixes: fdef665b
      
       ("smb3: fix mode passed in on create for modetosid mount option")
      
      Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
      Acked-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
      e0fc5b11
  2. 12 Dec, 2019 2 commits
    • Dominik Brodowski's avatar
      fs: remove ksys_dup() · 8243186f
      Dominik Brodowski authored
      
      
      ksys_dup() is used only at one place in the kernel, namely to duplicate
      fd 0 of /dev/console to stdout and stderr. The same functionality can be
      achieved by using functions already available within the kernel namespace.
      
      Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
      8243186f
    • Dominik Brodowski's avatar
      init: use do_mount() instead of ksys_mount() · cccaa5e3
      Dominik Brodowski authored
      
      
      In prepare_namespace(), do_mount() can be used instead of ksys_mount()
      as the first and third argument are const strings in the kernel, the
      second and fourth argument are passed through anyway, and the fifth
      argument is NULL.
      
      In do_mount_root(), ksys_mount() is called with the first and third
      argument being already kernelspace strings, which do not need to be
      copied over from userspace to kernelspace (again). The second and
      fourth arguments are passed through to do_mount() anyway. The fifth
      argument, while already residing in kernelspace, needs to be put into
      a page of its own. Then, do_mount() can be used instead of
      ksys_mount().
      
      Once this is done, there are no in-kernel users to ksys_mount() left,
      which can therefore be removed.
      
      Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
      cccaa5e3
  3. 11 Dec, 2019 7 commits
    • Jens Axboe's avatar
      io_uring: ensure we return -EINVAL on unknown opcode · 9e3aa61a
      Jens Axboe authored
      
      
      If we submit an unknown opcode and have fd == -1, io_op_needs_file()
      will return true as we default to needing a file. Then when we go and
      assign the file, we find the 'fd' invalid and return -EBADF. We really
      should be returning -EINVAL for that case, as we normally do for
      unsupported opcodes.
      
      Change io_op_needs_file() to have the following return values:
      
      0   - does not need a file
      1   - does need a file
      < 0 - error value
      
      and use this to pass back the right value for this invalid case.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      9e3aa61a
    • Linus Torvalds's avatar
      pipe: simplify signal handling in pipe_read() and add comments · d1c6a2aa
      Linus Torvalds authored
      
      
      There's no need to separately check for signals while inside the locked
      region, since we're going to do "wait_event_interruptible()" right
      afterwards anyway, and the error handling is much simpler there.
      
      The check for whether we had already read anything was also redundant,
      since we no longer do the odd merging of reads when there are pending
      writers.
      
      But perhaps more importantly, this adds commentary about why we still
      need to wake up possible writers even though we didn't read any data,
      and why we can skip all the finishing touches now if we get a signal (or
      had a signal pending) while waiting for more data.
      
      [ This is a split-out cleanup from my "make pipe IO use exclusive wait
        queues" thing, which I can't apply because it triggers a nasty bug in
        the GNU make jobserver   - Linus ]
      
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      d1c6a2aa
    • David Howells's avatar
      afs: Show volume name in /proc/net/afs/<cell>/volumes · 50559800
      David Howells authored
      
      
      Show the name of each volume in /proc/net/afs/<cell>/volumes to make it
      easier to work out the name corresponding to a volume ID.  This makes it
      easier to work out which mounts in /proc/mounts correspond to which volume
      ID.
      
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      50559800
    • David Howells's avatar
      afs: Fix missing cell comparison in afs_test_super() · 106bc798
      David Howells authored
      Fix missing cell comparison in afs_test_super().  Without this, any pair
      volumes that have the same volume ID will share a superblock, no matter the
      cell, unless they're in different network namespaces.
      
      Normally, most users will only deal with a single cell and so they won't
      see this.  Even if they do look into a second cell, they won't see a
      problem unless they happen to hit a volume with the same ID as one they've
      already got mounted.
      
      Before the patch:
      
          # ls /afs/grand.central.org/archive
          linuxdev/  mailman/  moin/  mysql/  pipermail/  stage/  twiki/
          # ls /afs/kth.se/
          linuxdev/  mailman/  moin/  mysql/  pipermail/  stage/  twiki/
          # cat /proc/mounts | grep afs
          none /afs afs rw,relatime,dyn,autocell 0 0
          #grand.central.org:root.cell /afs/grand.central.org afs ro,relatime 0 0
          #grand.central.org:root.archive /afs/grand.central.org/archive afs ro,relatime 0 0
          #grand.central.org:root.archive /afs/kth.se afs ro,relatime 0 0
      
      After the patch:
      
          # ls /afs/grand.central.org/archive
          linuxdev/  mailman/  moin/  mysql/  pipermail/  stage/  twiki/
          # ls /afs/kth.se/
          admin/        common/  install/  OldFiles/  service/  system/
          bakrestores/  home/    misc/     pkg/       src/      wsadmin/
          # cat /proc/mounts | grep afs
          none /afs afs rw,relatime,dyn,autocell 0 0
          #grand.central.org:root.cell /afs/grand.central.org afs ro,relatime 0 0
          #grand.central.org:root.archive /afs/grand.central.org/archive afs ro,relatime 0 0
          #kth.se:root.cell /afs/kth.se afs ro,relatime 0 0
      
      Fixes: ^1da177e4
      
       ("Linux-2.6.12-rc2")
      Reported-by: default avatarCarsten Jacobi <jacobi@de.ibm.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Tested-by: default avatarJonathan Billings <jsbillings@jsbillings.org>
      cc: Todd DeSantis <atd@us.ibm.com>
      106bc798
    • David Howells's avatar
      afs: Fix creation calls in the dynamic root to fail with EOPNOTSUPP · 1da4bd9f
      David Howells authored
      
      
      Fix the lookup method on the dynamic root directory such that creation
      calls, such as mkdir, open(O_CREAT), symlink, etc. fail with EOPNOTSUPP
      rather than failing with some odd error (such as EEXIST).
      
      lookup() itself tries to create automount directories when it is invoked.
      These are cached locally in RAM and not committed to storage.
      
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Tested-by: default avatarJonathan Billings <jsbillings@jsbillings.org>
      1da4bd9f
    • David Howells's avatar
      afs: Fix mountpoint parsing · 158d5833
      David Howells authored
      Each AFS mountpoint has strings that define the target to be mounted.  This
      is required to end in a dot that is supposed to be stripped off.  The
      string can include suffixes of ".readonly" or ".backup" - which are
      supposed to come before the terminal dot.  To add to the confusion, the "fs
      lsmount" afs utility does not show the terminal dot when displaying the
      string.
      
      The kernel mount source string parser, however, assumes that the terminal
      dot marks the suffix and that the suffix is always "" and is thus ignored.
      In most cases, there is no suffix and this is not a problem - but if there
      is a suffix, it is lost and this affects the ability to mount the correct
      volume.
      
      The command line mount command, on the other hand, is expected not to
      include a terminal dot - so the problem doesn't arise there.
      
      Fix this by making sure that the dot exists and then stripping it when
      passing the string to the mount configuration.
      
      Fixes: bec5eb61
      
       ("AFS: Implement an autocell mount capability [ver #2]")
      Reported-by: default avatarJonathan Billings <jsbillings@jsbillings.org>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Tested-by: default avatarJonathan Billings <jsbillings@jsbillings.org>
      158d5833
    • Flavio Leitner's avatar
      sched/cputime, proc/stat: Fix incorrect guest nice cpustat value · 346da4d2
      Flavio Leitner authored
      The value being used for guest_nice should be CPUTIME_GUEST_NICE
      and not CPUTIME_USER.
      
      Fixes: 26dae145
      
       ("procfs: Use all-in-one vtime aware kcpustat accessor")
      Signed-off-by: default avatarFlavio Leitner <fbl@sysclose.org>
      Signed-off-by: default avatarFrederic Weisbecker <frederic@kernel.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Link: https://lkml.kernel.org/r/20191205020344.14940-1-frederic@kernel.org
      
      
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      346da4d2
  4. 10 Dec, 2019 12 commits