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; }
/* * 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; }
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; }
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; }
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); }
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); }
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); }
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; }
/* 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; }
/* * 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; }
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); } } }
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; }
// 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; }
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; }
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; }
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; }
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; }
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); } }
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); }
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); }
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; }
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; }
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; }
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); }
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; }
/* * 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; }
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; }
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; }