Example #1
0
int rd_creat(char* pathname){
	char *dir_path;
	char *filename;
	split_dir_file(pathname, &dir_path, &filename);
	int dir_inode_num = get_dir_inode(dir_path, 1); //check if dir_path exists
	if(dir_inode_num == -1){
		return -1;
	}
	int tmp = get_dir_entry(dir_inode_num, filename, 1);
	if(tmp != -1){
		//directory already exists
		printf("error: dir already exists\n");
		return -1;
	}
	//get ready to allocate inode
	int index = get_free_inode();
	if(index == -1){
		printf("no free inodes\n");
		return -1;
	}
	s_block->free_inodes = s_block->free_inodes - 1;
	init_inode(index, 2); //type = 2, regular file
	
	inode_array[dir_inode_num].size = inode_array[dir_inode_num].size + sizeof(dir_entry);
	dir_entry* new_dir = get_free_dir_entry(dir_inode_num);
	new_dir->inode_number = index;
	strcpy(new_dir->filename, filename);		

	printf("rd_creat created a file\n");
	return 1;
}
Example #2
0
/*===========================================================================*
 *				go_down					     *
 *===========================================================================*/
static int go_down(
	char path[PATH_MAX],    /* path to add the name to */
	struct inode *parent,   /* inode of the current directory */
	char *name,             /* name of the directory entry */
	struct inode **res_ino, /* place to store resulting inode */
	struct sffs_attr *attr  /* place to store inode attributes */
)
{
/* Given a directory inode and a name, progress into a directory entry.
 */
  struct inode *ino;
  int r, stale = 0;

  if ((r = push_path(path, name)) != OK)
	return r;

  dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path));

  ino = lookup_dentry(parent, name);

  dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino));

  if (ino != NULL)
	r = verify_path(path, ino, attr, &stale);
  else
	r = sffs_table->t_getattr(path, attr);

  dprintf(("%s: path query returned %d\n", sffs_name, r));

  if (r != OK) {
	if (ino != NULL) {
		put_inode(ino);

		ino = NULL;
	}

	if (!stale)
		return r;
  }

  dprintf(("%s: name '%s'\n", sffs_name, name));

  if (ino == NULL) {
	if ((ino = get_free_inode()) == NULL)
		return ENFILE;

	dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref));

	ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode);

	add_dentry(parent, name, ino);
  }

  *res_ino = ino;
  return OK;
}
Example #3
0
/** Create a directory */
int nphfuse_mkdir(const char *path, mode_t mode){
    // char *filename, *dir;
    // extract_directory_file(&dir,&filename,path);
    struct timeval currTime;
    npheap_store *inode = NULL;
    char dir[236];
    char filename[128];
    uint64_t findex = -1;
    log_msg("Into mkdir functionality.\n");
    inode = get_free_inode(&findex);

    //If empty directory not found
    if(inode == NULL){
        log_msg("Empty Directory not found. \n");
        return -ENOENT; 
    }

    //Get directory and filename
    int extract = extract_directory_file(dir, filename, path);
    if(extract == 1){
        log_msg("Extraction failed. \n");
        return -EINVAL;
    }

    log_msg("Directory %s and Filename is %s \n", dir, filename);

    memset(inode, 0, sizeof(npheap_store));
    strcpy(inode->dirname, dir);
    strcpy(inode->filename, filename);

    inode->mystat.st_ino = inode_off;
    inode_off++;
    inode->mystat.st_mode = S_IFDIR | mode;
    inode->mystat.st_gid = getgid();
    inode->mystat.st_uid = getuid();
    inode->mystat.st_size = BLOCK_SIZE/2;
    inode->mystat.st_nlink = 2;

    gettimeofday(&currTime, NULL);
    inode->mystat.st_atime = currTime.tv_sec;
    inode->mystat.st_mtime = currTime.tv_sec;
    inode->mystat.st_ctime = currTime.tv_sec;

    log_msg("mkdir executed successfully.! %d st_ino\n", inode->mystat.st_ino);

    return 0;
}
Example #4
0
int main(int argc, char const *argv[]){
	if(argc != 4) {
        fprintf(stderr, "Usage: ext2_cp <formatted virtual disk> <local path> <absolute disk path>\n");
        exit(1);
    }

    int fd = open(argv[1], O_RDWR);

    disk = mmap(NULL, 128 * EXT2_BLOCK_SIZE, PROT_READ 
    						| PROT_WRITE, MAP_SHARED, fd, 0);

    if(disk == MAP_FAILED) {
		perror("mmap");
		exit(1);
    }

    FILE * fp;
    fp = fopen(argv[2], "r");
    if (fp == NULL) {
    	printf("File not found\n");
    	exit(ENOENT);
    }
    //get file size
    fseek(fp, 0L, SEEK_END);
    int file_sz = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    //number of blocks needed to copy file
    int num_blocks_needed = (int) (file_sz / EXT2_BLOCK_SIZE) + 1;

    //get the superblock 
    struct ext2_super_block *superblock = (struct ext2_super_block *)
    										(disk + EXT2_BLOCK_SIZE);

    int first_data_block = superblock->s_first_data_block;

    if (num_blocks_needed > superblock->s_free_blocks_count){
    	fprintf(stderr, "No space left on device\n");
    	exit(ENOSPC);
    }

	// get the group descriptor table
	// we know that this table always start at third datablock (index 2)
	struct ext2_group_desc *group_des_table = (struct ext2_group_desc*)
												(disk + EXT2_BLOCK_SIZE * 2);
	int inode_bitmap = group_des_table->bg_inode_bitmap;
	int block_bitmap = group_des_table->bg_block_bitmap;
	int inode_table = group_des_table->bg_inode_table;
	void *tablestart = disk + EXT2_BLOCK_SIZE * inode_table;

	//check that the path does not already exist
	int found_inode;
	found_inode = search_inode(argv[3]);
    if (found_inode != -1){ // has to be not found
    	fprintf(stderr, "File exists\n");
        exit(EEXIST);
    }

    //get the parent directory into which to copy the file
    int parent_inode_num = parent_conversion(argv[3]);
    if (parent_inode_num == -1){
    	fprintf(stderr, "No such file or directory\n");
    	exit(ENOENT);
    }

    //get the inode of that parent directory
    struct ext2_inode *parent_inode = (struct ext2_inode*)
    									(tablestart) + (parent_inode_num - 1);
    if (parent_inode->i_mode & EXT2_S_IFREG){
    	fprintf(stderr, "No such file or directory\n");
    	exit(ENOENT); 
    }

	//get block bitmap
    int block_bitmap_block = block_bitmap * EXT2_BLOCK_SIZE;
    void * block_bits = (void *)(disk + block_bitmap_block);

    //get inode bitmap
    unsigned long inode_bitmap_block = inode_bitmap * EXT2_BLOCK_SIZE;
    void * inode_bits = (void *)(disk + inode_bitmap_block);

    //find free inode
    int inode_indx = get_free_inode(inode_bits);

    if (inode_indx == -1){
    	fprintf(stderr, "No space left on device\n");
    	exit(ENOSPC);
    }

    //update superblock
    superblock->s_free_inodes_count = superblock->s_free_inodes_count - 1;
    
    //init new inode
    struct ext2_inode *new_inode = (struct ext2_inode*)(tablestart) 
    													+ (inode_indx);
    new_inode->i_mode = 32768; //is file
    new_inode->i_size = file_sz;
    new_inode->i_blocks = 1;
    new_inode->i_links_count = 1;

    //global variables for indirect block if necessary
    void *indirect_block;
    unsigned int indr_block[15];
    void *data_block;

    int i;
    for (i = 0; i < num_blocks_needed; i++){
    	if (i < 12){
    		int free_block_num = get_free_block(block_bits);
    		if (free_block_num == -1){
    			fprintf(stderr, "No space left on device\n");
    			exit(ENOSPC);
    		}
    		superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1;
    		new_inode->i_blocks += 1;
    		new_inode->i_block[i] = first_data_block + free_block_num -1;
    		data_block = (void *)(disk + (EXT2_BLOCK_SIZE * 
    													new_inode->i_block[i]));

    	}	
    	else if (i == 12){
    		//i_blocks[12] entry is the 13th entry in the array
    		//It holds the block number of the indirect block
    		//- this block contains an array of block numbers 
    		//for the next data blocks of the file.
    		//get free block for indirect block
    		int indirect_block_num = get_free_block(block_bits);
    		if (indirect_block_num == -1){
    			fprintf(stderr, "No space left on device\n");
    			exit(ENOSPC);
    		}
    		new_inode->i_block[i] = first_data_block + indirect_block_num;
    		//initialize indirect block
    		indirect_block = (void *)(disk + (EXT2_BLOCK_SIZE 
    											* new_inode->i_block[i]));
    		//get data block
    		int free_block_num = get_free_block(block_bits);
    		if (free_block_num == -1){
    			fprintf(stderr, "No space left on device\n");
    			exit(ENOSPC);
    		}
    		superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1;
    		new_inode->i_blocks += 1;
    		indr_block[i - 12] = first_data_block + free_block_num -1;
    		memcpy(indirect_block, (void *) indr_block, 16);
    		data_block = (void *)(disk + (EXT2_BLOCK_SIZE * indr_block[i - 12]));
    	}
    	else if (i > 12){
    		int free_block_num = get_free_block(block_bits);
    		if (free_block_num == -1){
    			fprintf(stderr, "No space left on device\n");
    			exit(ENOSPC);
    		}
    		superblock->s_free_blocks_count = superblock->s_free_blocks_count - 1;
    		new_inode->i_blocks += 1;
    		indr_block[i - 12] = first_data_block + free_block_num -1;
    		memcpy(indirect_block, (void *) indr_block, 16);
    		data_block = (void *)(disk + (EXT2_BLOCK_SIZE * indr_block[i - 12]));
    	}

    	//read data from file to data block
    	int num_read = fread(data_block, 1, EXT2_BLOCK_SIZE, fp);
    	if (num_read == 0){
    		perror("Error reading file");
    	}
    }

    fclose(fp);

    //add this new file's directory entry to the parent directory
    int c;
    //loop through directory entries to get to the last entry
    for (c = 0; c < EXT2_BLOCK_SIZE;){
    	struct ext2_dir_entry_2 *node_dir = (struct ext2_dir_entry_2 *)
    				(disk + (EXT2_BLOCK_SIZE * parent_inode->i_block[0]) + c);

    	if (c + node_dir->rec_len == EXT2_BLOCK_SIZE){
    		//this is the last block in the directory
			int new_rec_len = node_dir->rec_len - node_dir->name_len - 8;
			node_dir->rec_len = node_dir->name_len + 8;

			//create directory entry
		    struct ext2_dir_entry_2 *par_dir = (struct ext2_dir_entry_2 *)
		    		(disk + (EXT2_BLOCK_SIZE * parent_inode->i_block[0] 
		    		+ c + node_dir->rec_len));

		    par_dir->inode = inode_indx + 1;
		    par_dir->file_type = 1;

		    //get name of new file
		    char dup_path[strlen(argv[3])];
		    strcpy(dup_path, argv[3]);
		    char *ret;
		    ret = strrchr(dup_path, '/');
		    if (ret[0] == '/'){
		    	ret++;
		    }
		    par_dir->rec_len = new_rec_len;
		    par_dir->name_len = strlen(ret);
		    strcpy(par_dir->name, ret);
		    break;
    	}
    	c += node_dir->rec_len;
    }
    return 0;
}
Example #5
0
/** Create a file node
 *
 * There is no create() operation, mknod() will be called for
 * creation of all non-directory, non-symlink nodes.
 */
