Exemple #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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
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;
}
Exemple #5
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;
}
Exemple #6
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");
}
Exemple #7
0
void fs_open(PUNICODE_STRING DriveRoot,int rw)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;

    InitializeObjectAttributes(&ObjectAttributes,
        DriveRoot,
        0,
        NULL,
        NULL);

    Status = NtOpenFile(&fd,
        FILE_GENERIC_READ | (rw ? FILE_GENERIC_WRITE : 0),
        &ObjectAttributes,
        &Iosb,
        rw ? 0 : FILE_SHARE_READ,
        FILE_SYNCHRONOUS_IO_ALERT);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile() failed with status 0x%.08x\n", Status);
        return;
    }

    // If rw is specified, then the volume should be exclusively locked
    if (rw) fs_lock(TRUE);

    // Query geometry and partition info, to have bytes per sector, etc

    CurrentOffset.QuadPart = 0LL;

    changes = last = NULL;
    did_change = 0;
}
Exemple #8
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);
}
Exemple #9
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;
}
Exemple #10
0
static int
fs_sis_lock(struct fs_file *_file, unsigned int secs, struct fs_lock **lock_r)
{
	struct sis_fs_file *file = (struct sis_fs_file *)_file;

	if (fs_lock(file->super, secs, lock_r) < 0) {
		fs_sis_file_copy_error(file);
		return -1;
	}
	return 0;
}
Exemple #11
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;
}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
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
}
Exemple #15
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);
}
Exemple #16
0
	void operator() ()
	{
		prctl(PR_SET_NAME, "swarm-fs");
		{
			std::unique_lock<std::mutex> lock(scope.mutex);
			++scope.active_threads;
			scope.condition.notify_all();
		}
		for (;;) {
			queue_element element;
			{
				std::unique_lock<std::mutex> fs_lock(scope.fs_mutex);
				while (scope.files.empty() && !scope.done)
					scope.fs_condition.wait(fs_lock);
				if (!scope.files.empty()) {
					element = scope.files.front();
					scope.files.erase(scope.files.begin());
				} else if (scope.done) {
					break;
				}
			}
			in_progress_guard guard = { scope };

			ioremap::swarm::url base_url;
			ioremap::swarm::url_finder finder(element.data);

			if (!base_url.set_base(element.url))
				continue;

			element.url = base_url.normalized();
			if (element.url.empty())
				continue;

			result_handler handler = { scope, element.depth };
			if (element.depth >= 0) {
				for (auto it = finder.urls().begin(); it != finder.urls().end(); ++it) {
					std::string url = *it;

					if (url.compare(0, 7, "mailto:") == 0)
						continue;

					std::string host;
					element.request.set_url(base_url.relative(url, &host));
					if (element.request.url().empty() || host.empty())
						continue;

					if (!scope.base_host.empty()) {
						if (host.size() < scope.base_host.size())
							continue;

						if (host.size() > scope.base_host.size()) {
							if (host.find(scope.base_host) != host.size() - scope.base_host.size())
								continue;
							if (host[host.size() - scope.base_host.size() - 1] != '.')
								continue;
						} else if (host != scope.base_host) {
							continue;
						}
					}

					bool inserted = false;
					{
						std::lock_guard<std::mutex> lock(scope.mutex);
						if (scope.need_to_load > 0) {
							inserted = scope.used.insert(element.request.url()).second;
							if (inserted)
								--scope.need_to_load;
						}
					}
					if (inserted) {
						++scope.in_progress;
						scope.managers[rand() % scope.managers.size()]->get(handler, element.request);
					}
				}
			}

			std::string filepath = scope.base_directory + "/" + element.url;
			size_t index = 0;
			while ((index = filepath.find("//", index)) != std::string::npos) {
				filepath.erase(index, 1);
			}
			if (filepath[filepath.size() - 1] == '/')
				filepath.resize(filepath.size() - 1);
			filepath += "~file-tag";


			index = 0;
			int err = 0;
			while ((index = filepath.find('/', index + 1)) != std::string::npos) {
				std::string dir = filepath.substr(0, index);
				err = mkdir(dir.c_str(), 0755);
				if (err < 0) {
					if (errno != EEXIST) {
						err = errno;
						std::cerr << "Can not create directory: \"" << scope.base_directory << "\": " << strerror(err) << std::endl;
						break;
					} else {
						err = 0;
					}
				}
			}
			if (err != 0)
				continue;

			int oflags = O_RDWR | O_CREAT | O_LARGEFILE | O_CLOEXEC | O_TRUNC;
			int fd = open(filepath.c_str(), oflags, 0644);
			if (fd < 0) {
				err = errno;
				std::cerr << "Can not create file: \"" << filepath << "\": " << strerror(err) << std::endl;
				continue;
			}
			ssize_t written = pwrite(fd, element.data.c_str(), element.data.size(), 0);
			close(fd);
			if (written != (ssize_t)element.data.size()) {
				err = errno;
				std::cerr << "Can not write data to : \"" << filepath << "\": " << strerror(err) << std::endl;
				continue;
			}
		}
	}
Exemple #17
0
NTSTATUS
WINAPI
VfatChkdsk(IN PUNICODE_STRING DriveRoot,
           IN BOOLEAN FixErrors,
           IN BOOLEAN Verbose,
           IN BOOLEAN CheckOnlyIfDirty,
           IN BOOLEAN ScanDrive,
           IN PFMIFSCALLBACK Callback)
{
#if 0
    BOOLEAN verify;
    BOOLEAN salvage_files;
#endif
    //ULONG free_clusters;
    //DOS_FS fs;

    /* Store callback pointer */
    ChkdskCallback = Callback;
    FsCheckMemQueue = NULL;

    /* Set parameters */
    FsCheckFlags = 0;
    if (Verbose)
        FsCheckFlags |= FSCHECK_VERBOSE;

    FsCheckTotalFiles = 0;

#if 0
    verify = TRUE;
    salvage_files = TRUE;

    /* Open filesystem */
    fs_open(DriveRoot,FixErrors);

    if (CheckOnlyIfDirty && !fs_isdirty())
    {
        /* No need to check FS */
        return fs_close(FALSE);
    }

    read_boot(&fs);
    if (verify)
        VfatPrint("Starting check/repair pass.\n");

    while (read_fat(&fs), scan_root(&fs))
        qfree(&FsCheckMemQueue);

    if (ScanDrive)
        fix_bad(&fs);

    if (salvage_files)
        reclaim_file(&fs);
    else
        reclaim_free(&fs);

    free_clusters = update_free(&fs);
    file_unused();
    qfree(&FsCheckMemQueue);
    if (verify)
    {
        VfatPrint("Starting verification pass.\n");
        read_fat(&fs);
        scan_root(&fs);
        reclaim_free(&fs);
        qfree(&FsCheckMemQueue);
    }

    if (fs_changed())
    {
        if (FixErrors)
        {
            if (FsCheckFlags & FSCHECK_INTERACTIVE)
                FixErrors = get_key("yn","Perform changes ? (y/n)") == 'y';
            else
                VfatPrint("Performing changes.\n");
        }
        else
        {
            VfatPrint("Leaving file system unchanged.\n");
        }
    }

    VfatPrint("%wZ: %u files, %lu/%lu clusters\n", DriveRoot,
        FsCheckTotalFiles, fs.clusters - free_clusters, fs.clusters );

    if (FixErrors)
    {
        /* Dismount the volume */
        fs_dismount();

        /* Unlock the volume */
        fs_lock(FALSE);
    }

    /* Close the volume */
    return fs_close(FixErrors) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
#else
    return STATUS_SUCCESS;
#endif
}