static int ramfs_unlink(vnode_t *dir, const char *name, size_t namelen) { vnode_t *vn; int ret; off_t i; ramfs_dirent_t *entry; ret = ramfs_lookup(dir, name, namelen, &vn); KASSERT(0 == ret); KASSERT(!S_ISDIR(vn->vn_mode)); /* And then remove the entry from the directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (name_match(entry->rd_name, name, namelen)) { entry->rd_name[0] = '\0'; break; } } VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t); VNODE_TO_RAMFSINODE(vn)->rf_linkcount--; vput(vn); return 0; }
static int ramfs_readdir(vnode_t *dir, off_t offset, struct dirent *d) { int ret = 0; ramfs_dirent_t *dir_entry, *targ_entry; KASSERT(S_ISDIR(dir->vn_mode)); KASSERT(0 == offset % sizeof(ramfs_dirent_t)); dir_entry = VNODE_TO_DIRENT(dir); dir_entry = (ramfs_dirent_t *)(((char *)dir_entry) + offset); targ_entry = dir_entry; while ((offset < (off_t)(RAMFS_MAX_DIRENT * sizeof(ramfs_dirent_t))) && (!targ_entry->rd_name[0])) { ++targ_entry; offset += sizeof(ramfs_dirent_t); } if (offset >= (off_t)(RAMFS_MAX_DIRENT * sizeof(ramfs_dirent_t))) return 0; ret = sizeof(ramfs_dirent_t) + (targ_entry - dir_entry) * sizeof(ramfs_dirent_t); d->d_ino = targ_entry->rd_ino; d->d_off = 0; /* unused */ strncpy(d->d_name, targ_entry->rd_name, NAME_LEN - 1); d->d_name[NAME_LEN - 1] = '\0'; return ret; }
static int ramfs_link(vnode_t *oldvnode, vnode_t *dir, const char *name, size_t name_len) { vnode_t *vn; off_t i; ramfs_dirent_t *entry; KASSERT(oldvnode->vn_fs == dir->vn_fs); 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; } /* Set entry in parent */ entry->rd_ino = oldvnode->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); /* Increase linkcount */ VNODE_TO_RAMFSINODE(oldvnode)->rf_linkcount++; return 0; }
static int ramfs_rmdir(vnode_t *dir, const char *name, size_t name_len) { vnode_t *vn; int ret; off_t i; ramfs_dirent_t *entry; KASSERT(!name_match(".", name, name_len) && !name_match("..", name, name_len)); if ((ret = ramfs_lookup(dir, name, name_len, &vn)) != 0) return ret; if (!S_ISDIR(vn->vn_mode)) { vput(vn); return -ENOTDIR; } /* We have to make sure that this directory is empty */ entry = VNODE_TO_DIRENT(vn); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (!strcmp(entry->rd_name, ".") || !strcmp(entry->rd_name, "..")) continue; if (entry->rd_name[0]) { vput(vn); return -ENOTEMPTY; } } /* Finally, remove the entry from the parent directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (name_match(entry->rd_name, name, name_len)) { entry->rd_name[0] = '\0'; break; } } VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t); VNODE_TO_RAMFSINODE(vn)->rf_linkcount--; vput(vn); 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; }
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_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; }