int nphfuse_mknod(const char *path, mode_t mode, dev_t dev){
    struct timeval currTime;
    npheap_store *inode = NULL;
    char dir[236];
    char filename[128];
    char *blk_data = NULL;
    uint64_t findex = -1;
    log_msg("Into mkdir functionality.\n");
    inode = get_free_inode(&findex);

    //If empty directory not found
    if(inode == NULL){
        log_msg("Empty Directory not found. \n");
        return -ENOENT; 
    }

    //Get directory and filename
    int extract = extract_directory_file(dir, filename, path);
    if(extract == 1){
        log_msg("Extraction failed. \n");
        return -EINVAL;
    }

    log_msg("Directory %s and Filename is %s \n", dir, filename);

    memset(inode, 0, sizeof(npheap_store));
    strcpy(inode->dirname, dir);
    strcpy(inode->filename, filename);

    // Set mystat
    inode->mystat.st_ino = inode_off;
    inode_off++;
    inode->mystat.st_mode = mode;
    inode->mystat.st_gid = getgid();
    inode->mystat.st_uid = getuid();
    inode->mystat.st_dev = dev;
    inode->mystat.st_nlink = 1;

    gettimeofday(&currTime, NULL);
    inode->mystat.st_atime = currTime.tv_sec;
    inode->mystat.st_mtime = currTime.tv_sec;
    inode->mystat.st_ctime = currTime.tv_sec;


    //Set the offset for data object
    while(npheap_getsize(npheap_fd, data_off) != 0 && data_off < 10000){
        log_msg("Offset already in use - %d\n", data_off);
        data_off++;
    }

    blk_data  = (char *)npheap_alloc(npheap_fd, data_off, BLOCK_SIZE);

    //Check if allocated
    if(blk_data == NULL){
        log_msg("Data block, couldn't be allocated\n");
        memset(inode, 0, sizeof(npheap_store));
        inode_off--;
        return -ENOMEM;
    }

    //Everything worked fine
    memset(blk_data, 0, BLOCK_SIZE);
    blk_array[data_off] = blk_data;
    inode->offset = data_off;
    log_msg("mknod ran successfully in NPHeap for %d data offset\n", data_off);
    data_off++;
    return 0;
}
int mk_new_directory(jfs_t *jfs, char *pathname, 
		      int parent_inodenum, int grandparent_inodenum) 
{
    /* we need to create this directory */
    /* round size up to nearest 4 byte boundary */
    int size, prev_size, bytes_done=0;
    int new_inodenum, new_blocknum;
    char block[BLOCKSIZE];
    struct inode* new_inode, *parent_inode;

    /* calculate the size of the new parent dirent */
    size = (((strlen(pathname)/4) + 1) * 4) + 16;

    /* does it fit?*/
    if (bytes_done + size > BLOCKSIZE) {
	fprintf(stderr,
		"No more space in the directory to add another entry\n");
	exit(1);
    }

    /* allocate an inode for this directory */
    if (strcmp(pathname, ".")==0) {
	new_inodenum = parent_inodenum;
    } else if (strcmp(pathname, "..")==0) {
	new_inodenum = grandparent_inodenum;
    } else {
	new_inodenum = get_free_inode(jfs);
    }


    /* update the parent directories inode size field */
    jfs_read_block(jfs, block, inode_to_block(parent_inodenum));
    parent_inode = (struct inode*)(block + (parent_inodenum % INODES_PER_BLOCK)
				   * INODE_SIZE);

    prev_size = parent_inode->size;
    parent_inode->size += size;
    jfs_write_block(jfs, block, inode_to_block(parent_inodenum));

    /* create an entry in the parent directory */
    create_dirent(jfs, pathname, DT_DIRECTORY, parent_inode->blockptrs[0],
		  prev_size, size, new_inodenum);


    if (strcmp(pathname, ".")!=0 && strcmp(pathname, "..")!=0) {
	/* it's a real directory */

	/* get a block to hold the directory */
	new_blocknum = get_free_block(jfs);

	/* read in the block that contains our new inode */
	jfs_read_block(jfs, block, inode_to_block(new_inodenum));
	
	new_inode = (struct inode*)(block + (new_inodenum % INODES_PER_BLOCK)
				    * INODE_SIZE);
	new_inode->flags = FLAG_DIR;
	new_inode->blockptrs[0] = new_blocknum;
	new_inode->size = 0;
	
	/* write back the inode block */
	jfs_write_block(jfs, block, inode_to_block(new_inodenum));
	return new_inodenum;
    }

    return parent_inodenum;
}
Example #7
0
/*===========================================================================*
 *				do_create				     *
 *===========================================================================*/
