(dirent_buf + PSIZE)) { 
(dirent_buf + PAGE_SIZE)) { 
int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir){	struct inode *ip = filp->f_dentry->d_inode;	struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab;	int rc = 0;	loff_t dtpos;	/* legacy OS/2 style position */	struct dtoffset {		s16 pn;		s16 index;		s32 unused;	} *dtoffset = (struct dtoffset *) &dtpos;	s64 bn;	struct metapage *mp;	dtpage_t *p;	int index;	s8 *stbl;	struct btstack btstack;	int i, next;	struct ldtentry *d;	struct dtslot *t;	int d_namleft, len, outlen;	unsigned long dirent_buf;	char *name_ptr;	u32 dir_index;	int do_index = 0;	uint loop_count = 0;	struct jfs_dirent *jfs_dirent;	int jfs_dirents;	int overflow, fix_page, page_fixed = 0;	static int unique_pos = 2;	/* If we can't fix broken index */	if (filp->f_pos == DIREND)		return 0;	if (DO_INDEX(ip)) {		/*		 * persistent index is stored in directory entries.		 * Special cases:        0 = .		 *                       1 = ..		 *                      -1 = End of directory		 */		do_index = 1;		dir_index = (u32) filp->f_pos;		if (dir_index > 1) {			struct dir_table_slot dirtab_slot;			if (dtEmpty(ip) ||			    (dir_index >= JFS_IP(ip)->next_index)) {				/* Stale position.  Directory has shrunk */				filp->f_pos = DIREND;				return 0;			}		      repeat:			rc = read_index(ip, dir_index, &dirtab_slot);			if (rc) {				filp->f_pos = DIREND;				return rc;			}			if (dirtab_slot.flag == DIR_INDEX_FREE) {				if (loop_count++ > JFS_IP(ip)->next_index) {					jfs_err("jfs_readdir detected "						   "infinite loop!");					filp->f_pos = DIREND;					return 0;				}				dir_index = le32_to_cpu(dirtab_slot.addr2);				if (dir_index == -1) {					filp->f_pos = DIREND;					return 0;				}				goto repeat;			}			bn = addressDTS(&dirtab_slot);			index = dirtab_slot.slot;			DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);			if (rc) {				filp->f_pos = DIREND;				return 0;			}			if (p->header.flag & BT_INTERNAL) {				jfs_err("jfs_readdir: bad index table");				DT_PUTPAGE(mp);				filp->f_pos = -1;				return 0;			}		} else {			if (dir_index == 0) {				/*				 * self "."				 */				filp->f_pos = 0;				if (filldir(dirent, ".", 1, 0, ip->i_ino,					    DT_DIR))					return 0;			}			/*			 * parent ".."			 */			filp->f_pos = 1;			if (filldir(dirent, "..", 2, 1, PARENT(ip), DT_DIR))				return 0;			/*			 * Find first entry of left-most leaf			 */			if (dtEmpty(ip)) {				filp->f_pos = DIREND;				return 0;			}			if ((rc = dtReadFirst(ip, &btstack)))				return rc;			DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);		}	} else {		/*		 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6		 *		 * pn = index = 0:      First entry "."		 * pn = 0; index = 1:   Second entry ".."		 * pn > 0:              Real entries, pn=1 -> leftmost page		 * pn = index = -1:     No more entries		 */		dtpos = filp->f_pos;		if (dtpos == 0) {			/* build "." entry */			if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,				    DT_DIR))				return 0;			dtoffset->index = 1;			filp->f_pos = dtpos;		}		if (dtoffset->pn == 0) {			if (dtoffset->index == 1) {				/* build ".." entry */				if (filldir(dirent, "..", 2, filp->f_pos,					    PARENT(ip), DT_DIR))					return 0;			} else {				jfs_err("jfs_readdir called with "					"invalid offset!");			}			dtoffset->pn = 1;			dtoffset->index = 0;			filp->f_pos = dtpos;		}		if (dtEmpty(ip)) {			filp->f_pos = DIREND;			return 0;		}		if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) {			jfs_err("jfs_readdir: unexpected rc = %d "				"from dtReadNext", rc);			filp->f_pos = DIREND;			return 0;		}		/* get start leaf page and index */		DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);		/* offset beyond directory eof ? */		if (bn < 0) {			filp->f_pos = DIREND;			return 0;		}	}	dirent_buf = __get_free_page(GFP_KERNEL);	if (dirent_buf == 0) {		DT_PUTPAGE(mp);		jfs_warn("jfs_readdir: __get_free_page failed!");		filp->f_pos = DIREND;		return -ENOMEM;	}	while (1) {		jfs_dirent = (struct jfs_dirent *) dirent_buf;		jfs_dirents = 0;		overflow = fix_page = 0;		stbl = DT_GETSTBL(p);		for (i = index; i < p->header.nextindex; i++) {			d = (struct ldtentry *) & p->slot[stbl[i]];			if (((long) jfs_dirent + d->namlen + 1) >			    (dirent_buf + PSIZE)) {				/* DBCS codepages could overrun dirent_buf */				index = i;				overflow = 1;				break;			}			d_namleft = d->namlen;			name_ptr = jfs_dirent->name;			jfs_dirent->ino = le32_to_cpu(d->inumber);			if (do_index) {				len = min(d_namleft, DTLHDRDATALEN);				jfs_dirent->position = le32_to_cpu(d->index);				/*				 * d->index should always be valid, but it				 * isn't.  fsck.jfs doesn't create the				 * directory index for the lost+found				 * directory.  Rather than let it go,				 * we can try to fix it.				 */				if ((jfs_dirent->position < 2) ||				    (jfs_dirent->position >=				     JFS_IP(ip)->next_index)) {					if (!page_fixed && !isReadOnly(ip)) {						fix_page = 1;						/*						 * setting overflow and setting						 * index to i will cause the						 * same page to be processed						 * again starting here						 */						overflow = 1;						index = i;						break;					}					jfs_dirent->position = unique_pos++;				}			} else {				jfs_dirent->position = dtpos;				len = min(d_namleft, DTLHDRDATALEN_LEGACY);			}			/* copy the name of head/only segment */			outlen = jfs_strfromUCS_le(name_ptr, d->name, len,						   codepage);			jfs_dirent->name_len = outlen;			/* copy name in the additional segment(s) */			next = d->next;			while (next >= 0) {				t = (struct dtslot *) & p->slot[next];				name_ptr += outlen;				d_namleft -= len;				/* Sanity Check */				if (d_namleft == 0) {					jfs_error(ip->i_sb,						  "JFS:Dtree error: ino = "						  "%ld, bn=%Ld, index = %d",						  (long)ip->i_ino,						  (long long)bn,						  i);					goto skip_one;				}				len = min(d_namleft, DTSLOTDATALEN);				outlen = jfs_strfromUCS_le(name_ptr, t->name,							   len, codepage);				jfs_dirent->name_len += outlen;				next = t->next;			}			jfs_dirents++;			jfs_dirent = next_jfs_dirent(jfs_dirent);skip_one:			if (!do_index)				dtoffset->index++;		}		if (!overflow) {			/* Point to next leaf page */			if (p->header.flag & BT_ROOT)				bn = 0;			else {				bn = le64_to_cpu(p->header.next);				index = 0;				/* update offset (pn:index) for new page */				if (!do_index) {					dtoffset->pn++;					dtoffset->index = 0;				}			}			page_fixed = 0;		}		/* unpin previous leaf page */		DT_PUTPAGE(mp);		jfs_dirent = (struct jfs_dirent *) dirent_buf;		while (jfs_dirents--) {			filp->f_pos = jfs_dirent->position;			if (filldir(dirent, jfs_dirent->name,				    jfs_dirent->name_len, filp->f_pos,				    jfs_dirent->ino, DT_UNKNOWN))				goto out;			jfs_dirent = next_jfs_dirent(jfs_dirent);		}		if (fix_page) {			add_missing_indices(ip, bn);			page_fixed = 1;		}		if (!overflow && (bn == 0)) {			filp->f_pos = DIREND;			break;		}		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);		if (rc) {			free_page(dirent_buf);			return rc;		}	}      out:	free_page(dirent_buf);	return rc;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/dc5798d9a7b656550533a5c0177dba17d4ef4990/jfs_dtree.c/clean/fs/jfs/jfs_dtree.c