[Ocfs2-tools-devel] [PATCH 05/10] debugfs: Decode dentry locks
Sunil Mushran
sunil.mushran at oracle.com
Tue Jul 22 14:44:13 PDT 2008
This patch teaches debugfs to encode and decode dentry lockres'
that have a different encoding scheme than others.
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
debugfs.ocfs2/commands.c | 50 ++++++------------
debugfs.ocfs2/main.c | 42 ++++++++-------
debugfs.ocfs2/utils.c | 36 ++++++++-----
include/ocfs2-kernel/ocfs2_lockid.h | 35 +++++++++++++
include/ocfs2/ocfs2.h | 8 ++-
libocfs2/dlm.c | 8 ++--
libocfs2/lockid.c | 97 +++++++++++++++-------------------
7 files changed, 148 insertions(+), 128 deletions(-)
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index 0fb89c4..7fff4ba 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -1360,49 +1360,33 @@ static void do_rdump(char **args)
*/
static void do_encode_lockres (char **args)
{
- struct ocfs2_dinode *inode;
+ struct ocfs2_dinode *inode = (struct ocfs2_dinode *)gbls.blockbuf;
uint64_t blkno;
- char *buf = NULL;
+ uint32_t gen;
errcode_t ret = 0;
- char suprlock[50] = "\0";
- char metalock[50] = "\0";
- char datalock[50] = "\0";
- char rdwrlock[50] = "\0";
+ char lock[50] = "\0";
+ enum ocfs2_lock_type type = OCFS2_LOCK_TYPE_META;
if (process_inode_args(args, &blkno))
- return ;
+ return;
- if (blkno == OCFS2_SUPER_BLOCK_BLKNO) {
- ret = ocfs2_encode_lockres(OCFS2_LOCK_TYPE_SUPER, blkno, 0,
- suprlock);
- } else {
- buf = gbls.blockbuf;
- ret = ocfs2_read_inode(gbls.fs, blkno, buf);
- if (!ret) {
- inode = (struct ocfs2_dinode *)buf;
- ocfs2_encode_lockres(OCFS2_LOCK_TYPE_META, blkno,
- inode->i_generation, metalock);
- ocfs2_encode_lockres(OCFS2_LOCK_TYPE_DATA, blkno,
- inode->i_generation, datalock);
- ocfs2_encode_lockres(OCFS2_LOCK_TYPE_RW, blkno,
- inode->i_generation, rdwrlock);
+ if (blkno == OCFS2_SUPER_BLOCK_BLKNO)
+ type = OCFS2_LOCK_TYPE_SUPER;
+ else {
+ ret = ocfs2_read_inode(gbls.fs, blkno, (char *)inode);
+ if (ret) {
+ com_err(args[0], ret, "while reading inode %"PRIu64"",
+ blkno);
+ return;
}
+ gen = inode->i_generation;
}
- if (ret) {
- com_err(args[0], ret, "while reading inode %"PRIu64"", blkno);
- return ;
- }
+ ocfs2_encode_lockres(type, blkno, gen, 0, lock);
printf("\t");
- if (*suprlock)
- printf("%s ", suprlock);
- if (*metalock)
- printf("%s ", metalock);
- if (*datalock)
- printf("%s ", datalock);
- if (*rdwrlock)
- printf("%s ", rdwrlock);
+ if (*lock)
+ printf("%s ", lock);
printf("\n");
return ;
diff --git a/debugfs.ocfs2/main.c b/debugfs.ocfs2/main.c
index 3588726..36a5192 100644
--- a/debugfs.ocfs2/main.c
+++ b/debugfs.ocfs2/main.c
@@ -115,8 +115,9 @@ static void process_decode_lockres(int argc, char **argv, int startind)
int i;
errcode_t ret;
enum ocfs2_lock_type type;
- uint64_t blkno;
- uint32_t generation;
+ uint64_t blkno = 0;
+ uint32_t generation = 0;
+ uint64_t parent = 0;
if (startind + 1 > argc) {
usage(gbls.progname);
@@ -124,34 +125,33 @@ static void process_decode_lockres(int argc, char **argv, int startind)
}
for (i = startind; i < argc; ++i) {
- ret = ocfs2_decode_lockres(argv[i], -1, &type, &blkno,
- &generation);
- if (ret) {
- com_err(gbls.progname, ret, "while decoding lockres %s",
- argv[i]);
+ ret = ocfs2_decode_lockres(argv[i], &type, &blkno,
+ &generation, &parent);
+ if (ret)
continue;
- }
printf("Lockres: %s\n", argv[i]);
- printf("Type: %s\n",
- ocfs2_get_lock_type_string(type));
- printf("Block: %"PRIu64"\n", blkno);
- printf("Generation: 0x%08x\n", generation);
+ printf("Type: %s\n", ocfs2_lock_type_string(type));
+ if (blkno)
+ printf("Block: %"PRIu64"\n", blkno);
+ if (generation)
+ printf("Generation: 0x%08x\n", generation);
+ if (parent)
+ printf("Parent: %"PRIu64"\n", parent);
printf("\n");
}
return ;
}
-/* [M|D|S] [blkno] [generation] */
static void process_encode_lockres(int argc, char **argv, int startind)
{
int i;
errcode_t ret;
enum ocfs2_lock_type type;
uint64_t blkno;
- uint32_t generation;
- char lockres[50];
+ uint64_t extra; /* generation or parent */
+ char lock[50];
if (startind + 3 > argc) {
usage(gbls.progname);
@@ -162,15 +162,19 @@ static void process_encode_lockres(int argc, char **argv, int startind)
type = ocfs2_get_lock_type(argv[i++][0]);
blkno = strtoull(argv[i++], NULL, 0);
- generation = strtoul(argv[i++], NULL, 0);
+ extra = strtoull(argv[i++], NULL, 0);
- ret = ocfs2_encode_lockres(type, blkno, generation, lockres);
+ if (type == OCFS2_LOCK_TYPE_DENTRY)
+ ret = ocfs2_encode_lockres(type, blkno, 0, extra, lock);
+ else
+ ret = ocfs2_encode_lockres(type, blkno, (uint32_t)extra, 0,
+ lock);
if (ret) {
- com_err(gbls.progname, ret, "while encoding lockres");
+ com_err(gbls.progname, ret, "while encoding lockname");
return ;
}
- printf("%s\n", lockres);
+ printf("%s\n", lock);
return ;
}
diff --git a/debugfs.ocfs2/utils.c b/debugfs.ocfs2/utils.c
index 5eb6e90..c78d5b7 100644
--- a/debugfs.ocfs2/utils.c
+++ b/debugfs.ocfs2/utils.c
@@ -325,30 +325,36 @@ void close_pager(FILE *stream)
* inodestr_to_inode()
*
* Returns ino if string is of the form <ino>
- *
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
*/
int inodestr_to_inode(char *str, uint64_t *blkno)
{
int len;
+ char *buf = NULL;
char *end;
+ int ret = OCFS2_ET_INVALID_LOCKRES;
len = strlen(str);
- if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) {
- if (ocfs2_get_lock_type(str[1]) < OCFS2_NUM_LOCK_TYPES) {
- if (!ocfs2_decode_lockres(str+1, len-2, NULL, blkno,
- NULL))
- return 0;
- else
- return -1;
- }
- *blkno = strtoull(str+1, &end, 0);
- if (*end=='>')
- return 0;
+ if (!((len > 2) && (str[0] == '<') && (str[len - 1] == '>')))
+ goto bail;
+
+ ret = OCFS2_ET_NO_MEMORY;
+ buf = strndup(str + 1, len - 2);
+ if (!buf)
+ goto bail;
+
+ if (ocfs2_get_lock_type(*buf < OCFS2_NUM_LOCK_TYPES))
+ ret = ocfs2_decode_lockres(buf, NULL, blkno, NULL, NULL);
+ else {
+ *blkno = strtoull(buf, &end, 0);
+ if (*end)
+ ret = OCFS2_ET_INVALID_LOCKRES;
}
- return -1;
+bail:
+ if (buf)
+ free(buf);
+
+ return ret;
}
/*
diff --git a/include/ocfs2-kernel/ocfs2_lockid.h b/include/ocfs2-kernel/ocfs2_lockid.h
index 7dd9e1e..82c200f 100644
--- a/include/ocfs2-kernel/ocfs2_lockid.h
+++ b/include/ocfs2-kernel/ocfs2_lockid.h
@@ -35,12 +35,17 @@
#define OCFS2_LOCK_ID_MAX_LEN 32
#define OCFS2_LOCK_ID_PAD "000000"
+#define OCFS2_DENTRY_LOCK_INO_START 18
+
enum ocfs2_lock_type {
OCFS2_LOCK_TYPE_META = 0,
OCFS2_LOCK_TYPE_DATA,
OCFS2_LOCK_TYPE_SUPER,
OCFS2_LOCK_TYPE_RENAME,
OCFS2_LOCK_TYPE_RW,
+ OCFS2_LOCK_TYPE_DENTRY,
+ OCFS2_LOCK_TYPE_OPEN,
+ OCFS2_LOCK_TYPE_FLOCK,
OCFS2_NUM_LOCK_TYPES
};
@@ -63,6 +68,15 @@ static inline char ocfs2_lock_type_char(enum ocfs2_lock_type type)
case OCFS2_LOCK_TYPE_RW:
c = 'W';
break;
+ case OCFS2_LOCK_TYPE_DENTRY:
+ c = 'N';
+ break;
+ case OCFS2_LOCK_TYPE_OPEN:
+ c = 'O';
+ break;
+ case OCFS2_LOCK_TYPE_FLOCK:
+ c = 'F';
+ break;
default:
c = '\0';
}
@@ -70,4 +84,25 @@ static inline char ocfs2_lock_type_char(enum ocfs2_lock_type type)
return c;
}
+static char *ocfs2_lock_type_strings[] = {
+ [OCFS2_LOCK_TYPE_META] = "Meta",
+ [OCFS2_LOCK_TYPE_DATA] = "Data",
+ [OCFS2_LOCK_TYPE_SUPER] = "Super",
+ [OCFS2_LOCK_TYPE_RENAME] = "Rename",
+ /* Need to differntiate from [R]ename.. serializing writes is the
+ * important job it does, anyway. */
+ [OCFS2_LOCK_TYPE_RW] = "Write/Read",
+ [OCFS2_LOCK_TYPE_DENTRY] = "Dentry",
+ [OCFS2_LOCK_TYPE_OPEN] = "Open",
+ [OCFS2_LOCK_TYPE_FLOCK] = "Flock",
+};
+
+static inline const char *ocfs2_lock_type_string(enum ocfs2_lock_type type)
+{
+#ifdef __KERNEL__
+ BUG_ON(type >= OCFS2_NUM_LOCK_TYPES);
+#endif
+ return ocfs2_lock_type_strings[type];
+}
+
#endif /* OCFS2_LOCKID_H */
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 7c21d28..c8d446e 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -583,10 +583,12 @@ enum ocfs2_lock_type ocfs2_get_lock_type(char c);
char *ocfs2_get_lock_type_string(enum ocfs2_lock_type type);
errcode_t ocfs2_encode_lockres(enum ocfs2_lock_type type, uint64_t blkno,
- uint32_t generation, char *lockres);
+ uint32_t generation, uint64_t parent,
+ char *lockres);
-errcode_t ocfs2_decode_lockres(char *lockres, int len, enum ocfs2_lock_type *type,
- uint64_t *blkno, uint32_t *generation);
+errcode_t ocfs2_decode_lockres(char *lockres, enum ocfs2_lock_type *type,
+ uint64_t *blkno, uint32_t *generation,
+ uint64_t *parent);
/* write the superblock at the specific block. */
errcode_t ocfs2_write_backup_super(ocfs2_filesys *fs, uint64_t blkno);
diff --git a/libocfs2/dlm.c b/libocfs2/dlm.c
index cf5f61b..3a5015c 100644
--- a/libocfs2/dlm.c
+++ b/libocfs2/dlm.c
@@ -253,7 +253,7 @@ errcode_t ocfs2_super_lock(ocfs2_filesys *fs)
errcode_t ret;
ocfs2_encode_lockres(OCFS2_LOCK_TYPE_SUPER, OCFS2_SUPER_BLOCK_BLKNO,
- 0, lock_name);
+ 0, 0, lock_name);
ret = o2dlm_lock(fs->fs_dlm_ctxt, lock_name,
O2DLM_TRYLOCK, O2DLM_LEVEL_EXMODE);
@@ -267,7 +267,7 @@ errcode_t ocfs2_super_unlock(ocfs2_filesys *fs)
errcode_t ret;
ocfs2_encode_lockres(OCFS2_LOCK_TYPE_SUPER, OCFS2_SUPER_BLOCK_BLKNO,
- 0, lock_name);
+ 0, 0, lock_name);
ret = o2dlm_unlock(fs->fs_dlm_ctxt, lock_name);
@@ -283,7 +283,7 @@ errcode_t ocfs2_meta_lock(ocfs2_filesys *fs,
errcode_t ret;
ocfs2_encode_lockres(OCFS2_LOCK_TYPE_META, ci->ci_blkno,
- ci->ci_inode->i_generation, lock_name);
+ ci->ci_inode->i_generation, 0, lock_name);
ret = o2dlm_lock(fs->fs_dlm_ctxt, lock_name, flags, level);
@@ -297,7 +297,7 @@ errcode_t ocfs2_meta_unlock(ocfs2_filesys *fs,
errcode_t ret;
ocfs2_encode_lockres(OCFS2_LOCK_TYPE_META, ci->ci_blkno,
- ci->ci_inode->i_generation, lock_name);
+ ci->ci_inode->i_generation, 0, lock_name);
ret = o2dlm_unlock(fs->fs_dlm_ctxt, lock_name);
diff --git a/libocfs2/lockid.c b/libocfs2/lockid.c
index 7046e51..b2f1e76 100644
--- a/libocfs2/lockid.c
+++ b/libocfs2/lockid.c
@@ -5,7 +5,7 @@
*
* Encode and decode lockres name
*
- * Copyright (C) 2004 Oracle. All rights reserved.
+ * Copyright (C) 2004, 2008 Oracle. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -22,6 +22,7 @@
* Boston, MA 021110-1307, USA.
*/
+#include "ocfs2/byteorder.h"
#include "ocfs2/ocfs2.h"
#include <string.h>
@@ -40,31 +41,20 @@ enum ocfs2_lock_type ocfs2_get_lock_type(char c)
return OCFS2_LOCK_TYPE_RENAME;
case 'W':
return OCFS2_LOCK_TYPE_RW;
+ case 'N':
+ return OCFS2_LOCK_TYPE_DENTRY;
+ case 'O':
+ return OCFS2_LOCK_TYPE_OPEN;
+ case 'F':
+ return OCFS2_LOCK_TYPE_FLOCK;
default:
return OCFS2_NUM_LOCK_TYPES;
}
}
-char *ocfs2_get_lock_type_string(enum ocfs2_lock_type type)
-{
- switch (type) {
- case OCFS2_LOCK_TYPE_META:
- return "Metadata";
- case OCFS2_LOCK_TYPE_DATA:
- return "Data";
- case OCFS2_LOCK_TYPE_SUPER:
- return "Superblock";
- case OCFS2_LOCK_TYPE_RENAME:
- return "Rename";
- case OCFS2_LOCK_TYPE_RW:
- return "Write/Read";
- default:
- return NULL;
- }
-}
-
errcode_t ocfs2_encode_lockres(enum ocfs2_lock_type type, uint64_t blkno,
- uint32_t generation, char *lockres)
+ uint32_t generation, uint64_t parent,
+ char *lockres)
{
if (type >= OCFS2_NUM_LOCK_TYPES)
return OCFS2_ET_INVALID_LOCKRES;
@@ -73,53 +63,52 @@ errcode_t ocfs2_encode_lockres(enum ocfs2_lock_type type, uint64_t blkno,
generation = ((type == OCFS2_LOCK_TYPE_SUPER) ||
(type == OCFS2_LOCK_TYPE_RENAME)) ? 0 : generation;
- snprintf(lockres, OCFS2_LOCK_ID_MAX_LEN, "%c%s%016"PRIx64"%08x",
- ocfs2_lock_type_char(type), OCFS2_LOCK_ID_PAD,
- blkno, generation);
+ if (type != OCFS2_LOCK_TYPE_DENTRY) {
+ snprintf(lockres, OCFS2_LOCK_ID_MAX_LEN, "%c%s%016"PRIx64"%08x",
+ ocfs2_lock_type_char(type), OCFS2_LOCK_ID_PAD,
+ blkno, generation);
+ } else {
+ }
return 0;
}
-errcode_t ocfs2_decode_lockres(char *lockres, int len, enum ocfs2_lock_type *type,
- uint64_t *blkno, uint32_t *generation)
+errcode_t ocfs2_decode_lockres(char *lockres, enum ocfs2_lock_type *type,
+ uint64_t *blkno, uint32_t *generation,
+ uint64_t *parent)
{
- char *lock = NULL;
- errcode_t ret = OCFS2_ET_NO_MEMORY;
- char blkstr[20];
int i = 0;
+ enum ocfs2_lock_type t;
+ char *l = lockres;
+ uint64_t b = 0;
+ uint64_t p = 0;
+ uint32_t g = 0;
- if (len != -1) {
- lock = calloc(len+1, 1);
- if (!lock)
- goto bail;
- strncpy(lock, lockres, len);
- } else
- lock = lockres;
-
- ret = OCFS2_ET_INVALID_LOCKRES;
-
- if ((strlen(lock) + 1) != OCFS2_LOCK_ID_MAX_LEN)
- goto bail;
+ if ((t = ocfs2_get_lock_type(*l)) >= OCFS2_NUM_LOCK_TYPES)
+ return OCFS2_ET_INVALID_LOCKRES;
- if (ocfs2_get_lock_type(lock[0]) >= OCFS2_NUM_LOCK_TYPES)
- goto bail;
+ if (t != OCFS2_LOCK_TYPE_DENTRY) {
+ i = sscanf(l + 1, OCFS2_LOCK_ID_PAD"%016llx%08x", &b, &g);
+ if (i != 2)
+ return OCFS2_ET_INVALID_LOCKRES;
+ } else {
+ i = sscanf(l + 1, "%016llx", &p);
+ if (i != 1)
+ return OCFS2_ET_INVALID_LOCKRES;
+ b = strtoull(&l[OCFS2_DENTRY_LOCK_INO_START], NULL, 16);
+ }
if (type)
- *type = ocfs2_get_lock_type(lock[i]);
+ *type = t;
- i = 1 + strlen(OCFS2_LOCK_ID_PAD);
- memset(blkstr, 0, sizeof(blkstr));
- memcpy(blkstr, &lock[i], 16);
if (blkno)
- *blkno = strtoull(blkstr, NULL, 16);
+ *blkno = b;
- i += 16;
if (generation)
- *generation = strtoul(&lock[i], NULL, 16);
+ *generation = g;
+
+ if (parent)
+ *parent = p;
- ret = 0;
-bail:
- if (len != -1 && lock)
- free(lock);
- return ret;
+ return 0;
}
--
1.5.4.3
More information about the Ocfs2-tools-devel
mailing list