PUBLIC int do_create()
{
/* Create a new file.
 */
  char path[PATH_MAX], name[NAME_MAX+1];
  struct inode *parent, *ino;
  struct hgfs_attr attr;
  hgfs_file_t handle;
  int r;

  /* We cannot create files on a read-only file system. */
  if (state.read_only)
	return EROFS;

  /* Get path, name, parent inode and possibly inode for the given path. */
  if ((r = get_name(m_in.REQ_GRANT, m_in.REQ_PATH_LEN, name)) != OK)
	return r;

  if (!strcmp(name, ".") || !strcmp(name, "..")) return EEXIST;

  if ((parent = find_inode(m_in.REQ_INODE_NR)) == NULL)
	return EINVAL;

  if ((r = verify_dentry(parent, name, path, &ino)) != OK)
	return r;

  /* Are we going to need a new inode upon success?
   * Then make sure there is one available before trying anything.
   */
  if (ino == NULL || ino->i_ref > 1 || HAS_CHILDREN(ino)) {
	if (!have_free_inode()) {
		if (ino != NULL)
			put_inode(ino);

		return ENFILE;
	}
  }

  /* Perform the actual create call. */
  r = hgfs_open(path, O_CREAT | O_EXCL | O_RDWR, m_in.REQ_MODE, &handle);

  if (r != OK) {
	/* Let's not try to be too clever with error codes here. If something
	 * is wrong with the directory, we'll find out later anyway.
	 */

	if (ino != NULL)
		put_inode(ino);

	return r;
  }

  /* Get the created file's attributes. */
  attr.a_mask = HGFS_ATTR_MODE | HGFS_ATTR_SIZE;
  r = hgfs_getattr(path, &attr);

  /* If this fails, or returns a directory, we have a problem. This
   * scenario is in fact possible with race conditions.
   * Simulate a close and return a somewhat appropriate error.
   */
  if (r != OK || S_ISDIR(attr.a_mode)) {
	printf("HGFS: lost file after creation!\n");

	hgfs_close(handle);

	if (ino != NULL) {
		del_dentry(ino);

		put_inode(ino);
	}

	return (r == OK) ? EEXIST : r;
  }

  /* We do assume that the HGFS open(O_CREAT|O_EXCL) did its job.
   * If we previousy found an inode, get rid of it now. It's old.
   */
  if (ino != NULL) {
	del_dentry(ino);

	put_inode(ino);
  }

  /* Associate the open file handle with an inode, and reply with its details.
   */
  ino = get_free_inode();

  assert(ino != NULL); /* we checked before whether we had a free one */

  ino->i_file = handle;
  ino->i_flags = I_HANDLE;

  add_dentry(parent, name, ino);

  m_out.RES_INODE_NR = INODE_NR(ino);
  m_out.RES_MODE = get_mode(ino, attr.a_mode);
  m_out.RES_FILE_SIZE_HI = ex64hi(attr.a_size);
  m_out.RES_FILE_SIZE_LO = ex64lo(attr.a_size);
  m_out.RES_UID = opt.uid;
  m_out.RES_GID = opt.gid;
  m_out.RES_DEV = NO_DEV;

  return OK;
}
Example #8
0
File: read.c Project: Sciumo/minix
/*===========================================================================*
 *				do_getdents				     *
 *===========================================================================*/
