Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 107103
Collapse All | Expand All

(-)aboot-1.0_pre20040408/Makefile (-2 / +2 lines)
Lines 17-23 Link Here
17
#TESTING	= yes
17
#TESTING	= yes
18
18
19
# for boot testing
19
# for boot testing
20
#CFGDEFS       	= -DDEBUG_ISO -DDEBUG_ROCK -DDEBUG_EXT2 -DDEBUG
20
#CFGDEFS       	= -DDEBUG_ISO -DDEBUG_ROCK -DDEBUG_EXT2 -DDEBUG_XFS -DDEBUG
21
21
22
# root, aka prefix
22
# root, aka prefix
23
root		=
23
root		=
Lines 58-64 Link Here
58
	$(CC) $(ASFLAGS) -D__ASSEMBLY__ -traditional -c -o $*.o $<
58
	$(CC) $(ASFLAGS) -D__ASSEMBLY__ -traditional -c -o $*.o $<
59
59
60
NET_OBJS = net.o
60
NET_OBJS = net.o
61
DISK_OBJS = disk.o fs/ext2.o fs/ufs.o fs/dummy.o fs/iso.o
61
DISK_OBJS = disk.o fs/ext2.o fs/ufs.o fs/dummy.o fs/iso.o fs/xfs.o
62
ifeq ($(TESTING),)
62
ifeq ($(TESTING),)
63
ABOOT_OBJS = \
63
ABOOT_OBJS = \
64
	head.o aboot.o cons.o utils.o \
64
	head.o aboot.o cons.o utils.o \
(-)aboot-1.0_pre20040408/disk.c (-16 / +13 lines)
Lines 42-47 Link Here
42
extern struct bootfs iso;
42
extern struct bootfs iso;
43
extern struct bootfs ufs;
43
extern struct bootfs ufs;
44
extern struct bootfs dummyfs;
44
extern struct bootfs dummyfs;
45
extern struct bootfs xfsfs;
45
46
46
struct disklabel * label;
47
struct disklabel * label;
47
int boot_part = -1;
48
int boot_part = -1;
Lines 49-55 Link Here
49
static struct bootfs *bootfs[] = {
50
static struct bootfs *bootfs[] = {
50
	&ext2fs,
51
	&ext2fs,
51
	&iso,
52
	&iso,
52
	&ufs
53
	&ufs,
54
	&xfsfs
53
};
55
};
54
56
55
/*
57
/*
Lines 329-351 Link Here
329
			return 0;
331
			return 0;
330
		}
332
		}
331
		part = &label->d_partitions[partition - 1];
333
		part = &label->d_partitions[partition - 1];
332
		for (i = 0; bootfs[i]->fs_type != part->p_fstype; ++i) {
334
		for (i = 0; i < (int)(sizeof(bootfs)/sizeof(bootfs[0])); i++) {
333
			if (i + 1
335
			if (bootfs[i]->fs_type == part->p_fstype) {
334
			    >= (int) (sizeof(bootfs)/sizeof(bootfs[0])))
336
			        fs = bootfs[i];
335
			{
337
				if (!((*fs->mount)(dev, (long)(part->p_offset) * (long)(label->d_secsize), 1)
336
				printf("aboot: don't know how to mount "
338
				< 0))
337
				       "partition %d (filesystem type %d)\n",
339
				return fs;
338
				       partition, part->p_fstype);
339
				return 0;
340
			}
340
			}
341
		}
341
		}
342
		fs = bootfs[i];
342
		printf("aboot: don't know how to mount "
343
		if ((*fs->mount)(dev, (long)(part->p_offset) * (long)(label->d_secsize), 0)
343
		       "partition %d (filesystem type %d)\n",
344
		    < 0) {
344
	  	        partition, part->p_fstype);
345
			printf("aboot: mount of partition %d failed\n",
345
		return 0;
346
			       partition);
347
			return 0;
348
		}
349
	}
346
	}
350
	return fs;
347
	return fs;
351
}
348
}
(-)aboot-1.0_pre20040408/fs/xfs.c (+816 lines)
Line 0 Link Here
1
/*
2
 *  xfs.c - an implementation of the SGI XFS file system for aboot
3
 *  Jan-Jaap van der Heijden <J.J.vanderHeijden@home.nl>
4
 *
5
 *  Based on fsys_xfs.c from GRUB  --  GRand Unified Bootloader
6
 *  Copyright (C) 2001,2002,2004  Free Software Foundation, Inc.
7
 */
8
/*
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program; if not, write to the Free Software
21
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
 */
23
24
#include <asm/system.h>
25
#include "config.h"
26
#include "aboot.h"
27
#include "bootfs.h"
28
#include "cons.h"
29
#include "disklabel.h"
30
#include "utils.h"
31
#include "xfs.h"
32
33
static int xfs_mount(long cons_dev, long p_offset, long quiet);
34
static int xfs_bread(int fd, long blkno, long nblks, char *buffer);
35
static int xfs_open(const char *dirname);
36
static void xfs_close(int fd);
37
static const char *xfs_readdir(int fd, int rewind);
38
static int xfs_fstat(int fd, struct stat* buf);
39
40
struct bootfs xfsfs = {
41
       FS_EXT2,
42
       0,
43
       xfs_mount,
44
       xfs_open,
45
       xfs_bread,
46
       xfs_close,
47
       xfs_readdir,
48
       xfs_fstat
49
};
50
51
static long dev = -1;
52
static long partition_offset;
53
static long filepos;
54
static long filemax; /* filelen */
55
56
static long xfs_read (void *buf, long len);
57
58
#define isspace(c) ((c) == 0x10)
59
60
static int
61
devread(long sector, long start, long length, void *buf)
62
{
63
       long pos = sector * SECT_SIZE;
64
       pos += partition_offset + start;
65
#ifdef DEBUG_XFS
66
       printf("Reading %ld bytes, starting at sector %ld, disk offset %ld\n",
67
               length, sector, pos);
68
#endif
69
       return cons_read(dev, buf, length, pos);
70
}
71
72
#define MAXNAMELEN     256
73
#define SECTOR_BITS    9
74
#define MAX_LINK_COUNT 8
75
76
typedef struct xad {
77
       xfs_fileoff_t offset;
78
       xfs_fsblock_t start;
79
       xfs_filblks_t len;
80
} xad_t;
81
82
struct xfs_info {
83
       int bsize;
84
       int dirbsize;
85
       int isize;
86
       unsigned int agblocks;
87
       int bdlog;
88
       int blklog;
89
       int inopblog;
90
       int agblklog;
91
       int agnolog;
92
       unsigned int nextents;
93
       xfs_daddr_t next;
94
       xfs_daddr_t daddr;
95
       xfs_dablk_t forw;
96
       xfs_dablk_t dablk;
97
       xfs_bmbt_rec_32_t *xt;
98
       xfs_bmbt_ptr_t ptr0;
99
       int btnode_ptr0_off;
100
       int i8param;
101
       int dirpos;
102
       int dirmax;
103
       int blkoff;
104
       int fpos;
105
       xfs_ino_t rootino;
106
       xfs_ino_t new_ino;
107
};
108
109
static struct xfs_info xfs;
110
111
#ifdef __alpha__ /* take care of alignment*/
112
 static long FSYS_BUF[32768/sizeof(long)];
