/* * sfs_getdirentry - according to the iob->io_offset, calculate the dir entry's slot in disk block, get dir entry content from the disk */ static int sfs_getdirentry(struct inode *node, struct iobuf *iob) { struct sfs_disk_entry *entry; if ((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, slot; off_t offset = iob->io_offset; if (offset < 0 || offset % sfs_dentry_size != 0) { kfree(entry); return -E_INVAL; } if ((slot = offset / sfs_dentry_size) > sin->din->blocks) { kfree(entry); return -E_NOENT; } lock_sin(sin); if ((ret = sfs_getdirentry_sub_nolock(sfs, sin, slot, entry)) != 0) { unlock_sin(sin); goto out; } unlock_sin(sin); ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL); out: kfree(entry); return ret; }
static int sfs_getdirentry(struct inode *node, struct iobuf *iob) { struct sfs_disk_entry *entry; if ((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); off_t offset = iob->io_offset; if (offset < 0 || offset % sfs_dentry_size != 0) { kfree(entry); return -E_INVAL; } int ret, slot = offset / sfs_dentry_size; if (slot >= sin->din->dirinfo.slots + 2) { kfree(entry); return -E_NOENT; } switch (slot) { case 0: strcpy(entry->name, "."); break; case 1: strcpy(entry->name, ".."); break; default: if ((ret = trylock_sin(sin)) != 0) { goto out; } ret = sfs_getdirentry_sub_nolock(sfs, sin, slot - 2, entry); unlock_sin(sin); if (ret != 0) { goto out; } } ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL); out: kfree(entry); return ret; }
static int sfs_getdirentry(struct inode *node, struct iobuf *iob) { struct sfs_disk_entry *entry; if ((entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) { // kprintf("%s %s %d -E_NO_MEM\n", __FILE__, __func__, __LINE__); 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, slot; off_t offset = iob->io_offset; if (offset < 0 || offset % sfs_dentry_size != 0) { // kprintf("%s %s %d -E_INVAL\n", __FILE__, __func__, __LINE__); kfree(entry); return -E_INVAL; } if ((slot = offset / sfs_dentry_size) > sin->din->blocks) { // kprintf("%s %s %d -E_NOENT\n", __FILE__, __func__, __LINE__); kfree(entry); return -E_NOENT; } lock_sin(sin); if ((ret = sfs_getdirentry_sub_nolock(sfs, sin, slot, entry)) != 0) { unlock_sin(sin); // kprintf("%s %s %d can not find!!! slot is %d\n", __FILE__, __func__, __LINE__, slot); goto out; } unlock_sin(sin); // kprintf("sfs_getdirentry\n"); ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL); out: kfree(entry); return ret; }