// Look up and return the inode for a path name. // If parent != 0, return the inode for the parent and copy the final // path element into name, which must have room for DIRSIZ bytes. static struct inode* namex(char *path, int nameiparent, char *name) { struct inode *ip, *next; if(*path == '/') ip = iget(ROOTDEV, ROOTINO); else ip = idup(proc->cwd); while((path = skipelem(path, name)) != 0){ ilock(ip); if(ip->type != T_DIR){ iunlockput(ip); return 0; } if(nameiparent && *path == '\0'){ // Stop one level early. iunlock(ip); return ip; } if((next = dirlookup(ip, name, 0)) == 0){ iunlockput(ip); return 0; } iunlockput(ip); ip = next; } if(nameiparent){ iput(ip); return 0; } return ip; }
// Look up and return the inode for a path name. // If parent != 0, return the inode for the parent and copy the final // path element into name, which must have room for DIRSIZ bytes. static struct inode* namex(struct inode *ip, char *path, int nameiparent, char *name) { struct inode *next; struct sfs_inode *sinp; while((path = skipelem(path, name)) != 0){ sfs_ilock(ip); sinp = vop_info(ip, sfs_inode); if(sinp->type != T_DIR){ sfs_iunlockput(ip); return 0; } if(nameiparent && *path == '\0'){ // Stop one level early. sfs_iunlock(ip); return ip; } if((next = sfs_dirlookup(ip, name, 0)) == 0){ sfs_iunlockput(ip); return 0; } sfs_iunlockput(ip); ip = next; } if(nameiparent){ sfs_iput(ip); return 0; } return ip; }
/** * Look up and return the inode for a path name. * If nameiparent is true, return the inode for the parent and copy the final * path element into name, which must have room for DIRSIZ bytes. * Returns 0 in the case of error. */ static struct inode* namex(char *path, bool nameiparent, char *name) { struct inode *ip; struct inode *next; // If path is a full path, get the pointer to the root inode. Otherwise get // the inode corresponding to the current working directory. if(*path == '/'){ ip = inode_get(ROOTDEV, ROOTINO); } else { ip = inode_dup((struct inode*) tcb_get_cwd(get_curid())); } while((path = skipelem(path, name)) != 0){ inode_lock(ip); if(ip -> type != T_DIR) { return 0; } if(nameiparent && *path == 0) { inode_unlock(ip); return ip; } next = dir_lookup(ip, name, 0); inode_unlockput(ip); ip = next; } if(nameiparent){ inode_put(ip); return 0; } return ip; }
// Look up and return the inode for a path name. // If parent != 0, return the inode for the parent and copy the final // path element into name, which must have room for DIRSIZ bytes. static struct inode* namex(char *path, int nameiparent, char *name, int mode) // mode - 0-reference 1-dereference { struct inode *ip, *next; char buf[64]; if(*path == '/') ip = iget(ROOTDEV, ROOTINO); else ip = idup(proc->cwd); while((path = skipelem(path, name)) != 0){ ilock(ip); if(ip->type != T_DIR){ iunlockput(ip); return 0; } if(nameiparent && *path == '\0'){ // Stop one level early. iunlock(ip); return ip; } if((next = dirlookup(ip, name, 0)) == 0){ iunlockput(ip); return 0; } iunlockput(ip); if(mode || *path!='\0') { next= recursive_readlink(buf,next, 16, 0); } ip = next; } if(nameiparent){ iput(ip); return 0; } return ip; }
// Look up and return the inode for a path name. // If parent != 0, return the inode for the parent and copy the final // path element into name, which must have room for DIRSIZ bytes. static struct inode* _namei(char *path, int parent, char *name) { //cprintf("Path: %s\n", path); struct inode *ip, *next; if(*path == '/') ip = iget(ROOTDEV, 1); else ip = idup(cp->cwd); //cprintf("cp name: %s\n", cp->name); while((path = skipelem(path, name)) != 0){ ilock(ip); if(ip->type != T_DIR){ iunlockput(ip); //cprintf("HERE\n"); return 0; } if(parent && *path == '\0'){ // Stop one level early. iunlock(ip); //cprintf("HERE3\n"); return ip; } if((next = dirlookup(ip, name, 0)) == 0){ iunlockput(ip); //cprintf("HERE1\n"); return 0; } iunlockput(ip); ip = next; } if(parent){ iput(ip); //cprintf("HERE2\n"); return 0; } //cprintf("HERE4-2: %d\n", ip); return ip; }
static struct inode *_path2inode(char *path, int parent, char *name) { struct inode *ip, *next; ip = 0; if (*path == '/') { ip = iget(ROOT_DEV, ROOT_INO); } else { ip = idup(proc->cwd); } while ((path = skipelem(path, name)) != 0) { /* read from disk */ ilock(ip); if (!S_ISDIR(ip->mode)) { iunlockput(ip); return 0; } if (parent && *path == '\0') { iunlock(ip); return ip; } if ((next = dir_lookup(ip, name, 0)) == 0) { iunlockput(ip); return 0; } iunlockput(ip); ip = next; } if (parent) { iput(ip); return 0; } return ip; }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off, bin_inum, tests_inum, sbin_inum; //dir_inum struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2) { fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); if(fsfd < 0) { perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2 + nlog); sb.bmapstart = xint(2 + nlog + ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) { wsect(i, zeroes); } memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); // create /bin folder bin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "bin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "."); iappend(bin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(bin_inum, &de, sizeof(de)); // create /dev folder inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "dev"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "."); iappend(inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(inum, &de, sizeof(de)); // create /sbin folder sbin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "sbin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "."); iappend(sbin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(sbin_inum, &de, sizeof(de)); // create /tests folder tests_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "tests"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "."); iappend(tests_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(tests_inum, &de, sizeof(de)); for(i = 2; i < argc; i++) { printf("argv[i]: %s and index: %s\n", argv[i], index(argv[i], '/')); //assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0) { perror(argv[i]); exit(1); } if(index(argv[i], '/') != 0) { char foldername[256]; char *progname = malloc(sizeof(char) * 256); strcpy(progname, skipelem(argv[i], foldername)); if(progname[0] == '_') { progname++; } if(strcmp(foldername, "bin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "tests") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(tests_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "sbin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(sbin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "docs") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "shell") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else { printf("\nERROR: Found folder other than bin and tests: %s\n", foldername); exit(1); } } else { // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') { ++argv[i]; } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off / BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
//part 1 - signature change, and de-referencing symbolic links to the correct inode struct inode* namex(char *path, int nameiparent, char *name, struct inode *prev, int loopCount,int noDeRef) { struct inode *ip, *next; char buf[512]; // part 1 - prevent loop in symbolic links if(loopCount > 16) return 0; if(*path == '/') { ip = iget(ROOTDEV, ROOTINO); } else if(prev) { ip = idup(prev); } else { ip = idup(proc->cwd); } while( (path = skipelem(path, name)) != 0 ) { ilock(ip); if(ip->type != T_DIR){ iunlockput(ip); return 0; } if(nameiparent && *path == '\0'){ // Stop one level early. iunlock(ip); return ip; } if((next = dirlookup(ip, name, 0)) == 0){ iunlockput(ip); return 0; } if(noDeRef) { iunlockput(ip); } else { iunlock(ip); //part 1 ilock(next); if(next->type == T_SYMLINK) { if(readi(next, buf, 0, sizeof(buf)) != next->size) { iunlockput(ip); return 0; } buf[next->size] = 0; iunlock(next); next = namex(buf, 0, name, ip, loopCount++,0); } else { iunlock(next); } // End part 1 iput(ip); } ip = next; } if(nameiparent) { iput(ip); return 0; } return ip; }
// Same as filereadlink, but doesn't dereference the final path element int filereadlinki(const char *pathname, char *buf, int bufsiz) { int loops_left = MAX_SYMLINK_LOOPS; int l; char name[DIRSIZ+1]; char result[MAXPATH]; int result_off; char origpath[MAXPATH]; char *origpath_p; struct inode* ip; if(*pathname == '\0'){ return -1; } if(pathname[0] == '/' && pathname[1] == '\0') { buf[0] = '/'; buf[1] = '\0'; return 2; } strncpy(origpath, pathname, MAXPATH); restart: result_off = 0; if(origpath[0] == '/'){ result[0] = '/'; result_off = 1; } result[result_off] = '\0'; origpath_p = origpath; for(;;){ origpath_p = skipelem(origpath_p, name); if(!origpath_p){ return -1; } if(*origpath_p == '\0'){ // Last element // `name' contains the filename safestrcpy(&result[result_off], name, MAXPATH); result_off += strlen(name); result[result_off] = '\0'; if(bufsiz < result_off + 1){ return -1; } else { safestrcpy(buf, result, MAXPATH); return result_off; } } else { safestrcpy(&result[result_off], name, MAXPATH); result_off += strlen(name); result[result_off] = '\0'; ip = namei(result); if(!ip){ return -1; } ilock(ip); if(ip->type == T_FILE || ip->type == T_DEV){ // Tried to traverse through a file/dev as if it was a directory return -1; } else if(ip->type == T_DIR) { result[result_off] = '/'; result_off++; result[result_off] = '\0'; } else if(ip->type == T_SYMLINK) { result_off -= strlen(name); l = readi(ip, &result[result_off], 0, MAXPATH); iunlock(ip); result[result_off+l] = '/'; safestrcpy(&result[result_off+l+1], origpath_p, MAXPATH); if(result[result_off] == '/') { // Absolute symlink safestrcpy(origpath, &result[result_off], MAXPATH); } else { safestrcpy(origpath, result, MAXPATH); } loops_left--; if(loops_left == 0){ return -1; } goto restart; } else { panic("filereadlink: unknown inode type"); } iunlock(ip); } } }
// Look up and return the inode for a path name. // If parent != 0, return the inode for the parent and copy the final // path element into name, which must have room for DIRSIZ bytes. // Must be called inside a transaction since it calls iput(). static struct inode* namex(char* path, int nameiparent, int ignoreMounts, char* name) { // cprintf("namex \n"); struct inode* ip, *next; // cprintf("path %s nameparent %d , name %s bootfrom %d\n", path, nameiparent, name, bootfrom); if (*path == '/') ip = iget(ROOTDEV, ROOTINO, bootfrom); else ip = idup(proc->cwd); while ((path = skipelem(path, name)) != 0) { //cprintf("namex path %s \n",path); ilock(ip); if (ip->type != T_DIR) { iunlockput(ip); return 0; } if (nameiparent && *path == '\0') { // Stop one level early. // cprintf("fileread \n"); iunlock(ip); return ip; } if ((next = dirlookup(ip, name, 0)) == 0) { // cprintf("next is zero \n"); iunlockput(ip); return 0; } iunlockput(ip); ilock(next); // cprintf("next %d , type %d major %d minor %d \n",next->inum,next->type,next->major,next->minor); if (!ignoreMounts && next->type == T_DIR && next->major != 0 && next->major != MOUNTING_POINT) { // cprintf("major used ,we are f****d \n"); } // handle mounting points if (!ignoreMounts && next->type == T_DIR && next->major == MOUNTING_POINT) { // cprintf("got into condition \n"); iunlock(next); // iunlockput(ip); uint partitionNumnber = next->minor; ip = iget(ROOTDEV, 1, partitionNumnber); } else{ iunlock(next); // testing ip = next; } } if (nameiparent) { iput(ip); return 0; } // cprintf("ip returned is %d \n", ip->inum); return ip; }