Example #1
0
File: rfs.c Project: karajrish/OS
// Delete directory (if it is empty)
int removeDirHelper(int fd, char *dname, int parINodeNo){
	int i;
	struct INode parent_in;
	// Tokenize the name and find its parent directory
	readINode(fd, parINodeNo, &parent_in);

	// Find dname in parent directory and read its inode
	struct DirEntry d;
	int linkNo = fileExists(fd, dname, parent_in, &d);
	int inodeNo = d.d_entry.d_inode;
	if( linkNo==-1 ){
		printf("Directory does not exist!\n");
		return -1;
	}
	if( inodeNo == s.sb_rootdir ){
		printf("Cannot delete root directory!\n");
		return -1;
	}
	struct INode in;
	readINode(fd, inodeNo, &in);

	// On each of the link in its inode call recursive delete after taking permission
	if( in.i_nlinks==0 ){
		printf("Not a valid directory!\n");
		return -1;
	}
	if( in.i_nlinks>2 ){
		printf("Directory not empty! Do you want to proceed[y]? ");
		char c;
		scanf("%c",&c);
		if( c!='y' || c!='Y' ){
			return -1;
		}
		struct DirEntry temp;
		struct INode tempINode;
		for(i=1; i<in.i_nlinks; i++){
			readDirEntry(fd, i, &temp);
			if( strcmp(temp.d_entry.d_name, "..")==0 )	continue;
			readINode(fd, temp.d_entry.d_inode, &tempINode);
			if( tempINode.i_nlinks==0 )		freeINode(fd, temp.d_entry.d_inode);
			else{
				removeDirHelper(fd, temp.d_entry.d_name, inodeNo);
			}
		}
	}
	freeINode(fd, inodeNo);
	freeDirEntry(fd, &parent_in, linkNo);
	printf("Directory successfully deleted!\n");
}
Example #2
0
File: rfs.c Project: karajrish/OS
int closeDir(int dirhandle){
	// Find the corresponding open file object and remove it
	int i;
	struct InCoreINode icn;
	struct DirEntry d;
	struct INode in;
	int inodeNo = isOpen(dirhandle, &icn);
	if( inodeNo==-1 ){
		printf("Directory not open!\n");
		return -1;
	}
	if( icn.ic_inode.i_nlinks==0 ){
		// readDirEntry(icn.ic_inode, )
		printf("Not a directory!%d\n", icn.ic_ino);
		return -1;
	}
	for(i=1; i<icn.ic_inode.i_nlinks; i++){
		readDirEntry(icn.ic_dev, &icn.ic_inode, i, &d);
		readINode(icn.ic_dev, d.d_entry.d_inode, &in);
		if( in.i_nlinks==0 )	closeFile(d.d_entry.d_inode);
		else					closeDir(d.d_entry.d_inode);
	}
	removeOpenFile(dirhandle);

}
Example #3
0
File: rfs.c Project: karajrish/OS
int freeINode(int fd, int inodeNo){
	struct INode in;
	int i;
	readINode(fd, inodeNo, &in);
	for(i=0; i<13 && in.i_blocks[i]>0; i++){
		freeBlock(fd, in.i_blocks[i]);
	}
	lseek(fd, INODEBLOCKSTART + inodeNo*sizeof(struct INode), SEEK_SET);
	write(fd, &nullINode, sizeof(struct INode));
	printf("Freed inode number %d\n", inodeNo);
	s.sb_nfreeinodes++;
}
Example #4
0
File: rfs.c Project: karajrish/OS
// Create a directory
int makeDir(int fd, char *dname, int uid, int gid, int attributes){
	printf("Creating new directory %s\n",dname);
	int parINodeNo, inodeNo;
	struct INode parent_in;
	struct DirEntry d;

	//Tokenize the dname, check for validity and find its parent directory
	parINodeNo = currDirINode;
	readINode(fd, parINodeNo, &parent_in);

	// Check if the dname already exists in the INode in
	if( fileExists(fd, dname, parent_in, &d)!=-1 ){
		printf("Directory already exists!\n\n");
		return -1;
	}

	// Initialize an inode and data block for new directory
	struct INode in;
	in.i_atime = 0;
	bzero(in.i_blocks, 13);
	in.i_blocks[0] = allocBlock(fd);
	in.i_gen = 0;
	in.i_gid = gid;
	in.i_uid = uid;
	in.i_nlinks = 0;
	in.i_mode = attributes;
	bzero(d.d_entry.d_name, MAXNAMELENGTH);
	strcpy(d.d_entry.d_name, ".");
	int allocatedINode = allocINode(fd, &in);
	d.d_entry.d_inode = allocatedINode;
	d.d_offset = 0;
	allocDirEntry(fd, &in, &d);
	bzero(d.d_entry.d_name, MAXNAMELENGTH);
	strcpy(d.d_entry.d_name, "..");
	d.d_entry.d_inode = parINodeNo;
	allocDirEntry(fd, &in, &d);
	writeInode(fd, allocatedINode, &in);

	// Add its DirEntry in its parent INode and rewrite Inode entry
	bzero(d.d_entry.d_name, MAXNAMELENGTH);
	strcpy(d.d_entry.d_name, dname);
	d.d_entry.d_inode = allocatedINode;
	allocDirEntry(fd, &parent_in, &d);
	writeInode(fd, parINodeNo, &parent_in);
	printf("\n");
	return 0;
}
Example #5
0
File: rfs.c Project: karajrish/OS
int openDir(int fd, char *dname){

	struct INode parent_in;
	struct InCoreINode* icn;
	struct DirEntry d;
	readINode(fd, currDirINode, &parent_in);
	
	// Tokenize the name and find its inode no
	int linkNo = fileExists(fd, dname, parent_in, &d);
	if( linkNo==-1 ){
		printf("No such directory exists!\n");
		return -1;
	}
	int dirhandle = isOpen(d.d_entry.d_inode, icn);
	if( dirhandle!=-1 )
		return dirhandle;
	
	// Add the inode to open file object DLL and return the reference number
	return addOpenFile(fd, d.d_entry.d_inode);
}
Example #6
0
File: rfs.c Project: karajrish/OS
int addOpenFile(int fd, int inodeNo){
	printf("Opening directory no %d\n", inodeNo);
	struct InCoreINode *icn = malloc(sizeof(struct InCoreINode));
	struct INode in;
	readINode(fd, inodeNo, &icn->ic_inode);
	icn->ic_ref = 0;
	icn->ofo_curpos = 0;
	icn->ic_ino = inodeNo;
	icn->ic_dev = fd;
	icn->ic_next = NULL;
	icn->ic_prev = NULL;
	struct InCoreINode* temp = o.ofo_inode;
	if( o.ofo_inode==NULL ){
		o.ofo_inode = icn;
		return inodeNo;
	}
	while( temp->ic_next!=NULL ){
		temp = temp->ic_next;
	}
	temp->ic_next = icn;
	icn->ic_prev = temp;
	return inodeNo;
}
Example #7
0
void testINodes(UINT nDBlks, UINT nINodes) {
    printf("\n==== inode test ====\n");

    //test makefs
    printf("\n---- makefs ----\n");
    FileSystem fs;
    UINT succ = makefs(nDBlks, nINodes, &fs);
    if(succ == 0) {
        printf("makefs succeeded with filesystem size: %d\n", fs.nBytes);
    }

    printf("\nSuperblock:\n");
    printSuperBlock(&fs.superblock);
    printf("\nINodes:\n");
    printINodes(&fs);
    printf("\nData blocks:\n");
    printDBlks(&fs);
    printf("\nFree inode cache:\n");
    printFreeINodeCache(&fs.superblock);
    printf("\nFree dblk cache:\n");
    printFreeDBlkCache(&fs.superblock);

    assert(fs.diskINodeBlkOffset == 1);
    assert(fs.diskDBlkOffset == 1 + nINodes / INODES_PER_BLK);

    //test allocINode until no free inodes are left
    printf("\n---- allocINode ----\n");
    for(int i = 0; i < nINodes; i++) {
        INode testINode;
        UINT id = allocINode(&fs, &testINode);
        printf("allocINode call %d returned ID %d\n", i, id);
        printINode(&testINode);
    }

    assert(fs.superblock.nFreeINodes == 0);

    //allocINode should fail gracefully when no free inodes are left
    INode testINode;
    UINT id = allocINode(&fs, &testINode);
    printf("Invalid allocINode call returned ID %d\n", id);
    assert(id == -1);

    printf("\nSuperblock:\n");
    printSuperBlock(&fs.superblock);
    printf("\nINodes:\n");
    printINodes(&fs);
    printf("\nFree inode cache:\n");
    printFreeINodeCache(&fs.superblock);

    //test random freeINode
    printf("\n---- random freeINode ----\n");
    
    int shuffled[nINodes];
    for(int i = 0; i < nINodes; i++) {
        shuffled[i] = i;
    }
    shuffle(shuffled, nINodes);
    
    for(int i = 0; i < nINodes; i++) {
        printf("Freeing inode id: %d\n", shuffled[i]);
        succ = freeINode(&fs, shuffled[i]);
        assert(succ == 0);
    }

    printf("%d, %d\n", fs.superblock.nFreeINodes, nINodes);
    assert(fs.superblock.nFreeINodes == nINodes);

    printf("\nSuperblock:\n");
    printSuperBlock(&fs.superblock);
    printf("\nINodes:\n");
    printINodes(&fs);
    printf("\nFree inode cache:\n");
    printFreeINodeCache(&fs.superblock);

    //test allocINode until no free inodes are left
    printf("\n---- allocINode ----\n");
    for(int i = 0; i < nINodes; i++) {
        INode testINode;
        UINT id = allocINode(&fs, &testINode);
        printf("allocINode call %d returned ID %d\n", i, id);
    }

    assert(fs.superblock.nFreeINodes == 0);

    //test ordered freeINode
    printf("\n---- ordered freeINode ----\n");
    for(int i = 0; i < nINodes; i++) {
        printf("Freeing inode id: %d\n", i);
        succ = freeINode(&fs, i);
        assert(succ == 0);
    }

    assert(fs.superblock.nFreeINodes == nINodes);

    printf("\nSuperblock:\n");
    printSuperBlock(&fs.superblock);
    printf("\nINodes:\n");
    printINodes(&fs);
    printf("\nFree inode cache:\n");
    printFreeINodeCache(&fs.superblock);

    //temporary variables for read/write test
    if(nINodes < NUM_TEST_INODES) {
        printf("\nError: must have at least %d inodes to do read/write test!\n", NUM_TEST_INODES);
        exit(1);
    }
    INode inodes[NUM_TEST_INODES];
    UINT inodeIds[NUM_TEST_INODES];
    for(int i = 0; i < NUM_TEST_INODES; i++) {
        inodeIds[i] = -1;
    }
    
    //test allocINode
    printf("\n---- allocINode (2) ----\n");
    for(int i = 0; i < NUM_TEST_INODES; i++) {
        inodeIds[i] = allocINode(&fs, &inodes[i]);
        printf("allocINode call %d returned ID %d\n", i, inodeIds[i]);
        printINode(&inodes[i]);

        //ensure allocated IDs are valid and unique
        assert(inodeIds[i] >= 0 && inodeIds[i] < nINodes);
        for(UINT j = 0; j < i; j++) {
            assert(inodeIds[i] != inodeIds[j]);
        }
    }
    
    //test group writeINode
    printf("\n---- writeINode ----\n");
    for(int i = 0; i < NUM_TEST_INODES; i++) {
        //inodes[i]._in_owner = TEST_OWNER;
        strcpy(inodes[i]._in_owner, TEST_OWNER);
        inodes[i]._in_permissions = TEST_PERMISSIONS;
        inodes[i]._in_modtime = TEST_MODTIME;
        inodes[i]._in_accesstime = TEST_ACCESSTIME;
        inodes[i]._in_filesize = TEST_FILESIZE;
        
        printf("Writing test data to inode id: %d\n", inodeIds[i]);
        succ = writeINode(&fs, inodeIds[i], &inodes[i]);
        assert(succ == 0);
    }
    printINodes(&fs);

    //test group readINode
    printf("\n---- readINode ----\n");
        
    for(int i = 0; i < NUM_TEST_INODES; i++) {
        INode testINode;
        
        printf("Reading test data from inode id: %d\n", inodeIds[i]);
        succ = readINode(&fs, inodeIds[i], &testINode);
        printINode(&testINode);
        assert(succ == 0);
        //assert(testINode._in_owner = TEST_OWNER);
        assert(!strcmp(testINode._in_owner, TEST_OWNER));
        assert(testINode._in_permissions = TEST_PERMISSIONS);
        assert(testINode._in_modtime = TEST_MODTIME);
        assert(testINode._in_accesstime = TEST_ACCESSTIME);
        assert(testINode._in_filesize = TEST_FILESIZE);
    }

    //test modifying read/writeINode
    printf("\n---- modify read/writeINode ----\n");
    printINodes(&fs);
    for(int i = NUM_TEST_INODES - 1; i >= 0; i--) {
        succ = readINode(&fs, inodeIds[i], &inodes[i]);
        assert(succ == 0);

        printf("Modifying inode id: %d\n", inodeIds[i]);
        //inodes[i]._in_owner = "WILL";
        strcpy(inodes[i]._in_owner, "WILL");
        inodes[i]._in_permissions = TEST_PERMISSIONS - 1;
        inodes[i]._in_modtime = TEST_MODTIME - 1;
        inodes[i]._in_accesstime = TEST_ACCESSTIME - 1;
        inodes[i]._in_filesize = TEST_FILESIZE - 1;
        succ = writeINode(&fs, inodeIds[i], &inodes[i]);
        assert(succ == 0);

        INode testINode2;
        succ = readINode(&fs, inodeIds[i], &testINode2);
        printINode(&testINode2);
        assert(succ == 0);
        //assert(testINode2._in_owner = inodes[i]._in_owner);
        assert(!strcmp(testINode2._in_owner, inodes[i]._in_owner));
        assert(testINode2._in_permissions = inodes[i]._in_permissions);
        assert(testINode2._in_modtime = inodes[i]._in_modtime);
        assert(testINode2._in_accesstime = inodes[i]._in_accesstime);
        assert(testINode2._in_filesize = inodes[i]._in_filesize);
    }
    
    printf("\n---- closefs ----\n");
    succ = closefs(&fs);
    assert(succ == 0);

    printf("\n==== inode test complete ====\n");
}