113
 #define dirbuf                ((long *)FSYS_BUF)
114
 #define filebuf       ((long *)FSYS_BUF + 4096/sizeof(long))
115
 #define inode         ((xfs_dinode_t *)((long *)FSYS_BUF + 8192/sizeof(long)))
116
#else
117
 static char FSYS_BUF[32768];
118
 #define dirbuf                ((char *)FSYS_BUF)
119
 #define filebuf       ((char *)FSYS_BUF + 4096)
120
 #define inode         ((xfs_dinode_t *)((char *)FSYS_BUF + 8192))
121
#endif
122
123
#define icore          (inode->di_core)
124
#define        mask32lo(n)     (((uint32_t)1 << (n)) - 1)
125
126
#define        XFS_INO_MASK(k)         ((uint32_t)((1ULL << (k)) - 1))
127
#define        XFS_INO_OFFSET_BITS     xfs.inopblog
128
#define        XFS_INO_AGBNO_BITS      xfs.agblklog
129
#define        XFS_INO_AGINO_BITS      (xfs.agblklog + xfs.inopblog)
130
#define        XFS_INO_AGNO_BITS       xfs.agnolog
131
132
static inline xfs_agblock_t
133
agino2agbno (xfs_agino_t agino)
134
{
135
       return agino >> XFS_INO_OFFSET_BITS;
136
}
137
138
static inline xfs_agnumber_t
139
ino2agno (xfs_ino_t ino)
140
{
141
       return ino >> XFS_INO_AGINO_BITS;
142
}
143
144
static inline xfs_agino_t
145
ino2agino (xfs_ino_t ino)
146
{
147
       return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS);
148
}
149
150
static inline int
151
ino2offset (xfs_ino_t ino)
152
{
153
       return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS);
154
}
155
156
/* XFS is big endian, alpha is little endian */
157
#define le16(x) __swab16(x)
158
#define le32(x) __swab32(x)
159
#define le64(x) __swab64(x)
160
161
static xfs_fsblock_t
162
xt_start (xfs_bmbt_rec_32_t *r)
163
{
164
       return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | 
165
              (((xfs_fsblock_t)le32 (r->l2)) << 11) |
166
              (((xfs_fsblock_t)le32 (r->l3)) >> 21);
167
}
168
169
static xfs_fileoff_t
170
xt_offset (xfs_bmbt_rec_32_t *r)
171
{
172
       return (((xfs_fileoff_t)le32 (r->l0) &
173
               mask32lo(31)) << 23) |
174
               (((xfs_fileoff_t)le32 (r->l1)) >> 9);
175
}
176
177
static xfs_filblks_t
178
xt_len (xfs_bmbt_rec_32_t *r)
179
{
180
       return le32(r->l3) & mask32lo(21);
181
}
182
183
static const char xfs_highbit[256] = {
184
       -1, 0, 1, 1, 2, 2, 2, 2,                        /* 00 .. 07 */
185
       3, 3, 3, 3, 3, 3, 3, 3,                 /* 08 .. 0f */
186
       4, 4, 4, 4, 4, 4, 4, 4,                 /* 10 .. 17 */
187
       4, 4, 4, 4, 4, 4, 4, 4,                 /* 18 .. 1f */
188
       5, 5, 5, 5, 5, 5, 5, 5,                 /* 20 .. 27 */
189
       5, 5, 5, 5, 5, 5, 5, 5,                 /* 28 .. 2f */
190
       5, 5, 5, 5, 5, 5, 5, 5,                 /* 30 .. 37 */
191
       5, 5, 5, 5, 5, 5, 5, 5,                 /* 38 .. 3f */
192
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 40 .. 47 */
193
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 48 .. 4f */
194
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 50 .. 57 */
195
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 58 .. 5f */
196
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 60 .. 67 */
197
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 68 .. 6f */
198
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 70 .. 77 */
199
       6, 6, 6, 6, 6, 6, 6, 6,                 /* 78 .. 7f */
200
       7, 7, 7, 7, 7, 7, 7, 7,                 /* 80 .. 87 */
201
       7, 7, 7, 7, 7, 7, 7, 7,                 /* 88 .. 8f */
202
       7, 7, 7, 7, 7, 7, 7, 7,                 /* 90 .. 97 */
203
       7, 7, 7, 7, 7, 7, 7, 7,                 /* 98 .. 9f */
204
       7, 7, 7, 7, 7, 7, 7, 7,                 /* a0 .. a7 */
205
       7, 7, 7, 7, 7, 7, 7, 7,                 /* a8 .. af */
206
       7, 7, 7, 7, 7, 7, 7, 7,                 /* b0 .. b7 */
207
       7, 7, 7, 7, 7, 7, 7, 7,                 /* b8 .. bf */
208
       7, 7, 7, 7, 7, 7, 7, 7,                 /* c0 .. c7 */
209
       7, 7, 7, 7, 7, 7, 7, 7,                 /* c8 .. cf */
210
       7, 7, 7, 7, 7, 7, 7, 7,                 /* d0 .. d7 */
211
       7, 7, 7, 7, 7, 7, 7, 7,                 /* d8 .. df */
212
       7, 7, 7, 7, 7, 7, 7, 7,                 /* e0 .. e7 */
213
       7, 7, 7, 7, 7, 7, 7, 7,                 /* e8 .. ef */
214
       7, 7, 7, 7, 7, 7, 7, 7,                 /* f0 .. f7 */
215
       7, 7, 7, 7, 7, 7, 7, 7,                 /* f8 .. ff */
216
};
217
218
static int
219
xfs_highbit32(uint32_t v)
220
{
221
       int             i;
222
223
       if (v & 0xffff0000)
224
               if (v & 0xff000000)
225
                       i = 24;
226
               else
227
                       i = 16;
228
       else if (v & 0x0000ffff)
229
               if (v & 0x0000ff00)
230
                       i = 8;
231
              else
232
                       i = 0;
233
       else
234
               return -1;
235
       return i + xfs_highbit[(v >> i) & 0xff];
236
}
237
238
static int
239
isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len)
240
{
241
       return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
242
}
243
244
static xfs_daddr_t
245
agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno)
246
{
247
       return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog;
248
}
249
250
static xfs_daddr_t
251
fsb2daddr (xfs_fsblock_t fsbno)
252
{
253
       return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog),
254
                        (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog)));
255
}
256
257
#undef offsetof
258
#define offsetof(t,m)  ((int)&(((t *)0)->m))
259
260
static inline int
261
btroot_maxrecs (void)
262
{
263
       int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize;
264
265
       return (tmp - sizeof(xfs_bmdr_block_t) - offsetof(xfs_dinode_t, di_u)) /
266
               (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t));
267
}
268
269
static int
270
di_read (xfs_ino_t ino)
271
{
272
       xfs_agino_t agino;
273
       xfs_agnumber_t agno;
274
       xfs_agblock_t agbno;
275
       xfs_daddr_t daddr;
276
       int offset;
277
278
       agno = ino2agno (ino);
279
       agino = ino2agino (ino);
280
       agbno = agino2agbno (agino);
281
       offset = ino2offset (ino);
282
       daddr = agb2daddr (agno, agbno);
283
284
       devread (daddr, offset*xfs.isize, xfs.isize, (char *)inode);
285
286
       xfs.ptr0 = *(xfs_bmbt_ptr_t *)
287
                   (inode->di_u.di_c + sizeof(xfs_bmdr_block_t)
288
                   + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t));
