/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
#include <linux/fs.h>
+#include <linux/quotaops.h>
+#include <linux/vs_dlimit.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_filsys.h"
static void dtGetKey(dtpage_t * p, int i, struct component_name * key,
int flag);
-static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
- int ri, struct component_name * key, int flag);
+static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
+ int ri, struct component_name * key, int flag);
static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
ddata_t * data, struct dt_lock **);
s32 xlen;
rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
- if (rc || (xlen == 0))
+ if (rc || (xaddr == 0))
return NULL;
return read_metapage(inode, xaddr, PSIZE, 1);
s32 xlen;
rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
- if (rc || (xlen == 0))
+ if (rc || (xaddr == 0))
return NULL;
return get_metapage(inode, xaddr, PSIZE, 1);
jfs_warn("find_entry called with index = %d", index);
maxWarnings--;
}
- return 0;
+ return NULL;
}
if (index >= jfs_ip->next_index) {
jfs_warn("find_entry called with index >= next_index");
- return 0;
+ return NULL;
}
- if (jfs_ip->next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+ if (jfs_dirtable_inline(ip)) {
/*
* Inline directory table
*/
- *mp = 0;
+ *mp = NULL;
slot = &jfs_ip->i_dirtable[index - 2];
} else {
offset = (index - 2) * sizeof(struct dir_table_slot);
if (*mp && (*lblock != blkno)) {
release_metapage(*mp);
- *mp = 0;
+ *mp = NULL;
}
if (*mp == 0) {
*lblock = blkno;
}
if (*mp == 0) {
jfs_err("free_index: error reading directory table");
- return 0;
+ return NULL;
}
slot =
struct metapage *mp;
s64 offset;
uint page_offset;
- int rc;
struct tlock *tlck;
s64 xaddr;
return index;
}
if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+ struct dir_table_slot temp_table[12];
+
/*
* It's time to move the inline table to an external
* page and begin to build the xtree
*/
+ if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
+ goto clean_up;
+ if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
+ goto clean_up_quota;
+ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
+ goto clean_up_dlim;
/*
* Save the table, we're going to overwrite it with the
* xtree root
*/
- struct dir_table_slot temp_table[12];
memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table));
/*
xtInitRoot(tid, ip);
/*
- * Allocate the first block & add it to the xtree
+ * Add the first block to the xtree
*/
- xaddr = 0;
- if ((rc =
- xtInsert(tid, ip, 0, 0, sbi->nbperpage,
- &xaddr, 0))) {
+ if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
+ /* This really shouldn't fail */
jfs_warn("add_index: xtInsert failed!");
- return -EPERM;
+ memcpy(&jfs_ip->i_dirtable, temp_table,
+ sizeof (temp_table));
+ dbFree(ip, xaddr, sbi->nbperpage);
+ DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+ goto clean_up;
}
ip->i_size = PSIZE;
- ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
if ((mp = get_index_page(ip, 0)) == 0) {
jfs_err("add_index: get_metapage failed!");
xtTruncate(tid, ip, 0, COMMIT_PWMAP);
- return -EPERM;
+ memcpy(&jfs_ip->i_dirtable, temp_table,
+ sizeof (temp_table));
+ goto clean_up;
}
tlck = txLock(tid, ip, mp, tlckDATA);
llck = (struct linelock *) & tlck->lock;
* This will be the beginning of a new page
*/
xaddr = 0;
- if ((rc =
- xtInsert(tid, ip, 0, blkno, sbi->nbperpage,
- &xaddr, 0))) {
+ if (xtInsert(tid, ip, 0, blkno, sbi->nbperpage, &xaddr, 0)) {
jfs_warn("add_index: xtInsert failed!");
- jfs_ip->next_index--;
- return -EPERM;
+ goto clean_up;
}
ip->i_size += PSIZE;
- ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
if ((mp = get_index_page(ip, blkno)))
memset(mp->data, 0, PSIZE); /* Just looks better */
if (mp == 0) {
jfs_err("add_index: get/read_metapage failed!");
- return -EPERM;
+ goto clean_up;
}
lock_index(tid, ip, mp, index);
release_metapage(mp);
return index;
+
+ clean_up_dlim:
+ DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
+ clean_up_quota:
+ DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+ clean_up:
+
+ jfs_ip->next_index--;
+
+ return 0;
}
/*
{
struct dir_table_slot *dirtab_slot;
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
dirtab_slot = find_index(ip, index, &mp, &lblock);
struct dir_table_slot * dirtab_slot)
{
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
struct dir_table_slot *slot;
slot = find_index(ip, index, &mp, &lblock);
*/
getChild:
/* update max. number of pages to split */
- if (btstack->nsplit >= 8) {
+ if (BT_STACK_FULL(btstack)) {
/* Something's corrupted, mark filesytem dirty so
* chkdsk will fix it.
*/
jfs_error(sb, "stack overrun in dtSearch!");
+ BT_STACK_DUMP(btstack);
rc = -EIO;
goto out;
}
data.leaf.ip = ip;
} else {
n = NDTLEAF_LEGACY(name->namlen);
- data.leaf.ip = 0; /* signifies legacy directory format */
+ data.leaf.ip = NULL; /* signifies legacy directory format */
}
- data.leaf.ino = cpu_to_le32(*fsn);
+ data.leaf.ino = *fsn;
/*
* leaf page does not have enough room for new entry:
int xlen, xsize;
struct pxdlist pxdlist;
pxd_t *pxd;
- struct component_name key = { 0, 0 };
+ struct component_name key = { 0, NULL };
ddata_t *data = split->data;
int n;
struct dt_lock *dtlck;
struct tlock *tlck;
struct lv *lv;
+ int quota_allocation = 0;
+ int dlimit_allocation = 0;
/* get split page */
smp = split->mp;
n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */
if (n <= split->nslot)
xlen++;
- if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)))
+ if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) {
+ DT_PUTPAGE(smp);
goto freeKeyName;
+ }
pxdlist.maxnpxd = 1;
pxdlist.npxd = 0;
split->pxdlist = &pxdlist;
rc = dtSplitRoot(tid, ip, split, &rmp);
- if (!rc)
+ if (rc)
+ dbFree(ip, xaddr, xlen);
+ else
DT_PUTPAGE(rmp);
DT_PUTPAGE(smp);
+ if (!DO_INDEX(ip))
+ ip->i_size = xlen << sbi->l2bsize;
+
goto freeKeyName;
}
n = xlen + (xlen << 1);
else
n = xlen;
+
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, n)) {
+ rc = -EDQUOT;
+ goto extendOut;
+ }
+ quota_allocation += n;
+
+ if (DLIMIT_ALLOC_BLOCK(ip, n)) {
+ rc = -ENOSPC;
+ goto extendOut;
+ }
+ dlimit_allocation += n;
+
if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
(s64) n, &nxaddr)))
goto extendOut;
xaddr = addressPXD(pxd) + xlen;
dbFree(ip, xaddr, (s64) n);
}
- }
+ } else if (!DO_INDEX(ip))
+ ip->i_size = lengthPXD(pxd) << sbi->l2bsize;
+
extendOut:
DT_PUTPAGE(smp);
goto splitOut;
}
+ if (!DO_INDEX(ip))
+ ip->i_size += PSIZE;
+
/*
* propagate up the router entry for the leaf page just split
*
if ((sp->header.flag & BT_ROOT && skip > 1) ||
sp->header.prev != 0 || skip > 1) {
/* compute uppercase router prefix key */
- ciGetLeafPrefixKey(lp,
- lp->header.nextindex - 1,
- rp, 0, &key, sbi->mntflag);
+ rc = ciGetLeafPrefixKey(lp,
+ lp->header.nextindex-1,
+ rp, 0, &key,
+ sbi->mntflag);
+ if (rc) {
+ DT_PUTPAGE(lmp);
+ DT_PUTPAGE(rmp);
+ DT_PUTPAGE(smp);
+ goto splitOut;
+ }
} else {
/* next to leftmost entry of
lowest internal level */
freeKeyName:
kfree(key.name);
+ /* Rollback dlimit allocation */
+ if (rc && dlimit_allocation)
+ DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
+ /* Rollback quota allocation */
+ if (rc && quota_allocation)
+ DQUOT_FREE_BLOCK(ip, quota_allocation);
+
dtSplitUp_Exit:
return rc;
static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
{
- struct super_block *sb = ip->i_sb;
int rc = 0;
struct metapage *smp;
dtpage_t *sp;
if (rmp == NULL)
return -EIO;
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ release_metapage(rmp);
+ return -EDQUOT;
+ }
+ /* Allocate blocks to dlimit. */
+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
+ release_metapage(rmp);
+ return -ENOSPC;
+ }
+
jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
BT_MARK_DIRTY(rmp, ip);
if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
s64 lblock;
- mp = 0;
+ mp = NULL;
stbl = DT_GETSTBL(rp);
for (n = 0; n < rp->header.nextindex; n++) {
ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
*rmpp = rmp;
*rpxdp = *pxd;
- ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd));
-
return rc;
}
if (DO_INDEX(ip)) {
s64 lblock;
- mp = 0;
+ mp = NULL;
stbl = DT_GETSTBL(sp);
for (n = 0; n < sp->header.nextindex; n++) {
ldtentry =
tpxd = (pxd_t *) & pp->slot[1];
*tpxd = *pxd;
- /* Since the directory might have an EA and/or ACL associated with it
- * we need to make sure we take that into account when setting the
- * i_nblocks
- */
- ip->i_blocks = LBLK2PBLK(ip->i_sb, xlen +
- ((JFS_IP(ip)->ea.flag & DXD_EXTENT) ?
- lengthDXD(&JFS_IP(ip)->ea) : 0) +
- ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ?
- lengthDXD(&JFS_IP(ip)->acl) : 0));
-
DT_PUTPAGE(pmp);
return 0;
}
rp = rmp->data;
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ release_metapage(rmp);
+ return -EDQUOT;
+ }
+ /* Allocate blocks to dlimit. */
+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
+ release_metapage(rmp);
+ return -ENOSPC;
+ }
+
BT_MARK_DIRTY(rmp, ip);
/*
* acquire a transaction lock on the new right page
*/
if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
struct ldtentry *ldtentry;
stbl = DT_GETSTBL(rp);
*rmpp = rmp;
- ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
return 0;
}
if (DO_INDEX(ip) && index < p->header.nextindex) {
s64 lblock;
- imp = 0;
+ imp = NULL;
stbl = DT_GETSTBL(p);
for (i = index; i < p->header.nextindex; i++) {
ldtentry =
}
xlen = lengthPXD(&fp->header.self);
- ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+ /* Free dlimit allocation. */
+ DLIMIT_FREE_BLOCK(ip, xlen);
+ /* Free quota allocation. */
+ DQUOT_FREE_BLOCK(ip, xlen);
/* free/invalidate its buffer page */
discard_metapage(fmp);
}
xlen = lengthPXD(&p->header.self);
- ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+ /* Free dlimit allocation */
+ DLIMIT_FREE_BLOCK(ip, xlen);
+ /* Free quota allocation */
+ DQUOT_FREE_BLOCK(ip, xlen);
/* free/invalidate its buffer page */
discard_metapage(mp);
break;
}
+ if (!DO_INDEX(ip))
+ ip->i_size -= PSIZE;
+
return 0;
}
* the old directory table.
*/
if (DO_INDEX(ip)) {
- if (jfs_ip->next_index > (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+ if (!jfs_dirtable_inline(ip)) {
struct tblock *tblk = tid_to_tblock(tid);
/*
* We're playing games with the tid's xflag. If
/* init '..' entry */
p->header.idotdot = cpu_to_le32(idotdot);
-#if 0
- ip->i_blocks = LBLK2PBLK(ip->i_sb,
- ((jfs_ip->ea.flag & DXD_EXTENT) ?
- lengthDXD(&jfs_ip->ea) : 0) +
- ((jfs_ip->acl.flag & DXD_EXTENT) ?
- lengthDXD(&jfs_ip->acl) : 0));
-#endif
-
return;
}
ASSERT(p->header.flag & BT_LEAF);
tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
+ if (BT_IS_ROOT(mp))
+ tlck->type |= tlckBTROOT;
+
dtlck = (struct dt_lock *) &tlck->lock;
stbl = DT_GETSTBL(p);
d = (struct ldtentry *) & p->slot[stbl[i]];
if (((long) jfs_dirent + d->namlen + 1) >
- (dirent_buf + PSIZE)) {
+ (dirent_buf + PAGE_SIZE)) {
/* DBCS codepages could overrun dirent_buf */
index = i;
overflow = 1;
/*
* descend down to leftmost child page
*/
+ if (BT_STACK_FULL(btstack)) {
+ DT_PUTPAGE(mp);
+ jfs_error(ip->i_sb, "dtReadFirst: btstack overrun");
+ BT_STACK_DUMP(btstack);
+ return -EIO;
+ }
/* push (bn, index) of the parent page/entry */
BT_PUSH(btstack, bn, 0);
dtpage_t * p, /* directory page */
int si)
{ /* entry slot index */
- wchar_t *kname, *name;
+ wchar_t *kname;
+ __le16 *name;
int klen, namlen, len, rc;
struct idtentry *ih;
struct dtslot *t;
int si, /* entry slot index */
int flag)
{
- wchar_t *kname, *name, x;
+ wchar_t *kname, x;
+ __le16 *name;
int klen, namlen, len, rc;
struct ldtentry *lh;
struct idtentry *ih;
* from two adjacent leaf entries
* across page boundary
*
- * return:
- * Number of prefix bytes needed to distinguish b from a.
+ * return: non-zero on error
+ *
*/
-static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
+static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
int ri, struct component_name * key, int flag)
{
int klen, namlen;
wchar_t *pl, *pr, *kname;
- wchar_t lname[JFS_NAME_MAX + 1];
- struct component_name lkey = { 0, lname };
- wchar_t rname[JFS_NAME_MAX + 1];
- struct component_name rkey = { 0, rname };
+ struct component_name lkey;
+ struct component_name rkey;
+
+ lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+ GFP_KERNEL);
+ if (lkey.name == NULL)
+ return -ENOSPC;
+
+ rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+ GFP_KERNEL);
+ if (rkey.name == NULL) {
+ kfree(lkey.name);
+ return -ENOSPC;
+ }
/* get left and right key */
dtGetKey(lp, li, &lkey, flag);
*kname = *pr;
if (*pl != *pr) {
key->namlen = klen + 1;
- return;
+ goto free_names;
}
}
} else /* l->namelen == r->namelen */
key->namlen = klen;
- return;
+free_names:
+ kfree(lkey.name);
+ kfree(rkey.name);
+ return 0;
}
struct idtentry *ih;
struct dtslot *t;
int namlen, len;
- wchar_t *name, *kname;
+ wchar_t *kname;
+ __le16 *name;
/* get entry */
stbl = DT_GETSTBL(p);
/*
* move head/only segment
*/
- UniStrncpy_le(kname, name, len);
+ UniStrncpy_from_le(kname, name, len);
/*
* move additional segment(s)
kname += len;
namlen -= len;
len = min(namlen, DTSLOTDATALEN);
- UniStrncpy_le(kname, t->name, len);
+ UniStrncpy_from_le(kname, t->name, len);
si = t->next;
}
ddata_t * data, struct dt_lock ** dtlock)
{
struct dtslot *h, *t;
- struct ldtentry *lh = 0;
- struct idtentry *ih = 0;
+ struct ldtentry *lh = NULL;
+ struct idtentry *ih = NULL;
int hsi, fsi, klen, len, nextindex;
- wchar_t *kname, *name;
+ wchar_t *kname;
+ __le16 *name;
s8 *stbl;
pxd_t *xd;
struct dt_lock *dtlck = *dtlock;
struct lv *lv;
int xsi, n;
s64 bn = 0;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
klen = key->namlen;
kname = key->name;
if (p->header.flag & BT_LEAF) {
lh = (struct ldtentry *) h;
lh->next = h->next;
- lh->inumber = data->leaf.ino; /* little-endian */
+ lh->inumber = cpu_to_le32(data->leaf.ino);
lh->namlen = klen;
name = lh->name;
if (data->leaf.ip) {
len = min(klen, DTIHDRDATALEN);
}
- UniStrncpy_le(name, kname, len);
+ UniStrncpy_to_le(name, kname, len);
n = 1;
xsi = hsi;
kname += len;
len = min(klen, DTSLOTDATALEN);
- UniStrncpy_le(t->name, kname, len);
+ UniStrncpy_to_le(t->name, kname, len);
n++;
xsi = fsi;
* Need to update slot number for entries that moved
* in the stbl
*/
- mp = 0;
+ mp = NULL;
for (n = index + 1; n <= nextindex; n++) {
lh = (struct ldtentry *) & (p->slot[stbl[n]]);
modify_index(data->leaf.tid, data->leaf.ip,
int dsi; /* dst slot index */
s8 *sstbl, *dstbl; /* sorted entry table */
int snamlen, len;
- struct ldtentry *slh, *dlh = 0;
- struct idtentry *sih, *dih = 0;
+ struct ldtentry *slh, *dlh = NULL;
+ struct idtentry *sih, *dih = NULL;
struct dtslot *h, *s, *d;
struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock;
struct lv *slv, *dlv;
d++;
len = min(snamlen, DTSLOTDATALEN);
- UniStrncpy(d->name, s->name, len);
+ UniStrncpy_le(d->name, s->name, len);
ns++;
nd++;
return 0;
}
-
-#ifdef _JFS_DEBUG_DTREE
-/*
- * dtDisplayTree()
- *
- * function: traverse forward
- */
-int dtDisplayTree(struct inode *ip)
-{
- int rc;
- struct metapage *mp;
- dtpage_t *p;
- s64 bn, pbn;
- int index, lastindex, v, h;
- pxd_t *xd;
- struct btstack btstack;
- struct btframe *btsp;
- struct btframe *parent;
- u8 *stbl;
- int psize = 256;
-
- printk("display B+-tree.\n");
-
- /* clear stack */
- btsp = btstack.stack;
-
- /*
- * start with root
- *
- * root resides in the inode
- */
- bn = 0;
- v = h = 0;
-
- /*
- * first access of each page:
- */
- newPage:
- DT_GETPAGE(ip, bn, mp, psize, p, rc);
- if (rc)
- return rc;
-
- /* process entries forward from first index */
- index = 0;
- lastindex = p->header.nextindex - 1;
-
- if (p->header.flag & BT_INTERNAL) {
- /*
- * first access of each internal page
- */
- printf("internal page ");
- dtDisplayPage(ip, bn, p);
-
- goto getChild;
- } else { /* (p->header.flag & BT_LEAF) */
-
- /*
- * first access of each leaf page
- */
- printf("leaf page ");
- dtDisplayPage(ip, bn, p);
-
- /*
- * process leaf page entries
- *
- for ( ; index <= lastindex; index++)
- {
- }
- */
-
- /* unpin the leaf page */
- DT_PUTPAGE(mp);
- }
-
- /*
- * go back up to the parent page
- */
- getParent:
- /* pop/restore parent entry for the current child page */
- if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL)
- /* current page must have been root */
- return;
-
- /*
- * parent page scan completed
- */
- if ((index = parent->index) == (lastindex = parent->lastindex)) {
- /* go back up to the parent page */
- goto getParent;
- }
-
- /*
- * parent page has entries remaining
- */
- /* get back the parent page */
- bn = parent->bn;
- /* v = parent->level; */
- DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
- if (rc)
- return rc;
-
- /* get next parent entry */
- index++;
-
- /*
- * internal page: go down to child page of current entry
- */
- getChild:
- /* push/save current parent entry for the child page */
- btsp->bn = pbn = bn;
- btsp->index = index;
- btsp->lastindex = lastindex;
- /* btsp->level = v; */
- /* btsp->node = h; */
- ++btsp;
-
- /* get current entry for the child page */
- stbl = DT_GETSTBL(p);
- xd = (pxd_t *) & p->slot[stbl[index]];
-
- /*
- * first access of each internal entry:
- */
-
- /* get child page */
- bn = addressPXD(xd);
- psize = lengthPXD(xd) << ip->i_ipmnt->i_l2bsize;
-
- printk("traverse down 0x%Lx[%d]->0x%Lx\n", pbn, index, bn);
- v++;
- h = index;
-
- /* release parent page */
- DT_PUTPAGE(mp);
-
- /* process the child page */
- goto newPage;
-}
-
-
-/*
- * dtDisplayPage()
- *
- * function: display page
- */
-int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p)
-{
- int rc;
- struct metapage *mp;
- struct ldtentry *lh;
- struct idtentry *ih;
- pxd_t *xd;
- int i, j;
- u8 *stbl;
- wchar_t name[JFS_NAME_MAX + 1];
- struct component_name key = { 0, name };
- int freepage = 0;
-
- if (p == NULL) {
- freepage = 1;
- DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
- if (rc)
- return rc;
- }
-
- /* display page control */
- printk("bn:0x%Lx flag:0x%08x nextindex:%d\n",
- bn, p->header.flag, p->header.nextindex);
-
- /* display entries */
- stbl = DT_GETSTBL(p);
- for (i = 0, j = 1; i < p->header.nextindex; i++, j++) {
- dtGetKey(p, i, &key, JFS_SBI(ip->i_sb)->mntflag);
- key.name[key.namlen] = '\0';
- if (p->header.flag & BT_LEAF) {
- lh = (struct ldtentry *) & p->slot[stbl[i]];
- printf("\t[%d] %s:%d", i, key.name,
- le32_to_cpu(lh->inumber));
- } else {
- ih = (struct idtentry *) & p->slot[stbl[i]];
- xd = (pxd_t *) ih;
- bn = addressPXD(xd);
- printf("\t[%d] %s:0x%Lx", i, key.name, bn);
- }
-
- if (j == 4) {
- printf("\n");
- j = 0;
- }
- }
-
- printf("\n");
-
- if (freepage)
- DT_PUTPAGE(mp);
-
- return 0;
-}
-#endif /* _JFS_DEBUG_DTREE */