119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dir_iterate.c --- ext2fs directory iteration operations 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o. 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License. 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_ERRNO_H 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_fs.h" 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fsP.h" 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define EXT4_MAX_REC_LEN ((1<<16)-1) 253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_get_rec_len(ext2_filsys fs, 273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_dir_entry *dirent, 283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int *rec_len) 293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int len = dirent->rec_len; 313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (len == EXT4_MAX_REC_LEN || len == 0) 333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *rec_len = fs->blocksize; 343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *rec_len = (len & 65532) | ((len & 3) << 16); 363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_set_rec_len(ext2_filsys fs, 403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int len, 413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_dir_entry *dirent) 423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((len > fs->blocksize) || (fs->blocksize > (1 << 18)) || (len & 3)) 443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EINVAL; 453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (len < 65536) { 463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dirent->rec_len = len; 473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (len == fs->blocksize) { 503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fs->blocksize == 65536) 513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dirent->rec_len = EXT4_MAX_REC_LEN; 523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dirent->rec_len = 0; 543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dirent->rec_len = (len & 65532) | ((len >> 16) & 3); 563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function checks to see whether or not a potential deleted 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * directory entry looks valid. What we do is check the deleted entry 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * and each successive entry to make sure that they all look valid and 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * that the last deleted entry ends at the beginning of the next 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * undeleted entry. Returns 1 if the deleted entry looks valid, zero 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * if not valid. 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int ext2fs_validate_entry(ext2_filsys fs, char *buf, 683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int offset, 693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int final_offset) 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent; 723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int rec_len; 733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define DIRENT_MIN_LENGTH 12 743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while ((offset < final_offset) && 763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (offset <= fs->blocksize - DIRENT_MIN_LENGTH)) { 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent = (struct ext2_dir_entry *)(buf + offset); 783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ext2fs_get_rec_len(fs, dirent, &rec_len)) 793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt offset += rec_len; 813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((rec_len < 8) || 823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((rec_len % 4) != 0) || 833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((((unsigned) dirent->name_len & 0xFF)+8) > rec_len)) 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (offset == final_offset); 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_dir_iterate2(ext2_filsys fs, 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t dir, 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags, 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf, 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int (*func)(ext2_ino_t dir, 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int entry, 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int offset, 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int blocksize, 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf, 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data), 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_context ctx; 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 1043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_check_directory(fs, dir); 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 1103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.dir = dir; 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.flags = flags; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (block_buf) 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.buf = block_buf; 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_mem(fs->blocksize, &ctx.buf); 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.func = func; 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.priv_data = priv_data; 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx.errcode = 0; 1233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_READ_ONLY, 0, 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_process_dir_block, &ctx); 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!block_buf) 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&ctx.buf); 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ctx.errcode; 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct xlate { 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int (*func)(struct ext2_dir_entry *dirent, 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int offset, 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int blocksize, 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf, 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data); 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *real_private; 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int xlate_func(ext2_ino_t dir EXT2FS_ATTR((unused)), 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int entry EXT2FS_ATTR((unused)), 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, int offset, 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int blocksize, char *buf, void *priv_data) 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct xlate *xl = (struct xlate *) priv_data; 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (*xl->func)(dirent, offset, blocksize, buf, xl->real_private); 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtextern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t dir, 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags, 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf, 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int (*func)(struct ext2_dir_entry *dirent, 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int offset, 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int blocksize, 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf, 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data), 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct xlate xl; 1633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project xl.real_private = priv_data; 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project xl.func = func; 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ext2fs_dir_iterate2(fs, dir, flags, block_buf, 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project xlate_func, &xl); 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Helper function which is private to this module. Used by 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate() 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint ext2fs_process_dir_block(ext2_filsys fs, 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t *blocknr, 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blockcnt, 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t ref_block EXT2FS_ATTR((unused)), 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ref_offset EXT2FS_ATTR((unused)), 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_context *ctx = (struct dir_context *) priv_data; 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int offset = 0; 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int next_real_entry = 0; 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret = 0; 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int changed = 0; 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int do_abort = 0; 1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int rec_len, size; 1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int entry; 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent; 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (blockcnt < 0) 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE; 1973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf); 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->errcode) 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (offset < fs->blocksize) { 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent = (struct ext2_dir_entry *) (ctx->buf + offset); 2043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ext2fs_get_rec_len(fs, dirent, &rec_len)) 2053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return BLOCK_ABORT; 2063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (((offset + rec_len) > fs->blocksize) || 2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (rec_len < 8) || 2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((rec_len % 4) != 0) || 2093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((((unsigned) dirent->name_len & 0xFF)+8) > rec_len)) { 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->errcode = EXT2_ET_DIR_CORRUPTED; 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dirent->inode && 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY)) 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = (ctx->func)(ctx->dir, 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (next_real_entry > offset) ? 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project DIRENT_DELETED_FILE : entry, 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent, offset, 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->blocksize, ctx->buf, 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->priv_data); 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (entry < DIRENT_OTHER_FILE) 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project entry++; 2253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ret & DIRENT_CHANGED) { 2273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ext2fs_get_rec_len(fs, dirent, &rec_len)) 2283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return BLOCK_ABORT; 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project changed++; 2303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret & DIRENT_ABORT) { 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_abort++; 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtnext: 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (next_real_entry == offset) 2373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_real_entry += rec_len; 2383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) { 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size = ((dirent->name_len & 0xFF) + 11) & ~3; 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (rec_len != size) { 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int final_offset; 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt final_offset = offset + rec_len; 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project offset += size; 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (offset < final_offset && 2483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt !ext2fs_validate_entry(fs, ctx->buf, 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project offset, 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project final_offset)) 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project offset += 4; 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt offset += rec_len; 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (changed) { 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf); 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->errcode) 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (do_abort) 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 268