Inode* fs_load_inode(FileSystem *fs, int page_num) { int i = 0; Inode *inode = NULL; int magic_number = 0; for (i = 0; i < fs->ninode; ++i) { if (fs->inodes[i]->page_num == page_num) { return fs->inodes[i]; } } magic_number = storage_readint(fs->stor, page_num, CONTENT_BYTES_PER_PAGE); if (magic_number != INODE_MAGIC_NUMBER) { return NULL; } if (fs->ninode == INODE_NUM) { inode_free(&(fs->inodes[0])); fs->ninode--; for (i = 0; i < fs->ninode; ++i) { fs->inodes[i] = fs->inodes[i + 1]; } } fs->inodes[fs->ninode++] = inode = inode_new(page_num); inode->type = storage_readint(fs->stor, page_num, 0); inode->filesize = storage_readint(fs->stor, page_num, 4); inode->firstpage = storage_readint(fs->stor, page_num, 16); return inode; }
int nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how) { int ret = -EFAULT; inode_t *inode = NULL; if (!loc) return ret; inode = inode_find (itable, gfid); if (!inode) { gf_msg_trace (GF_NFS, 0, "Inode not found in itable, will " "try to create one."); if (how == NFS_RESOLVE_CREATE) { gf_msg_trace (GF_NFS, 0, "Inode needs to be created."); inode = inode_new (itable); if (!inode) { gf_msg (GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, "Failed to " "allocate memory"); ret = -ENOMEM; goto err; } } else { gf_msg (GF_NFS, GF_LOG_ERROR, ENOENT, NFS_MSG_INODE_NOT_FOUND, "Inode not found in " "itable and no creation was requested."); ret = -ENOENT; goto err; } } else { gf_msg_trace (GF_NFS, 0, "Inode was found in the itable."); } gf_uuid_copy (loc->gfid, gfid); ret = nfs_inode_loc_fill (inode, loc, how); if (ret < 0) { gf_msg (GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_INODE_LOC_FILL_ERROR, "Inode loc filling failed.: %s", strerror (-ret)); goto err; } err: if (inode) inode_unref (inode); return ret; }
/** * bg_raise_ilevel - raise the index levels * @iprev: the first index node at this level * @iprev_tall: the first index node at the next highest level * @height: the height of the level we are raising * @ptst: per-thread state * * Returns 1 if a node was raised and 0 otherwise. */ static int bg_raise_ilevel(inode_t *iprev, inode_t *iprev_tall, int height, ptst_t *ptst) { int raised = 0; inode_t *index, *inext, *inew, *above, *above_prev; above = above_prev = iprev_tall; assert(NULL != iprev); assert(NULL != iprev_tall); index = iprev->right; while ((NULL != index) && (NULL != (inext = index->right))) { while (index->node->val == index->node) { /* skip deleted nodes */ iprev->right = inext; if (NULL == inext) break; index = inext; inext = inext->right; } if (NULL == inext) break; if (((iprev->node->level <= height) && (index->node->level <= height)) && (inext->node->level <= height)) { raised = 1; /* get the correct index above and behind */ while (above && above->node->key < index->node->key) { above = above->right; if (above != iprev_tall->right) above_prev = above_prev->right; } inew = inode_new(above_prev->right, index, index->node, ptst); above_prev->right = inew; index->node->level = height + 1; above_prev = above = iprev_tall = inew; } iprev = index; index = inext; } return raised; }
/** * bg_raise_nlevel - raise level 0 nodes into index levels * @inode: the index node at the start of the bottom index level * @ptst: per-thread state * * Returns 1 if a node was raised and 0 otherwise. */ static int bg_raise_nlevel(inode_t *inode, ptst_t *ptst) { int raised = 0; node_t *prev, *node, *next; inode_t *inew, *above, *above_prev; above = above_prev = inode; assert(NULL != inode); prev = set->head; node = set->head->next; if (NULL == node) return 0; next = node->next; while (NULL != next) { /* don't raise deleted nodes */ if (node != node->val) { if (((prev->level == 0) && (node->level == 0)) && (next->level == 0)) { raised = 1; /* get the correct index above and behind */ while (above && above->node->key < node->key) { above = above->right; if (above != inode->right) above_prev = above_prev->right; } /* add a new index item above node */ inew = inode_new(above_prev->right, NULL, node, ptst); above_prev->right = inew; node->level = 1; above_prev = inode = above = inew; } } prev = node; node = next; next = next->next; } return raised; }
int glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc, int32_t *op_errno) { void *index_gfid = NULL; int ret = 0; dict_t *xattr = NULL; struct iatt iattr = {0}; struct iatt parent = {0}; ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTROP_INDEX_GFID); if (ret < 0) { *op_errno = -ret; goto out; } ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid); if (ret < 0) { *op_errno = EINVAL; goto out; } uuid_copy (dirloc->gfid, index_gfid); dirloc->path = ""; dirloc->inode = inode_new (rootloc->inode->table); ret = syncop_lookup (xl, dirloc, NULL, &iattr, NULL, &parent); dirloc->path = NULL; if (ret < 0) { *op_errno = -ret; goto out; } ret = glfsh_link_inode_update_loc (dirloc, &iattr); if (ret) goto out; glfs_loc_touchup (dirloc); ret = 0; out: if (xattr) dict_unref (xattr); return ret; }
int fs_mkdir(FileSystem *fs, const char *d) { int p = 0; Inode *inode = NULL; Folder *fd = NULL; char ppath[4096] = ""; char cname[4096] = ""; Folder *pfd = NULL; int parent_page_num = 0; p = freelist_allocate(fs->freelist); if (p <= 1) return ERROR; inode = inode_new(p); if (!inode) return ERROR; inode->type = INODE_FOLDER; inode->filesize = 0; inode->lastmod = time(NULL); inode->firstpage = 0; fs_save_inode(fs, inode); inode_free(&inode); fs_split_path(d, ppath, cname); #ifdef DEBUG fprintf(stderr, "fs_mkdir, d=`%s`, ppath=`%s`, cname=`%s`\n", d, ppath, cname); #endif pfd = folder_open(fs, folder_lookup(fs, fs->cur, ppath)); parent_page_num = AS_FILE(pfd)->inode->page_num; folder_add_child(pfd, cname, p); folder_close(&pfd); fd = folder_open(fs, fs_load_inode(fs, p)); fs_split_path(d, ppath, cname); folder_add_child(fd, "", ROOT_PAGE_NUM()); folder_add_child(fd, ".", p); folder_add_child(fd, "..", parent_page_num); folder_close(&fd); return OK; }
int fs_create(FileSystem *fs, const char *f) { int p = 0; Inode *inode = NULL; char ppath[4096] = ""; char cname[4096] = ""; Folder *pfd = NULL; p = freelist_allocate(fs->freelist); if (p <= 1) return ERROR; inode = inode_new(p); if (!inode) return ERROR; inode->type = INODE_FILE; inode->filesize = 0; inode->firstpage = 0; fs_save_inode(fs, inode); inode_free(&inode); fs_split_path(f, ppath, cname); pfd = folder_open(fs, folder_lookup(fs, fs->cur, ppath)); folder_add_child(pfd, cname, p); folder_close(&pfd); return OK; }
struct glfs_object * glfs_h_create_from_handle (struct glfs *fs, unsigned char *handle, int len, struct stat *stat) { loc_t loc = {0, }; int ret = -1; struct iatt iatt = {0, }; inode_t *newinode = NULL; xlator_t *subvol = NULL; struct glfs_object *object = NULL; /* validate in args */ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) { errno = EINVAL; return NULL; } __glfs_entry_fs (fs); /* get the active volume */ subvol = glfs_active_subvol (fs); if (!subvol) { errno = EIO; goto out; } memcpy (loc.gfid, handle, GFAPI_HANDLE_LENGTH); newinode = inode_find (subvol->itable, loc.gfid); if (newinode) loc.inode = newinode; else { loc.inode = inode_new (subvol->itable); if (!loc.inode) { errno = ENOMEM; goto out; } } ret = syncop_lookup (subvol, &loc, 0, &iatt, 0, 0); DECODE_SYNCOP_ERR (ret); if (ret) { gf_log (subvol->name, GF_LOG_WARNING, "inode refresh of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); goto out; } newinode = inode_link (loc.inode, 0, 0, &iatt); if (newinode) inode_lookup (newinode); else { gf_log (subvol->name, GF_LOG_WARNING, "inode linking of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); errno = EINVAL; goto out; } /* populate stat */ if (stat) glfs_iatt_to_stat (fs, &iatt, stat); object = GF_CALLOC (1, sizeof(struct glfs_object), glfs_mt_glfs_object_t); if (object == NULL) { errno = ENOMEM; ret = -1; goto out; } /* populate the return object */ object->inode = newinode; uuid_copy (object->gfid, object->inode->gfid); out: /* TODO: Check where the inode ref is being held? */ loc_wipe (&loc); glfs_subvol_done (fs, subvol); return object; }
/** * bg_loop - loop for maintaining index levels * @args: void* args as per pthread_create requirements * * Returns a void* value as per pthread_create requirements. * Note: Do this loop forever while the program is running. */ static void* bg_loop(void *args) { inode_t *inode; inode_t *inew; inode_t *inodes[MAX_LEVELS]; int raised = 0; /* keep track of if we raised index level */ int threshold; /* for testing if we should lower index level */ int i; struct sl_ptst *ptst; assert(NULL != set); while (1) { if (bg_finished) break; usleep(bg_sleep_time); #ifdef USE_GC ptst = ptst_critical_enter(); #endif for (i = 0; i < MAX_LEVELS; i++) inodes[i] = NULL; #ifdef BG_STATS ++bg_stats.loops; #endif bg_non_deleted = 0; bg_tall_deleted = 0; /* traverse the node level and do physical deletes */ bg_trav_nodes(ptst); assert(set->head->level < MAX_LEVELS); /* get the first index node at each level */ inode = set->top; for (i = set->head->level - 1; i >= 0; i--) { inodes[i] = inode; assert(NULL != inodes[i]); inode = inode->down; } assert(NULL == inode); /* raise bottom level nodes */ raised = bg_raise_nlevel(inodes[0], ptst); if (raised && (1 == set->head->level)) { /* add a new index level */ inew = inode_new(NULL, set->top, set->head, ptst); set->top = inew; ++set->head->level; assert(NULL == inodes[1]); inodes[1] = set->top; #ifdef BG_STATS ++bg_stats.raises; #endif } /* raise the index level nodes */ for (i = 0; i < (set->head->level - 1); i++) { assert(i < MAX_LEVELS-1); raised = bg_raise_ilevel(inodes[i],/* level raised */ inodes[i + 1],/* level above */ i + 1,/* current height */ ptst); } if (raised) { /* add a new index level */ inew = inode_new(NULL, set->top, set->head, ptst); set->top = inew; ++set->head->level; #ifdef BG_STATS ++bg_stats.raises; #endif } /* if needed, remove the lowest index level */ threshold = bg_non_deleted * 10; if (bg_tall_deleted > threshold) { if (NULL != inodes[1]) { bg_lower_ilevel(inodes[1],/* level above */ ptst); #ifdef BG_STATS ++bg_stats.lowers; #endif } } #ifdef USE_GC ptst_critical_exit(ptst); #endif } return NULL; }
#include "common-utils.h" #include "byte-order.h" #include "marker-quota.h" #include "marker-quota-helper.h" int32_t loc_fill_from_name (xlator_t *this, loc_t *newloc, loc_t *oldloc, uint64_t ino, char *name) { int32_t ret = 0; int32_t len = 0; char *path = NULL; newloc->ino = ino; newloc->inode = inode_new (oldloc->inode->table); if (!newloc->inode) { ret = -1; goto out; } newloc->parent = inode_ref (oldloc->inode); len = strlen (oldloc->path); if (oldloc->path [len - 1] == '/') ret = gf_asprintf ((char **) &path, "%s%s", oldloc->path, name); else ret = gf_asprintf ((char **) &path, "%s/%s",