Commit fff4f98f authored by Dave Kleikamp's avatar Dave Kleikamp

Merge jfs@jfs.bkbits.net:linux-2.5

into austin.ibm.com:/shaggy/bk/jfs-2.5
parents 929ad084 fa2c79c3
/*
* Copyright (c) International Business Machines Corp., 2000-2001
* 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
......@@ -108,13 +108,12 @@ struct btpage {
* record the path traversed during the search;
* top frame record the leaf page/entry selected.
*/
#define MAXTREEHEIGHT 8
struct btframe { /* stack frame */
s64 bn; /* 8: */
s16 index; /* 2: */
s16 lastindex; /* 2: */
struct metapage *mp; /* 4: */
}; /* (16) */
s16 lastindex; /* 2: unused */
struct metapage *mp; /* 4/8: */
}; /* (16/24) */
struct btstack {
struct btframe *top;
......@@ -125,12 +124,15 @@ struct btstack {
#define BT_CLR(btstack)\
(btstack)->top = (btstack)->stack
#define BT_STACK_FULL(btstack)\
( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
#define BT_PUSH(BTSTACK, BN, INDEX)\
{\
assert(!BT_STACK_FULL(BTSTACK));\
(BTSTACK)->top->bn = BN;\
(BTSTACK)->top->index = INDEX;\
++(BTSTACK)->top;\
assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
}
#define BT_POP(btstack)\
......@@ -139,6 +141,16 @@ struct btstack {
#define BT_STACK(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
static inline void BT_STACK_DUMP(struct btstack *btstack)
{
int i;
printk("btstack dump:\n");
for (i = 0; i < MAXTREEHEIGHT; i++)
printk(KERN_ERR "bn = %Lx, index = %d\n",
btstack->stack[i].bn,
btstack->stack[i].index);
}
/* retrieve search results */
#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
{\
......
/*
* 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
......@@ -382,7 +382,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
IREAD_LOCK(ipbmap);
/* block to be freed better be within the mapsize. */
if (blkno + nblocks > bmp->db_mapsize) {
if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
IREAD_UNLOCK(ipbmap);
printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",
(unsigned long long) blkno,
......
/*
* 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
......@@ -378,6 +378,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
* It's time to move the inline table to an external
* page and begin to build the xtree
*/
if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
goto clean_up; /* No space */
/*
* Save the table, we're going to overwrite it with the
......@@ -394,8 +396,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
/*
* Allocate the first block & add it to the xtree
*/
xaddr = 0;
if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
/* This really shouldn't fail */
jfs_warn("add_index: xtInsert failed!");
memcpy(&jfs_ip->i_dirtable, temp_table,
sizeof (temp_table));
......@@ -764,11 +766,12 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
*/
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;
}
......@@ -975,8 +978,10 @@ static int dtSplitUp(tid_t tid,
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;
......@@ -3342,6 +3347,12 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
/*
* 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);
......
......@@ -1747,7 +1747,10 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
if (lwm == next)
goto out;
assert(lwm < next);
if (lwm > next) {
jfs_err("xtLog: lwm > next\n");
goto out;
}
tlck->flag |= tlckUPDATEMAP;
xadlock->flag = mlckALLOCXADLIST;
xadlock->count = next - lwm;
......@@ -1913,11 +1916,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
/*
* write log records
*/
/*
* allocate entries XAD[lwm:next]:
*/
if (lwm < next) {
/* log after-image for logredo():
*
* logredo() will update bmap for alloc of new/extended
* extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
* after-image of XADlist;
......@@ -1926,12 +1926,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
*/
lrd->type = cpu_to_le16(LOG_REDOPAGE);
PXDaddress(pxd, mp->index);
PXDlength(pxd,
mp->logical_size >> tblk->sb->
s_blocksize_bits);
lrd->backchain =
cpu_to_le32(lmLog(log, tblk, lrd, tlck));
}
PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);
lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
/*
* truncate entry XAD[twm == next - 1]:
......@@ -2624,6 +2620,7 @@ void txAbort(tid_t tid, int dirty)
lid_t lid, next;
struct metapage *mp;
struct tblock *tblk = tid_to_tblock(tid);
struct tlock *tlck;
jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty);
......@@ -2631,9 +2628,10 @@ void txAbort(tid_t tid, int dirty)
* free tlocks of the transaction
*/
for (lid = tblk->next; lid; lid = next) {
next = lid_to_tlock(lid)->next;
mp = lid_to_tlock(lid)->mp;
tlck = lid_to_tlock(lid);
next = tlck->next;
mp = tlck->mp;
JFS_IP(tlck->ip)->xtlid = 0;
if (mp) {
mp->lid = 0;
......
......@@ -113,11 +113,12 @@ typedef struct {
#define addressPXD(pxd)\
( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
#define MAXTREEHEIGHT 8
/* pxd list */
struct pxdlist {
s16 maxnpxd;
s16 npxd;
pxd_t pxd[8];
pxd_t pxd[MAXTREEHEIGHT];
};
......
......@@ -858,7 +858,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
unchar *i_fastsymlink;
s64 xlen = 0;
int bmask = 0, xsize;
s64 xaddr;
s64 extent = 0, xaddr;
struct metapage *mp;
struct super_block *sb;
struct tblock *tblk;
......@@ -892,29 +892,11 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
goto out3;
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
/*
* create entry for symbolic link in parent directory
*/
ino = ip->i_ino;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jfs_err("jfs_symlink: dtInsert returned %d", rc);
/* discard ne inode */
goto out3;
}
/* fix symlink access permission
* (dir_create() ANDs in the u.u_cmask,
* but symlinks really need to be 777 access)
......@@ -966,37 +948,48 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
xsize = (ssize + bmask) & ~bmask;
xaddr = 0;
xlen = xsize >> JFS_SBI(sb)->l2bsize;
if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) {
if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
txAbort(tid, 0);
rc = -ENOSPC;
goto out3;
}
extent = xaddr;
ip->i_size = ssize - 1;
while (ssize) {
/* This is kind of silly since PATH_MAX == 4K */
int copy_size = min(ssize, PSIZE);
mp = get_metapage(ip, xaddr, PSIZE, 1);
if (mp == NULL) {
dtDelete(tid, dip, &dname, &ino,
JFS_REMOVE);
dbFree(ip, extent, xlen);
rc = -EIO;
txAbort(tid, 0);
goto out3;
}
memcpy(mp->data, name, copy_size);
flush_metapage(mp);
#if 0
set_buffer_uptodate(bp);
mark_buffer_dirty(bp, 1);
if (IS_SYNC(dip))
sync_dirty_buffer(bp);
brelse(bp);
#endif /* 0 */
ssize -= copy_size;
name += copy_size;
xaddr += JFS_SBI(sb)->nbperpage;
}
ip->i_blocks = LBLK2PBLK(sb, xlen);
} else {
dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
rc = -ENOSPC;
goto out3;
}
/*
* create entry for symbolic link in parent directory
*/
rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
if (rc == 0) {
ino = ip->i_ino;
rc = dtInsert(tid, dip, &dname, &ino, &btstack);
}
if (rc) {
if (xlen)
dbFree(ip, extent, xlen);
txAbort(tid, 0);
/* discard new inode */
goto out3;
}
insert_inode_hash(ip);
......@@ -1004,23 +997,11 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
/*
* commit update of parent directory and link object
*
* if extent allocation failed (ENOSPC),
* the parent inode is committed regardless to avoid
* backing out parent directory update (by dtInsert())
* and subsequent dtDelete() which is harmless wrt
* integrity concern.
* the symlink inode will be freed by iput() at exit
* as it has a zero link count (by dtDelete()) and
* no permanant resources.
*/
iplist[0] = dip;
if (rc == 0) {
iplist[1] = ip;
rc = txCommit(tid, 2, &iplist[0], 0);
} else
rc = txCommit(tid, 1, &iplist[0], 0);
out3:
txEnd(tid);
......@@ -1223,7 +1204,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* Linelock header of dtree */
tlck = txLock(tid, old_ip,
(struct metapage *) &JFS_IP(old_ip)->bxflag,
tlckDTREE | tlckBTROOT);
tlckDTREE | tlckBTROOT | tlckRELINK);
dtlck = (struct dt_lock *) & tlck->lock;
ASSERT(dtlck->index == 0);
lv = & dtlck->lv[0];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment