Example #1
0
/*
 * May be called with null parent, for root and ctl files.
 * The first call with a null parent is root, all others are ctl
 * files linked at root.
 */
Memblk*
dfcreate(Memblk *parent, char *name, int uid, ulong mode)
{
	Memblk *nf;
	Mfile *m;
	int isctl;

	if(fsfull())
		error("file system full");
	isctl = parent == nil;
	if(parent == nil)
		parent = fs->root;

	if(parent != nil){
		dprint("dfcreate '%s' %M at\n%H\n", name, mode, parent);
		isdir(parent);
		isrwlocked(parent, Wr);
		ismelted(parent);
	}else
		dprint("dfcreate '%s' %M", name, mode);

	if(isctl)
		nf = dballoc(DBctl);
	else
		nf = dballoc(DBfile);
	if(catcherror()){
		mbput(nf);
		if(parent != nil)
			rwunlock(parent, Wr);
		error(nil);
	}

	m = nf->mf;
	nf->d.id = nsec();
	nf->d.mode = mode;
	nf->d.mtime = nf->d.id;
	nf->d.atime = nf->d.id;
	nf->d.length = 0;
	m->uid = usrname(uid);
	nf->d.uid = uid;
	m->gid = m->uid;
	nf->d.gid = nf->d.uid;
	m->muid = m->uid;
	nf->d.muid = nf->d.uid;
	m->name = name;
	nf->d.asize = pmeta(nf->d.embed, Embedsz, nf);
	changed(nf);

	if(parent != nil){
		m->gid = parent->mf->gid;
		nf->d.gid = parent->d.gid;
		dflink(parent, nf);
	}
	noerror();
	dprint("dfcreate-> %H\n within %H\n", nf, parent);
	return nf;
}
Example #2
0
int dblist_delitem(pgctx_t *ctx, dbtype_t list, int n, dbtype_t *item, int sync)
{
	_list_t *_list, *_newlist = NULL;
	int sz, i, j;

    list.ptr = dbptr(ctx, list);
	assert(list.ptr->type == List);
    do {
        // Read-Copy-Update loop for modify operations
        _list = dbptr(ctx, list.ptr->list);
        if (!_list)
            return -1;
        // As in Python, negative list index means "from end of list"
        if (n<0) n += _list->len;
        if (n < 0 || n >= _list->len)
            return -1;
        sz = dblist_size(_list, 0);
        dbfree(_newlist, 0xf3);
        _newlist = dballoc(ctx, sz);
        _newlist->type = _InternalList;
        _newlist->len = _list->len - 1;
        for(i=j=0; i<_list->len; i++) {
            if (i==n) {
                *item = _list->item[i];
            } else {
                _newlist->item[j++] = _list->item[i];
            }
        }
    } while(!synchronizep(ctx, sync, &list.ptr->list, _list, _newlist));
    dbfree(_list, 0xf4);
    return 0;
}
Example #3
0
int dblist_setitem(pgctx_t *ctx, dbtype_t list, int n, dbtype_t item, int sync)
{
	_list_t *_list, *_newlist = NULL;
	int sz, llen;

    list.ptr = dbptr(ctx, list);
	assert(list.ptr->type == List);
    do {
        // Read-Copy-Update loop for modify operations
    	_list = dbptr(ctx, list.ptr->list);
        llen = _list ? _list->len : 0;
        // As in Python, negative list index means "from end of list"
        if (n<0) n += llen;
        if (n < 0 || n >= llen)
		return -1;

        sz = dblist_size(_list, 0);
        dbfree(_newlist, 0xf1);
        _newlist = dballoc(ctx, sz);
        memcpy(_newlist, _list, sz);
        _newlist->item[n] = item;
    } while(!synchronizep(ctx, sync, &list.ptr->list, _list, _newlist));
    dbfree(_list, 0xf2);
    return 0;
}
Example #4
0
int dblist_extend(pgctx_t *ctx, dbtype_t list, int n, extendcb_t elem, void *user, int sync)
{
	_list_t *_list, *_newlist = NULL;
	int sz, i, j, llen;
    dbtype_t item;

    list.ptr = dbptr(ctx, list);
	assert(list.ptr->type == List);
    // Read-Copy-Update loop for modify operations
    do {
	    _list = dbptr(ctx, list.ptr->list);
        llen = _list ? _list->len : 0;
        sz = dblist_size(_list, n);
        dbfree(_newlist, 0xf7);
        _newlist = dballoc(ctx, sz);
        _newlist->type = _InternalList;
        _newlist->len = llen + n;
        for(i=0; i<llen; i++) {
            _newlist->item[i] = _list->item[i];
        }
        for(j=0; j<n; j++, i++) {
            if (elem(ctx, j, &item, user) < 0) {
                return -1;
            }
            _newlist->item[i] = item;
        }
    } while(!synchronizep(ctx, sync, &list.ptr->list, _list, _newlist));
    dbfree(_list, 0xf8);
    return 0;
}
Example #5
0
int dblist_insert(pgctx_t *ctx, dbtype_t list, int n, dbtype_t item, int sync)
{
	_list_t *_list, *_newlist = NULL;
	int sz, i, j, llen;

    list.ptr = dbptr(ctx, list);
	assert(list.ptr->type == List);
    // Read-Copy-Update loop for modify operations
    do {
        _list = dbptr(ctx, list.ptr->list);
        llen = _list ? _list->len : 0;

        // INT_MAX is a magic value that means append
        if (n == INT_MAX) n = llen;
        // As in Python, negative list index means "from end of list"
        if (n<0) n += llen;
        if (n < 0 || n > llen)
            return -1;
        sz = dblist_size(_list, 1);
        dbfree(_newlist, 0xf5);
        _newlist = dballoc(ctx, sz);
        _newlist->type = _InternalList;
        _newlist->len = llen + 1;
        for(i=j=0; i<_newlist->len; i++) {
            if (i == n) {
                _newlist->item[i] = item; 
            } else {
                _newlist->item[i] = _list->item[j++];
            }
        }
    } while(!synchronizep(ctx, sync, &list.ptr->list, _list, _newlist));
    dbfree(_list, 0xf6);
    return 0;
}
Example #6
0
/* for dfblk only */
static Memblk*
getmelted(uint isdir, uint type, daddrt *addrp, int *chg)
{
	Memblk *b, *nb;

	*chg = 0;
	if(*addrp == 0){
		b = dballoc(type);
		*addrp = b->addr;
		*chg = 1;
		return b;
	}

	b = dbget(type, *addrp);
	nb = nil;
	if(!b->frozen)
		return b;
	if(catcherror()){
		mbput(b);
		mbput(nb);
		error(nil);
	}
	nb = dbdup(b);
	assert(type == b->type);
	if(isdir && type == DBdata)
		dupdentries(nb->d.data, Dblkdatasz/Daddrsz);
	USED(&nb);		/* for error() */
	*addrp = nb->addr;
	*chg = 1;
	dbput(b, b->type, b->addr);
	noerror();
	mbput(b);
	return nb;
}
Example #7
0
dbtype_t dblist_new(pgctx_t *ctx)
{
	dbtype_t list;
	list.ptr = dballoc(ctx, sizeof(dblist_t));
    if (!list.ptr) return DBNULL;
	list.ptr->type = List;
	return dboffset(ctx, list.ptr);
}
Example #8
0
static dbtype_t
bonsai_ncopy(pgctx_t *ctx, dbtype_t left, dbtype_t right, dbtype_t orig, int n)
{
    dbtype_t node;
    unsigned copysz = 0;

    orig.ptr = dbptr(ctx, orig);
    if (orig.ptr->type == _BonsaiNode) {
        node.ptr = dballoc(ctx, sizeof(dbnode_t));
        copysz = 2*sizeof(dbtype_t);
    } else if (orig.ptr->type == _BonsaiMultiNode) {
        node.ptr = dballoc(ctx, sizeof(dbmultinode_t) + orig.ptr->nvalue * sizeof(dbtype_t));
        copysz = 2*sizeof(dbtype_t) + (orig.ptr->nvalue + n) * sizeof(dbtype_t);
    }
    node.ptr->type = orig.ptr->type;
    node.ptr->left = left;
    node.ptr->right = right;
    node.ptr->size = 1 + bonsai_size(ctx, left) + bonsai_size(ctx, right);
    memcpy(&node.ptr->key, &orig.ptr->key, copysz);
    rculoser(node, 0);
    return dboffset(ctx, node.ptr);
}
Example #9
0
static dbtype_t
bonsai_new(pgctx_t *ctx, dbtype_t left, dbtype_t right, dbtype_t key, dbtype_t value)
{
    dbtype_t node;

    node.ptr = dballoc(ctx, sizeof(dbnode_t));
    node.ptr->type = _BonsaiNode;
    node.ptr->left = left;
    node.ptr->right = right;
    node.ptr->size = 1 + bonsai_size(ctx, left) + bonsai_size(ctx, right);
    node.ptr->key = key;
    node.ptr->value = value;
    rculoser(node, 0);
    return dboffset(ctx, node.ptr);
}
Example #10
0
int dblist_remove(pgctx_t *ctx, dbtype_t list, dbtype_t item, int sync)
{
	_list_t *_list, *_newlist = NULL;
	int sz, i, j, remove;

    list.ptr = dbptr(ctx, list);
	assert(list.ptr->type == List);
    // Read-Copy-Update loop for modify operations
    do {
	    _list = dbptr(ctx, list.ptr->list);
        if (!_list)
            return -1;
        sz = dblist_size(_list, 0);
        dbfree(_newlist, 0xf9);
        _newlist = dballoc(ctx, sz);
        _newlist->type = _InternalList;
        _newlist->len = _list->len - 1;
        remove = 0;
        for(i=j=0; i<_list->len; i++) {
            // Copy all items that don't match.  Only remove
            // one matching item
            if (!remove && dbcmp(ctx, _list->item[i], item) == 0) {
                remove = 1;
            } else {
                _newlist->item[j++] = _list->item[i];
            }
        }
        if (!remove) {
            dbfree(_newlist, 0xfa);
            // No item was removed, so discard the copy (no one will
            // ever see it) and return an error
            return -1;
        }
    } while(!synchronizep(ctx, sync, &list.ptr->list, _list, _newlist));
    dbfree(_list, 0xfb);
    return 0;
}