/* * namei() * * is used by most simple commands to get the inode of a specified name. * Open, link etc use their own routines, but this is enough for things * like 'chmod' etc. */ struct m_inode * namei(const char * pathname) { const char * basename; int inr,dev,namelen; struct m_inode * dir; struct buffer_head * bh; struct dir_entry * de; if (!(dir = dir_namei(pathname,&namelen,&basename))) return NULL; if (!namelen) /* special case: '/usr/' etc */ return dir; bh = find_entry(&dir,basename,namelen,&de); if (!bh) { iput(dir); return NULL; } inr = de->inode; dev = dir->i_dev; brelse(bh); iput(dir); dir=iget(dev,inr); if (dir) { dir->i_atime=CURRENT_TIME; dir->i_dirt=1; } return dir; }
int do_unlink(char *name) { char *basename; int namelen; struct m_inode *dir,*inode; // struct buffer_head *bh; struct dir_entry *de; if(!(dir = dir_namei(name,&basename,&namelen))) { //no such file or direntry return -ENOENT; } if(!namelen) { iput(dir); return -ENOENT; } //删除目录项 if((del_entry(dir,basename,namelen,&de)) != 0) { printk("no such file"); iput(dir); return -ENOENT; } if(!(inode = iget(dir->i_dev,de->inode_num))) { iput(dir); return -ENOENT; } //not permit to del direntry if(S_ISDIR(inode->i_mode)) { iput(inode); iput(dir); return -EPERM; } if(--(inode->i_count)) { printk("deleting using file\n"); return -EMLINK; } de->inode_num = 0; inode->i_dirt = 1; iput(inode); iput(dir); printk("delete file successful\n"); return 0; }
static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base, const char *pathname, size_t pathlen, int follow, int link_count, char *buf, ext2_ino_t *res_inode) { const char *base_name; int namelen; ext2_ino_t dir, inode; errcode_t retval; #ifdef NAMEI_DEBUG printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n", root, base, pathlen, pathname, link_count); #endif retval = dir_namei(fs, root, base, pathname, pathlen, link_count, buf, &base_name, &namelen, &dir); if (retval) return retval; if (!namelen) { *res_inode=dir; return 0; } retval = ext2fs_lookup (fs, dir, base_name, namelen, buf, &inode); if (retval) return retval; if (follow) { retval = follow_link(fs, root, dir, inode, link_count, buf, &inode); if (retval) return retval; } #ifdef NAMEI_DEBUG printf("open_namei: (link_count=%d) returns %lu\n", link_count, inode); #endif *res_inode = inode; return 0; }
/* * open_namei() * * namei for open - this is in fact almost the whole open-routine. */ int open_namei(const char * pathname, int flag, int mode, struct m_inode ** res_inode) { const char * basename; int inr,dev,namelen; struct m_inode * dir, *inode; struct buffer_head * bh; struct dir_entry * de; if ((flag & O_TRUNC) && !(flag & O_ACCMODE)) flag |= O_WRONLY; mode &= 0777 & ~current->umask; mode |= I_REGULAR; if (!(dir = dir_namei(pathname,&namelen,&basename))) return -ENOENT; if (!namelen) { /* special case: '/usr/' etc */ if (!(flag & (O_ACCMODE|O_CREAT|O_TRUNC))) { *res_inode=dir; return 0; } iput(dir); return -EISDIR; } bh = find_entry(&dir,basename,namelen,&de); if (!bh) { if (!(flag & O_CREAT)) { iput(dir); return -ENOENT; } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; } inode->i_mode = mode; bh = add_entry(dir,basename,namelen,&de); if (!bh) { inode->i_nlinks--; iput(inode); iput(dir); return -ENOSPC; } bh->b_dirt = 1; brelse(bh); iput(dir); *res_inode = inode; return 0; } inr = de->inode; dev = dir->i_dev; brelse(bh); iput(dir); if (flag & O_EXCL) return -EEXIST; if (!(inode=iget(dev,inr))) return -EACCES; if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) || !permission(inode,ACC_MODE(flag))) { iput(inode); return -EPERM; } inode->i_atime = CURRENT_TIME; if (flag & O_TRUNC) truncate(inode); *res_inode = inode; return 0; }
static errcode_t open_namei(cmfs_filesys *fs, uint64_t root, uint64_t base, const char *pathname, size_t pathlen, int follow, int link_count, char *buf, uint64_t *res_inode) { const char *basename; int namelen; uint64_t dir, inode; errcode_t ret; #ifdef NAMIE_DEBUG printf("%s:%d root=%lu, dir=%lu, path=%*s, lc=%d\n", __func__, __LINE__, root, base, pathlen, pathname, link_count); #endif ret = dir_namei(fs, root, base, pathname, pathlen, link_count, buf, &basename, &namelen, &dir); if (ret) return ret; /* special case: '/usr/' etc */ if (!namelen) { *res_inode = dir; return 0; } ret = cmfs_lookup(fs, dir, basename, namelen, buf, &inode); if (ret) return ret; if (follow) { ret = follow_link(fs, root, dir, inode, link_count, buf, &inode); if (ret) return ret; } #ifdef NAMEI_DEBUG printf("%s:%d (link_count=%d) returns %lu\n", link_count, inode); #endif *res_inode = inode; return 0; }