Hello community, here is the log from the commit of package ocfs2-tools for openSUSE:Factory checked in at 2015-04-25 09:53:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ocfs2-tools (Old) and /work/SRC/openSUSE:Factory/.ocfs2-tools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ocfs2-tools" Changes: -------- --- /work/SRC/openSUSE:Factory/ocfs2-tools/ocfs2-tools.changes 2014-02-01 09:40:18.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ocfs2-tools.new/ocfs2-tools.changes 2015-04-25 11:25:58.000000000 +0200 @@ -1,0 +2,33 @@ +Mon Feb 9 03:26:29 UTC 2015 - [email protected] + +- Update ocfs2-tools.tar.bz2 to upstream v1.8.3 +- Drop patches (merged upstream): + - fix-indexed-dirs.patch + - 0001-fswreck-Create-a-loop-in-group-chains.patch + - 0002-Break-a-chain-loop-in-group-desc.patch + - restore-g_list_append.patch + - ocfs2console-libraries-include-aio.patch + - libocfs2-needs-libaio.patch + - libocfs2-Change-asserts-to-error.patch +- Drop patches for ocfs2_controld + - force-debug.patch + - extra-debug.patch + - bug-805764-ocfs2-controld.patch + - bnc804707-reduce-RR-priority.patch + - use-symlink-in-udev-rules.patch + +------------------------------------------------------------------- +Tue Feb 11 16:57:54 UTC 2014 - [email protected] + +- Recommend ocfs2-kmp +- Autosetup pcmk if no cluster stack found (bnc#862758) + + 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch +- Err if cannot write to cluster_stack (cluster mismatch) + + 0003-Auto-setup-cluster_stack-based-on-what-is-on-disk.patch + +------------------------------------------------------------------- +Mon Feb 10 12:32:37 UTC 2014 - [email protected] + +- Update summary and description for the -o2cb package (bnc#862761) + +------------------------------------------------------------------- Old: ---- 0001-fswreck-Create-a-loop-in-group-chains.patch 0002-Break-a-chain-loop-in-group-desc.patch bnc804707-reduce-RR-priority.patch bug-805764-ocfs2-controld.patch extra-debug.patch fix-indexed-dirs.patch force-debug.patch libocfs2-Change-asserts-to-error.patch libocfs2-needs-libaio.patch ocfs2-tools-1.8.2+git.1361836695.ff84eb5.tar.gz ocfs2console-libraries-include-aio.patch restore-g_list_append.patch use-symlink-in-udev-rules.patch New: ---- 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch ocfs2-tools-1.8.3+git.1418704844.65fac00.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ocfs2-tools.spec ++++++ --- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200 +++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package ocfs2-tools # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: ocfs2-tools -Version: 1.8.2+git.1361836695.ff84eb5 +Version: 1.8.3+git.1418704844.65fac00 Release: 0 Summary: Oracle Cluster File System 2 Core Tools License: GPL-2.0+ @@ -26,8 +26,6 @@ Source: ocfs2-tools-%{version}.tar.gz Source1: o2cb.ocf Source2: reflink.tar.bz2 -Patch101: force-debug.patch -Patch102: extra-debug.patch Patch103: debug-ocfs2_hb_ctl.patch Patch105: bug-470741-debug_start_failures.patch Patch106: ocfs2-devel.diff @@ -37,21 +35,12 @@ Patch204: dont-use-var-lock-subsys.patch Patch205: ocfs2-tools-kernel33.patch Patch206: ocfs2-tools-resource.patch -Patch207: fix-indexed-dirs.patch -Patch208: 0001-fswreck-Create-a-loop-in-group-chains.patch -Patch209: 0002-Break-a-chain-loop-in-group-desc.patch -Patch210: restore-g_list_append.patch -Patch212: bug-805764-ocfs2-controld.patch -Patch213: bnc804707-reduce-RR-priority.patch -Patch214: use-symlink-in-udev-rules.patch -Patch215: ocfs2console-libraries-include-aio.patch -Patch220: libocfs2-needs-libaio.patch -Patch221: libocfs2-Change-asserts-to-error.patch Patch222: 0001-Use-cmap-for-getting-cluster-name.patch Patch223: 0002-Remove-controld-dependency-in-group_join-leave.patch Patch224: 0003-Auto-setup-cluster_stack-based-on-what-is-on-disk.patch Patch225: 0004-mkfs.ocfs2-Abort-if-cluster-information-is-not-detec.patch Patch226: 0005-mkfs-Setup-cluster_stack-if-not-setup-based-on-what-.patch +Patch227: 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch BuildRequires: autoconf BuildRequires: e2fsprogs-devel @@ -75,8 +64,7 @@ Requires: modutils Requires: net-tools BuildRoot: %{_tmppath}/%{name}-%{version}-build -%if 0%{?suse_version} < 1120 -# There's no separate kmp for openSUSE 11.2 +%if 0%{?suse_version} < 1320 Recommends: ocfs2-kmp %endif @@ -130,20 +118,18 @@ OCFS2-aware applications. %package o2cb -Summary: Oracle Cluster File System 2 Core Tools +Summary: Oracle Cluster File System 2 tools for the native o2cb stack Group: System/Filesystems Requires: ocfs2-tools = %{version} %description o2cb OCFS is the Oracle Cluster File System. -This package contains the core user-space tools needed for creating and -managing the file system. +This package contains the tools to manage the native o2cb stack for the +OCFS2 filesystem. %prep %setup -q -a 2 -%patch101 -p1 -%patch102 -p1 %patch103 -p1 %patch105 -p1 %patch106 -p1 @@ -153,21 +139,12 @@ %patch204 -p1 %patch205 -p1 %patch206 -p1 -%patch207 -p1 -%patch208 -p1 -%patch209 -p1 -%patch210 -p1 -%patch212 -p1 -%patch213 -p1 -%patch214 -p1 -%patch215 -p1 -%patch220 -p1 -%patch221 -p1 %patch222 -p1 %patch223 -p1 %patch224 -p1 %patch225 -p1 %patch226 -p1 +%patch227 -p1 %build export PROJECT="ocfs2-tools" ++++++ 0001-Use-cmap-for-getting-cluster-name.patch ++++++ --- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200 +++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200 @@ -3,7 +3,6 @@ Date: Sat, 21 Dec 2013 18:41:04 -0600 Subject: [PATCH] Use cmap for getting cluster name -Signed-off-by: Goldwyn Rodrigues <[email protected]> --- debugfs.ocfs2/Makefile | 2 +- libo2cb/o2cb_abi.c | 79 +++++++++++++++++++++++++++----------------------- ++++++ 0006-Auto-setup-pcmk-stack-as-default-if-no-stack-is-setu.patch ++++++ >From 1e041fdfb09bfc39aa37bea7d491bcf56794fa1c Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues <[email protected]> Date: Tue, 11 Feb 2014 10:54:23 -0600 Subject: [PATCH] Auto setup pcmk stack as default if no stack is setup Note: This changes the default behavior from classic stack to pcmk --- libo2cb/o2cb_abi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libo2cb/o2cb_abi.c b/libo2cb/o2cb_abi.c index 5e0c4fb..26ea03e 100644 --- a/libo2cb/o2cb_abi.c +++ b/libo2cb/o2cb_abi.c @@ -172,7 +172,9 @@ static errcode_t determine_stack(void) ssize_t len; char line[100]; errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE; + int setup_performed = 0; +redo: len = read_stack_file(line, sizeof(line)); if (len > 0) { if (line[len - 1] == '\n') { @@ -192,8 +194,11 @@ static errcode_t determine_stack(void) err = 0; } } else if (len == -ENOENT) { - current_stack = &classic_stack; - err = 0; + if (!setup_performed) { + o2cb_setup_stack(OCFS2_PCMK_CLUSTER_STACK); + setup_performed = 1; + goto redo; + } } return err; -- 1.8.4 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.bF7rHq/_old 2015-04-25 11:25:59.000000000 +0200 +++ /var/tmp/diff_new_pack.bF7rHq/_new 2015-04-25 11:25:59.000000000 +0200 @@ -3,7 +3,7 @@ <param name="url">git://oss.oracle.com/git/ocfs2-tools.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="versionformat">1.8.2+git.%ct.%h</param> + <param name="versionformat">1.8.3+git.%ct.%h</param> <param name="revision">master</param> </service> ++++++ ocfs2-tools-1.8.2+git.1361836695.ff84eb5.tar.gz -> ocfs2-tools-1.8.3+git.1418704844.65fac00.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/configure.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/configure.in --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/configure.in 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/configure.in 2015-01-27 10:04:16.000000000 +0100 @@ -9,7 +9,7 @@ # Adjust these for the software version. MAJOR_VERSION=1 MINOR_VERSION=8 -MICRO_VERSION=2 +MICRO_VERSION=3 EXTRA_VERSION= DIST_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/commands.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/commands.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/commands.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/commands.c 2015-01-27 10:04:16.000000000 +0100 @@ -64,6 +64,7 @@ static void do_frag(char **args); static void do_fs_locks(char **args); static void do_group(char **args); +static void do_grpextents(char **args); static void do_hb(char **args); static void do_help(char **args); static void do_icheck(char **args); @@ -188,6 +189,11 @@ "group <block#>", "Show chain group", }, + { "grpextents", + do_grpextents, + "grpextents <block#>", + "Show free extents in a chain group", + }, { "hb", do_hb, "hb", @@ -1243,6 +1249,36 @@ return ; } +static void do_grpextents(char **args) +{ + struct ocfs2_group_desc *grp; + uint64_t blkno; + char *buf = NULL; + FILE *out; + errcode_t ret = 0; + + if (process_inodestr_args(args, 1, &blkno) != 1) + return; + + buf = gbls.blockbuf; + out = open_pager(gbls.interactive); + while (blkno) { + ret = ocfs2_read_group_desc(gbls.fs, blkno, buf); + if (ret) { + com_err(args[0], ret, "while reading block group " + "descriptor %"PRIu64"", blkno); + close_pager(out); + return; + } + + grp = (struct ocfs2_group_desc *)buf; + dump_group_extents(out, grp); + blkno = grp->bg_next_group; + } + + close_pager(out); +} + static int dirblocks_proxy(ocfs2_filesys *fs, uint64_t blkno, uint64_t bcount, uint16_t ext_flags, void *priv_data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/dump.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/dump.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/dump.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/dump.c 2015-01-27 10:04:16.000000000 +0100 @@ -157,87 +157,30 @@ } /* - * dump_block_check + * dump_block_check() * + * As the checksum is computed in the disk format, we have to swap_from_cpu + * before computing it. */ void dump_block_check(FILE *out, struct ocfs2_block_check *bc, void *block) { struct ocfs2_block_check tmp = *bc; int crc_fail; - enum ocfs2_block_type bt = ocfs2_detect_block(block); - /* Swap block to little endian for compute_meta_ecc */ - switch (bt) { - case OCFS2_BLOCK_INODE: - case OCFS2_BLOCK_SUPERBLOCK: - ocfs2_swap_inode_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_EXTENT_BLOCK: - ocfs2_swap_extent_block_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_GROUP_DESCRIPTOR: - ocfs2_swap_group_desc_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DIR_BLOCK: - ocfs2_swap_dir_entries_from_cpu(block, - gbls.fs->fs_blocksize); - break; - case OCFS2_BLOCK_XATTR: - ocfs2_swap_xattr_block_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_REFCOUNT: - ocfs2_swap_refcount_block_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DXROOT: - ocfs2_swap_dx_root_from_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DXLEAF: - ocfs2_swap_dx_leaf_from_cpu(block); - break; - default: - fprintf(out, "Unable to determine block type"); - return; + fprintf(out, "\tCRC32: %.8"PRIx32" ECC: %.4"PRIx16"\n", + le32_to_cpu(tmp.bc_crc32e), le16_to_cpu(tmp.bc_ecc)); + + /* Cannot validate unknown blocks */ + if (ocfs2_detect_block(block) == OCFS2_BLOCK_UNKNOWN) { + fprintf(out, "\t**UNKNOWN BLOCK** (Cannot validate checksum)\n"); + return; } - /* Re-compute based on what we got from disk */ + ocfs2_swap_block_from_cpu(gbls.fs, block); ocfs2_compute_meta_ecc(gbls.fs, block, bc); - - /* Swap block back to CPU */ - switch (bt) { - case OCFS2_BLOCK_INODE: - case OCFS2_BLOCK_SUPERBLOCK: - ocfs2_swap_inode_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_EXTENT_BLOCK: - ocfs2_swap_extent_block_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_GROUP_DESCRIPTOR: - ocfs2_swap_group_desc_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DIR_BLOCK: - ocfs2_swap_dir_entries_to_cpu(block, - gbls.fs->fs_blocksize); - break; - case OCFS2_BLOCK_XATTR: - ocfs2_swap_xattr_block_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_REFCOUNT: - ocfs2_swap_refcount_block_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DXROOT: - ocfs2_swap_dx_root_to_cpu(gbls.fs, block); - break; - case OCFS2_BLOCK_DXLEAF: - ocfs2_swap_dx_leaf_to_cpu(block); - break; - default: - break; - } + ocfs2_swap_block_to_cpu(gbls.fs, block); crc_fail = memcmp(bc, &tmp, sizeof(*bc)); - - fprintf(out, "\tCRC32: %.8"PRIx32" ECC: %.4"PRIx16"\n", - le32_to_cpu(tmp.bc_crc32e), le16_to_cpu(tmp.bc_ecc)); if (crc_fail) fprintf(out, "\t**FAILED CHECKSUM** Computed CRC32: %.8" PRIx32" ECC: %.4"PRIx16"\n", @@ -547,6 +490,15 @@ return ; } +void dump_group_extents(FILE *out, struct ocfs2_group_desc *grp) +{ + fprintf(out, "\tGroup# %"PRIu64" Total: %u Used: %u Free: %u\n", + (uint64_t)grp->bg_blkno, grp->bg_bits, + (grp->bg_bits - grp->bg_free_bits_count), + grp->bg_free_bits_count); + print_contig_bits(out, grp); +} + /* * dump_dir_entry() * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/dump.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/dump.h --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/dump.h 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/dump.h 2015-01-27 10:04:16.000000000 +0100 @@ -42,6 +42,7 @@ void dump_chain_list (FILE *out, struct ocfs2_chain_list *cl); void dump_extent_block (FILE *out, struct ocfs2_extent_block *blk); void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp, int index); +void dump_group_extents(FILE *out, struct ocfs2_group_desc *grp); int dump_dir_entry (struct ocfs2_dir_entry *rec, uint64_t blocknr, int offset, int blocksize, char *buf, void *priv_data); void dump_dx_root (FILE *out, struct ocfs2_dx_root_block *dx_root); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/utils.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/utils.h --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/include/utils.h 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/include/utils.h 2015-01-27 10:04:16.000000000 +0100 @@ -64,6 +64,7 @@ const char *dumproot, int verbose); void crunch_strsplit(char **args); void find_max_contig_free_bits(struct ocfs2_group_desc *gd, int *max_contig_free_bits); +void print_contig_bits(FILE *out, struct ocfs2_group_desc *gd); errcode_t get_debugfs_path(char *debugfs_path, int len); errcode_t open_debugfs_file(const char *debugfs_path, const char *dirname, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/utils.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/utils.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/debugfs.ocfs2/utils.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/debugfs.ocfs2/utils.c 2015-01-27 10:04:16.000000000 +0100 @@ -816,6 +816,65 @@ } } +void print_contig_bits(FILE *out, struct ocfs2_group_desc *gd) +{ + int x, free_bits, start, end = 0, avg = 0, found = 0, total = 0; + int max_contig_free_bits = 0; + +#define HEADER_FORMAT "%-3s %-6s %-6s" +#define DATA_FORMAT "%-3d %-6d %-6d" + +#define LEFT_HEADER "\t"HEADER_FORMAT" " +#define MIDDLE_HEADER HEADER_FORMAT" " +#define RIGHT_HEADER HEADER_FORMAT"\n" + +#define LEFT_DATA "\t"DATA_FORMAT" " +#define MIDDLE_DATA DATA_FORMAT" " +#define RIGHT_DATA DATA_FORMAT"\n" + + while (end < gd->bg_bits) { + start = ocfs2_find_next_bit_clear(gd->bg_bitmap, gd->bg_bits, + end); + if (start >= gd->bg_bits) + break; + + end = ocfs2_find_next_bit_set(gd->bg_bitmap, gd->bg_bits, start); + free_bits = end - start; + + if (!free_bits) + continue; + + if (!found) { + fprintf(out, LEFT_HEADER, "###", "Start", "Length"); + fprintf(out, MIDDLE_HEADER, "###", "Start", "Length"); + fprintf(out, RIGHT_HEADER, "###", "Start", "Length"); + } + + found++; + x = found % 3; + if (x == 1) + fprintf(out, LEFT_DATA, found, start, free_bits); + else if (x == 2) + fprintf(out, MIDDLE_DATA, found, start, free_bits); + else + fprintf(out, RIGHT_DATA, found, start, free_bits); + + total += free_bits; + + if (max_contig_free_bits < free_bits) + max_contig_free_bits = free_bits; + } + + if (found) { + avg = total / found; + if (found % 3) + fprintf(out, "\n"); + } + + fprintf(out, "\tFree Extent Count: %d Longest: %d Average: %d\n\n", + found, max_contig_free_bits, avg); +} + #define SYSFS_BASE "/sys/kernel/" #define DEBUGFS_PATH SYSFS_BASE "debug" #define DEBUGFS_ALTERNATE_PATH "/debug" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/fsck.ocfs2.checks.8.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/fsck.ocfs2.checks.8.in --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/fsck.ocfs2.checks.8.in 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/fsck.ocfs2.checks.8.in 2015-01-27 10:04:16.000000000 +0100 @@ -202,6 +202,15 @@ Answering yes decreases the number of recorded free bits so that it equals the total number of bits in the group descriptor's bitmap. +.SS "GROUP_CHAIN_LOOP" +A chain may loop if the next field of the group descriptor points to one of +the previous group descriptors in the chain. This causes the ocfs2 code, both +user space and kernel module to loop forever. + +Answering yes breaks the loop at an optimum location so that all the existing +group descriptors are in the chain. However, it cannot re-connect stray group +descriptors and must rely on the rest of the fsck code to fix it. + .SS "CHAIN_COUNT" The chain list embedded in an inode is limited by the block size and the number of bytes consumed by the rest of the inode. A chain list header was @@ -1149,6 +1158,23 @@ Answering yes will serialize the extents. +.SS "DX_TREE_CORRUPT" +The index tree of the directory is corrupt. + +Answering yes will rebuild the directory index, in pass 2. + + +.SS "DX_TREE_MISSING" +The index of this directory is missing. + +Answering yes will rebuild the directory index. + +.SS "BAD_CRC32" +The metadata block has a bad CRC32, which means either the block or the +crc32 field is corrupted. + +Answering yes will recalculate the CRC32. + .SH "SEE ALSO" .BR debugfs.ocfs2(8) .BR fsck.ocfs2(8) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass0.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass0.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass0.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass0.c 2015-01-27 10:04:16.000000000 +0100 @@ -666,6 +666,46 @@ return ret; } +static errcode_t break_loop(o2fsck_state *ost, struct ocfs2_chain_rec *chain, + unsigned int max_depth) +{ + uint64_t *list; + int i; + unsigned int depth = 0; + uint64_t blkno = chain->c_blkno; + char *buf; + struct ocfs2_group_desc *gd; + errcode_t ret = ocfs2_malloc0(sizeof(uint64_t) * max_depth, &list); + if (ret) + goto out; + ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf); + if (ret) + goto out; + gd = (struct ocfs2_group_desc *)buf; + + while (blkno && (depth<=max_depth)) { + list[depth++] = blkno; + ret = ocfs2_read_group_desc(ost->ost_fs, blkno, buf); + if (ret) + goto out; + blkno = gd->bg_next_group; + for (i=0; i<depth; i++) + if (list[i]==blkno) { + gd->bg_next_group = 0; + verbosef("Breaking gd loop %"PRIu64"\n", blkno); + ret = ocfs2_write_group_desc(ost->ost_fs, + blkno, buf); + goto out; + } + } +out: + if (list) + ocfs2_free(&list); + if (buf) + ocfs2_free(&buf); + return ret; +} + /* this takes a slightly ridiculous number of arguments :/ */ static errcode_t check_chain(o2fsck_state *ost, struct ocfs2_dinode *di, @@ -675,7 +715,8 @@ char *buf2, int *chain_changed, ocfs2_bitmap *allowed, - ocfs2_bitmap *forbidden) + ocfs2_bitmap *forbidden, + unsigned int max_depth) { struct ocfs2_group_desc *bg1 = (struct ocfs2_group_desc *)buf1; struct ocfs2_group_desc *bg2 = (struct ocfs2_group_desc *)buf2; @@ -792,6 +833,14 @@ /* the loop will now start by reading bg1->next_group */ memcpy(buf1, buf2, ost->ost_fs->fs_blocksize); depth++; + if (depth > max_depth) { + if (prompt(ost, PY, PR_GROUP_CHAIN_LOOP, + "Loop detected in chain %d at block %"PRIu64 + ". Break the loop?",cs->cs_chain_no, + (uint64_t) chain->c_blkno)) + ret = break_loop(ost, chain, max_depth); + break; + } } /* we hit the premature end of a chain.. clear the last @@ -854,6 +903,7 @@ int changed = 0, trust_next_free = 1; errcode_t ret = 0; uint64_t chain_bytes; + unsigned int num_gds, max_chain_len; if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE, strlen(OCFS2_INODE_SIGNATURE))) { @@ -883,9 +933,12 @@ /* XXX should we check suballoc_node? */ cl = &di->id2.i_chain; + num_gds = (di->i_clusters + cl->cl_cpg)/cl->cl_cpg; + max_chain_len = (num_gds + cl->cl_count)/cl->cl_count; - verbosef("cl cpg %u bpc %u count %u next %u\n", - cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec); + verbosef("cl cpg %u bpc %u count %u next %u gds %u max_ch_len %u\n", + cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec, + num_gds, max_chain_len); max_count = ocfs2_chain_recs_per_inode(ost->ost_fs->fs_blocksize); @@ -948,7 +1001,7 @@ .cs_cpg = cl->cl_cpg, }; ret = check_chain(ost, di, &cs, cr, buf1, buf2, &changed, - allowed, forbidden); + allowed, forbidden, max_chain_len); /* XXX what? not checking ret? */ if (cr->c_blkno != 0) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1.c 2015-01-27 10:04:16.000000000 +0100 @@ -917,10 +917,14 @@ } ret = o2fsck_check_dx_dir(ost, di); - if (ret) { - com_err(whoami, ret, "while iterating over the dir indexed " - "tree for directory inode %"PRIu64, (uint64_t)di->i_blkno); - goto out; + if (ret && prompt(ost, PY, PR_DX_TREE_CORRUPT, + "Inode %"PRIu64" has invalid dx tree. " + "Reset for later rebuild?", (uint64_t)di->i_blkno)) { + ocfs2_dx_dir_truncate(fs, di->i_blkno); + di->i_dx_root = 0ULL; + di->i_dyn_features &= ~OCFS2_INDEXED_DIR_FL; + o2fsck_write_inode(ost, di->i_blkno, di); + ret = 0; } if (S_ISLNK(di->i_mode)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1b.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1b.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass1b.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass1b.c 2015-01-27 10:04:16.000000000 +0100 @@ -961,12 +961,20 @@ static void walk_cwd(struct dir_scan_context *scan) { errcode_t ret; - struct ocfs2_dir_entry de; + struct ocfs2_dir_entry *de; + int len = sizeof(struct ocfs2_dir_entry); - memcpy(de.name, scan->ds_cwd, scan->ds_cwdlen); - de.name_len = scan->ds_cwdlen; - name_inode(scan, &de); + if (scan->ds_cwdlen > OCFS2_MAX_FILENAME_LEN) + len = sizeof(struct ocfs2_dir_entry) + scan->ds_cwdlen + - OCFS2_MAX_FILENAME_LEN; + ret = ocfs2_malloc(len, &de); + + memcpy(de->name, scan->ds_cwd, scan->ds_cwdlen); + de->name_len = scan->ds_cwdlen; + name_inode(scan, de); + free(de); + ret = ocfs2_dir_iterate(scan->ds_ost->ost_fs, scan->ds_ino, OCFS2_DIRENT_FLAG_EXCLUDE_DOTS, NULL, walk_iterate, scan); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass2.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass2.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fsck.ocfs2/pass2.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fsck.ocfs2/pass2.c 2015-01-27 10:04:16.000000000 +0100 @@ -664,6 +664,15 @@ ret = ocfs2_lookup(dd->fs, dbe->e_ino, dirent->name, dirent->name_len, NULL, &ino); if (ret) { + if ((ret == OCFS2_ET_DIR_CORRUPTED) && + prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED, + "Directory inode %"PRIu64" has invalid index. " + "Rebuild index tree?", dbe->e_ino)) { + *flags |= OCFS2_DIRENT_CHANGED; + ret = 0; + goto out; + } + if (ret != OCFS2_ET_FILE_NOT_FOUND) goto out; ret = 0; @@ -722,7 +731,15 @@ ret = ocfs2_read_inode(dd->ost->ost_fs, dbe->e_ino, dd->inoblock_buf); - if (ret) { + if (ret == OCFS2_ET_BAD_CRC32) { + if (prompt(dd->ost, PY, PR_BAD_CRC32, + "Directory inode %"PRIu64" " + "has bad CRC32. Recalculate CRC32 " + "and write inode block?", dbe->e_ino)) { + ocfs2_write_inode(dd->ost->ost_fs, dbe->e_ino, + dd->inoblock_buf); + } + } else if (ret) { com_err(whoami, ret, "while reading dir inode %"PRIu64, dbe->e_ino); ret_flags |= OCFS2_DIRENT_ABORT; @@ -735,9 +752,11 @@ /* Set the flag for index rebuilding */ if (ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)) && !(di->i_dyn_features & OCFS2_INLINE_DATA_FL) - && !(di->i_dyn_features & OCFS2_INDEXED_DIR_FL)) { - ret_flags |= OCFS2_DIRENT_CHANGED; - } + && !(di->i_dyn_features & OCFS2_INDEXED_DIR_FL) + && prompt(dd->ost, PY, PR_DX_TREE_MISSING, + "Directory %"PRIu64" is missing index. " + "Rebuild?", dbe->e_ino)) + ret_flags |= OCFS2_DIRENT_CHANGED; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/corrupt.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/corrupt.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/corrupt.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/corrupt.c 2015-01-27 10:04:16.000000000 +0100 @@ -331,6 +331,9 @@ case GROUP_FREE_BITS: func = mess_up_group_minor; break; + case GROUP_CHAIN_LOOP: + func = mess_up_group_minor; + break; case GROUP_GEN: func = mess_up_group_gen; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/group.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/group.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/group.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/group.c 2015-01-27 10:04:16.000000000 +0100 @@ -176,6 +176,12 @@ bg->bg_chain, (bg->bg_chain + 10)); bg->bg_chain += 10; break; + case GROUP_CHAIN_LOOP: + fprintf(stdout, "Corrput GROUP_LOOP: " + "change group next from %"PRIu64" to %"PRIu64"\n", + bg->bg_next_group, cr->c_blkno); + bg->bg_next_group = cpu_to_le64(cr->c_blkno); + break; case GROUP_FREE_BITS: fprintf(stdout, "Corrput GROUP_FREE_BITS: " "change group free bits from %u to %u\n", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/include/fsck_type.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/include/fsck_type.h --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/include/fsck_type.h 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/include/fsck_type.h 2015-01-27 10:04:16.000000000 +0100 @@ -57,6 +57,7 @@ GROUP_BLKNO, GROUP_CHAIN, GROUP_FREE_BITS, + GROUP_CHAIN_LOOP, CHAIN_COUNT, CHAIN_NEXT_FREE, CHAIN_EMPTY, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/main.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/main.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/fswreck/main.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/fswreck/main.c 2015-01-27 10:04:16.000000000 +0100 @@ -102,6 +102,8 @@ "Corrupt chain group's blkno"), define_prompt_code(GROUP_CHAIN, corrupt_group_desc, "", 1, "Corrupt chain group's chain where it was in"), + define_prompt_code(GROUP_CHAIN_LOOP, corrupt_group_desc, "", 1, + "Corrupt group's chain to form a loop"), define_prompt_code(GROUP_FREE_BITS, corrupt_group_desc, "", 1, "Corrupt chain group's free bits"), define_prompt_code(CHAIN_COUNT, corrupt_sys_file, "", 1, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2/ocfs2.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2/ocfs2.h --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2/ocfs2.h 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2/ocfs2.h 2015-01-27 10:04:16.000000000 +0100 @@ -1656,5 +1656,7 @@ uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len); enum ocfs2_block_type ocfs2_detect_block(char *buf); +void ocfs2_swap_block_from_cpu(ocfs2_filesys *fs, void *block); +void ocfs2_swap_block_to_cpu(ocfs2_filesys *fs, void *block); #endif /* _FILESYS_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2-kernel/ocfs2_fs.h new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2-kernel/ocfs2_fs.h --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/include/ocfs2-kernel/ocfs2_fs.h 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/include/ocfs2-kernel/ocfs2_fs.h 2015-01-27 10:04:16.000000000 +0100 @@ -1682,7 +1682,7 @@ } static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de, - umode_t mode) + unsigned short mode) { de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libo2cb/o2cb_abi.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libo2cb/o2cb_abi.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libo2cb/o2cb_abi.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libo2cb/o2cb_abi.c 2015-01-27 10:04:16.000000000 +0100 @@ -1762,9 +1762,9 @@ void o2cb_free_cluster_desc(struct o2cb_cluster_desc *cluster) { if (cluster->c_stack) - free(cluster->c_stack); + ocfs2_free(&cluster->c_stack); if (cluster->c_cluster) - free(cluster->c_cluster); + ocfs2_free(&cluster->c_cluster); } errcode_t o2cb_running_cluster_desc(struct o2cb_cluster_desc *cluster) @@ -1815,10 +1815,8 @@ out: if (clusters) o2cb_free_cluster_list(clusters); - if (err) { - free(cluster->c_stack); - free(cluster->c_cluster); - } + if (err) + o2cb_free_cluster_desc(cluster); return err; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blockcheck.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blockcheck.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blockcheck.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blockcheck.c 2015-01-27 10:04:16.000000000 +0100 @@ -360,7 +360,7 @@ if (crc == check.bc_crc32e) goto out; - err = OCFS2_ET_IO; + err = OCFS2_ET_BAD_CRC32; out: bc->bc_crc32e = cpu_to_le32(check.bc_crc32e); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blocktype.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blocktype.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/blocktype.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/blocktype.c 2015-01-27 10:04:16.000000000 +0100 @@ -82,3 +82,78 @@ return OCFS2_BLOCK_UNKNOWN; } + +static void ocfs2_swap_block(ocfs2_filesys *fs, void *block, int to_cpu) +{ + enum ocfs2_block_type bt = ocfs2_detect_block(block); + + switch (bt) { + case OCFS2_BLOCK_INODE: + case OCFS2_BLOCK_SUPERBLOCK: + if (to_cpu) + ocfs2_swap_inode_to_cpu(fs, block); + else + ocfs2_swap_inode_from_cpu(fs, block); + break; + case OCFS2_BLOCK_EXTENT_BLOCK: + if (to_cpu) + ocfs2_swap_extent_block_to_cpu(fs, block); + else + ocfs2_swap_extent_block_from_cpu(fs, block); + break; + case OCFS2_BLOCK_GROUP_DESCRIPTOR: + if (to_cpu) + ocfs2_swap_group_desc_to_cpu(fs, block); + else + ocfs2_swap_group_desc_from_cpu(fs, block); + break; + case OCFS2_BLOCK_DIR_BLOCK: + if (to_cpu) + ocfs2_swap_dir_entries_to_cpu(block, + fs->fs_blocksize); + else + ocfs2_swap_dir_entries_from_cpu(block, + fs->fs_blocksize); + break; + case OCFS2_BLOCK_XATTR: + if (to_cpu) + ocfs2_swap_xattr_block_to_cpu(fs, block); + else + ocfs2_swap_xattr_block_from_cpu(fs, block); + break; + case OCFS2_BLOCK_REFCOUNT: + if (to_cpu) + ocfs2_swap_refcount_block_to_cpu(fs, block); + else + ocfs2_swap_refcount_block_from_cpu(fs, block); + break; + case OCFS2_BLOCK_DXROOT: + if (to_cpu) + ocfs2_swap_dx_root_to_cpu(fs, block); + else + ocfs2_swap_dx_root_from_cpu(fs, block); + break; + case OCFS2_BLOCK_DXLEAF: + if (to_cpu) + ocfs2_swap_dx_leaf_to_cpu(block); + else + ocfs2_swap_dx_leaf_from_cpu(block); + break; + } + + return ; +} + +/* + * ocfs2_swap_block...() silently ignores unknown block types. The caller + * needs to detect unknown blocks. + */ +void ocfs2_swap_block_from_cpu(ocfs2_filesys *fs, void *block) +{ + ocfs2_swap_block(fs, block, 0); +} + +void ocfs2_swap_block_to_cpu(ocfs2_filesys *fs, void *block) +{ + ocfs2_swap_block(fs, block, 1); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/dir_indexed.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/dir_indexed.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/dir_indexed.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/dir_indexed.c 2015-01-27 10:04:16.000000000 +0100 @@ -1247,6 +1247,9 @@ goto out; dx_root = (struct ocfs2_dx_root_block *)dx_buf; + /* set inode to use indexed-dirs */ + di->i_dyn_features |= OCFS2_INDEXED_DIR_FL; + ret = ocfs2_init_dir_trailers(fs, di, dx_root); if (ret) goto out; @@ -1281,8 +1284,6 @@ ret = ocfs2_read_inode(fs, dir, di_buf); if (ret) goto out; - /* set inode to use indexed-dirs */ - di->i_dyn_features |= OCFS2_INDEXED_DIR_FL; ret = ocfs2_write_inode(fs, dir, di_buf); if(ret) @@ -1436,10 +1437,12 @@ entry_list = &dx_leaf->dl_list; } - assert(entry_list->de_count > 0); - assert(entry_list->de_num_used > 0); - assert(dx_root->dr_num_entries > 0); - + if ((entry_list->de_count == 0) || (entry_list->de_num_used == 0) || + (dx_root->dr_num_entries == 0)) { + ret = OCFS2_ET_DIR_CORRUPTED; + goto out; + } + ret = ocfs2_malloc_block(fs->fs_io, &dir_buf); if (ret) goto out; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/inode.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/inode.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/inode.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/inode.c 2015-01-27 10:04:16.000000000 +0100 @@ -231,6 +231,10 @@ if (bytes > max_inline) bytes = max_inline; + /* if inode is empty do not swap */ + if (di->i_size == 0) + return; + if (to_cpu) ocfs2_swap_dir_entries_to_cpu(de_buf, bytes); else @@ -297,9 +301,6 @@ goto out; di = (struct ocfs2_dinode *)blk; - ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check); - if (ret) - goto out; ret = OCFS2_ET_BAD_INODE_MAGIC; if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE, @@ -308,6 +309,10 @@ memcpy(inode_buf, blk, fs->fs_blocksize); + ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check); + if (ret) + goto out; + di = (struct ocfs2_dinode *) inode_buf; ocfs2_swap_inode_to_cpu(fs, di); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/ocfs2_err.et new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/ocfs2_err.et --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/libocfs2/ocfs2_err.et 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/libocfs2/ocfs2_err.et 2015-01-27 10:04:16.000000000 +0100 @@ -195,4 +195,7 @@ ec OCFS2_ET_NONEMTY_QUOTA_HASH, "Freeing non-empty quota hash" +ec OCFS2_ET_BAD_CRC32, + "Bad CRC32" + end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/mount.ocfs2.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/mount.ocfs2.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/mount.ocfs2.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/mount.ocfs2.c 2015-01-27 10:04:16.000000000 +0100 @@ -312,6 +312,7 @@ int clustered = 1; int group_join = 0; struct stat statbuf; + const char *spec; initialize_ocfs_error_table(); initialize_o2dl_error_table(); @@ -414,8 +415,8 @@ } group_join = 1; } - - ret = mount(mo.dev, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS, + spec = canonicalize(mo.dev); + ret = mount(spec, mo.dir, OCFS2_FS_NAME, mo.flags & ~MS_NOSYS, mo.xtra_opts); if (ret) { ret = errno; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/sundries.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/sundries.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mount.ocfs2/sundries.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mount.ocfs2/sundries.c 2015-01-27 10:04:16.000000000 +0100 @@ -223,6 +223,37 @@ return 1; } +/* + * Converts private "dm-N" names to "/dev/mapper/<name>" + * + * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs + * provides the real DM device names in /sys/block/<ptname>/dm/name + */ +char * +canonicalize_dm_name(const char *ptname) +{ + FILE *f; + size_t sz; + char path[256], name[256], *res = NULL; + int err; + + snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname); + f = fopen(path, "r"); + if (!f) + return NULL; + + /* read "<name>\n" from sysfs */ + err = fgets(name, sizeof(name), f); + sz = strlen(name); + if (!err && sz > 1) { + name[sz - 1] = '\0'; + snprintf(path, sizeof(path), "/dev/mapper/%s", name); + res = strdup(path); + } + fclose(f); + return res; +} + /* Make a canonical pathname from PATH. Returns a freshly malloced string. It is up the *caller* to ensure that the PATH is sensible. i.e. canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' @@ -231,6 +262,7 @@ char * canonicalize (const char *path) { char canonical[PATH_MAX+2]; + char *p; if (path == NULL) return NULL; @@ -241,8 +273,13 @@ streq(path, "devpts")) return xstrdup(path); #endif - if (myrealpath (path, canonical, PATH_MAX+1)) - return xstrdup(canonical); - - return xstrdup(path); + if (!myrealpath(path, canonical, PATH_MAX+1)) + return xstrdup(path); + p = strrchr(canonical, '/'); + if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { + p = canonicalize_dm_name(p+1); + if (p) + return p; + } + return xstrdup(canonical); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mounted.ocfs2/mounted.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mounted.ocfs2/mounted.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/mounted.ocfs2/mounted.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/mounted.ocfs2/mounted.c 2015-01-27 10:04:16.000000000 +0100 @@ -31,6 +31,7 @@ #include <errno.h> #include <fcntl.h> #include <linux/fd.h> +#include <linux/major.h> #include <string.h> #include <sys/stat.h> #include <dirent.h> @@ -256,6 +257,58 @@ } } +static void list_rm_device(struct list_head *dev_list, int major, int minor) +{ + struct list_head *pos1, *pos2; + ocfs2_devices *dev; + + list_for_each_safe(pos1, pos2, dev_list) { + dev = list_entry(pos1, ocfs2_devices, list); + if ((dev->maj_num == major) && (dev->min_num == minor)) { + if (dev->map) + ocfs2_free(&dev->map); + list_del(&(dev->list)); + ocfs2_free(&dev); + } + } +} + +static int is_partition(int major, int minor) +{ + char path[PATH_MAX + 1]; + struct stat info; + + snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/partition", + major, minor); + + return !stat(path, &info); +} + +static int find_whole_disk_minor(int major, int minor) { +#ifndef SCSI_BLK_MAJOR +#ifdef SCSI_DISK0_MAJOR +#ifdef SCSI_DISK8_MAJOR +#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \ + ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \ + ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR)) +#else +#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \ + ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR)) +#endif /* defined(SCSI_DISK8_MAJOR) */ +#define SCSI_BLK_MAJOR(M) (SCSI_DISK_MAJOR((M)) || (M) == SCSI_CDROM_MAJOR) +#else +#define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR) +#endif /* defined(SCSI_DISK0_MAJOR) */ +#endif /* defined(SCSI_BLK_MAJOR) */ + if (major == HD_MAJOR) + return (minor - (minor%64)); + + if (SCSI_BLK_MAJOR(major)) + return (minor - (minor%16)); + /* FIXME: Catch all */ + return 0; +} + static errcode_t build_partition_list(struct list_head *dev_list, char *device) { errcode_t ret = 0; @@ -328,6 +381,11 @@ continue; } + if (is_partition(major, minor)) { + int whole_minor = find_whole_disk_minor(major, minor); + list_rm_device(dev_list, major, whole_minor); + } + dev->maj_num = major; dev->min_num = minor; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/jconfig.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/jconfig.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/jconfig.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/jconfig.c 2015-01-27 10:04:16.000000000 +0100 @@ -1082,6 +1082,8 @@ g_strdup(stanza_name), elem); } + else + g_list_append(elem, cfs); return(cfs); } /* j_config_add_stanza() */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/op_register.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/op_register.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/o2cb_ctl/op_register.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/o2cb_ctl/op_register.c 2015-01-27 10:04:16.000000000 +0100 @@ -225,10 +225,15 @@ { errcode_t ret; gchar *hbmode = NULL; + int localhb; hbmode = o2cb_cluster_get_heartbeat_mode(cluster); + localhb = !strcmp(hbmode, O2CB_LOCAL_HEARTBEAT_TAG); ret = o2cb_set_heartbeat_mode(clustername, hbmode); + if (ret && localhb) + ret = 0; + if (ret) tcom_err(ret, "while registering heartbeat mode '%s'", hbmode); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2.pc.in new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2.pc.in --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2.pc.in 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2.pc.in 2015-01-27 10:04:16.000000000 +0100 @@ -7,5 +7,5 @@ Description: Userspace ocfs2 library Version: @VERSION@ Requires: o2dlm o2cb com_err -Libs: -L${libdir} -locfs2 +Libs: -L${libdir} -locfs2 -laio Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2_controld/main.c new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2_controld/main.c --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2_controld/main.c 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2_controld/main.c 2015-01-27 10:04:16.000000000 +0100 @@ -1154,7 +1154,7 @@ { FILE *fp; - fp = fopen("/proc/self/oom_adj", "w"); + fp = fopen("/proc/self/oom_score_adj", "w"); if (!fp) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2console/ocfs2interface/Makefile new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2console/ocfs2interface/Makefile --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/ocfs2console/ocfs2interface/Makefile 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/ocfs2console/ocfs2interface/Makefile 2015-01-27 10:04:16.000000000 +0100 @@ -8,7 +8,7 @@ PYMOD_CFLAGS = -fno-strict-aliasing $(PYTHON_INCLUDES) -LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2 +LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2 -laio LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm $(DL_LIBS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/vendor/common/o2cb.init.sh new/ocfs2-tools-1.8.3+git.1418704844.65fac00/vendor/common/o2cb.init.sh --- old/ocfs2-tools-1.8.2+git.1361836695.ff84eb5/vendor/common/o2cb.init.sh 2013-04-02 11:38:06.000000000 +0200 +++ new/ocfs2-tools-1.8.3+git.1418704844.65fac00/vendor/common/o2cb.init.sh 2015-01-27 10:04:16.000000000 +0100 @@ -32,6 +32,8 @@ LOADED_PLUGINS_FILE="${OCFS2_SYS_DIR}/loaded_cluster_plugins" CLUSTER_STACK_FILE="${OCFS2_SYS_DIR}/cluster_stack" DLMFS_CAPABILITIES_FILE='/sys/module/ocfs2_dlmfs/parameters/capabilities' +DLMFS_DIR="/dlm" +DLMFS_MAGIC="76a9f425" DEBUGFS_DIR="/sys/kernel/debug" if [ -f /etc/sysconfig/o2cb ] @@ -83,6 +85,21 @@ fi } +touch_lockfile() +{ + if [ -d /var/lock/subsys ] + then + touch /var/lock/subsys/o2cb + fi +} + +remove_lockfile() +{ + if [ -e /var/lock/subsys/o2cb ] + then + rm /var/lock/subsys/o2cb + fi +} # # if_fail() @@ -600,6 +617,19 @@ return 0 } +o2cbmounts() +{ + if [ "$#" != "1" -o -z "$1" ] + then + echo "o2cbmounts(): Missing arguments" >&2 + exit 1 + fi + + FSNAME="$1" + + LC_ALL=C awk -v FSNAME=$FSNAME 'BEGIN {fsname = FSNAME;} $3 == fsname { print $2 }' /proc/mounts +} + # # unmount_filesystem() # Unmount a pseudo-filesystem of type $1 from mountpoint $2. It will @@ -620,14 +650,34 @@ if check_filesystem "$FSNAME" "$MOUNTPOINT" then echo -n "Unmounting ${FSNAME} filesystem: " - umount $MOUNTPOINT - RC=$? - if [ $RC != 0 ] + remaining=$(o2cbmounts $FSNAME) + sig= + retry=3 + while [ -n "$remaining" -a "$retry" -gt 0 ] + do + if [ "$retry" -lt 3 ]; then + echo -n "Retry unmounting $FSNAME} filesystem: " + fi + + umount $MOUNTPOINT + RC=$? + if_fail $RC + + remaining=$(o2cbmounts $FSNAME) + [ -z "$remaining" ] && break + + fuser -km $sig $remaining >/dev/null 2>&1 + sleep 5 + retry=$(($retry - 1)) + sig=-9 + done + + remaining=$(o2cbmounts $FSNAME) + if [ -n "$remaining" ] then echo "Unable to unmount ${FSNAME} filesystem" >&2 return 1 fi - if_fail $RC # For the success string fi unload_filesystem "$FSNAME" @@ -953,12 +1003,60 @@ fi fi - mount_filesystem "ocfs2_dlmfs" "/dlm" + mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR if_fail $? return 0 } +# Return the list of userdlm domains +# +userdlm_domains() +{ + magic=$(stat -f --printf="%t" ${DLMFS_DIR}) + if [ "x$magic" = "x$DLMFS_MAGIC" ] + then + ls ${DLMFS_DIR} + fi +} + +# +# Print userdlm domains +# +userdlm_status() +{ + [ -n "$(userdlm_domains)" ] && { + echo "Active userdlm domains: " $(userdlm_domains) + } +} + +# +# Force removes all userdlm domains +# +clean_userdlm_domains() +{ + # Cleanup only if mounted + magic=$(stat -f --printf="%t" ${DLMFS_DIR}) + if [ "x$magic" = "x$DLMFS_MAGIC" ] + then + echo -n "Clean userdlm domains: " + # Kill all processes accessing dlmfs + fuser -km -9 ${DLMFS_DIR} >/dev/null 2>&1 + + # Remove all domains and locks + for domain in $(userdlm_domains) + do + domain_path="${DLMFS_DIR}/${domain}" + magic=$(stat -f --printf="%t" ${domain_path}) + if [ "x$magic" = "x$DLMFS_MAGIC" ] + then + rm -rf ${domain_path} + fi + done + echo "OK" + fi +} + # # dlmfs_user_capable() # Check if dlmfs supports user stacks. @@ -1021,7 +1119,7 @@ if dlmfs_user_capable then - mount_filesystem "ocfs2_dlmfs" "/dlm" + mount_filesystem "ocfs2_dlmfs" $DLMFS_DIR if_fail $? fi @@ -1078,7 +1176,7 @@ fi fi - unmount_filesystem "ocfs2_dlmfs" "/dlm" + unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR if_fail $? unload_stack_plugins @@ -1101,7 +1199,7 @@ exit 1 fi - unmount_filesystem "ocfs2_dlmfs" "/dlm" + unmount_filesystem "ocfs2_dlmfs" $DLMFS_DIR if_fail $? unload_stack_plugins @@ -1133,7 +1231,7 @@ status_stack_o2cb() { status_stack_plugin - status_filesystem "ocfs2_dlmfs" "/dlm" + status_filesystem "ocfs2_dlmfs" $DLMFS_DIR } status_stack_user() @@ -1221,6 +1319,8 @@ { PLUGIN="$(select_stack_plugin)" + touch_lockfile + # XXX: SPECIAL CASE! We must load configfs for configfs_path() to work load_filesystem "configfs" if_fail $? @@ -1605,6 +1705,8 @@ FORCE=0 fi + clean_userdlm_domains + offline_$PLUGIN "$CLUSTER" "$FORCE" unload_filesystem "ocfs2" @@ -1628,6 +1730,8 @@ unload_stack_$PLUGIN + remove_lockfile + # Only unmount configfs if there are no other users if [ -z "$(ls -1 "$(configfs_path)" 2>/dev/null)" ] then @@ -1727,9 +1831,39 @@ fi online_status "$CLUSTER" + + userdlm_status } +# +# online_status() +# +# Return codes to userspace. ** Do not change. ** +# 0 is online, 1 is offline, 2 is error +# +online-status() +{ + CLUSTER="${1:-${O2CB_BOOTCLUSTER}}" + if [ -z "$CLUSTER" ] + then + return 2 + fi + check_online "$CLUSTER" + RC=$? + if [ "$RC" = "2" ] + then + echo "online" + exit 0 + elif [ "$RC" = "0" ] + then + echo "offline" + exit 1 + else + echo "error" + exit 2 + fi +} case "$1" in start) @@ -1763,6 +1897,10 @@ online "$2" ;; + online-status) + online-status "$2" + ;; + offline) offline "$2" ;; @@ -1801,7 +1939,7 @@ ;; *) - echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|force-offline|status}" + echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|force-offline|status|online-status}" exit 1 ;; esac
