/* 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; }
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; }
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; }
/* * 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; }
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; }
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"); }
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; }
/* 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); }
/* 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; }
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; }
/* 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; }
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; }
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; }
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 }
/* 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); }
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; } } }
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 }