コード例 #1
0
int sCreat(int pinum, int type, char *name)
{

	int i,j;
	int newBlockPtr=-1;
	int newDirEnt=-1;
	int newF=1; 
	//Check if valid pinum
	if(pinum<0 || pinum>=NUMINODES)
		return -1;
	//check name size
	if(strlen(name) < 1 || strlen(name) > 60)
		return -1;

	//Get the parent inode
	lseek(fdImage, BYOFF_INODE(pinum), SEEK_SET);
	inode_t pinode;
	read(fdImage, &pinode, sizeof(pinode));
	//should be a directory
	if(pinode.type!=MFS_DIRECTORY)
		return -1;

	//scan all directory entries to check if name already exists, also save the first unassigned directory entry for later use
	dir_t dirBlock;
	for(i=0; i<14; i++)
	{
		if(pinode.blockPtrs[i]!=-1)//valid blockPtr
		{
			//printf("Parent inode:%d points to blockPtr[%d]:%d\n",pinum,i,pinode.blockPtrs[i]);
			//Go to that block
			lseek(fdImage, pinode.blockPtrs[i], SEEK_SET);
			read(fdImage, &dirBlock, sizeof(dir_t));
			//Check all entries in the directory block
			for(j=0; j<NUM_DIR_ENTS; j++)
			{
				if(dirBlock.dirEnt[j].inum!=-1)//valid inode number
				{
					//printf("Valid directory entry number:%d name:%s and inode num:%d\n",j,dirBlock.dirEnt[j].name,dirBlock.dirEnt[j].inum);
					if( strcmp(dirBlock.dirEnt[j].name, name)==0 )//name match
						return 0;//file or directory name already exists so success
				}
				else//unused dirent
				{
					if(newF)//save the first unused dir entry to be overwritten later
					{
						//printf("Parent inode:%d points to blockPtr[%d]:%d\n",pinum,i,pinode.blockPtrs[i]);
						//printf("Within parent inode the first unused dir ent is %d\n",j);
						newBlockPtr=i;
						newDirEnt=j;
						newF=0;
					}
				}
			}
		}
	}

	//TODO
	//Corner case where no unused dirEntry was found. Meaning we have to assign a whole new data block of directory entries and update the pinode size
	//This could fail if all the data blocks of this directory are filled with valid data entries. No room for more


	//Find a free inode number
	int freeInode= getFreeInum();	
	if(freeInode<0)//no free inode was found then no more space for new files
		return -1;

	int d=-1;	
	//if directory type then initialize it with . and .. directory ent
	if(type==MFS_DIRECTORY)
	{
		d = allocDataBlock();
		if(d<0)//out of data blocks
			return -1;
		//printf("Dir Inode:%d with data block:%d\n",freeInode,d);
	}
		
	//Create the new inode
	allocInode(type, freeInode, d);
	if(type==MFS_DIRECTORY)//and initialize it if directory
	{
		assert(d!=-1);
		dirDataInit(freeInode, pinum, d);
	}
	
	//Write the name:inum directory entry
	//Go to the parent directory's data block
	lseek(fdImage, pinode.blockPtrs[newBlockPtr], SEEK_SET);
	read(fdImage, &dirBlock, sizeof(dir_t));
	//Edit the unused directory entry inside it
	dirBlock.dirEnt[newDirEnt].inum=freeInode;
	sprintf(dirBlock.dirEnt[newDirEnt].name, name);
	//Write down the updated directory entry data block	
	lseek(fdImage, pinode.blockPtrs[newBlockPtr], SEEK_SET);
	write(fdImage, &dirBlock, sizeof(dir_t));

	//printf("New inode number:%d and name:%s and directory blockPtr:%d entry number:%d\n", freeInode, name, newBlockPtr, newDirEnt);
	fsync(fdImage);
	return 0;
}
コード例 #2
0
ファイル: mkfs.wufs.c プロジェクト: mammothbane/wufs
/*
 * Build the initial inodes.
 * inode 1 is always the root directory (identifiable by the fact that . == ..)
 * inode 2 (and possibly others) are files to hold the identifiable bad blocks.
 */
