123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942 |
- /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
- /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
- /* Copyright (C) 2014 OSCAR lab, Stony Brook University
- This file is part of Graphene Library OS.
- Graphene Library OS is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- Graphene Library OS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- /*
- * shim_handle.c
- *
- * This file contains codes to maintain bookkeeping for handles in library OS.
- */
- #include <shim_internal.h>
- #include <shim_thread.h>
- #include <shim_handle.h>
- #include <shim_checkpoint.h>
- #include <shim_fs.h>
- #include <pal.h>
- #include <pal_error.h>
- static LOCKTYPE handle_mgr_lock;
- #define HANDLE_MGR_ALLOC 32
- #define system_lock() lock(handle_mgr_lock)
- #define system_unlock() unlock(handle_mgr_lock)
- #define PAGE_SIZE allocsize
- #define OBJ_TYPE struct shim_handle
- #include <memmgr.h>
- static MEM_MGR handle_mgr = NULL;
- #define INIT_HANDLE_MAP_SIZE 32
- //#define DEBUG_REF
- static inline int init_tty_handle (struct shim_handle * hdl, bool write)
- {
- struct shim_dentry * dent = NULL;
- int ret;
- if ((ret = path_lookupat(NULL, "/dev/tty", LOOKUP_OPEN, &dent)) < 0)
- return ret;
- int flags = (write ? O_WRONLY : O_RDONLY)|O_APPEND;
- struct shim_mount * fs = dent->fs;
- ret = fs->d_ops->open(hdl, dent, flags);
- if (ret < 0)
- return ret;
- set_handle_fs(hdl, fs);
- hdl->dentry = dent;
- hdl->flags = O_RDWR|O_APPEND|0100000;
- int size;
- char * path = dentry_get_path(dent, true, &size);
- if (path)
- qstrsetstr(&hdl->path, path, size);
- else
- qstrsetstr(&hdl->path, "/dev/tty", 8);
- return 0;
- }
- static inline int init_exec_handle (struct shim_thread * thread)
- {
- if (!PAL_CB(executable))
- return 0;
- struct shim_handle * exec = get_new_handle();
- if (!exec)
- return -ENOMEM;
- qstrsetstr(&exec->uri, PAL_CB(executable), strlen(PAL_CB(executable)));
- exec->type = TYPE_FILE;
- exec->flags = O_RDONLY;
- exec->acc_mode = MAY_READ;
- struct shim_mount * fs = find_mount_from_uri(PAL_CB(executable));
- if (fs) {
- path_lookupat(fs->root, PAL_CB(executable) + fs->uri.len, 0,
- &exec->dentry);
- set_handle_fs(exec, fs);
- if (exec->dentry) {
- int len;
- const char * path = dentry_get_path(exec->dentry, true, &len);
- qstrsetstr(&exec->path, path, len);
- }
- put_mount(fs);
- } else {
- set_handle_fs(exec, &chroot_builtin_fs);
- }
- lock(thread->lock);
- thread->exec = exec;
- unlock(thread->lock);
- return 0;
- }
- static struct shim_handle_map * get_new_handle_map (FDTYPE size);
- PAL_HANDLE shim_stdio = NULL;
- static int __set_new_fd_handle(struct shim_fd_handle ** fdhdl, FDTYPE fd,
- struct shim_handle * hdl, int flags);
- static struct shim_handle_map * __enlarge_handle_map
- (struct shim_handle_map * map, FDTYPE size);
- int init_handle (void)
- {
- create_lock(handle_mgr_lock);
- handle_mgr = create_mem_mgr(init_align_up(HANDLE_MGR_ALLOC));
- if (!handle_mgr)
- return -ENOMEM;
- return 0;
- }
- int init_important_handles (void)
- {
- struct shim_thread * thread = get_cur_thread();
- if (thread->handle_map)
- goto done;
- struct shim_handle_map * handle_map = get_cur_handle_map(thread);
- if (!handle_map) {
- handle_map = get_new_handle_map(INIT_HANDLE_MAP_SIZE);
- if (!handle_map)
- return -ENOMEM;
- set_handle_map(thread, handle_map);
- }
- lock(handle_map->lock);
- if (handle_map->fd_size < 3) {
- if (!__enlarge_handle_map(handle_map, INIT_HANDLE_MAP_SIZE)) {
- unlock(handle_map->lock);
- return -ENOMEM;
- }
- }
- struct shim_handle * hdl = NULL;
- int ret;
- for (int fd = 0 ; fd < 3 ; fd++)
- if (!HANDLE_ALLOCATED(handle_map->map[fd])) {
- if (!hdl) {
- hdl = get_new_handle();
- if (!hdl)
- return -ENOMEM;
- if ((ret = init_tty_handle(hdl, fd)) < 0) {
- put_handle(hdl);
- return ret;
- }
- } else {
- get_handle(hdl);
- }
- __set_new_fd_handle(&handle_map->map[fd], fd, hdl, 0);
- put_handle(hdl);
- if (fd != 1)
- hdl = NULL;
- } else {
- if (fd == 1)
- hdl = handle_map->map[fd]->handle;
- }
- if (handle_map->fd_top == FD_NULL || handle_map->fd_top < 2)
- handle_map->fd_top = 2;
- unlock(handle_map->lock);
- done:
- init_exec_handle(thread);
- return 0;
- }
- struct shim_handle * __get_fd_handle (FDTYPE fd, int * flags,
- struct shim_handle_map * map)
- {
- struct shim_fd_handle * fd_handle = NULL;
- if (map->fd_top != FD_NULL &&
- fd <= map->fd_top) {
- fd_handle = map->map[fd];
- if (!HANDLE_ALLOCATED(fd_handle))
- return NULL;
- if (flags)
- *flags = fd_handle->flags;
- return fd_handle->handle;
- }
- return NULL;
- }
- struct shim_handle * get_fd_handle (FDTYPE fd, int * flags,
- struct shim_handle_map * map)
- {
- if (!map)
- map = get_cur_handle_map(NULL);
- struct shim_handle * hdl = NULL;
- lock(map->lock);
- if ((hdl = __get_fd_handle(fd, flags, map)))
- get_handle(hdl);
- unlock(map->lock);
- return hdl;
- }
- struct shim_handle *
- __detach_fd_handle (struct shim_fd_handle * fd, int * flags,
- struct shim_handle_map * map)
- {
- struct shim_handle * handle = NULL;
- if (HANDLE_ALLOCATED(fd)) {
- int vfd = fd->vfd;
- handle = fd->handle;
- if (flags)
- *flags = fd->flags;
- fd->vfd = FD_NULL;
- fd->handle = NULL;
- fd->flags = 0;
- if (vfd == map->fd_top)
- do {
- map->fd_top = vfd ? vfd - 1 : FD_NULL;
- vfd--;
- } while (vfd >= 0 &&
- !HANDLE_ALLOCATED(map->map[vfd]));
- }
- return handle;
- }
- struct shim_handle * detach_fd_handle (FDTYPE fd, int * flags,
- struct shim_handle_map * handle_map)
- {
- struct shim_handle * handle = NULL;
- if (!handle_map && !(handle_map = get_cur_handle_map(NULL)))
- return NULL;
- lock(handle_map->lock);
- if (fd < handle_map->fd_size)
- handle = __detach_fd_handle(handle_map->map[fd], flags,
- handle_map);
- unlock(handle_map->lock);
- return handle;
- }
- struct shim_handle * get_new_handle (void)
- {
- struct shim_handle * new_handle =
- get_mem_obj_from_mgr_enlarge(handle_mgr,
- size_align_up(HANDLE_MGR_ALLOC));
- if (!new_handle)
- return NULL;
- memset(new_handle, 0, sizeof(struct shim_handle));
- REF_SET(new_handle->ref_count, 1);
- create_lock(new_handle->lock);
- new_handle->owner = cur_process.vmid;
- return new_handle;
- }
- static int __set_new_fd_handle(struct shim_fd_handle ** fdhdl, FDTYPE fd,
- struct shim_handle * hdl, int flags)
- {
- struct shim_fd_handle * new_handle = *fdhdl;
- if (!new_handle) {
- new_handle = malloc(sizeof(struct shim_fd_handle));
- if (!new_handle)
- return -ENOMEM;
- *fdhdl = new_handle;
- }
- new_handle->vfd = fd;
- new_handle->flags = flags;
- open_handle(hdl);
- new_handle->handle = hdl;
- return 0;
- }
- int set_new_fd_handle (struct shim_handle * hdl, int flags,
- struct shim_handle_map * handle_map)
- {
- FDTYPE fd = 0;
- int new_size = 0;
- int ret = 0;
- if (!handle_map && !(handle_map = get_cur_handle_map(NULL)))
- return -EBADF;
- lock(handle_map->lock);
- if (!handle_map->map ||
- handle_map->fd_size < INIT_HANDLE_MAP_SIZE)
- new_size = INIT_HANDLE_MAP_SIZE;
- if (!handle_map->map)
- goto extend;
- if (handle_map->fd_top != FD_NULL)
- do {
- ++fd;
- if (fd == handle_map->fd_size) {
- new_size = handle_map->fd_size < new_size ? new_size :
- handle_map->fd_size * 2;
- extend:
- if (!__enlarge_handle_map(handle_map, new_size)) {
- ret = -ENOMEM;
- goto out;
- }
- }
- } while (handle_map->fd_top != FD_NULL &&
- fd <= handle_map->fd_top &&
- HANDLE_ALLOCATED(handle_map->map[fd]));
- if (handle_map->fd_top == FD_NULL ||
- fd > handle_map->fd_top)
- handle_map->fd_top = fd;
- ret = __set_new_fd_handle(&handle_map->map[fd], fd, hdl, flags);
- if (ret < 0) {
- if (fd == handle_map->fd_top)
- handle_map->fd_top = fd ? fd - 1 : FD_NULL;
- } else
- ret = fd;
- out:
- unlock(handle_map->lock);
- return ret;
- }
- int set_new_fd_handle_by_fd (FDTYPE fd, struct shim_handle * hdl, int flags,
- struct shim_handle_map * handle_map)
- {
- int new_size = 0;
- int ret = 0;
- if (!handle_map && !(handle_map = get_cur_handle_map(NULL)))
- return -EBADF;
- lock(handle_map->lock);
- if (!handle_map->map ||
- handle_map->fd_size < INIT_HANDLE_MAP_SIZE)
- new_size = INIT_HANDLE_MAP_SIZE;
- if (!handle_map->map)
- goto extend;
- if (fd >= handle_map->fd_size) {
- new_size = handle_map->fd_size < new_size ? new_size :
- handle_map->fd_size;
- extend:
- while (new_size <= fd)
- new_size *= 2;
- if (!__enlarge_handle_map(handle_map, new_size)) {
- ret = -ENOMEM;
- goto out;
- }
- }
- if (handle_map->fd_top != FD_NULL &&
- fd <= handle_map->fd_top &&
- HANDLE_ALLOCATED(handle_map->map[fd])) {
- ret = -EBADF;
- goto out;
- }
- if (handle_map->fd_top == FD_NULL ||
- fd > handle_map->fd_top)
- handle_map->fd_top = fd;
- struct shim_fd_handle * new_handle = handle_map->map[fd];
- if (!new_handle) {
- new_handle = malloc(sizeof(struct shim_fd_handle));
- if (!new_handle) {
- ret = -ENOMEM;
- goto out;
- }
- handle_map->map[fd] = new_handle;
- }
- ret = __set_new_fd_handle(&handle_map->map[fd], fd, hdl, flags);
- if (ret < 0) {
- if (fd == handle_map->fd_top)
- handle_map->fd_top = fd ? fd - 1 : FD_NULL;
- } else
- ret = fd;
- out:
- unlock(handle_map->lock);
- return fd;
- }
- void flush_handle (struct shim_handle * hdl)
- {
- if (hdl->fs && hdl->fs->fs_ops &&
- hdl->fs->fs_ops->flush)
- hdl->fs->fs_ops->flush(hdl);
- }
- static inline __attribute__((unused))
- const char * __handle_name (struct shim_handle * hdl)
- {
- if (!qstrempty(&hdl->path))
- return qstrgetstr(&hdl->path);
- if (!qstrempty(&hdl->uri))
- return qstrgetstr(&hdl->uri);
- if (hdl->fs_type[0])
- return hdl->fs_type;
- return "(unknown)";
- }
- void open_handle (struct shim_handle * hdl)
- {
- get_handle(hdl);
- #ifdef DEBUG_REF
- int opened = REF_INC(hdl->opened);
- debug("open handle %p(%s) (opened = %d)\n", hdl, __handle_name(hdl),
- opened);
- #else
- REF_INC(hdl->opened);
- #endif
- }
- void close_handle (struct shim_handle * hdl)
- {
- int opened = REF_DEC(hdl->opened);
- #ifdef DEBUG_REF
- debug("close handle %p(%s) (opened = %d)\n", hdl, __handle_name(hdl),
- opened);
- #endif
- if (!opened) {
- if (hdl->type == TYPE_DIR) {
- struct shim_dir_handle * dir = &hdl->info.dir;
- if (dir->dot) {
- put_dentry(dir->dot);
- dir->dot = NULL;
- }
- if (dir->dotdot) {
- put_dentry(dir->dotdot);
- dir->dotdot = NULL;
- }
- while (dir->ptr && *dir->ptr) {
- struct shim_dentry * dent = *dir->ptr;
- put_dentry(dent);
- *(dir->ptr++) = NULL;
- }
- } else {
- if (hdl->fs && hdl->fs->fs_ops &&
- hdl->fs->fs_ops->close)
- hdl->fs->fs_ops->close(hdl);
- }
- }
- put_handle(hdl);
- }
- void get_handle (struct shim_handle * hdl)
- {
- #ifdef DEBUG_REF
- int ref_count = REF_INC(hdl->ref_count);
- debug("get handle %p(%s) (ref_count = %d)\n", hdl, __handle_name(hdl),
- ref_count);
- #else
- REF_INC(hdl->ref_count);
- #endif
- }
- static void destroy_handle (struct shim_handle * hdl)
- {
- destroy_lock(hdl->lock);
- if (MEMORY_MIGRATED(hdl))
- memset(hdl, 0, sizeof(struct shim_handle));
- else
- free_mem_obj_to_mgr(handle_mgr, hdl);
- }
- void put_handle (struct shim_handle * hdl)
- {
- int ref_count = REF_DEC(hdl->ref_count);
- #ifdef DEBUG_REF
- debug("put handle %p(%s) (ref_count = %d)\n", hdl, __handle_name(hdl),
- ref_count);
- #endif
- if (!ref_count) {
- if (hdl->fs && hdl->fs->fs_ops &&
- hdl->fs->fs_ops->hput)
- hdl->fs->fs_ops->hput(hdl);
- qstrfree(&hdl->path);
- qstrfree(&hdl->uri);
- if (hdl->pal_handle)
- DkObjectClose(hdl->pal_handle);
- if (hdl->dentry)
- put_dentry(hdl->dentry);
- if (hdl->fs)
- put_mount(hdl->fs);
- destroy_handle(hdl);
- }
- }
- size_t get_file_size (struct shim_handle * hdl)
- {
- if (!hdl->fs || !hdl->fs->fs_ops)
- return -EINVAL;
- if (hdl->fs->fs_ops->poll)
- return hdl->fs->fs_ops->poll(hdl, FS_POLL_SZ);
- if (hdl->fs->fs_ops->hstat) {
- struct stat stat;
- int ret = hdl->fs->fs_ops->hstat(hdl, &stat);
- if (ret < 0)
- return ret;
- return stat.st_size;
- }
- return 0;
- }
- void dup_fd_handle (struct shim_handle_map * map,
- const struct shim_fd_handle * old,
- struct shim_fd_handle * new)
- {
- struct shim_handle * replaced = NULL;
- lock(map->lock);
- if (old->vfd != FD_NULL) {
- open_handle(old->handle);
- replaced = new->handle;
- new->handle = old->handle;
- }
- unlock(map->lock);
- if (replaced)
- close_handle(replaced);
- }
- static struct shim_handle_map * get_new_handle_map (FDTYPE size)
- {
- struct shim_handle_map * handle_map =
- malloc(sizeof(struct shim_handle_map));
- if (handle_map == NULL)
- return NULL;
- memset(handle_map, 0, sizeof(struct shim_handle_map));
- handle_map->map = malloc(sizeof(struct shim_fd_handle) * size);
- if (handle_map->map == NULL) {
- free(handle_map);
- return NULL;
- }
- memset(handle_map->map, 0,
- sizeof(struct shim_fd_handle) * size);
- handle_map->fd_top = FD_NULL;
- handle_map->fd_size = size;
- create_lock(handle_map->lock);
- return handle_map;
- }
- static struct shim_handle_map * __enlarge_handle_map
- (struct shim_handle_map * map, FDTYPE size)
- {
- if (size <= map->fd_size)
- return NULL;
- struct shim_fd_handle ** old_map = map->map;
- map->map = malloc(sizeof(struct shim_fd_handle *) * size);
- if (map->map == NULL) {
- map->map = old_map;
- return NULL;
- }
- size_t copy_size = sizeof(struct shim_fd_handle *) * map->fd_size;
- map->fd_size = size;
- if (old_map && copy_size)
- memcpy(map->map, old_map, copy_size);
- memset(&map->map[map->fd_size], 0,
- (sizeof(struct shim_fd_handle *) * size) - copy_size);
- if (old_map)
- free(old_map);
- return map;
- }
- int dup_handle_map (struct shim_handle_map ** new,
- struct shim_handle_map * old_map)
- {
- lock(old_map->lock);
- /* allocate a new handle mapping with the same size as
- the old one */
- struct shim_handle_map * new_map =
- get_new_handle_map(old_map->fd_size);
- new_map->fd_top = old_map->fd_top;
- if (old_map->fd_top == FD_NULL)
- goto done;
- for (int i = 0 ; i <= old_map->fd_top ; i++) {
- struct shim_fd_handle * fd_old = old_map->map[i];
- struct shim_fd_handle * fd_new;
- /* now we go through the handle map and reassign each
- of them being allocated */
- if (HANDLE_ALLOCATED(fd_old)) {
- /* first, get the handle to prevent it from being deleted */
- struct shim_handle * hdl = fd_old->handle;
- open_handle(hdl);
- /* DP: I assume we really need a deep copy of the handle map? */
- fd_new = malloc(sizeof(struct shim_fd_handle));
- new_map->map[i] = fd_new;
- fd_new->vfd = fd_old->vfd;
- fd_new->handle = hdl;
- fd_new->flags = fd_old->flags;
- }
- }
- done:
- unlock(old_map->lock);
- *new = new_map;
- return 0;
- }
- void get_handle_map (struct shim_handle_map * map)
- {
- REF_INC(map->ref_count);
- }
- void put_handle_map (struct shim_handle_map * map)
- {
- int ref_count = REF_DEC(map->ref_count);
- if (!ref_count) {
- if (map->fd_top == FD_NULL)
- goto done;
- for (int i = 0 ; i <= map->fd_top ; i++) {
- if (!map->map[i])
- continue;
- if (map->map[i]->vfd != FD_NULL) {
- struct shim_handle * handle = map->map[i]->handle;
- if (handle)
- close_handle(handle);
- }
- free(map->map[i]);
- }
- done:
- destroy_lock(map->lock);
- free(map->map);
- free(map);
- }
- }
- int flush_handle_map (struct shim_handle_map * map)
- {
- get_handle_map(map);
- lock(map->lock);
- if (map->fd_top == FD_NULL)
- goto done;
- /* now we go through the handle map and flush each handle */
- for (int i = 0 ; i <= map->fd_top ; i++) {
- if (!HANDLE_ALLOCATED(map->map[i]))
- continue;
- struct shim_handle * handle = map->map[i]->handle;
- if (handle)
- flush_handle(handle);
- }
- done:
- unlock(map->lock);
- put_handle_map(map);
- return 0;
- }
- int walk_handle_map (int (*callback) (struct shim_fd_handle *,
- struct shim_handle_map *, void *),
- struct shim_handle_map * map, void * arg)
- {
- int ret = 0;
- lock(map->lock);
- if (map->fd_top == FD_NULL)
- goto done;
- for (int i = 0 ; i <= map->fd_top ; i++) {
- if (!HANDLE_ALLOCATED(map->map[i]))
- continue;
- if ((ret = (*callback) (map->map[i], map, arg)) < 0)
- break;
- }
- done:
- unlock(map->lock);
- return ret;
- }
- BEGIN_CP_FUNC(handle)
- {
- assert(size == sizeof(struct shim_handle));
- struct shim_handle * hdl = (struct shim_handle *) obj;
- struct shim_handle * new_hdl = NULL;
- ptr_t off = GET_FROM_CP_MAP(obj);
- if (!off) {
- off = ADD_CP_OFFSET(sizeof(struct shim_handle));
- ADD_TO_CP_MAP(obj, off);
- new_hdl = (struct shim_handle *) (base + off);
- lock(hdl->lock);
- struct shim_mount * fs = hdl->fs;
- *new_hdl = *hdl;
- if (fs && fs->fs_ops && fs->fs_ops->checkout)
- fs->fs_ops->checkout(new_hdl);
- new_hdl->dentry = NULL;
- REF_SET(new_hdl->opened, 0);
- REF_SET(new_hdl->ref_count, 0);
- clear_lock(new_hdl->lock);
- DO_CP_IN_MEMBER(qstr, new_hdl, path);
- DO_CP_IN_MEMBER(qstr, new_hdl, uri);
- if (fs && hdl->dentry) {
- DO_CP_MEMBER(mount, hdl, new_hdl, fs);
- } else {
- new_hdl->fs = NULL;
- }
- if (hdl->dentry)
- DO_CP_MEMBER(dentry, hdl, new_hdl, dentry);
- if (new_hdl->pal_handle) {
- struct shim_palhdl_entry * entry;
- DO_CP(palhdl, hdl->pal_handle, &entry);
- entry->uri = &new_hdl->uri;
- entry->phandle = &new_hdl->pal_handle;
- }
- unlock(hdl->lock);
- ADD_CP_FUNC_ENTRY(off);
- } else {
- new_hdl = (struct shim_handle *) (base + off);
- }
- if (objp)
- *objp = (void *) new_hdl;
- }
- END_CP_FUNC(handle)
- BEGIN_RS_FUNC(handle)
- {
- struct shim_handle * hdl = (void *) (base + GET_CP_FUNC_ENTRY());
- CP_REBASE(hdl->fs);
- CP_REBASE(hdl->dentry);
- create_lock(hdl->lock);
- if (!hdl->fs) {
- assert(hdl->fs_type);
- search_builtin_fs(hdl->fs_type, &hdl->fs);
- if (!hdl->fs)
- return -EINVAL;
- }
- if (hdl->fs && hdl->fs->fs_ops &&
- hdl->fs->fs_ops->checkin)
- hdl->fs->fs_ops->checkin(hdl);
- DEBUG_RS("path=%s,type=%s,uri=%s,flags=%03o",
- qstrgetstr(&hdl->path), hdl->fs_type, qstrgetstr(&hdl->uri),
- hdl->flags);
- }
- END_RS_FUNC(handle)
- BEGIN_CP_FUNC(fd_handle)
- {
- assert(size == sizeof(struct shim_fd_handle));
- struct shim_fd_handle * fdhdl = (struct shim_fd_handle *) obj;
- struct shim_fd_handle * new_fdhdl = NULL;
- ptr_t off = ADD_CP_OFFSET(sizeof(struct shim_fd_handle));
- new_fdhdl = (struct shim_fd_handle *) (base + off);
- memcpy(new_fdhdl, fdhdl, sizeof(struct shim_fd_handle));
- DO_CP(handle, fdhdl->handle, &new_fdhdl->handle);
- ADD_CP_FUNC_ENTRY(off);
- if (objp)
- *objp = (void *) new_fdhdl;
- }
- END_CP_FUNC_NO_RS(fd_handle)
- BEGIN_CP_FUNC(handle_map)
- {
- assert(size >= sizeof(struct shim_handle_map));
- struct shim_handle_map * handle_map = (struct shim_handle_map *) obj;
- struct shim_handle_map * new_handle_map = NULL;
- struct shim_fd_handle ** ptr_array;
- lock(handle_map->lock);
- int fd_size = handle_map->fd_top != FD_NULL ?
- handle_map->fd_top + 1 : 0;
- size = sizeof(struct shim_handle_map) +
- (sizeof(struct shim_fd_handle *) * fd_size);
- ptr_t off = GET_FROM_CP_MAP(obj);
- if (!off) {
- off = ADD_CP_OFFSET(size);
- new_handle_map = (struct shim_handle_map *) (base + off);
- memcpy(new_handle_map, handle_map,
- sizeof(struct shim_handle_map));
- ptr_array = (void *) new_handle_map + sizeof(struct shim_handle_map);
- new_handle_map->fd_size = fd_size;
- new_handle_map->map = fd_size ? ptr_array : NULL;
- REF_SET(new_handle_map->ref_count, 0);
- clear_lock(new_handle_map->lock);
- for (int i = 0 ; i < fd_size ; i++) {
- if (HANDLE_ALLOCATED(handle_map->map[i]))
- DO_CP(fd_handle, handle_map->map[i], &ptr_array[i]);
- else
- ptr_array[i] = NULL;
- }
- ADD_CP_FUNC_ENTRY(off);
- } else {
- new_handle_map = (struct shim_handle_map *) (base + off);
- }
- unlock(handle_map->lock);
- if (objp)
- *objp = (void *) new_handle_map;
- }
- END_CP_FUNC(handle_map)
- BEGIN_RS_FUNC(handle_map)
- {
- struct shim_handle_map * handle_map = (void *) (base + GET_CP_FUNC_ENTRY());
- CP_REBASE(handle_map->map);
- assert(handle_map->map);
- DEBUG_RS("size=%d,top=%d", handle_map->fd_size, handle_map->fd_top);
- create_lock(handle_map->lock);
- lock(handle_map->lock);
- if (handle_map->fd_top != FD_NULL)
- for (int i = 0 ; i <= handle_map->fd_top ; i++) {
- CP_REBASE(handle_map->map[i]);
- if (HANDLE_ALLOCATED(handle_map->map[i])) {
- CP_REBASE(handle_map->map[i]->handle);
- struct shim_handle * hdl = handle_map->map[i]->handle;
- assert(hdl);
- open_handle(hdl);
- DEBUG_RS("[%d]%s", i, qstrempty(&hdl->uri) ? hdl->fs_type :
- qstrgetstr(&hdl->uri));
- }
- }
- unlock(handle_map->lock);
- }
- END_RS_FUNC(handle_map)
|