// 设置当前的目录 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; }
int sfs_unlink(struct inode *dp, char *name){ struct inode *ip; struct sfs_dirent de; uint off; vop_ilock(dp); // Cannot unlink "." or "..". if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0) goto bad; if((ip = vop_dirlookup(dp, name, &off)) == 0) goto bad; vop_ilock(ip); if(vop_getnlink(ip) < 1) panic("unlink: nlink < 1"); if(vop_gettype(ip) == T_DIR && !vop_isdirempty(ip)){ vop_iunlockput(ip); goto bad; } memset(&de, 0, sizeof(de)); if(vop_write(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) panic("unlink: writei"); if(vop_gettype(ip) == T_DIR){ vop_link_dec(dp); vop_iupdate(dp); } vop_iunlockput(dp); vop_link_dec(ip); vop_iupdate(ip); vop_iunlockput(ip); return 0; bad: vop_iunlockput(dp); return -1; }
/* * sfs_fstat - Return nlinks/block/size, etc. info about a file. The pointer is a pointer to struct stat; */ static int sfs_fstat(struct inode *node, struct stat *stat) { int ret; memset(stat, 0, sizeof(struct stat)); if ((ret = vop_gettype(node, &(stat->st_mode))) != 0) { return ret; } struct sfs_disk_inode *din = vop_info(node, sfs_inode)->din; stat->st_nlinks = din->nlinks; stat->st_blocks = din->blocks; stat->st_size = din->size; return 0; }
/* * Called for fstat(). * Set the type and the size. * The link count for a device is always 1. */ static int dev_fstat(struct inode *node, struct stat *stat) { int ret; memset(stat, 0, sizeof(struct stat)); if ((ret = vop_gettype(node, &(stat->st_mode))) != 0) { return ret; } struct device *dev = vop_info(node, device); stat->st_nlinks = 1; stat->st_blocks = dev->d_blocks; stat->st_size = stat->st_blocks * dev->d_blocksize; return 0; }
static int pipe_inode_fstat(struct inode *node, struct stat *stat) { int ret; memset(stat, 0, sizeof(struct stat)); if ((ret = vop_gettype(node, &(stat->st_mode))) != 0) { return ret; } struct pipe_inode *pin = vop_info(node, pipe_inode); stat->st_nlinks = 1; stat->st_blocks = 0; stat->st_size = pipe_state_size(pin->state, pin->pin_type == PIN_WRONLY); return 0; }
static int sfs_fstat(struct inode *node, struct stat *stat) { int ret; memset(stat, 0, sizeof(struct stat)); if ((ret = vop_gettype(node, &(stat->st_mode))) != 0) { return ret; } struct sfs_disk_inode *din = vop_info(node, sfs_inode)->din; stat->st_nlinks = din->nlinks; stat->st_blocks = din->blocks; if (din->type != SFS_TYPE_DIR) { stat->st_size = din->fileinfo.size; } else { stat->st_size = (din->dirinfo.slots + 2) * sfs_dentry_size; } return 0; }