//This tests the rmdir function //The first test removes an emptry dir and checks to make sure it cannot get the ino of the deleted dirname //If it gets the ino, it must not have been deleted and returns 0. //The secind test atempts to remove a non empty dir. It attempts to get the ino. //If the ino it gets is not the expected ino of the non-removed directory it returns 0; int rmdirTest() { MINODE *test_mip = running->cwd; INODE *ip = NULL; int ino = 0; int flag = 0; int actual = 0; int expected1 = 0; int expected2 = 12; strcpy(pathname, ""); cd(pathname); test_mip = running->cwd; printf("\n\n-------- TESTING RMDIR FUNCTION --------\n\n"); printf("Testing >rmdir Testdir1\n"); strcpy(pathname, "Testdir1"); remove_dir(pathname); printf("Getting ino on Testdir1\n"); strcpy(pathname, "Testdir1"); actual = getino(test_mip, pathname); printf("\nExpected ino = %d\n", expected1); printf("Actual ino = %d\n", actual); if (expected1 != actual) { printf("TEST FAILED!\n\n"); flag = 1; } else printf("TEST PASSED!\n\n"); //This remove should not happen because X is not empty. printf("Testing >rmdir X\n"); strcpy(pathname, "X"); remove_dir(pathname); printf("Getting ino on X\n"); strcpy(pathname, "X"); actual = getino(test_mip, pathname); printf("\nExpected ino = %d\n", expected2); printf("Actual ino = %d\n", actual); if (expected2 != actual) { printf("TEST FAILED!\n\n"); flag = 1; } else printf("TEST PASSED!\n\n"); if (flag == 1) { printf("RMDIR TESTS FAILED!\n\n\n"); } else printf("ALL RMDIR TESTS PASSED!\n\n\n"); return 1; }
//This tests touch and creat //First test makes sure the mtime changes on a file that exists. //Returns 0 if the time isnt greater than what it was before. //Second test touches a file that doesnt exits, and therefore makes one. //Checks the inode of the new file, and if isn't what is expected, returns zero. //This second test checks both if touch and creat are working. int touchTest() { MINODE *test_mip = running->cwd; INODE *ip = NULL; int ino = 0; int old = 0; int expected1 = 28; strcpy(pathname, ""); cd(pathname); test_mip = running->cwd; printf("\n\n-------- TESTING TOUCH FUNCTION --------\n\n"); strcpy(pathname, "tiny"); ino = getino(test_mip, pathname); test_mip = iget(dev, ino); ip = &test_mip->INODE; old = ip->i_mtime; printf("tiny's current mtime = %d\n", ip->i_mtime); printf("Testing >touch tiny\n"); strcpy(pathname, "tiny"); touch_file(pathname); printf("tiny's new mtime = %d\n", ip->i_mtime); if(ip->i_mtime > old) printf("TEST PASSED!\n\n"); else { printf("TEST FAILED!\n\n"); return 0; } test_mip = running->cwd; printf("Testing >touch newfile\n"); strcpy(pathname, "newfile"); touch_file(pathname); strcpy(pathname, "newfile"); ino = getino(test_mip, pathname); printf("Expected ino of newfile = %d\n", expected1); printf("Actual ino of newfile = %d\n", ino); if (ino != expected1) { printf("TEST FAILED!\n\n"); return 0; } printf("TEST PASSED!\n\n"); printf("\nALL TOUCH TESTS PASSED!\n\n\n"); return 1; }
// Hard link old file to new file // NOTE: Links cannot be across different devices (would have to check for level 3) // SOURCE: http://www.eecs.wsu.edu/~cs360/link.html int link(char *old_pathname, char *new_pathname) { int dev, old_ino, new_ino, new_pino; MINODE *old_mip, *new_mip, *new_pmip; char new_pathname_copy_1[256], new_pathname_copy_2[256], *new_dir_name, *new_base_name; // Get running device if (old_pathname[0] == '/') dev = root->dev; else dev = running->cwd->dev; // Old pathname inode old_ino = getino(dev, old_pathname); old_mip = iget(dev, old_ino); // Check if old file is not dir if (is_dir_file(old_mip)) return EXIT_FAILURE; // Splitup new pathname strcpy(new_pathname_copy_1, new_pathname); strcpy(new_pathname_copy_2, new_pathname); new_dir_name = dirname(new_pathname_copy_1); new_base_name = basename(new_pathname_copy_2); // Does new parent exist and is a directory? new_pino = getino(dev, new_dir_name); if (new_pino < 0) return EXIT_FAILURE; new_pmip = iget(dev, new_pino); if (new_pmip->INODE.i_mode != DIR_MODE) return EXIT_FAILURE; // Does new file already exist? new_ino = getino(dev, new_pathname); if (new_ino >= 0) return EXIT_FAILURE; printf(YELLOW "\t...LINK(%s, %s)" RESET ": <GOOD> New file parent dir '%s' exists, but internal (new) file '%s' does not\n", old_pathname, new_pathname, new_dir_name, new_base_name); // Create new entry (file) in dir (= new_pino) with inode number (= old_ino) mylinkfile(new_pmip, old_ino, new_base_name); // Incrememnt i_links_count of inode (= old_mip) by 1 old_mip->INODE.i_links_count += 1; old_mip->dirty = 1; iput(old_mip); /// TODO: See if I have to link the new file to the old file's inode structure? return EXIT_SUCCESS; }
/* ------------------------------------------------------------- * do_stat: print all important inode info for the path INODE * (1) get INODE of path into a minode[] table * (2) print all important info * * Note: This is the lazy way. KC's recommended way utilizes * the stat struct --------------------------------------------------------------*/ void do_stat(char* path) { MINODE* dir; char timebuf[256]; int ino; int dev = running->cwd->dev; //(1) get INODE of path into a minode[table] ino = getino(&dev, path); // get ino dir = iget(dev, ino); // get MINODE* if(dir == NULL) { printf("Error: unable to stat %s\n", path); return; } // Copy dir's modified time into timebuf ctime_r(&dir->INODE.i_mtime, timebuf); timebuf[24] = 0; // add NULL terminator printf("-------------------------------------------------------\n"); printf("file: %s\n", Basename(path)); printf("dev: %d\t\tinode number: %i\tmode:%3x\n", dir->dev, dir->ino, dir->INODE.i_mode); printf("uid: %i\tgid: %i\tlink count: %d\n", running->uid, running->gid, dir->INODE.i_links_count); printf("size: %d\t\t%5s\n", dir->INODE.i_size, timebuf); printf("-------------------------------------------------------\n"); iput(dir); }
/* * Determine if given inode should be dumped */ void mapfileino(ino_t ino, int64_t *tapesize, int *dirskipped) { int mode; union dinode *dp; dp = getino(ino, &mode); if (mode == 0) return; /* * Skip WAPBL log file inodes. */ if (DIP(dp, di_flags) & SF_LOG) return; SETINO(ino, usedinomap); if (mode == IFDIR) SETINO(ino, dumpdirmap); if (CHECKNODUMP(dp) && (DIP(dp, di_mtime) >= spcl.c_ddate || DIP(dp, di_ctime) >= spcl.c_ddate)) { SETINO(ino, dumpinomap); if (mode != IFREG && mode != IFDIR && mode != IFLNK) *tapesize += 1; else *tapesize += blockest(dp); return; } if (mode == IFDIR) { if (!CHECKNODUMP(dp)) CLRINO(ino, usedinomap); *dirskipped = 1; } }
/* * Clear the flag bits so the journal can be removed. */ static void journal_clear(void) { struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; ino_t ino; int mode; void *ip; ino = journal_findfile(); if (ino == (ino_t)-1 || ino == 0) { warnx("Journal file does not exist"); return; } printf("Clearing journal flags from inode %ju\n", (uintmax_t)ino); if (getino(&disk, &ip, ino, &mode) != 0) { warn("Failed to get journal inode"); return; } dp2 = ip; dp1 = ip; if (sblock.fs_magic == FS_UFS1_MAGIC) dp1->di_flags = 0; else dp2->di_flags = 0; if (putino(&disk) < 0) { warn("Failed to write journal inode"); return; } }
void creat_file() { int dev; u32 ino; char* parent; char* child; MINODE* pip; if ('/' == pathName[0]) { dev = root->dev; } else { dev = running->cwd->dev; } parent = dir_name(pathName); child = base_name(pathName); if (0 == strcmp(child, ".")) { printf("creat : provide a file name\n"); return; } ino = getino(&dev, parent); pip = iget(dev, ino); // verify parent INODE is a DIR and child does not exist in the parent dir if ((0040000 == (pip->INODE.i_mode & 0040000)) && (0 == is_exist(pip, child))) { my_creat(pip, child); } }
static ino_t journal_findfile( void ) { struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; ino_t ino; int mode; void *ip; int i; if ( getino( &disk, &ip, ROOTINO, &mode ) != 0 ) { warn( "Failed to get root inode" ); return ( -1 ); } dp2 = ip; dp1 = ip; if ( sblock.fs_magic == FS_UFS1_MAGIC ) { if ( (off_t) dp1->di_size >= lblktosize( &sblock, NDADDR ) ) { warnx( "ROOTINO extends beyond direct blocks." ); return ( -1 ); } for ( i = 0; i < NDADDR; i++ ) { if ( dp1->di_db[i] == 0 ) break; if ( ( ino = dir_search( dp1->di_db[i], sblksize( &sblock, (off_t) dp1->di_size, i ) ) ) != 0 ) return ( ino ); } } else { if ( (off_t) dp2->di_size >= lblktosize( &sblock, NDADDR ) ) { warnx( "ROOTINO extends beyond direct blocks." ); return ( -1 ); } for ( i = 0; i < NDADDR; i++ ) { if ( dp2->di_db[i] == 0 ) break; if ( ( ino = dir_search( dp2->di_db[i], sblksize( &sblock, (off_t) dp2->di_size, i ) ) ) != 0 ) return ( ino ); } } return ( 0 ); }
//prints everything located at the pathname //Calls printdir which calls printinfo for a given pathname //The main function of ls is to get the pathname and check for certain cases //Finds the ino of the pathname void ls(char *pathname) { int ino, offset; MINODE *mip = running->cwd; char name[64][64], temp[64]; char buf[1024]; //ls cwd if(!strcmp(pathname, "")) { //print_dir(mip->INODE); print_dir(mip); return; } //ls root dir if(!strcmp(pathname, "/")) { //print_dir(root->INODE); print_dir(root); return; } //if there's a pathname, ls pathname if(pathname) { //check if path starts at root if(pathname[0] == '/') { mip = root; } //search for path to print ino = getino(mip, pathname); if(ino == 0) { return; } mip = iget(dev, ino); if(!S_ISDIR(mip->INODE.i_mode)) { printf("%s is not a directory!\n", pathname); strcpy(teststr, pathname); strcat(teststr, " is not a directory!"); iput(mip); return; } //print_dir(mip->INODE); print_dir(mip); iput(mip); } else { //print root dir //print_dir(root->INODE); print_dir(root); } }
//releases a minode[] void iput(MINODE *mip) { int ino = getino(mip, "."); int offset, ipos; char buf[1024]; //decrement refCount by 1 mip->refCount--; //check refcount to see if anyone using it //check dirty to see if it's been changed, dirty == 1 if changed //if refCount > 0 or dirty return if (mip->refCount || !mip->dirty) return; //mail man's to determine disk block and which inode in that block ipos = (ino - 1) / 8 + INODE_START_POS; offset = (ino -1) % 8; //read that block in get_block(dev, ipos, buf); //copy minode's inode into the inode area in that block ip = (INODE*)buf + offset; *ip = mip->INODE; //write block back to disk put_block(dev, ipos, buf); }
// Modify INODE.i_mode's permission bits int chown_file() { int newOwner = atoi(pathM); char *pathname = parameterM; int dev, ino; MINODE *mp; // Get inode if(pathname[0] == '/') dev = root->dev; else dev = running->cwd->dev; ino = getino(dev, pathname); if (ino == EXIT_FAILURE) { printf("CHMOD: File does not exist\n"); return EXIT_FAILURE; } mp = iget(dev, ino); // Update owner mp->INODE.i_uid = newOwner; // Write file back mp->dirty = 1; iput(mp); // Update file access time touch_file(pathname); return EXIT_SUCCESS; }
void do_ls() { int dev; u32 ino; MINODE* mip; char buf[BLOCK_SIZE]; char temp[BLOCK_SIZE]; char* cp; int i; if (0 == pathName[0]) { printf("ls : current working directory"); ino = running->cwd->ino; dev = running->cwd->dev; } else if (0 == strcmp(pathName, "/")) { printf("ls : root directory"); ino = root->ino; dev = root->dev; } else { printf("ls : "); ino = getino(&dev, pathName); } if ((u32)-1 == ino) { err_printf("ls : it is not a directory\n"); return; } printf("\n"); mip = iget(dev, ino); for (i = 0; i < 12 && (mip->INODE).i_block[i]; i++) { get_block(mip->dev, (mip->INODE).i_block[i], buf); cp = buf; dp = (DIR*)buf; //printf("i_block is %i\n", (int) (mip->INODE).i_block[i]); while (cp < buf + BLOCK_SIZE && dp->rec_len) { if (0 == dp->rec_len) break; strncpy(temp, dp->name, dp->name_len); temp[dp->name_len] = 0; file_info(dev, dp->inode); //printf("%3u %s\n", dp->inode, temp); // with inode printf("%s\n", temp); cp += dp->rec_len; dp = (DIR*)cp; } } iput(mip); }
ino_t fs_maxino(void) { return ((getino(sblock->lfs_ifile)->dp1.di_size - (sblock->lfs_cleansz + sblock->lfs_segtabsz) * sblock->lfs_bsize) / sblock->lfs_bsize) * sblock->lfs_ifpb - 1; }
/* * Dump pass 2. * * Scan each directory on the filesystem to see if it has any modified * files in it. If it does, and has not already been added to the dump * list (because it was itself modified), then add it. If a directory * has not been modified itself, contains no modified files and has no * subdirectories, then it can be deleted from the dump list and from * the list of directories. By deleting it from the list of directories, * its parent may now qualify for the same treatment on this or a later * pass using this algorithm. */ int mapdirs(ino_t maxino, off_t *tapesize) { union dinode *dp; int i, isdir; char *map; ino_t ino; union dinode di; off_t filesize; int ret, change = 0; isdir = 0; /* XXX just to get gcc to shut up */ for (map = dumpdirmap, ino = 1; ino < maxino; ino++) { if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */ isdir = *map++; else isdir >>= 1; if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap)) continue; dp = getino(ino, &i); /* * inode buf may change in searchdir(). */ if (sblock->fs_magic == FS_UFS1_MAGIC) di.dp1 = dp->dp1; else di.dp2 = dp->dp2; filesize = (off_t)DIP(dp, di_size); for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) { if (DIP(&di, di_db[i]) != 0) ret |= searchdir(ino, DIP(&di, di_db[i]), sblksize(sblock, DIP(dp, di_size), i), filesize); if (ret & HASDUMPEDFILE) filesize = 0; else filesize -= sblock->fs_bsize; } for (i = 0; filesize > 0 && i < NIADDR; i++) { if (DIP(&di, di_ib[i]) == 0) continue; ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize); } if (ret & HASDUMPEDFILE) { SETINO(ino, dumpinomap); *tapesize += blockest(dp); change = 1; continue; } if ((ret & HASSUBDIRS) == 0) { if (!TSTINO(ino, dumpinomap)) { CLRINO(ino, dumpdirmap); change = 1; } } } return (change); }
/* * Scan a disk block containing directory information looking to see if * any of the entries are on the dump list and to see if the directory * contains any subdirectories. */ static int searchdir(ufs1_ino_t ino, daddr_t blkno, long size, long filesize, long *tape_size, int nodump) { struct direct *dp; struct ufs1_dinode *ip; long loc, ret = 0; char dblk[MAXBSIZE]; bread(fsbtodb(sblock, blkno), dblk, (int)size); if (filesize < size) size = filesize; for (loc = 0; loc < size; ) { dp = (struct direct *)(dblk + loc); if (dp->d_reclen == 0) { msg("corrupted directory, inumber %d\n", ino); break; } loc += dp->d_reclen; if (dp->d_ino == 0) continue; if (dp->d_name[0] == '.') { if (dp->d_name[1] == '\0') continue; if (dp->d_name[1] == '.' && dp->d_name[2] == '\0') continue; } if (nodump) { ip = getino(dp->d_ino); if (TSTINO(dp->d_ino, dumpinomap)) { CLRINO(dp->d_ino, dumpinomap); *tape_size -= blockest(ip); } /* * Add back to dumpdirmap and remove from usedinomap * to propagate nodump. */ if ((ip->di_mode & IFMT) == IFDIR) { SETINO(dp->d_ino, dumpdirmap); CLRINO(dp->d_ino, usedinomap); ret |= HASSUBDIRS; } } else { if (TSTINO(dp->d_ino, dumpinomap)) { ret |= HASDUMPEDFILE; if (ret & HASSUBDIRS) break; } if (TSTINO(dp->d_ino, dumpdirmap)) { ret |= HASSUBDIRS; if (ret & HASDUMPEDFILE) break; } } } return (ret); }
/* ---------------------------------------------------------- * list_dir: * print the directories and files of cwd or a pathname * * (1) if pathname == NULL, use CWD * (2) print INODE info --------------------------------------------------------------*/ void list_dir(char* pathname) { MINODE* dir; int ino, dev; // (1) pathname == NULL, use CWD if(pathname == 0) { ino = running->cwd->ino; dev = running->cwd->dev; } else { // Absolute path, start from root if(strncmp(pathname, "/", 1)==0) { dev = root->dev; } else // Relative path, start from cwd { dev = running->cwd->dev; } // Get the ino number if(pathname[0] == '/' && strlen(pathname) == 1) // only the root was entered { // Get ino from root ino = root->ino; } else { // Get ino from path ino = getino(&dev, pathname); } } // Could not find valid ino if(ino == 0) { printf("%s is not a valid path\n", pathname); return NULL; } else { dir = iget(dev, ino); // Load MINODE* into minode[] table } if(dir == NULL) { printf("Unable to access %s\n no such file or directory", pathname); return; } printInode(dir); iput(dir); }
//change cwd to pathname. If no pathname, set cwd to root. void cd(char *pathname) { int i = 0, n = 0, ino; char name[64][64]; char *temp; MINODE *mip = running->cwd; if(pathname) { //cd to pathname printf("cd to %s\n", pathname); if(pathname[0] == '/') { mip = root; } //parse the pathname and put it into name strcat(pathname, "/"); temp = strtok(pathname, "/"); while(temp != NULL) { strcpy(name[i], temp); temp = strtok(NULL, "/"); i++; n++; } //null terminate the name array strcpy(name[i], "\0"); //go through the pathname until end for(i = 0; i < n; i++) { ino = getino(mip, name[i]); printf("inode is: %d\n", ino); //getino returns 0 if not found if(ino == 0) { //bad path, exit exit(1); } mip = iget(dev, ino); } running->cwd = mip; } else { printf("cd to root\n"); //cd to root running->cwd = root; } }
void mytouch(char** args) { char* filename; MINODE* mp; int ino; int dev = running->cwd->dev; if(args[0] == NULL) { printf("Error: touch requires a filename\n"); return; } filename=strdup(args[0]); ino = getino(&dev, filename); // get inumber mp = iget(dev, ino); // get MINODE* if(mp != NULL) // we found it { mp->INODE.i_atime = mp->INODE.i_mtime = time(0L); mp->dirty = 1; iput(mp); } else // Create the file { creat_r(filename); ino = getino(&dev, filename); mp = iget(dev, ino); if(mp == NULL) { printf("Failed to create file %s\n", filename); return; } mp->INODE.i_atime = mp->INODE.i_mtime = time(0L); mp->dirty = 1; iput(mp); } }
int read_file(char *cmd) { int fd,i,nbytes,ino,count,dev; char *buffer, file[1024], nbt[12]; OFT *oftp; MINODE *mip; MOUNT *mnt; mnt=(MOUNT *)find_mount(running->cwd->dev); i=mnt->blksize; buffer=malloc(i); memset(buffer, 0, i); bzero(file, 1024); bzero(nbt, 12); if (strcmp(cmd, "")==0) { printf("Enter filename/fd [nbytes=1]: "); fgets(cmd, 512, stdin); } sscanf(cmd, "%s %s", file, nbt); fd=strtol(file, NULL, 0); nbytes=strtol(nbt, NULL, 0); if (fd==0) { if (strcmp(file, "0")!=0) { dev=running->cwd->dev; ino = getino(&dev, file); mip = iget(dev, ino); for (i=0;i<NFD;i++) { oftp=running->fd[i]; if (oftp==0) continue; if (oftp->ptr->ino==ino && oftp->refCount>0) { fd=i; break; } } if (mip->ino!=ino) { printf(RED"File is not open!\n"RESET); free(buffer); return -1; } iput(mip); } } if (oftp->mode!=0 && oftp->mode!=2) { printf(RED"File is open in incompatible mode!\n"RESET); free(buffer); return -1; } count=(myread(fd, buffer, nbytes)); buffer[count]=0; myprintf("READ BUFFER: %s\n", buffer); free(buffer); return count; }
//prints everything located at the pathname void ls(char *pathname) { int ino, offset; MINODE *mip = running->cwd; char name[64][64], temp[64]; char buf[1024]; //ls cwd if(!strcmp(pathname, "")) { print_dir(mip->INODE); return; } //ls root dir if(!strcmp(pathname, "/")) { print_dir(root->INODE); return; } //if there's a pathname, ls pathname if(pathname) { //check if path starts at root if(pathname[0] == '/') { mip = root; } //search for path to print ino = getino(mip, pathname); if(ino == 0) { return; } printf("%d %d\n", ino, dev); if(iget(dev, ino) != NULL) mip = iget(dev, ino); else { printf("ERROR: cannot ls a file\n"); return; } print_dir(mip->INODE); } else { //print root dir print_dir(root->INODE); } }
/* ------------------------------------------------------- * make_dir: * must understand perfectly!!! * * Takes a pathname as parameter * * (1) set the device * (2) get parent MINODE by using dirname with * getino * Load MINODE using iget * (3) call my_mkdir(MINODE* parent, char* name) * --------------------------------------------------------*/ void make_dir(char* path) { MINODE* pip; // parent MINODE* int dev, pino; // device, parent ino // parent = path to parent directory, child = basename char* parent, *child; // (1) Set device according to relative or absolute path if(path[0] == '/') dev = root->dev; else dev = running->cwd->dev; // (2) Separate path into dirname and basename parent = strdup(Dirname(path)); // make copies child = strdup(Basename(path)); // Debug print //printf("parent: %s\n", parent); //printf("child: %s\n", child); // (3) get in memory MINODE of parent directory pino = getino(&dev, parent); // First, get parent ino pip = iget(dev, pino); // Then use it to load INODE into minode[] table // (4) Error checking on found MINODE if(pip == NULL) // (4.1) ensure the MINODE was found { printf("Error: unable to locate %s\n", parent); } else if(!isdir(pip)) // (4.2) is DIR { printf("Error: %s is not a directory\n", parent); } else if(search(pip, child) != 0) // (4.3) child does not already exist { // the child was already found printf("Error: %s already exists in %s\n", child, parent); } // (5) We've verified that parent path exists, is a directory // and child does not exist in it, so add to it else my_mkdir(pip,child); // No matter what, dont forget to write back! // Release parent from minode[] table and write back to disk iput(pip); }
// ls => ls <cwd> // ls dir => ls <cwd>/dir // ls a/b/c // ls a/b/c e/f/g /h/i/j int my_ls(int argc, char* argv[]) { result_t result = NONE; const int device = running->cwd->device; // If given no path, ls cwd if(argc < 2) { list_dir(running->cwd); return SUCCESS; } // ls each path given by user int i = 1; while(i < argc) { int ino = getino(device, argv[i]); MINODE* mip = iget(device, ino); if(!mip) { result = DOES_NOT_EXIST; printf("ls: cannot access '%s':" " No such file or directory\n", argv[i]); goto clean_up; } // If printing multiple lists label each one if(argc > 2) printf("%s:\n", argv[i]); if(S_ISDIR(mip->inode.i_mode)) list_dir(mip); else list_file(mip, argv[i]); clean_up: // Move parent inode from memory to disk iput(mip); if(result != NONE) return result; i++; } return SUCCESS; }
static struct ifile * lfs_ientry(ino_t ino) { static struct ifile ifileblock[MAXIFPB]; static daddr_t ifblkno; daddr_t lbn; daddr_t blkno; union dinode *dp; lbn = ino/sblock->lfs_ifpb + sblock->lfs_cleansz + sblock->lfs_segtabsz; dp = getino(sblock->lfs_ifile); blkno = lfs_bmap(sblock, &dp->dp1 ,lbn); if (blkno != ifblkno) bread(fsbtodb(sblock, blkno), (char *)ifileblock, sblock->lfs_bsize); return ifileblock + (ino % sblock->lfs_ifpb); }
/* --------------------------------------------------------------- * creat_r: * Given path of a file to be made, * get the parent's MINODE and ensure that it is a DIR * and that the new file does not already exist in it -------------------------------------------------------------------*/ void creat_r(char* path) { MINODE* pip; char* parent, *child; int dev, pino; // (1) Set device according to relative or absolute pathname if(path[0] == '/') dev = root->dev; else dev = running->cwd->dev; parent = strdup(Dirname(path)); child = strdup(Basename(path)); // (3) get in memory MINODE of parent directory // First, get parent ino pino = getino(&dev, parent); // Then use it to load MINODE into minode[] table pip = iget(dev, pino); // (4)Verify pip // (4.1) was found if(pip == NULL) { printf("Error: unable to locate %s\n", parent); } // (4.2) is directory else if(!isdir(pip)) { printf("Error: %s is not a directory\n", parent); } // (4.3) does not already contain child else if(search(pip, child) != 0) // the child was already found { printf("Error: %s already exists in %s\n", child, parent); } // (5) We've verified that parent path exists, is a directory // and child does not exist in it, so add to it else my_creat(pip,child); iput(pip); }
int touch (char *pathname) { MINODE *mip; int ino, dev; MOUNT *mnt; dev=running->cwd->dev; ino=getino(&dev, pathname); if(ino==0) { printf(RED "Invalid path\n" RESET); return -1; } mip=iget(dev, ino); mip->inode.i_mtime=time(0L); mip->dirty=true; mnt=(MOUNT *)find_mount(dev); sync_mount_atime(mnt); iput(mip); }
int do_readinode(uufsd_t *ufs, const char *path, ino_t *ino, struct inode *inode) { errcode_t rc; int mode; struct ufs2_dinode *dinop = NULL; rc = ufs_namei(ufs, ROOTINO, ROOTINO, path, ino); if (rc || !*ino) { debugf("ufs_namei(ufs, ROOTINO, ROOTINO, %s, ino); failed", path); return -ENOENT; } rc = getino(ufs, (void **)&dinop, *ino, &mode); if (rc) { debugf("getino(ufs, *ino, inode, &mode); failed"); return -EIO; } copy_ondisk_to_incore(ufs, inode, dinop, *ino); return 0; }
/* * Dump pass 1. * * Walk the inode list for a filesystem to find all allocated inodes * that have been modified since the previous dump time. Also, find all * the directories in the filesystem. */ int mapfiles(ufs1_ino_t maxino, long *tape_size) { int mode; ufs1_ino_t ino; struct ufs1_dinode *dp; int anydirskipped = 0; for (ino = ROOTINO; ino < maxino; ino++) { dp = getino(ino); if ((mode = (dp->di_mode & IFMT)) == 0) continue; /* * Everything must go in usedinomap so that a check * for "in dumpdirmap but not in usedinomap" to detect * dirs with nodump set has a chance of succeeding * (this is used in mapdirs()). */ SETINO(ino, usedinomap); if (mode == IFDIR) SETINO(ino, dumpdirmap); if (WANTTODUMP(dp)) { SETINO(ino, dumpinomap); if (mode != IFREG && mode != IFDIR && mode != IFLNK) *tape_size += 1; else *tape_size += blockest(dp); continue; } if (mode == IFDIR) { if (!nonodump && (dp->di_flags & UF_NODUMP)) CLRINO(ino, usedinomap); anydirskipped = 1; } } /* * Restore gets very upset if the root is not dumped, * so ensure that it always is dumped. */ SETINO(ROOTINO, dumpinomap); return (anydirskipped); }
/* ------------------------------------------------------------ * change_dir: * accept a pathname and change to that directory * * (1) Check pathname for NULL, set to root if so * (2) get INODE of pathname into a MINODE * (3) get INODE into minode[] table * (4) check DIR type, return if not a DIR * (5) dispose of running->cwd, change to found MINODE* dir * -----------------------------------------------------------------*/ void change_dir(char** args) { MINODE* dir; int ino; int dev = running->cwd->dev; // (1) Check for pathname if(args[0] == NULL) // no path provided { iput(running->cwd); // Dispose of cwd running->cwd = root; // change to root return; } // (2) get INODE of pathname into a MINODE ino = getino(&dev, args[0]); // (2.1) get inumber dir = iget(dev, ino); // (3) get INODE into minode[] table if(dir == NULL) // unable to find directory { printf("No such file or directory %s\n", args[0]); return; } else // Release running->cwd and update to dir { // (4) Check DIR type, return if not directory if(isreg(dir)) // if dir is a regular file { printf("Error: Not a directory %s\n", args[0]); iput(dir); // release minode[] entry return; } // (5) We've found the (valid) directory iput(running->cwd); // dispose the current cwd running->cwd = iget(dir->dev, dir->ino); // load new cwd by calling iget iput(dir); // write back to disk } }
int chmod_file(char *cmd) { int newMod, ino, dev; char path[1024], mod[10]; MINODE *mip; MOUNT *mnt; sscanf(cmd, "%s %s", mod, path); newMod=strtol(mod, NULL, 0); dev=running->cwd->dev; ino=getino(&dev, path); if (ino==0) { printf(RED "invalid path\n" RESET); return -1; } mip=iget(dev, ino); mip->inode.i_mode=newMod; mip->dirty=true; mnt=(MOUNT *)find_mount(dev); sync_mount_atime(mnt); iput(mip); }
int chown(char *cmd) { int newOwner, ino, dev; char path[1024], own[10]; MINODE *mip; MOUNT *mnt; sscanf(cmd, "%s %s", own, path); newOwner=atoi(own); dev=running->cwd->dev; ino=getino(&dev, path); if(ino==0) { printf(RED "invalid path\n" RESET); return -1; } mip=iget(dev, ino); mip->inode.i_uid=newOwner; mip->dirty=true; mnt=(MOUNT *)find_mount(dev); sync_mount_atime(mnt); iput(mip); return; }