int do_getdents()
{
/* Retrieve directory entries.
 */
  char name[NAME_MAX+1];
  struct inode *ino, *child;
  struct dirent *dent;
  struct sffs_attr attr;
  size_t len, off, user_off, user_left;
  off_t pos;
  int r;
  /* must be at least sizeof(struct dirent) + NAME_MAX */
  static char buf[BLOCK_SIZE];

  attr.a_mask = SFFS_ATTR_MODE;

  if ((ino = find_inode(m_in.REQ_INODE_NR)) == NULL)
	return EINVAL;

  if (m_in.REQ_SEEK_POS_HI != 0) return EINVAL;

  if (!IS_DIR(ino)) return ENOTDIR;

  /* We are going to need at least one free inode to store children in. */
  if (!have_free_inode()) return ENFILE;

  /* If we don't have a directory handle yet, get one now. */
  if ((r = get_handle(ino)) != OK)
	return r;

  off = 0;
  user_off = 0;
  user_left = m_in.REQ_MEM_SIZE;

  /* We use the seek position as file index number. The first position is for
   * the "." entry, the second position is for the ".." entry, and the next
   * position numbers each represent a file in the directory.
   */
  for (pos = m_in.REQ_SEEK_POS_LO; ; pos++) {
	/* Determine which inode and name to use for this entry.
	 * We have no idea whether the host will give us "." and/or "..",
	 * so generate our own and skip those from the host.
	 */
	if (pos == 0) {
		/* Entry for ".". */
		child = ino;

		strcpy(name, ".");

		get_inode(child);
	}
	else if (pos == 1) {
		/* Entry for "..", but only when there is a parent. */
		if (ino->i_parent == NULL)
			continue;

		child = ino->i_parent;

		strcpy(name, "..");

		get_inode(child);
	}
	else {
		/* Any other entry, not being "." or "..". */
		r = sffs_table->t_readdir(ino->i_dir, pos - 2, name,
			sizeof(name), &attr);

		if (r != OK) {
			/* No more entries? Then close the handle and stop. */
			if (r == ENOENT) {
				put_handle(ino);

				break;
			}

			/* FIXME: what if the error is ENAMETOOLONG? */
			return r;
		}

		if (!strcmp(name, ".") || !strcmp(name, ".."))
			continue;

		if ((child = lookup_dentry(ino, name)) == NULL) {
			child = get_free_inode();

			/* We were promised a free inode! */
			assert(child != NULL);

			child->i_flags = MODE_TO_DIRFLAG(attr.a_mode);

			add_dentry(ino, name, child);
		}
	}

	len = DWORD_ALIGN(sizeof(struct dirent) + strlen(name));

	/* Is the user buffer too small to store another record?
	 * Note that we will be rerequesting the same dentry upon a subsequent
	 * getdents call this way, but we really need the name length for this.
	 */
	if (user_off + off + len > user_left) {
		put_inode(child);

		/* Is the user buffer too small for even a single record? */
		if (user_off == 0 && off == 0)
			return EINVAL;

		break;
	}

	/* If our own buffer cannot contain the new record, copy out first. */
	if (off + len > sizeof(buf)) {
		r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT,
			user_off, (vir_bytes) buf, off, D);

		if (r != OK) {
			put_inode(child);

			return r;
		}

		user_off += off;
		user_left -= off;
		off = 0;
	}

	/* Fill in the actual directory entry. */
	dent = (struct dirent *) &buf[off];
	dent->d_ino = INODE_NR(child);
	dent->d_off = pos;
	dent->d_reclen = len;
	strcpy(dent->d_name, name);

	off += len;

	put_inode(child);
  }

  /* If there is anything left in our own buffer, copy that out now. */
  if (off > 0) {
	r = sys_safecopyto(m_in.m_source, m_in.REQ_GRANT, user_off,
		(vir_bytes) buf, off, D);

	if (r != OK)
		return r;

	user_off += off;
  }

  m_out.RES_SEEK_POS_HI = 0;
  m_out.RES_SEEK_POS_LO = pos;
  m_out.RES_NBYTES = user_off;

  return OK;
}
Example #9
0
int create_file(char *path, int is_dir)
{
    char *lpath = malloc(sizeof(char)*strlen(path)+1);
    char *last;
    char *ptr;
    int wd, free_inode_num, found, s;

    struct inode_block *cur_inode_block = NULL;
    struct inode *cur_inode = NULL;

    strcpy(lpath, path);

    if(strlen(lpath) == 1)
    {
        if(lpath[0] == '/')
        {
            return ERR_FILE_EXISTS;
        }
        else
        {
            return ERR_INVALID_PATH;
        }
    }

    ptr = strrchr(lpath, '/');


    if(ptr == lpath+strlen(lpath)-1)
    {
        *ptr = '\0';
        ptr = strrchr(lpath, '/');
    }

    *ptr = '\0';
    ptr++;

    last = malloc(sizeof(char)*strlen(ptr)+1);

    strcpy(last, ptr);

    wd = path_to_inode(lpath);

    DEBUG1 &&  printf("wd = %d \n", wd);

    if(wd < 0)
    {
        return ERR_INVALID_PATH;
    }
    //printf("wd inode = %d \n", wd);

    get_inode(&cur_inode_block, &cur_inode, wd);

    if(cur_inode_block == NULL || cur_inode == NULL)
    {
        DEBUG2 && 	printf("get inode failed\n");
        return ERR_INTERNAL;
    }

    found = has_file(cur_inode, last);
    //printf("found = %d \n", found);
    DEBUG1 && printf("found = %d \n", found);

    if(found != -1)
    {
        //printf("file or dir already exists!\n");
        //printf("wd = %d, last = %s \n ", wd, last);
        return ERR_FILE_EXISTS;
    }

    free_inode_num = get_free_inode();
    //printf("free inode num = %d\n", free_inode_num);

    if(free_inode_num < 0)
    {
        return ERR_MAX_FILES;
    }

    get_inode( &cur_inode_block, &cur_inode , free_inode_num);

    if(cur_inode_block == NULL || cur_inode == NULL)
    {
        return ERR_INTERNAL;
    }

    cur_inode->is_dir = is_dir;

    put_inode_block(cur_inode_block, free_inode_num);

    //free_data_block_num = get_free_datablock();
    //printf("free_data_block_num = %d\n", free_data_block_num);

    s = add_dir_to_inode(wd, last, free_inode_num);

    return s;
}
Example #10
0
File: read.c Project: Hooman3/minix
/*===========================================================================*
 *				do_getdents				     *
 *===========================================================================*/
