4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; if not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2016, DDN Storage Corporation.
26 * lustre/utils/ll_decode_linkea.c
28 * Tool for printing the MDT link_ea structure on the objects
29 * in human readable form.
31 * Author: Li Xi <lixi@ddn.com>
40 #include <sys/types.h>
41 #include <sys/xattr.h>
42 #include <linux/lustre/lustre_fid.h>
44 #define BUFFER_SIZE 65536
46 static void print_name(const char *cp, int len)
52 if (!isprint(ch) || ch == '\\')
53 printf("\\x%02x", ch);
59 int decode_linkea(const char *fname)
61 char buf[BUFFER_SIZE];
62 struct link_ea_header *leh;
64 struct link_ea_entry *lee;
70 size = getxattr(fname, "trusted.link", buf, BUFFER_SIZE);
72 if (errno == ERANGE) {
73 fprintf(stderr, "%s: failed to read trusted.link "
74 "xattr, the buffer size %u might be too "
75 "small\n", fname, BUFFER_SIZE);
78 "%s: failed to read trusted.link xattr: %s\n",
79 fname, strerror(errno));
84 leh = (struct link_ea_header *)buf;
85 if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
86 leh->leh_magic = LINK_EA_MAGIC;
87 leh->leh_reccount = __swab32(leh->leh_reccount);
88 leh->leh_len = __swab64(leh->leh_len);
90 if (leh->leh_magic != LINK_EA_MAGIC) {
92 "%s: magic mismatch, expected 0x%lx, got 0x%x\n",
93 fname, LINK_EA_MAGIC, leh->leh_magic);
96 if (leh->leh_reccount == 0) {
97 fprintf(stderr, "%s: empty record count\n", fname);
100 if (leh->leh_len > size) {
102 "%s: invalid length %llu, should smaller than %zd\n",
103 fname, (unsigned long long)leh->leh_len, size);
107 length = sizeof(struct link_ea_header);
108 lee = (struct link_ea_entry *)(leh + 1);
109 printf("%s: count %u\n", fname, leh->leh_reccount);
110 for (i = 0; i < leh->leh_reccount; i++) {
111 reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
113 if (length > leh->leh_len) {
115 "%s: length exceeded, expected %llu, got %llu\n",
116 fname, (unsigned long long)leh->leh_len,
117 (unsigned long long)length);
120 memcpy(&pfid, &lee->lee_parent_fid, sizeof(pfid));
121 fid_be_to_cpu(&pfid, &pfid);
123 printf(" %d: pfid "DFID", name '", i, PFID(&pfid));
124 print_name(lee->lee_name, reclen - (int)sizeof(*lee));
126 lee = (struct link_ea_entry *)((char *)lee + reclen);
129 if (length != leh->leh_len) {
131 "%s: length mismatch, expected %llu, got %llu\n",
133 (unsigned long long)leh->leh_len,
134 (unsigned long long)length);
141 int main(int argc, char *argv[])
147 for (i = 1; i < argc; i++) {
148 rc2 = decode_linkea(argv[i]);