17c478bd9Sstevel@tonic-gate /* fsys_jfs.c - an implementation for the IBM JFS file system */
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate * GRUB -- GRand Unified Bootloader
47c478bd9Sstevel@tonic-gate * Copyright (C) 2001,2002 Free Software Foundation, Inc.
57c478bd9Sstevel@tonic-gate *
67c478bd9Sstevel@tonic-gate * This program is free software; you can redistribute it and/or modify
77c478bd9Sstevel@tonic-gate * it under the terms of the GNU General Public License as published by
87c478bd9Sstevel@tonic-gate * the Free Software Foundation; either version 2 of the License, or
97c478bd9Sstevel@tonic-gate * (at your option) any later version.
107c478bd9Sstevel@tonic-gate *
117c478bd9Sstevel@tonic-gate * This program is distributed in the hope that it will be useful,
127c478bd9Sstevel@tonic-gate * but WITHOUT ANY WARRANTY; without even the implied warranty of
137c478bd9Sstevel@tonic-gate * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
147c478bd9Sstevel@tonic-gate * GNU General Public License for more details.
157c478bd9Sstevel@tonic-gate *
167c478bd9Sstevel@tonic-gate * You should have received a copy of the GNU General Public License
177c478bd9Sstevel@tonic-gate * along with this program; if not, write to the Free Software
187c478bd9Sstevel@tonic-gate * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
197c478bd9Sstevel@tonic-gate */
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gate #ifdef FSYS_JFS
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate #include "shared.h"
247c478bd9Sstevel@tonic-gate #include "filesys.h"
257c478bd9Sstevel@tonic-gate #include "jfs.h"
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #define MAX_LINK_COUNT 8
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #define DTTYPE_INLINE 0
307c478bd9Sstevel@tonic-gate #define DTTYPE_PAGE 1
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate struct jfs_info
337c478bd9Sstevel@tonic-gate {
347c478bd9Sstevel@tonic-gate int bsize;
357c478bd9Sstevel@tonic-gate int l2bsize;
367c478bd9Sstevel@tonic-gate int bdlog;
377c478bd9Sstevel@tonic-gate int xindex;
387c478bd9Sstevel@tonic-gate int xlastindex;
397c478bd9Sstevel@tonic-gate int sindex;
407c478bd9Sstevel@tonic-gate int slastindex;
417c478bd9Sstevel@tonic-gate int de_index;
427c478bd9Sstevel@tonic-gate int dttype;
437c478bd9Sstevel@tonic-gate xad_t *xad;
447c478bd9Sstevel@tonic-gate ldtentry_t *de;
457c478bd9Sstevel@tonic-gate };
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate static struct jfs_info jfs;
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate #define xtpage ((xtpage_t *)FSYS_BUF)
507c478bd9Sstevel@tonic-gate #define dtpage ((dtpage_t *)((char *)FSYS_BUF + 4096))
517c478bd9Sstevel@tonic-gate #define fileset ((dinode_t *)((char *)FSYS_BUF + 8192))
527c478bd9Sstevel@tonic-gate #define inode ((dinode_t *)((char *)FSYS_BUF + 8192 + sizeof(dinode_t)))
537c478bd9Sstevel@tonic-gate #define dtroot ((dtroot_t *)(&inode->di_btroot))
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate static ldtentry_t de_always[2] = {
567c478bd9Sstevel@tonic-gate {1, -1, 2, {'.', '.'}},
577c478bd9Sstevel@tonic-gate {1, -1, 1, {'.'}}
587c478bd9Sstevel@tonic-gate };
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate static int
isinxt(s64 key,s64 offset,s64 len)617c478bd9Sstevel@tonic-gate isinxt (s64 key, s64 offset, s64 len)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate static xad_t *
first_extent(dinode_t * di)677c478bd9Sstevel@tonic-gate first_extent (dinode_t *di)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate xtpage_t *xtp;
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate jfs.xindex = 2;
727c478bd9Sstevel@tonic-gate xtp = (xtpage_t *)&di->di_btroot;
737c478bd9Sstevel@tonic-gate jfs.xad = &xtp->xad[2];
747c478bd9Sstevel@tonic-gate if (xtp->header.flag & BT_LEAF) {
757c478bd9Sstevel@tonic-gate jfs.xlastindex = xtp->header.nextindex;
767c478bd9Sstevel@tonic-gate } else {
777c478bd9Sstevel@tonic-gate do {
787c478bd9Sstevel@tonic-gate devread (addressXAD (jfs.xad) << jfs.bdlog, 0,
797c478bd9Sstevel@tonic-gate sizeof(xtpage_t), (char *)xtpage);
807c478bd9Sstevel@tonic-gate jfs.xad = &xtpage->xad[2];
817c478bd9Sstevel@tonic-gate } while (!(xtpage->header.flag & BT_LEAF));
827c478bd9Sstevel@tonic-gate jfs.xlastindex = xtpage->header.nextindex;
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate return jfs.xad;
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate static xad_t *
next_extent(void)897c478bd9Sstevel@tonic-gate next_extent (void)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate if (++jfs.xindex < jfs.xlastindex) {
927c478bd9Sstevel@tonic-gate } else if (xtpage->header.next) {
937c478bd9Sstevel@tonic-gate devread (xtpage->header.next << jfs.bdlog, 0,
947c478bd9Sstevel@tonic-gate sizeof(xtpage_t), (char *)xtpage);
957c478bd9Sstevel@tonic-gate jfs.xlastindex = xtpage->header.nextindex;
967c478bd9Sstevel@tonic-gate jfs.xindex = XTENTRYSTART;
977c478bd9Sstevel@tonic-gate jfs.xad = &xtpage->xad[XTENTRYSTART];
987c478bd9Sstevel@tonic-gate } else {
997c478bd9Sstevel@tonic-gate return NULL;
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate return ++jfs.xad;
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate static void
di_read(u32 inum,dinode_t * di)1067c478bd9Sstevel@tonic-gate di_read (u32 inum, dinode_t *di)
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate s64 key;
1097c478bd9Sstevel@tonic-gate u32 xd, ioffset;
1107c478bd9Sstevel@tonic-gate s64 offset;
1117c478bd9Sstevel@tonic-gate xad_t *xad;
1127c478bd9Sstevel@tonic-gate pxd_t pxd;
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate key = (((inum >> L2INOSPERIAG) << L2INOSPERIAG) + 4096) >> jfs.l2bsize;
1157c478bd9Sstevel@tonic-gate xd = (inum & (INOSPERIAG - 1)) >> L2INOSPEREXT;
1167c478bd9Sstevel@tonic-gate ioffset = ((inum & (INOSPERIAG - 1)) & (INOSPEREXT - 1)) << L2DISIZE;
1177c478bd9Sstevel@tonic-gate xad = first_extent (fileset);
1187c478bd9Sstevel@tonic-gate do {
1197c478bd9Sstevel@tonic-gate offset = offsetXAD (xad);
1207c478bd9Sstevel@tonic-gate if (isinxt (key, offset, lengthXAD (xad))) {
1217c478bd9Sstevel@tonic-gate devread ((addressXAD (xad) + key - offset) << jfs.bdlog,
1227c478bd9Sstevel@tonic-gate 3072 + xd*sizeof(pxd_t), sizeof(pxd_t), (char *)&pxd);
1237c478bd9Sstevel@tonic-gate devread (addressPXD (&pxd) << jfs.bdlog,
1247c478bd9Sstevel@tonic-gate ioffset, DISIZE, (char *)di);
1257c478bd9Sstevel@tonic-gate break;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate } while ((xad = next_extent ()));
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate static ldtentry_t *
next_dentry(void)1317c478bd9Sstevel@tonic-gate next_dentry (void)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate ldtentry_t *de;
1347c478bd9Sstevel@tonic-gate s8 *stbl;
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate if (jfs.dttype == DTTYPE_INLINE) {
1377c478bd9Sstevel@tonic-gate if (jfs.sindex < jfs.slastindex) {
1387c478bd9Sstevel@tonic-gate return (ldtentry_t *)&dtroot->slot[(int)dtroot->header.stbl[jfs.sindex++]];
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate } else {
1417c478bd9Sstevel@tonic-gate de = (ldtentry_t *)dtpage->slot;
1427c478bd9Sstevel@tonic-gate stbl = (s8 *)&de[(int)dtpage->header.stblindex];
1437c478bd9Sstevel@tonic-gate if (jfs.sindex < jfs.slastindex) {
1447c478bd9Sstevel@tonic-gate return &de[(int)stbl[jfs.sindex++]];
1457c478bd9Sstevel@tonic-gate } else if (dtpage->header.next) {
1467c478bd9Sstevel@tonic-gate devread (dtpage->header.next << jfs.bdlog, 0,
1477c478bd9Sstevel@tonic-gate sizeof(dtpage_t), (char *)dtpage);
1487c478bd9Sstevel@tonic-gate jfs.slastindex = dtpage->header.nextindex;
1497c478bd9Sstevel@tonic-gate jfs.sindex = 1;
1507c478bd9Sstevel@tonic-gate return &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]];
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate return (jfs.de_index < 2) ? &de_always[jfs.de_index++] : NULL;
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate static ldtentry_t *
first_dentry(void)1587c478bd9Sstevel@tonic-gate first_dentry (void)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate dtroot_t *dtr;
1617c478bd9Sstevel@tonic-gate pxd_t *xd;
1627c478bd9Sstevel@tonic-gate idtentry_t *de;
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate dtr = (dtroot_t *)&inode->di_btroot;
1657c478bd9Sstevel@tonic-gate jfs.sindex = 0;
1667c478bd9Sstevel@tonic-gate jfs.de_index = 0;
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate de_always[0].inumber = inode->di_parent;
1697c478bd9Sstevel@tonic-gate de_always[1].inumber = inode->di_number;
1707c478bd9Sstevel@tonic-gate if (dtr->header.flag & BT_LEAF) {
1717c478bd9Sstevel@tonic-gate jfs.dttype = DTTYPE_INLINE;
1727c478bd9Sstevel@tonic-gate jfs.slastindex = dtr->header.nextindex;
1737c478bd9Sstevel@tonic-gate } else {
1747c478bd9Sstevel@tonic-gate de = (idtentry_t *)dtpage->slot;
1757c478bd9Sstevel@tonic-gate jfs.dttype = DTTYPE_PAGE;
1767c478bd9Sstevel@tonic-gate xd = &((idtentry_t *)dtr->slot)[(int)dtr->header.stbl[0]].xd;
1777c478bd9Sstevel@tonic-gate for (;;) {
1787c478bd9Sstevel@tonic-gate devread (addressPXD (xd) << jfs.bdlog, 0,
1797c478bd9Sstevel@tonic-gate sizeof(dtpage_t), (char *)dtpage);
1807c478bd9Sstevel@tonic-gate if (dtpage->header.flag & BT_LEAF)
1817c478bd9Sstevel@tonic-gate break;
1827c478bd9Sstevel@tonic-gate xd = &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]].xd;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate jfs.slastindex = dtpage->header.nextindex;
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate return next_dentry ();
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate static dtslot_t *
next_dslot(int next)1927c478bd9Sstevel@tonic-gate next_dslot (int next)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate return (jfs.dttype == DTTYPE_INLINE)
1957c478bd9Sstevel@tonic-gate ? (dtslot_t *)&dtroot->slot[next]
1967c478bd9Sstevel@tonic-gate : &((dtslot_t *)dtpage->slot)[next];
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate static void
uni2ansi(UniChar * uni,char * ansi,int len)2007c478bd9Sstevel@tonic-gate uni2ansi (UniChar *uni, char *ansi, int len)
2017c478bd9Sstevel@tonic-gate {
2027c478bd9Sstevel@tonic-gate for (; len; len--, uni++)
2037c478bd9Sstevel@tonic-gate *ansi++ = (*uni & 0xff80) ? '?' : *(char *)uni;
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate int
jfs_mount(void)2077c478bd9Sstevel@tonic-gate jfs_mount (void)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate struct jfs_superblock super;
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate if (part_length < MINJFS >> SECTOR_BITS
2127c478bd9Sstevel@tonic-gate || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
2137c478bd9Sstevel@tonic-gate sizeof(struct jfs_superblock), (char *)&super)
2147c478bd9Sstevel@tonic-gate || (super.s_magic != JFS_MAGIC)
2157c478bd9Sstevel@tonic-gate || !devread ((AITBL_OFF >> SECTOR_BITS) + FILESYSTEM_I,
2167c478bd9Sstevel@tonic-gate 0, DISIZE, (char*)fileset)) {
2177c478bd9Sstevel@tonic-gate return 0;
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate jfs.bsize = super.s_bsize;
2217c478bd9Sstevel@tonic-gate jfs.l2bsize = super.s_l2bsize;
2227c478bd9Sstevel@tonic-gate jfs.bdlog = jfs.l2bsize - SECTOR_BITS;
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate return 1;
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate int
jfs_read(char * buf,int len)2287c478bd9Sstevel@tonic-gate jfs_read (char *buf, int len)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate xad_t *xad;
2317c478bd9Sstevel@tonic-gate s64 endofprev, endofcur;
2327c478bd9Sstevel@tonic-gate s64 offset, xadlen;
2337c478bd9Sstevel@tonic-gate int toread, startpos, endpos;
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate startpos = filepos;
2367c478bd9Sstevel@tonic-gate endpos = filepos + len;
2377c478bd9Sstevel@tonic-gate endofprev = (1ULL << 62) - 1;
2387c478bd9Sstevel@tonic-gate xad = first_extent (inode);
2397c478bd9Sstevel@tonic-gate do {
2407c478bd9Sstevel@tonic-gate offset = offsetXAD (xad);
2417c478bd9Sstevel@tonic-gate xadlen = lengthXAD (xad);
2427c478bd9Sstevel@tonic-gate if (isinxt (filepos >> jfs.l2bsize, offset, xadlen)) {
2437c478bd9Sstevel@tonic-gate endofcur = (offset + xadlen) << jfs.l2bsize;
2447c478bd9Sstevel@tonic-gate toread = (endofcur >= endpos)
2457c478bd9Sstevel@tonic-gate ? len : (endofcur - filepos);
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate disk_read_func = disk_read_hook;
2487c478bd9Sstevel@tonic-gate devread (addressXAD (xad) << jfs.bdlog,
2497c478bd9Sstevel@tonic-gate filepos - (offset << jfs.l2bsize), toread, buf);
2507c478bd9Sstevel@tonic-gate disk_read_func = NULL;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate buf += toread;
2537c478bd9Sstevel@tonic-gate len -= toread;
2547c478bd9Sstevel@tonic-gate filepos += toread;
2557c478bd9Sstevel@tonic-gate } else if (offset > endofprev) {
2567c478bd9Sstevel@tonic-gate toread = ((offset << jfs.l2bsize) >= endpos)
2577c478bd9Sstevel@tonic-gate ? len : ((offset - endofprev) << jfs.l2bsize);
2587c478bd9Sstevel@tonic-gate len -= toread;
2597c478bd9Sstevel@tonic-gate filepos += toread;
2607c478bd9Sstevel@tonic-gate for (; toread; toread--) {
2617c478bd9Sstevel@tonic-gate *buf++ = 0;
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate continue;
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate endofprev = offset + xadlen;
2667c478bd9Sstevel@tonic-gate xad = next_extent ();
2677c478bd9Sstevel@tonic-gate } while (len > 0 && xad);
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate return filepos - startpos;
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate int
jfs_dir(char * dirname)2737c478bd9Sstevel@tonic-gate jfs_dir (char *dirname)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate char *ptr, *rest, ch;
2767c478bd9Sstevel@tonic-gate ldtentry_t *de;
2777c478bd9Sstevel@tonic-gate dtslot_t *ds;
2787c478bd9Sstevel@tonic-gate u32 inum, parent_inum;
2797c478bd9Sstevel@tonic-gate s64 di_size;
2807c478bd9Sstevel@tonic-gate u32 di_mode;
2817c478bd9Sstevel@tonic-gate int namlen, cmp, n, link_count;
2827c478bd9Sstevel@tonic-gate char namebuf[JFS_NAME_MAX + 1], linkbuf[JFS_PATH_MAX];
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate parent_inum = inum = ROOT_I;
2857c478bd9Sstevel@tonic-gate link_count = 0;
2867c478bd9Sstevel@tonic-gate for (;;) {
2877c478bd9Sstevel@tonic-gate di_read (inum, inode);
2887c478bd9Sstevel@tonic-gate di_size = inode->di_size;
2897c478bd9Sstevel@tonic-gate di_mode = inode->di_mode;
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate if ((di_mode & IFMT) == IFLNK) {
2927c478bd9Sstevel@tonic-gate if (++link_count > MAX_LINK_COUNT) {
2937c478bd9Sstevel@tonic-gate errnum = ERR_SYMLINK_LOOP;
2947c478bd9Sstevel@tonic-gate return 0;
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate if (di_size < (di_mode & INLINEEA ? 256 : 128)) {
2977c478bd9Sstevel@tonic-gate grub_memmove (linkbuf, inode->di_fastsymlink, di_size);
2987c478bd9Sstevel@tonic-gate n = di_size;
2997c478bd9Sstevel@tonic-gate } else if (di_size < JFS_PATH_MAX - 1) {
3007c478bd9Sstevel@tonic-gate filepos = 0;
3017c478bd9Sstevel@tonic-gate filemax = di_size;
3027c478bd9Sstevel@tonic-gate n = jfs_read (linkbuf, filemax);
3037c478bd9Sstevel@tonic-gate } else {
3047c478bd9Sstevel@tonic-gate errnum = ERR_FILELENGTH;
3057c478bd9Sstevel@tonic-gate return 0;
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate inum = (linkbuf[0] == '/') ? ROOT_I : parent_inum;
3097c478bd9Sstevel@tonic-gate while (n < (JFS_PATH_MAX - 1) && (linkbuf[n++] = *dirname++));
3107c478bd9Sstevel@tonic-gate linkbuf[n] = 0;
3117c478bd9Sstevel@tonic-gate dirname = linkbuf;
3127c478bd9Sstevel@tonic-gate continue;
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate if (!*dirname || isspace (*dirname)) {
3167c478bd9Sstevel@tonic-gate if ((di_mode & IFMT) != IFREG) {
3177c478bd9Sstevel@tonic-gate errnum = ERR_BAD_FILETYPE;
3187c478bd9Sstevel@tonic-gate return 0;
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate filepos = 0;
3217c478bd9Sstevel@tonic-gate filemax = di_size;
3227c478bd9Sstevel@tonic-gate return 1;
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate if ((di_mode & IFMT) != IFDIR) {
3267c478bd9Sstevel@tonic-gate errnum = ERR_BAD_FILETYPE;
3277c478bd9Sstevel@tonic-gate return 0;
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate for (; *dirname == '/'; dirname++);
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
3337c478bd9Sstevel@tonic-gate *rest = 0;
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate de = first_dentry ();
3367c478bd9Sstevel@tonic-gate for (;;) {
3377c478bd9Sstevel@tonic-gate namlen = de->namlen;
3387c478bd9Sstevel@tonic-gate if (de->next == -1) {
3397c478bd9Sstevel@tonic-gate uni2ansi (de->name, namebuf, namlen);
3407c478bd9Sstevel@tonic-gate namebuf[namlen] = 0;
3417c478bd9Sstevel@tonic-gate } else {
3427c478bd9Sstevel@tonic-gate uni2ansi (de->name, namebuf, DTLHDRDATALEN);
3437c478bd9Sstevel@tonic-gate ptr = namebuf;
3447c478bd9Sstevel@tonic-gate ptr += DTLHDRDATALEN;
3457c478bd9Sstevel@tonic-gate namlen -= DTLHDRDATALEN;
3467c478bd9Sstevel@tonic-gate ds = next_dslot (de->next);
3477c478bd9Sstevel@tonic-gate while (ds->next != -1) {
3487c478bd9Sstevel@tonic-gate uni2ansi (ds->name, ptr, DTSLOTDATALEN);
3497c478bd9Sstevel@tonic-gate ptr += DTSLOTDATALEN;
3507c478bd9Sstevel@tonic-gate namlen -= DTSLOTDATALEN;
3517c478bd9Sstevel@tonic-gate ds = next_dslot (ds->next);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate uni2ansi (ds->name, ptr, namlen);
3547c478bd9Sstevel@tonic-gate ptr += namlen;
3557c478bd9Sstevel@tonic-gate *ptr = 0;
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate cmp = (!*dirname) ? -1 : substring (dirname, namebuf);
3597c478bd9Sstevel@tonic-gate #ifndef STAGE1_5
3607c478bd9Sstevel@tonic-gate if (print_possibilities && ch != '/'
3617c478bd9Sstevel@tonic-gate && cmp <= 0) {
3627c478bd9Sstevel@tonic-gate if (print_possibilities > 0)
3637c478bd9Sstevel@tonic-gate print_possibilities = -print_possibilities;
3647c478bd9Sstevel@tonic-gate print_a_completion (namebuf);
3657c478bd9Sstevel@tonic-gate } else
3667c478bd9Sstevel@tonic-gate #endif
3677c478bd9Sstevel@tonic-gate if (cmp == 0) {
3687c478bd9Sstevel@tonic-gate parent_inum = inum;
3697c478bd9Sstevel@tonic-gate inum = de->inumber;
3707c478bd9Sstevel@tonic-gate *(dirname = rest) = ch;
3717c478bd9Sstevel@tonic-gate break;
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate de = next_dentry ();
3747c478bd9Sstevel@tonic-gate if (de == NULL) {
3757c478bd9Sstevel@tonic-gate if (print_possibilities < 0)
3767c478bd9Sstevel@tonic-gate return 1;
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate errnum = ERR_FILE_NOT_FOUND;
3797c478bd9Sstevel@tonic-gate *rest = ch;
3807c478bd9Sstevel@tonic-gate return 0;
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate int
jfs_embed(unsigned long long * start_sector,int needed_sectors)387*2e1aefd1SJoshua M. Clulow jfs_embed (unsigned long long *start_sector, int needed_sectors)
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate struct jfs_superblock super;
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate if (needed_sectors > 63
3927c478bd9Sstevel@tonic-gate || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
3937c478bd9Sstevel@tonic-gate sizeof (struct jfs_superblock),
3947c478bd9Sstevel@tonic-gate (char *)&super)
3957c478bd9Sstevel@tonic-gate || (super.s_magic != JFS_MAGIC)) {
3967c478bd9Sstevel@tonic-gate return 0;
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate *start_sector = 1;
4007c478bd9Sstevel@tonic-gate return 1;
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate
4037c478bd9Sstevel@tonic-gate #endif /* FSYS_JFS */
404