Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=6ee32886070... Commit: 6ee32886070b682b8ccb02ddeeba86b28e6b83be Parent: cc0a456dd650c793e4ebce10b0bb7c7ff5048a90 Author: Andrew Price anprice@redhat.com AuthorDate: Sat May 18 00:13:41 2013 +0100 Committer: Andrew Price anprice@redhat.com CommitterDate: Sat May 18 00:13:41 2013 +0100
gfs2l: Enable setting the type of a block
This adds an optional type specifier to the set statement so that when you do
set 12345 <type> { ... }
the block's meta header fields will be set to that of <type> where <type> is a structure name e.g. gfs2_rgrp.
This is useful for setting unallocated blocks to a certain block type as the type can't be inferred from an existing meta header.
Signed-off-by: Andrew Price anprice@redhat.com --- gfs2/libgfs2/lang.c | 41 ++++++++++++++++++++++++++++++++++------- gfs2/libgfs2/lang.h | 1 + gfs2/libgfs2/libgfs2.h | 1 + gfs2/libgfs2/meta.c | 15 +++++++++++++++ gfs2/libgfs2/parser.y | 12 ++++++++++++ 5 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/gfs2/libgfs2/lang.c b/gfs2/libgfs2/lang.c index 069750f..28805b5 100644 --- a/gfs2/libgfs2/lang.c +++ b/gfs2/libgfs2/lang.c @@ -27,6 +27,7 @@ const char* ast_type_string[] = { [AST_EX_BLOCKSPEC] = "BLOCKSPEC", [AST_EX_STRUCTSPEC] = "STRUCTSPEC", [AST_EX_FIELDSPEC] = "FIELDSPEC", + [AST_EX_TYPESPEC] = "TYPESPEC",
// Keywords [AST_KW_STATE] = "STATE", @@ -64,6 +65,7 @@ static int ast_expr_init(struct ast_node *expr, ast_node_t type, const char *str case AST_EX_BLOCKSPEC: case AST_EX_STRUCTSPEC: case AST_EX_FIELDSPEC: + case AST_EX_TYPESPEC: case AST_KW_STATE: break; default: @@ -173,7 +175,6 @@ static uint64_t ast_lookup_path(char *path, struct gfs2_sbd *sbd) segment = strtok_r(NULL, "/", &c); }
- perror("Path lookup"); return 0; }
@@ -263,6 +264,8 @@ static uint64_t ast_lookup_block_num(struct ast_node *ast, struct gfs2_sbd *sbd) bn = ast_lookup_block_num(ast->ast_left, sbd) + ast->ast_num; break; case AST_EX_ADDRESS: + if (gfs2_check_range(sbd, ast->ast_num)) + break; bn = ast->ast_num; break; case AST_EX_PATH: @@ -284,6 +287,7 @@ static struct gfs2_buffer_head *ast_lookup_block(struct ast_node *node, struct g { uint64_t bn = ast_lookup_block_num(node, sbd); if (bn == 0) { + fprintf(stderr, "Block not found: %s\n", node->ast_text); return NULL; }
@@ -526,6 +530,23 @@ static int ast_field_set(struct gfs2_buffer_head *bh, const struct lgfs2_metafie return AST_INTERP_INVAL; }
+static const struct lgfs2_metadata *lang_find_mtype(struct ast_node *node, struct gfs2_buffer_head *bh, unsigned ver) +{ + const struct lgfs2_metadata *mtype = NULL; + + if (node->ast_type == AST_EX_TYPESPEC) { + mtype = lgfs2_find_mtype_name(node->ast_str, ver); + if (mtype == NULL) + fprintf(stderr, "Invalid block type: %s\n", node->ast_text); + } else { + mtype = lgfs2_find_mtype(lgfs2_get_block_type(bh), ver); + if (mtype == NULL) + fprintf(stderr, "Unrecognised block at: %s\n", node->ast_text); + } + + return mtype; +} + /** * Interpret an assignment (set) */ @@ -536,9 +557,9 @@ static struct lgfs2_lang_result *ast_interp_set(struct lgfs2_lang_state *state, struct ast_node *fieldspec; struct ast_node *fieldname; struct ast_node *fieldval; - uint32_t mh_type = 0; int i = 0; int ret = 0; + unsigned ver = sbd->gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2;
struct lgfs2_lang_result *result = calloc(1, sizeof(struct lgfs2_lang_result)); if (result == NULL) { @@ -551,14 +572,20 @@ static struct lgfs2_lang_result *ast_interp_set(struct lgfs2_lang_state *state, goto out_err; }
- mh_type = lgfs2_get_block_type(result->lr_bh); - if (mh_type == 0) { + result->lr_mtype = lang_find_mtype(lookup->ast_right, result->lr_bh, ver); + if (result->lr_mtype == NULL) { + fprintf(stderr, "Unrecognised block at: %s\n", lookup->ast_str); goto out_err; }
- result->lr_mtype = lgfs2_find_mtype(mh_type, sbd->gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2); - if (result->lr_mtype == NULL) { - goto out_err; + if (lookup->ast_right->ast_type == AST_EX_TYPESPEC) { + struct gfs2_meta_header mh = { + .mh_magic = GFS2_MAGIC, + .mh_type = result->lr_mtype->mh_type, + .mh_format = result->lr_mtype->mh_format, + }; + gfs2_meta_header_out(&mh, result->lr_bh->iov.iov_base); + lookup = lookup->ast_right; }
for (fieldspec = lookup->ast_right; diff --git a/gfs2/libgfs2/lang.h b/gfs2/libgfs2/lang.h index 955e52e..7d9a6e9 100644 --- a/gfs2/libgfs2/lang.h +++ b/gfs2/libgfs2/lang.h @@ -30,6 +30,7 @@ typedef enum { AST_EX_BLOCKSPEC, AST_EX_STRUCTSPEC, AST_EX_FIELDSPEC, + AST_EX_TYPESPEC,
// Keywords AST_KW_STATE, diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 997e23f..55847c8 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -356,6 +356,7 @@ extern const struct lgfs2_symbolic lgfs2_ld1_types[]; extern const unsigned lgfs2_ld1_type_size; extern int lgfs2_selfcheck(void); extern const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type, const unsigned versions); +extern const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name, const unsigned versions);
/* bitmap.c */ struct gfs2_bmap { diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c index dc22e9a..94be823 100644 --- a/gfs2/libgfs2/meta.c +++ b/gfs2/libgfs2/meta.c @@ -1,4 +1,5 @@ #include <stdint.h> +#include <string.h> #include "libgfs2.h"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) @@ -821,3 +822,17 @@ const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type, const unsigned v
return NULL; } + +const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name, const unsigned versions) +{ + const struct lgfs2_metadata *m = lgfs2_metadata; + unsigned n = 0; + + do { + if ((m[n].versions & versions) && !strcmp(m[n].name, name)) + return &m[n]; + n++; + } while (n < lgfs2_metadata_size); + + return NULL; +} diff --git a/gfs2/libgfs2/parser.y b/gfs2/libgfs2/parser.y index 0321d74..d60c1af 100644 --- a/gfs2/libgfs2/parser.y +++ b/gfs2/libgfs2/parser.y @@ -65,6 +65,12 @@ set_stmt: TOK_SET blockspec structspec { $2->ast_right = $3; $$ = $1; } + | TOK_SET blockspec typespec structspec { + $1->ast_right = $2; + $2->ast_right = $3; + $3->ast_right = $4; + $$ = $1; + } ; get_stmt: TOK_GET blockspec { $1->ast_right = $2; $$ = $1; } | TOK_GET blockspec TOK_STATE { @@ -84,6 +90,11 @@ offset: blockspec TOK_OFFSET { $$ = $2; } ; +typespec: identifier { + $1->ast_type = AST_EX_TYPESPEC; + $$ = $1; + } +; block_literal: identifier { $$ = $1; } ; subscript: block_literal TOK_LBRACKET index TOK_RBRACKET { @@ -107,6 +118,7 @@ path: string { } ; structspec: TOK_LBRACE fieldspecs TOK_RBRACE { $$ = $2; } +structspec: TOK_LBRACE TOK_RBRACE { $$ = NULL; } ; fieldspecs: fieldspecs TOK_COMMA fieldspec { $1->ast_left = $3; $$ = $1; } | fieldspec { $$ = $1; }
cluster-commits@lists.fedorahosted.org