static int __init ftfs_module_init(void) { int ret; void *data = NULL; if (!sb_dev) { ftfs_error(__func__, "no mount device for ftfs_southbound!"); return -EINVAL; } if (!sb_fstype) { ftfs_error(__func__, "no fstype for ftfs_southbound!"); return -EINVAL; } ret = resolve_ftfs_symbols(); if (ret) { ftfs_error(__func__, "could not resolve all symbols!"); return ret; } ftfs_log(__func__, "Successfully loaded all ftfs_files.c symbols"); /* * Now we create a disconnected mount for our southbound file * system. It will not be inserted into any mount trees, but * we pin a global struct vfsmount that we use for all path * resolution. */ ret = ftfs_private_mount(sb_dev, sb_fstype, data); if (ret) { ftfs_error(__func__, "can't mount southbound"); return ret; } BUG_ON(ftfs_fs); BUG_ON(ftfs_files); /* * The southbound "file system context" needs to be created to * force all fractal tree worker threads to "see" our file * system as if they were running in user space. */ ret = init_ftfs_southbound(); if (ret) { ftfs_error(__func__, "can't init southbound_fs"); return ret; } return toku_test_init(); }
/* must hold ftfs_southbound_lock */ int __init_ftfs_southbound_fs(void) { struct fs_struct *current_fs = current->fs; struct fs_struct *fs; struct path path; BUG_ON(ftfs_fs); BUG_ON(!ftfs_vfs); fs = ftfs_copy_fs_struct(current_fs); if (!fs) { ftfs_error(__func__, "init ftfs_fs"); ftfs_fs = NULL; return -ENOMEM; } ftfs_log(__func__, "ftfs->fs->umask: %d", fs->umask); path.mnt = ftfs_vfs; path.dentry = ftfs_vfs->mnt_root; ftfs_set_fs_root(fs, &path); ftfs_set_fs_pwd(fs, &path); ftfs_fs = fs; return 0; }
static void __exit ftfs_module_exit(void) { put_ftfs_southbound(); if (ftfs_private_umount()) ftfs_error(__func__, "unable to umount ftfs southbound"); toku_test_exit(); }
PARTITIONED_COUNTER create_partitioned_counter(void) { int err; PARTITIONED_COUNTER pc; pc = (PARTITIONED_COUNTER) kmalloc(sizeof(*pc), GFP_KERNEL); if (!pc) { ftfs_error(__func__, "err allocating a partitioned counter: %d", -ENOMEM); return NULL; } err = percpu_counter_init(&pc->pcpu_counter, 0); if (err) { ftfs_error(__func__, "err creating a partitioned counter: %d", err); return NULL; } return pc; }
/* takes and releases ftfs_southbound lock */ int init_ftfs_southbound(void) { int ret; BUG_ON(!ftfs_vfs); BUG_ON(ftfs_fs); BUG_ON(ftfs_files); BUG_ON(ftfs_cred); mutex_lock(&ftfs_southbound_lock); ret = __init_ftfs_southbound_fs(); if (ret) { ftfs_error(__func__, "can't init southbound_fs"); return ret; } ret = __init_ftfs_southbound_files(); if (ret) { ftfs_error(__func__, "initialize ftfs_files"); ftfs_free_fs_struct(ftfs_fs); return ret; } ret = __init_ftfs_southbound_cred(); if (ret) { ftfs_error(__func__, "initialize ftfs_cred"); ftfs_free_fs_struct(ftfs_fs); return ret; } BUG_ON(!ftfs_fs); BUG_ON(!ftfs_files); BUG_ON(!ftfs_cred); mutex_unlock(&ftfs_southbound_lock); return 0; }
static ssize_t toku_write_engine_proc(struct file *file, const char __user *buffer, size_t count, loff_t *offp) { int i, ret; char *buf; buf = kmalloc(count+1, GFP_KERNEL); if (!buf) { ftfs_error(__func__, "toku_write_proc: out of memory"); return -ENOMEM; } ret = copy_from_user(buf, buffer, count); if (ret) { ftfs_error(__func__, "toku_write_proc: bad buffer"); goto out; } for (i = 0; i < count; i++) { if (buf[i] == '\n') { buf[i] = '\0'; break; } } buf[count] = '\0'; if (0 == strcmp(buf, "print")) ftfs_print_engine_status(); ret = count; out: kfree(buf); return ret; }
int toku_engine_status_init(void) { engine_status_entry = proc_create(TOKU_ENGINE_STATUS_PROC, 0666, NULL, &toku_proc_engine_fops); if (engine_status_entry == NULL) { remove_proc_entry(TOKU_ENGINE_STATUS_PROC, NULL); ftfs_error(__func__, "Failed to initialize toku procfile: %s", TOKU_ENGINE_STATUS_PROC); return -ENOMEM; } ftfs_log(__func__, "toku procfs entry created"); return 0; }
ssize_t toku_write_proc(struct file *file, const char __user *buffer, size_t count, loff_t *offp) { int i, ret; char *buf; buf = kmalloc(count+1, GFP_KERNEL); if (!buf) { ftfs_error(__func__, "toku_write_proc: out of memory"); return -ENOMEM; } ret = copy_from_user(buf, buffer, count); if (ret) { ftfs_error(__func__, "toku_write_proc: bad buffer"); return ret; } for (i = 0; i < count; i++) { if (buf[i] == '\n') { buf[i] = '\0'; break; } } buf[count] = '\0'; //last_result = run_test(buf); thread_run_test(buf); kfree(buf); return count; }
static void __exit ftfs_module_exit(void) { destroy_ft_index(); exit_ftfs_fs(); put_ftfs_southbound(); toku_engine_status_exit(); toku_checkpoint_exit(); toku_flusher_exit(); if (ftfs_private_umount()) ftfs_error(__func__, "unable to umount ftfs southbound"); }
static int toku_test_init(void) { last_result = 0; /* create proc file */ toku_proc_entry = proc_create(TOKU_PROC_NAME, 0666, NULL, &toku_proc_fops); if (toku_proc_entry == NULL) { remove_proc_entry(TOKU_PROC_NAME, NULL); ftfs_error(__func__, "Failed to initialize toku procfile: %s", TOKU_PROC_NAME); return -ENOMEM; } ftfs_log(__func__, "toku procfs entry created"); return 0; }
/* must hold ftfs_southbound_lock */ int __init_ftfs_southbound_files(void) { int err; struct files_struct *files; BUG_ON(ftfs_files); files = ftfs_dup_fd(&ftfs_files_init, &err); if (!files) { ftfs_error(__func__, "init ftfs_files"); ftfs_files = NULL; return err; } ftfs_files = files; return 0; }
/* * attach to the ftfs fs_struct (path, root, pwd, etc) * * must hold ftfs_southbound lock * takes and relases lock of tsk */ static int __attach_ftfs_southbound(struct task_struct *tsk) { struct fs_struct *fs_copy; fs_copy = ftfs_copy_fs_struct(ftfs_fs); if (!fs_copy) { ftfs_error(__func__, "ftfs_fs copy failed"); return -ENOMEM; } task_lock(tsk); tsk->fs = fs_copy; tsk->files = (struct files_struct *)POISON_FREE; /* we should * not be using the file table, so * poison it for testing */ task_unlock(tsk); return 0; }
void ftfs_print_engine_status(void) { uint64_t nrows; int buff_size; char *buff; if (!XXX_db_env) { ftfs_error(__func__, "no db_env"); return; } XXX_db_env->get_engine_status_num_rows(XXX_db_env, &nrows); buff_size = nrows * 128; //assume 128 chars per row buff = (char *)kmalloc(sizeof(char) * buff_size, GFP_KERNEL); if (buff == NULL) return; XXX_db_env->get_engine_status_text(XXX_db_env, buff, buff_size); kfree(buff); }
/** * A fairly useless function. We just read the result of the last test * run (pass or fail). */ ssize_t toku_read_proc(struct file *filp, char __user *buf, size_t count, loff_t *off) { int res; char tmp[20]; if (*off) return 0; res = sprintf(tmp, "[%d]\n", last_result); if (count < res) res = count; if (copy_to_user(buf, tmp, res)) ftfs_error(__func__, "could not copy all bytes to user"); *off += res; return res; }
static int __init ftfs_module_init(void) { int ret; void *data = NULL; if (!sb_dev) { ftfs_error(__func__, "no mount device for ftfs_southbound!"); return -EINVAL; } if (!sb_fstype) { ftfs_error(__func__, "no fstype for ftfs_southbound!"); return -EINVAL; } ret = resolve_ftfs_symbols(); if (ret) { ftfs_error(__func__, "could not resolve all symbols!"); return ret; } ftfs_log(__func__, "Successfully loaded all ftfs_files.c symbols"); /* * Now we create a disconnected mount for our southbound file * system. It will not be inserted into any mount trees, but * we pin a global struct vfsmount that we use for all path * resolution internally in the fractal tree. */ ret = ftfs_private_mount(sb_dev, sb_fstype, data); if (ret) { ftfs_error(__func__, "can't mount southbound"); return ret; } BUG_ON(ftfs_fs); BUG_ON(ftfs_files); /* * Actually create the southbound "file system context" * for fractal tree path name resolution. * we need our own file system root and file table */ ret = init_ftfs_southbound(); if (ret) { ftfs_error(__func__, "can't init southbound_fs"); return ret; } ret = init_ftfs_fs(); if (ret) { ftfs_error(__func__, "can't init ftfs_fs"); return ret; } /* print fractal tree statistics by writing to /proc/toku_engine_status */ ret = toku_engine_status_init(); if (ret) { ftfs_error(__func__, "can't init toku engine proc"); return ret; } /* intiate a checkpoint by writing to /proc/toku_checkpoint */ ret = toku_checkpoint_init(); if (ret) { ftfs_error(__func__, "can't init toku checkpoint proc"); return ret; } /* intiate a hot optimize by writing to /proc/toku_flusht */ ret = toku_flusher_init(); if (ret) { ftfs_error(__func__, "can't init toku flusher proc"); return ret; } /* we commonly allocate and then quickly free buffers for the * cachetable. we found that keeping a few handy increases * performance significantly without requiring a complete * overhaul of the fractal tree memory allocators */ ret = init_ftfs_vmalloc_cache(); if (ret) { ftfs_error(__func__, "can't init vmalloc caches"); return ret; } return init_ft_index(); }