ssize_t do_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
	off_t *posp)
{
/* Retrieve directory entries.
 */
  struct fsdriver_dentry fsdentry;
  char name[NAME_MAX+1];
  struct inode *ino, *child;
  struct sffs_attr attr;
  off_t pos;
  int r;
  /* must be at least sizeof(struct dirent) + NAME_MAX */
  static char buf[BLOCK_SIZE];

  if ((ino = find_inode(ino_nr)) == NULL)
	return EINVAL;

  if (!IS_DIR(ino)) return ENOTDIR;

  if (*posp < 0 || *posp >= ULONG_MAX) return EINVAL;

  /* We are going to need at least one free inode to store children in. */
  if (!have_free_inode()) return ENFILE;

  /* If we don't have a directory handle yet, get one now. */
  if ((r = get_handle(ino)) != OK)
	return r;

  fsdriver_dentry_init(&fsdentry, data, bytes, buf, sizeof(buf));

  /* We use the seek position as file index number. The first position is for
   * the "." entry, the second position is for the ".." entry, and the next
   * position numbers each represent a file in the directory.
   */
  do {
	/* Determine which inode and name to use for this entry.
	 * We have no idea whether the host will give us "." and/or "..",
	 * so generate our own and skip those from the host.
	 */
	pos = (*posp)++;

	if (pos == 0) {
		/* Entry for ".". */
		child = ino;

		strcpy(name, ".");

		get_inode(child);
	}
	else if (pos == 1) {
		/* Entry for "..", but only when there is a parent. */
		if (ino->i_parent == NULL)
			continue;

		child = ino->i_parent;

		strcpy(name, "..");

		get_inode(child);
	}
	else {
		/* Any other entry, not being "." or "..". */
		attr.a_mask = SFFS_ATTR_MODE;

		r = sffs_table->t_readdir(ino->i_dir, pos - 2, name,
			sizeof(name), &attr);

		if (r != OK) {
			/* No more entries? Then close the handle and stop. */
			if (r == ENOENT) {
				put_handle(ino);

				break;
			}

			/* FIXME: what if the error is ENAMETOOLONG? */
			return r;
		}

		if (!strcmp(name, ".") || !strcmp(name, ".."))
			continue;

		if ((child = lookup_dentry(ino, name)) == NULL) {
			child = get_free_inode();

			/* We were promised a free inode! */
			assert(child != NULL);

			child->i_flags = MODE_TO_DIRFLAG(attr.a_mode);

			add_dentry(ino, name, child);
		}
	}

	r = fsdriver_dentry_add(&fsdentry, INODE_NR(child), name, strlen(name),
		IS_DIR(child) ? DT_DIR : DT_REG);

	put_inode(child);

	if (r < 0)
		return r;
  } while (r > 0);

  return fsdriver_dentry_finish(&fsdentry);
}
Example #11
0
/** Creates and fills in a gd_fs_entry_t from an <entry>...</entry> in xml.
 *
 *  @xml  the xml containing the entry
 *  @node the node representing this <entry>...</entry> block
 *
 *  @returns pointer to gd_fs_entry_t with fields filled in as needed
 */
