static int ramfs_mknod(struct vnode *dir, const char *name, size_t name_len, int mode, devid_t devid) { vnode_t *vn; off_t i; ramfs_dirent_t *entry; KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn)); /* Look for space in the directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (!entry->rd_name[0]) break; } if (i == RAMFS_MAX_DIRENT) { return -ENOSPC; } int ino; if (S_ISCHR(mode)) { if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_CHR, devid))) { return ino; } } else if (S_ISBLK(mode)) { if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_BLK, devid))) { return ino; } } else { panic("Invalid mode!\n"); } /* Set entry in directory */ entry->rd_ino = ino; strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1)); entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0'; VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t); return 0; }
static int ramfs_mkdir(vnode_t *dir, const char *name, size_t name_len) { vnode_t *vn; off_t i; ramfs_dirent_t *entry; dbg(DBG_INIT,"RAMFS_MKDIR before KASSERT %s\n",name); KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn)); /* Look for space in the directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (!entry->rd_name[0]) break; } if (i == RAMFS_MAX_DIRENT) { return -ENOSPC; } /* Allocate an inode */ int ino; if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_DIR, 0))) { return ino; } /* Set entry in parent */ entry->rd_ino = ino; strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1)); entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0'; VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t); /* Set up '.' and '..' in the directory */ entry = (ramfs_dirent_t *) VNODE_TO_RAMFS(dir)->rfs_inodes[ino]->rf_mem; entry->rd_ino = ino; strcpy(entry->rd_name, "."); entry++; entry->rd_ino = dir->vn_vno; strcpy(entry->rd_name, ".."); /* Increase inode size accordingly */ VNODE_TO_RAMFS(dir)->rfs_inodes[ino]->rf_size = 2 * sizeof(ramfs_dirent_t); return 0; }
int ramfs_mount(struct fs *fs) { /* Allocate filesystem */ ramfs_t *rfs = kmalloc(sizeof(ramfs_t)); if (NULL == rfs) return -ENOMEM; memset(rfs->rfs_inodes, 0, sizeof(rfs->rfs_inodes)); fs->fs_i = rfs; fs->fs_op = &ramfs_ops; /* Set up root inode */ int root_ino; if (0 > (root_ino = ramfs_alloc_inode(fs, RAMFS_TYPE_DIR, 0))) { return root_ino; } KASSERT(0 == root_ino); ramfs_inode_t *root = rfs->rfs_inodes[root_ino]; /* Set up '.' and '..' in the root directory */ ramfs_dirent_t *rootdent = (ramfs_dirent_t *) root->rf_mem; rootdent->rd_ino = 0; strcpy(rootdent->rd_name, "."); rootdent++; rootdent->rd_ino = 0; strcpy(rootdent->rd_name, ".."); /* Increase root inode size accordingly */ root->rf_size = 2 * sizeof(ramfs_dirent_t); /* Put the root in the inode table */ rfs->rfs_inodes[0] = root; /* And vget the root vnode */ fs->fs_root = vget(fs, 0); return 0; }
static int ramfs_create(vnode_t *dir, const char *name, size_t name_len, vnode_t **result) { vnode_t *vn; off_t i; ramfs_dirent_t *entry; KASSERT(0 != ramfs_lookup(dir, name, name_len, &vn)); /* Look for space in the directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (!entry->rd_name[0]) break; } if (i == RAMFS_MAX_DIRENT) { return -ENOSPC; } /* Allocate an inode */ int ino; if (0 > (ino = ramfs_alloc_inode(dir->vn_fs, RAMFS_TYPE_DATA, 0))) { return ino; } /* Get a vnode, set entry in directory */ vn = vget(dir->vn_fs, (ino_t) ino); entry->rd_ino = vn->vn_vno; strncpy(entry->rd_name, name, MIN(name_len, NAME_LEN - 1)); entry->rd_name[MIN(name_len, NAME_LEN - 1)] = '\0'; VNODE_TO_RAMFSINODE(dir)->rf_size += sizeof(ramfs_dirent_t); *result = vn; return 0; }