Beispiel #1
0
static errcode_t ext3u_write_inode(ext2_filsys fs, ext2_ino_t undel_ino, int flags)
{

	char				*buf;
	errcode_t			retval;
	struct ext2_inode	inode;
	struct mk_ext3u_struct	es;
	__u32 num_blocks = ext3u_fifo_reserved + ext3u_skip_reserved + ext3u_index_reserved + 1;

	if ((retval = ext3u_create_superblock(fs, flags, &buf)))
		return retval;

	if ((retval = ext2fs_read_bitmaps(fs)))
		return retval;

	if ((retval = ext2fs_read_inode(fs, undel_ino, &inode)))
		return retval;

	if (inode.i_blocks > 0)
		return EEXIST;

	es.goal = 0;
	es.num_blocks = num_blocks;
	es.newblocks = 0;
	es.buf = buf;
	es.err = 0;
	es.zero_count = 0;

	retval = ext2fs_block_iterate2(fs, undel_ino, BLOCK_FLAG_APPEND, 0, mk_ext3u_proc, &es);
	if (es.err) {
		retval = es.err;
		goto errout;
	}
	if (es.zero_count) {
		retval = ext2fs_zero_blocks(fs, es.blk_to_zero, es.zero_count, 0, 0);
		if (retval)
			goto errout;
	}

	 if ((retval = ext2fs_read_inode(fs, undel_ino, &inode)))
		goto errout;

 	inode.i_size += fs->blocksize * num_blocks;
	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
	inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
	inode.i_links_count = 1;
	inode.i_mode = LINUX_S_IFREG | 0600;

	if ((retval = ext2fs_write_inode(fs, undel_ino, &inode)))
		goto errout;
	retval = 0;


errout:
	ext2fs_free_mem(&buf);
	return retval;
}
Beispiel #2
0
/*
 * This function creates a journal using direct I/O routines.
 */
