}
static u64
-leaf_lookup(void *bf, int len, u32 startaddr, u32 target, u32 *nextp)
+leaf_lookup(void *bf, int len, u32 target, u32 *nextp)
{
/* buf starts with a 2byte header
* if 1, then 6byte littleending indirect entries.
break;
case IBLK_INDIRECT: /* indirect */
- dprintk("indirect lookup for %lu from %lu, len %d\n",
- (unsigned long)target, (unsigned long)startaddr, len);
len -= 2;
buf += 2;
+ addr = decode32(buf);
+ len -= 4;
+ dprintk("indirect lookup for %lu from %lu, len %d\n",
+ (unsigned long)target, (unsigned long)addr, len);
- if (target < startaddr)
+ if (target < addr)
return 0;
next = target;
- target -= startaddr;
+ target -= addr;
/* Need both tests as target could be v.large and
* multiply by 6 could overflow
if (test_bit(B_InoIdx, &ib->b.flags))
phys = leaf_lookup(buf + li->metadata_size,
blocksize - li->metadata_size,
- ib->b.fileaddr, start, &next);
+ start, &next);
else
phys = leaf_lookup(buf, blocksize,
- ib->b.fileaddr, start, &next);
+ start, &next);
unmap_iblock(ib, buf);
if (phys)
return start;
offset = lai->metadata_size;
buf = map_iblock(leaf);
p = leaf_lookup(buf+offset, fs->prime_sb->s_blocksize-offset,
- leaf->b.fileaddr, (u32)*addrp, &nextd);
+ (u32)*addrp, &nextd);
unmap_iblock(leaf, buf);
if (p) {
lafs_iounlock_block(&leaf->b);
b->b.physaddr = leaf_lookup(buf+offset,
b->b.inode->i_sb->s_blocksize
- offset,
- ib->b.fileaddr, b->b.fileaddr,
+ b->b.fileaddr,
NULL);
set_bit(B_PhysValid, &b->b.flags);
unmap_iblock(ib, buf);
return cr;
}
-static int incorporate_indirect(struct uninc *ui, char *buf, u32 addr, int len)
+static int incorporate_indirect(struct uninc *ui, char *buf, int len)
{
/* See if this uninc info can be incorporated directly into
* this indirect block, and if it can: do it.
*/
int i;
int credits = 0;
+ u32 addr;
+
+ addr = decode32(buf);
+ len -= 4;
if ( ui->pending_addr[ui->pending_cnt-1].fileaddr
+ui->pending_addr[ui->pending_cnt-1].cnt
atomic_set(&new->pincnt[!!test_bit(B_Phase1, &ib->b.flags)], 1);
}
-static void print_index(char *buf, u32 start, int len)
+static void print_index(char *buf, int len)
{
int type = le16_to_cpu(*(u16 *)(buf));
char *p = buf+2;
switch (type) {
case IBLK_INDIRECT:
- printk(" Indirect:\n");
+ addr = decode32(p);
+ printk(" Indirect %lu:\n", (unsigned long)addr);
while (len >= 6) {
phys = decode48(p);
if (phys)
- printk(" %u:%lu", start, (unsigned long)phys);
- start++;
+ printk(" %u:%lu", addr, (unsigned long)phys);
+ addr++;
len -= 6;
}
printk("\n");
if (phys == 0) {
/* initialise */
- li->lastaddr = addr;
+ li->lastphys = 0;
p = li->data;
encode16(p, IBLK_INDIRECT);
li->size -= 2;
if (len == 0)
return 0; /* finalise */
+ if (li->lastphys == 0) {
+ /* This is the first address, add the address header */
+ li->lastaddr = addr;
+ li->lastphys = phys;
+ p = li->data;
+ encode32(p, addr);
+ li->data = p;
+ li->size -= 4;
+ }
p = li->data + (addr - li->lastaddr) * 6;
lastaddr = li->lastaddr + (li->size/6);
for (i = 0; i < len && addr < lastaddr ; i++) {
if (phys == 0) {
/* We are initialising the structure */
memset(li, 0, sizeof(*li));
- li->firstaddr = addr;
li->blksize = len - 2; /* exclude type filed */
return 0;
}
if (len == 0)
return 0; /* nothing to finalise */
+ if (li->cnt == 0)
+ li->firstaddr = addr;
li->cnt++;
/* Check for indirect layout */
- if (((addr + len) - li->firstaddr) * 6 > li->blksize) {
+ if (((addr + len) - li->firstaddr) * 6 > (li->blksize-4)) {
/* Indirect no longer fits */
if (!li->choice)
li->choice = IBLK_EXTENT;
return origlen;
}
-static u32 walk_index(u32 addr, char **bufp, int len, struct block *uninc,
+static u32 walk_index(char **bufp, int len, struct block *uninc,
int (*handle)(void*, u32, u64),
void *data)
{
*/
char *buf = *bufp;
- handle(data, addr, 0); /* initialise */
+ handle(data, 0, 0); /* initialise */
while (len >= 10 || uninc != NULL) {
unsigned long addr = 0;
return 0;
}
-static u32 walk_indirect(u32 addr, char **bufp, int len, struct uninc *ui,
+static u32 walk_indirect(char **bufp, int len, struct uninc *ui,
int (*handle)(void*, u32, u64, int),
void *data)
{
int uinum = 0;
int uioffset = 0;
char *buf = *bufp;
+ u32 addr;
+
- handle(data, addr, 0, len); /* initialise */
+ handle(data, 0, 0, len); /* initialise */
+ addr = decode32(buf);
+ len -= 4;
while (len >= 6 || uinum < ui->pending_cnt) {
u64 phys = 0;
return 0;
}
-static u32 walk_extent(u32 addr, char **bufp, int len, struct uninc *ui,
- int (*handle)(void*, u32, u64, int),
- void *data)
+static u32 walk_extent(char **bufp, int len, struct uninc *ui,
+ int (*handle)(void*, u32, u64, int),
+ void *data)
{
/* pass each extent in buf or ui to handle. Extents
* can overlap, so care is needed
int handled;
char *buf = *bufp;
- handle(data, addr, 0, len); /* initialise */
+ handle(data, 0, 0, len); /* initialise */
while (len >= 12 || uinum < ui->pending_cnt || elen) {
dprintk("CURRENT=%d\n", current_layout);
switch (current_layout) {
case IBLK_INDIRECT:
- walk_indirect(ib->b.fileaddr,
- &buf, len-2, &ui,
+ walk_indirect(&buf, len-2, &ui,
handle, data);
break;
case IBLK_EXTENT:
- walk_extent(ib->b.fileaddr,
- &buf, len-2, &ui,
+ walk_extent(&buf, len-2, &ui,
handle, data);
break;
default:
buf = ibuf + offset + 2;
switch (current_layout) {
case IBLK_INDIRECT:
- walk_indirect(ib->b.fileaddr,
- &buf, len-2, ui,
+ walk_indirect(&buf, len-2, ui,
check_leaf, &leafinfo);
break;
case IBLK_EXTENT:
- walk_extent(ib->b.fileaddr,
- &buf, len-2, ui,
+ walk_extent(&buf, len-2, ui,
check_leaf, &leafinfo);
break;
default:
buf = ibuf + offset + 2;
switch (current_layout) {
case IBLK_INDIRECT:
- next = walk_indirect(ib->b.fileaddr,
- &buf, len-2, ui,
+ next = walk_indirect(&buf, len-2, ui,
(choice == IBLK_EXTENT)
? add_extent : add_indirect,
&layout);
break;
case IBLK_EXTENT:
- next = walk_extent(ib->b.fileaddr,
- &buf, len-2, ui,
+ next = walk_extent(&buf, len-2, ui,
(choice == IBLK_EXTENT)
? add_extent : add_indirect,
&layout);
break;
}
dprintk("walk_leaf only got as far as %d\n", (int)next);
- // print_index(ibuf+offset, ib->b.fileaddr, len);
+ // print_index(ibuf+offset, len);
if (next == 0) {
/* it all fit perfectly.
* Copy from 'new' into 'ib' and zero the uninc list
}
layout.data = ibuf;
layout.size = len;
- next2 = walk_extent(next, &sbuf, slen, ui, add_extent, &layout);
+ next2 = walk_extent(&sbuf, slen, ui, add_extent, &layout);
LAFS_BUG(next2 != 0, &ib->b);
if (slen && layout.data > sbuf) {
printk("slen=%d ld-sb=%d layout.data=%p sbuf=%p "
buf = ibuf + offset + 2;
- next = walk_index(ib->b.fileaddr,
- &buf, len-2, uninc,
+ next = walk_index(&buf, len-2, uninc,
add_index,
&layout);
/* Maybe a direct update of an indirect block */
if (*(u16 *)(buf) == cpu_to_le16(IBLK_INDIRECT) &&
incorporate_indirect(&uit, buf+2,
- ib->b.fileaddr,
blocksize-(offset+2))) {
unmap_iblock(ib, buf-offset);
goto out;
dprintk("Index contains:\n");
if (lafs_trace)
- print_index(buf, ib->b.fileaddr, blocksize - offset);
+ print_index(buf, blocksize - offset);
dprintk("uninc contains:\n");
if (lafs_trace)
lafs_print_uninc(&uit);
if (lafs_trace) {
struct block *b;
- print_index(buf, ib->b.fileaddr, blocksize - offset);
+ print_index(buf, blocksize - offset);
printk("uninc list:\n");
for (b = uninc; b ; b=b->chain)
printk(" %lu: %llu\n",