#pragma fragment PROLOG #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "glusterfs.h" #include "iatt.h" #include "syncop.h" #include "xlator.h" #include "glfs-internal.h" #include "fdl.h" #define GFAPI_SUCCESS 0 inode_t * recon_get_inode(glfs_t *fs, uuid_t gfid) { inode_t *inode; loc_t loc = { NULL, }; struct iatt iatt; int ret; inode_t *newinode; inode = inode_find(fs->active_subvol->itable, gfid); if (inode) { printf("=== FOUND %s IN TABLE\n", uuid_utoa(gfid)); return inode; } loc.inode = inode_new(fs->active_subvol->itable); if (!loc.inode) { return NULL; } gf_uuid_copy(loc.inode->gfid, gfid); gf_uuid_copy(loc.gfid, gfid); printf("=== DOING LOOKUP FOR %s\n", uuid_utoa(gfid)); ret = syncop_lookup(fs->active_subvol, &loc, &iatt, NULL, NULL, NULL); if (ret != GFAPI_SUCCESS) { fprintf(stderr, "syncop_lookup failed (%d)\n", ret); return NULL; } newinode = inode_link(loc.inode, NULL, NULL, &iatt); if (newinode) { inode_lookup(newinode); } return newinode; } #pragma fragment DICT dict_t *@ARGNAME @; @ARGNAME @ = dict_new(); if (!@ARGNAME @) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; { int key_len, data_len; char *key_ptr; int garbage; for (;;) { key_len = *((int *)new_meta); new_meta += sizeof(int); if (!key_len) { break; } key_ptr = new_meta; new_meta += key_len; data_len = *((int *)new_meta); new_meta += sizeof(int); garbage = dict_set_static_bin(@ARGNAME @, key_ptr, new_meta, data_len); /* TBD: check error from dict_set_static_bin */ (void)garbage; new_meta += data_len; } } #pragma fragment DICT_CLEANUP cleanup_ @ARGNAME @ : dict_unref(@ARGNAME @); #pragma fragment DOUBLE @ARGTYPE @ @ARGNAME @ = *((@ARGTYPE @ *)new_meta); new_meta += sizeof(uint64_t); #pragma fragment FD inode_t *@ARGNAME @_ino; fd_t *@ARGNAME @; @ARGNAME @_ino = recon_get_inode(fs, *((uuid_t *)new_meta)); new_meta += 16; if (!@ARGNAME @_ino) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @_ino; @ARGNAME @ = fd_anonymous(@ARGNAME @_ino); if (!@ARGNAME @) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; #pragma fragment FD_CLEANUP cleanup_ @ARGNAME @ : fd_unref(@ARGNAME @); cleanup_ @ARGNAME @_ino : inode_unref(@ARGNAME @_ino); #pragma fragment NEW_FD /* * This pseudo-type is only used for create, and in that case we know * we'll be using loc.inode, so it's not worth generalizing to take an * extra argument. */ fd_t *@ARGNAME @ = fd_anonymous(loc.inode); if (!fd) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; new_meta += 16; #pragma fragment NEW_FD_CLEANUP cleanup_ @ARGNAME @ : fd_unref(@ARGNAME @); #pragma fragment INTEGER @ARGTYPE @ @ARGNAME @ = *((@ARGTYPE @ *)new_meta); new_meta += sizeof(@ARGTYPE @); #pragma fragment LOC loc_t @ARGNAME @ = { NULL, }; @ARGNAME @.inode = recon_get_inode(fs, *((uuid_t *)new_meta)); if (!@ARGNAME @.inode) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; gf_uuid_copy(@ARGNAME @.gfid, @ARGNAME @.inode->gfid); new_meta += 16; new_meta += 16; /* skip over pargfid */ if (*(new_meta++)) { @ARGNAME @.name = new_meta; new_meta += strlen(new_meta) + 1; } #pragma fragment LOC_CLEANUP cleanup_ @ARGNAME @ : loc_wipe(&@ARGNAME @); #pragma fragment PARENT_LOC loc_t @ARGNAME @ = { NULL, }; new_meta += 16; /* skip over gfid */ @ARGNAME @.parent = recon_get_inode(fs, *((uuid_t *)new_meta)); if (!@ARGNAME @.parent) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; gf_uuid_copy(@ARGNAME @.pargfid, @ARGNAME @.parent->gfid); new_meta += 16; if (!*(new_meta++)) { goto *err_label; } @ARGNAME @.name = new_meta; new_meta += strlen(new_meta) + 1; @ARGNAME @.inode = inode_new(fs->active_subvol->itable); if (!@ARGNAME @.inode) { goto *err_label; } #pragma fragment PARENT_LOC_CLEANUP cleanup_ @ARGNAME @ : loc_wipe(&@ARGNAME @); #pragma fragment STRING char *@ARGNAME @; if (*(new_meta++)) { @ARGNAME @ = new_meta; new_meta += (strlen(new_meta) + 1); } else { goto *err_label; } #pragma fragment VECTOR struct iovec @ARGNAME @; @ARGNAME @.iov_len = *((size_t *)new_meta); new_meta += sizeof(@ARGNAME @.iov_len); @ARGNAME @.iov_base = new_data; new_data += @ARGNAME @.iov_len; #pragma fragment IATT struct iatt @ARGNAME @; { @ARGNAME @.ia_prot = *((ia_prot_t *)new_meta); new_meta += sizeof(ia_prot_t); uint32_t *myints = (uint32_t *)new_meta; @ARGNAME @.ia_uid = myints[0]; @ARGNAME @.ia_gid = myints[1]; @ARGNAME @.ia_atime = myints[2]; @ARGNAME @.ia_atime_nsec = myints[3]; @ARGNAME @.ia_mtime = myints[4]; @ARGNAME @.ia_mtime_nsec = myints[5]; new_meta += sizeof(*myints) * 6; } #pragma fragment IOBREF struct iobref *@ARGNAME @; @ARGNAME @ = iobref_new(); if (!@ARGNAME @) { goto *err_label; } err_label = &&cleanup_ @ARGNAME @; #pragma fragment IOBREF_CLEANUP cleanup_ @ARGNAME @ : iobref_unref(@ARGNAME @); #pragma fragment LINK /* TBD: check error */ inode_t *new_inode = inode_link(@INODE_ARG @, NULL, NULL, @IATT_ARG @); if (new_inode) { inode_lookup(new_inode); } #pragma fragment FOP int fdl_replay_ @NAME @(glfs_t *fs, char **old_meta, char **old_data) { char *new_meta = *old_meta; char *new_data = *old_data; int ret; int status = 0xbad; void *err_label = &&done; @FUNCTION_BODY @ ret = syncop_ @NAME @(fs->active_subvol, @SYNCOP_ARGS @, NULL); if (ret != @SUCCESS_VALUE @) { fprintf(stderr, "syncop_@NAME@ returned %d", ret); goto *err_label; } @LINKS @ status = 0; @CLEANUPS @ done : *old_meta = new_meta; *old_data = new_data; return status; } #pragma fragment CASE case GF_FOP_ @UPNAME @: printf("=== GF_FOP_@UPNAME@\n"); if (fdl_replay_ @NAME @(fs, &new_meta, &new_data) != 0) { goto done; } recognized = 1; break; #pragma fragment EPILOG int recon_execute(glfs_t *fs, char **old_meta, char **old_data) { char *new_meta = *old_meta; char *new_data = *old_data; int recognized = 0; event_header_t *eh; eh = (event_header_t *)new_meta; new_meta += sizeof(*eh); /* TBD: check event_type instead of assuming NEW_REQUEST */ switch (eh->fop_type) { @SWITCH_BODY @ default : printf("unknown fop %u\n", eh->fop_type); } done: *old_meta = new_meta; *old_data = new_data; return recognized; }