[PATCH v2] btrfs-progs: force overwrite should wipe stale SB
(I am unable to reproduce the issue, tried to go back with progs versions but still the same. So as of now this code remains untested, suggest to wait till we have a reproducible test case). Here is a test case which says it all.. mkfs.xfs -f $DEV mkfs.btrfs -f $DEV mount $DEV $MNT mount: /dev/vdiskc: more filesystems detected. This should not happen, use -t to explicitly specify the filesystem type or use wipefs(8) to clean up the device. mount: you must specify the filesystem type with this patch btrfs_prepare_device() also wipes old FS if any, btrfs_prepare_device() is called after we have verified that user has provided -f option. v2: to satisfy the backward compatibility issue, replace blkid_do_wipe() with local wipe function. Signed-off-by: Anand Jain Signed-off-by: David Sterba --- utils.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/utils.c b/utils.c index fb78dd6..5f21737 100644 --- a/utils.c +++ b/utils.c @@ -680,6 +680,42 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, return 0; } +static void btrfs_wipe_existing_sb(int fd) +{ + const char *off = NULL; + size_t len = 0; + loff_t offset; + char buf[BUFSIZ]; + int rc = 0; + blkid_probe pr = NULL; + + pr = blkid_new_probe(); + if (!pr) + return; + + if (blkid_probe_set_device(pr, fd, 0, 0)) + goto out; + + rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL); + if (!rc) + rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len); + + if (rc || len == 0 || off == NULL) + goto out; + + offset = strtoll(off, NULL, 10); + if (len > sizeof(buf)) + len = sizeof(buf); + + memset(buf, 0, len); + rc = pwrite(fd, buf, len, offset); + fsync(fd); + +out: + blkid_free_probe(pr); + return; +} + int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, u64 max_block_count, int *mixed, int discard) { @@ -731,6 +767,8 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, return 1; } + btrfs_wipe_existing_sb(fd); + *block_count_ret = block_count; return 0; } -- 2.0.0.153.g79d -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
3.17.0-rc7: kernel BUG at fs/btrfs/relocation.c:931!
Got this when running balance with 3.17.0-rc7: (...) [173394.571080] BTRFS info (device sdd1): relocating block group 4391666974720 flags 17 [173405.407779] BTRFS info (device sdd1): found 52296 extents [173441.235837] BTRFS info (device sdd1): found 52296 extents [173442.266918] BTRFS info (device sdd1): relocating block group 4390593232896 flags 17 [173451.515002] BTRFS info (device sdd1): found 22314 extents [173473.761612] BTRFS info (device sdd1): found 22314 extents [173474.498414] BTRFS info (device sdd1): relocating block group 4389519491072 flags 20 [173475.410657] [ cut here ] [173475.410717] kernel BUG at fs/btrfs/relocation.c:931! [173475.410774] invalid opcode: [#1] SMP [173475.410829] Modules linked in: ipt_MASQUERADE iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack ip_tables x_tables cpufreq_ondemand cpufreq_conservative cpufreq_powersave cpufreq_stats bridge stp llc ipv6 btrfs xor raid6_pq zlib_deflate coretemp hwmon loop i2c_i801 i2c_core pcspkr battery tpm_infineon tpm_tis tpm parport_pc parport video lpc_ich mfd_core ehci_pci ehci_hcd button acpi_cpufreq ext4 crc16 jbd2 mbcache raid1 sg sd_mod ahci libahci libata scsi_mod r8169 mii [173475.411284] CPU: 1 PID: 5512 Comm: btrfs Not tainted 3.17.0-rc7 #1 [173475.411341] Hardware name: System manufacturer System Product Name/P8H77-M PRO, BIOS 1101 02/04/2013 [173475.411450] task: 8807f1744830 ti: 88076e9b task.ti: 88076e9b [173475.411555] RIP: 0010:[] [] build_backref_tree+0x64a/0xe77 [btrfs] [173475.411684] RSP: 0018:88076e9b3888 EFLAGS: 00010287 [173475.411740] RAX: 8805abb30480 RBX: 880589dfcf00 RCX: 0003 [173475.411845] RDX: 0510a31b8000 RSI: 880589dfcac0 RDI: 8804c69f8800 [173475.411949] RBP: 88076e9b3988 R08: 000143e0 R09: [173475.412053] R10: 8807c97366f0 R11: R12: 8804c69f8800 [173475.412157] R13: 880589dfca80 R14: R15: 88065a3b [173475.412262] FS: 7f320e446840() GS:88081fa4() knlGS: [173475.413687] CS: 0010 DS: ES: CR0: 80050033 [173475.413744] CR2: ff600400 CR3: 0007ea08f000 CR4: 001407e0 [173475.413849] Stack: [173475.413899] 8807c820a000 880589dfcf00 8801a22bf7c0 [173475.414007] 8801a22bfb60 880589dfcac0 88065a3b0124 0001 [173475.414114] 88065a3b0120 0003 8805abb30480 8805dbbb7240 [173475.414223] Call Trace: [173475.414291] [] relocate_tree_blocks+0x1b7/0x532 [btrfs] [173475.414364] [] ? free_extent_buffer+0x6f/0x7c [btrfs] [173475.414434] [] ? tree_insert+0x49/0x50 [btrfs] [173475.414501] [] ? add_tree_block+0x13a/0x162 [btrfs] [173475.414570] [] relocate_block_group+0x275/0x4de [btrfs] [173475.414640] [] btrfs_relocate_block_group+0x158/0x278 [btrfs] [173475.414763] [] btrfs_relocate_chunk.isra.62+0x58/0x5f7 [btrfs] [173475.414884] [] ? btrfs_set_lock_blocking_rw+0x68/0x95 [btrfs] [173475.414995] [] ? btrfs_set_path_blocking+0x23/0x54 [btrfs] [173475.415107] [] ? btrfs_search_slot+0x7bc/0x816 [btrfs] [173475.415177] [] ? free_extent_buffer+0x6f/0x7c [btrfs] [173475.415248] [] btrfs_balance+0xa7b/0xc80 [btrfs] [173475.415318] [] btrfs_ioctl_balance+0x220/0x29f [btrfs] [173475.415388] [] btrfs_ioctl+0x10bd/0x2281 [btrfs] [173475.415448] [] ? handle_mm_fault+0x44d/0xa00 [173475.415507] [] ? avc_has_perm+0x2e/0xf7 [173475.415566] [] ? __vm_enough_memory+0x25/0x13c [173475.415625] [] do_vfs_ioctl+0x3f2/0x43c [173475.415682] [] SyS_ioctl+0x4e/0x7d [173475.415740] [] ? do_page_fault+0xc/0xf [173475.415798] [] system_call_fastpath+0x16/0x1b [173475.415856] Code: ff ff 01 e9 50 02 00 00 48 63 8d 48 ff ff ff 48 8b 85 50 ff ff ff 48 83 3c c8 00 75 46 48 8b 53 18 49 39 94 24 d8 00 00 00 74 02 <0f> 0b 4c 89 e7 e8 9b e8 ff ff 85 c0 74 21 48 8b 55 98 48 8d 43 [173475.416080] RIP [] build_backref_tree+0x64a/0xe77 [btrfs] [173475.416151] RSP [173475.416482] ---[ end trace 17e512e0d6dc91d7 ]--- -- Tomasz Chmielewski http://www.sslrack.com -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Fwd: Deleting a Subvol from a Cancelled Btrfs-Send
Hugo, Many thanks for the help. That was far easier than I was anticipating. :) Now that I have that cleaned up, I'm having trouble with sending the delta. Perhaps this is a limitation of send/receive because it seems odd that btrfs-receive doesn't have a parent option. I'm sending a snapshot from venus to spaceman using ssh for transport. I prepared spaceman with ~$ mkdir -p /var/media/backups/venus/ ~$ sudo btrfs subvol create /var/media/backups/venus/home Then on venus, I created a read-only snapshot and sent it spaceman: ~$ sudo btrfs sub snap -r /home home-2014-09-26 ~$ sudo btrfs send -vv home-2014-09-26 | ssh root@spaceman "/usr/sbin/btrfs receive -vv /var/media/backups/venus/home" All good so far. Now, I'm trying to send a delta: ~$ sudo btrfs send -vv -p home-2014-09-26 home-2014-10-01 | ssh root@spaceman "/usr/sbin/btrfs receive -vv /var/media/backups/venus/home" receiving snapshot home-2014-10-01 uuid=60dd57bd-4cd0-394c-ba85-065f646829d7, ctransid=446614 parent_uuid=a994d4b5-6c89-9442-a5cc-ffa1d74b9847, parent_ctransid=432944 At snapshot home-2014-10-01 It seems that you have changed your default subvolume or you specify other subvolume to mount btrfs, try to remount this btrfs filesystem with fs tree, and run btrfs receive again! I'm not sure what "fs tree" is supposed to mean, and Google didn't have anything useful. On spaceman, the target btrfs file system is multi-device RAID10 with the "media" subvol mounted at /var/media and "ovirt" subvol at /var/ovirt. There are also the subvols "backups/venus/home" and "backups/venus/home/home-2014-09-26," which I suppose is only mounted because I haven't rebooted or unmounted since creating and sending them, respectively. This seems like it's falling into the third caveat from `man btrfs-receive`: 3. default subvolume is changed or you don’t mount btrfs filesystem with fs tree. I don't have any idea what that means, and the Btrfs mount options page (https://btrfs.wiki.kernel.org/index.php/Mount_options) doesn't provide any help. In a vain effort, I tried setting setting the default subvolume to both ~$ sudo btrfs subvolume set-default 4169 /var/media/backups/venus/home/home-2014-09-26 and then ~$ sudo btrfs subvolume set-default 4170 /var/media/backups/venus/home/home-2014-09-26 Neither had any effect on the error output. It really seems like the command should be something like: ~$ sudo btrfs send -vv -p home-2014-09-26 home-2014-10-01 | ssh r...@spaceman.lab.fandingo.org "/usr/sbin/btrfs receive -vv -p /var/media/backups/venus/home/home-2014-09-26 /var/media/backups/venus/home/" Any idea what's happening? I can't find a single example online of sending a delta over ssh. Thanks, Justin On Thu, Oct 2, 2014 at 1:53 AM, Hugo Mills wrote: > On Thu, Oct 02, 2014 at 12:05:39AM -0500, Justin Brown wrote: >> I'm experimenting with btrfs-send. Previously (2014-09-26), I did my >> first btrfs-send on a subvol, and that worked fine. Today, I tried to >> send a new snapshot. Unfortunately, I realized part way through that I >> forgot to specify the parent to only send a delta, and killed the send >> with ^C. >> >> On the destination, I'm left with: >> >> ~$ sudo btrfs subvol list /var/media/backups/venus/home/ >> ID 2820 gen 57717 top level 5 path media >> ID 2821 gen 57402 top level 5 path ovirt >> ID 4169 gen 57703 top level 2820 path media/backups/venus/home >> ID 4170 gen 57575 top level 4169 path home-2014-09-26 >> ID 4243 gen 57707 top level 4169 path home-2014-10-01 >> >> Home-2014-10-01 was the partial send that was cancelled. I figured >> that I could delete this partial subvol and try again. >> >> ~$ sudo btrfs subvol del home-2014-10-01 >> Transaction commit: none (default) >> ERROR: error accessing 'home-2014-10-01' > >If you're not doing this from /var/media/backups/venus/home/ it > won't succeed. You need to specify (either via a relative path or an > absolute one) where the subvol is, not just what its name is. > >(Consider what happens if you have two filesystems, each with a > home-2014-09-26 subvol.) > >Hugo. > >> Obviously, trying to delete the subvol directory fails too: >> >> ~$ sudo rm -rf /var/media/backups/venus/home/home-2014-10-01/ >> rm: cannot remove ‘/var/media/backups/venus/home/home-2014-10-01/’: >> Operation not permitted >> >> Is there anyway to delete this partial subvol? >> >> Thanks, >> Justin > > -- > === Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk === > PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk >--- All hope abandon, Ye who press Enter here. --- -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] btrfs-progs: fix uninitialized warining in btrfs_calc_stripe_index
chunk-recover.c: In function ‘btrfs_calc_stripe_index’: chunk-recover.c:1481: warning: ‘index’ may be used uninitialized in this function Signed-off-by: Anand Jain --- chunk-recover.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chunk-recover.c b/chunk-recover.c index 209d7a7..5daffe3 100644 --- a/chunk-recover.c +++ b/chunk-recover.c @@ -1478,7 +1478,7 @@ static int btrfs_calc_stripe_index(struct chunk_record *chunk, u64 logical) u64 offset = logical - chunk->offset; int stripe_nr; int nr_data_stripes; - int index; + int index = 0; stripe_nr = offset / chunk->stripe_len; if (chunk->type_flags & BTRFS_BLOCK_GROUP_RAID0) { -- 2.0.0.153.g79d -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
btrfs 3.16.2 does not recognize subvolumes correctly
Hi all, I just noticed that when doing a 'btrfs subvolume show /' I get the error 'ERROR: / doesn't belong to btrfs mount point', which is not quite true. I get the same error for all the other subvolumes as well. It worked fine until 3.14.1. Regards, -- J.Hofmüller ich zitiere wie Espenlaub. https://twitter.com/TheGurkenkaiser/status/463444397678690304 signature.asc Description: OpenPGP digital signature
Re: btrfs check segfaults after flipping 2 Bytes
Brendan Hide posted on Thu, 02 Oct 2014 07:51:08 +0200 as excerpted: > A reasonable workaround to get the filesystem back into a usable or > recoverable state might be to mount read-only and ignore checksums. That > would keep the filesystem intact, though the system has no way to know > whether or not the folder structures are also corrupt. > > I'm not sure if there is a mount option for this use case however. The > option descriptions for "nodatasum" and "nodatacow" imply that *new* > checksums are not generated. In this case the checksums already exist. >From a certain viewpoint that's sort of what btrfs restore does, except that it doesn't mount the filesystem; it simply lets you retrieve files already there without mounting, if the filesystem isn't mountable. Also see btrfs check --init-csum-tree, which basically wipes out the csums, after which the filesystem should mount, but entirely without checksums. Of course this option kills all the csums and there's presently nothing that actually recalculates and rebuilds the csum tree (tho there's a very recent patch that I believe adds that functionality), so once they're gone, there' gone. -- Duncan - List replies preferred. No HTML msgs. "Every nonfree program has a lord, a master -- and if you use the program, he is your master." Richard Stallman -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
FIBMAP unsupported
Hi, I have a large (25G) virtual disk on a btrfs fs. Yes, I know this is not optimial. So I try to defrag it from time to time. However, using "btrfs fi defrag -c vm.vdi" results in even more fragments than before (reported by filefrag). So I wrote my own pseudo defragger, - #!/bin/sh test -f $1 || exit 2 echo "defrag $1" /usr/sbin/filefrag $1 || exit fallocate -n -l `filesize $1` $1.new || exit chattr +C $1.new dd if=$1 of=$1.new conv=notrunc oflag=append status=none chmod --reference $1 $1.new chown --reference $1 $1.new mv $1.new $1 /usr/sbin/filefrag $1 - which produces much better results (ok, the file must not be in use). Somewhere in the 3.17 cycle the resulting image got corrupted using the script above. Running filefrag on it returns "FIBMAP unsupported". Virtualbox returns "AHCI#0P0: Read at offset 606236672 (49152 bytes left) returned rc=VERR_DEV_IO_ERROR". No errors in the kernel log. Trying "cp vm.vdi /dev/null" returns: cp: Error reading „vm.vdi“: IO-Error kernel 3.17-rc7 btrfs 3.17.x mount options: rw,nodiratime,relatime,compress=lzo,space_cache,autodefrag Marc -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/14] Misc cleanups for 3.18
Assorted cleanups. There's fix from Filipe mixed among my patches because I found it in the mailinglist but only after I had written my own patch of course. You can pull from git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git cleanup/misc-for-3.18 David Sterba (13): btrfs: defrag, use unsigned type for extent thresh btrfs: remove unused variable from btrfs_parse_options btrfs: remove unused extent state bits btrfs: use enum for wq endio metadata type btrfs: fix error labels in init_btrfs_fs btrfs: use slab for end_io_wq structures btrfs: remove unused members from struct scrub_warning btrfs: let merge_reloc_roots return void btrfs: hide typecast to definition of BTRFS_SEND_TRANS_STUB btrfs: drop constant param from btrfs_release_extent_buffer_page btrfs: kill extent_buffer_page helper btrfs: new define for the inline extent data start btrfs: move checks for DUMMY_ROOT into a helper Filipe David Borba Manana (1): Btrfs: set default max_inline to 8KiB instead of 8MiB fs/btrfs/compression.c | 11 +--- fs/btrfs/ctree.c | 8 +++--- fs/btrfs/ctree.h | 26 +-- fs/btrfs/disk-io.c | 61 --- fs/btrfs/disk-io.h | 6 +++-- fs/btrfs/extent-tree.c | 16 +--- fs/btrfs/extent_io.c | 70 +++--- fs/btrfs/extent_io.h | 10 fs/btrfs/inode.c | 3 ++- fs/btrfs/ioctl.c | 8 +++--- fs/btrfs/qgroup.c | 10 +++- fs/btrfs/relocation.c | 3 +-- fs/btrfs/scrub.c | 17 ++-- fs/btrfs/send.c| 2 +- fs/btrfs/super.c | 14 ++ fs/btrfs/transaction.c | 2 +- fs/btrfs/transaction.h | 2 +- 17 files changed, 131 insertions(+), 138 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/14] Btrfs: set default max_inline to 8KiB instead of 8MiB
From: Filipe David Borba Manana 8MiB is way too large and likely set by mistake. This is not a significant issue as in practice the max amount of data added to an inline extent is also limited by the page cache and btree leaf sizes. Signed-off-by: Filipe David Borba Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 1 + fs/btrfs/disk-io.c | 2 +- fs/btrfs/super.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 089f6da09411..dd79ba7ee3ea 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2089,6 +2089,7 @@ struct btrfs_ioctl_defrag_range_args { #defineBTRFS_MOUNT_CHANGE_INODE_CACHE (1 << 24) #define BTRFS_DEFAULT_COMMIT_INTERVAL (30) +#define BTRFS_DEFAULT_MAX_INLINE (8192) #define btrfs_clear_opt(o, opt)((o) &= ~BTRFS_MOUNT_##opt) #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4780e6623c7b..9b2a741370b7 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2260,7 +2260,7 @@ int open_ctree(struct super_block *sb, atomic_set(&fs_info->qgroup_op_seq, 0); atomic64_set(&fs_info->tree_mod_seq, 0); fs_info->sb = sb; - fs_info->max_inline = 8192 * 1024; + fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE; fs_info->metadata_ratio = 0; fs_info->defrag_inodes = RB_ROOT; fs_info->free_chunk_space = 0; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1c6da8e00c1b..b1d2a42f379d 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1014,7 +1014,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) seq_puts(seq, ",nodatacow"); if (btrfs_test_opt(root, NOBARRIER)) seq_puts(seq, ",nobarrier"); - if (info->max_inline != 8192 * 1024) + if (info->max_inline != BTRFS_DEFAULT_MAX_INLINE) seq_printf(seq, ",max_inline=%llu", info->max_inline); if (info->alloc_start != 0) seq_printf(seq, ",alloc_start=%llu", info->alloc_start); -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/14] btrfs: remove unused variable from btrfs_parse_options
Signed-off-by: David Sterba --- fs/btrfs/super.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2375f94fb780..1c6da8e00c1b 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -395,7 +395,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) int ret = 0; char *compress_type; bool compress_force = false; - bool compress = false; cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); if (cache_gen) @@ -473,7 +472,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) /* Fallthrough */ case Opt_compress: case Opt_compress_type: - compress = true; if (token == Opt_compress || token == Opt_compress_force || strcmp(args[0].from, "zlib") == 0) { @@ -503,7 +501,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) btrfs_set_and_info(root, FORCE_COMPRESS, "force %s compression", compress_type); - } else if (compress) { + } else { if (!btrfs_test_opt(root, COMPRESS)) btrfs_info(root->fs_info, "btrfs: use %s compression", -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/14] btrfs: use enum for wq endio metadata type
The enum exists but is not consistently used. Signed-off-by: David Sterba --- fs/btrfs/compression.c | 11 +++ fs/btrfs/disk-io.c | 14 +++--- fs/btrfs/disk-io.h | 4 ++-- fs/btrfs/inode.c | 3 ++- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 13842cd0..d3220d31d3cb 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -388,7 +388,8 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, * freed before we're done setting it up */ atomic_inc(&cb->pending_bios); - ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); + ret = btrfs_bio_wq_end_io(root->fs_info, bio, + BTRFS_WQ_ENDIO_DATA); BUG_ON(ret); /* -ENOMEM */ if (!skip_sum) { @@ -419,7 +420,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, } bio_get(bio); - ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); + ret = btrfs_bio_wq_end_io(root->fs_info, bio, BTRFS_WQ_ENDIO_DATA); BUG_ON(ret); /* -ENOMEM */ if (!skip_sum) { @@ -668,7 +669,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, PAGE_CACHE_SIZE) { bio_get(comp_bio); - ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); + ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, + BTRFS_WQ_ENDIO_DATA); BUG_ON(ret); /* -ENOMEM */ /* @@ -706,7 +708,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, } bio_get(comp_bio); - ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); + ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, + BTRFS_WQ_ENDIO_DATA); BUG_ON(ret); /* -ENOMEM */ if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 9b2a741370b7..d7cb58ed2946 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -82,7 +82,7 @@ struct end_io_wq { void *private; struct btrfs_fs_info *info; int error; - int metadata; + enum btrfs_wq_endio_type metadata; struct list_head list; struct btrfs_work work; }; @@ -733,16 +733,8 @@ static void end_workqueue_bio(struct bio *bio, int err) btrfs_queue_work(wq, &end_io_wq->work); } -/* - * For the metadata arg you want - * - * 0 - if data - * 1 - if normal metadta - * 2 - if writing to the free space cache area - * 3 - raid parity work - */ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, - int metadata) + enum btrfs_wq_endio_type metadata) { struct end_io_wq *end_io_wq; @@ -930,7 +922,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, * can happen in the async kernel threads */ ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info, - bio, 1); + bio, BTRFS_WQ_ENDIO_METADATA); if (ret) goto out_w_error; ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 14d06ee1e143..84da438fd9a3 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -25,7 +25,7 @@ #define BTRFS_SUPER_MIRROR_MAX 3 #define BTRFS_SUPER_MIRROR_SHIFT 12 -enum { +enum btrfs_wq_endio_type { BTRFS_WQ_ENDIO_DATA = 0, BTRFS_WQ_ENDIO_METADATA = 1, BTRFS_WQ_ENDIO_FREE_SPACE = 2, @@ -120,7 +120,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(char *data, u32 seed, size_t len); void btrfs_csum_final(u32 crc, char *result); int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, - int metadata); + enum btrfs_wq_endio_type metadata); int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, int rw, struct bio *bio, int mirror_num, unsigned long bio_flags, u64 bio_offset, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 344a322eb386..b1e388dea7b8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7721,7 +7721,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, bio_get(bio); if (!write) { - ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); + ret = btrfs_bio_wq_end_io(root->fs_info, bio, + BTRFS_WQ_ENDIO_DATA);
[PATCH 04/14] btrfs: remove unused extent state bits
The last users are long gone. Signed-off-by: David Sterba --- fs/btrfs/extent_io.h | 4 1 file changed, 4 deletions(-) diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 5e91fb9d1764..1e06f0e4a185 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -11,8 +11,6 @@ #define EXTENT_NEW (1 << 4) #define EXTENT_DELALLOC (1 << 5) #define EXTENT_DEFRAG (1 << 6) -#define EXTENT_DEFRAG_DONE (1 << 7) -#define EXTENT_BUFFER_FILLED (1 << 8) #define EXTENT_BOUNDARY (1 << 9) #define EXTENT_NODATASUM (1 << 10) #define EXTENT_DO_ACCOUNTING (1 << 11) @@ -34,7 +32,6 @@ /* these are bit numbers for test/set bit */ #define EXTENT_BUFFER_UPTODATE 0 -#define EXTENT_BUFFER_BLOCKING 1 #define EXTENT_BUFFER_DIRTY 2 #define EXTENT_BUFFER_CORRUPT 3 #define EXTENT_BUFFER_READAHEAD 4 /* this got triggered by readahead */ @@ -57,7 +54,6 @@ * map has page->private set to one. */ #define EXTENT_PAGE_PRIVATE 1 -#define EXTENT_PAGE_PRIVATE_FIRST_PAGE 3 struct extent_state; struct btrfs_root; -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/14] btrfs: hide typecast to definition of BTRFS_SEND_TRANS_STUB
Signed-off-by: David Sterba --- fs/btrfs/disk-io.c | 3 +-- fs/btrfs/send.c| 2 +- fs/btrfs/transaction.c | 2 +- fs/btrfs/transaction.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2f075ef20050..0abf4b0a9010 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -347,8 +347,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, { struct extent_state *cached_state = NULL; int ret; - bool need_lock = (current->journal_info == - (void *)BTRFS_SEND_TRANS_STUB); + bool need_lock = (current->journal_info == BTRFS_SEND_TRANS_STUB); if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 7edfc7cebda4..8b44630f4abf 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5728,7 +5728,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) NULL); sort_clone_roots = 1; - current->journal_info = (void *)BTRFS_SEND_TRANS_STUB; + current->journal_info = BTRFS_SEND_TRANS_STUB; ret = send_subvol(sctx); current->journal_info = NULL; if (ret < 0) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 16d0c1b62b3e..f4c194b160b7 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -386,7 +386,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, int ret; /* Send isn't supposed to start transactions. */ - ASSERT(current->journal_info != (void *)BTRFS_SEND_TRANS_STUB); + ASSERT(current->journal_info != BTRFS_SEND_TRANS_STUB); if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) return ERR_PTR(-EROFS); diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 579be51b27e5..d8f40e1a5d2d 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h @@ -79,7 +79,7 @@ struct btrfs_transaction { #define TRANS_EXTWRITERS (__TRANS_USERSPACE | __TRANS_START |\ __TRANS_ATTACH) -#define BTRFS_SEND_TRANS_STUB 1 +#define BTRFS_SEND_TRANS_STUB ((void *)1) struct btrfs_trans_handle { u64 transid; -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/14] btrfs: use slab for end_io_wq structures
The structure is frequently reused. Rename it according to the slab name. Signed-off-by: David Sterba --- fs/btrfs/disk-io.c | 38 +- fs/btrfs/disk-io.h | 2 ++ fs/btrfs/super.c | 8 +++- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d7cb58ed2946..2f075ef20050 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -72,11 +72,11 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root); static void btrfs_error_commit_super(struct btrfs_root *root); /* - * end_io_wq structs are used to do processing in task context when an IO is - * complete. This is used during reads to verify checksums, and it is used + * btrfs_end_io_wq structs are used to do processing in task context when an IO + * is complete. This is used during reads to verify checksums, and it is used * by writes to insert metadata for new file extents after IO is complete. */ -struct end_io_wq { +struct btrfs_end_io_wq { struct bio *bio; bio_end_io_t *end_io; void *private; @@ -87,6 +87,26 @@ struct end_io_wq { struct btrfs_work work; }; +static struct kmem_cache *btrfs_end_io_wq_cache; + +int __init btrfs_end_io_wq_init(void) +{ + btrfs_end_io_wq_cache = kmem_cache_create("btrfs_end_io_wq", + sizeof(struct btrfs_end_io_wq), + 0, + SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, + NULL); + if (!btrfs_end_io_wq_cache) + return -ENOMEM; + return 0; +} + +void btrfs_end_io_wq_exit(void) +{ + if (btrfs_end_io_wq_cache) + kmem_cache_destroy(btrfs_end_io_wq_cache); +} + /* * async submit bios are used to offload expensive checksumming * onto the worker threads. They checksum file and metadata bios @@ -690,7 +710,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror) static void end_workqueue_bio(struct bio *bio, int err) { - struct end_io_wq *end_io_wq = bio->bi_private; + struct btrfs_end_io_wq *end_io_wq = bio->bi_private; struct btrfs_fs_info *fs_info; struct btrfs_workqueue *wq; btrfs_work_func_t func; @@ -736,9 +756,9 @@ static void end_workqueue_bio(struct bio *bio, int err) int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, enum btrfs_wq_endio_type metadata) { - struct end_io_wq *end_io_wq; + struct btrfs_end_io_wq *end_io_wq; - end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS); + end_io_wq = kmem_cache_alloc(btrfs_end_io_wq_cache, GFP_NOFS); if (!end_io_wq) return -ENOMEM; @@ -1723,16 +1743,16 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) static void end_workqueue_fn(struct btrfs_work *work) { struct bio *bio; - struct end_io_wq *end_io_wq; + struct btrfs_end_io_wq *end_io_wq; int error; - end_io_wq = container_of(work, struct end_io_wq, work); + end_io_wq = container_of(work, struct btrfs_end_io_wq, work); bio = end_io_wq->bio; error = end_io_wq->error; bio->bi_private = end_io_wq->private; bio->bi_end_io = end_io_wq->end_io; - kfree(end_io_wq); + kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq); bio_endio_nodec(bio, error); } diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 84da438fd9a3..9ac233923ca3 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -142,6 +142,8 @@ int btree_lock_page_hook(struct page *page, void *data, void (*flush_fn)(void *)); int btrfs_calc_num_tolerated_disk_barrier_failures( struct btrfs_fs_info *fs_info); +int __init btrfs_end_io_wq_init(void); +void btrfs_end_io_wq_exit(void); #ifdef CONFIG_DEBUG_LOCK_ALLOC void btrfs_init_lockdep(void); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b915d7704f19..4685b9704f15 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2001,10 +2001,14 @@ static int __init init_btrfs_fs(void) if (err) goto free_delayed_ref; - err = btrfs_interface_init(); + err = btrfs_end_io_wq_init(); if (err) goto free_prelim_ref; + err = btrfs_interface_init(); + if (err) + goto free_end_io_wq; + btrfs_init_lockdep(); btrfs_print_info(); @@ -2021,6 +2025,8 @@ static int __init init_btrfs_fs(void) unregister_ioctl: btrfs_interface_exit(); +free_end_io_wq: + btrfs_end_io_wq_exit(); free_prelim_ref: btrfs_prelim_ref_exit(); free_delayed_ref: -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htm
[PATCH 06/14] btrfs: fix error labels in init_btrfs_fs
btrfs_interface_init rarely fails but we could leak the prelim_ref slab. Signed-off-by: David Sterba --- fs/btrfs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b1d2a42f379d..b915d7704f19 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1999,11 +1999,11 @@ static int __init init_btrfs_fs(void) err = btrfs_prelim_ref_init(); if (err) - goto free_prelim_ref; + goto free_delayed_ref; err = btrfs_interface_init(); if (err) - goto free_delayed_ref; + goto free_prelim_ref; btrfs_init_lockdep(); -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/14] btrfs: defrag, use unsigned type for extent thresh
Signed type mismatches the ioctl structure, all extent calculations are done on unsigned types. Signed-off-by: David Sterba --- fs/btrfs/ioctl.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0ff212757b95..87a7267a6bb2 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -885,7 +885,7 @@ out_unlock: * file you want to defrag, we return 0 to let you know to skip this * part of the file */ -static int check_defrag_in_cache(struct inode *inode, u64 offset, int thresh) +static int check_defrag_in_cache(struct inode *inode, u64 offset, u32 thresh) { struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_map *em = NULL; @@ -920,7 +920,7 @@ static int check_defrag_in_cache(struct inode *inode, u64 offset, int thresh) */ static int find_new_extents(struct btrfs_root *root, struct inode *inode, u64 newer_than, - u64 *off, int thresh) + u64 *off, u32 thresh) { struct btrfs_path *path; struct btrfs_key min_key; @@ -1029,7 +1029,7 @@ static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em) return ret; } -static int should_defrag_range(struct inode *inode, u64 start, int thresh, +static int should_defrag_range(struct inode *inode, u64 start, u32 thresh, u64 *last_len, u64 *skip, u64 *defrag_end, int compress) { @@ -1259,7 +1259,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, int ret; int defrag_count = 0; int compress_type = BTRFS_COMPRESS_ZLIB; - int extent_thresh = range->extent_thresh; + u32 extent_thresh = range->extent_thresh; unsigned long max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT; unsigned long cluster = max_cluster; u64 new_align = ~((u64)128 * 1024 - 1); -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/14] btrfs: remove unused members from struct scrub_warning
Signed-off-by: David Sterba --- fs/btrfs/scrub.c | 17 ++--- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index b9c37ac9ed1b..efa083113827 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -177,17 +177,12 @@ struct scrub_copy_nocow_ctx { struct scrub_warning { struct btrfs_path *path; u64 extent_item_size; - char*scratch_buf; - char*msg_buf; const char *errstr; sector_tsector; u64 logical; struct btrfs_device *dev; - int msg_bufsize; - int scratch_bufsize; }; - static void scrub_pending_bio_inc(struct scrub_ctx *sctx); static void scrub_pending_bio_dec(struct scrub_ctx *sctx); static void scrub_pending_trans_workers_inc(struct scrub_ctx *sctx); @@ -551,7 +546,6 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) u64 ref_root; u32 item_size; u8 ref_level; - const int bufsize = 4096; int ret; WARN_ON(sblock->page_count < 1); @@ -559,18 +553,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) fs_info = sblock->sctx->dev_root->fs_info; path = btrfs_alloc_path(); + if (!path) + return; - swarn.scratch_buf = kmalloc(bufsize, GFP_NOFS); - swarn.msg_buf = kmalloc(bufsize, GFP_NOFS); swarn.sector = (sblock->pagev[0]->physical) >> 9; swarn.logical = sblock->pagev[0]->logical; swarn.errstr = errstr; swarn.dev = NULL; - swarn.msg_bufsize = bufsize; - swarn.scratch_bufsize = bufsize; - - if (!path || !swarn.scratch_buf || !swarn.msg_buf) - goto out; ret = extent_from_logical(fs_info, swarn.logical, path, &found_key, &flags); @@ -611,8 +600,6 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) out: btrfs_free_path(path); - kfree(swarn.scratch_buf); - kfree(swarn.msg_buf); } static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx) -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/14] btrfs: new define for the inline extent data start
Use a common definition for the inline data start so we don't have to open-code it and introduce bugs like "Btrfs: fix wrong max inline data size limit" fixed. Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 3 +-- fs/btrfs/ctree.h | 16 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 39021bf2df9a..533657c508e2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -4625,8 +4625,7 @@ void btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, ptr = btrfs_item_ptr_offset(leaf, slot); memmove_extent_buffer(leaf, ptr, (unsigned long)fi, - offsetof(struct btrfs_file_extent_item, -disk_bytenr)); + BTRFS_FILE_EXTENT_INLINE_DATA_START); } } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index dd79ba7ee3ea..bae025a20e63 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -385,9 +385,11 @@ struct btrfs_header { sizeof(struct btrfs_key_ptr)) #define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) #define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->nodesize)) +#define BTRFS_FILE_EXTENT_INLINE_DATA_START\ + (offsetof(struct btrfs_file_extent_item, disk_bytenr)) #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) - \ - offsetof(struct btrfs_file_extent_item, disk_bytenr)) + BTRFS_FILE_EXTENT_INLINE_DATA_START) #define BTRFS_MAX_XATTR_SIZE(r)(BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) -\ sizeof(struct btrfs_dir_item)) @@ -896,6 +898,8 @@ struct btrfs_file_extent_item { /* * disk space consumed by the extent, checksum blocks are included * in these numbers +* +* At this offset in the structure, the inline extent data start. */ __le64 disk_bytenr; __le64 disk_num_bytes; @@ -3043,14 +3047,12 @@ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_compression, static inline unsigned long btrfs_file_extent_inline_start(struct btrfs_file_extent_item *e) { - unsigned long offset = (unsigned long)e; - offset += offsetof(struct btrfs_file_extent_item, disk_bytenr); - return offset; + return (unsigned long)e + BTRFS_FILE_EXTENT_INLINE_DATA_START; } static inline u32 btrfs_file_extent_calc_inline_size(u32 datasize) { - return offsetof(struct btrfs_file_extent_item, disk_bytenr) + datasize; + return BTRFS_FILE_EXTENT_INLINE_DATA_START + datasize; } BTRFS_SETGET_FUNCS(file_extent_disk_bytenr, struct btrfs_file_extent_item, @@ -3080,9 +3082,7 @@ BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, struct btrfs_item *e) { - unsigned long offset; - offset = offsetof(struct btrfs_file_extent_item, disk_bytenr); - return btrfs_item_size(eb, e) - offset; + return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START; } /* this returns the number of file bytes represented by the inline item. -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/14] btrfs: let merge_reloc_roots return void
Signed-off-by: David Sterba --- fs/btrfs/relocation.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 2d221c46180c..f39abe690bb2 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2316,7 +2316,7 @@ void free_reloc_roots(struct list_head *list) } static noinline_for_stack -int merge_reloc_roots(struct reloc_control *rc) +void merge_reloc_roots(struct reloc_control *rc) { struct btrfs_root *root; struct btrfs_root *reloc_root; @@ -2397,7 +2397,6 @@ out: } BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root)); - return ret; } static void free_block_list(struct rb_root *blocks) -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/14] btrfs: move checks for DUMMY_ROOT into a helper
Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 5 ++--- fs/btrfs/ctree.h | 9 + fs/btrfs/disk-io.c | 4 +--- fs/btrfs/extent-tree.c | 16 +++- fs/btrfs/qgroup.c | 10 -- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 533657c508e2..ce1d71d171bb 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1506,10 +1506,9 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) { -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + if (btrfs_test_is_dummy_root(root)) return 0; -#endif + /* ensure we can see the force_cow */ smp_rmb(); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index bae025a20e63..557fd9520607 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -4131,4 +4131,13 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, u64 rfer, u64 excl); #endif +static inline int btrfs_test_is_dummy_root(struct btrfs_root *root) +{ +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS + if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + return 1; +#endif + return 0; +} + #endif diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0abf4b0a9010..14117f85b545 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1130,11 +1130,9 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) { -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + if (btrfs_test_is_dummy_root(root)) return alloc_test_extent_buffer(root->fs_info, bytenr, blocksize); -#endif return alloc_extent_buffer(root->fs_info, bytenr, blocksize); } diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 44d04979f071..7895db9c6bdc 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3073,10 +3073,10 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, u64, u64, u64, u64, u64, u64, int); -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + + if (btrfs_test_is_dummy_root(root)) return 0; -#endif + ref_root = btrfs_header_owner(buf); nritems = btrfs_header_nritems(buf); level = btrfs_header_level(buf); @@ -6264,10 +6264,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, int ret; struct btrfs_fs_info *fs_info = root->fs_info; -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + if (btrfs_test_is_dummy_root(root)) return 0; -#endif + add_pinned_bytes(root->fs_info, num_bytes, owner, root_objectid); /* @@ -7336,15 +7335,14 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, bool skinny_metadata = btrfs_fs_incompat(root->fs_info, SKINNY_METADATA); -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) { + if (btrfs_test_is_dummy_root(root)) { buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr, blocksize, level); if (!IS_ERR(buf)) root->alloc_bytenr += blocksize; return buf; } -#endif + block_rsv = use_block_rsv(trans, root, blocksize); if (IS_ERR(block_rsv)) return ERR_CAST(block_rsv); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index cd9717ea8c9d..48b60dbf807f 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -539,10 +539,9 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; struct btrfs_key key; -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, "a_root->state))) + if (btrfs_test_is_dummy_root(quota_root)) return 0; -#endif + path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -698,10 +697,9 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans, int ret; int slot; -#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS - if (unlikely(test_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state))) + if (btrfs_
[PATCH 11/14] btrfs: drop constant param from btrfs_release_extent_buffer_page
All callers use the same value, simplify the function. Signed-off-by: David Sterba --- fs/btrfs/extent_io.c | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 78229007f99e..638e1a5b00e2 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4450,19 +4450,16 @@ int extent_buffer_under_io(struct extent_buffer *eb) /* * Helper for releasing extent buffer page. */ -static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, - unsigned long start_idx) +static void btrfs_release_extent_buffer_page(struct extent_buffer *eb) { unsigned long index; - unsigned long num_pages; struct page *page; int mapped = !test_bit(EXTENT_BUFFER_DUMMY, &eb->bflags); BUG_ON(extent_buffer_under_io(eb)); - num_pages = num_extent_pages(eb->start, eb->len); - index = start_idx + num_pages; - if (start_idx >= index) + index = num_extent_pages(eb->start, eb->len); + if (index == 0) return; do { @@ -4498,7 +4495,7 @@ static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, /* One for when we alloced the page */ page_cache_release(page); } - } while (index != start_idx); + } while (index != 0); } /* @@ -4506,7 +4503,7 @@ static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, */ static inline void btrfs_release_extent_buffer(struct extent_buffer *eb) { - btrfs_release_extent_buffer_page(eb, 0); + btrfs_release_extent_buffer_page(eb); __free_extent_buffer(eb); } @@ -4863,7 +4860,7 @@ static int release_extent_buffer(struct extent_buffer *eb) } /* Should be safe to release our pages at this point */ - btrfs_release_extent_buffer_page(eb, 0); + btrfs_release_extent_buffer_page(eb); call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); return 1; } -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/14] btrfs: kill extent_buffer_page helper
It used to be more complex but now it's just a simple array access. Signed-off-by: David Sterba --- fs/btrfs/extent_io.c | 55 +--- fs/btrfs/extent_io.h | 6 -- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 638e1a5b00e2..3359969b1a36 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2064,7 +2064,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, return -EROFS; for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); + struct page *p = eb->pages[i]; ret = repair_io_failure(root->fs_info->btree_inode, start, PAGE_CACHE_SIZE, start, p, @@ -3580,7 +3580,7 @@ lock_extent_buffer_for_io(struct extent_buffer *eb, num_pages = num_extent_pages(eb->start, eb->len); for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); + struct page *p = eb->pages[i]; if (!trylock_page(p)) { if (!flush) { @@ -3651,7 +3651,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, bio_flags = EXTENT_BIO_TREE_LOG; for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); + struct page *p = eb->pages[i]; clear_page_dirty_for_io(p); set_page_writeback(p); @@ -3674,10 +3674,8 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, } if (unlikely(ret)) { - for (; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - unlock_page(p); - } + for (; i < num_pages; i++) + unlock_page(eb->pages[i]); } return ret; @@ -4464,7 +4462,7 @@ static void btrfs_release_extent_buffer_page(struct extent_buffer *eb) do { index--; - page = extent_buffer_page(eb, index); + page = eb->pages[index]; if (page && mapped) { spin_lock(&page->mapping->private_lock); /* @@ -4646,7 +4644,8 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb, num_pages = num_extent_pages(eb->start, eb->len); for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); + struct page *p = eb->pages[i]; + if (p != accessed) mark_page_accessed(p); } @@ -4815,7 +4814,7 @@ again: */ SetPageChecked(eb->pages[0]); for (i = 1; i < num_pages; i++) { - p = extent_buffer_page(eb, i); + p = eb->pages[i]; ClearPageChecked(p); unlock_page(p); } @@ -4926,7 +4925,7 @@ void clear_extent_buffer_dirty(struct extent_buffer *eb) num_pages = num_extent_pages(eb->start, eb->len); for (i = 0; i < num_pages; i++) { - page = extent_buffer_page(eb, i); + page = eb->pages[i]; if (!PageDirty(page)) continue; @@ -4962,7 +4961,7 @@ int set_extent_buffer_dirty(struct extent_buffer *eb) WARN_ON(!test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)); for (i = 0; i < num_pages; i++) - set_page_dirty(extent_buffer_page(eb, i)); + set_page_dirty(eb->pages[i]); return was_dirty; } @@ -4975,7 +4974,7 @@ int clear_extent_buffer_uptodate(struct extent_buffer *eb) clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb->start, eb->len); for (i = 0; i < num_pages; i++) { - page = extent_buffer_page(eb, i); + page = eb->pages[i]; if (page) ClearPageUptodate(page); } @@ -4991,7 +4990,7 @@ int set_extent_buffer_uptodate(struct extent_buffer *eb) set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb->start, eb->len); for (i = 0; i < num_pages; i++) { - page = extent_buffer_page(eb, i); + page = eb->pages[i]; SetPageUptodate(page); } return 0; @@ -5031,7 +5030,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, num_pages = num_extent_pages(eb->start, eb->len); for (i = start_i; i < num_pages; i++) { - page = extent_buffer_page(eb, i); + page = eb->pages[i]; if (wait == WAIT_NONE) { if (!trylock_page(page)) goto unlock_exit; @@ -5054,7 +5053,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
[PATCH 0/6] Cleanup, remove superfluous blocksize parameter
First portion of cleanups that remove a parameter that's being passed to a lot of functions, although the value does not change during the filesystem lifetime. This part contains the obvious and safe changes, but there are more pending that start to touch functionality and haven't not passed xfstests without warnings. You can pull from git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git cleanup/blocksize-diet-part1 David Sterba (6): btrfs: remove unused parameter from readahead_tree_block btrfs: return void from readahead_tree_block btrfs: inline code of reada_tree_block and remove it btrfs: remove parameter blocksize from read_tree_block btrfs: remove unused parameter blocksize from btrfs_find_tree_block btrfs: remove blocksize from btrfs_alloc_free_block and rename fs/btrfs/backref.c | 6 ++ fs/btrfs/ctree.c | 54 -- fs/btrfs/ctree.h | 6 +++--- fs/btrfs/disk-io.c | 37 +++--- fs/btrfs/disk-io.h | 7 +++ fs/btrfs/extent-tree.c | 20 --- fs/btrfs/ioctl.c | 3 +-- fs/btrfs/print-tree.c | 1 - fs/btrfs/relocation.c | 28 ++ 9 files changed, 57 insertions(+), 105 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] btrfs: return void from readahead_tree_block
Errors in readahead are not fatal and ignored elsewhere in the code. Signed-off-by: David Sterba --- fs/btrfs/disk-io.c | 6 ++ fs/btrfs/disk-io.h | 2 +- fs/btrfs/extent-tree.c | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ff83748d39da..332f63518156 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1062,19 +1062,17 @@ static const struct address_space_operations btree_aops = { .set_page_dirty = btree_set_page_dirty, }; -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) +void readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) { struct extent_buffer *buf = NULL; struct inode *btree_inode = root->fs_info->btree_inode; - int ret = 0; buf = btrfs_find_create_tree_block(root, bytenr, blocksize); if (!buf) - return 0; + return; read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, buf, 0, WAIT_NONE, btree_get_extent, 0); free_extent_buffer(buf); - return ret; } int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 8cd6a53db621..0d9793f6b594 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -46,7 +46,7 @@ struct btrfs_fs_devices; struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent_transid); -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); +void readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, int mirror_num, struct extent_buffer **eb); struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 058abd088f0f..e0468a9789a5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -7486,9 +7486,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, continue; } reada: - ret = readahead_tree_block(root, bytenr, blocksize); - if (ret) - break; + readahead_tree_block(root, bytenr, blocksize); nread++; } wc->reada_slot = slot; -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] btrfs: remove blocksize from btrfs_alloc_free_block and rename
Rename to btrfs_alloc_tree_block as it fits to the alloc/find/free + _tree_block family. The parameter blocksize was set to the metadata block size, directly or indirectly. Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 26 +++--- fs/btrfs/ctree.h | 6 +++--- fs/btrfs/disk-io.c | 8 +++- fs/btrfs/extent-tree.c | 5 +++-- fs/btrfs/ioctl.c | 3 +-- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 2fb4ab659a0f..d498982bd202 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -258,9 +258,8 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, else btrfs_node_key(buf, &disk_key, 0); - cow = btrfs_alloc_free_block(trans, root, buf->len, 0, -new_root_objectid, &disk_key, level, -buf->start, 0); + cow = btrfs_alloc_tree_block(trans, root, 0, new_root_objectid, + &disk_key, level, buf->start, 0); if (IS_ERR(cow)) return PTR_ERR(cow); @@ -1133,9 +1132,9 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, } else parent_start = 0; - cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, -root->root_key.objectid, &disk_key, -level, search_start, empty_size); + cow = btrfs_alloc_tree_block(trans, root, parent_start, + root->root_key.objectid, &disk_key, level, + search_start, empty_size); if (IS_ERR(cow)) return PTR_ERR(cow); @@ -3355,9 +3354,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, else btrfs_node_key(lower, &lower_key, 0); - c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, - root->root_key.objectid, &lower_key, - level, root->node->start, 0); + c = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &lower_key, level, root->node->start, 0); if (IS_ERR(c)) return PTR_ERR(c); @@ -3495,9 +3493,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, mid = (c_nritems + 1) / 2; btrfs_node_key(c, &disk_key, mid); - split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, - root->root_key.objectid, - &disk_key, level, c->start, 0); + split = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &disk_key, level, c->start, 0); if (IS_ERR(split)) return PTR_ERR(split); @@ -4275,9 +4272,8 @@ again: else btrfs_item_key(l, &disk_key, mid); - right = btrfs_alloc_free_block(trans, root, root->nodesize, 0, - root->root_key.objectid, - &disk_key, 0, l->start, 0); + right = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid, + &disk_key, 0, l->start, 0); if (IS_ERR(right)) return PTR_ERR(right); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 089f6da09411..3073b8876bca 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3290,9 +3290,9 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group( u64 bytenr); void btrfs_put_block_group(struct btrfs_block_group_cache *cache); int get_block_group_index(struct btrfs_block_group_cache *cache); -struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u32 blocksize, - u64 parent, u64 root_objectid, +struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 parent, + u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); void btrfs_free_tree_block(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e0293d2fbb3a..2e5d460d4e0c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1324,8 +1324,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, root->root_key.type = BTRFS_ROOT_ITEM_KEY; root->root_key.offset = 0; - leaf = btrfs_alloc_free_block(trans, root, root->nodesize, - 0, objectid, NULL, 0, 0, 0); + leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0);
[PATCH 5/6] btrfs: remove unused parameter blocksize from btrfs_find_tree_block
Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 12 +--- fs/btrfs/disk-io.c | 5 ++--- fs/btrfs/disk-io.h | 2 +- fs/btrfs/extent-tree.c | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 302c3f955706..2fb4ab659a0f 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1683,7 +1683,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, continue; } - cur = btrfs_find_tree_block(root, blocknr, blocksize); + cur = btrfs_find_tree_block(root, blocknr); if (cur) uptodate = btrfs_buffer_uptodate(cur, gen, 0); else @@ -2264,7 +2264,7 @@ static void reada_for_search(struct btrfs_root *root, search = btrfs_node_blockptr(node, slot); blocksize = root->nodesize; - eb = btrfs_find_tree_block(root, search, blocksize); + eb = btrfs_find_tree_block(root, search); if (eb) { free_extent_buffer(eb); return; @@ -2326,7 +2326,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot > 0) { block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); - eb = btrfs_find_tree_block(root, block1, blocksize); + eb = btrfs_find_tree_block(root, block1); /* * if we get -eagain from btrfs_buffer_uptodate, we * don't want to return eagain here. That will loop @@ -2339,7 +2339,7 @@ static noinline void reada_for_balance(struct btrfs_root *root, if (slot + 1 < nritems) { block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); - eb = btrfs_find_tree_block(root, block2, blocksize); + eb = btrfs_find_tree_block(root, block2); if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) block2 = 0; free_extent_buffer(eb); @@ -2450,16 +2450,14 @@ read_block_for_search(struct btrfs_trans_handle *trans, { u64 blocknr; u64 gen; - u32 blocksize; struct extent_buffer *b = *eb_ret; struct extent_buffer *tmp; int ret; blocknr = btrfs_node_blockptr(b, slot); gen = btrfs_node_ptr_generation(b, slot); - blocksize = root->nodesize; - tmp = btrfs_find_tree_block(root, blocknr, blocksize); + tmp = btrfs_find_tree_block(root, blocknr); if (tmp) { /* first we do an atomic uptodate check */ if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 03c0973568ef..e0293d2fbb3a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1108,7 +1108,7 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, } struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, - u64 bytenr, u32 blocksize) + u64 bytenr) { return find_extent_buffer(root->fs_info, bytenr); } @@ -4002,8 +4002,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); while (start <= end) { - eb = btrfs_find_tree_block(root, start, - root->nodesize); + eb = btrfs_find_tree_block(root, start); start += root->nodesize; if (!eb) continue; diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 03f396144fe1..ae04daef6087 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -62,7 +62,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct buffer_head *btrfs_read_dev_super(struct block_device *bdev); int btrfs_commit_super(struct btrfs_root *root); struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, - u64 bytenr, u32 blocksize); + u64 bytenr); struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root, struct btrfs_key *location); int btrfs_init_fs_root(struct btrfs_root *root); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 178f6dbf2d7c..d9a90da93302 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -7825,7 +7825,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); blocksize = root->nodesize; - next = btrfs_find_tree_block(root, bytenr, blocksize); + next = btrfs_find_tree_bl
[PATCH 1/6] btrfs: remove unused parameter from readahead_tree_block
The parent_transid parameter has been unused since its introduction in ca7a79ad8dbe2466 ("Pass down the expected generation number when reading tree blocks"). In reada_tree_block, it was even wrongly set to leafsize. Transid check is done in the proper read and readahead ignores errors. Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 6 +++--- fs/btrfs/disk-io.c | 3 +-- fs/btrfs/disk-io.h | 3 +-- fs/btrfs/extent-tree.c | 3 +-- fs/btrfs/relocation.c | 9 ++--- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 39021bf2df9a..1b7e3545a596 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2298,7 +2298,7 @@ static void reada_for_search(struct btrfs_root *root, if ((search <= target && target - search <= 65536) || (search > target && search - target <= 65536)) { gen = btrfs_node_ptr_generation(node, nr); - readahead_tree_block(root, search, blocksize, gen); + readahead_tree_block(root, search, blocksize); nread += blocksize; } nscan++; @@ -2350,9 +2350,9 @@ static noinline void reada_for_balance(struct btrfs_root *root, } if (block1) - readahead_tree_block(root, block1, blocksize, 0); + readahead_tree_block(root, block1, blocksize); if (block2) - readahead_tree_block(root, block2, blocksize, 0); + readahead_tree_block(root, block2, blocksize); } diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4780e6623c7b..ff83748d39da 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1062,8 +1062,7 @@ static const struct address_space_operations btree_aops = { .set_page_dirty = btree_set_page_dirty, }; -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, -u64 parent_transid) +int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) { struct extent_buffer *buf = NULL; struct inode *btree_inode = root->fs_info->btree_inode; diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 14d06ee1e143..8cd6a53db621 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -46,8 +46,7 @@ struct btrfs_fs_devices; struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent_transid); -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, -u64 parent_transid); +int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, int mirror_num, struct extent_buffer **eb); struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 44d04979f071..058abd088f0f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -7486,8 +7486,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, continue; } reada: - ret = readahead_tree_block(root, bytenr, blocksize, - generation); + ret = readahead_tree_block(root, bytenr, blocksize); if (ret) break; nread++; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 2d221c46180c..16cb2b4a9620 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2861,13 +2861,8 @@ static int reada_tree_block(struct reloc_control *rc, struct tree_block *block) { BUG_ON(block->key_ready); - if (block->key.type == BTRFS_METADATA_ITEM_KEY) - readahead_tree_block(rc->extent_root, block->bytenr, -block->key.objectid, -rc->extent_root->nodesize); - else - readahead_tree_block(rc->extent_root, block->bytenr, -block->key.objectid, block->key.offset); + readahead_tree_block(rc->extent_root, block->bytenr, + block->key.objectid); return 0; } -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] btrfs: remove parameter blocksize from read_tree_block
We know the tree block size, no need to pass it around. Signed-off-by: David Sterba --- fs/btrfs/backref.c | 6 ++ fs/btrfs/ctree.c | 10 +++--- fs/btrfs/disk-io.c | 17 + fs/btrfs/disk-io.h | 2 +- fs/btrfs/extent-tree.c | 8 +++- fs/btrfs/print-tree.c | 1 - fs/btrfs/relocation.c | 11 --- 7 files changed, 18 insertions(+), 37 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 6829dc5aa657..2d3e32ebfd15 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -490,7 +490,7 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, continue; BUG_ON(!ref->wanted_disk_byte); eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, -fs_info->tree_root->nodesize, 0); +0); if (!eb || !extent_buffer_uptodate(eb)) { free_extent_buffer(eb); return -EIO; @@ -1028,12 +1028,10 @@ again: if (ref->count && ref->parent) { if (extent_item_pos && !ref->inode_list && ref->level == 0) { - u32 bsz; struct extent_buffer *eb; - bsz = fs_info->extent_root->nodesize; eb = read_tree_block(fs_info->extent_root, - ref->parent, bsz, 0); + ref->parent, 0); if (!eb || !extent_buffer_uptodate(eb)) { free_extent_buffer(eb); ret = -EIO; diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 1b7e3545a596..302c3f955706 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1425,7 +1425,6 @@ get_old_root(struct btrfs_root *root, u64 time_seq) struct tree_mod_root *old_root = NULL; u64 old_generation = 0; u64 logical; - u32 blocksize; eb_root = btrfs_read_lock_root_node(root); tm = __tree_mod_log_oldest_root(root->fs_info, eb_root, time_seq); @@ -1444,8 +1443,7 @@ get_old_root(struct btrfs_root *root, u64 time_seq) if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) { btrfs_tree_read_unlock(eb_root); free_extent_buffer(eb_root); - blocksize = root->nodesize; - old = read_tree_block(root, logical, blocksize, 0); + old = read_tree_block(root, logical, 0); if (WARN_ON(!old || !extent_buffer_uptodate(old))) { free_extent_buffer(old); btrfs_warn(root->fs_info, @@ -1692,8 +1690,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, uptodate = 0; if (!cur || !uptodate) { if (!cur) { - cur = read_tree_block(root, blocknr, -blocksize, gen); + cur = read_tree_block(root, blocknr, gen); if (!cur || !extent_buffer_uptodate(cur)) { free_extent_buffer(cur); return -EIO; @@ -1872,7 +1869,6 @@ static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root, BUG_ON(level == 0); eb = read_tree_block(root, btrfs_node_blockptr(parent, slot), -root->nodesize, btrfs_node_ptr_generation(parent, slot)); if (eb && !extent_buffer_uptodate(eb)) { free_extent_buffer(eb); @@ -2507,7 +2503,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, btrfs_release_path(p); ret = -EAGAIN; - tmp = read_tree_block(root, blocknr, blocksize, 0); + tmp = read_tree_block(root, blocknr, 0); if (tmp) { /* * If the read above didn't mark this buffer up to date, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 332f63518156..03c0973568ef 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1138,12 +1138,12 @@ int btrfs_wait_tree_block_writeback(struct extent_buffer *buf) } struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, - u32 blocksize, u64 parent_transid) + u64 parent_transid) { struct extent_buffer *buf = NULL; int ret; - buf = btrfs_find_create_tree_block(root, bytenr, blocksize); + buf = btrfs_find_create_tree_block(root, bytenr, root->nodesize); if (!buf) return NULL; @@ -1484,7 +1484,6 @@ static struct btrfs_root *btrfs_rea
[PATCH 3/6] btrfs: inline code of reada_tree_block and remove it
It's trivial with a single user. And remove one pointless BUG_ON. Signed-off-by: David Sterba --- fs/btrfs/relocation.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 16cb2b4a9620..d7506325b024 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2857,15 +2857,6 @@ static int get_tree_block_key(struct reloc_control *rc, return 0; } -static int reada_tree_block(struct reloc_control *rc, - struct tree_block *block) -{ - BUG_ON(block->key_ready); - readahead_tree_block(rc->extent_root, block->bytenr, - block->key.objectid); - return 0; -} - /* * helper function to relocate a tree block */ @@ -2945,7 +2936,8 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans, while (rb_node) { block = rb_entry(rb_node, struct tree_block, rb_node); if (!block->key_ready) - reada_tree_block(rc, block); + readahead_tree_block(rc->extent_root, block->bytenr, + block->key.objectid); rb_node = rb_next(rb_node); } -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] Remove branch hints
Two patches removing some 'unlikely' branch hints where it does not make much sense. Sent separately from the other cleanups in case they do not seem to fit. You can pull from git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git remove-unlikely David Sterba (2): btrfs: remove unlikely from NULL checks btrfs: remove unlikely from data-dependent branches and slow paths fs/btrfs/async-thread.c | 10 +- fs/btrfs/extent-tree.c | 4 ++-- fs/btrfs/file.c | 4 ++-- fs/btrfs/inode.c| 10 +- fs/btrfs/ioctl.c| 2 +- fs/btrfs/transaction.c | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] btrfs: remove unlikely from NULL checks
Unlikely is implicit for NULL checks of pointers. Signed-off-by: David Sterba --- fs/btrfs/async-thread.c | 10 +- fs/btrfs/inode.c| 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 2da0a66790ba..4dabeb893b7c 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -92,7 +92,7 @@ __btrfs_alloc_workqueue(const char *name, int flags, int max_active, { struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS); - if (unlikely(!ret)) + if (!ret) return NULL; ret->max_active = max_active; @@ -116,7 +116,7 @@ __btrfs_alloc_workqueue(const char *name, int flags, int max_active, ret->normal_wq = alloc_workqueue("%s-%s", flags, ret->max_active, "btrfs", name); - if (unlikely(!ret->normal_wq)) { + if (!ret->normal_wq) { kfree(ret); return NULL; } @@ -138,12 +138,12 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, { struct btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS); - if (unlikely(!ret)) + if (!ret) return NULL; ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI, max_active, thresh); - if (unlikely(!ret->normal)) { + if (!ret->normal) { kfree(ret); return NULL; } @@ -151,7 +151,7 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, if (flags & WQ_HIGHPRI) { ret->high = __btrfs_alloc_workqueue(name, flags, max_active, thresh); - if (unlikely(!ret->high)) { + if (!ret->high) { __btrfs_destroy_workqueue(ret->normal); kfree(ret); return NULL; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 344a322eb386..998e67fdf2f6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9013,7 +9013,7 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput, spin_unlock(&root->delalloc_lock); work = btrfs_alloc_delalloc_work(inode, 0, delay_iput); - if (unlikely(!work)) { + if (!work) { if (delay_iput) btrfs_add_delayed_iput(inode); else -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] btrfs: remove unlikely from data-dependent branches and slow paths
There are the branch hints that obviously depend on the data being processed, the CPU predictor will do better job according to the actual load. It also does not make sense to use the hints in slow paths that do a lot of other operations like locking, waiting or IO. Signed-off-by: David Sterba --- fs/btrfs/extent-tree.c | 4 ++-- fs/btrfs/file.c| 4 ++-- fs/btrfs/inode.c | 8 fs/btrfs/ioctl.c | 2 +- fs/btrfs/transaction.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 44d04979f071..ede740bfaac0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -9694,7 +9694,7 @@ void btrfs_end_nocow_write(struct btrfs_root *root) int btrfs_start_nocow_write(struct btrfs_root *root) { - if (unlikely(atomic_read(&root->will_be_snapshoted))) + if (atomic_read(&root->will_be_snapshoted)) return 0; percpu_counter_inc(&root->subv_writers->counter); @@ -9702,7 +9702,7 @@ int btrfs_start_nocow_write(struct btrfs_root *root) * Make sure counter is updated before we check for snapshot creation. */ smp_mb(); - if (unlikely(atomic_read(&root->will_be_snapshoted))) { + if (atomic_read(&root->will_be_snapshoted)) { btrfs_end_nocow_write(root); return 0; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 29b147d46b0a..a18ceabd99a8 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -452,7 +452,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, if (unlikely(copied == 0)) break; - if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { + if (copied < PAGE_CACHE_SIZE - offset) { offset += copied; } else { pg++; @@ -1792,7 +1792,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, if (sync) atomic_inc(&BTRFS_I(inode)->sync_writers); - if (unlikely(file->f_flags & O_DIRECT)) { + if (file->f_flags & O_DIRECT) { num_written = __btrfs_direct_write(iocb, from, pos); } else { num_written = __btrfs_buffered_write(file, from, pos); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 998e67fdf2f6..47d214560831 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7802,9 +7802,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, atomic_inc(&dip->pending_bios); while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { - if (unlikely(map_length < submit_len + bvec->bv_len || + if (map_length < submit_len + bvec->bv_len || bio_add_page(bio, bvec->bv_page, bvec->bv_len, -bvec->bv_offset) < bvec->bv_len)) { +bvec->bv_offset) < bvec->bv_len) { /* * inc the count before we submit the bio so * we know the end IO handler won't happen before @@ -8017,8 +8017,8 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, ret = btrfs_delalloc_reserve_space(inode, count); if (ret) goto out; - } else if (unlikely(test_bit(BTRFS_INODE_READDIO_NEED_LOCK, -&BTRFS_I(inode)->runtime_flags))) { + } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, +&BTRFS_I(inode)->runtime_flags)) { inode_dio_done(inode); flags = DIO_LOCKING | DIO_SKIP_HOLES; wakeup = false; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0ff212757b95..f2c60cd70e63 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3167,7 +3167,7 @@ static void clone_update_extent_map(struct inode *inode, em->start + em->len - 1, 0); } - if (unlikely(ret)) + if (ret) set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags); } diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 16d0c1b62b3e..8eded14e8c5c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -418,7 +418,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, /* * Do the reservation for the relocation root creation */ - if (unlikely(need_reserve_reloc_root(root))) { + if (need_reserve_reloc_root(root)) { num_bytes += root->nodesize; reloc_reserved = true; } -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://v
[PATCH] btrfs-progs: scrub, detect stale information in the status file
If scrub is not cancelled nor finished, the recorded status will prevent scrub to start again though it's not running. There's a force option to run it anyway, but this is just a bandaid and the true status of scrub should be detected automatically. The force option should not be necessary anymore. The test introduced in 9681f82853360aac1ff2 checks only the status file, not kernel status of scrub. Signed-off-by: David Sterba --- cmds-scrub.c | 40 +++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/cmds-scrub.c b/cmds-scrub.c index 731c5c94e6cc..eb50d8a65708 100644 --- a/cmds-scrub.c +++ b/cmds-scrub.c @@ -59,6 +59,7 @@ struct scrub_stats { u64 duration; u64 finished; u64 canceled; + int in_progress; }; /* TBD: replace with #include "linux/ioprio.h" in some years */ @@ -251,7 +252,11 @@ static void _print_scrub_ss(struct scrub_stats *ss) printf(" and was aborted after %llu seconds\n", ss->duration); } else { - printf(", running for %llu seconds\n", ss->duration); + if (ss->in_progress) + printf(", running for %llu seconds\n", ss->duration); + else + printf(", interrupted after %llu seconds, not running\n", + ss->duration); } } @@ -1057,6 +1062,28 @@ static int is_scrub_running_on_fs(struct btrfs_ioctl_fs_info_args *fi_args, return 0; } +static int is_scrub_running_in_kernel(int fd, + struct btrfs_ioctl_dev_info_args *di_args, u64 max_devices) +{ + struct scrub_progress sp; + int i; + int ret; + + for (i = 0; i < max_devices; i++) { + memset(&sp, 0, sizeof(sp)); + sp.scrub_args.devid = di_args[i].devid; + ret = ioctl(fd, BTRFS_IOC_SCRUB_PROGRESS, &sp.scrub_args); + if (ret < 0 && errno == ENODEV) + continue; + if (ret < 0 && errno == ENOTCONN) + return 0; + if (!ret) + return 1; + } + + return 1; +} + static const char * const cmd_scrub_start_usage[]; static const char * const cmd_scrub_resume_usage[]; @@ -1206,6 +1233,13 @@ static int scrub_start(int argc, char **argv, int resume) } /* +* Check for stale information in the status file, ie. if it's +* canceled=0, finished=0 but no scrub is running. +*/ + if (!is_scrub_running_in_kernel(fdmnt, di_args, fi_args.num_devices)) + force = 1; + + /* * check whether any involved device is already busy running a * scrub. This would cause damaged status messages and the state * "aborted" without the explanation that a scrub was already @@ -1636,6 +1670,7 @@ static int cmd_scrub_status(int argc, char **argv) struct sockaddr_un addr = { .sun_family = AF_UNIX, }; + int in_progress; int ret; int i; int fdmnt; @@ -1725,6 +1760,7 @@ static int cmd_scrub_status(int argc, char **argv) fprintf(stderr, "WARNING: failed to read status: %s\n", strerror(-PTR_ERR(past_scrubs))); } + in_progress = is_scrub_running_in_kernel(fdmnt, di_args, fi_args.num_devices); printf("scrub status for %s\n", fsid); @@ -1737,6 +1773,7 @@ static int cmd_scrub_status(int argc, char **argv) NULL, NULL); continue; } + last_scrub->stats.in_progress = in_progress; print_scrub_dev(&di_args[i], &last_scrub->p, print_raw, last_scrub->stats.finished ? "history" : "status", @@ -1744,6 +1781,7 @@ static int cmd_scrub_status(int argc, char **argv) } } else { init_fs_stat(&fs_stat); + fs_stat.s.in_progress = in_progress; for (i = 0; i < fi_args.num_devices; ++i) { last_scrub = last_dev_scrub(past_scrubs, di_args[i].devid); -- 2.1.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Btrfs: send, don't delay dir move if there's a new parent inode
If between two snapshots we rename an existing directory named X to Y and make it a child (direct or not) of a new inode named X, we were delaying the move/rename of the former directory unnecessarily, which would result in attempting to rename the new directory from its orphan name to name X prematurely. Minimal reproducer: $ mkfs.btrfs -f /dev/vdd $ mount /dev/vdd /mnt $ mkdir -p /mnt/merlin/RC/OSD/Source $ btrfs subvolume snapshot -r /mnt /mnt/mysnap1 $ mkdir /mnt/OSD $ mv /mnt/merlin/RC/OSD /mnt/OSD/OSD-Plane_788 $ mv /mnt/OSD /mnt/merlin/RC $ btrfs subvolume snapshot -r /mnt /mnt/mysnap2 $ btrfs send /mnt/mysnap1 -f /tmp/1.snap $ btrfs send -p /mnt/mysnap1 /mnt/mysnap2 -f /tmp/2.snap $ mkfs.btrfs -f /dev/vdc $ mount /dev/vdc /mnt2 $ btrfs receive /mnt2 -f /tmp/1.snap $ btrfs receive /mnt2 -f /tmp/2.snap The second receive (from an incremental send) failed with the following error message: "rename o261-7-0 -> merlin/RC/OSD failed". This is a regression introduced in the 3.16 kernel. A test case for xfstests follows. Reported-by: Marc Merlin Signed-off-by: Filipe Manana --- fs/btrfs/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 7edfc7c..b9c27aa 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -3327,7 +3327,7 @@ static int wait_for_parent_move(struct send_ctx *sctx, if (ret < 0 && ret != -ENOENT) { goto out; } else if (ret == -ENOENT) { - ret = 1; + ret = 0; break; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] fstests: regression test for btrfs incremental send
This is a regression test for a btrfs incremental send issue. If between two snapshots we rename an existing directory named X to Y and make it a child (direct or not) of a new inode named X, we were delaying the move/rename of the former directory unnecessarily, which would result in attempting to rename the new directory from its orphan name to name X prematurely. This made btrfs receive fail with an error message like the following: rename o261-7-0 -> merlin/RC/OSD failed This issue was a regression in the 3.16 kernel and got fixed by the following linux kernel btrfs patch: Btrfs: send, don't delay dir move if there's a new parent inode Signed-off-by: Filipe Manana --- tests/btrfs/060 | 148 tests/btrfs/060.out | 2 + tests/btrfs/group | 1 + 3 files changed, 151 insertions(+) create mode 100755 tests/btrfs/060 create mode 100644 tests/btrfs/060.out diff --git a/tests/btrfs/060 b/tests/btrfs/060 new file mode 100755 index 000..20dc0ad --- /dev/null +++ b/tests/btrfs/060 @@ -0,0 +1,148 @@ +#! /bin/bash +# FS QA Test No. btrfs/060 +# +# Regression test for a btrfs incremental send issue. +# If between two snapshots we rename an existing directory named X to Y and +# make it a child (direct or not) of a new inode named X, we were delaying +# the move/rename of the former directory unnecessarily, which would result +# in attempting to rename the new directory from its orphan name to name X +# prematurely. This made btrfs receive fail with an error message like the +# following: +# +# rename o261-7-0 -> merlin/RC/OSD failed +# +# This issue was a regression in the 3.16 kernel and got fixed by the following +# linux kernel btrfs patch: +# +# Btrfs: send, don't delay dir move if there's a new parent inode +# +#--- +# Copyright (C) 2014 SUSE Linux Products GmbH. All Rights Reserved. +# Author: Filipe Manana +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#--- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +tmp=`mktemp -d` +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ +rm -fr $send_files_dir +rm -fr $tmp +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs btrfs +_supported_os Linux +_require_scratch +_require_fssum +_need_to_be_root + +send_files_dir=$TEST_DIR/btrfs-test-$seq + +rm -f $seqres.full +rm -fr $send_files_dir +mkdir $send_files_dir + +_scratch_mkfs >>$seqres.full 2>&1 +_scratch_mount + +mkdir -p $SCRATCH_MNT/merlin/RC/OSD/Source +mkdir -p $SCRATCH_MNT/fdm/RCz/OSDz/Sourcez +mkdir -p $SCRATCH_MNT/Z/Z2 + +# Filesystem looks like: +# +# . (ino 256) +# | merlin/ (ino 257) +# || RC/(ino 258) +# | |- OSD/(ino 259) +# | | Source/ (ino 260) +# | +# | fdm/(ino 261) +# | | RCz/(ino 262) +# | |- OSDz/(ino 263) +# | | Sourcez/ (ino 264) +# | +# | Z/ (ino 265) +# | Z2/ (ino 266) +# +_run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1 + +mkdir $SCRATCH_MNT/OSD +mv $SCRATCH_MNT/merlin/RC/OSD $SCRATCH_MNT/OSD/OSD-Plane_788 +mv $SCRATCH_MNT/OSD $SCRATCH_MNT/merlin/RC + +mkdir $SCRATCH_MNT/OSDz +mv $SCRATCH_MNT/Z/Z2 $SCRATCH_MNT/OSDz/xz2 +mv $SCRATCH_MNT/Z $SCRATCH_MNT/OSDz/xz2/xz +mv $SCRATCH_MNT/fdm/RCz/OSDz $SCRATCH_MNT/OSDz/xz2/xz/OSD-Plane_788z +mv $SCRATCH_MNT/OSDz $SCRATCH_MNT/fdm/RCz + +# Filesystem now looks like: +# +# +# . (ino 256) +# | merlin/ (ino 257) +# | | RC/ (ino 258) +# | |- OSD/ (ino 267) (new) +# |
Re: FIBMAP unsupported
On Thu, Oct 02, 2014 at 05:13:22PM +0200, Marc Dietrich wrote: > I have a large (25G) virtual disk on a btrfs fs. Yes, I know this is not > optimial. So I try to defrag it from time to time. However, using "btrfs fi > defrag -c vm.vdi" results in even more fragments than before (reported by > filefrag). So I wrote my own pseudo defragger, Unfortunatelly the default target fragment size is 256k. Try 'btrfs filesystem defrag -t 32m ...' or higher numbers and see if it helps. > which produces much better results (ok, the file must not be in use). > Somewhere in the 3.17 cycle the resulting image got corrupted using the > script > above. > > Running filefrag on it returns "FIBMAP unsupported". This message doe not mean it is a corruption, but filefrag tries to use the FIBMAP ioctl that is not implemented on btrfs, instead FIEMAP is used. filefrag on a nocow file works for me here (3.16.x kernel), I can see that filefrag on a directory prints the FIBMAP message. > Virtualbox returns "AHCI#0P0: Read at offset 606236672 (49152 bytes left) > returned rc=VERR_DEV_IO_ERROR". No errors in the kernel log. > > Trying "cp vm.vdi /dev/null" returns: cp: Error reading „vm.vdi“: IO-Error This could be caused by the virtualization layer. Try to run scrub and fsck in the non-destru^Wchecking mode if it finds problems. As you're using compression and autodefrag, a quick skim of the 3.17 patches points to e9512d72e8e61c750c90efacd720abe3c4569822 "fix autodefrag with compression", but that's just "keyword" match. There's another report about nocow corruption and VirtualBox in a 3.16 + for-linus version (which is almost 3.17-rc) http://article.gmane.org/gmane.comp.file-systems.btrfs/38701/ But according to the attached messages, the underlying device is unreliable and logs a lot of IO errors. For now it looks like VirutalBox is not writing the data or there is a bug introduced post 3.16 killing nocow files. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: FIBMAP unsupported
On Thu, Oct 02, 2014 at 07:25:49PM +0200, David Sterba wrote: > On Thu, Oct 02, 2014 at 05:13:22PM +0200, Marc Dietrich wrote: > > I have a large (25G) virtual disk on a btrfs fs. Yes, I know this is not > > optimial. So I try to defrag it from time to time. However, using "btrfs fi > > defrag -c vm.vdi" results in even more fragments than before (reported by > > filefrag). So I wrote my own pseudo defragger, > > Unfortunatelly the default target fragment size is 256k. Try > 'btrfs filesystem defrag -t 32m ...' or higher numbers and see if it > helps. Note also that a compressed file will have fragments on the scale of about 128k reported by filefrag, because of the way that the compression works. The file may actually be contiguous, but filefrag won't know about it. (At least, that's historically been the case. I don't know if filefrag has recently grown some extra knowledge of compressed extents.) Hugo. > > which produces much better results (ok, the file must not be in use). > > Somewhere in the 3.17 cycle the resulting image got corrupted using the > > script > > above. > > > > Running filefrag on it returns "FIBMAP unsupported". > > This message doe not mean it is a corruption, but filefrag tries to use > the FIBMAP ioctl that is not implemented on btrfs, instead FIEMAP is > used. > > filefrag on a nocow file works for me here (3.16.x kernel), I can see > that filefrag on a directory prints the FIBMAP message. > > > Virtualbox returns "AHCI#0P0: Read at offset 606236672 (49152 bytes left) > > returned rc=VERR_DEV_IO_ERROR". No errors in the kernel log. > > > > Trying "cp vm.vdi /dev/null" returns: cp: Error reading „vm.vdi“: IO-Error > > This could be caused by the virtualization layer. Try to run scrub and > fsck in the non-destru^Wchecking mode if it finds problems. > > As you're using compression and autodefrag, a quick skim of the 3.17 > patches points to e9512d72e8e61c750c90efacd720abe3c4569822 "fix > autodefrag with compression", but that's just "keyword" match. > > There's another report about nocow corruption and VirtualBox in a 3.16 + > for-linus version (which is almost 3.17-rc) > http://article.gmane.org/gmane.comp.file-systems.btrfs/38701/ > > But according to the attached messages, the underlying device is > unreliable and logs a lot of IO errors. > > For now it looks like VirutalBox is not writing the data or there is a > bug introduced post 3.16 killing nocow files. -- === Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk === PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk --- ... one ping(1) to rule them all, and in the --- darkness bind(2) them. signature.asc Description: Digital signature
Re: btrfs check segfaults after flipping 2 Bytes
On 2014/10/02 07:51, Brendan Hide wrote: On 2014/10/02 01:31, Duncan wrote: [snip] I'm not sure if there is a mount option for this use case however. The option descriptions for "nodatasum" and "nodatacow" imply that *new* checksums are not generated. In this case the checksums already exist. Looks like btrfsck has a relevant option, albeit likely more destructive than absolutely necessary: --init-csum-tree create a new CRC tree. ^ Also, mail was sent as HTML 12 hours ago thus was never delivered. Thunderbird has been disciplined. -- __ Brendan Hide http://swiftspirit.co.za/ http://www.webafrica.co.za/?AFF1E97 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Btrfs-progs: add the ability to delete items
Somtetimes you just need to delete an item, add that functionality to btrfs-corrupt-block. Thanks, Signed-off-by: Josef Bacik --- btrfs-corrupt-block.c | 47 ++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 22390b5..278a56f 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -108,6 +108,7 @@ static void print_usage(void) fprintf(stderr, "\t-K The key to corrupt in the format " ",, (must also specify -f for the field)\n"); fprintf(stderr, "\t-f The field in the item to corrupt\n"); + fprintf(stderr, "\t-d Delete this item (must specify -K)\n"); exit(1); } @@ -645,6 +646,39 @@ out: return ret; } +static int delete_item(struct btrfs_root *root, struct btrfs_key *key) +{ + struct btrfs_trans_handle *trans; + struct btrfs_path *path; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + btrfs_free_path(path); + fprintf(stderr, "Couldn't start transaction %ld\n", + PTR_ERR(trans)); + return PTR_ERR(trans); + } + + ret = btrfs_search_slot(trans, root, key, path, -1, 1); + if (ret) { + if (ret > 0) + ret = -ENOENT; + fprintf(stderr, "Error searching to node %d\n", ret); + goto out; + } + ret = btrfs_del_item(trans, root, path); + btrfs_mark_buffer_dirty(path->nodes[0]); +out: + btrfs_commit_transaction(trans, root); + btrfs_free_path(path); + return ret; +} + static struct option long_options[] = { /* { "byte-count", 1, NULL, 'b' }, */ { "logical", 1, NULL, 'l' }, @@ -660,6 +694,7 @@ static struct option long_options[] = { { "metadata-block", 1, NULL, 'm'}, { "field", 1, NULL, 'f'}, { "key", 1, NULL, 'K'}, + { "delete", 0, NULL, 'd'}, { 0, 0, 0, 0} }; @@ -823,6 +858,7 @@ int main(int ac, char **av) int corrupt_block_keys = 0; int chunk_rec = 0; int chunk_tree = 0; + int delete = 0; u64 metadata_block = 0; u64 inode = 0; u64 file_extent = (u64)-1; @@ -834,7 +870,7 @@ int main(int ac, char **av) while(1) { int c; - c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:", long_options, + c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:d", long_options, &option_index); if (c < 0) break; @@ -885,6 +921,9 @@ int main(int ac, char **av) print_usage(); } break; + case 'd': + delete = 1; + break; default: print_usage(); } @@ -981,6 +1020,12 @@ int main(int ac, char **av) ret = corrupt_metadata_block(root, metadata_block, field); goto out_close; } + if (delete) { + if (!key.objectid) + print_usage(); + ret = delete_item(root, &key); + goto out_close; + } if (key.objectid || key.offset || key.type) { if (!strlen(field)) print_usage(); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Btrfs-progs: repair missing dir index
If we have an inode backref entry then we know enough to add back a missing dir index. When messing with the inode backrefs we need to do all of that first before we process the inode recs themselves as we may clear errors on the inode recs as we fix the directory indexes. This adds the framework for fixing backref errors and fixes missing dir index issues. Thanks, Signed-off-by: Josef Bacik --- cmds-check.c | 131 +- tests/fsck-tests/004-no-dir-index.img | Bin 0 -> 4096 bytes 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 tests/fsck-tests/004-no-dir-index.img diff --git a/cmds-check.c b/cmds-check.c index b962b15..5b8417c 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -1504,15 +1504,121 @@ static int repair_inode_orphan_item(struct btrfs_trans_handle *trans, return ret; } +static int add_missing_dir_index(struct btrfs_trans_handle *trans, +struct btrfs_root *root, +struct cache_tree *inode_cache, +struct btrfs_path *path, +struct inode_record *rec, +struct inode_backref *backref) +{ + struct btrfs_dir_item *dir_item; + struct extent_buffer *leaf; + struct btrfs_key key; + struct btrfs_disk_key disk_key; + struct inode_record *dir_rec; + unsigned long name_ptr; + u32 data_size = sizeof(*dir_item) + backref->namelen; + int ret; + + printf("repairing missing dir index item for inode %llu\n", + (unsigned long long)rec->ino); + key.objectid = backref->dir; + key.type = BTRFS_DIR_INDEX_KEY; + key.offset = backref->index; + + ret = btrfs_insert_empty_item(trans, root, path, &key, data_size); + if (ret) + return ret; + + leaf = path->nodes[0]; + dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); + + disk_key.objectid = cpu_to_le64(rec->ino); + disk_key.type = BTRFS_INODE_ITEM_KEY; + disk_key.offset = 0; + + btrfs_set_dir_item_key(leaf, dir_item, &disk_key); + btrfs_set_dir_type(leaf, dir_item, imode_to_type(rec->imode)); + btrfs_set_dir_data_len(leaf, dir_item, 0); + btrfs_set_dir_name_len(leaf, dir_item, backref->namelen); + name_ptr = (unsigned long)(dir_item + 1); + write_extent_buffer(leaf, backref->name, name_ptr, backref->namelen); + btrfs_mark_buffer_dirty(leaf); + btrfs_release_path(path); + backref->found_dir_index = 1; + + dir_rec = get_inode_rec(inode_cache, backref->dir, 0); + if (!dir_rec) + return 0; + dir_rec->found_size += backref->namelen; + if (dir_rec->found_size == dir_rec->isize && + (dir_rec->errors & I_ERR_DIR_ISIZE_WRONG)) + dir_rec->errors &= ~I_ERR_DIR_ISIZE_WRONG; + if (dir_rec->found_size != dir_rec->isize) + dir_rec->errors |= I_ERR_DIR_ISIZE_WRONG; + + return 0; + +} + +static int repair_inode_backrefs(struct btrfs_root *root, +struct inode_record *rec, +struct cache_tree *inode_cache) +{ + struct btrfs_trans_handle *trans; + struct btrfs_path *path; + struct inode_backref *tmp, *backref; + u64 root_dirid = btrfs_root_dirid(&root->root_item); + int ret; + int repaired = 0; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + btrfs_free_path(path); + return PTR_ERR(trans); + } + + list_for_each_entry_safe(backref, tmp, &rec->backrefs, list) { + /* Index 0 for root dir's are special, don't mess with it */ + if (rec->ino == root_dirid && backref->index == 0) + continue; + + if (!backref->found_dir_index && backref->found_inode_ref) { + ret = add_missing_dir_index(trans, root, inode_cache, + path, rec, backref); + if (!ret) + repaired = 1; + else + break; + } + + if (backref->found_dir_item && backref->found_dir_index) { + if (!backref->errors && backref->found_inode_ref) { + list_del(&backref->list); + free(backref); + } + } + } + + BUG_ON(repaired && ret); /* Poor mans transaction abort */ + btrfs_commit_transaction(trans, root); + btrfs_free_path(path); + + return ret; +} + static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) { struc
[PATCH] Btrfs-progs: check blocks when checking fs roots
If check block fails during the extent tree checks we could evict the extent buffer from cache, so the next time we go to read it for the fs_tree checks we could miss the fact that its bogus and blow up in strange and interesting ways. Fix this by running the leaf/node checks on all blocks in the fs root so we know we're looking at valid blocks. Thanks, Signed-off-by: Josef Bacik --- cmds-check.c | 21 + 1 file changed, 21 insertions(+) diff --git a/cmds-check.c b/cmds-check.c index 5b8417c..db779ae 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -1376,6 +1376,8 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, next = btrfs_find_tree_block(root, bytenr, blocksize); if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { + enum btrfs_tree_block_status status; + free_extent_buffer(next); reada_walk_down(root, cur, path->slots[*level]); next = read_tree_block(root, bytenr, blocksize, @@ -1384,6 +1386,16 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, err = -EIO; goto out; } + + if (btrfs_is_leaf(next)) + status = btrfs_check_leaf(root, NULL, next); + else + status = btrfs_check_node(root, NULL, next); + if (status != BTRFS_TREE_BLOCK_CLEAN) { + free_extent_buffer(next); + err = -EIO; + goto out; + } } *level = *level - 1; @@ -2078,6 +2090,7 @@ static int check_fs_root(struct btrfs_root *root, struct shared_node root_node; struct root_record *rec; struct btrfs_root_item *root_item = &root->root_item; + enum btrfs_tree_block_status status; if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { rec = get_root_rec(root_cache, root->root_key.objectid); @@ -2096,6 +2109,14 @@ static int check_fs_root(struct btrfs_root *root, wc->active_node = level; wc->root_level = level; + /* We may not have checked the root block, lets do that now */ + if (btrfs_is_leaf(root->node)) + status = btrfs_check_leaf(root, NULL, root->node); + else + status = btrfs_check_node(root, NULL, root->node); + if (status != BTRFS_TREE_BLOCK_CLEAN) + return -EIO; + if (btrfs_root_refs(root_item) > 0 || btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { path.nodes[level] = root->node; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Btrfs-progs: corrupt btrfs items in btrfs-corrup-block
For testing fsck against completely broken btrfs_items. Signed-off-by: Josef Bacik --- btrfs-corrupt-block.c | 90 +-- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 278a56f..c58f01a 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -109,6 +109,8 @@ static void print_usage(void) ",, (must also specify -f for the field)\n"); fprintf(stderr, "\t-f The field in the item to corrupt\n"); fprintf(stderr, "\t-d Delete this item (must specify -K)\n"); + fprintf(stderr, "\t-I An item to corrupt (must also specify the field " + "to corrupt and a root+key for the item)\n"); exit(1); } @@ -308,6 +310,11 @@ enum btrfs_metadata_block_field { BTRFS_METADATA_BLOCK_BAD, }; +enum btrfs_item_field { + BTRFS_ITEM_OFFSET, + BTRFS_ITEM_BAD, +}; + enum btrfs_key_field { BTRFS_KEY_OBJECTID, BTRFS_KEY_TYPE, @@ -350,6 +357,13 @@ static enum btrfs_key_field convert_key_field(char *field) return BTRFS_KEY_BAD; } +static enum btrfs_item_field convert_item_field(char *field) +{ + if (!strncmp(field, "offset", FIELD_BUF_LEN)) + return BTRFS_ITEM_OFFSET; + return BTRFS_ITEM_BAD; +} + static u64 generate_u64(u64 orig) { u64 ret; @@ -359,6 +373,15 @@ static u64 generate_u64(u64 orig) return ret; } +static u32 generate_u32(u32 orig) +{ + u32 ret; + do { + ret = rand(); + } while (ret == orig); + return ret; +} + static u8 generate_u8(u8 orig) { u8 ret; @@ -679,6 +702,58 @@ out: return ret; } +static int corrupt_btrfs_item(struct btrfs_root *root, struct btrfs_key *key, + char *field) +{ + struct btrfs_trans_handle *trans; + struct btrfs_path *path; + enum btrfs_item_field corrupt_field; + u32 orig, bogus; + int ret; + + corrupt_field = convert_item_field(field); + if (corrupt_field == BTRFS_ITEM_BAD) { + fprintf(stderr, "Invalid field %s\n", field); + return -EINVAL; + } + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + btrfs_free_path(path); + fprintf(stderr, "Couldn't start transaction %ld\n", + PTR_ERR(trans)); + return PTR_ERR(trans); + } + + ret = btrfs_search_slot(trans, root, key, path, 0, 1); + if (ret != 0) { + fprintf(stderr, "Error searching to node %d\n", ret); + goto out; + } + + ret = 0; + switch (corrupt_field) { + case BTRFS_ITEM_OFFSET: + orig = btrfs_item_offset_nr(path->nodes[0], path->slots[0]); + bogus = generate_u32(orig); + btrfs_set_item_offset(path->nodes[0], + btrfs_item_nr(path->slots[0]), bogus); + break; + default: + ret = -EINVAL; + break; + } + btrfs_mark_buffer_dirty(path->nodes[0]); +out: + btrfs_commit_transaction(trans, root); + btrfs_free_path(path); + return ret; +} + static struct option long_options[] = { /* { "byte-count", 1, NULL, 'b' }, */ { "logical", 1, NULL, 'l' }, @@ -695,6 +770,7 @@ static struct option long_options[] = { { "field", 1, NULL, 'f'}, { "key", 1, NULL, 'K'}, { "delete", 0, NULL, 'd'}, + { "item", 0, NULL, 'I'}, { 0, 0, 0, 0} }; @@ -859,6 +935,7 @@ int main(int ac, char **av) int chunk_rec = 0; int chunk_tree = 0; int delete = 0; + int corrupt_item = 0; u64 metadata_block = 0; u64 inode = 0; u64 file_extent = (u64)-1; @@ -870,8 +947,8 @@ int main(int ac, char **av) while(1) { int c; - c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:d", long_options, - &option_index); + c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:dI", + long_options, &option_index); if (c < 0) break; switch(c) { @@ -924,6 +1001,9 @@ int main(int ac, char **av) case 'd': delete = 1; break; + case 'I': + corrupt_item = 1; + break; default: print_usage(); } @@ -1026,6 +1106,12 @@ int main(int ac, char **av) ret = delete_item(root, &key); goto out_close; } + if (corrupt_item) { + if (!key.object
Re: FIBMAP unsupported
Am Donnerstag 02 Oktober 2014, 19:25:49 schrieb David Sterba: > On Thu, Oct 02, 2014 at 05:13:22PM +0200, Marc Dietrich wrote: > > I have a large (25G) virtual disk on a btrfs fs. Yes, I know this is not > > optimial. So I try to defrag it from time to time. However, using "btrfs > > fi > > defrag -c vm.vdi" results in even more fragments than before (reported by > > filefrag). So I wrote my own pseudo defragger, > > Unfortunatelly the default target fragment size is 256k. Try > 'btrfs filesystem defrag -t 32m ...' or higher numbers and see if it > helps. ok, need to try if I can ever recover from this error ... > > which produces much better results (ok, the file must not be in use). > > Somewhere in the 3.17 cycle the resulting image got corrupted using the > > script above. > > > > Running filefrag on it returns "FIBMAP unsupported". > > This message doe not mean it is a corruption, but filefrag tries to use > the FIBMAP ioctl that is not implemented on btrfs, instead FIEMAP is > used. > > filefrag on a nocow file works for me here (3.16.x kernel), I can see > that filefrag on a directory prints the FIBMAP message. ah, for some reason FIBMAP is used on a file: # strace filefrag vm.vdi open("vm.vdi", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=26681016320, ...}) = 0 fstatfs(3, {f_type=0x9123683e, f_bsize=4096, f_blocks=106856459, f_bfree=35124686, f_bavail=33785307, f_files=0, f_ffree=0, f_fsid={741604101, -890814488}, f_namelen=255, f_frsize=4096}) = 0 ioctl(3, FIGETBSZ, 0x603150)= 0 ioctl(3, FS_IOC_FIEMAP, 0x7fff8e0b65a0) = -1 EEXIST (File exists) ioctl(3, FIBMAP, 0x7fff8e0ba65c)= -1 EINVAL (Invalid argument) write(2, "vm.vdi: FIBMAP unsupported\n", 32vm.vdi: FIBMAP unsupported ) = 32 close(3)= 0 exit_group(22) = ? So it tries first FIEMAP and fails and then it tries FIBMAP which also fails. > > Virtualbox returns "AHCI#0P0: Read at offset 606236672 (49152 bytes left) > > returned rc=VERR_DEV_IO_ERROR". No errors in the kernel log. > > > > Trying "cp vm.vdi /dev/null" returns: cp: Error reading „vm.vdi“: IO-Error > > This could be caused by the virtualization layer. Try to run scrub and > fsck in the non-destru^Wchecking mode if it finds problems. the first error comes from the virtual machine log, maybe we can ignore it. the second error is on the bare metal (no virtual machine). The disk is ok, so the I/O error comes from btrfs itself. > As you're using compression and autodefrag, a quick skim of the 3.17 > patches points to e9512d72e8e61c750c90efacd720abe3c4569822 "fix > autodefrag with compression", but that's just "keyword" match. I have this in my kernel already... > There's another report about nocow corruption and VirtualBox in a 3.16 + > for-linus version (which is almost 3.17-rc) > http://article.gmane.org/gmane.comp.file-systems.btrfs/38701/ > > But according to the attached messages, the underlying device is > unreliable and logs a lot of IO errors. > > For now it looks like VirutalBox is not writing the data or there is a > bug introduced post 3.16 killing nocow files. as said above, this is not related to virtualbox (problem exists on bare metal). Will try to restore the file using btrfs restore Marc -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: FIBMAP unsupported
Am Donnerstag 02 Oktober 2014, 21:55:55 schrieb Marc Dietrich: > Will try to restore the file using btrfs restore ok, restore worked. I did some more tests. This is unrelated to CoW. It seems that the "fallocate -n" in combination with "dd conv=notrunc" using large files (>10G) triggers it. Maybe this rings some bells. Marc -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html