Example #1
0
/* Get a free block number from the disk and mark the block used */
blocknum_t
balloc(disk_t* disk)
{
    blocknum_t free_bit = -1;
    blocknum_t block_offset = -1;

    /* Get super block */
    fs_lock(mainsb);
    if (mainsb->free_blocks <= 0) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Get free block number */
    free_bit = bitmap_next_zero(mainsb->block_bitmap, mainsb->disk_num_blocks);
    block_offset = free_bit / BITS_PER_BLOCK;
    if (block_offset < 0 || block_offset >= mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Set the free block to used */
    bitmap_set(mainsb->block_bitmap, free_bit);
    bpush(block_offset + mainsb->block_bitmap_first,
          (char*) mainsb->block_bitmap + block_offset * DISK_BLOCK_SIZE);

    mainsb->free_blocks--;
    fs_unlock(mainsb);

    return free_bit;
}
Example #2
0
/* Set a block to used */
void
bset(blocknum_t blocknum)
{
    blocknum_t bit = -1;
    blocknum_t block_offset;

    fs_lock(mainsb);
    if (blocknum <= mainsb->block_bitmap_last || blocknum >=mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return;
    }

    /* Set the block to free */
    bit = blocknum;
    block_offset = bit / BITS_PER_BLOCK;

    if (bitmap_get(mainsb->block_bitmap, bit) == 0) {
        bitmap_set(mainsb->block_bitmap, bit);
        bpush(block_offset + mainsb->block_bitmap_first,
            (char*) mainsb->block_bitmap + block_offset * DISK_BLOCK_SIZE);
        mainsb->free_blocks--;
    }

    fs_unlock(mainsb);
}
Example #3
0
/*
 * Allocate a free inode and return a pointer to free inode
 * Return NULL if fail.
 */
inodenum_t
ialloc(disk_t* disk)
{
    inodenum_t free_bit = -1;
    inodenum_t block_offset = -1;

    fs_lock(mainsb);
    if (mainsb->free_inodes <= 0) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Get free inode number */
    free_bit = bitmap_next_zero(mainsb->inode_bitmap, mainsb->disk_num_blocks);
    block_offset = free_bit / BITS_PER_BLOCK;
    if (free_bit < 0 || block_offset >= mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Set the free inode to used */
    bitmap_set(mainsb->inode_bitmap, free_bit);
    bpush(block_offset + mainsb->inode_bitmap_first,
          (char*) mainsb->inode_bitmap + block_offset * DISK_BLOCK_SIZE);

    mainsb->free_inodes--;
    fs_unlock(mainsb);

    return free_bit;
}
Example #4
0
static int sc_hdlr_open(void *_p){
	char path[((sc_fs_t*)(_p))->data_len];
	sc_fs_t *p;
	fs_node_t *root;
	process_t *this_p;


	this_p = sched_running()->parent;

	/* initials */
	p = (sc_fs_t*)_p;
	copy_from_user(path, p->data, p->data_len, this_p);

	/* identify file system and call its open callback */
	mutex_lock(&this_p->mtx);
	root = (path[0] == '/') ? (fs_root) : this_p->cwd;
	mutex_unlock(&this_p->mtx);

	if(root->ops->open == 0x0)
		return_errno(E_NOIMP);

	DEBUG("path \"%s\", mode %#x\n", path, p->mode);

	fs_lock();
	p->fd = root->ops->open(root, path, p->mode, this_p);
	fs_unlock();

	DEBUG("created fd with id %d, \"%s\"\n", p->fd, strerror(errno));

	return E_OK;
}
Example #5
0
static int sc_hdlr_rmnode(void *_p){
	char path[((sc_fs_t*)(_p))->data_len];
	sc_fs_t *p;
	fs_node_t *root;
	process_t *this_p;


	this_p = sched_running()->parent;

	/* initials */
	p = (sc_fs_t*)_p;
	copy_from_user(path, p->data, p->data_len, this_p);

	DEBUG("%s\n", path);

	/* identify file system and call its rmnode callback */
	mutex_lock(&this_p->mtx);
	root = (path[0] == '/') ? (fs_root) : this_p->cwd;
	mutex_unlock(&this_p->mtx);

	if(root->ops->node_rm == 0x0)
		return_errno(E_NOIMP);

	fs_lock();
	(void)root->ops->node_rm(root, path);
	fs_unlock();

	return -errno;
}
Example #6
0
static int sc_hdlr_close(void *_p){
	sc_fs_t *p;
	fs_filed_t *fd;
	process_t *this_p;


	this_p = sched_running()->parent;

	/* initials */
	p = (sc_fs_t*)_p;
	fd = fs_fd_acquire(p->fd, this_p);

	DEBUG("fd %d%s\n", p->fd, (fd == 0x0 ? " (invalid)" : ""));

	if(fd == 0x0)
		return_errno(E_INVAL);

	/* handle close */
	fs_lock();
	(void)fd->node->ops->close(fd, this_p);
	fs_unlock();

	// NOTE fs_fd_release must not be called, since
	// 		close has already deleted the decriptor

	return E_OK;
}
Example #7
0
static void
fs_hotplug_alarm(void *arg)
{
	struct rte_eth_dev *dev = arg;
	struct sub_device *sdev;
	int ret;
	uint8_t i;

	if (!PRIV(dev)->pending_alarm)
		return;
	PRIV(dev)->pending_alarm = 0;
	FOREACH_SUBDEV(sdev, i, dev)
		if (sdev->state != PRIV(dev)->state)
			break;
	/* if we have non-probed device */
	if (i != PRIV(dev)->subs_tail) {
		if (fs_lock(dev, 1) != 0)
			goto reinstall;
		ret = failsafe_eth_dev_state_sync(dev);
		fs_unlock(dev, 1);
		if (ret)
			ERROR("Unable to synchronize sub_device state");
	}
	failsafe_dev_remove(dev);
reinstall:
	ret = failsafe_hotplug_alarm_install(dev);
	if (ret)
		ERROR("Unable to set up next alarm");
}
Example #8
0
static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
			     uint32_t flags, struct logical_volume *lv)
{
	switch (flags & LCK_SCOPE_MASK) {
	case LCK_VG:
		if (!strcmp(resource, VG_SYNC_NAMES))
			fs_unlock();
		break;
	case LCK_LV:
		switch (flags & LCK_TYPE_MASK) {
		case LCK_NULL:
			return lv_deactivate(cmd, resource, lv_ondisk(lv));
		case LCK_UNLOCK:
			return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0, (flags & LCK_REVERT) ? 1 : 0, lv_ondisk(lv));
		case LCK_READ:
			return lv_activate_with_filter(cmd, resource, 0, lv_ondisk(lv));
		case LCK_WRITE:
			return lv_suspend_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1 : 0, 0, lv_ondisk(lv), lv);
		case LCK_EXCL:
			return lv_activate_with_filter(cmd, resource, 1, lv_ondisk(lv));
		default:
			break;
		}
		break;
	default:
		log_error("Unrecognised lock scope: %d",
			  flags & LCK_SCOPE_MASK);
		return 0;
	}

	return 1;
}
Example #9
0
int do_unlock(const char *filename,uint64_t lv,uint32_t ts,char *ptr) {
	uint64_t chunkid;
	(void)ts;
	EAT(ptr,filename,lv,'(');
	GETU64(chunkid,ptr);
	EAT(ptr,filename,lv,')');
	return fs_unlock(chunkid);
}
Example #10
0
uint8_t do_unlock(uint64_t lv,uint32_t ts,char *ptr) {
	uint64_t chunkid;
	(void)ts;
	EAT(ptr,lv,'(');
	GETU64(chunkid,ptr);
	EAT(ptr,lv,')');
	return fs_unlock(chunkid);
}
Example #11
0
/* Establish the file system and write it to disk */
int
fs_format(mem_sblock_t sbp)
{
    blocknum_t inode_bitmap_size;
    blocknum_t block_bitmap_size;
    blocknum_t i;
    sbp->filesys_lock = semaphore_new(1);
    if (NULL == sbp->filesys_lock) {
        return -1;
    }

    fs_lock(sbp);

    /* Format super block */
    sblock_get(maindisk, sbp);
    sblock_format(sbp, disk_size);
    sblock_update(sbp);

    /* Format inode and block bitmaps */
    inode_bitmap_size = sbp->inode_bitmap_last - sbp->inode_bitmap_first + 1;
    sbp->inode_bitmap = malloc(inode_bitmap_size * DISK_BLOCK_SIZE);
    block_bitmap_size = sbp->block_bitmap_last - sbp->block_bitmap_first + 1;
    sbp->block_bitmap = malloc(block_bitmap_size * DISK_BLOCK_SIZE);
    if (NULL == sbp->block_bitmap || NULL == sbp->inode_bitmap) {
        semaphore_V(sbp->filesys_lock);
        return -1;
    }
    /* Clear bitmaps */
    bitmap_zeroall(sbp->inode_bitmap, inode_bitmap_size * BITS_PER_BLOCK);
    bitmap_zeroall(sbp->block_bitmap, block_bitmap_size * BITS_PER_BLOCK);
    /* Set file system blocks to be occupied */
    for (i = 0; i <= sbp->block_bitmap_last; ++i) {
        bitmap_set(sbp->block_bitmap, i);
    }
    /* Set inode 0 to be occupied */
    bitmap_set(sbp->inode_bitmap, 0);
    /* Push updates to disk */
    for (i = sbp->inode_bitmap_first; i <= sbp->inode_bitmap_last; ++i) {
        bpush(i, (char*) sbp->inode_bitmap + (i - sbp->inode_bitmap_first)
              * DISK_BLOCK_SIZE);
    }
    for (i = sbp->block_bitmap_first; i <= sbp->block_bitmap_last; ++i) {
        bpush(i, (char*) sbp->block_bitmap + (i - sbp->block_bitmap_first)
              * DISK_BLOCK_SIZE);
    }

    /* Count free inodes and free blocks */
    mainsb->free_inodes = bitmap_count_zero(mainsb->inode_bitmap,
                                            mainsb->total_inodes);
    mainsb->free_blocks = bitmap_count_zero(mainsb->block_bitmap,
                                            mainsb->disk_num_blocks);

    fs_unlock(sbp);
    return 0;
}
Example #12
0
static int _lock_resource(struct cmd_context *cmd, const char *resource,
			  uint32_t flags)
{
	if (!_lock_fn)
		return 0;

	if (!strcmp(resource, VG_SYNC_NAMES)) {
		/* Hide this lock request from external locking */
		fs_unlock();
		return 1;
	}

	return _lock_fn(cmd, resource, flags);
}
Example #13
0
/* Initialize the file system structure from disk */
int
fs_init(mem_sblock_t sbp)
{
    blocknum_t inode_bitmap_size;
    blocknum_t block_bitmap_size;
    blocknum_t i;
    sbp->filesys_lock = semaphore_new(1);
    if (NULL == sbp->filesys_lock) {
        return -1;
    }

    fs_lock(sbp);
    sblock_get(maindisk, sbp);
    sblock_put(sbp);
    if (sblock_isvalid(sbp) != 1) {
        sblock_print(sbp);
        kprintf("File system is not recognized. ");
        kprintf("Recommend running './mkfs <blocks>'.\n");
        return -2;
    }

    inode_bitmap_size = sbp->inode_bitmap_last - sbp->inode_bitmap_first + 1;
    sbp->inode_bitmap = malloc(inode_bitmap_size * DISK_BLOCK_SIZE);
    block_bitmap_size = sbp->block_bitmap_last - sbp->block_bitmap_first + 1;
    sbp->block_bitmap = malloc(block_bitmap_size * DISK_BLOCK_SIZE);
    if (NULL == sbp->block_bitmap || NULL == sbp->inode_bitmap) {
        semaphore_V(sbp->filesys_lock);
        return -1;
    }

    /* Get disk bitmap */
    for (i = sbp->inode_bitmap_first; i <= sbp->inode_bitmap_last; ++i) {
        bpull(i, (char*) sbp->inode_bitmap + (i - sbp->inode_bitmap_first)
              * DISK_BLOCK_SIZE);
    }
    for (i = sbp->block_bitmap_first; i <= sbp->block_bitmap_last; ++i) {
        bpull(i, (char*) sbp->block_bitmap + (i - sbp->block_bitmap_first)
              * DISK_BLOCK_SIZE);
    }

    /* Count free inodes and free blocks */
    mainsb->free_inodes = bitmap_count_zero(mainsb->inode_bitmap,
                                            mainsb->total_inodes);
    mainsb->free_blocks = bitmap_count_zero(mainsb->block_bitmap,
                                            mainsb->disk_num_blocks);

    fs_unlock(sbp);

    return 0;
}
Example #14
0
static int sc_hdlr_chdir(void *_p){
	char path[((sc_fs_t*)(_p))->data_len];
	sc_fs_t *p;
	fs_node_t *root;
	process_t *this_p;


	this_p = sched_running()->parent;

	/* initials */
	p = (sc_fs_t*)_p;
	copy_from_user(path, p->data, p->data_len, this_p);

	DEBUG("sc chdir: %s\n", path);

	/* identify file system and call its findnode callback */
	fs_lock();
	mutex_lock(&this_p->mtx);

	root = (path[0] == '/') ? (fs_root) : this_p->cwd;

	if(root->ops->node_find == 0x0)
		goto_errno(end, E_NOIMP);

	root = root->ops->node_find(root, path);

	if(root == 0x0)
		goto end;

	if(root->type != FT_DIR)
		goto_errno(end, E_INVAL);

	// update current working directory
	this_p->cwd->ref_cnt--;
	this_p->cwd = root;
	root->ref_cnt++;


end:
	mutex_unlock(&this_p->mtx);
	fs_unlock();

	DEBUG("new cwd \"%s\", \"%s\"\n", this_p->cwd->name, strerror(errno));

	return -errno;
}
Example #15
0
static int sc_hdlr_dup(void *_p){
	int old_id;
	sc_fs_t *p;
	fs_filed_t *old_fd;
	process_t *this_p;


	this_p = sched_running()->parent;

	/* initiali */
	p = (sc_fs_t*)_p;
	old_id = (int)p->data;
	old_fd = fs_fd_acquire(old_id, this_p);

	DEBUG("oldfd %d%s, newfd %d\n", old_id, (old_fd == 0x0 ? " (invalid)" : ""), p->fd);

	// exit if oldfd does not exist or old and new fd are the same
	if(old_fd == 0x0 || old_fd->id == p->fd)
		return_errno(E_INVAL);

	/* close the desired fd if one is given */
	if(p->fd >= 0)
		sc_hdlr_close(_p);

	// E_INVAL is expected in case the desired fd
	// was not open before
	if(errno && errno != E_INVAL)
		return -errno;

	errno = E_OK;

	/* duplicate old fd */
	fs_lock();
	p->fd = fs_fd_dup(old_fd, p->fd, this_p);
	fs_unlock();

	fs_fd_release(old_fd);

	DEBUG("created fd with id %d\n", p->fd);

	return E_OK;
}
Example #16
0
/* Add an inode back to free list */
void
ifree(inodenum_t inum)
{
    blocknum_t bit = -1;
    blocknum_t block_offset;

    fs_lock(mainsb);

    /* Set the inode to free */
    bit = inum;
    block_offset = bit / BITS_PER_BLOCK;
    if (bitmap_get(mainsb->inode_bitmap, bit) == 1) {
        mainsb->free_inodes++;
    }
    bitmap_clear(mainsb->inode_bitmap, bit);
    bpush(block_offset + mainsb->inode_bitmap_first,
          (char*) mainsb->inode_bitmap + block_offset * DISK_BLOCK_SIZE);

    fs_unlock(mainsb);
}
Example #17
0
void log_brew(FIL *file, char *fmt, ...)
{
#if 0
	if (file->fs)
	{
		fs_lock();
		char message[40];
		UINT written;
		va_list ap;
		va_start(ap, fmt);
		int len = vsnprintf(message, sizeof(message) - 1, fmt, ap);
		va_end(ap);

		f_write(file, message, len, &written);
		f_sync(file);

		fs_unlock();
	}
#endif
}
Example #18
0
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
			       uint32_t flags, struct logical_volume *lv)
{
	char lockfile[PATH_MAX];
	unsigned origin_only = (flags & LCK_ORIGIN_ONLY) ? 1 : 0;
	unsigned revert = (flags & LCK_REVERT) ? 1 : 0;

	switch (flags & LCK_SCOPE_MASK) {
	case LCK_ACTIVATION:
		if (dm_snprintf(lockfile, sizeof(lockfile),
				"%s/A_%s", _lock_dir, resource + 1) < 0) {
			log_error("Too long locking filename %s/A_%s.", _lock_dir, resource + 1);
			return 0;
		}

		if (!lock_file(lockfile, flags))
			return_0;
		break;
	case LCK_VG:
		/* Skip cache refresh for VG_GLOBAL - the caller handles it */
		if (strcmp(resource, VG_GLOBAL))
			lvmcache_drop_metadata(resource, 0);

		if (!strcmp(resource, VG_SYNC_NAMES))
			fs_unlock();

		/* LCK_CACHE does not require a real lock */
		if (flags & LCK_CACHE)
			break;

		if (is_orphan_vg(resource) || is_global_vg(resource)) {
			if (dm_snprintf(lockfile, sizeof(lockfile),
					"%s/P_%s", _lock_dir, resource + 1) < 0) {
				log_error("Too long locking filename %s/P_%s.",
					  _lock_dir, resource + 1);
				return 0;
			}
		} else
			if (dm_snprintf(lockfile, sizeof(lockfile),
					"%s/V_%s", _lock_dir, resource) < 0) {
				log_error("Too long locking filename %s/V_%s.",
					  _lock_dir, resource);
				return 0;
			}

		if (!lock_file(lockfile, flags))
			return_0;
		break;
	case LCK_LV:
		switch (flags & LCK_TYPE_MASK) {
		case LCK_UNLOCK:
			log_very_verbose("Unlocking LV %s%s%s", resource, origin_only ? " without snapshots" : "", revert ? " (reverting)" : "");
			if (!lv_resume_if_active(cmd, resource, origin_only, 0, revert, lv_ondisk(lv)))
				return 0;
			break;
		case LCK_NULL:
			log_very_verbose("Locking LV %s (NL)", resource);
			if (!lv_deactivate(cmd, resource, lv_ondisk(lv)))
				return 0;
			break;
		case LCK_READ:
			log_very_verbose("Locking LV %s (R)", resource);
			if (!lv_activate_with_filter(cmd, resource, 0, lv->status & LV_NOSCAN ? 1 : 0,
						     lv->status & LV_TEMPORARY ? 1 : 0, lv_ondisk(lv)))
				return 0;
			break;
		case LCK_PREAD:
			log_very_verbose("Locking LV %s (PR) - ignored", resource);
			break;
		case LCK_WRITE:
			log_very_verbose("Locking LV %s (W)%s", resource, origin_only ? " without snapshots" : "");
			if (!lv_suspend_if_active(cmd, resource, origin_only, 0, lv_ondisk(lv), lv))
				return 0;
			break;
		case LCK_EXCL:
			log_very_verbose("Locking LV %s (EX)", resource);
			if (!lv_activate_with_filter(cmd, resource, 1, lv->status & LV_NOSCAN ? 1 : 0,
						     lv->status & LV_TEMPORARY ? 1 : 0, lv_ondisk(lv)))
				return 0;
			break;
		default:
			break;
		}
		break;
	default:
		log_error("Unrecognised lock scope: %d",
			  flags & LCK_SCOPE_MASK);
		return 0;
	}

	return 1;
}