289
290
       return 1;
291
}
292
293
static void
294
init_extents (void)
295
{
296
       xfs_bmbt_ptr_t ptr0;
297
       xfs_btree_lblock_t h;
298
299
       switch (icore.di_format) {
300
       case XFS_DINODE_FMT_EXTENTS:
301
               xfs.xt = inode->di_u.di_bmx;
302
               xfs.nextents = le32 (icore.di_nextents);
303
               break;
304
       case XFS_DINODE_FMT_BTREE:
305
               ptr0 = xfs.ptr0;
306
               for (;;) {
307
                       xfs.daddr = fsb2daddr (le64(ptr0));
308
                       devread (xfs.daddr, 0,
309
                                sizeof(xfs_btree_lblock_t), (char *)&h);
310
                       if (!h.bb_level) {
311
                               xfs.nextents = le16(h.bb_numrecs);
312
                               xfs.next = fsb2daddr (le64(h.bb_rightsib));
313
                               xfs.fpos = sizeof(xfs_btree_block_t);
314
                               return;
315
                       }
316
                       devread (xfs.daddr, xfs.btnode_ptr0_off,
317
                                sizeof(xfs_bmbt_ptr_t), (char *)&ptr0);
318
               }
319
       }
320
}
321
322
static xad_t *
323
next_extent (void)
324
{
325
       static xad_t xad;
326
327
       switch (icore.di_format) {
328
       case XFS_DINODE_FMT_EXTENTS:
329
               if (xfs.nextents == 0)
330
                       return NULL;
331
               break;
332
       case XFS_DINODE_FMT_BTREE:
333
               if (xfs.nextents == 0) {
334
                       xfs_btree_lblock_t h;
335
                       if (xfs.next == 0)
336
                               return NULL;
337
                       xfs.daddr = xfs.next;
338
                       devread (xfs.daddr, 0, sizeof(xfs_btree_lblock_t), (char *)&h);
339
                       xfs.nextents = le16(h.bb_numrecs);
340
                       xfs.next = fsb2daddr (le64(h.bb_rightsib));
341
                       xfs.fpos = sizeof(xfs_btree_block_t);
342
               }
343
               /* Yeah, I know that's slow, but I really don't care */
344
               devread (xfs.daddr, xfs.fpos, sizeof(xfs_bmbt_rec_t), filebuf);
345
               xfs.xt = (xfs_bmbt_rec_32_t *)filebuf;
346
               xfs.fpos += sizeof(xfs_bmbt_rec_32_t);
347
       }
348
       xad.offset = xt_offset (xfs.xt);
349
       xad.start = xt_start (xfs.xt);
350
       xad.len = xt_len (xfs.xt);
351
       ++xfs.xt;
352
       --xfs.nextents;
353
354
       return &xad;
355
}
356
357
/*
358
 * Name lies - the function reads only first 100 bytes
359
 */
360
static void
361
xfs_dabread (void)
362
{
363
       xad_t *xad;
364
       xfs_fileoff_t offset;;
365
366
       init_extents ();
367
       while ((xad = next_extent ())) {
368
               offset = xad->offset;
369
               if (isinxt (xfs.dablk, offset, xad->len)) {
370
                       devread (fsb2daddr (xad->start + xfs.dablk - offset),
371
                                0, 100, dirbuf);
372
                       break;
373
               }
374
       }
375
}
376
377
static inline xfs_ino_t
378
sf_ino (char *sfe, int namelen)
379
{
380
       void *p = sfe + namelen + 3;
381
#ifdef __alpha__
382
       xfs_ino_t ino = 0;
383
       if (xfs.i8param == 0) {
384
               memcpy(&ino, p, sizeof(xfs_dir2_ino8_t));
385
               return le64(ino);
386
       } else {
387
               memcpy(&ino, p, sizeof(xfs_dir2_ino4_t));
388
               return le32(ino);
389
       }
390
#else
391
       /* unaligned access */
392
       return (xfs.i8param == 0)
393
               ? le64(*(xfs_ino_t *)p) : le32(*(uint32_t *)p);
394
#endif
395
}
396
397
static inline xfs_ino_t
398
sf_parent_ino (void)
399
{
400
#ifdef __alpha__
401
       void *p = &inode->di_u.di_dir2sf.hdr.parent;
402
       xfs_ino_t ino = 0;
403
       if (xfs.i8param == 0) {
404
               memcpy(&ino, p, sizeof(xfs_dir2_ino8_t));
405
               return le64(ino);
406
       } else {
407
               memcpy(&ino, p, sizeof(xfs_dir2_ino4_t));
408
               return le32(ino);
409
       }
410
#else
411
       /* unaligned access */
412
       return (xfs.i8param == 0)
413
               ? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent))
414
               : le32(*(uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent));
415
#endif
416
}
417
418
static inline int
419
roundup8 (int n)
420
{
421
       return ((n+7)&~7);
422
}
423
424
static char *
425
next_dentry (xfs_ino_t *ino)
426
{
427
       int namelen;
428
       int toread;
429
       static xfs_dir2_sf_entry_t *sfe;
430
       char *name = NULL;
431
432
       if (xfs.dirpos >= xfs.dirmax) {
433
               if (xfs.forw == 0)
434
                       return NULL;
435
               xfs.dablk = xfs.forw;
436
               xfs_dabread ();
437
#define h      ((xfs_dir2_leaf_hdr_t *)dirbuf)
438
               xfs.dirmax = le16 (h->count) - le16 (h->stale);
439
               xfs.forw = le32 (h->info.forw);
440
#undef h
441
               xfs.dirpos = 0;
442
       }
443
444
       switch (icore.di_format) {
445
       case XFS_DINODE_FMT_LOCAL:
446
               switch (xfs.dirpos) {
447
               case -2:
448
                       *ino = 0;
449
                       name = ".";
450
                       namelen = 1;
451
                       break;
452
               case -1: /* ".." */
453
                       *ino = sf_parent_ino ();
454
                       name = "..";
455
                       namelen = 2;
456
                       sfe = (xfs_dir2_sf_entry_t *)
457
                               (inode->di_u.di_c 
458
                                + sizeof(xfs_dir2_sf_hdr_t)
459
                                - xfs.i8param);
460
                       break;
461
               default:
462
                       namelen = sfe->namelen;
463
                       *ino = sf_ino ((char *)sfe, namelen);
464
                       name = sfe->name;
465
                       name[namelen] = 0;
466
                       sfe = (xfs_dir2_sf_entry_t *)
467
                                 ((char *)sfe + namelen + 11 - xfs.i8param);
468
               }
469
               break;
470
       case XFS_DINODE_FMT_BTREE:
471
       case XFS_DINODE_FMT_EXTENTS:
472
#define dau    ((xfs_dir2_data_union_t *)dirbuf)
473
               for (;;) {
474
                       if (xfs.blkoff >= xfs.dirbsize) {
475
                               xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
476
                               filepos &= ~(xfs.dirbsize - 1);
477
                               filepos |= xfs.blkoff;
478
                       }
479
                       xfs.blkoff += 4;
480
                       if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) {
481
                               toread = roundup8 (le16(dau->unused.length)) - 4;
482
                               xfs.blkoff += toread;
483
                               filepos += toread;
484
                               continue;
485
                       }
486
                       break;
487
               }
488
               xfs_read ((char *)dirbuf + 4, 5);
489
               *ino = le64 (dau->entry.inumber);
490
               namelen = dau->entry.namelen;
491
#undef dau
492
               toread = roundup8 (namelen + 11) - 9;
493
               xfs_read (dirbuf, toread);
494
               name = (char *)dirbuf;
495
               name[namelen] = 0;
496
               xfs.blkoff += toread + 5;
497
       }
