[Ocfs2-tools-devel] [PATCH 7/7] debugfs: add set/get xattr commands
Tiger Yang
tiger.yang at oracle.com
Tue Oct 20 01:42:30 PDT 2009
This patch add do_setxattr and do_getxattr commands
for setting and getting xattrs of a file.
This patch also add a new option "l" for list all xattrs' name
for command do_xattr.
Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
---
debugfs.ocfs2/commands.c | 179 ++++++++++++++++++++++++++++++++++++++++--
debugfs.ocfs2/dump.c | 45 +++++++++--
debugfs.ocfs2/include/dump.h | 4 +-
3 files changed, 212 insertions(+), 16 deletions(-)
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index c0bf85a..63894b1 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -75,6 +75,8 @@ static void do_dlm_locks (char **args);
static void do_controld(char **args);
static void do_dirblocks(char **args);
static void do_xattr(char **args);
+static void do_setxattr(char **args);
+static void do_getxattr(char **args);
static void do_frag(char **args);
dbgfs_gbls gbls;
@@ -110,6 +112,8 @@ static Command commands[] = {
{ "stat", do_stat },
{ "stats", do_stats },
{ "xattr", do_xattr },
+ { "setxattr", do_setxattr },
+ { "getxattr", do_getxattr },
{ "encode", do_encode_lockres },
{ "decode", do_decode_lockres },
{ "dirblocks", do_dirblocks },
@@ -1784,10 +1788,11 @@ static void do_xattr(char **args)
struct ocfs2_dinode *inode;
char *buf = NULL;
FILE *out;
- char *usage = "usage: xattr [-v] <filespec>";
+ char *usage = "usage: xattr [-v] [-l] <filespec>";
uint64_t blkno, xattrs_bucket = 0;
uint32_t xattrs_ibody = 0, xattrs_block = 0;
- int ind = 1, verbose = 0;
+ int ind = 0, verbose = 0, listxattr = 0;
+ int argc, c;
errcode_t ret = 0;
if (check_device_open())
@@ -1798,11 +1803,23 @@ static void do_xattr(char **args)
return;
}
- if (!strcmp(args[1], "-v")) {
- ++ind;
- ++verbose;
+ for (argc = 0; (args[argc]); ++argc);
+
+ optind = 0;
+ while ((c = getopt(argc, args, "vl")) != -1) {
+ switch (c) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'l':
+ listxattr = 1;
+ break;
+ default:
+ break;
+ }
}
+ ind = optind;
if (!args[ind]) {
fprintf(stderr, "%s\n", usage);
return;
@@ -1828,11 +1845,12 @@ static void do_xattr(char **args)
out = open_pager(gbls.interactive);
- xattrs_ibody = dump_xattr_ibody(out, gbls.fs, inode, verbose);
+ xattrs_ibody = dump_xattr_ibody(out, gbls.fs, inode, verbose,
+ listxattr);
if (inode->i_xattr_loc)
ret = dump_xattr_block(out, gbls.fs, inode, &xattrs_block,
- &xattrs_bucket, verbose);
+ &xattrs_bucket, verbose, listxattr);
if (ret)
com_err(args[0], ret, "while traversing inode at block "
@@ -1845,6 +1863,153 @@ static void do_xattr(char **args)
return ;
}
+static void do_setxattr(char **args)
+{
+ ocfs2_cached_inode *ci = NULL;
+ char *usage = "usage: setxattr -n xxxx -v xxxx <filespec>";
+ uint64_t blkno;
+ int ind = 0;
+ errcode_t ret = 0;
+ char *name = NULL;
+ char *value = NULL;
+ int argc, c;
+ int value_len;
+
+ if (check_device_open())
+ return;
+
+ if (!args[1]) {
+ fprintf(stderr, "%s\n", usage);
+ return;
+ }
+
+ for (argc = 0; (args[argc]); ++argc);
+
+ optind = 0;
+ while ((c = getopt(argc, args, "n:v:")) != -1) {
+ switch (c) {
+ case 'n':
+ name = optarg;
+ break;
+ case 'v':
+ value = optarg;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ind = optind;
+ if (!args[ind]) {
+ fprintf(stderr, "%s\n", usage);
+ return;
+ }
+
+ ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
+ args[ind], &blkno);
+ if (ret) {
+ com_err(args[0], ret, "while translating %s", args[ind]);
+ return;
+ }
+ value_len = strlen(value);
+
+ ret = ocfs2_read_cached_inode(gbls.fs, blkno, &ci);
+ if (ret) {
+ com_err(args[0], ret, "while reading inode %"PRIu64"", blkno);
+ return;
+ }
+
+ ret = ocfs2_xattr_set(ci, name, value, value_len);
+ if (ret) {
+ com_err(args[0], ret, "while set xattr in inode %"PRIu64"",
+ blkno);
+ return;
+ }
+ ret = ocfs2_write_cached_inode(gbls.fs, ci);
+ if (ret) {
+ com_err(args[0], ret, "while write xattr in inode %"PRIu64"",
+ blkno);
+ return;
+ }
+
+ if (ci)
+ ocfs2_free_cached_inode(gbls.fs, ci);
+
+ return ;
+}
+
+static void do_getxattr(char **args)
+{
+ ocfs2_cached_inode *ci = NULL;
+ char *usage = "usage: getxattr -n xxxx <filespec>";
+ uint64_t blkno;
+ int ind = 0;
+ errcode_t ret = 0;
+ char *name = NULL;
+ char *value = NULL;
+ int argc, c;
+ int value_len;
+ size_t got = 0;
+
+ if (check_device_open())
+ return;
+
+ if (!args[1]) {
+ fprintf(stderr, "%s\n", usage);
+ return;
+ }
+
+ for (argc = 0; (args[argc]); ++argc);
+
+ optind = 0;
+ while ((c = getopt(argc, args, "n:")) != -1) {
+ switch (c) {
+ case 'n':
+ name = optarg;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ind = optind;
+ if (!args[ind]) {
+ fprintf(stderr, "%s\n", usage);
+ return;
+ }
+
+ ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
+ args[ind], &blkno);
+ if (ret) {
+ com_err(args[0], ret, "while translating %s", args[ind]);
+ return;
+ }
+ ret = ocfs2_malloc_blocks(gbls.fs->fs_io,
+ 65536 / gbls.fs->fs_blocksize, &value);
+ if (ret)
+ return;
+ value_len = 65536;
+
+ ret = ocfs2_read_cached_inode(gbls.fs, blkno, &ci);
+ if (ret) {
+ com_err(args[0], ret, "while reading inode %"PRIu64"", blkno);
+ return;
+ }
+
+ ret = ocfs2_xattr_get(ci, name, value, value_len, &got);
+ if (ret < 0) {
+ com_err(args[0], ret, "while get xattr in inode %"PRIu64"",
+ blkno);
+ return;
+ }
+
+ if (ci)
+ ocfs2_free_cached_inode(gbls.fs, ci);
+
+ ocfs2_free(&value);
+ return ;
+}
+
static errcode_t calc_num_extents(ocfs2_filesys *fs,
struct ocfs2_extent_list *el,
uint32_t *ne)
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
index 4c6891a..ba1b515 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -829,6 +829,28 @@ void dump_icheck(FILE *out, int hdr, uint64_t blkno, uint64_t inode,
fprintf(out, "\t%-15"PRIu64" %-15s %-15s\n", blkno, inostr, offstr);
}
+static void list_xattr(FILE *out, struct ocfs2_xattr_header *xh)
+{
+ int i, type;
+ const char *prefix, *name;
+ char xname[400];
+
+ for (i = 0 ; i < xh->xh_count; i++) {
+ struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
+ int pre_len;
+ type = ocfs2_xattr_get_type(xe);
+ prefix = ocfs2_xattr_get_prefix(type);
+ if (prefix) {
+ pre_len = strlen(prefix);
+ name = (const char *)xh + xe->xe_name_offset;
+ memcpy(xname, prefix, pre_len);
+ memcpy(xname + pre_len, name, xe->xe_name_len);
+ xname[pre_len + xe->xe_name_len] = '\0';
+ fprintf(out, "%s\n", xname);
+ }
+ }
+}
+
static void dump_xattr(FILE *out, struct ocfs2_xattr_header *xh)
{
int i;
@@ -861,7 +883,8 @@ static errcode_t dump_xattr_buckets(FILE *out,
uint64_t blkno,
uint32_t clusters,
uint64_t *xattrs_bucket,
- int verbose)
+ int verbose,
+ int listxattr)
{
int i;
errcode_t ret = 0;
@@ -895,6 +918,8 @@ static errcode_t dump_xattr_buckets(FILE *out,
i, xh->xh_count);
if (verbose)
dump_xattr(out, xh);
+ else if (listxattr)
+ list_xattr(out, xh);
*xattrs_bucket += xh->xh_count;
}
@@ -911,7 +936,8 @@ static errcode_t dump_xattr_index_block(FILE *out,
struct ocfs2_dinode *di,
struct ocfs2_xattr_block *xb,
uint64_t *xattrs_bucket,
- int verbose)
+ int verbose,
+ int listxattr)
{
struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
errcode_t ret = 0;
@@ -934,7 +960,7 @@ static errcode_t dump_xattr_index_block(FILE *out,
goto out;
ret = dump_xattr_buckets(out, fs, p_blkno, num_clusters,
- xattrs_bucket, verbose);
+ xattrs_bucket, verbose, listxattr);
if (ret)
goto out;
@@ -956,7 +982,8 @@ errcode_t dump_xattr_block(FILE *out, ocfs2_filesys *fs,
struct ocfs2_dinode *in,
uint32_t *xattrs_block,
uint64_t *xattrs_bucket,
- int verbose)
+ int verbose,
+ int listxattr)
{
errcode_t ret;
char *blk = NULL;
@@ -979,9 +1006,11 @@ errcode_t dump_xattr_block(FILE *out, ocfs2_filesys *fs,
(uint64_t)in->i_xattr_loc, *xattrs_block);
if (verbose)
dump_xattr(out, xh);
+ else if (listxattr)
+ list_xattr(out, xh);
} else {
- ret = dump_xattr_index_block(out, fs, in, xb,
- xattrs_bucket, verbose);
+ ret = dump_xattr_index_block(out, fs, in, xb, xattrs_bucket,
+ verbose, listxattr);
}
out:
@@ -994,7 +1023,7 @@ out:
*
*/
uint32_t dump_xattr_ibody(FILE *out, ocfs2_filesys *fs,
- struct ocfs2_dinode *in, int verbose)
+ struct ocfs2_dinode *in, int verbose, int listxattr)
{
if (in->i_dyn_features & OCFS2_INLINE_XATTR_FL) {
struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)
@@ -1005,6 +1034,8 @@ uint32_t dump_xattr_ibody(FILE *out, ocfs2_filesys *fs,
xh->xh_count);
if (verbose)
dump_xattr(out, xh);
+ else if (listxattr)
+ list_xattr(out, xh);
return xh->xh_count;
} else {
fprintf(out, "\tExtended Attributes inline: 0\n");
diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
index 8cd9a97..ea0cbcf 100644
--- a/debugfs.ocfs2/include/dump.h
+++ b/debugfs.ocfs2/include/dump.h
@@ -70,12 +70,12 @@ void dump_icheck(FILE *out, int hdr, uint64_t blkno, uint64_t inode,
int validoffset, uint64_t offset, int status);
void dump_block_check(FILE *out, struct ocfs2_block_check *bc);
uint32_t dump_xattr_ibody(FILE *out, ocfs2_filesys *fs,
- struct ocfs2_dinode *in, int verbose);
+ struct ocfs2_dinode *in, int verbose, int listxattr);
errcode_t dump_xattr_block(FILE *out, ocfs2_filesys *fs,
struct ocfs2_dinode *in,
uint32_t *xattrs_block,
uint64_t *xattrs_bucket,
- int verbose);
+ int verbose, int listxattr);
void dump_frag(FILE *out, uint64_t ino, uint32_t clusters,
uint32_t extents);
--
1.5.4.1
More information about the Ocfs2-tools-devel
mailing list