static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
				     blk_t size, int flags)
{
	char			*buf;
	errcode_t		retval;
	struct ext2_inode	inode;
	struct mkjournal_struct	es;

	if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
		return retval;

	if ((retval = ext2fs_read_bitmaps(fs)))
		return retval;

	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
		return retval;

	if (inode.i_blocks > 0)
		return EEXIST;

	es.num_blocks = size;
	es.newblocks = 0;
	es.buf = buf;
	es.err = 0;

	retval = ext2fs_block_iterate2(fs, journal_ino, BLOCK_FLAG_APPEND,
				       0, mkjournal_proc, &es);
	if (es.err) {
		retval = es.err;
		goto errout;
	}

	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
		goto errout;

	inode.i_size += fs->blocksize * size;
	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
	inode.i_mtime = inode.i_ctime = time(0);
	inode.i_links_count = 1;
	inode.i_mode = LINUX_S_IFREG | 0600;

	if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
		goto errout;
	retval = 0;

	memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
	fs->super->s_jnl_blocks[16] = inode.i_size;
	fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
	ext2fs_mark_super_dirty(fs);

errout:
	ext2fs_free_mem(&buf);
	return retval;
}
Beispiel #3
0
void ext2CloseFile (ext2_file_state *file)
{
    // Sanity check
    if (!file || !file->vd)
        return;

    ext2fs_file_close(file->fd);

    // Sync the file (and its attributes) to disc
    if(file->write)
    {
        // Read in node changes before writing them
        ext2fs_read_inode(file->vd->fs, file->ni->ino, &file->ni->ni);
        ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ACTIME);
    }

    if (file->read)
        ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME);

    ext2Sync(file->vd, file->ni);

    // Close the file (if open)
    if (file->ni)
        ext2CloseEntry(file->vd, file->ni);

    // Reset the file state
    file->ni = NULL;
    file->fd = NULL;
    file->flags = 0;
    file->read = false;
    file->write = false;
    file->append = false;

    return;
}
Beispiel #4
0
static int fix_directory(ext2_filsys fs,
			 struct ext2_db_entry2 *db,
			 void *priv_data)
{
	errcode_t	retval;

	empty_dir_info edi = (empty_dir_info) priv_data;

	edi->logblk = 0;
	edi->freed_blocks = 0;
	edi->ino = db->ino;

	retval = ext2fs_read_inode(fs, db->ino, &edi->inode);
	if (retval)
		return 0;

	retval = ext2fs_block_iterate3(fs, db->ino, 0, edi->block_buf,
				       empty_pass1, edi);
	if (retval)
		return 0;

	if (edi->freed_blocks) {
		edi->inode.i_size -= edi->freed_blocks * fs->blocksize;
		ext2fs_iblk_add_blocks(fs, &edi->inode, edi->freed_blocks);
		retval = ext2fs_write_inode(fs, db->ino, &edi->inode);
		if (retval)
			return 0;
	}
	return 0;
}
Beispiel #5
0
static char *ext2fs_read_symlink(struct ext2fs_node *node)
{
    char *symlink;
    struct ext2fs_node *diro = node;
    int status;

    if (!diro->inode_read) {
        status = ext2fs_read_inode (diro->data, diro->ino,
                        &diro->inode);
        if (status == 0) {
            return (0);
        }
    }
    symlink = malloc (__le32_to_cpu (diro->inode.size) + 1);
    if (!symlink) {
        return (0);
    }
    /* If the filesize of the symlink is bigger than
       60 the symlink is stored in a separate block,
       otherwise it is stored in the inode.  */
    if (__le32_to_cpu (diro->inode.size) <= 60) {
        strncpy (symlink, diro->inode.b.symlink,
             __le32_to_cpu (diro->inode.size));
    } else {
        status = ext2fs_read_file (diro, 0,
                       __le32_to_cpu (diro->inode.size),
                       symlink);
        if (status == 0) {
            free (symlink);
            return (0);
        }
    }
    symlink[__le32_to_cpu (diro->inode.size)] = '\0';
    return (symlink);
}
Beispiel #6
0
int ext2fs_open (const char *filename) {
    struct ext2fs_node *fdiro = NULL;
    int status;
    int len;

    if (ext2fs_root == NULL) {
        return (-1);
    }
    ext2fs_file = NULL;
    status = ext2fs_find_file (filename, &ext2fs_root->diropen, &fdiro,
                   FILETYPE_REG);
    if (status == 0) {
        goto fail;
    }
    if (!fdiro->inode_read) {
        status = ext2fs_read_inode (fdiro->data, fdiro->ino,
                        &fdiro->inode);
        if (status == 0) {
            goto fail;
        }
    }
    len = __le32_to_cpu (fdiro->inode.size);
    ext2fs_file = fdiro;
    return (len);

fail:
    ext2fs_free_node (fdiro, &ext2fs_root->diropen);
    return (-1);
}
Beispiel #7
0
static void move_quota_inode(ext2_filsys fs, ext2_ino_t from_ino,
			     ext2_ino_t to_ino, int qtype)
{
	struct ext2_inode	inode;
	char			qf_name[QUOTA_NAME_LEN];

	/* We need the inode bitmap to be loaded */
	if (ext2fs_read_bitmaps(fs))
		return;

	if (ext2fs_read_inode(fs, from_ino, &inode))
		return;

	inode.i_links_count = 1;
	inode.i_mode = LINUX_S_IFREG | 0600;
	inode.i_flags = EXT2_IMMUTABLE_FL;
	if (fs->super->s_feature_incompat &
			EXT3_FEATURE_INCOMPAT_EXTENTS)
		inode.i_flags |= EXT4_EXTENTS_FL;

	ext2fs_write_new_inode(fs, to_ino, &inode);
	/* unlink the old inode */
	quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
	ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0);
	ext2fs_inode_alloc_stats(fs, from_ino, -1);
	/* Clear out the original inode in the inode-table block. */
	memset(&inode, 0, sizeof(struct ext2_inode));
	ext2fs_write_inode(fs, from_ino, &inode);
}
Beispiel #8
0
int modinode(e2i_ctx_t *e2c, const char *fname, ext2_ino_t e2ino)
{
	struct ext2_inode inode;
	int uid, gid, ret;
	
	/* read the inode, alter uid, gid  and write it back */
	ret = ext2fs_read_inode(e2c->fs, e2ino, &inode);
	E2_ERR(ret, "Ext2 read Inode Error", "");

	/* do the root squash */
	if (! e2c->preserve_uidgid) {
		inode.i_uid = e2c->default_uid;
		inode.i_gid = e2c->default_gid;
	}

	/* if the filename is mentioned in .UIDGID we must change the owner */
	if (uiddb_search(e2c->uid_db, fname, &uid, &gid)){
		if (e2c->verbose)
			printf("Changing UID and GID for %s (%d:%d)\n", fname, uid, gid);
		inode.i_uid = uid;
		inode.i_gid = gid;
	}		
		
	ret = ext2fs_write_inode(e2c->fs, e2ino, &inode);
	E2_ERR(ret, "Ext2 write Inode Error", "");
	
	return 0;
}
/*
 * Reads the current bad blocks from the bad blocks inode.
 */
errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
{
	errcode_t	retval;
	struct read_bb_record rb;
	struct ext2_inode inode;
	blk_t	numblocks;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!*bb_list) {
		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
		if (retval)
			return retval;
		if (inode.i_blocks < 500)
			numblocks = (inode.i_blocks /
				     (fs->blocksize / 512)) + 20;
		else
			numblocks = 500;
		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
		if (retval)
			return retval;
	}

	rb.bb_list = *bb_list;
	rb.err = 0;
	retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, 0, 0,
				      mark_bad_block, &rb);
	if (retval)
		return retval;

	return rb.err;
}
Beispiel #10
0
/* Link an inode number to a directory */
static errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
			  ext2_ino_t ino, const char *name)
{
	struct ext2_inode	inode;
	errcode_t		retval;

	retval = ext2fs_read_inode(fs, ino, &inode);
        if (retval) {
		com_err(__func__, retval, "while reading inode %u", ino);
		return retval;
	}

	retval = ext2fs_link(fs, parent_ino, name, ino, inode.i_flags);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, parent_ino);
		if (retval) {
			com_err(__func__, retval, "while expanding directory");
			return retval;
		}
		retval = ext2fs_link(fs, parent_ino, name, ino, inode.i_flags);
	}
	if (retval) {
		com_err(__func__, retval, "while linking %s", name);
		return retval;
	}

	inode.i_links_count++;

	retval = ext2fs_write_inode(fs, ino, &inode);
	if (retval)
		com_err(__func__, retval, "while writing inode %u", ino);

	return retval;
}
Beispiel #11
0
/*
 * When caller uses this function to retrieve the inline data, it must
 * allocate a buffer which has the size of inline data.  The size of
 * inline data can be know by ext2fs_inline_data_get_size().
 */