498
       ++xfs.dirpos;
499
500
       return name;
501
}
502
503
static char *
504
first_dentry (xfs_ino_t *ino)
505
{
506
       xfs.forw = 0;
507
       switch (icore.di_format) {
508
       case XFS_DINODE_FMT_LOCAL:
509
               xfs.dirmax = inode->di_u.di_dir2sf.hdr.count;
510
               xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4;
511
               xfs.dirpos = -2;
512
               break;
513
       case XFS_DINODE_FMT_EXTENTS:
514
       case XFS_DINODE_FMT_BTREE:
515
               filepos = 0;
516
               xfs_read (dirbuf, sizeof(xfs_dir2_data_hdr_t));
517
               if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) {
518
#define tail           ((xfs_dir2_block_tail_t *)dirbuf)
519
                       filepos = xfs.dirbsize - sizeof(*tail);
520
                       xfs_read (dirbuf, sizeof(*tail));
521
                       xfs.dirmax = le32 (tail->count) - le32 (tail->stale);
522
#undef tail
523
               } else {
524
                       xfs.dablk = (1ULL << 35) >> xfs.blklog;
525
#define h              ((xfs_dir2_leaf_hdr_t *)dirbuf)
526
#define n              ((xfs_da_intnode_t *)dirbuf)
527
                       for (;;) {
528
                               xfs_dabread ();
529
                               if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC))
530
                                   || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) {
531
                                       xfs.dirmax = le16 (h->count) - le16 (h->stale);
532
                                       xfs.forw = le32 (h->info.forw);
533
                                       break;
534
                               }
535
                               xfs.dablk = le32 (n->btree[0].before);
536
                       }
537
#undef n
538
#undef h
539
               }
540
               xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
541
               filepos = xfs.blkoff;
542
               xfs.dirpos = 0;
543
       }
544
       return next_dentry (ino);
545
}
546
547
548
549
/*
550
 * Initialize an XFS partition starting at offset P_OFFSET; this is
551
 * sort-of the same idea as "mounting" it.  Read in the relevant
552
 * control structures and make them available to the user.  Returns 0
553
 * if successful, -1 on failure.
554
 */
555
static int
556
xfs_mount(long cons_dev, long p_offset, long quiet)
557
{
558
       xfs_sb_t super;
559
560
       partition_offset = p_offset;
561
562
       if (cons_read (cons_dev, &super, sizeof(super), partition_offset) != sizeof(super)) {
563
               printf("xfs_mount: read_disk_block failed!\n");
564
               return -1;
565
       } else if (le32(super.sb_magicnum) != XFS_SB_MAGIC) {
566
               printf("xfs_mount: Bad magic: %x\n", super.sb_magicnum);
567
               return -1;
568
       } else if ((le16(super.sb_versionnum) & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) {
569
               printf("xfs_mount: Bad version: %x\n", super.sb_versionnum);
570
               return -1;
571
       }
572
573
       xfs.bsize = le32 (super.sb_blocksize);
574
       xfs.blklog = super.sb_blocklog;
575
       xfs.bdlog = xfs.blklog - SECTOR_BITS;
576
       xfs.rootino = le64 (super.sb_rootino);
577
       xfs.isize = le16 (super.sb_inodesize);
578
       xfs.agblocks = le32 (super.sb_agblocks);
579
       xfs.dirbsize = xfs.bsize << super.sb_dirblklog;
580
581
       xfs.inopblog = super.sb_inopblog;
582
       xfs.agblklog = super.sb_agblklog;
583
       xfs.agnolog = xfs_highbit32 (le32(super.sb_agcount));
584
585
       xfs.btnode_ptr0_off =
586
               ((xfs.bsize - sizeof(xfs_btree_block_t)) /
587
               (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)))
588
                * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t);
589
590
#ifdef DEBUG
591
       printf("XFS: version   = %d\n",le16(super.sb_versionnum) & XFS_SB_VERSION_NUMBITS);
592
       printf("XFS: blocksize = %d\n",xfs.bsize);
593
#endif
594
       dev = cons_dev;
595
       xfsfs.blocksize = xfs.bsize;
596
       return 0;
597
}
598
599
static long
600
xfs_read (void *buf, long len)
601
{
602
       xad_t *xad;
603
       xfs_fileoff_t endofprev, endofcur, offset;
604
       xfs_filblks_t xadlen;
605
       int toread, startpos, endpos;
606
607
       if (icore.di_format == XFS_DINODE_FMT_LOCAL) {
608
               memmove (buf, inode->di_u.di_c + filepos, len);
609
               filepos += len;
610
               return len;
611
       }
612
613
       startpos = filepos;
614
       endpos = filepos + len;
615
       endofprev = (xfs_fileoff_t)-1;
616
       init_extents ();
617
       while (len > 0 && (xad = next_extent ())) {
618
               offset = xad->offset;
619
               xadlen = xad->len;
620
               if (isinxt (filepos >> xfs.blklog, offset, xadlen)) {
621
                       endofcur = (offset + xadlen) << xfs.blklog; 
622
                       toread = (endofcur >= endpos)
623
                                 ? len : (endofcur - filepos);
624
                       devread (fsb2daddr (xad->start),
625
                                filepos - (offset << xfs.blklog), toread, buf);
626
                       buf += toread;
627
                       len -= toread;
628
                       filepos += toread;
629
               } else if (offset > endofprev) {
630
                       toread = ((offset << xfs.blklog) >= endpos)
631
                                 ? len : ((offset - endofprev) << xfs.blklog);
632
                       len -= toread;
633
                       filepos += toread;
634
                       for (; toread; toread--) {
635
                               *(char*)buf++ = 0;
636
                       }
637
                       continue;
638
               }
639
               endofprev = offset + xadlen; 
640
       }
641
642
       return filepos - startpos;
643
}
644
645
/*
646
 * Read block number "blkno".
647
 */
648
649
static int
650
xfs_bread(int fd, long blkno, long nblks, char *buffer)
651
{
652
       if (fd == 1) {
653
               /*
654
                * Duh. XFS doesn't read past EOF
655
                * aboot does just that by trying to read nblks*blksize,
656
                * where nblks*blksize > filesize
657
                */
658
               memset(buffer,0,nblks*xfs.bsize);
659
               long nbytes = xfs_read(buffer, nblks*xfs.bsize);
660
               if (nbytes == le64(icore.di_size))
661
                       return nblks*xfs.bsize;
662
               return (int)nbytes;
663
       }
664
       printf("XFS error: bad file descriptor!\n");
665
       return -1;
666
}
667
668
/*
669
 * Unix-like open routine.  Returns a small integer 
670
 * (does not care what file, we say it's OK)
671
 */
