Beispiel #1
0
// 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");
}
Beispiel #2
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");
}