static telf_status libfs_getattr(void *obj_hdl, telf_stat *stp) { telf_obj *obj = obj_hdl; telf_status ret; telf_status rc; telf_stat st; int i; elf_obj_lock(obj); memset(&st, 0, sizeof st); st.st_mode |= ELF_S_IFLNK; st.st_mode |= ELF_S_IRWXU|ELF_S_IRWXG|ELF_S_IRWXO; st.st_size = 0; ret = ELF_SUCCESS; end: elf_obj_unlock(obj); if (stp) *stp = st; return ret; }
static telf_status defaultfs_readdir(void *ctx_hdl, const char *path, void *data, fuse_fill_dir_t fill) { telf_ctx *ctx = ctx_hdl; telf_obj *obj = NULL; telf_status ret; int rc; telf_dir_hdl *dir_hdl = NULL; telf_dirent dirent; int locked = 0; DEBUG("%s", path); elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("can't find object with key '%s': %s", path, elf_status_to_str(rc)); ret = ELF_ENOENT; goto end; } elf_obj_lock(obj); locked = 1; dir_hdl = alloca(sizeof *dir_hdl); if (! dir_hdl) { ERR("alloca: %s", strerror(errno)); ret = ELF_ENOMEM; goto end; } memset(&dirent, 0, sizeof dirent); dir_ctor(obj->ctx, obj, dir_hdl); while (0 == readdir_getdirent(dir_hdl, &dirent)) { if (fill(data, dirent.name, NULL, 0)) break; } ret = ELF_SUCCESS; end: if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); return ret; }
static telf_status defaultfs_read(void *ctx_hdl, const char *path, char *buf, size_t size, off_t offset, ssize_t *sizep) { telf_ctx *ctx = ctx_hdl; telf_obj *obj = NULL; telf_default_content *content = NULL; telf_status ret; telf_status rc; int locked = 0; DEBUG("path=%s", path); elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("namei(%s) failed: %d", path, rc); ret = ELF_ENOENT; goto end; } elf_obj_lock(obj); locked = 1; DEBUG("name:%s data=%p", obj->name, obj->data); content = obj->data; if (content->buf) { if (size > content->buf_len - offset) size = content->buf_len - offset; memcpy(buf, content->buf + offset, size); } ret = ELF_SUCCESS; end: if (sizep) *sizep = size; if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret); return ret; }
telf_status libfs_readlink(void *obj_hdl, char **bufp, size_t *buf_lenp) { telf_obj *obj = obj_hdl; telf_status ret; Elf64_Shdr *shdr = NULL; char path[PATH_MAX]; char *buf = NULL; size_t buf_len = 0; int i; elf_obj_lock(obj); for (i = 0; i < list_get_size(obj->ctx->libpath); i++) { char *lp = list_get_nth(obj->ctx->libpath, i); char path[PATH_MAX] = ""; snprintf(path, sizeof path, "%s/%s", lp, obj->name); if (-1 == access(path, R_OK)) { if (ENOENT != errno) ERR("access: %s", strerror(errno)); continue; } buf = strdup(path); if (! buf) { ERR("malloc: %s", strerror(errno)); ret = ELF_ENOMEM; goto end; } buf_len = strlen(buf); break; } ret = ELF_SUCCESS; end: elf_obj_unlock(obj); if (bufp) *bufp = buf; else free(buf); if (buf_lenp) *buf_lenp = buf_len; return ret; }
static telf_status defaultfs_getattr(void *ctx_hdl, const char *path, telf_stat *st) { telf_ctx *ctx = ctx_hdl; telf_status ret; telf_status rc; telf_obj *obj = NULL; int locked = 0; DEBUG("path=%s", path); elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("namei(%s) failed: %d", path, rc); ret = ELF_ENOENT; goto end; } elf_obj_lock(obj); locked = 1; DEBUG("name:%s data=%p", obj->name, obj->data); memcpy(st, &obj->st, sizeof *st); st->mode |= ELF_S_IRUSR|ELF_S_IWUSR | ELF_S_IRGRP | ELF_S_IROTH; st->nlink = 1; st->atime = st->mtime = st->ctime = time(NULL); if (ELF_S_ISREG(obj->st.mode)) { if (obj->fill_func) { rc = obj->fill_func(obj, NULL, &st->size); if (ELF_SUCCESS != rc) { ret = rc; goto end; } } } ret = ELF_SUCCESS; end: if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret); return ret; }
static telf_status defaultfs_release(void *ctx_hdl, const char *path) { telf_ctx *ctx = ctx_hdl; telf_obj *obj = NULL; telf_status ret; telf_status rc; int locked = 0; DEBUG("path=%s", path); elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("namei(%s) failed: %d", path, rc); ret = ELF_ENOENT; goto end; } elf_obj_lock(obj); locked = 1; elf_obj_unref_nolock(obj); DEBUG("name:%s data=%p", obj->name, obj->data); if (0 == obj->refcount) { if (obj->free_func) { obj->free_func(obj->data); obj->data = NULL; } } ret = ELF_SUCCESS; end: if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret); return ELF_SUCCESS; }
static telf_status symentryfs_getattr(void *obj_hdl, telf_stat *stp) { telf_obj *obj = obj_hdl; telf_status ret; telf_status rc; telf_stat st; int i; elf_obj_lock(obj); DEBUG("name:%s data=%p", obj->name, obj->data); memset(&st, 0, sizeof st); st.st_mode |= ELF_S_IFREG; for (i = 0; i < N_ELEMS(symentryfs_fcb); i++) { telf_fcb *fcb = symentryfs_fcb + i; if (0 == strcmp(obj->name, fcb->str)) { rc = fcb->getsize_func(obj, &st.st_size); if (ELF_SUCCESS != rc) { ERR("can't get size of '%s'", obj->name); ret = rc; goto end; } break; } } ret = ELF_SUCCESS; end: elf_obj_unlock(obj); if (stp) *stp = st; DEBUG("ret=%s (%d)", elf_status_to_str(ret), ret); return ret; }
static telf_status headerfs_release(void *ctx_hdl, const char *path) { telf_ctx *ctx = ctx_hdl; telf_obj *obj = NULL; telf_fcb *fcb = NULL; telf_status ret; telf_status rc; int locked = 0; elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("namei(%s) failed: %d", path, rc); ret = -ENOENT; goto end; } elf_obj_lock(obj); locked = 1; elf_obj_unref_nolock(obj); DEBUG("name:%s data=%p", obj->name, obj->data); fcb = elf_get_fcb(headerfs_fcb, N_ELEMS(headerfs_fcb), obj->name); if (! fcb) { ERR("no fcb matching obj '%s'", obj->name); ret = ELF_ENOENT; goto end; } if (fcb->release_func) { rc = fcb->release_func(obj); if (ELF_SUCCESS != rc) { ERR("release ('%s') failed: %s", obj->name, elf_status_to_str(rc)); ret = rc; goto end; } } if (0 == obj->refcount) { if (obj->free_func) { obj->free_func(obj->data); obj->data = NULL; } } ret = ELF_SUCCESS; end: if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); return ret; }
static telf_status defaultfs_open(void *ctx_hdl, const char *path, void **obj_hdlp) { telf_ctx *ctx = ctx_hdl; telf_obj *obj = NULL; telf_status ret; telf_status rc; telf_default_content *content; int locked = 0; DEBUG("path=%s", path); elf_ctx_lock(ctx); rc = elf_namei(ctx, path, &obj); if (ELF_SUCCESS != rc) { ERR("namei(%s) failed: %d", path, rc); ret = ELF_ENOENT; goto end; } elf_obj_lock(obj); locked = 1; elf_obj_ref_nolock(obj); content = malloc(sizeof *content); if (! content) { ERR("malloc: %s", strerror(errno)); ret = ELF_ENOMEM; goto end; } if (obj->fill_func) { rc = obj->fill_func(obj, &content->buf, &content->buf_len); if (ELF_SUCCESS != rc) { ret = rc; goto end; } } if (obj->data && obj->free_func) obj->free_func(obj->data); obj->data = content; ret = ELF_SUCCESS; end: if (obj_hdlp) *obj_hdlp = obj; if (locked) elf_obj_unlock(obj); elf_ctx_unlock(ctx); DEBUG("path=%s, ret=%s (%d)", path, elf_status_to_str(ret), ret); return ret; }