672
static int xfs_open(const char *dirname)
673
{
674
       xfs_ino_t ino, parent_ino;
675
       xfs_fsize_t di_size;
676
       int di_mode;
677
       int cmp, n, link_count;
678
       char linkbuf[xfs.bsize];
679
       char *rest, *name, ch;
680
       char namebuf[MAXNAMELEN];
681
       strncpy(namebuf,dirname,MAXNAMELEN);
682
       char *filename = namebuf;
683
684
#ifdef DEBUG_XFS
685
       printf("xfs_open(): filename = %s\n", filename);
686
#endif
687
688
       parent_ino = ino = xfs.rootino;
689
       link_count = 0;
690
       for (;;) {
691
               di_read (ino);
692
               di_size = le64 (icore.di_size);
693
               di_mode = le16 (icore.di_mode);
694
695
#ifdef DEBUG_XFS
696
               printf("xfs_open(): di_mode = %o\n", di_mode);
697
#endif
698
               if ((di_mode & IFMT) == IFLNK) {
699
                       if (++link_count > MAX_LINK_COUNT) {
700
                               printf("XFS error: symlink loop!\n");
701
                               return 0;
702
                       }
703
                       if (di_size < xfs.bsize - 1) {
704
                               filepos = 0;
705
                               filemax = di_size;
706
                               n = xfs_read (linkbuf, filemax);
707
                       } else {
708
                               printf("XFS error: bad file length!\n");
709
                               return 0;
710
                       }
711
712
                       ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino;
713
                       while (n < (xfs.bsize - 1) && (linkbuf[n++] = *filename++));
714
                       linkbuf[n] = 0;
715
                       filename = linkbuf;
716
                       continue;
717
               }
718
719
               if (!*filename || isspace (*filename)) {
720
                       if (((di_mode & IFMT) != IFREG)
721
                           && ((di_mode & IFMT) != IFDIR)) {
722
                               printf("XFS error: bad file type!\n");
723
                               return 0;
724
                       }
725
                       filepos = 0;
726
                       filemax = di_size;
727
                       return 1;
728
               }
729
730
               if ((di_mode & IFMT) != IFDIR) {
731
                       printf("XFS error: bad file type!\n");
732
                       return 0;
733
               }
734
735
               for (; *filename == '/'; filename++);
736
737
               if (!strcmp(filename,"")) {
738
                       filepos = 0;
739
                       filemax = 0;
740
                       return 1;
741
               }
742
743
               for (rest = filename; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
744
               *rest = 0;
745
746
               name = first_dentry (&xfs.new_ino);
747
               for (;;) {
748
#ifdef DEBUG
749
                       printf("xfs_open(): found %s\n", name);
750
#endif
751
                       cmp = (!*filename) ? -1 : strcmp (filename, name);
752
                       if (cmp == 0) {
753
                               parent_ino = ino;
754
                               if (xfs.new_ino)
755
                                       ino = xfs.new_ino;
756
                               *(filename = rest) = ch;
757
                               break;
758
                       }
759
                       name = next_dentry (&xfs.new_ino);
760
                       if (name == NULL) {
761
                               *rest = ch;
762
                               return -1;
763
                       }
764
               }
765
       }
766
}
767
768
/*
769
 * Only one file is opened at any time, so close is a nop.
770
 */
771
static void xfs_close(int fd)
772
{
773
}
774
775
/*
776
 * Return the next directory entry.
777
 * Must have opened the directory with xfs_open()
778
 */
779
static const char *
780
xfs_readdir(int fd, int rewind)
781
{
782
       if (fd != 1)
783
               return NULL;
784
       if ((le16 (icore.di_mode) & IFMT) != IFDIR) {
785
               printf("Not a directory!\n");
786
               return NULL;
787
       }
788
       if (rewind)
789
               return first_dentry (&xfs.new_ino);
790
       return next_dentry (&xfs.new_ino);
791
}
792
793
/*
794
 * Get file status
795
 */
796
static int
797
xfs_fstat(int fd, struct stat* buf)
798
{
799
       if (fd != 1)
800
               return -1;
801
802
       memset(buf, 0, sizeof(struct stat));
803
       buf->st_mode   = le16(icore.di_mode);
804
       buf->st_flags  = le16(icore.di_flags);
805
       buf->st_nlink  = le16(icore.di_onlink);
806
       buf->st_uid    = le32(icore.di_uid);
807
       buf->st_gid    = le32(icore.di_gid);
808
       buf->st_size   = le64(icore.di_size);
809
       buf->st_blocks = le64(icore.di_nblocks);
810
       buf->st_atime  = le32(icore.di_atime.t_sec);
811
       buf->st_mtime  = le32(icore.di_mtime.t_sec);
812
       buf->st_ctime  = le32(icore.di_ctime.t_sec);
813
       return 0;
814
}
815
816
(-)aboot-1.0_pre20040408/fs/xfs.h (+536 lines)
Line 0 Link Here
1
/*
2
 * xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file
3
 *
4
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of version 2 of the GNU General Public License as
8
 * published by the Free Software Foundation.
9
 * 
10
 * This program is distributed in the hope that it would be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 * 
14
 * Further, this software is distributed without any warranty that it is
15
 * free of the rightful claim of any third person regarding infringement
16
 * or the like.  Any license provided herein, whether implied or
17
 * otherwise, applies only to this software file.  Patent licenses, if
18
 * any, provided herein do not apply to combinations of this program with
19
 * other software, or any other product whatsoever.
20
 * 
21
 * You should have received a copy of the GNU General Public License along
22
 * with this program; if not, write the Free Software Foundation, Inc., 59
23
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
24
 * 
25
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26
 * Mountain View, CA  94043, or:
27
 * 
28
 * http://www.sgi.com 
29
 * 
30
 * For further information regarding this notice, see: 
31
 * 
32
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33
 */
34
35
typedef uint64_t       xfs_ino_t;
36
typedef        uint32_t        xfs_agino_t;
37
typedef int64_t                xfs_daddr_t;
38
typedef int64_t                xfs_off_t;
39
typedef uint8_t                uuid_t[16];
40
41
42
/* those are from xfs_types.h */
43
44
typedef uint32_t       xfs_agblock_t;  /* blockno in alloc. group */
45
typedef        uint32_t        xfs_extlen_t;   /* extent length in blocks */
46
typedef        uint32_t        xfs_agnumber_t; /* allocation group number */
47
typedef int32_t                xfs_extnum_t;   /* # of extents in a file */
48
typedef int16_t                xfs_aextnum_t;  /* # extents in an attribute fork */
49
typedef        int64_t         xfs_fsize_t;    /* bytes in a file */
50
51
typedef        uint32_t        xfs_dablk_t;    /* dir/attr block number (in file) */
52
typedef        uint32_t        xfs_dahash_t;   /* dir/attr hash value */
53
54
/*
55
 * Disk based types:
56
 */
57
typedef uint64_t       xfs_dfsbno_t;   /* blockno in filesystem (agno|agbno) */
58
typedef uint64_t       xfs_drfsbno_t;  /* blockno in filesystem (raw) */
59
typedef        uint64_t        xfs_drtbno_t;   /* extent (block) in realtime area */
60
typedef        uint64_t        xfs_dfiloff_t;  /* block number in a file */
61
62
typedef        uint64_t        xfs_fsblock_t;  /* blockno in filesystem (agno|agbno) */
63
typedef        uint64_t        xfs_fileoff_t;  /* block number in a file */
64
typedef        uint64_t        xfs_filblks_t;  /* number of blocks in a file */
65
66
67
/* those are from xfs_sb.h */
68
69
#define        XFS_SB_MAGIC            0x58465342      /* 'XFSB'*/
70
#define        XFS_SB_VERSION_4        4               /* 6.2+ - bitmask version */
71
#define        XFS_SB_VERSION_NUMBITS  0x000f
72
73
typedef struct xfs_sb
74
{
75
       uint32_t        sb_magicnum;    /* magic number == XFS_SB_MAGIC */
76
       uint32_t        sb_blocksize;   /* logical block size, bytes */
77
       xfs_drfsbno_t   sb_dblocks;     /* number of data blocks */
78
       xfs_drfsbno_t   sb_rblocks;     /* number of realtime blocks */
79
       xfs_drtbno_t    sb_rextents;    /* number of realtime extents */
80
       uuid_t          sb_uuid;        /* file system unique id */
81
       xfs_dfsbno_t    sb_logstart;    /* starting block of log if internal */
82
       xfs_ino_t       sb_rootino;     /* root inode number */
83
       xfs_ino_t       sb_rbmino;      /* bitmap inode for realtime extents */
84
       xfs_ino_t       sb_rsumino;     /* summary inode for rt bitmap */
85
       xfs_agblock_t   sb_rextsize;    /* realtime extent size, blocks */
86
       xfs_agblock_t   sb_agblocks;    /* size of an allocation group */
87
       xfs_agnumber_t  sb_agcount;     /* number of allocation groups */
88
       xfs_extlen_t    sb_rbmblocks;   /* number of rt bitmap blocks */
89
       xfs_extlen_t    sb_logblocks;   /* number of log blocks */
90
       uint16_t        sb_versionnum;  /* header version == XFS_SB_VERSION */
91
       uint16_t        sb_sectsize;    /* volume sector size, bytes */
92
       uint16_t        sb_inodesize;   /* inode size, bytes */
93
       uint16_t        sb_inopblock;   /* inodes per block */
94
       char            sb_fname[12];   /* file system name */
95
       uint8_t sb_blocklog;    /* log2 of sb_blocksize */
96
       uint8_t sb_sectlog;     /* log2 of sb_sectsize */
97
       uint8_t sb_inodelog;    /* log2 of sb_inodesize */
98
       uint8_t sb_inopblog;    /* log2 of sb_inopblock */
99
       uint8_t sb_agblklog;    /* log2 of sb_agblocks (rounded up) */
100
       uint8_t sb_rextslog;    /* log2 of sb_rextents */
101
       uint8_t sb_inprogress;  /* mkfs is in progress, don't mount */
102
       uint8_t sb_imax_pct;    /* max % of fs for inode space */
103
                                       /* statistics */
104
       /*
105
        * These fields must remain contiguous.  If you really
106
        * want to change their layout, make sure you fix the
107
        * code in xfs_trans_apply_sb_deltas().
108
        */
109
       uint64_t        sb_icount;      /* allocated inodes */
110
       uint64_t        sb_ifree;       /* free inodes */
111
       uint64_t        sb_fdblocks;    /* free data blocks */
112
       uint64_t        sb_frextents;   /* free realtime extents */
113
       /*
114
        * End contiguous fields.
115
        */
116
       xfs_ino_t       sb_uquotino;    /* user quota inode */
117
       xfs_ino_t       sb_gquotino;    /* group quota inode */
118
       uint16_t        sb_qflags;      /* quota flags */
119
       uint8_t sb_flags;       /* misc. flags */
120
       uint8_t sb_shared_vn;   /* shared version number */
121
       xfs_extlen_t    sb_inoalignmt;  /* inode chunk alignment, fsblocks */
122
       uint32_t        sb_unit;        /* stripe or raid unit */
123
       uint32_t        sb_width;       /* stripe or raid width */      
124
       uint8_t sb_dirblklog;   /* log2 of dir block size (fsbs) */
125
        uint8_t       sb_dummy[7];    /* padding */
126
} xfs_sb_t;
127
128
129
/* those are from xfs_btree.h */
130
131
/*
132
 * Long form header: bmap btrees.
133
 */
134
typedef struct xfs_btree_lblock
135
{
136
       uint32_t        bb_magic;       /* magic number for block type */
137
       uint16_t        bb_level;       /* 0 is a leaf */
138
       uint16_t        bb_numrecs;     /* current # of data records */
139
       xfs_dfsbno_t    bb_leftsib;     /* left sibling block or NULLDFSBNO */
140
       xfs_dfsbno_t    bb_rightsib;    /* right sibling block or NULLDFSBNO */
141
} xfs_btree_lblock_t;
142
143
/*
144
 * Combined header and structure, used by common code.
145
 */
146
typedef struct xfs_btree_hdr
147
{
148
       uint32_t        bb_magic;       /* magic number for block type */
149
       uint16_t        bb_level;       /* 0 is a leaf */
150
       uint16_t        bb_numrecs;     /* current # of data records */
151
} xfs_btree_hdr_t;
152
153
typedef struct xfs_btree_block
154
{
155
       xfs_btree_hdr_t bb_h;           /* header */
156
       union           {
157
               struct  {
158
                       xfs_agblock_t   bb_leftsib;
159
                       xfs_agblock_t   bb_rightsib;
160
               }       s;              /* short form pointers */
161
               struct  {
162
                       xfs_dfsbno_t    bb_leftsib;
163
                       xfs_dfsbno_t    bb_rightsib;
164
               }       l;              /* long form pointers */
165
       }               bb_u;           /* rest */
166
} xfs_btree_block_t;
167
168
/* those are from xfs_bmap_btree.h */
169
170
/*
171
 * Bmap root header, on-disk form only.
172
 */
173
typedef struct xfs_bmdr_block
174
{
175
       uint16_t        bb_level;       /* 0 is a leaf */
176
       uint16_t        bb_numrecs;     /* current # of data records */
177
} xfs_bmdr_block_t;
178
179
/*
180
 * Bmap btree record and extent descriptor.
181
 * For 32-bit kernels,
182
 *  l0:31 is an extent flag (value 1 indicates non-normal).
183
 *  l0:0-30 and l1:9-31 are startoff.
184
 *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
185
 *  l3:0-20 are blockcount.
186
 * For 64-bit kernels,
187
 *  l0:63 is an extent flag (value 1 indicates non-normal).
188
 *  l0:9-62 are startoff.
189
 *  l0:0-8 and l1:21-63 are startblock.
190
 *  l1:0-20 are blockcount.
191
 */
192
193
#define        BMBT_USE_64     1
194
195
typedef struct xfs_bmbt_rec_32
196
{
197
       uint32_t                l0, l1, l2, l3;
198
} xfs_bmbt_rec_32_t;
199
typedef struct xfs_bmbt_rec_64
200
{
201
       uint64_t                l0, l1;
202
} xfs_bmbt_rec_64_t;
203
204
#if BMBT_USE_64
205
typedef        uint64_t        xfs_bmbt_rec_base_t;    /* use this for casts */
206
typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
207
#else  /* !BMBT_USE_64 */
208
typedef        uint32_t        xfs_bmbt_rec_base_t;    /* use this for casts */
209
typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
210
#endif /* BMBT_USE_64 */
211
212
/*
213
 * Key structure for non-leaf levels of the tree.
214
 */
215
typedef struct xfs_bmbt_key
216
{
217
       xfs_dfiloff_t   br_startoff;    /* starting file offset */
218
} xfs_bmbt_key_t, xfs_bmdr_key_t;
219
220
typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;   /* btree pointer type */
221
                                       /* btree block header type */
222
typedef        struct xfs_btree_lblock xfs_bmbt_block_t;
223
224
225
226
/* those are from xfs_dir2.h */
227
/*
228
 * Directory version 2.
229
 * There are 4 possible formats:
230
 *     shortform
231
 *     single block - data with embedded leaf at the end
232
 *     multiple data blocks, single leaf+freeindex block
233
 *     data blocks, node&leaf blocks (btree), freeindex blocks
234
 *
235
 *     The shortform format is in xfs_dir2_sf.h.
236
 *     The single block format is in xfs_dir2_block.h.
237
 *     The data block format is in xfs_dir2_data.h.
238
 *     The leaf and freeindex block formats are in xfs_dir2_leaf.h.
239
 *     Node blocks are the same as the other version, in xfs_da_btree.h.
240
 */
241
242
/*
243
 * Byte offset in data block and shortform entry.
244
 */
245
typedef        uint16_t        xfs_dir2_data_off_t;
246
247
/*
248
 * Byte offset in a directory.
249
 */
250
typedef        xfs_off_t               xfs_dir2_off_t;
251
252
/* those are from xfs_da_btree.h */
253
/*========================================================================
254
 * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
255
 *========================================================================*/
256
257
/*
258
 * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
259
 *
260
 * Is is used to manage a doubly linked list of all blocks at the same
261
 * level in the Btree, and to identify which type of block this is.
262
 */
263
#define        XFS_DIR2_LEAF1_MAGIC    0xd2f1  /* magic number: v2 dirlf single blks */
264
#define        XFS_DIR2_LEAFN_MAGIC    0xd2ff  /* magic number: v2 dirlf multi blks */
265
266
typedef struct xfs_da_blkinfo {
267
       xfs_dablk_t forw;                       /* previous block in list */
268
       xfs_dablk_t back;                       /* following block in list */
269
       uint16_t magic;                 /* validity check on block */
270
       uint16_t pad;                           /* unused */
271
} xfs_da_blkinfo_t;
272
273
/*
274
 * This is the structure of the root and intermediate nodes in the Btree.
275
 * The leaf nodes are defined above.
276
 *
277
 * Entries are not packed.
278
 *
279
 * Since we have duplicate keys, use a binary search but always follow
280
 * all match in the block, not just the first match found.
281
 */
282
283
typedef struct xfs_da_intnode {
284
       struct xfs_da_node_hdr {        /* constant-structure header block */
285
              xfs_da_blkinfo_t info;  /* block type, links, etc. */
286
               uint16_t count; /* count of active entries */
287
               uint16_t level; /* level above leaves (leaf == 0) */
288
      } hdr;
289
       struct xfs_da_node_entry {
290
              xfs_dahash_t hashval;   /* hash value for this descendant */
291
              xfs_dablk_t before;     /* Btree block before this key */
292
       } btree[1];                     /* variable sized array of keys */
293
} xfs_da_intnode_t;
294
295
296
/* those are from xfs_dir2_data.h */
297
/*
298
 * Directory format 2, data block structures.
299
 */
300
301
/*
302
 * Constants.
303
 */
304
#define        XFS_DIR2_DATA_FREE_TAG  0xffff
305
#define        XFS_DIR2_DATA_FD_COUNT  3
306
307
/*
308
 * Structures.
309
 */
310
311
/*
312
 * Describe a free area in the data block.
313
 * The freespace will be formatted as a xfs_dir2_data_unused_t.
314
 */
315
typedef struct xfs_dir2_data_free {
316
       xfs_dir2_data_off_t     offset;         /* start of freespace */
317
       xfs_dir2_data_off_t     length;         /* length of freespace */
318
} xfs_dir2_data_free_t;
319
320
/*
321
 * Header for the data blocks.
322
 * Always at the beginning of a directory-sized block.
323
 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
324
 */
325
typedef struct xfs_dir2_data_hdr {
326
       uint32_t                magic;          /* XFS_DIR2_DATA_MAGIC */
327
                                               /* or XFS_DIR2_BLOCK_MAGIC */
328
       xfs_dir2_data_free_t    bestfree[XFS_DIR2_DATA_FD_COUNT];
329
} xfs_dir2_data_hdr_t;
330
331
/*
332
 * Active entry in a data block.  Aligned to 8 bytes.
333
 * Tag appears as the last 2 bytes.
334
 */
335
typedef struct xfs_dir2_data_entry {
336
       xfs_ino_t               inumber;        /* inode number */
337
       uint8_t         namelen;        /* name length */
338
       uint8_t         name[1];        /* name bytes, no null */
339
                                               /* variable offset */
340
       xfs_dir2_data_off_t     tag;            /* starting offset of us */
341
} xfs_dir2_data_entry_t;
342
343
/*
344
 * Unused entry in a data block.  Aligned to 8 bytes.
345
 * Tag appears as the last 2 bytes.
346
 */
347
typedef struct xfs_dir2_data_unused {
348
       uint16_t                freetag;        /* XFS_DIR2_DATA_FREE_TAG */
349
       xfs_dir2_data_off_t     length;         /* total free length */
350
                                              /* variable offset */
351
       xfs_dir2_data_off_t     tag;            /* starting offset of us */
352
} xfs_dir2_data_unused_t;
353
354
typedef union {
355
       xfs_dir2_data_entry_t   entry;
356
       xfs_dir2_data_unused_t  unused;
357
} xfs_dir2_data_union_t;
358
359
360
/* those are from xfs_dir2_leaf.h */
361
/*
362
 * Directory version 2, leaf block structures.
363
 */
364
365
/*
366
 * Leaf block header.
367
 */
368
typedef struct xfs_dir2_leaf_hdr {
369
       xfs_da_blkinfo_t        info;           /* header for da routines */
370
       uint16_t                count;          /* count of entries */
371
       uint16_t                stale;          /* count of stale entries */
372
} xfs_dir2_leaf_hdr_t;
373
374
375
/* those are from xfs_dir2_block.h */
376
/*
377
 * xfs_dir2_block.h
378
 * Directory version 2, single block format structures
379
 */
380
381
/*
382
 * The single block format is as follows:
383
 * xfs_dir2_data_hdr_t structure
384
 * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
385
 * xfs_dir2_leaf_entry_t structures
386
 * xfs_dir2_block_tail_t structure
387
 */
388
389
#define        XFS_DIR2_BLOCK_MAGIC    0x58443242      /* XD2B: for one block dirs */
390
391
typedef struct xfs_dir2_block_tail {
392
       uint32_t        count;                  /* count of leaf entries */
393
       uint32_t        stale;                  /* count of stale lf entries */
394
} xfs_dir2_block_tail_t;
395
396
397
/* those are from xfs_dir2_sf.h */
398
399
/*
400
 * Directory layout when stored internal to an inode.
401
 *
402
 * Small directories are packed as tightly as possible so as to
403
 * fit into the literal area of the inode.
404
 */
405
406
/*
407
 * Inode number stored as 8 8-bit values.
408
 */
409
typedef        struct { uint8_t i[8]; } xfs_dir2_ino8_t;
410
411
/*
412
 * Inode number stored as 4 8-bit values.
413
 * Works a lot of the time, when all the inode numbers in a directory
414
 * fit in 32 bits.
415
 */
416
typedef struct { uint8_t i[4]; } xfs_dir2_ino4_t;
417
418
typedef union {
419
       xfs_dir2_ino8_t i8;
420
       xfs_dir2_ino4_t i4;
421
} xfs_dir2_inou_t;
422
423
/*
424
 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
425
 * Only need 16 bits, this is the byte offset into the single block form.
426
 */
427
typedef struct { uint8_t i[2]; } xfs_dir2_sf_off_t;
428
429
/*
430
 * The parent directory has a dedicated field, and the self-pointer must
431
 * be calculated on the fly.
432
 *
433
 * Entries are packed toward the top as tightly as possible.  The header
434
 * and the elements must be bcopy()'d out into a work area to get correct
435
 * alignment for the inode number fields.
436
 */
437
typedef struct xfs_dir2_sf_hdr {
438
       uint8_t         count;          /* count of entries */
439
       uint8_t         i8count;        /* count of 8-byte inode #s */
440
       xfs_dir2_inou_t         parent;         /* parent dir inode number */
441
} xfs_dir2_sf_hdr_t;
442
443
typedef struct xfs_dir2_sf_entry {
444
       uint8_t         namelen;        /* actual name length */
445
       xfs_dir2_sf_off_t       offset;         /* saved offset */
446
       uint8_t         name[1];        /* name, variable size */
447
       xfs_dir2_inou_t         inumber;        /* inode number, var. offset */
448
} xfs_dir2_sf_entry_t;
449
450
typedef struct xfs_dir2_sf {
451
       xfs_dir2_sf_hdr_t       hdr;            /* shortform header */
452
       xfs_dir2_sf_entry_t     list[1];        /* shortform entries */
453
} xfs_dir2_sf_t;
454
455
/* those are from xfs_dinode.h */
456
457
#define        XFS_DINODE_VERSION_1    1
458
#define        XFS_DINODE_VERSION_2    2
459
#define        XFS_DINODE_MAGIC        0x494e  /* 'IN' */
460
461
/*
462
 * Disk inode structure.
463
 * This is just the header; the inode is expanded to fill a variable size
464
 * with the last field expanding.  It is split into the core and "other"
465
 * because we only need the core part in the in-core inode.
466
 */
467
typedef struct xfs_timestamp {
468
       int32_t t_sec;          /* timestamp seconds */
469
       int32_t t_nsec;         /* timestamp nanoseconds */
470
} xfs_timestamp_t;
471
472
/*
473
 * Note: Coordinate changes to this structure with the XFS_DI_* #defines
474
 * below and the offsets table in xfs_ialloc_log_di().
475
 */
476
typedef struct xfs_dinode_core
477
{
478
       uint16_t        di_magic;       /* inode magic # = XFS_DINODE_MAGIC */
479
       uint16_t        di_mode;        /* mode and type of file */
480
       int8_t  di_version;     /* inode version */
481
       int8_t  di_format;      /* format of di_c data */
482
       uint16_t        di_onlink;      /* old number of links to file */
483
       uint32_t        di_uid;         /* owner's user id */
484
       uint32_t        di_gid;         /* owner's group id */
485
       uint32_t        di_nlink;       /* number of links to file */
486
       uint16_t        di_projid;      /* owner's project id */
487
       uint8_t di_pad[10];     /* unused, zeroed space */
488
       xfs_timestamp_t di_atime;       /* time last accessed */
489
       xfs_timestamp_t di_mtime;       /* time last modified */
490
       xfs_timestamp_t di_ctime;       /* time created/inode modified */
491
       xfs_fsize_t     di_size;        /* number of bytes in file */
492
       xfs_drfsbno_t   di_nblocks;     /* # of direct & btree blocks used */
493
       xfs_extlen_t    di_extsize;     /* basic/minimum extent size for file */
494
       xfs_extnum_t    di_nextents;    /* number of extents in data fork */
495
       xfs_aextnum_t   di_anextents;   /* number of extents in attribute fork*/
496
       uint8_t di_forkoff;     /* attr fork offs, <<3 for 64b align */
497
       int8_t  di_aformat;     /* format of attr fork's data */
498
       uint32_t        di_dmevmask;    /* DMIG event mask */
499
       uint16_t        di_dmstate;     /* DMIG state info */
500
       uint16_t        di_flags;       /* random flags, XFS_DIFLAG_... */
501
       uint32_t        di_gen;         /* generation number */
502
} xfs_dinode_core_t;
503
504
typedef struct xfs_dinode
505
{
506
       xfs_dinode_core_t       di_core;
507
       xfs_agino_t             di_next_unlinked;/* agi unlinked list ptr */
508
       union {
509
               xfs_bmdr_block_t di_bmbt;       /* btree root block */
510
               xfs_bmbt_rec_32_t di_bmx[1];    /* extent list */
511
               xfs_dir2_sf_t   di_dir2sf;      /* shortform directory v2 */
512
               char            di_c[1];        /* local contents */
513
       } di_u;
514
} xfs_dinode_t;
515
516
/*
517
 * Values for di_format
518
 */
519
typedef enum xfs_dinode_fmt
520
{
521
       XFS_DINODE_FMT_DEV,             /* CHR, BLK: di_dev */
522
       XFS_DINODE_FMT_LOCAL,           /* DIR, REG: di_c */
523
                                       /* LNK: di_symlink */
524
       XFS_DINODE_FMT_EXTENTS,         /* DIR, REG, LNK: di_bmx */
525
       XFS_DINODE_FMT_BTREE,           /* DIR, REG, LNK: di_bmbt */
526
       XFS_DINODE_FMT_UUID             /* MNT: di_uuid */
527
} xfs_dinode_fmt_t;
528
529
/*
530
 * File types (mode field)
531
 */
532
#define        IFMT            0170000         /* type of file */
533
#define        IFDIR           0040000         /* directory */
534
#define        IFREG           0100000         /* regular */
535
#define        IFLNK           0120000         /* symbolic link */
536

Return to bug 107103