errcode_t ext2fs_inline_data_get(ext2_filsys fs, ext2_ino_t ino,
                                 struct ext2_inode *inode,
                                 void *buf, size_t *size)
{
    struct ext2_inode inode_buf;
    struct ext2_inline_data data;
    errcode_t retval;

    if (!inode) {
        retval = ext2fs_read_inode(fs, ino, &inode_buf);
        if (retval)
            return retval;
        inode = &inode_buf;
    }

    data.fs = fs;
    data.ino = ino;
    retval = ext2fs_inline_data_ea_get(&data);
    if (retval)
        return retval;

    memcpy(buf, (void *)inode->i_block, EXT4_MIN_INLINE_DATA_SIZE);
    if (data.ea_size > 0)
        memcpy(buf + EXT4_MIN_INLINE_DATA_SIZE,
               data.ea_data, data.ea_size);

    if (size)
        *size = EXT4_MIN_INLINE_DATA_SIZE + data.ea_size;
    ext2fs_free_mem(&data.ea_data);
    return 0;
}
Beispiel #12
0
static void create_root_dir(ext2_filsys fs)
{
	errcode_t	retval;
	struct ext2_inode	inode;

	retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0);
	if (retval) {
		com_err("ext2fs_mkdir", retval, _("while creating root dir"));
		exit(1);
	}
	if (geteuid()) {
		retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode);
		if (retval) {
			com_err("ext2fs_read_inode", retval,
				_("while reading root inode"));
			exit(1);
		}
		inode.i_uid = getuid();
		if (inode.i_uid)
			inode.i_gid = getgid();
		retval = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
		if (retval) {
			com_err("ext2fs_write_inode", retval,
				_("while setting root inode ownership"));
			exit(1);
		}
	}
}
Beispiel #13
0
long
read_inode(ext2_filsys fs, ext2_ino_t file, struct ext2_inode *inode)
{
  long retval;

  if ((retval = ext2fs_read_inode(fs, file, inode)))
    fprintf(stderr, "%s\n", error_message(retval));
  return retval;
}
Beispiel #14
0
// read real fs inode 128
int intern_read_inode(ext2_ino_t ino, struct ext2_inode * inode)
{
        int retval;

        retval = ext2fs_read_inode(current_fs, ino, inode);
        if (retval) {
                fprintf(stderr,"Error %d while reading inode %u\n",retval, ino);
                return 1;
        }
        return 0;
}
Beispiel #15
0
quik_err_t
ext2fs_mount(part_t *part)
{
   struct ext2_data *data;
   quik_err_t err;

   data = malloc(sizeof(struct ext2_data));
   if (!data) {
      return ERR_NO_MEM;
   }

   /* Read the superblock.  */
   err = part_read(part, 1 * 2, 0, sizeof(struct ext2_sblock),
                      (char *) &data->sblock);
   if (err != ERR_NONE) {
      goto fail;
   }

   /* Make sure this is an ext2 filesystem.  */
   if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) {
      err = ERR_FS_NOT_EXT2;
      goto fail;
   }

   if (__le32_to_cpu(data->sblock.revision_level == 0)) {
      inode_size = 128;
   } else {
      inode_size = __le16_to_cpu(data->sblock.inode_size);
   }

#ifdef DEBUG
   printk("EXT2 rev %d, inode_size %d\n",
          __le32_to_cpu(data->sblock.revision_level), inode_size);
#endif

   data->part = part;
   data->diropen.data = data;
   data->diropen.ino = 2;
   data->diropen.inode_read = 1;
   data->inode = &data->diropen.inode;

   err = ext2fs_read_inode(data, 2, data->inode);
   if (err != ERR_NONE) {
      goto fail;
   }

   ext2fs_root = data;
   return ERR_NONE;

fail:
   free(data);
   ext2fs_root = NULL;
   return err;
}
Beispiel #16
0
static errcode_t create_directory(ext2_filsys fs, char *dir,
                                  ext2_ino_t *ret_ino)

{
    struct ext2_inode	inode;
    ext2_ino_t		ino = EXT2_ROOT_INO;
    ext2_ino_t		newdir;
    errcode_t		retval = 0;
    char			*fn, *cp, *next;

    fn = malloc(strlen(dir) + 1);
    if (fn == NULL)
        return ENOMEM;

    strcpy(fn, dir);
    cp = fn;
    while(1) {
        next = strchr(cp, '/');
        if (next)
            *next++ = 0;
        if (*cp) {
            retval = ext2fs_new_inode(fs, ino, LINUX_S_IFDIR,
                                      NULL, &newdir);
            if (retval)
                goto errout;

            retval = ext2fs_mkdir(fs, ino, newdir, cp);
            if (retval)
                goto errout;

            ino = newdir;
            retval = ext2fs_read_inode(fs, ino, &inode);
            if (retval)
                goto errout;

            inode.i_uid = uid & 0xFFFF;
            ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
            inode.i_gid = gid & 0xFFFF;
            ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);
            retval = ext2fs_write_inode(fs, ino, &inode);
            if (retval)
                goto errout;
        }
        if (next == NULL || *next == '\0')
            break;
        cp = next;
    }
