LOGSYNC_UNLOCK(log); 
LOGSYNC_UNLOCK(log, flags); 
dbUpdatePMap(struct inode *ipbmap,	     int free, s64 blkno, s64 nblocks, struct tblock * tblk){	int nblks, dbitno, wbitno, rbits;	int word, nbits, nwords;	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;	s64 lblkno, rem, lastlblkno;	u32 mask;	struct dmap *dp;	struct metapage *mp;	struct jfs_log *log;	int lsn, difft, diffp;	/* the blocks better be within the mapsize. */	if (blkno + nblocks > bmp->db_mapsize) {		printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",		       (unsigned long long) blkno,		       (unsigned long long) nblocks);		jfs_error(ipbmap->i_sb,			  "dbUpdatePMap: blocks are outside the map");		return -EIO;	}	/* compute delta of transaction lsn from log syncpt */	lsn = tblk->lsn;	log = (struct jfs_log *) JFS_SBI(tblk->sb)->log;	logdiff(difft, lsn, log);	/*	 * update the block state a dmap at a time.	 */	mp = NULL;	lastlblkno = 0;	for (rem = nblocks; rem > 0; rem -= nblks, blkno += nblks) {		/* get the buffer for the current dmap. */		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);		if (lblkno != lastlblkno) {			if (mp) {				write_metapage(mp);			}			mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE,					   0);			if (mp == NULL)				return -EIO;		}		dp = (struct dmap *) mp->data;		/* determine the bit number and word within the dmap of		 * the starting block.  also determine how many blocks		 * are to be updated within this dmap.		 */		dbitno = blkno & (BPERDMAP - 1);		word = dbitno >> L2DBWORD;		nblks = min(rem, (s64)BPERDMAP - dbitno);		/* update the bits of the dmap words. the first and last		 * words may only have a subset of their bits updated. if		 * this is the case, we'll work against that word (i.e.		 * partial first and/or last) only in a single pass.  a 		 * single pass will also be used to update all words that		 * are to have all their bits updated.		 */		for (rbits = nblks; rbits > 0;		     rbits -= nbits, dbitno += nbits) {			/* determine the bit number within the word and			 * the number of bits within the word.			 */			wbitno = dbitno & (DBWORD - 1);			nbits = min(rbits, DBWORD - wbitno);			/* check if only part of the word is to be updated. */			if (nbits < DBWORD) {				/* update (free or allocate) the bits				 * in this word.				 */				mask =				    (ONES << (DBWORD - nbits) >> wbitno);				if (free)					dp->pmap[word] &=					    cpu_to_le32(~mask);				else					dp->pmap[word] |=					    cpu_to_le32(mask);				word += 1;			} else {				/* one or more words are to have all				 * their bits updated.  determine how				 * many words and how many bits.				 */				nwords = rbits >> L2DBWORD;				nbits = nwords << L2DBWORD;				/* update (free or allocate) the bits				 * in these words.				 */				if (free)					memset(&dp->pmap[word], 0,					       nwords * 4);				else					memset(&dp->pmap[word], (int) ONES,					       nwords * 4);				word += nwords;			}		}		/*		 * update dmap lsn		 */		if (lblkno == lastlblkno)			continue;		lastlblkno = lblkno;		if (mp->lsn != 0) {			/* inherit older/smaller lsn */			logdiff(diffp, mp->lsn, log);			if (difft < diffp) {				mp->lsn = lsn;				/* move bp after tblock in logsync list */				LOGSYNC_LOCK(log);				list_move(&mp->synclist, &tblk->synclist);				LOGSYNC_UNLOCK(log);			}			/* inherit younger/larger clsn */			LOGSYNC_LOCK(log);			logdiff(difft, tblk->clsn, log);			logdiff(diffp, mp->clsn, log);			if (difft > diffp)				mp->clsn = tblk->clsn;			LOGSYNC_UNLOCK(log);		} else {			mp->log = log;			mp->lsn = lsn;			/* insert bp after tblock in logsync list */			LOGSYNC_LOCK(log);			log->count++;			list_add(&mp->synclist, &tblk->synclist);			mp->clsn = tblk->clsn;			LOGSYNC_UNLOCK(log);		}	}	/* write the last buffer. */	if (mp) {		write_metapage(mp);	}	return (0);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/7fab479bebb96b1b4888bdae9b42e1fa9c5d3f38/jfs_dmap.c/buggy/fs/jfs/jfs_dmap.c