TXN_UNLOCK(); 
struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,		     int type){	struct jfs_inode_info *jfs_ip = JFS_IP(ip);	int dir_xtree = 0;	lid_t lid;	tid_t xtid;	struct tlock *tlck;	struct xtlock *xtlck;	struct linelock *linelock;	xtpage_t *p;	struct tblock *tblk;	TXN_LOCK();	if (S_ISDIR(ip->i_mode) && (type & tlckXTREE) &&	    !(mp->xflag & COMMIT_PAGE)) {		/*		 * Directory inode is special.  It can have both an xtree tlock		 * and a dtree tlock associated with it.		 */		dir_xtree = 1;		lid = jfs_ip->xtlid;	} else		lid = mp->lid;	/* is page not locked by a transaction ? */	if (lid == 0)		goto allocateLock;	jfs_info("txLock: tid:%d ip:0x%p mp:0x%p lid:%d", tid, ip, mp, lid);	/* is page locked by the requester transaction ? */	tlck = lid_to_tlock(lid);	if ((xtid = tlck->tid) == tid) {		TXN_UNLOCK();		goto grantLock;	}	/*	 * is page locked by anonymous transaction/lock ?	 *	 * (page update without transaction (i.e., file write) is	 * locked under anonymous transaction tid = 0:	 * anonymous tlocks maintained on anonymous tlock list of	 * the inode of the page and available to all anonymous	 * transactions until txCommit() time at which point	 * they are transferred to the transaction tlock list of	 * the commiting transaction of the inode)	 */	if (xtid == 0) {		tlck->tid = tid;		TXN_UNLOCK();		tblk = tid_to_tblock(tid);		/*		 * The order of the tlocks in the transaction is important		 * (during truncate, child xtree pages must be freed before		 * parent's tlocks change the working map).		 * Take tlock off anonymous list and add to tail of		 * transaction list		 *		 * Note:  We really need to get rid of the tid & lid and		 * use list_head's.  This code is getting UGLY!		 */		if (jfs_ip->atlhead == lid) {			if (jfs_ip->atltail == lid) {				/* only anonymous txn.				 * Remove from anon_list				 */				list_del_init(&jfs_ip->anon_inode_list);			}			jfs_ip->atlhead = tlck->next;		} else {			lid_t last;			for (last = jfs_ip->atlhead;			     lid_to_tlock(last)->next != lid;			     last = lid_to_tlock(last)->next) {				assert(last);			}			lid_to_tlock(last)->next = tlck->next;			if (jfs_ip->atltail == lid)				jfs_ip->atltail = last;		}		/* insert the tlock at tail of transaction tlock list */		if (tblk->next)			lid_to_tlock(tblk->last)->next = lid;		else			tblk->next = lid;		tlck->next = 0;		tblk->last = lid;		goto grantLock;	}	goto waitLock;	/*	 * allocate a tlock	 */      allocateLock:	lid = txLockAlloc();	tlck = lid_to_tlock(lid);	/*	 * initialize tlock	 */	tlck->tid = tid;	TXN_UNLOCK();	/* mark tlock for meta-data page */	if (mp->xflag & COMMIT_PAGE) {		tlck->flag = tlckPAGELOCK;		/* mark the page dirty and nohomeok */		metapage_nohomeok(mp);		jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p",			 mp, mp->nohomeok, tid, tlck);		/* if anonymous transaction, and buffer is on the group		 * commit synclist, mark inode to show this.  This will		 * prevent the buffer from being marked nohomeok for too		 * long a time.		 */		if ((tid == 0) && mp->lsn)			set_cflag(COMMIT_Synclist, ip);	}	/* mark tlock for in-memory inode */	else		tlck->flag = tlckINODELOCK;	tlck->type = 0;	/* bind the tlock and the page */	tlck->ip = ip;	tlck->mp = mp;	if (dir_xtree)		jfs_ip->xtlid = lid;	else		mp->lid = lid;	/*	 * enqueue transaction lock to transaction/inode	 */	/* insert the tlock at tail of transaction tlock list */	if (tid) {		tblk = tid_to_tblock(tid);		if (tblk->next)			lid_to_tlock(tblk->last)->next = lid;		else			tblk->next = lid;		tlck->next = 0;		tblk->last = lid;	}	/* anonymous transaction:	 * insert the tlock at head of inode anonymous tlock list	 */	else {		tlck->next = jfs_ip->atlhead;		jfs_ip->atlhead = lid;		if (tlck->next == 0) {			/* This inode's first anonymous transaction */			jfs_ip->atltail = lid;			TXN_LOCK();			list_add_tail(&jfs_ip->anon_inode_list,				      &TxAnchor.anon_list);			TXN_UNLOCK();		}	}	/* initialize type dependent area for linelock */	linelock = (struct linelock *) & tlck->lock;	linelock->next = 0;	linelock->flag = tlckLINELOCK;	linelock->maxcnt = TLOCKSHORT;	linelock->index = 0;	switch (type & tlckTYPE) {	case tlckDTREE:		linelock->l2linesize = L2DTSLOTSIZE;		break;	case tlckXTREE:		linelock->l2linesize = L2XTSLOTSIZE;		xtlck = (struct xtlock *) linelock;		xtlck->header.offset = 0;		xtlck->header.length = 2;		if (type & tlckNEW) {			xtlck->lwm.offset = XTENTRYSTART;		} else {			if (mp->xflag & COMMIT_PAGE)				p = (xtpage_t *) mp->data;			else				p = &jfs_ip->i_xtroot;			xtlck->lwm.offset =			    le16_to_cpu(p->header.nextindex);		}		xtlck->lwm.length = 0;	/* ! */		xtlck->twm.offset = 0;		xtlck->hwm.offset = 0;		xtlck->index = 2;		break;	case tlckINODE:		linelock->l2linesize = L2INODESLOTSIZE;		break;	case tlckDATA:		linelock->l2linesize = L2DATASLOTSIZE;		break;	default:		jfs_err("UFO tlock:0x%p", tlck);	}	/*	 * update tlock vector	 */      grantLock:	tlck->type |= type;	return tlck;	/*	 * page is being locked by another transaction:	 */      waitLock:	/* Only locks on ipimap or ipaimap should reach here */	/* assert(jfs_ip->fileset == AGGREGATE_I); */	if (jfs_ip->fileset != AGGREGATE_I) {		jfs_err("txLock: trying to lock locked page!");		dump_mem("ip", ip, sizeof(struct inode));		dump_mem("mp", mp, sizeof(struct metapage));		dump_mem("Locker's tblk", tid_to_tblock(tid),			 sizeof(struct tblock));		dump_mem("Tlock", tlck, sizeof(struct tlock));		BUG();	}	INCREMENT(stattx.waitlock);	/* statistics */	TXN_UNLOCK();	release_metapage(mp);	TXN_LOCK();	xtid = tlck->tid;	/* reaquire after dropping TXN_LOCK */	jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",		 tid, xtid, lid);	/* Recheck everything since dropping TXN_LOCK */	if (xtid && (tlck->mp == mp) && (mp->lid == lid))		TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);	else		TXN_UNLOCK();	jfs_info("txLock: awakened     tid = %d, lid = %d", tid, lid);	return NULL;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8a9cd6d676728792aaee31f30015d284acd154a3/jfs_txnmgr.c/buggy/fs/jfs/jfs_txnmgr.c