errout:
    free(fn);
    if (retval == 0)
        *ret_ino = ino;
    return retval;
}
Beispiel #17
0
static int list_dir_proc2(ext2_ino_t dir,
			 int    entry,
			 struct ext2_dir_entry *dirent,
			 int	offset,
			 int	blocksize,
			 char	*buf,
			 void	*privateinfo)
{
  struct ext2_inode	inode;
  ext2_ino_t		ino;
  const struct ext2_dir_struct *ls = (const struct ext2_dir_struct *) privateinfo;
  file_info_t *new_file;
  if(entry==DIRENT_DELETED_FILE && (ls->dir_data->param & FLAG_LIST_DELETED)==0)
    return 0;
  ino = dirent->inode;
  if (ino) {
    errcode_t retval;
//    log_info("ext2fs_read_inode(ino=%u)\n", ino);
    if ((retval=ext2fs_read_inode(ls->current_fs,ino, &inode))!=0)
    {
      log_error("ext2fs_read_inode(ino=%u) failed with error %ld.\n",(unsigned)ino, (long)retval);
      memset(&inode, 0, sizeof(struct ext2_inode));
    }
  } else {
    memset(&inode, 0, sizeof(struct ext2_inode));
  }
  new_file=(file_info_t *)MALLOC(sizeof(*new_file));
  {
    const unsigned int thislen = ((dirent->name_len & 0xFF) < EXT2_NAME_LEN) ?
      (dirent->name_len & 0xFF) : EXT2_NAME_LEN;
    new_file->name=(char *)MALLOC(thislen+1);
    memcpy(new_file->name, dirent->name, thislen);
    new_file->name[thislen] = '\0';
  }
  if(entry==DIRENT_DELETED_FILE)
    new_file->status=FILE_STATUS_DELETED;
  else
    new_file->status=0;
  new_file->st_ino=ino;
  new_file->st_mode=inode.i_mode;
//  new_file->st_nlink=inode.i_links_count;
  new_file->st_uid=inode.i_uid;
  new_file->st_gid=inode.i_gid;
  new_file->st_size=LINUX_S_ISDIR(inode.i_mode)?inode.i_size:
    inode.i_size| ((uint64_t)inode.i_size_high << 32);
//  new_file->st_blksize=blocksize;
//  new_file->st_blocks=inode.i_blocks;
  new_file->td_atime=inode.i_atime;
  new_file->td_mtime=inode.i_mtime;
  new_file->td_ctime=inode.i_ctime;
  td_list_add_tail(&new_file->list, &ls->dir_list->list);
  return 0;
}
static errcode_t get_file(ext2_filsys fs, const char * filename,
		   struct mem_file *ret_file)
{
	errcode_t	retval;
	char 		*buf;
	ext2_file_t	e2_file = NULL;
	unsigned int	got;
	struct ext2_inode inode;
	ext2_ino_t	ino;

	ret_file->buf = 0;
	ret_file->size = 0;
	ret_file->ptr = 0;

	retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
			      filename, &ino);
	if (retval)
		return retval;

	retval = ext2fs_read_inode(fs, ino, &inode);
	if (retval)
		return retval;

	if (inode.i_size_high || (inode.i_size > 65536))
		return EFBIG;

	buf = malloc(inode.i_size + 1);
	if (!buf)
		return ENOMEM;
	memset(buf, 0, inode.i_size+1);

	retval = ext2fs_file_open(fs, ino, 0, &e2_file);
	if (retval)
		goto errout;

	retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
	if (retval)
		goto errout;

	retval = ext2fs_file_close(e2_file);
	if (retval)
		goto errout;

	ret_file->buf = buf;
	ret_file->size = (int) got;
	return 0;

errout:
	free(buf);
	if (e2_file)
		ext2fs_file_close(e2_file);
	return retval;
}
Beispiel #19
0
int debugfs_read_inode(ext2_ino_t ino, struct ext2_inode * inode,
			const char *cmd)
{
	int retval;

	retval = ext2fs_read_inode(current_fs, ino, inode);
	if (retval) {
		com_err(cmd, retval, "while reading inode %u", ino);
		return 1;
	}
	return 0;
}
Beispiel #20
0
void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
			      struct ext2_inode * inode, const char *proc)
{
	errcode_t retval;

	retval = ext2fs_read_inode(ctx->fs, ino, inode);
	if (retval) {
		com_err("ext2fs_read_inode", retval,
			_("while reading inode %lu in %s"), ino, proc);
		fatal_error(ctx, 0);
	}
}
Beispiel #21
0
errcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino,
                                 struct ext2_inode *inode,
                                 void *buf, size_t size)
{
    struct ext2_inode inode_buf;
    struct ext2_inline_data data;
    errcode_t retval;
    size_t free_ea_size, existing_size, free_inode_size;

    if (!inode) {
        retval = ext2fs_read_inode(fs, ino, &inode_buf);
        if (retval)
            return retval;
        inode = &inode_buf;
    }

    if (size <= EXT4_MIN_INLINE_DATA_SIZE) {
        retval = ext2fs_inline_data_ea_remove(fs, ino);
        if (retval)
            return retval;
        memcpy((void *)inode->i_block, buf, size);
        return ext2fs_write_inode(fs, ino, inode);
    }

    retval = ext2fs_xattr_inode_max_size(fs, ino, &free_ea_size);
    if (retval)
        return retval;

    retval = ext2fs_inline_data_size(fs, ino, &existing_size);
    if (retval)
        return retval;

    if (existing_size < EXT4_MIN_INLINE_DATA_SIZE)
        free_inode_size = EXT4_MIN_INLINE_DATA_SIZE - existing_size;
    else
        free_inode_size = 0;

    if (size != existing_size &&
            size > existing_size + free_ea_size + free_inode_size)
        return EXT2_ET_INLINE_DATA_NO_SPACE;

    memcpy((void *)inode->i_block, buf, EXT4_MIN_INLINE_DATA_SIZE);
    retval = ext2fs_write_inode(fs, ino, inode);
    if (retval)
        return retval;
    data.fs = fs;
    data.ino = ino;
    data.ea_size = size - EXT4_MIN_INLINE_DATA_SIZE;
    data.ea_data = buf + EXT4_MIN_INLINE_DATA_SIZE;
    return ext2fs_inline_data_ea_set(&data);
}
Beispiel #22
0
int ext2fs_mount (unsigned part_length) {
	struct ext2_data *data;
	int status;

	data = malloc (sizeof (struct ext2_data));
	if (!data) {
		return (0);
	}
	/* Read the superblock.  */
	status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock),
				 (char *) &data->sblock);
	if (status == 0) {
		goto fail;
	}
	/* Make sure this is an ext2 filesystem.  */
	if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) {
		goto fail;
	}
#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
#ifdef DEBUG
       printf("revision_level = 0x%x, inode_size = 0x%x\n", data->sblock.revision_level, data->sblock.inode_size);
#endif
       if (__le32_to_cpu (data->sblock.revision_level) == EXT2_GOOD_OLD_REV) {
               ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
       } else {
               ext2_inode_size = __le16_to_cpu (data->sblock.inode_size);
       }
#endif
       

	data->diropen.data = data;
	data->diropen.ino = 2;
	data->diropen.inode_read = 1;
	data->inode = &data->diropen.inode;

	status = ext2fs_read_inode (data, 2, data->inode);
	if (status == 0) {
		goto fail;
	}

	ext2fs_root = data;

	return (1);

