Beispiel #1
0
static int
pipe_root_lookup_parent(struct inode *node, char *path, struct inode **node_store, char **endp) {
    assert((path[0] == 'r' || path[0] == 'w') && path[1] == '_');
    *node_store = node, *endp = path;
    vop_ref_inc(node);
    return 0;
}
Beispiel #2
0
// 设置当前的目录
int
vfs_set_curdir(struct inode *dir) {
    int ret = 0;
    lock_cfs();
    struct inode *old_dir;
    if ((old_dir = get_cwd_nolock()) != dir) { // 得到当前的工作目录的inode
        if (dir != NULL) {
            uint32_t type;
            if ((ret = vop_gettype(dir, &type)) != 0) {
                goto out;
            }
            if (!S_ISDIR(type)) {
                ret = -E_NOTDIR;
                goto out;
            }
            vop_ref_inc(dir);
        }
        set_cwd_nolock(dir);
        if (old_dir != NULL) {
            vop_ref_dec(old_dir);
        }
    }
out:
    unlock_cfs();
    return ret;
}
Beispiel #3
0
/*
 * vfs_get_root - Given a device name (stdin, stdout, etc.), hand
 *                back an appropriate inode.
 */
int
vfs_get_root(const char *devname, struct inode **node_store) {
    assert(devname != NULL);
    int ret = -E_NO_DEV;
    if (!list_empty(&vdev_list)) {
        lock_vdev_list();
        {
            list_entry_t *list = &vdev_list, *le = list;
            while ((le = list_next(le)) != list) {
                vfs_dev_t *vdev = le2vdev(le, vdev_link);
                if (strcmp(devname, vdev->devname) == 0) {
                    struct inode *found = NULL;
                    if (vdev->fs != NULL) {
                        found = fsop_get_root(vdev->fs);
                    }
                    else if (!vdev->mountable) {
                        vop_ref_inc(vdev->devnode);
                        found = vdev->devnode;
                    }
                    if (found != NULL) {
                        ret = 0, *node_store = found;
                    }
                    else {
                        ret = -E_NA_DEV;
                    }
                    break;
                }
            }
        }
        unlock_vdev_list();
    }
    return ret;
}
Beispiel #4
0
static int
sfs_namefile(struct inode *node, struct iobuf *iob) {
    struct sfs_disk_entry *entry;
    if (iob->io_resid <= 2 || (entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) {
        return -E_NO_MEM;
    }

    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    int ret;
    uint32_t ino;
    char *ptr = iob->io_base + iob->io_resid;
    size_t alen, resid = iob->io_resid - 2;
    
    vop_ref_inc(node);
    while ((ino = sin->ino) != SFS_BLKN_ROOT) {
        struct inode *parent;
        if ((ret = sfs_load_parent(sfs, sin, &parent)) != 0) {
            goto failed;
        }
        vop_ref_dec(node);
        
        node = parent, sin = vop_info(node, sfs_inode);
        assert(ino != sin->ino && sin->din->type == SFS_TYPE_DIR);

        if ((ret = trylock_sin(sin)) != 0) {
            goto failed;
        }
        ret = sfs_dirent_findino_nolock(sfs, sin, ino, entry);
        unlock_sin(sin);

        if (ret != 0) {
            goto failed;
        }

        if ((alen = strlen(entry->name) + 1) > resid) {
            goto failed_nomem;
        }
        resid -= alen, ptr -= alen;
        memcpy(ptr, entry->name, alen - 1);
        ptr[alen - 1] = '/';
    }
    vop_ref_dec(node);
    alen = iob->io_resid - resid - 2;
    ptr = memmove(iob->io_base + 1, ptr, alen);
    ptr[-1] = '/', ptr[alen] = '\0';
    iobuf_skip(iob, alen);
    kfree(entry);
    return 0;

failed_nomem:
    ret = -E_NO_MEM;
failed:
    vop_ref_dec(node);
    kfree(entry);
    return ret;
}
Beispiel #5
0
/*
 * Name lookup.
 *
 * One interesting feature of device:name pathname syntax is that you
 * can implement pathnames on arbitrary devices. For instance, if you
 * had a graphics device that supported multiple resolutions (which we
 * don't), you might arrange things so that you could open it with
 * pathnames like "video:800x600/24bpp" in order to select the operating
 * mode.
 *
 * However, we have no support for this in the base system.
 */
static int
dev_lookup(struct inode *node, char *path, struct inode **node_store) {
    if (*path != '\0') {
        return -E_NOENT;
    }
    vop_ref_inc(node);
    *node_store = node;
    return 0;
}
Beispiel #6
0
/*
 * Given a device name (lhd0, emu0, somevolname, null, etc.), hand
 * back an appropriate inode.
 */
int
vfs_get_root(const char *devname, struct inode **node_store) {
    assert(devname != NULL);
    int ret = -E_NO_DEV;
    if (!list_empty(&vdev_list)) {
        lock_vdev_list();
        {
            list_entry_t *list = &vdev_list, *le = list;
            while ((le = list_next(le)) != list) {
                vfs_dev_t *vdev = le2vdev(le, vdev_link);
                if (strcmp(devname, vdev->devname) == 0) {
                    struct inode *found = NULL;

        /*
         * If this device has a mounted filesystem, and
         * DEVNAME names either the filesystem or the device,
         * return the root of the filesystem.
         *
         * If it has no mounted filesystem, it's mountable,
         * and DEVNAME names the device, return -E_NA_DEV.
         */

                    if (vdev->fs != NULL) {
                        found = fsop_get_root(vdev->fs);
                    }
                    else if (!vdev->mountable) {
                        vop_ref_inc(vdev->devnode);
                        found = vdev->devnode;
                    }
                    if (found != NULL) {
        /*
         * If DEVNAME names the device, and we get here, it
         * must have no fs and not be mountable. In this case,
         * we return the inode of device itself--node_store.
         */
                        ret = 0, *node_store = found;
                    }
                    else {
            /*
             * If we got here, the device specified by devname doesn't exist.
             */
                        ret = -E_NA_DEV;
                    }
                    break;
                }
        /*
         * If none of the above tests matched, we didn't name
         * any of the names of this device, so go on to the
         * next one. 
         */
            }
        }
        unlock_vdev_list();
    }
    return ret;
}
Beispiel #7
0
/* *
 * inode_init - initialize a inode structure
 * invoked by vop_init
 * */
void
inode_init(struct inode *node, const struct inode_ops *ops, struct fs *fs) {
    atomic_set(&(node->ref_count), 0);
    atomic_set(&(node->open_count), 0);
    node->in_ops = ops, node->in_fs = fs;
#ifdef UCONFIG_BIONIC_LIBC
	list_init(&(node->mapped_addr_list));
#endif //UCONFIG_BIONIC_LIBC
    vop_ref_inc(node);
}
Beispiel #8
0
/*
 * Get current directory as a inode.
 * 
 * We do not synchronize current->fs_struct->pwd, because it belongs exclusively
 * to its own process(or threads) with the holding lock.
 */
int
vfs_get_curdir(struct inode **dir_store) {
    struct inode *node;
    if ((node = get_cwd_nolock()) != NULL) {
        vop_ref_inc(node);
        *dir_store = node;
        return 0;
    }
    return -E_NOENT;
}
Beispiel #9
0
// 得到当前的目录所对应的inode
int
vfs_get_curdir(struct inode **dir_store) {
    struct inode *node;
    if ((node = get_cwd_nolock()) != NULL) {
        vop_ref_inc(node); // 增加对inode的ref_count计数
        *dir_store = node; // 记录下这个node
        return 0;
    }
    return -E_NOENT;
}
Beispiel #10
0
void filemap_dup_close(struct file *to, struct file *from)
{
	assert(to->status == FD_CLOSED && from->status == FD_CLOSED);
	to->pos = from->pos;
	to->readable = from->readable;
	to->writable = from->writable;
	struct inode *node = from->node;
	vop_ref_inc(node), vop_open_inc(node);
	to->node = node;
}
Beispiel #11
0
void filemap_dup(struct file *to, struct file *from)
{
	assert(to->status == FD_INIT && from->status == FD_OPENED);
	to->pos = from->pos;
	to->readable = from->readable;
	to->writable = from->writable;
	struct inode *node = from->node;
	vop_ref_inc(node), vop_open_inc(node);
	to->node = node;
	filemap_open(to);
}
Beispiel #12
0
//fs_array_dup - duplicate file 'from'  to file 'to'
void
fd_array_dup(struct file *to, struct file *from) {
    //cprintf("[fd_array_dup]from fd=%d, to fd=%d\n",from->fd, to->fd);
    assert(to->status == FD_INIT && from->status == FD_OPENED);
    to->pos = from->pos;
    to->readable = from->readable;
    to->writable = from->writable;
    struct inode *node = from->node;
    vop_ref_inc(node), vop_open_inc(node);
    to->node = node;
    fd_array_open(to);
}
Beispiel #13
0
int
sfs_getpath(struct inode *node, char *path, int maxlen){
  int ret, namelen;
  int pos = maxlen - 2;
  uint inum;
  char *ptr = path + maxlen;
  char namebuf[DIRSIZ];
  struct sfs_inode *sin = vop_info(node, sfs_inode);
  vop_ref_inc(node);
  while(1){
    struct inode *parent;
    if((parent = sfs_dirlookup(node, "..", 0)) == 0){
      goto failed;
    }
    inum = sin->inum;
    vop_ref_dec(node);
    if(node == parent){
      vop_ref_dec(node);
      break;
    }
    node = parent;
    sin = vop_info(node, sfs_inode);
    ret = sfs_inumtoname(node, inum, namebuf);
    if(ret != 0){
      goto failed;
    }
    if((namelen = strlen(namebuf) + 1) > pos){
      return -1;
    }
    pos -= namelen;
    ptr -= namelen;
    memcpy(ptr, namebuf, namelen -1);
    ptr[namelen -1] = '/';
  }
  namelen = maxlen - pos - 2;
  ptr = memmove(path + 5, ptr, namelen);
  ptr[-1] = '/';
  ptr[-2] = ':';
  ptr[-3] = 's';
  ptr[-4] = 'f';
  ptr[-5] = 's';
  ptr[namelen] = '\0';
  
  return 0;
failed:
  vop_ref_dec(node);
  return -1;
}
Beispiel #14
0
/*
 * lookup_sfs_nolock - according ino, find related inode
 *
 * NOTICE: le2sin, info2node MACRO
 */
static struct inode *
lookup_sfs_nolock(struct sfs_fs *sfs, uint32_t ino) {
    struct inode *node;
    list_entry_t *list = sfs_hash_list(sfs, ino), *le = list;
    while ((le = list_next(le)) != list) {
        struct sfs_inode *sin = le2sin(le, hash_link);
        if (sin->ino == ino) {
            node = info2node(sin, sfs_inode);
            if (vop_ref_inc(node) == 1) {
                sin->reclaim_count ++;
            }
            return node;
        }
    }
    return NULL;
}
Beispiel #15
0
int
vfs_get_bootfs(struct inode **node_store) {
    struct inode *node = NULL;
    if (bootfs_node != NULL) {
        lock_bootfs();
        {
            if ((node = bootfs_node) != NULL) {
                vop_ref_inc(bootfs_node);
            }
        }
        unlock_bootfs();
    }
    if (node == NULL) {
        return -E_NOENT;
    }
    *node_store = node;
    return 0;
}
Beispiel #16
0
int
dup_fs(struct fs_struct *to, struct fs_struct *from) {
    assert(to != NULL && from != NULL);
    assert(fs_count(to) == 0 && fs_count(from) > 0);
    if ((to->pwd = from->pwd) != NULL) {
        vop_ref_inc(to->pwd);
    }
    int i;
    struct file *to_file = to->filemap, *from_file = from->filemap;
    for (i = 0; i < FS_STRUCT_NENTRY; i ++, to_file ++, from_file ++) {
        if (from_file->status == FD_OPENED) {
            /* alloc_fd first */
            to_file->status = FD_INIT;
            filemap_dup(to_file, from_file);
        }
    }
    return 0;
}
Beispiel #17
0
static int
sfs_lookup(struct inode *node, char *path, struct inode **node_store) {
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    assert(*path != '\0' && *path != '/');
    vop_ref_inc(node);
    do {
        struct sfs_inode *sin = vop_info(node, sfs_inode);
        if (sin->din->type != SFS_TYPE_DIR) {
            vop_ref_dec(node);
            return -E_NOTDIR;
        }

        char *subpath;
  next:
        subpath = sfs_lookup_subpath(path);
        if (strcmp(path, ".") == 0) {
            if ((path = subpath) != NULL) {
                goto next;
            }
            break;
        }

        int ret;
        struct inode *subnode;
        if (strcmp(path, "..") == 0) {
            ret = sfs_load_parent(sfs, sin, &subnode);
        }
        else {
            if (strlen(path) > SFS_MAX_FNAME_LEN) {
                vop_ref_dec(node);
                return -E_TOO_BIG;
            }
            ret = sfs_lookup_once(sfs, sin, path, &subnode, NULL);
        }

        vop_ref_dec(node);
        if (ret != 0) {
            return ret;
        }
        node = subnode, path = subpath;
    } while (path != NULL);
    *node_store = node;
    return 0;
}
Beispiel #18
0
// 我们来看一下复制files_struct的函数dup_fs
int
dup_fs(struct files_struct *to, struct files_struct *from) {
//    cprintf("[dup_fs]\n");
    assert(to != NULL && from != NULL);
    assert(files_count(to) == 0 && files_count(from) > 0);
    if ((to->pwd = from->pwd) != NULL) {
        vop_ref_inc(to->pwd); // 增加引用就可以了
    }
    int i;
    struct file *to_file = to->fd_array, *from_file = from->fd_array;
    for (i = 0; i < FILES_STRUCT_NENTRY; i ++, to_file ++, from_file ++) {
        if (from_file->status == FD_OPENED) {
            /* alloc_fd first */
            to_file->status = FD_INIT;
            fd_array_dup(to_file, from_file);
        }
    }
    return 0;
}
Beispiel #19
0
/*
 * sfs_lookup - Parse path relative to the passed directory
 *              DIR, and hand back the inode for the file it
 *              refers to.
 */
static int
sfs_lookup(struct inode *node, char *path, struct inode **node_store) {
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    assert(*path != '\0' && *path != '/');
    vop_ref_inc(node);
    struct sfs_inode *sin = vop_info(node, sfs_inode);
    if (sin->din->type != SFS_TYPE_DIR) {
        vop_ref_dec(node);
        return -E_NOTDIR;
    }
    struct inode *subnode;
    int ret = sfs_lookup_once(sfs, sin, path, &subnode, NULL);

    vop_ref_dec(node);
    if (ret != 0) {
        return ret;
    }
    *node_store = subnode;
    return 0;
}
Beispiel #20
0
static void
lookup_pipe_nolock(struct pipe_fs *pipe, const char *name, struct inode **rnode_store, struct inode **wnode_store) {
    list_entry_t *list = &(pipe->pipe_list), *le = list;
    *rnode_store = *wnode_store = NULL;
    while ((le = list_next(le)) != list) {
        struct pipe_inode *pin = le2pin(le, pipe_link);
        if (strcmp(pin->name, name) == 0) {
            struct inode *node = info2node(pin, pipe_inode);
            switch (pin->pin_type) {
            case PIN_RDONLY: assert(*rnode_store == NULL); *rnode_store = node; break;
            case PIN_WRONLY: assert(*wnode_store == NULL); *wnode_store = node; break;
            default:
                panic("unknown pipe_inode type %d.\n", pin->pin_type);
            }
            if (vop_ref_inc(node) == 1) {
                pin->reclaim_count ++;
            }
        }
    }
}
Beispiel #21
0
static struct inode *
pipe_get_root(struct fs *fs) {
    struct pipe_fs *pipe = fsop_info(fs, pipe);
    vop_ref_inc(pipe->root);
    return pipe->root;
}