void print_dir(t_files *head, char *dir_name, t_ls_args *args) { int links_column; int size_column; links_column = get_length_column(head, 1); size_column = get_length_column(head, 2); ft_putstr(dir_name); ft_putendl(":"); if (ft_strchr(args->options, 'l') && head) { ft_putstr("total "); ft_putnbr(get_total_size(head)); ft_putchar('\n'); } while (head) { if (ft_strchr(args->options, 's')) { ft_putnbr(head->blocks); ft_putchar(' '); } print_file(head, args, links_column, size_column); head = head->next; } }
static int aio_ref_get(struct aio_output *output, struct mref_object *mref) { loff_t total_size; if (unlikely(!output->brick->power.led_on)) return -EBADFD; if (unlikely(!output->mf)) { MARS_ERR("brick is not switched on\n"); return -EILSEQ; } if (unlikely(mref->ref_len <= 0)) { MARS_ERR("bad ref_len=%d\n", mref->ref_len); return -EILSEQ; } total_size = get_total_size(output); if (unlikely(total_size < 0)) { return total_size; } mref->ref_total_size = total_size; if (mref->ref_initialized) { _mref_get(mref); return mref->ref_len; } /* Buffered IO. */ if (!mref->ref_data) { struct aio_mref_aspect *mref_a = aio_mref_get_aspect(output->brick, mref); if (unlikely(!mref_a)) { MARS_ERR("bad mref_a\n"); return -EILSEQ; } if (unlikely(mref->ref_len <= 0)) { MARS_ERR("bad ref_len = %d\n", mref->ref_len); return -ENOMEM; } mref->ref_data = brick_block_alloc(mref->ref_pos, (mref_a->alloc_len = mref->ref_len)); if (unlikely(!mref->ref_data)) { MARS_ERR("ENOMEM %d bytes\n", mref->ref_len); return -ENOMEM; } #if 0 // ??? mref->ref_flags = 0; #endif mref_a->do_dealloc = true; atomic_inc(&output->total_alloc_count); atomic_inc(&output->alloc_count); } _mref_get_first(mref); return mref->ref_len; }
void get_system_information(void) { cprintf("Getting system information: "); cprintf("CPU..."); _cputype=get_cpu_type();_cpuvendor=get_cpu_id(); cprintf("\b\b\b\b\b\bFPU..."); _fputype=get_fpu_type();_fpuinfo=get_fpu_info(); cprintf("\b\b\b\b\b\bSYS..."); _systype=get_sys_type();_codecpl=get_cpl();_codeiopl=get_iopl(); _extendertype=get_extender_type(); _dpmiflags=get_dpmi_flags(); if((_dpmiflags&0x02)==0) _modetype=1; else _modetype=0; cprintf("\b\b\b\b\b\bMEM..."); _totalmemsize=get_total_size(); _lomemsize=get_lomem_size(); _himemsize=get_himem_size(); printf("\b\b\b\b\b\bDone. \n"); }
/****************************************************************************** * 函数名称:get_total_size * * 输入参数:char *dir_name * 输出参数:unsigned int *size * 返 回 值:成功:0; 失败:-1 * 修改记录: * 其他说明: ********************************************************************************/ int get_total_size(char *dir_name, unsigned int *size) { int ret ; DIR *dir; struct stat buf; struct dirent *ptr; char file_name[MAX_PATH]; ret = stat(dir_name,&buf); if (S_ISDIR(buf.st_mode)) { // 计算目录中所有文件的大小 dir = opendir(dir_name); while ((ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0 /*|| strcmp(ptr->d_name,"index.tm3k") == 0*/) { continue; } sprintf(file_name, "%s/%s", dir_name, ptr->d_name); stat(file_name, &buf); if (S_ISDIR(buf.st_mode)) { get_total_size(file_name,size); } else { *size += buf.st_size; } } closedir(dir); } else { *size += buf.st_size; } return ret; }
static void aio_ref_put(struct aio_output *output, struct mref_object *mref) { struct file *file; struct aio_mref_aspect *mref_a; if (!_mref_put(mref)) { goto done; } if (output->mf && (file = output->mf->mf_filp) && file->f_mapping && file->f_mapping->host) { mref->ref_total_size = get_total_size(output); } mref_a = aio_mref_get_aspect(output->brick, mref); if (mref_a && mref_a->do_dealloc) { brick_block_free(mref->ref_data, mref_a->alloc_len); atomic_dec(&output->alloc_count); } aio_free_mref(mref); done:; }
static int aio_event_thread(void *data) { struct aio_threadinfo *tinfo = data; struct aio_output *output = tinfo->output; struct aio_threadinfo *other = &output->tinfo[2]; struct io_event *events; int err = -ENOMEM; events = brick_mem_alloc(sizeof(struct io_event) * MARS_MAX_AIO_READ); MARS_DBG("event thread has started.\n"); //set_user_nice(current, -20); use_fake_mm(); if (!current->mm) goto err; err = aio_start_thread(output, &output->tinfo[2], aio_sync_thread, 'y'); if (unlikely(err < 0)) goto err; while (!tinfo->should_terminate || atomic_read(&tinfo->queued_sum) > 0) { mm_segment_t oldfs; int count; int i; struct timespec timeout = { .tv_sec = 1, }; if (unlikely(!(void*)output->ctxp)) { MARS_ERR("Oops, context vanished. queued_sum = %d\n", atomic_read(&tinfo->queued_sum)); break; } #ifdef CONFIG_MARS_DEBUG if (mars_hang_mode & 1) { brick_msleep(100); continue; } #endif oldfs = get_fs(); set_fs(get_ds()); /* TODO: don't timeout upon termination. * Probably we should submit a dummy request. */ count = sys_io_getevents(output->ctxp, 1, MARS_MAX_AIO_READ, events, &timeout); set_fs(oldfs); if (likely(count > 0)) { atomic_sub(count, &output->submit_count); } for (i = 0; i < count; i++) { struct aio_mref_aspect *mref_a = (void*)events[i].data; struct mref_object *mref; int err = events[i].res; if (!mref_a) { continue; // this was a dummy request } mref_a->di.dirty_stage = 2; mref = mref_a->object; MARS_IO("AIO done %p pos = %lld len = %d rw = %d\n", mref, mref->ref_pos, mref->ref_len, mref->ref_rw); mapfree_set(output->mf, mref->ref_pos, mref->ref_pos + mref->ref_len); if (output->brick->o_fdsync && err >= 0 && mref->ref_rw != READ && !mref->ref_skip_sync && !mref_a->resubmit++) { // workaround for non-implemented AIO FSYNC operation if (output->mf && output->mf->mf_filp && output->mf->mf_filp->f_op && !output->mf->mf_filp->f_op->aio_fsync) { mars_trace(mref, "aio_fsync"); _enqueue(other, mref_a, mref->ref_prio, true); continue; } err = aio_submit(output, mref_a, true); if (likely(err >= 0)) continue; } mref_a->di.dirty_stage = 3; _complete(output, mref_a, err); } } err = 0; err: MARS_DBG("event thread has stopped, err = %d\n", err); aio_stop_thread(output, 2, false); unuse_fake_mm(); tinfo->terminated = true; wake_up_interruptible_all(&tinfo->terminate_event); brick_mem_free(events); return err; } #if 1 /* This should go to fs/open.c (as long as vfs_submit() is not implemented) */ #include <linux/fdtable.h> void fd_uninstall(unsigned int fd) { struct files_struct *files = current->files; struct fdtable *fdt; MARS_DBG("fd = %d\n", fd); if (unlikely(fd < 0)) { MARS_ERR("bad fd = %d\n", fd); return; } spin_lock(&files->file_lock); fdt = files_fdtable(files); rcu_assign_pointer(fdt->fd[fd], NULL); spin_unlock(&files->file_lock); } EXPORT_SYMBOL(fd_uninstall); #endif static atomic_t ioctx_count = ATOMIC_INIT(0); static void _destroy_ioctx(struct aio_output *output) { if (unlikely(!output)) goto done; aio_stop_thread(output, 1, true); use_fake_mm(); if (likely(output->ctxp)) { mm_segment_t oldfs; int err; MARS_DBG("ioctx count = %d destroying %p\n", atomic_read(&ioctx_count), (void*)output->ctxp); oldfs = get_fs(); set_fs(get_ds()); err = sys_io_destroy(output->ctxp); set_fs(oldfs); atomic_dec(&ioctx_count); MARS_DBG("ioctx count = %d status = %d\n", atomic_read(&ioctx_count), err); output->ctxp = 0; } if (likely(output->fd >= 0)) { MARS_DBG("destroying fd %d\n", output->fd); fd_uninstall(output->fd); put_unused_fd(output->fd); output->fd = -1; } done: if (likely(current->mm)) { unuse_fake_mm(); } } static int _create_ioctx(struct aio_output *output) { struct file *file; mm_segment_t oldfs; int err = -EINVAL; CHECK_PTR_NULL(output, done); CHECK_PTR_NULL(output->mf, done); file = output->mf->mf_filp; CHECK_PTR_NULL(file, done); /* TODO: this is provisionary. We only need it for sys_io_submit() * which uses userspace concepts like file handles. * This should be accompanied by a future kernelsapce vfs_submit() or * do_submit() which currently does not exist :( */ /* see f938612dd97d481b8b5bf960c992ae577f081c17 * and 1a7bd2265fc57f29400d57f66275cc5918e30aa6 */ #if defined(get_unused_fd) || defined(get_unused_fd_flags) err = get_unused_fd(); #else err = get_unused_fd_flags(0); #endif MARS_DBG("file %p '%s' new fd = %d\n", file, output->mf->mf_name, err); if (unlikely(err < 0)) { MARS_ERR("cannot get fd, err=%d\n", err); goto done; } output->fd = err; fd_install(err, file); use_fake_mm(); err = -ENOMEM; if (unlikely(!current->mm)) { MARS_ERR("cannot fake mm\n"); goto done; } MARS_DBG("ioctx count = %d old = %p\n", atomic_read(&ioctx_count), (void*)output->ctxp); output->ctxp = 0; oldfs = get_fs(); set_fs(get_ds()); err = sys_io_setup(MARS_MAX_AIO, &output->ctxp); set_fs(oldfs); if (likely(output->ctxp)) atomic_inc(&ioctx_count); MARS_DBG("ioctx count = %d new = %p status = %d\n", atomic_read(&ioctx_count), (void*)output->ctxp, err); if (unlikely(err < 0)) { MARS_ERR("io_setup failed, err=%d\n", err); goto done; } err = aio_start_thread(output, &output->tinfo[1], aio_event_thread, 'e'); if (unlikely(err < 0)) { MARS_ERR("could not start event thread\n"); goto done; } done: if (likely(current->mm)) { unuse_fake_mm(); } return err; } static int aio_submit_thread(void *data) { struct aio_threadinfo *tinfo = data; struct aio_output *output = tinfo->output; struct file *file; int err = -EINVAL; MARS_DBG("submit thread has started.\n"); file = output->mf->mf_filp; use_fake_mm(); while (!tinfo->should_terminate || atomic_read(&output->read_count) + atomic_read(&output->write_count) + atomic_read(&tinfo->queued_sum) > 0) { struct aio_mref_aspect *mref_a; struct mref_object *mref; int sleeptime; int status; wait_event_interruptible_timeout( tinfo->event, atomic_read(&tinfo->queued_sum) > 0, HZ / 4); mref_a = _dequeue(tinfo); if (!mref_a) { continue; } mref = mref_a->object; status = -EINVAL; CHECK_PTR(mref, error); mapfree_set(output->mf, mref->ref_pos, -1); mref_a->di.dirty_stage = 0; if (mref->ref_rw) { mf_insert_dirty(output->mf, &mref_a->di); } mref->ref_total_size = get_total_size(output); // check for reads crossing the EOF boundary (special case) if (mref->ref_timeout > 0 && !mref->ref_rw && mref->ref_pos + mref->ref_len > mref->ref_total_size) { loff_t len = mref->ref_total_size - mref->ref_pos; if (len > 0) { if (mref->ref_len > len) mref->ref_len = len; } else { if (!mref_a->start_jiffies) { mref_a->start_jiffies = jiffies; } if ((long long)jiffies - mref_a->start_jiffies <= mref->ref_timeout) { if (atomic_read(&tinfo->queued_sum) <= 0) { atomic_inc(&output->total_msleep_count); brick_msleep(1000 * 4 / HZ); } _enqueue(tinfo, mref_a, MARS_PRIO_LOW, true); continue; } MARS_DBG("ENODATA %lld\n", len); _complete(output, mref_a, -ENODATA); continue; } } sleeptime = 1; for (;;) { mref_a->di.dirty_stage = 1; status = aio_submit(output, mref_a, false); if (likely(status != -EAGAIN)) { break; } mref_a->di.dirty_stage = 0; atomic_inc(&output->total_delay_count); brick_msleep(sleeptime); if (sleeptime < 100) { sleeptime++; } } error: if (unlikely(status < 0)) { MARS_IO("submit_count = %d status = %d\n", atomic_read(&output->submit_count), status); _complete_mref(output, mref, status); } } MARS_DBG("submit thread has stopped, status = %d.\n", err); if (likely(current->mm)) { unuse_fake_mm(); } tinfo->terminated = true; wake_up_interruptible_all(&tinfo->terminate_event); return err; } static int aio_get_info(struct aio_output *output, struct mars_info *info) { struct file *file; if (unlikely(!output || !output->mf || !(file = output->mf->mf_filp) || !file->f_mapping || !file->f_mapping->host)) return -EINVAL; info->tf_align = 1; info->tf_min_size = 1; info->current_size = get_total_size(output); MARS_DBG("determined file size = %lld\n", info->current_size); return 0; } //////////////// informational / statistics /////////////// static noinline char *aio_statistics(struct aio_brick *brick, int verbose) { struct aio_output *output = brick->outputs[0]; char *res = brick_string_alloc(4096); char *sync = NULL; int pos = 0; if (!res) return NULL; pos += report_timing(&timings[0], res + pos, 4096 - pos); pos += report_timing(&timings[1], res + pos, 4096 - pos); pos += report_timing(&timings[2], res + pos, 4096 - pos); snprintf(res + pos, 4096 - pos, "total " "reads = %d " "writes = %d " "allocs = %d " "submits = %d " "again = %d " "delays = %d " "msleeps = %d " "fdsyncs = %d " "fdsync_waits = %d " "map_free = %d | " "flying reads = %d " "writes = %d " "allocs = %d " "submits = %d " "q0 = %d " "q1 = %d " "q2 = %d " "| total " "q0 = %d " "q1 = %d " "q2 = %d " "%s\n", atomic_read(&output->total_read_count), atomic_read(&output->total_write_count), atomic_read(&output->total_alloc_count), atomic_read(&output->total_submit_count), atomic_read(&output->total_again_count), atomic_read(&output->total_delay_count), atomic_read(&output->total_msleep_count), atomic_read(&output->total_fdsync_count), atomic_read(&output->total_fdsync_wait_count), atomic_read(&output->total_mapfree_count), atomic_read(&output->read_count), atomic_read(&output->write_count), atomic_read(&output->alloc_count), atomic_read(&output->submit_count), atomic_read(&output->tinfo[0].queued_sum), atomic_read(&output->tinfo[1].queued_sum), atomic_read(&output->tinfo[2].queued_sum), atomic_read(&output->tinfo[0].total_enqueue_count), atomic_read(&output->tinfo[1].total_enqueue_count), atomic_read(&output->tinfo[2].total_enqueue_count), sync ? sync : ""); if (sync) brick_string_free(sync); return res; } static noinline void aio_reset_statistics(struct aio_brick *brick) { struct aio_output *output = brick->outputs[0]; int i; atomic_set(&output->total_read_count, 0); atomic_set(&output->total_write_count, 0); atomic_set(&output->total_alloc_count, 0); atomic_set(&output->total_submit_count, 0); atomic_set(&output->total_again_count, 0); atomic_set(&output->total_delay_count, 0); atomic_set(&output->total_msleep_count, 0); atomic_set(&output->total_fdsync_count, 0); atomic_set(&output->total_fdsync_wait_count, 0); atomic_set(&output->total_mapfree_count, 0); for (i = 0; i < 3; i++) { struct aio_threadinfo *tinfo = &output->tinfo[i]; atomic_set(&tinfo->total_enqueue_count, 0); } } //////////////// object / aspect constructors / destructors /////////////// static int aio_mref_aspect_init_fn(struct generic_aspect *_ini) { struct aio_mref_aspect *ini = (void*)_ini; INIT_LIST_HEAD(&ini->io_head); INIT_LIST_HEAD(&ini->di.dirty_head); ini->di.dirty_mref = ini->object; return 0; } static void aio_mref_aspect_exit_fn(struct generic_aspect *_ini) { struct aio_mref_aspect *ini = (void*)_ini; CHECK_HEAD_EMPTY(&ini->di.dirty_head); CHECK_HEAD_EMPTY(&ini->io_head); } MARS_MAKE_STATICS(aio); ////////////////////// brick constructors / destructors //////////////////// static int aio_brick_construct(struct aio_brick *brick) { return 0; } static int aio_switch(struct aio_brick *brick) { static int index; struct aio_output *output = brick->outputs[0]; const char *path = output->brick->brick_path; int flags = O_RDWR | O_LARGEFILE; int status = 0; MARS_DBG("power.button = %d\n", brick->power.button); if (!brick->power.button) goto cleanup; if (brick->power.led_on || output->mf) goto done; mars_power_led_off((void*)brick, false); if (brick->o_creat) { flags |= O_CREAT; MARS_DBG("using O_CREAT on %s\n", path); } if (brick->o_direct) { flags |= O_DIRECT; MARS_DBG("using O_DIRECT on %s\n", path); } output->mf = mapfree_get(path, flags); if (unlikely(!output->mf)) { MARS_ERR("could not open file = '%s' flags = %d\n", path, flags); status = -ENOENT; goto err; } output->index = ++index; status = _create_ioctx(output); if (unlikely(status < 0)) { MARS_ERR("could not create ioctx, status = %d\n", status); goto err; } status = aio_start_thread(output, &output->tinfo[0], aio_submit_thread, 's'); if (unlikely(status < 0)) { MARS_ERR("could not start theads, status = %d\n", status); goto err; } MARS_DBG("opened file '%s'\n", path); brick->mode_ptr = &output->mf->mf_mode; mars_power_led_on((void*)brick, true); done: return 0; err: MARS_ERR("status = %d\n", status); cleanup: if (brick->power.led_off) { goto done; } mars_power_led_on((void*)brick, false); for (;;) { int count = atomic_read(&output->work_count); if (count <= 0) break; MARS_DBG("working on %d requests\n", count); brick_msleep(1000); } aio_stop_thread(output, 0, false); brick->mode_ptr = NULL; _destroy_ioctx(output); mars_power_led_off((void*)brick, (output->tinfo[0].thread == NULL && output->tinfo[1].thread == NULL && output->tinfo[2].thread == NULL)); MARS_DBG("switch off led_off = %d status = %d\n", brick->power.led_off, status); if (brick->power.led_off) { if (output->mf) { MARS_DBG("closing file = '%s'\n", output->mf->mf_name); mapfree_put(output->mf); output->mf = NULL; } } return status; } static int aio_output_construct(struct aio_output *output) { init_waitqueue_head(&output->fdsync_event); output->fd = -1; return 0; }
size_t malloc_total() { return get_total_size(__malloc_pool); }
/****************************************************************************** * 函数名称:open_search_record_file_info * * * * 返 回 值:0 * 修改记录: * 其他说明: ********************************************************************************/ int open_search_record_file_info() { int i,j,k,total; unsigned int size; struct dirent **namelist; char path_name[MAX_PATH]; char dir_name[MAX_PATH]; RECORD_FILE_INFO *record = NULL; RECORD_FILE_INFO_LIST tmp_list = NULL; int language = 0; int disk_num; int channel_num = 0; channel_num = get_av_channel_num(); while (g_list != NULL) { tmp_list = g_list->next; free(g_list); g_list = tmp_list; } tmp_list = g_list = NULL; memset(dir_name, 0, sizeof(dir_name)); // 遍历所有硬盘的所有分区 #ifdef SD_STORAGE disk_num = 1; #else disk_num = get_hard_disk_num(); #endif for (i=0; i<disk_num; i++) { #ifdef SD_STORAGE #else if (hd_get_mount_flag(i, 0) != 1 ) { continue; } #endif for (j=0; j<channel_num; j++) { sprintf(path_name,"/record/hd%02d/%02d/ch%02d", i, 0, j); total = scandir(path_name,&namelist, filter, alphasort); if (total > 0) { for (k=0; k<total; k++) { size = 0; sprintf(dir_name,"%s/%s", path_name, namelist[k]->d_name); get_total_size(dir_name, &size); record = (RECORD_FILE_INFO *)malloc(sizeof(RECORD_FILE_INFO)); if (record != NULL) { sprintf(record->text, "%s CH%02d HD%02d %d M",namelist[k]->d_name, (j + 1),(i+1), size/(1024*1024)); record->next = NULL; if (tmp_list == NULL) tmp_list = g_list = record; else { tmp_list->next = record; tmp_list = record; } } } for (k=0; k<total; k++) { free(namelist[k]); } free(namelist); } } } // 对录像文件信息进行排序 sort_record_file_info(); return 0; }