fail:
	printf ("Failed to mount ext2 filesystem...\n");
	free (data);
	ext2fs_root = NULL;
	return (0);
}
Beispiel #23
0
int do_readinode (ext2_filsys e2fs, const char *path, ext2_ino_t *ino, struct ext2_inode *inode)
{
	errcode_t rc;
	rc = ext2fs_namei(e2fs, EXT2_ROOT_INO, EXT2_ROOT_INO, path, ino);
	if (rc) {
		debugf("ext2fs_namei(e2fs, EXT2_ROOT_INO, EXT2_ROOT_INO, %s, ino); failed", path);
		return -ENOENT;
	}
	rc = ext2fs_read_inode(e2fs, *ino, inode);
	if (rc) {
		debugf("ext2fs_read_inode(e2fs, *ino, inode); failed");
		return -EIO;
	}
	return 0;
}
Beispiel #24
0
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
		      ext2_ino_t ino, int flags)
{
	errcode_t		retval;
	struct link_struct	ls;
	struct ext2_inode	inode;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	ls.fs = fs;
	ls.name = name;
	ls.namelen = name ? strlen(name) : 0;
	ls.inode = ino;
	ls.flags = flags;
	ls.done = 0;
	ls.sb = fs->super;
	ls.blocksize = fs->blocksize;
	ls.err = 0;

	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
				    0, link_proc, &ls);
	if (retval)
		return retval;
	if (ls.err)
		return ls.err;

	if (!ls.done)
		return EXT2_ET_DIR_NO_SPACE;

	if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
		return retval;

	/*
	 * If this function changes to preserve the htree, remove the
	 * two hunks in link_proc that shove checksum tails into the
	 * former dx_root/dx_node blocks.
	 */
	if (inode.i_flags & EXT2_INDEX_FL) {
		inode.i_flags &= ~EXT2_INDEX_FL;
		if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
			return retval;
	}

	return 0;
}
Beispiel #25
0
errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
{
	errcode_t	retval;
	struct expand_dir_struct es;
	struct ext2_inode	inode;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	if (!fs->block_map)
		return EXT2_ET_NO_BLOCK_BITMAP;

	retval = ext2fs_check_directory(fs, dir);
	if (retval)
		return retval;

	es.done = 0;
	es.err = 0;
	es.goal = 0;
	es.newblocks = 0;
	es.dir = dir;

	retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
				       0, expand_dir_proc, &es);

	if (es.err)
		return es.err;
	if (!es.done)
		return EXT2_ET_EXPAND_DIR_ERR;

	/*
	 * Update the size and block count fields in the inode.
	 */
	retval = ext2fs_read_inode(fs, dir, &inode);
	if (retval)
		return retval;

	inode.i_size += fs->blocksize;
	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);

	retval = ext2fs_write_inode(fs, dir, &inode);
	if (retval)
		return retval;

	return 0;
}
Beispiel #26
0
int ext2fs_mount (unsigned part_length) {
    struct ext2_data *data;
    int status;

    data = malloc (sizeof (struct ext2_data));
    if (!data) {
        return (0);
    }
    /* Read the superblock.  */
    status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock),
                 (char *) &data->sblock);
    if (status == 0) {
        goto fail;
    }
    /* Make sure this is an ext2 filesystem.  */
    if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) {
        goto fail;
    }
    if (__le32_to_cpu(data->sblock.revision_level == 0)) {
        inode_size = 128;
    } else {
        inode_size = __le16_to_cpu(data->sblock.inode_size);
    }
#ifdef DEBUG
    printf("EXT2 rev %d, inode_size %d\n",
            __le32_to_cpu(data->sblock.revision_level), inode_size);
#endif
    data->diropen.data = data;
    data->diropen.ino = 2;
    data->diropen.inode_read = 1;
    data->inode = &data->diropen.inode;

    status = ext2fs_read_inode (data, 2, data->inode);
    if (status == 0) {
        goto fail;
    }

    ext2fs_root = data;

    return (1);

fail:
    printf ("Failed to mount ext2 filesystem...\n");
    free (data);
    ext2fs_root = NULL;
    return (0);
}
Beispiel #27
0
static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
			     ext2_ino_t inode, int link_count,
			     char *buf, ext2_ino_t *res_inode)
{
	char *pathname;
	char *buffer = 0;
	errcode_t retval;
	struct ext2_inode ei;
	blk64_t blk;

#ifdef NAMEI_DEBUG
	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
	       root, dir, inode, link_count);