struct gd_fs_entry_t* gd_fs_entry_from_xml(xmlDocPtr xml, xmlNodePtr node)
{
    struct gd_fs_entry_t* entry;
    unsigned long inode = 0;

    entry = (struct gd_fs_entry_t*) malloc(sizeof(struct gd_fs_entry_t));
    if(entry == NULL) {} // TODO: ERROR
    memset(entry, 0, sizeof(struct gd_fs_entry_t));

    size_t length;
    xmlNodePtr c1, c2;
    xmlChar *value = NULL;

    inode = get_free_inode();
    for(c1 = node->children; c1 != NULL; c1 = c1->next)
    {

        char const *name = c1->name;

        switch(*name)
        {
        case 'a': // 'author'
            for(c2 = c1->children; c2 != NULL; c2 = c2->next)
            {
                name = c2->name;
                value = xmlNodeListGetString(xml, c2->children, 1);
                switch(*name)
                {
                case 'n':
                    str_init_create(&entry->author, value, 0);
                    break;
                case 'e':
                    str_init_create(&entry->author_email, value, 0);
                    break;
                default:
                    break;
                }
                xmlFree(value);
            }
            break;
        case 'c':
            if(strcmp(name, "content") == 0)
            {
                value = xmlGetProp(c1, "src");
                str_init_create(&entry->src, value, 0);
                xmlFree(value);
            }
            // file's type
            else if (strcmp(name, "category") == 0)
            {
                value = xmlGetProp(c1, "label");
                if (strcmp(value, "folder")==0)
                {
                    inodetable[inode].inode->mode = S_IFDIR | 0700;
                    entry->mode = S_IFDIR | 0700;
                    entry->shared = 0;
                }
                else if (strcmp(value, "shared")==0)
                {
                    inodetable[inode].inode->mode = S_IFREG | 0600;
                    entry->mode = S_IFREG | 0600;
                    entry->shared = 1;
                }
                else
                {
                    inodetable[inode].inode->mode = S_IFREG | 0600;
                    entry->mode = S_IFREG | 0600;
                    entry->shared = 0;
                }
            }
            break;
        case 'f':
            if(strcmp(name, "feedlink") == 0)
            {
                value = xmlGetProp(c1, "rel");
                if(strcmp(value, "http://schemas.google.com/acl/2007#accessControlList") == 0)
                {
                    // Link for r/w access to ACLS for this entry
                    // Do we care?
                    // Can we expose this?
                }
                else if(strcmp(value, "http://schemas.google.com/docs/2007/revisions") == 0)
                {
                    // Link for r/w access to revisions
                    // It would be cool if we can expose these somehow
                }
            }
            break;
        case 'l':
            if(strcmp(name, "lastModifiedBy") == 0)
            {
                for(c2 = c1->children; c2 != NULL; c2 = c2->next)
                {
                    name = c2->name;
                    value = xmlNodeListGetString(xml, c2->children, 1);
                    switch(*name)
                    {
                    case 'n':
                        str_init_create(&entry->lastModifiedBy, value, 0);
                        break;
                    case 'e':
                        str_init_create(&entry->lastModifiedBy_email, value, 0);
                        break;
                    default:
                        break;
                    }
                    xmlFree(value);
                }
            }
            else if(strcmp(name, "link") == 0)
            {
                value = xmlGetProp(c1, "rel");
                if(strcmp(value, "http://schemas.google.com/docs/2007#parent") == 0)
                {
                    xmlChar *value;
                    value = xmlGetProp(c1, "title");
                    str_init_create(&entry->parent, value, 0);
                    xmlFree(value);
                    value = xmlGetProp(c1, "href");
                    str_init_create(&entry->parent_href, value, 0);
                    xmlFree(value);
                    // This entry is inside one (or more?) collections
                    // These entries are the folders for this entry
                }
                else if(strcmp(value, "alternate") == 0)
                {
                    // Link you can open this document in a web browser with
                    // Do we care?
                }
                else if(strcmp(value, "self") == 0)
                {
                    // Link to XML feed for just this entry
                    // Might be useful for checking for updates instead of changesets
                    xmlChar *href = xmlGetProp(c1, "href");
                    str_init_create(&entry->feed, href, 0);
                    xmlFree(href);
                }
                else if(strcmp(value, "edit") == 0)
                {
                    // For writes?
                }
                /*
                else if(strcmp(value, "edit-media") == 0)
                {
                	// deprecated, use 'resumeable-edit-media'
                }
                */
                else if(strcmp(value, "http://schemas.google.com/g/2005#resumable-edit-media") == 0)
                {
                    // For resumeable writes?
                    // This may be the one we *really* want to use, rather than 'edit'
                }
                else if(strcmp(value, "http://schemas.google.com/docs/2007/thumbnail") == 0)
                {
                    // Might be a useful way to expose this for GUI file managers?
                }
                xmlFree(value);
            }
            break;
        case 'm':
            if(strcmp(name, "md5Checksum") == 0)
            {
                value = xmlNodeListGetString(xml, c1->children, 1);
                entry->md5set = 1;
                str_init_create(&entry->md5, value, 0);
                xmlFree(value);
            }
            break;
        case 't': // 'title'
            if(strcmp(name, "title") == 0)
            {
                value = xmlNodeListGetString(xml, c1->children, 1);
                str_init_create(&entry->filename, value, 0);
                entry->filename.str = filenameencode(value, &entry->filename.len);
                entry->filename.reserved = entry->filename.len;
                xmlFree(value);
            }
            break;
        case 's':
            if(strcmp(name, "size") == 0)
            {
                value = xmlNodeListGetString(xml, c1->children, 1);
                length = xmlStrlen(value);
                // TODO: errors?
                entry->size = strtol((char*)value, NULL, 10);
                xmlFree(value);
            }
            break;
        default:
            break;
        }
    }
    entry->inode = inode;
    inodetable[inode].num = inode;
    inodetable[inode].inode->node = entry;
    return entry;
}
Example #12
0
int main(int argc, char **argv) {

    if (argc != 4)
    {
        fprintf(stderr, "Usage: readimg <image file name> filepath \n");
        exit(1);
    }
    
    // open source file
    int fd_src = open(argv[2], O_RDONLY);
    if (fd_src < 0){
        fprintf(stderr, "No such file exists in the native file system \n");
        exit(ENOENT);
    }

    int filesize_src = lseek(fd_src, 0, SEEK_END);
    // mmap cannot map size 0 file.
    if (filesize_src <= 0){
        fprintf(stderr, "The source file is empty \n");
        exit(ENOENT);
    }

    int req_block_num = (filesize_src - 1) / EXT2_BLOCK_SIZE + 1;

    // open the image
    int fd = open(argv[1], O_RDWR);
    if (fd < 0){
        fprintf(stderr, "No such virtual disk exists \n");
        exit(ENOENT);   
    }

    // map the virtual disk and source file on memory
    ptr_disk = mmap(NULL, BLOCK_NUM * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    unsigned char* ptr_disk_src = mmap(NULL, filesize_src, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0);
    if (ptr_disk == MAP_FAILED || ptr_disk_src == MAP_FAILED)
    {
       perror("mmap");
       exit(1);
    }

    struct ext2_group_desc *ptr_group_desc = (struct ext2_group_desc *)(ptr_disk + EXT2_SB_OFFSET + EXT2_BLOCK_SIZE);
    // get the inode table
    struct ext2_inode *ptr_inode = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table);
    unsigned char *bm_inode = (ptr_disk + (ptr_group_desc -> bg_inode_bitmap) * BLOCK_SIZE);
    unsigned char *bm_block = (ptr_disk + (ptr_group_desc -> bg_block_bitmap) * BLOCK_SIZE);
    struct ext2_super_block *ptr_super_block = (struct ext2_super_block *)(ptr_disk + EXT2_SB_OFFSET);
    char *ptr_path_src = strdup(argv[2]);
    char *ptr_path_dest = strdup(argv[3]);
    char *table_path_src[10];
    char *table_path_dest[10];
    int count_path_src = get_path_table(table_path_src, ptr_path_src);
    int count_path_dest = get_path_table(table_path_dest, ptr_path_dest);

    // Find the destination directory in the virtual disk
    struct ext2_dir_entry_2 *ptr_dir_dest = recurse_inode(ptr_inode + 1, table_path_dest, count_path_dest, 0, ptr_group_desc->bg_inode_table);

    if(ptr_dir_dest == 0)
    {
        printf("No such directory exists on virtual disk\n");
        return -1;
    }

    int table_new_block[req_block_num];
    int copy_flag = 0;

    int i = 0;
    while(i < req_block_num)
    {
        int free_block = get_free_block(bm_block, ptr_super_block);
        SETBIT(bm_block, free_block);
        table_new_block[i] = free_block;

        if(filesize_src - copy_flag <= BLOCK_SIZE)
        {
            memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, filesize_src - copy_flag - 1);
        }
        else
        {
            memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, EXT2_BLOCK_SIZE);
            copy_flag += BLOCK_SIZE;
        }
        i++;
    }

    int block_id_inderect;
    if(req_block_num > 11)
    {
        block_id_inderect = get_free_block(bm_block, ptr_super_block);
        int *indirect_block = (int *)(ptr_disk + EXT2_BLOCK_SIZE * (block_id_inderect + 1));
        SETBIT(bm_block, block_id_inderect);
        for(i = 12; i < req_block_num; i++)
        {
            *indirect_block = table_new_block[i];
            indirect_block++;
        }
    }

    int fr_inode = get_free_inode(bm_inode, ptr_super_block);
    struct ext2_inode *node_new = ptr_inode + (fr_inode);
    SETBIT(bm_inode, fr_inode);
    node_new->i_links_count = 1;
    node_new->i_mode = EXT2_S_IFREG;
    node_new->i_size = filesize_src;
    node_new->i_blocks = req_block_num * 2;

    i = 0;
    while (i < 11 && req_block_num != i)
    {
        node_new->i_block[i] = table_new_block[i];
        i++;
    }

    if(req_block_num > 11)
    {
        node_new -> i_block[12] = block_id_inderect;
    }

    struct ext2_inode *in_src = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table);
    struct ext2_inode *in_cur = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table);
    in_src = in_src + ptr_dir_dest -> inode - 1;
    in_cur = in_cur + ptr_dir_dest -> inode - 1;
    in_cur->i_links_count++;

    int len_req = strlen(table_path_src[count_path_src - 1]) + 8;
    struct ext2_dir_entry_2 *ptr_dir = get_free_space(in_cur, len_req);

    if(ptr_dir == 0)
    {
        int free_block_new = get_free_block(bm_block, ptr_super_block);
        ptr_dir = (void*)ptr_disk + EXT2_BLOCK_SIZE * (free_block_new + 1);
        ptr_dir -> inode = fr_inode + 1;
        ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]);
        ptr_dir -> file_type = EXT2_FT_DIR;
        strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]);
        ptr_dir -> rec_len = BLOCK_SIZE;
        
        in_src -> i_blocks += 2;
        in_src ->i_block[in_src -> i_size / BLOCK_SIZE] = free_block_new + 1;
        in_src -> i_size += BLOCK_SIZE;
    }
    else
    {
        int new_rec_len = ptr_dir -> rec_len - (4 * (ptr_dir -> name_len) + 8);
        ptr_dir -> rec_len = 4 * (ptr_dir -> name_len) + 8;
        ptr_dir = (void*)ptr_dir + ptr_dir -> rec_len;
        ptr_dir -> rec_len = new_rec_len;
        ptr_dir -> inode = fr_inode + 1;
        ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]);
        ptr_dir -> file_type = EXT2_FT_REG_FILE;
        strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]);
    }
    ptr_group_desc->bg_used_dirs_count++;
    return 0;
}