Exemple #1
0
// 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;
}
Exemple #2
0
int main(int argc, char *argv[]) {
    int i;
    int fd;
    int fd2;
    int ret;
    int curr;
    int *fat;
    int blocks;
    int diskSize;
    int fileCount;
    int fileArgs;
    char *imageFile;
    struct stat sbuf;
    int firstFreeBlock;
    bootSector bSector;
    directoryEntry *directory;
    int writeBoot = 0;

    if(argc <= 1) {
        printf
            ("usage: buildFat [-b <boot block> ] <diskImage> <files>\n");
        exit(-1);
    }

    curr = 2;
    if(!strcmp(argv[1], "-b")) {
        /* it's a boot disk */
        printf("writing boot block\n");
        curr += 2;
        writeBoot = 1;
    }

    imageFile = argv[curr - 1];
    printf("image file = %s\n", imageFile);

    ret = stat(imageFile, &sbuf);
    if(ret) {
        perror("stat");
        exit(EXIT_FAILURE);
    }

    fileArgs = argc - curr;
    if(fileArgs == 0) {
        printf
            ("WARNING: file count is zero in disk image being built.\n");
    }

    diskSize = sbuf.st_size;
    if(diskSize % SECTOR_SIZE != 0) {
        printf("image is not a multiple of 512 bytes\n");
        exit(EXIT_FAILURE);
    }

    blocks = diskSize / SECTOR_SIZE;

    bSector.magic = PFAT_MAGIC;
    bSector.fileAllocationOffset = 1;
    bSector.fileAllocationLength =
        roundToNextBlock(blocks) / SECTOR_SIZE * 4;
    fat = (int *)calloc(blocks, sizeof(int));
    bSector.rootDirectoryOffset = bSector.fileAllocationLength + 1;

    if(fileArgs == 0) {
        printf("WARNING: building an empty FAT filesystem\n");
    }

    fd = open(imageFile, O_WRONLY, 0);
    if(fd < 0) {
        perror("image File open:");
        exit(-1);
    }

    if(writeBoot) {
        /* copy boot block */
        char buffer[SECTOR_SIZE];

        fd2 = open(argv[2], O_RDONLY, 0);

        ret = read(fd2, buffer, SECTOR_SIZE);
        if(ret != SECTOR_SIZE) {
            printf("unable to read boot record\n");
        }

        lseek(fd, 0, SEEK_SET);

        ret = write(fd, buffer, SECTOR_SIZE);
        if(ret != SECTOR_SIZE) {
            printf("unable to write boot record\n");
        }

        close(fd2);
    }

    firstFreeBlock = bSector.rootDirectoryOffset +
        roundToNextBlock(sizeof(directoryEntry) * fileArgs) / SECTOR_SIZE;
    printf("first data blocks is %d\n", firstFreeBlock);

    directory =
        (directoryEntry *) malloc(sizeof(directoryEntry) * fileArgs);
    for(i = 0, fileCount = 0; i < fileArgs; i++) {
        int j;
        int numBlocks;
        directoryEntry *dir;

        if(!strcmp(argv[i + curr], "-d")) {
            // treat the next argument as a directory to create
            int writeSubDir = 0;
            i++;

            const char *dirname = argv[i + curr];
            char *ptr;
            if((ptr = strchr(dirname, '/'))) {
                *ptr = '\0';
                ptr++;
                // sub-directory, get the block
                writeSubDir = 1;
                dir = (directoryEntry *) malloc(512);
                strncpy(dir->fileName, ptr, sizeof(dir->fileName));

            } else {
                dir = allocDirEntry(directory);
                fileCount++;
                strncpy(dir->fileName, dirname, sizeof(dir->fileName));
            }

            dir->directory = 1;
            dir->fileSize = SECTOR_SIZE;
            dir->firstBlock = firstFreeBlock;

            fat[firstFreeBlock] = firstFreeBlock + 1;
            ++firstFreeBlock;
            fat[firstFreeBlock++] = FAT_ENTRY_EOF;

            if(writeSubDir) {
                // find the directory entry
                int j;
                for(j = 0; j < fileCount; j++) {
                    if(!strcmp(directory[j].fileName, dirname)) {
                        lseek(fd, directory[j].firstBlock * SECTOR_SIZE,
                              SEEK_SET);
                        write(fd, dir, 512);
                        break;
                    }
                }
                if(i == fileCount)
                    abort();
                writeSubDir = 0;
            }
            continue;
        } else {
            const char *filename = argv[i + curr];

            dir = allocDirEntry(directory);

            dir->firstBlock = firstFreeBlock;

            ret = stat(filename, &sbuf);
            if(ret != 0) {
                printf("buildFat FATAL ERROR: Error stat()ing %s: %s\n",
                       filename, strerror(errno));
                exit(EXIT_FAILURE);
            }
            assert(ret == 0);
            numBlocks = roundToNextBlock(sbuf.st_size) / SECTOR_SIZE;
            dir->fileSize = sbuf.st_size;

            if(writeBoot) {
                if(i == 0) {
                    /* setup.bin */
                    bSector.setupStart = firstFreeBlock;
                    bSector.setupSize = numBlocks;
                    printf("setup file starts at %d, %d sectors long\n",
                           bSector.setupStart, bSector.setupSize);
                } else if(i == 1) {
                    /* kernel.exe */
                    bSector.kernelStart = firstFreeBlock;
                    bSector.kernelSize = numBlocks;
                    printf("kernel file starts at %d, %d sectors long\n",
                           bSector.kernelStart, bSector.kernelSize);
                }
            }
            for(j = 0; j < numBlocks - 1; j++) {
                fat[firstFreeBlock] = firstFreeBlock + 1;
                ++firstFreeBlock;

                if(firstFreeBlock > (diskSize / SECTOR_SIZE)) {
                    printf("Error: %s is full\n", imageFile);
                    exit(-1);
                }
            }
            fat[firstFreeBlock++] = FAT_ENTRY_EOF;

            lseek(fd, dir->firstBlock * SECTOR_SIZE, SEEK_SET);

            /* copy the file to the disk */
            fd2 = open(filename, O_RDONLY, 0);
            assert(fd2 >= 0);   /* failure is -1, not 0 -ns */

            /* Remove leading directory path components */
            if(strrchr(filename, '/') != 0)
                filename = strrchr(filename, '/') + 1;

            if(strlen(filename) > sizeof(dir->fileName)) {
                printf
                    ("warning: file %s name too long, will be truncated!\n",
                     filename);
            }

            /* Set filename in directory entry */
            strncpy(dir->fileName, filename, sizeof(dir->fileName));

            /* 
               printf("file %s starts at block %d\n", dir->fileName, dir->firstBlock);
             */
            lseek(fd, dir->firstBlock * SECTOR_SIZE, SEEK_SET);

            /* copy the file to the disk */
            for(j = 0; j < numBlocks; j++) {
                int ret2;
                char buffer[SECTOR_SIZE];

                ret = read(fd2, buffer, SECTOR_SIZE);
                assert(ret >= 0);
                ret2 = write(fd, buffer, ret);
                assert(ret2 == ret);
            }
            close(fd2);

            fileCount++;
        }
    }

    bSector.rootDirectoryCount = fileCount;

    lseek(fd, SECTOR_SIZE, SEEK_SET);
    ret = write(fd, fat, sizeof(int) * blocks);
    assert(ret == (int)(sizeof(int) * blocks));

    lseek(fd, bSector.rootDirectoryOffset * SECTOR_SIZE, SEEK_SET);
    printf("putting the directory with %d files at sector %d\n",
           fileCount, bSector.rootDirectoryOffset);
    ret = write(fd, directory, sizeof(directoryEntry) * fileCount);
    assert(ret == (int)(sizeof(directoryEntry) * fileCount));

    /* write out boot record */
    lseek(fd, PFAT_BOOT_RECORD_OFFSET, SEEK_SET);
    ret = write(fd, &bSector, sizeof(bSector));
    assert(ret == sizeof(bSector));

    close(fd);

    exit(0);
}
Exemple #3
0
//============== UFS INTERFACE LAYER ==========================
int init_FS(int fd){
	// Boot block dummy block (Because no boot loader nothing...)
	bzero(nullbuf, BLOCKSIZE);
	write(fd, nullbuf, BLOCKSIZE);

	// Initialize variables
	int i;
	nsuperblocks = 1;
	ninodeblocks = 8;
	nbootblocks = 1;
	nrootdirblocks = 1;
	ndatablocks = TOTALBLOCKS - nsuperblocks - ninodeblocks - nbootblocks - nrootdirblocks;
	INODETABLESIZE = (ninodeblocks*BLOCKSIZE)/sizeof(struct INode);
	MAXDIRENTRIES = BLOCKSIZE/ sizeof(struct DirEntry);
	DATABLOCKSTART = BLOCKSIZE*(TOTALBLOCKS - ndatablocks);
	INODEBLOCKSTART = BLOCKSIZE*(nsuperblocks+nbootblocks);
	
	//Initialize super block
	strcpy(s.sb_vname, "root");
	s.sb_ninodes = (ninodeblocks*BLOCKSIZE)/sizeof(struct INode);
	s.sb_nblocks = ndatablocks;
	s.sb_nfreeblocks = s.sb_nblocks;
	s.sb_nfreeinodes = s.sb_ninodes;
	s.sb_flags = 0;
	bzero(s.sb_freeblocks, CACHESIZE);
	bzero(s.sb_freeinodes, CACHESIZE);
	s.sb_freeblockindex = CACHESIZE;
	s.sb_freeinodeindex = CACHESIZE;
	s.sb_chktime = time(NULL);
	s.sb_ctime = time(NULL);
	write(fd, &s, sizeof(struct SuperBlock));
	write(fd, nullbuf, (nsuperblocks*BLOCKSIZE) - sizeof(struct SuperBlock));
	printf("Superblock initialized!\n");

	// Write initialized list of inodes
	nullINode.i_size = 0;
	nullINode.i_atime = 0;
	nullINode.i_ctime = 0;
	nullINode.i_mtime = 0;
	bzero(nullINode.i_blocks, 13);
	nullINode.i_mode = 0;
	nullINode.i_uid = 0;
	nullINode.i_gid = 0;
	nullINode.i_gen = 0;
	nullINode.i_nlinks = 0;
	for(i=0; i<INODETABLESIZE; i++)
		write(fd, &nullINode, sizeof(struct INode));
	write(fd, &nullbuf, BLOCKSIZE%sizeof(struct INode));
	printf("Inodes initialized!\n");

	// Write initialized list of directory entries
	// Fill the remaining empty datablocks
	printf("%d\n",ndatablocks+nrootdirblocks );
	for(i=0; i<ndatablocks+nrootdirblocks; i++)
		write(fd, &nullbuf, BLOCKSIZE);
	printf("All data blocks initialized!\n");

	// Write free block information (data structures)
	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 = 1;
	in.i_uid = 1;
	in.i_nlinks = 0;
	in.i_mode = 0;
	struct DirEntry d;
	bzero(d.d_entry.d_name, MAXNAMELENGTH);
	strcpy(d.d_entry.d_name,".");
	s.sb_rootdir = currDirINode = d.d_entry.d_inode = allocINode(fd, &in);
	d.d_offset = 0;
	allocDirEntry(fd, &in, &d);
	writeInode(fd, s.sb_rootdir, &in);
	updateSB(fd);
	printf("\n");
	o.ofo_inode = NULL;
	o.ofo_mode = o.ofo_ref = 0;
	return 0;
}