#endif
	retval = ext2fs_read_inode (fs, inode, &ei);
	if (retval) return retval;
	if (!LINUX_S_ISLNK (ei.i_mode)) {
		*res_inode = inode;
		return 0;
	}
	if (link_count++ >= EXT2FS_MAX_NESTED_LINKS)
		return EXT2_ET_SYMLINK_LOOP;

	if (ext2fs_inode_data_blocks(fs,&ei)) {
		retval = ext2fs_bmap2(fs, inode, &ei, NULL, 0, 0, NULL, &blk);
		if (retval)
			return retval;

		retval = ext2fs_get_mem(fs->blocksize, &buffer);
		if (retval)
			return retval;

		retval = io_channel_read_blk64(fs->io, blk, 1, buffer);
		if (retval) {
			ext2fs_free_mem(&buffer);
			return retval;
		}
		pathname = buffer;
	} else
		pathname = (char *)&(ei.i_block[0]);
	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
			    link_count, buf, res_inode);
	if (buffer)
		ext2fs_free_mem(&buffer);
	return retval;
}
Beispiel #28
0
/*
 * This routine will connect a file to lost+found
 */
int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
{
	ext2_filsys fs = ctx->fs;
	errcode_t	retval;
	char		name[80];
	struct problem_context	pctx;
	struct ext2_inode 	inode;
	int		file_type = 0;

	clear_problem_context(&pctx);
	pctx.ino = ino;

	if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
		if (e2fsck_get_lost_and_found(ctx, 1) == 0)
			ctx->bad_lost_and_found++;
	}
	if (ctx->bad_lost_and_found) {
		fix_problem(ctx, PR_3_NO_LPF, &pctx);
		return 1;
	}

	sprintf(name, "#%u", ino);
	if (ext2fs_read_inode(fs, ino, &inode) == 0)
		file_type = ext2_file_type(inode.i_mode);
	retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
			return 1;
		retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
						 1, 0);
		if (retval) {
			pctx.errcode = retval;
			fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
			return 1;
		}
		retval = ext2fs_link(fs, ctx->lost_and_found, name,
				     ino, file_type);
	}
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
		return 1;
	}
	e2fsck_adjust_inode_count(ctx, ino, 1);

	return 0;
}
Beispiel #29
0
ext2_inode_t *ext2OpenEntry (ext2_vd *vd, const char *path)
{
    errcode_t errorcode = 0;
    ext2_inode_t * ni = 0;

    // Sanity check
    if (!vd) {
        errno = ENODEV;
        return NULL;
    }

    // Get the actual path of the entry
    path = ext2RealPath(path);
    if (!path)
        return NULL;

    ni = mem_alloc(sizeof(ext2_inode_t));
    if(!ni)
    {
        errno = ENOMEM;
        return NULL;
    }

	memset(ni, 0, sizeof(ext2_inode_t));

    // Find the entry, taking into account our current directory (if any)
    ni->ino = ext2PathToInode(vd, path);
    if(ni->ino == 0)
    {
        errno = ENOENT;
        mem_free(ni);
        return NULL;
    }

    errorcode = ext2fs_read_inode(vd->fs, ni->ino, &ni->ni);
    if(errorcode)
    {
        errno = EFAULT;
        mem_free(ni);
        return NULL;
    }

    return ni;
}
Beispiel #30
0
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
		      ext2_ino_t ino, int flags)
{
	errcode_t		retval;
	struct link_struct	ls;
	struct ext2_inode	inode;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	ls.fs = fs;
	ls.name = name;
	ls.namelen = name ? strlen(name) : 0;
	ls.inode = ino;
	ls.flags = flags;
	ls.done = 0;
	ls.sb = fs->super;
	ls.blocksize = fs->blocksize;
	ls.err = 0;

	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
				    0, link_proc, &ls);
	if (retval)
		return retval;
	if (ls.err)
		return ls.err;

	if (!ls.done)
		return EXT2_ET_DIR_NO_SPACE;

	if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
		return retval;

	if (inode.i_flags & EXT2_INDEX_FL) {
		inode.i_flags &= ~EXT2_INDEX_FL;
		if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
			return retval;
	}

	return 0;
}