version 1.10.2.4, 2014/05/22 11:41:04 |
version 1.11, 2011/12/25 06:09:08 |
|
|
#endif |
#endif |
typedef uint32_t ino32_t; |
typedef uint32_t ino32_t; |
#ifndef FSBTODB |
#ifndef FSBTODB |
#define FSBTODB(fs, indp) EXT2_FSBTODB(fs, indp) |
#define FSBTODB(fs, indp) fsbtodb(fs, indp) |
#endif |
#endif |
|
|
/* |
/* |
|
|
daddr_t f_buf_blkno; /* block number of data block */ |
daddr_t f_buf_blkno; /* block number of data block */ |
}; |
}; |
|
|
|
#if defined(LIBSA_ENABLE_LS_OP) |
|
|
|
#define NELEM(x) (sizeof (x) / sizeof(*x)) |
|
|
|
typedef struct entry_t entry_t; |
|
struct entry_t { |
|
entry_t *e_next; |
|
ino32_t e_ino; |
|
uint8_t e_type; |
|
char e_name[1]; |
|
}; |
|
|
|
static const char *const typestr[] = { |
|
"unknown", |
|
"REG", |
|
"DIR", |
|
"CHR", |
|
"BLK", |
|
"FIFO", |
|
"SOCK", |
|
"LNK" |
|
}; |
|
|
|
static int |
|
fn_match(const char *fname, const char *pattern) |
|
{ |
|
char fc, pc; |
|
|
|
do { |
|
fc = *fname++; |
|
pc = *pattern++; |
|
if (!fc && !pc) |
|
return 1; |
|
if (pc == '?' && fc) |
|
pc = fc; |
|
} while (fc == pc); |
|
|
|
if (pc != '*') |
|
return 0; |
|
/* |
|
* Too hard (and unnecessary really) too check for "*?name" etc.... |
|
* "**" will look for a '*' and "*?" a '?' |
|
*/ |
|
pc = *pattern++; |
|
if (!pc) |
|
return 1; |
|
while ((fname = strchr(fname, pc))) |
|
if (fn_match(++fname, pattern)) |
|
return 1; |
|
return 0; |
|
} |
|
#endif /* LIBSA_ENABLE_LS_OP */ |
|
|
static int read_inode(ino32_t, struct open_file *); |
static int read_inode(ino32_t, struct open_file *); |
static int block_map(struct open_file *, indp_t, indp_t *); |
static int block_map(struct open_file *, indp_t, indp_t *); |
Line 216 block_map(struct open_file *f, indp_t fi |
|
Line 268 block_map(struct open_file *f, indp_t fi |
|
/* |
/* |
* Index structure of an inode: |
* Index structure of an inode: |
* |
* |
* e2di_blocks[0..EXT2FS_NDADDR-1] |
* e2di_blocks[0..NDADDR-1] |
* hold block numbers for blocks |
* hold block numbers for blocks |
* 0..EXT2FS_NDADDR-1 |
* 0..NDADDR-1 |
* |
* |
* e2di_blocks[EXT2FS_NDADDR+0] |
* e2di_blocks[NDADDR+0] |
* block EXT2FS_NDADDR+0 is the single indirect block |
* block NDADDR+0 is the single indirect block |
* holds block numbers for blocks |
* holds block numbers for blocks |
* EXT2FS_NDADDR .. EXT2FS_NDADDR + EXT2_NINDIR(fs)-1 |
* NDADDR .. NDADDR + NINDIR(fs)-1 |
* |
* |
* e2di_blocks[EXT2FS_NDADDR+1] |
* e2di_blocks[NDADDR+1] |
* block EXT2FS_NDADDR+1 is the double indirect block |
* block NDADDR+1 is the double indirect block |
* holds block numbers for INDEX blocks for blocks |
* holds block numbers for INDEX blocks for blocks |
* EXT2FS_NDADDR + EXT2_NINDIR(fs) .. |
* NDADDR + NINDIR(fs) .. |
* EXT2FS_NDADDR + EXT2_NINDIR(fs) + EXT2_NINDIR(fs)**2 - 1 |
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1 |
* |
* |
* e2di_blocks[EXT2FS_NDADDR+2] |
* e2di_blocks[NDADDR+2] |
* block EXT2FS_NDADDR+2 is the triple indirect block |
* block NDADDR+2 is the triple indirect block |
* holds block numbers for double-indirect |
* holds block numbers for double-indirect |
* blocks for blocks |
* blocks for blocks |
* EXT2FS_NDADDR + EXT2_NINDIR(fs) + EXT2_NINDIR(fs)**2 .. |
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 .. |
* EXT2FS_NDADDR + EXT2_NINDIR(fs) + EXT2_NINDIR(fs)**2 |
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 |
* + EXT2_NINDIR(fs)**3 - 1 |
* + NINDIR(fs)**3 - 1 |
*/ |
*/ |
|
|
if (file_block < EXT2FS_NDADDR) { |
if (file_block < NDADDR) { |
/* Direct block. */ |
/* Direct block. */ |
*disk_block_p = fs2h32(fp->f_di.e2di_blocks[file_block]); |
*disk_block_p = fs2h32(fp->f_di.e2di_blocks[file_block]); |
return 0; |
return 0; |
} |
} |
|
|
file_block -= EXT2FS_NDADDR; |
file_block -= NDADDR; |
|
|
ind_cache = file_block >> LN2_IND_CACHE_SZ; |
ind_cache = file_block >> LN2_IND_CACHE_SZ; |
if (ind_cache == fp->f_ind_cache_block) { |
if (ind_cache == fp->f_ind_cache_block) { |
Line 259 block_map(struct open_file *f, indp_t fi |
|
Line 311 block_map(struct open_file *f, indp_t fi |
|
level += fp->f_nishift; |
level += fp->f_nishift; |
if (file_block < (indp_t)1 << level) |
if (file_block < (indp_t)1 << level) |
break; |
break; |
if (level > EXT2FS_NIADDR * fp->f_nishift) |
if (level > NIADDR * fp->f_nishift) |
/* Block number too high */ |
/* Block number too high */ |
return EFBIG; |
return EFBIG; |
file_block -= (indp_t)1 << level; |
file_block -= (indp_t)1 << level; |
} |
} |
|
|
ind_block_num = |
ind_block_num = |
fs2h32(fp->f_di.e2di_blocks[EXT2FS_NDADDR + |
fs2h32(fp->f_di.e2di_blocks[NDADDR + (level / fp->f_nishift - 1)]); |
(level / fp->f_nishift - 1)]); |
|
|
|
for (;;) { |
for (;;) { |
level -= fp->f_nishift; |
level -= fp->f_nishift; |
Line 317 buf_read_file(struct open_file *f, char |
|
Line 368 buf_read_file(struct open_file *f, char |
|
struct m_ext2fs *fs = fp->f_fs; |
struct m_ext2fs *fs = fp->f_fs; |
long off; |
long off; |
indp_t file_block; |
indp_t file_block; |
indp_t disk_block = 0; /* XXX: gcc */ |
indp_t disk_block; |
size_t block_size; |
size_t block_size; |
int rc; |
int rc; |
|
|
off = ext2_blkoff(fs, fp->f_seekp); |
off = blkoff(fs, fp->f_seekp); |
file_block = ext2_lblkno(fs, fp->f_seekp); |
file_block = lblkno(fs, fp->f_seekp); |
block_size = fs->e2fs_bsize; /* no fragment */ |
block_size = fs->e2fs_bsize; /* no fragment */ |
|
|
if (file_block != fp->f_buf_blkno) { |
if (file_block != fp->f_buf_blkno) { |
Line 546 ext2fs_open(const char *path, struct ope |
|
Line 597 ext2fs_open(const char *path, struct ope |
|
* of divide and remainder and avoinds pulling in the |
* of divide and remainder and avoinds pulling in the |
* 64bit division routine into the boot code. |
* 64bit division routine into the boot code. |
*/ |
*/ |
mult = EXT2_NINDIR(fs); |
mult = NINDIR(fs); |
#ifdef DEBUG |
#ifdef DEBUG |
if (!powerof2(mult)) { |
if (!powerof2(mult)) { |
/* Hummm was't a power of 2 */ |
/* Hummm was't a power of 2 */ |
Line 690 ext2fs_open(const char *path, struct ope |
|
Line 741 ext2fs_open(const char *path, struct ope |
|
out: |
out: |
if (rc) |
if (rc) |
ext2fs_close(f); |
ext2fs_close(f); |
else |
else { |
fsmod = "ext2fs"; |
fsmod = "ext2fs"; |
|
fsmod2 = "ffs"; |
|
} |
return rc; |
return rc; |
} |
} |
|
|
Line 804 ext2fs_stat(struct open_file *f, struct |
|
Line 857 ext2fs_stat(struct open_file *f, struct |
|
} |
} |
|
|
#if defined(LIBSA_ENABLE_LS_OP) |
#if defined(LIBSA_ENABLE_LS_OP) |
|
|
#include "ls.h" |
|
|
|
static const char *const typestr[] = { |
|
"unknown", |
|
"REG", |
|
"DIR", |
|
"CHR", |
|
"BLK", |
|
"FIFO", |
|
"SOCK", |
|
"LNK" |
|
}; |
|
|
|
__compactcall void |
__compactcall void |
ext2fs_ls(struct open_file *f, const char *pattern) |
ext2fs_ls(struct open_file *f, const char *pattern) |
{ |
{ |
Line 825 ext2fs_ls(struct open_file *f, const cha |
|
Line 864 ext2fs_ls(struct open_file *f, const cha |
|
size_t block_size = fp->f_fs->e2fs_bsize; |
size_t block_size = fp->f_fs->e2fs_bsize; |
char *buf; |
char *buf; |
size_t buf_size; |
size_t buf_size; |
lsentry_t *names = NULL; |
entry_t *names = 0, *n, **np; |
|
|
fp->f_seekp = 0; |
fp->f_seekp = 0; |
while (fp->f_seekp < (off_t)fp->f_di.e2di_size) { |
while (fp->f_seekp < (off_t)fp->f_di.e2di_size) { |
Line 864 ext2fs_ls(struct open_file *f, const cha |
|
Line 903 ext2fs_ls(struct open_file *f, const cha |
|
printf("bad dir entry\n"); |
printf("bad dir entry\n"); |
goto out; |
goto out; |
} |
} |
lsadd(&names, pattern, dp->e2d_name, |
if (pattern && !fn_match(dp->e2d_name, pattern)) |
strlen(dp->e2d_name), fs2h32(dp->e2d_ino), t); |
continue; |
|
n = alloc(sizeof *n + strlen(dp->e2d_name)); |
|
if (!n) { |
|
printf("%d: %s (%s)\n", |
|
fs2h32(dp->e2d_ino), dp->e2d_name, t); |
|
continue; |
|
} |
|
n->e_ino = fs2h32(dp->e2d_ino); |
|
n->e_type = dp->e2d_type; |
|
strcpy(n->e_name, dp->e2d_name); |
|
for (np = &names; *np; np = &(*np)->e_next) { |
|
if (strcmp(n->e_name, (*np)->e_name) < 0) |
|
break; |
|
} |
|
n->e_next = *np; |
|
*np = n; |
} |
} |
fp->f_seekp += buf_size; |
fp->f_seekp += buf_size; |
} |
} |
|
|
lsprint(names); |
if (names) { |
out: lsfree(names); |
entry_t *p_names = names; |
|
do { |
|
n = p_names; |
|
printf("%d: %s (%s)\n", |
|
n->e_ino, n->e_name, typestr[n->e_type]); |
|
p_names = n->e_next; |
|
} while (p_names); |
|
} else { |
|
printf("not found\n"); |
|
} |
|
out: |
|
if (names) { |
|
do { |
|
n = names; |
|
names = n->e_next; |
|
dealloc(n, 0); |
|
} while (names); |
|
} |
|
return; |
} |
} |
#endif |
#endif |
|
|
Line 958 void e2fs_i_bswap(struct ext2fs_dinode * |
|
Line 1030 void e2fs_i_bswap(struct ext2fs_dinode * |
|
new->e2di_dacl = bswap32(old->e2di_dacl); |
new->e2di_dacl = bswap32(old->e2di_dacl); |
new->e2di_faddr = bswap32(old->e2di_faddr); |
new->e2di_faddr = bswap32(old->e2di_faddr); |
memcpy(&new->e2di_blocks[0], &old->e2di_blocks[0], |
memcpy(&new->e2di_blocks[0], &old->e2di_blocks[0], |
(EXT2FS_NDADDR + EXT2FS_NIADDR) * sizeof(uint32_t)); |
(NDADDR + NIADDR) * sizeof(uint32_t)); |
} |
} |
#endif |
#endif |
|
|