From 1ef93745227af455da045cdf4a48ec1ae38c518c Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 13 Apr 2012 12:55:45 -0600 Subject: [PATCH] debugfs: dump "fid" and "lma" xattrs on inode stat Print out the Lustre "fid" and "lma" object xattr contents, if present, with debugfs stat to simplify debugging. Increase the size of xattrs hex-dumped from 40 to 120. LU-8998 debugfs: handle combined LMA EA and PFID EA We need to store the stripe size and stripe count information in the OST object's PFID EA for the layout LFSCK to recover the MDT object or its (lost or corrupted) LOV EA. On the other hand, for PFL file, we also need to store its PFL ID and extent information in its OST object's PFID EA. Consider performance, we will store the PFID EA inside the inode body to avoid extra IO when read/write the PFID EA. Unfortunately, the space inside current 256-bytes inode for EA is very limited, and above enlarged PFID EA exceeds such limitation. So we have to make some hack with the PFID EA and LMA EA combined together. The patch makes the debugfs tool to handle such case properly. Signed-off-by: Fan Yong Change-Id: I1380d16d94d6d05272e22fdfff07ada038685669 Reviewed-on: https://review.whamcloud.com/19436 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Change-Id: I9d3aaa1795426384bd78c3e214cc196d92f64edb Signed-off-by: Andreas Dilger --- debugfs/Makefile.in | 1 + debugfs/xattrs.c | 101 ++++++++++++++++++++++++++++++++++++++++++++- lib/ext2fs/ext2fs.h | 3 +- lib/ext2fs/ext_attr.c | 6 ++- lib/ext2fs/lfsck.h | 50 ++++++++++++++++++++++ misc/fuse2fs.c | 5 ++- tests/d_xattr_edits/expect | 2 +- 7 files changed, 161 insertions(+), 7 deletions(-) diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in index ed4ea8d..dd2acd7 100644 --- a/debugfs/Makefile.in +++ b/debugfs/Makefile.in @@ -51,6 +51,7 @@ STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) \ # clean up this mess, we should be able to drop it LOCAL_CFLAGS = -I$(srcdir)/../e2fsck -DDEBUGFS DEPEND_CFLAGS = -I$(srcdir) +@LFSCK_CMT@LUSTRE_INC=-I @LUSTRE@/lustre/include -I @LUSTRE@/include -I @LUSTRE@/libcfs/include -Wall .c.o: $(E) " CC $<" diff --git a/debugfs/xattrs.c b/debugfs/xattrs.c index bd11450..e69a609 100644 --- a/debugfs/xattrs.c +++ b/debugfs/xattrs.c @@ -17,6 +17,7 @@ extern char *optarg; #include "support/cstring.h" #include "debugfs.h" +#include "ext2fs/lfsck.h" #define PRINT_XATTR_HEX 0x01 #define PRINT_XATTR_RAW 0x02 @@ -24,6 +25,8 @@ extern char *optarg; #define PRINT_XATTR_STATFMT 0x08 #define PRINT_XATTR_NOQUOTES 0x10 +extern const char *debug_prog_name; + /* Dump extended attributes */ static void print_xattr_hex(FILE *f, const char *str, int len) { @@ -74,19 +77,113 @@ static void print_xattr(FILE *f, char *name, char *value, size_t value_len, (strcmp(name, "system.data") == 0)) value_len = 0; if (value_len != 0 && - (!(print_flags & PRINT_XATTR_STATFMT) || (value_len < 40))) { + (!(print_flags & PRINT_XATTR_STATFMT) || (value_len < 120))) { fprintf(f, " = "); print_xattr_string(f, value, value_len, print_flags); } fputc('\n', f); } -static int dump_attr(char *name, char *value, size_t value_len, void *data) +static void print_fidstr(FILE *f, void *name, void *value, + ext2_ino_t inode_num, size_t value_len) +{ + struct filter_fid_old *ff = value; + int stripe; + + /* Since Lustre 2.4 only the parent FID is stored in filter_fid, + * and the self fid is stored in the LMA and is printed below. */ + if (value_len < sizeof(ff->ff_parent)) { + fprintf(stderr, "%s: error: filter_fid for inode %u smaller " + "than expected (%lu bytes).\n", + debug_prog_name, inode_num, value_len); + return; + } + fid_le_to_cpu(&ff->ff_parent, &ff->ff_parent); + stripe = fid_ver(&ff->ff_parent); /* stripe index is stored in f_ver */ + ff->ff_parent.f_ver = 0; + + fprintf(f, " fid: "); + /* Old larger filter_fid should only ever be used with seq = 0. + * FID-on-OST should use LMA for FID_SEQ_NORMAL OST objects. */ + if (value_len == sizeof(*ff)) + fprintf(f, "objid=%llu seq=%llu ", + ext2fs_le64_to_cpu(ff->ff_objid), + ext2fs_le64_to_cpu(ff->ff_seq)); + + fprintf(f, "parent="DFID" stripe=%u", PFID(&ff->ff_parent), stripe); + if (value_len > sizeof(*ff)) { + struct filter_fid *ff_new = value; + + fprintf(f, " stripe_size=%u stripe_count=%u", + ext2fs_le32_to_cpu(ff_new->ff_stripe_size), + ext2fs_le32_to_cpu(ff_new->ff_stripe_count)); + if (ff_new->ff_pfl_id != 0) + fprintf(f, " component_id=%u component_start=%llu " + "component_end=%llu", + ext2fs_le32_to_cpu(ff_new->ff_pfl_id), + ext2fs_le64_to_cpu(ff_new->ff_pfl_start), + ext2fs_le64_to_cpu(ff_new->ff_pfl_end)); + } + fprintf(f, "\n"); +} + +static void print_lmastr(FILE *f, void *name, void *value, + ext2_ino_t inode_num, size_t value_len) +{ + struct lustre_mdt_attrs *lma = value; + struct lustre_ost_attrs *loa = value; + + if (value_len < offsetof(typeof(*lma), lma_self_fid) + + sizeof(lma->lma_self_fid)) { + fprintf(stderr, "%s: error: LMA for inode %u smaller than " + "expected (%lu bytes).\n", + debug_prog_name, inode_num, value_len); + return; + } + fid_le_to_cpu(&lma->lma_self_fid, &lma->lma_self_fid); + fprintf(f, " lma: fid="DFID" compat=%x incompat=%x\n", + PFID(&lma->lma_self_fid), ext2fs_le32_to_cpu(lma->lma_compat), + ext2fs_le32_to_cpu(lma->lma_incompat)); + if (value_len >= offsetof(typeof(*loa), loa_pfl_end) + + sizeof(loa->loa_pfl_end)) { + int idx; + int cnt; + + fid_le_to_cpu(&loa->loa_parent_fid, &loa->loa_parent_fid); + idx = loa->loa_parent_fid.f_ver & PFID_STRIPE_COUNT_MASK; + cnt = loa->loa_parent_fid.f_ver >> PFID_STRIPE_IDX_BITS; + loa->loa_parent_fid.f_ver = 0; + + fprintf(f, " fid: parent="DFID" stripe=%u stripe_size=%u " + "stripe_count=%u", PFID(&loa->loa_parent_fid), idx, + ext2fs_le32_to_cpu(loa->loa_stripe_size), cnt); + if (loa->loa_pfl_id != 0) + fprintf(f, " component_id=%u component_start=%llu " + "component_end=%llu", + ext2fs_le32_to_cpu(loa->loa_pfl_id), + ext2fs_le64_to_cpu(loa->loa_pfl_start), + ext2fs_le64_to_cpu(loa->loa_pfl_end)); + fprintf(f, "\n"); + } +} + +static int dump_attr(char *name, char *value, size_t value_len, + ext2_ino_t inode_num, void *data) { FILE *out = data; fprintf(out, " "); print_xattr(out, name, value, value_len, PRINT_XATTR_STATFMT); + if (!strncmp(name, EXT2_ATTR_INDEX_TRUSTED_PREFIX LUSTRE_XATTR_OST_FID, + strlen(name)) || + !strncmp(name, EXT2_ATTR_INDEX_LUSTRE_PREFIX LUSTRE_XATTR_OST_FID, + strlen(name))) + print_fidstr(out, name, value, inode_num, value_len); + if (!strncmp(name, EXT2_ATTR_INDEX_TRUSTED_PREFIX LUSTRE_XATTR_MDT_LMA, + strlen(name)) || + !strncmp(name, EXT2_ATTR_INDEX_LUSTRE_PREFIX LUSTRE_XATTR_MDT_LMA, + strlen(name))) + print_lmastr(out, name, value, inode_num, value_len); return 0; } diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 97843b5..d842c33 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -1307,7 +1307,8 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle); errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle); errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, int (*func)(char *name, char *value, - size_t value_len, void *data), + size_t value_len, + ext2_ino_t inode_num, void *data), void *data); errcode_t ext2fs_xattr_get(struct ext2_xattr_handle *h, const char *key, void **value, size_t *value_len); diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index 45135c9..21a2dbd 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -379,6 +379,7 @@ static struct ea_name_index ea_names[] = { {2, "system.posix_acl_access"}, {8, "system.richacl"}, {6, "security."}, + {5, "lustre."}, {4, "trusted."}, {7, "system."}, {1, "user."}, @@ -1130,7 +1131,8 @@ out: errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, int (*func)(char *name, char *value, - size_t value_len, void *data), + size_t value_len, + ext2_ino_t inode_num, void *data), void *data) { struct ext2_xattr *x; @@ -1139,7 +1141,7 @@ errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, EXT2_CHECK_MAGIC(h, EXT2_ET_MAGIC_EA_HANDLE); for (x = h->attrs; x < h->attrs + h->count; x++) { - ret = func(x->name, x->value, x->value_len, data); + ret = func(x->name, x->value, x->value_len, x->ea_ino, data); if (ret & XATTR_CHANGED) dirty = 1; if (ret & XATTR_ABORT) diff --git a/lib/ext2fs/lfsck.h b/lib/ext2fs/lfsck.h index 6a49042..00071f2 100644 --- a/lib/ext2fs/lfsck.h +++ b/lib/ext2fs/lfsck.h @@ -34,6 +34,56 @@ static inline void fid_be_to_cpu(struct lu_fid *dst, struct lu_fid *src) dst->f_oid = ext2fs_be32_to_cpu(src->f_oid); dst->f_ver = ext2fs_be32_to_cpu(src->f_ver); } + +static inline void fid_le_to_cpu(struct lu_fid *dst, struct lu_fid *src) +{ + dst->f_seq = ext2fs_le64_to_cpu(src->f_seq); + dst->f_oid = ext2fs_le32_to_cpu(src->f_oid); + dst->f_ver = ext2fs_le32_to_cpu(src->f_ver); +} +#endif /* HAVE_LUSTRE_LUSTRE_IDL_H */ + +#define LUSTRE_XATTR_MDT_LOV "lov" +#define LUSTRE_XATTR_MDT_LMA "lma" +#define LUSTRE_XATTR_MDT_LINK "link" +#define LUSTRE_XATTR_OST_FID "fid" + +#ifndef LMA_OLD_SIZE +#ifndef LMA_INCOMPAT_SUPP +struct lustre_mdt_attrs { + __u32 lma_compat; + __u32 lma_incompat; + struct lu_fid lma_self_fid; +}; +struct lustre_ost_attrs { + struct lustre_mdt_attrs loa_lma; + struct lu_fid loa_parent_fid; + __u32 loa_stripe_size; + __u32 loa_pfl_id; + __u64 loa_pfl_start; + __u64 loa_pfl_end; +}; #endif +struct filter_fid_old { + struct lu_fid ff_parent; + __u64 ff_objid; + __u64 ff_seq; +}; + +struct filter_fid { + struct lu_fid ff_parent; + __u32 ff_stripe_size; + __u32 ff_stripe_count; + __u64 ff_pfl_start; + __u64 ff_pfl_end; + __u32 ff_pfl_id; +}; + +#define LMA_OLD_SIZE 64 +#endif /* !LMA_OLD_SIZE */ + +#define PFID_STRIPE_IDX_BITS 16 +#define PFID_STRIPE_COUNT_MASK ((1 << PFID_STRIPE_IDX_BITS) - 1) + #endif /* LFSCK_H */ diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index c595721..f73ceba 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -2496,6 +2496,7 @@ out: static int count_buffer_space(char *name, char *value EXT2FS_ATTR((unused)), size_t value_len EXT2FS_ATTR((unused)), + ext2_ino_t inode_num EXT2FS_ATTR((unused)), void *data) { unsigned int *x = data; @@ -2505,7 +2506,9 @@ static int count_buffer_space(char *name, char *value EXT2FS_ATTR((unused)), } static int copy_names(char *name, char *value EXT2FS_ATTR((unused)), - size_t value_len EXT2FS_ATTR((unused)), void *data) + size_t value_len EXT2FS_ATTR((unused)), + ext2_ino_t inode_num EXT2FS_ATTR((unused)), + void *data) { char **b = data; diff --git a/tests/d_xattr_edits/expect b/tests/d_xattr_edits/expect index 38f3030..c87a973 100644 --- a/tests/d_xattr_edits/expect +++ b/tests/d_xattr_edits/expect @@ -36,7 +36,7 @@ ea_set -f d_xattr_edits.tmp / user.file_based_xattr Exit status is 0 ea_list / Extended attributes: - user.file_based_xattr (108) + user.file_based_xattr (108) = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\n" Exit status is 0 ea_get / user.file_based_xattr user.file_based_xattr (108) = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\n" -- 1.8.3.1