void buildInodes(void)
{
  Inode = (struct wufs_inode *)calloc(SB->sb_inodes,sizeof(struct wufs_inode));
  if (!Inode) {
    fprintf(stderr,"Could not allocated memory for the inodes.\n");
    exit(1);
  }
  
  /* create root directory file: */

  /*  1. allocate the inode */
  int rootInode = allocInode(); /* allocate a directory */
  struct wufs_inode *rino = &Inode[rootInode-1];
  rino->in_mode = S_IFDIR + 0755; /* mark as directory */

  /*  2. allocate space for the directory file */
  int rootDir = allocBlock();	/* allocate directory store */
  RootDir = (struct wufs_dirent *)calloc(WUFS_BLOCKSIZE,1);
  if (!RootDir) {
    fprintf(stderr,"Could not allocate memory to hold root directory image.\n");
    exit(1);
  }
  rino->in_block[0] = rootDir;

  /* tell me something I don't know */
  if (Verbose) {
    fprintf(stderr,"Root directory is at inode %d, using block %d.\n",
	    rootInode, rootDir);
  }

  /*  3. populate the directory file: */
  struct wufs_dirent *dp = RootDir;
  /* ... add "." directory */
  dp->de_ino = rootInode;
  strcpy(dp->de_name,".");
  rino->in_size += WUFS_DIRENTSIZE;
  rino->in_nlinks++;
  dp++;

  /* ... add ".." directory */
  dp->de_ino = rootInode;
  strcpy(dp->de_name,"..");
  rino->in_size += WUFS_DIRENTSIZE;
  rino->in_nlinks++;
  dp++;

  /* We now collect all the bad blocks, bundled together into exactly one "file" */
  /* keep count of remaining bad blocks to be bundled */
  int bbc = BadBlocks;
  if (bbc) {
    int bblock = SB->sb_first_block; /* first possible bad block */
    
    /* ... add bad block file to root dir */
    char* fileName = ".badblockfilexactlythirtychars";
    if (Verbose) {
      fprintf(stderr,"Placing the following bad blocks in /%s:\n", fileName);
    }
    /* 
     * first, we check to see if we can add another bad block file without
     * extending the root directory to a second block.  If so, we give up.
     * (Woof.  This system is a dog.)
     */
    if ((dp - RootDir) >= WUFS_DIRENTS_PER_BLOCK) {
      fprintf(stderr,"Too many bad blocks to store in root directory.\n");
      exit(1);
    }

    if (bbc > SB->sb_max_fsize) {
      fprintf(stderr, "Too many bad blocks to write to a single file.\n");
      exit(1);
    }
  
    /* allocate inode to hold some bad block pointers */
    int bbinonum = allocInode();
    struct wufs_inode *bbino = &Inode[bbinonum-1];
    int n = 0;

    /* create indirect block if necessary */
    if (bbc > WUFS_INODE_DIRECT) {
      indirect = calloc(1, sizeof(struct wufs_bptr));
    }

    /* place several bad blocks into this file */
    while (bbc && (n < WUFS_INODE_PTR_CT)) {
      bblock = findNextSet(BMap,bblock,SB->sb_blocks);
      /* sanity check: shouldn't run out of bad blocks before bbc hits zero */
      if (bblock == -1) {
	fprintf(stderr,"Internal error: lost bad block while building root directory.\n");
	exit(1);
      }
      /* take care: step over root directory block (only one allocated) */
      if (bblock != rootDir) {
	if (Verbose) {
	  fprintf(stderr," %d",bblock); fflush(stderr);
	}
	if (n < WUFS_INODE_DIRECT) {
	  bbino->in_block[n] = bblock;
	} else {
	  indirect->bp_block[n - WUFS_INODE_DIRECT] = bblock;
	}
	/* one more bad block, taken care of */
	n++;
	bbino->in_size += WUFS_BLOCKSIZE;
	bbc--;
      }
      bblock++;
    }

    if (indirect) {
      indirect_addr = bbino->in_block[WUFS_INODE_BPTRS - 1] = allocBlock();
      if (Verbose) fprintf(stderr, "\nrequired indirect block at address %d.", indirect_addr);
    }

    if (Verbose) {
      fprintf(stderr,"\n");
    }
      
    /* add the file to the root directory */
    dp->de_ino = bbinonum;
    strncpy(dp->de_name,fileName,WUFS_NAMELEN);
    rino->in_size += WUFS_DIRENTSIZE;
    bbino->in_nlinks++;
    dp++;
  }
}
コード例 #3
0
void initImage(char *imgName)
{
	int i=0;
	fdImage=open(imgName, O_RDWR);
	
	//Image does not exist
	if(fdImage<0)
	{
		fdImage=open(imgName, O_RDWR | O_CREAT, S_IRWXU);

		//create new super block
		superblock_t superblock;
		superblock.size=4;// 5: 1.unused, 2.superblock, 3.inode-block, 4.bitmap-block, 5.1st data block
		superblock.nblocks=0;//1 data block to hold root directory entries
		superblock.ninodes=0;//only root inode
		//Get to start of superblock
		lseek(fdImage, BYOFF_SUPER, SEEK_SET);
		//write the super block
		write(fdImage, &superblock, sizeof(superblock_t));
		super=superblock;

		//Create all the inodes and mark them as unused
		lseek(fdImage, BYOFF_INODE(0), SEEK_SET);
		inode_t inode;
		for(i=0; i<14; i++)
			inode.blockPtrs[i]=-1;//data block pointers unassigned
		inode.type=MFS_UNUSED;//unused inode
		inode.size=0;//No data blocks for the inode
		for (i=0; i<NUMINODES; i++)
		{
			lseek(fdImage, BYOFF_INODE(i), SEEK_SET);
			write(fdImage, &inode, sizeof(inode_t));
		}

		//Set the datablock bitmap to all zeros
		char zeroBuffer[MFS_BLOCK_SIZE];
		memset(zeroBuffer,0, sizeof(zeroBuffer));
		lseek(fdImage,BYOFF_BIT(0),SEEK_SET);
		write(fdImage, &zeroBuffer, sizeof(zeroBuffer));
		
		//Allocate and write the root inode
		allocInode(MFS_DIRECTORY, ROOTINO, 0);
		//Find a free data block and set it marked to used in the data bitmap
		int freeBlock=allocDataBlock();
		//First root directory data block
		dirDataInit(ROOTINO, ROOTINO, freeBlock);//initialize with . and ..	
	
		//int 
		//int freeInode=getFreeInum();
		//allocInode(MFS_DIRECTORY, freeInode, );
	
		//Test by another inode
		//printf("Test BYOFF_BLOCK(0):%d BYOFF_BLOCK(1):%d BYOFF_BLOCK(2):%d\n",BYOFF_BLOCK(0), BYOFF_BLOCK(1), BYOFF_BLOCK(2));
		
		fsync(fdImage);
	}
	else
	{
		//Do nothing for now
		//Get to start of superblock
		lseek(fdImage, BYOFF_SUPER, SEEK_SET);
		//read the super block
		read(fdImage, &super, sizeof(superblock_t));
	}
}