Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
/**
 * 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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
/**
 * 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;
}
Пример #10
0
#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",