summaryrefslogtreecommitdiffstats
path: root/sysutils/grub/files/patch-ufs2
blob: cb1f18aa1b9c9474795d7b0ed3b64dfbd0723724 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
diff -ruN configure.ac.orig configure.ac
--- configure.ac.orig	Sat Apr 24 20:49:07 2004
+++ configure.ac	Sat Apr 24 20:49:16 2004
@@ -227,6 +227,13 @@
   FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FFS=1"
 fi
 
+AC_ARG_ENABLE(ufs2,
+  [  --disable-ufs2          disable UFS2 support in Stage 2])
+
+if test x"$enable_ufs2" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_UFS2=1"
+fi
+
 AC_ARG_ENABLE(minix,
   [  --disable-minix         disable Minix fs support in Stage 2])
 
diff -ruN grub/Makefile.am.orig grub/Makefile.am
--- grub/Makefile.am.orig	Sat Apr 24 20:49:07 2004
+++ grub/Makefile.am	Sat Apr 24 20:49:16 2004
@@ -7,6 +7,7 @@
 endif
 
 AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 \
+	-DFSYS_UFS2=1 \
 	-DFSYS_FFS=1 -DFSYS_MINIX=1 -DSUPPORT_HERCULES=1 \
 	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
 	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
diff -ruN stage2/Makefile.am.orig stage2/Makefile.am
--- stage2/Makefile.am.orig	Sat Apr 24 20:49:07 2004
+++ stage2/Makefile.am	Sat Apr 24 20:49:16 2004
@@ -17,10 +17,12 @@
 noinst_LIBRARIES = libgrub.a
 libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
 	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_jfs.c \
+	fsys_ufs2.c \
 	fsys_minix.c fsys_reiserfs.c fsys_vstafs.c fsys_xfs.c gunzip.c \
 	md5.c serial.c stage2.c terminfo.c tparm.c
 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+	-DFSYS_UFS2=1 \
 	-DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 -DFSYS_VSTAFS=1 \
 	-DFSYS_XFS=1 -DUSE_MD5_PASSWORDS=1 \
 	-DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 -fwritable-strings
@@ -33,21 +35,25 @@
 if DISKLESS_SUPPORT
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
 	jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
+	ufs2_stage1_5 \
 	xfs_stage1_5 nbgrub pxegrub
 noinst_DATA = pre_stage2 start nbloader pxeloader diskless
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
 	fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
 	minix_stage1_5.exec reiserfs_stage1_5.exec \
+	ufs2_stage1_5.exec \
 	vstafs_stage1_5.exec xfs_stage1_5.exec nbloader.exec \
 	pxeloader.exec diskless.exec
 else
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
 	jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
+	ufs2_stage1_5 \
 	xfs_stage1_5
 noinst_DATA = pre_stage2 start
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
 	fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
 	minix_stage1_5.exec reiserfs_stage1_5.exec \
+	ufs2_stage1_5.exec \
 	vstafs_stage1_5.exec xfs_stage1_5.exec
 endif
 MOSTLYCLEANFILES = $(noinst_PROGRAMS)
@@ -84,6 +90,7 @@
 # For stage2 target.
 pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
 	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+	fsys_ufs2.c \
 	fsys_fat.c fsys_ffs.c fsys_jfs.c fsys_minix.c fsys_reiserfs.c \
 	fsys_vstafs.c fsys_xfs.c gunzip.c hercules.c md5.c serial.c \
 	smp-imps.c stage2.c terminfo.c tparm.c
@@ -148,6 +155,15 @@
 ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
 	-DNO_BLOCK_FILES=1
 ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ufs2_stage1_5 target.
+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ufs2.c bios.c
+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
 
 # For minix_stage1_5 target.
 minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
diff -ruN stage2/builtins.c.orig stage2/builtins.c
--- stage2/builtins.c.orig	Sat Apr 24 20:49:07 2004
+++ stage2/builtins.c	Sat Apr 24 20:49:16 2004
@@ -3747,6 +3747,7 @@
   {
     {"ext2fs",   "/e2fs_stage1_5"},
     {"fat",      "/fat_stage1_5"},
+    {"ufs2",     "/ufs2_stage1_5"},
     {"ffs",      "/ffs_stage1_5"},
     {"jfs",      "/jfs_stage1_5"},
     {"minix",    "/minix_stage1_5"},
diff -ruN stage2/disk_io.c.orig stage2/disk_io.c
--- stage2/disk_io.c.orig	Sat Apr 24 20:49:07 2004
+++ stage2/disk_io.c	Sat Apr 24 20:49:16 2004
@@ -72,6 +72,9 @@
 # ifdef FSYS_XFS
   {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0},
 # endif
+# ifdef FSYS_UFS2
+  {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed},
+# endif
   /* XX FFS should come last as it's superblock is commonly crossing tracks
      on floppies from track 1 to 2, while others only use 1.  */
 # ifdef FSYS_FFS
diff -ruN stage2/filesys.h.orig stage2/filesys.h
--- stage2/filesys.h.orig	Sat Apr 24 20:49:07 2004
+++ stage2/filesys.h	Sat Apr 24 20:49:16 2004
@@ -30,6 +30,16 @@
 #define FSYS_FFS_NUM 0
 #endif
 
+#ifdef FSYS_UFS2
+#define FSYS_UFS2_NUM 1
+int ufs2_mount (void);
+int ufs2_read (char *buf, int len);
+int ufs2_dir (char *dirname);
+int ufs2_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_UFS2_NUM 0
+#endif
+
 #ifdef FSYS_FAT
 #define FSYS_FAT_NUM 1
 int fat_mount (void);
@@ -109,6 +119,7 @@
 #define NUM_FSYS	\
   (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
    + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
+   + FSYS_UFS2_NUM \
    + FSYS_TFTP_NUM)
 #endif
 
diff -ruN stage2/fsys_ufs2.c.orig stage2/fsys_ufs2.c
--- stage2/fsys_ufs2.c.orig	Thu Jan  1 03:00:00 1970
+++ stage2/fsys_ufs2.c	Sat Apr 24 21:05:20 2004
@@ -0,0 +1,333 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Elements of this file were originally from the FreeBSD "biosboot"
+ * bootloader file "disk.c" dated 4/12/95.
+ *
+ * The license and header comments from that file are included here.
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
+ *	$Id: fsys_ufs2.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
+ */
+
+/*
+ * Copyright (c) 2004 Valery Hromov
+ *
+ * Permission to use, copy, modify and distribute this software granted
+ * to the Free Software Foundation.
+ *
+ */
+
+#ifdef FSYS_UFS2
+
+#include "shared.h"
+#include "filesys.h"
+
+#include "ufs2.h"
+
+/* used for filesystem map blocks */
+static int mapblock;
+static int mapblock_offset;
+static int mapblock_bsize;
+
+static int sblock_try[] = SBLOCKSEARCH;
+static ufs2_daddr_t sblockloc;
+static int type;
+
+/* pointer to superblock */
+#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
+
+#define INODE_UFS2 ((struct ufs2_dinode *) ( FSYS_BUF + 16384 ))
+
+#define MAPBUF ( FSYS_BUF + 24576 )
+#define MAPBUF_LEN 8192
+
+int
+ufs2_mount (void)
+{
+  int retval = 0;
+  int i;
+
+  sblockloc = -1;
+  type = 0;
+
+  if ( ! (((current_drive & 0x80) || (current_slice != 0))
+       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))) {
+
+	  for (i = 0; sblock_try[i] != -1; ++i) {
+		if (! (part_length < (sblock_try[i] + (SBLOCKSIZE / DEV_BSIZE))
+		    || !devread (0, sblock_try[i], SBLOCKSIZE, (char *) SUPERBLOCK))) {
+			if (SUPERBLOCK->fs_magic == FS_UFS2_MAGIC /* &&
+					(SUPERBLOCK->fs_sblockloc == sblockloc ||
+					(SUPERBLOCK->fs_old_flags & FS_FLAGS_UPDATED) == 0)*/) {
+				type = 2;
+			} else {
+				continue;
+			}
+
+			retval = 1;
+			sblockloc = sblock_try[i];
+			break;
+		}
+	  }
+  }
+
+  mapblock = -1;
+  mapblock_offset = -1;
+  
+  return retval;
+}
+
+static int64_t
+block_map (int file_block)
+{
+  int bnum, offset, bsize;
+  
+  if (file_block < NDADDR)
+    return (INODE_UFS2->di_db[file_block]);
+  
+  /* If the blockmap loaded does not include FILE_BLOCK,
+     load a new blockmap.  */
+
+  if ((bnum = fsbtodb (SUPERBLOCK, INODE_UFS2->di_ib[0])) != mapblock
+      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
+    {
+      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
+	{
+	  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
+	  bsize = MAPBUF_LEN;
+	  
+	  if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
+	    offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
+	}
+      else
+	{
+	  bsize = SUPERBLOCK->fs_bsize;
+	  offset = 0;
+	}
+      
+      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
+	{
+	  mapblock = -1;
+	  mapblock_bsize = -1;
+	  mapblock_offset = -1;
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      
+      mapblock = bnum;
+      mapblock_bsize = bsize;
+      mapblock_offset = offset;
+    }
+  
+  return (((int64_t *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
+			  - mapblock_offset]);
+}
+
+int
+ufs2_read (char *buf, int len)
+{
+  int logno, off, size, ret = 0;
+  int64_t map;
+
+  while (len && !errnum)
+    {
+      off = blkoff (SUPERBLOCK, filepos);
+      logno = lblkno (SUPERBLOCK, filepos);
+      size = blksize (SUPERBLOCK, INODE_UFS2, logno);
+
+      if ((map = block_map (logno)) < 0)
+	break; 
+
+      size -= off;
+
+      if (size > len)
+	size = len;
+
+      disk_read_func = disk_read_hook;
+
+      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
+
+      disk_read_func = NULL;
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+int
+ufs2_dir (char *dirname)
+{
+  char *rest, ch;
+  int block, off, loc, ino = ROOTINO;
+  int64_t map;
+  struct direct *dp;
+
+/* main loop to find destination inode */
+loop:
+
+  /* load current inode (defaults to the root inode) */
+
+    if (!devread (fsbtodb (SUPERBLOCK, ino_to_fsba (SUPERBLOCK, ino)),
+	    ino % (SUPERBLOCK->fs_inopb) * sizeof (struct ufs2_dinode),
+	    sizeof (struct ufs2_dinode), (char *) INODE_UFS2))
+		    return 0;			/* XXX what return value? */
+
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+
+  if (!*dirname || isspace (*dirname))
+    {
+      if ((INODE_UFS2->di_mode & IFMT) != IFREG)
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+
+      filemax = INODE_UFS2->di_size;
+
+      /* incomplete implementation requires this! */
+      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
+      return 1;
+    }
+
+  /* continue with file/directory name interpretation */
+
+  while (*dirname == '/')
+    dirname++;
+
+  if (!(INODE_UFS2->di_size) || ((INODE_UFS2->di_mode & IFMT) != IFDIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+
+  *rest = 0;
+  loc = 0;
+
+  /* loop for reading a the entries in a directory */
+
+  do
+    {
+      if (loc >= INODE_UFS2->di_size)
+	{
+	  if (print_possibilities < 0)
+	    return 1;
+
+	  errnum = ERR_FILE_NOT_FOUND;
+	  *rest = ch;
+	  return 0;
+	}
+
+      if (!(off = blkoff (SUPERBLOCK, loc)))
+	{
+	  block = lblkno (SUPERBLOCK, loc);
+
+	  if ((map = block_map (block)) < 0
+	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
+			   blksize (SUPERBLOCK, INODE_UFS2, block),
+			   (char *) FSYS_BUF))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      *rest = ch;
+	      return 0;
+	    }
+	}
+
+      dp = (struct direct *) (FSYS_BUF + off);
+      loc += dp->d_reclen;
+
+#ifndef STAGE1_5
+      if (dp->d_ino && print_possibilities && ch != '/'
+	  && (!*dirname || substring (dirname, dp->d_name) <= 0))
+	{
+	  if (print_possibilities > 0)
+	    print_possibilities = -print_possibilities;
+
+	  print_a_completion (dp->d_name);
+	}
+#endif /* STAGE1_5 */
+    }
+  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
+			|| (print_possibilities && ch != '/')));
+
+  /* only get here if we have a matching directory entry */
+
+  ino = dp->d_ino;
+  *(dirname = rest) = ch;
+
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+int
+ufs2_embed (int *start_sector, int needed_sectors)
+{
+  /* XXX: I don't know if this is really correct. Someone who is
+     familiar with BSD should check for this.  */
+  if (needed_sectors > 14)
+    return 0;
+  
+  *start_sector = 1;
+#if 1
+  /* FIXME: Disable the embedding in FFS until someone checks if
+     the code above is correct.  */
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+#endif /* FSYS_UFS2 */
diff -ruN stage2/shared.h.orig stage2/shared.h
--- stage2/shared.h.orig	Sat Apr 24 20:49:07 2004
+++ stage2/shared.h	Sat Apr 24 20:49:16 2004
@@ -205,6 +205,7 @@
 #define STAGE2_ID_VSTAFS_STAGE1_5	6
 #define STAGE2_ID_JFS_STAGE1_5		7
 #define STAGE2_ID_XFS_STAGE1_5		8
+#define STAGE2_ID_UFS2_STAGE1_5         9
 
 #ifndef STAGE1_5
 # define STAGE2_ID	STAGE2_ID_STAGE2
@@ -225,6 +226,8 @@
 #  define STAGE2_ID	STAGE2_ID_JFS_STAGE1_5
 # elif defined(FSYS_XFS)
 #  define STAGE2_ID	STAGE2_ID_XFS_STAGE1_5
+# elif defined(FSYS_UFS2)
+#  define STAGE2_ID	STAGE2_ID_UFS2_STAGE1_5
 # else
 #  error "unknown Stage 2"
 # endif
diff -ruN stage2/size_test.orig stage2/size_test
--- stage2/size_test.orig	Sat Apr 24 20:49:07 2004
+++ stage2/size_test	Sat Apr 24 20:49:16 2004
@@ -40,6 +40,8 @@
 # The bootloader area of a FFS partition is 14 sectors.
 check ffs_stage1_5 7168
 
+check ufs2_stage1_5 7168
+
 # Stage 1.5 can be installed in the sectors immediately after MBR in the
 # first cylinder, so the size is (63 - 1) sectors.
 check fat_stage1_5 31744
diff -ruN stage2/ufs2.h.orig stage2/ufs2.h
--- stage2/ufs2.h.orig	Thu Jan  1 03:00:00 1970
+++ stage2/ufs2.h	Sat Apr 24 20:49:31 2004
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * Copyright (c) 1982, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)dinode.h	8.3 (Berkeley) 1/21/94
+ * $FreeBSD: /tmp/pcvs/ports/sysutils/grub/files/Attic/patch-ufs2,v 1.2 2004-06-06 13:31:35 pav Exp $
+ */
+
+#ifndef _GRUB_UFS2_H_
+#define _GRUB_UFS2_H_
+
+typedef signed char            int8_t;
+typedef signed short           int16_t;
+typedef signed int             int32_t;
+typedef signed long long int   int64_t;
+typedef unsigned char          uint8_t;
+typedef unsigned short         uint16_t;
+typedef unsigned int           uint32_t;
+typedef unsigned long long int uint64_t;
+
+typedef uint8_t                u_char;
+typedef uint32_t               u_int;
+
+typedef uint8_t                u_int8_t;
+typedef uint16_t               u_int16_t;
+typedef uint32_t               u_int32_t;
+typedef uint64_t               u_int64_t;
+
+/*
+ * __uint* constants already defined in
+ * FreeBSD's /usr/include/machine/_types.h
+ */
+#if !defined(_MACHINE__TYPES_H_) && !defined(_MACHINE_ANSI_H_)
+typedef uint8_t                __uint8_t;
+typedef uint16_t               __uint16_t;
+typedef uint32_t               __uint32_t;
+typedef uint64_t               __uint64_t;
+#endif /* !_MACHINE__TYPES_H_ && !_MACHINE_ANSI_H_ */
+
+#define i_size di_size
+
+
+#define DEV_BSIZE 512
+
+/*
+ * The root inode is the root of the filesystem.  Inode 0 can't be used for
+ * normal purposes and historically bad blocks were linked to inode 1, thus
+ * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
+ * numerous dump tapes make this assumption, so we are stuck with it).
+ */
+#define	ROOTINO	((ino_t)2)
+
+/*
+ * The size of physical and logical block numbers and time fields in UFS.
+ */
+typedef int32_t ufs1_daddr_t;
+typedef	int64_t	ufs2_daddr_t;
+typedef int64_t ufs_lbn_t;
+typedef int64_t ufs_time_t;
+
+/* inode number */
+typedef __uint32_t      ino_t;
+
+/* File permissions. */
+#define	IEXEC		0000100		/* Executable. */
+#define	IWRITE		0000200		/* Writeable. */
+#define	IREAD		0000400		/* Readable. */
+#define	ISVTX		0001000		/* Sticky bit. */
+#define	ISGID		0002000		/* Set-gid. */
+#define	ISUID		0004000		/* Set-uid. */
+
+/* File types. */
+#define	IFMT		0170000		/* Mask of file type. */
+#define	IFIFO		0010000		/* Named pipe (fifo). */
+#define	IFCHR		0020000		/* Character device. */
+#define	IFDIR		0040000		/* Directory file. */
+#define	IFBLK		0060000		/* Block device. */
+#define	IFREG		0100000		/* Regular file. */
+#define	IFLNK		0120000		/* Symbolic link. */
+#define	IFSOCK		0140000		/* UNIX domain socket. */
+#define	IFWHT		0160000		/* Whiteout. */
+
+/*
+ * A dinode contains all the meta-data associated with a UFS2 file.
+ * This structure defines the on-disk format of a dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+
+#define	NXADDR	2			/* External addresses in inode. */
+#define	NDADDR	12			/* Direct addresses in inode. */
+#define	NIADDR	3			/* Indirect addresses in inode. */
+
+struct ufs1_dinode {
+	u_int16_t       di_mode;        /*   0: IFMT, permissions; see below. */
+	int16_t         di_nlink;       /*   2: File link count. */
+	union {
+		u_int16_t oldids[2];    /*   4: Ffs: old user and group ids. */
+	} di_u;
+	u_int64_t       di_size;        /*   8: File byte count. */
+	int32_t         di_atime;       /*  16: Last access time. */
+	int32_t         di_atimensec;   /*  20: Last access time. */
+	int32_t         di_mtime;       /*  24: Last modified time. */
+	int32_t         di_mtimensec;   /*  28: Last modified time. */
+	int32_t         di_ctime;       /*  32: Last inode change time. */
+	int32_t         di_ctimensec;   /*  36: Last inode change time. */
+	ufs1_daddr_t    di_db[NDADDR];  /*  40: Direct disk blocks. */
+	ufs1_daddr_t    di_ib[NIADDR];  /*  88: Indirect disk blocks. */
+	u_int32_t       di_flags;       /* 100: Status flags (chflags). */
+	int32_t         di_blocks;      /* 104: Blocks actually held. */
+	int32_t         di_gen;         /* 108: Generation number. */
+	u_int32_t       di_uid;         /* 112: File owner. */
+	u_int32_t       di_gid;         /* 116: File group. */
+	int32_t         di_spare[2];    /* 120: Reserved; currently unused */
+};
+
+struct ufs2_dinode {
+	u_int16_t	di_mode;	/*   0: IFMT, permissions; see below. */
+	int16_t		di_nlink;	/*   2: File link count. */
+	u_int32_t	di_uid;		/*   4: File owner. */
+	u_int32_t	di_gid;		/*   8: File group. */
+	u_int32_t	di_blksize;	/*  12: Inode blocksize. */
+	u_int64_t	di_size;	/*  16: File byte count. */
+	u_int64_t	di_blocks;	/*  24: Bytes actually held. */
+	ufs_time_t	di_atime;	/*  32: Last access time. */
+	ufs_time_t	di_mtime;	/*  40: Last modified time. */
+	ufs_time_t	di_ctime;	/*  48: Last inode change time. */
+	ufs_time_t	di_birthtime;	/*  56: Inode creation time. */
+	int32_t		di_mtimensec;	/*  64: Last modified time. */
+	int32_t		di_atimensec;	/*  68: Last access time. */
+	int32_t		di_ctimensec;	/*  72: Last inode change time. */
+	int32_t		di_birthnsec;	/*  76: Inode creation time. */
+	int32_t		di_gen;		/*  80: Generation number. */
+	u_int32_t	di_kernflags;	/*  84: Kernel flags. */
+	u_int32_t	di_flags;	/*  88: Status flags (chflags). */
+	int32_t		di_extsize;	/*  92: External attributes block. */
+	ufs2_daddr_t	di_extb[NXADDR];/*  96: External attributes block. */
+	ufs2_daddr_t	di_db[NDADDR];	/* 112: Direct disk blocks. */
+	ufs2_daddr_t	di_ib[NIADDR];	/* 208: Indirect disk blocks. */
+	int64_t		di_spare[3];	/* 232: Reserved; currently unused */
+};
+
+#define	MAXNAMLEN	255
+
+struct	direct {
+	u_int32_t d_ino;		/* inode number of entry */
+	u_int16_t d_reclen;		/* length of this record */
+	u_int8_t  d_type; 		/* file type, see below */
+	u_int8_t  d_namlen;		/* length of string in d_name */
+	char	  d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
+};
+
+/*
+ * File types
+ */
+#define DT_UNKNOWN       0
+#define DT_FIFO          1
+#define DT_CHR           2
+#define DT_DIR           4
+#define DT_BLK           6
+#define DT_REG           8
+#define DT_LNK          10
+#define DT_SOCK         12
+#define DT_WHT          14
+
+/*
+ * Superblock offsets
+ */
+#define SBLOCK_FLOPPY        0
+#define SBLOCK_UFS1       8192
+#define SBLOCK_UFS2      65536
+#define SBLOCK_PIGGY    262144
+#define SBLOCKSIZE        8192
+#define SBLOCKSEARCH \
+	{ SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
+
+#define MAXMNTLEN	512
+
+#define	NOCSPTRS	((128 / sizeof(void *)) - 4)
+
+/*
+ * The maximum number of snapshot nodes that can be associated
+ * with each filesystem. This limit affects only the number of
+ * snapshot files that can be recorded within the superblock so
+ * that they can be found when the filesystem is mounted. However,
+ * maintaining too many will slow the filesystem performance, so
+ * having this limit is a good idea.
+ */
+#define FSMAXSNAP 20
+	
+/*
+ * Per cylinder group information; summarized in blocks allocated
+ * from first cylinder group data blocks.  These blocks have to be
+ * read in from fs_csaddr (size fs_cssize) in addition to the
+ * super block.
+ */
+struct csum {
+	int32_t	cs_ndir;		/* number of directories */
+	int32_t	cs_nbfree;		/* number of free blocks */
+	int32_t	cs_nifree;		/* number of free inodes */
+	int32_t	cs_nffree;		/* number of free frags */
+};
+
+struct csum_total {
+	int64_t	cs_ndir;		/* number of directories */
+	int64_t	cs_nbfree;		/* number of free blocks */
+	int64_t	cs_nifree;		/* number of free inodes */
+	int64_t	cs_nffree;		/* number of free frags */
+	int64_t	cs_numclusters;		/* number of free clusters */
+	int64_t	cs_spare[3];		/* future expansion */
+};
+
+/*
+ * Super block for an FFS filesystem.
+ */
+struct fs {
+	int32_t	 fs_firstfield;		/* historic filesystem linked list, */
+	int32_t	 fs_unused_1;		/*     used for incore super blocks */
+	int32_t	 fs_sblkno;		/* offset of super-block in filesys */
+	int32_t	 fs_cblkno;		/* offset of cyl-block in filesys */
+	int32_t	 fs_iblkno;		/* offset of inode-blocks in filesys */
+	int32_t	 fs_dblkno;		/* offset of first data after cg */
+	int32_t	 fs_old_cgoffset;	/* cylinder group offset in cylinder */
+	int32_t	 fs_old_cgmask;		/* used to calc mod fs_ntrak */
+	int32_t  fs_old_time;		/* last time written */
+	int32_t	 fs_old_size;		/* number of blocks in fs */
+	int32_t	 fs_old_dsize;		/* number of data blocks in fs */
+	int32_t	 fs_ncg;		/* number of cylinder groups */
+	int32_t	 fs_bsize;		/* size of basic blocks in fs */
+	int32_t	 fs_fsize;		/* size of frag blocks in fs */
+	int32_t	 fs_frag;		/* number of frags in a block in fs */
+/* these are configuration parameters */
+	int32_t	 fs_minfree;		/* minimum percentage of free blocks */
+	int32_t	 fs_old_rotdelay;	/* num of ms for optimal next block */
+	int32_t	 fs_old_rps;		/* disk revolutions per second */
+/* these fields can be computed from the others */
+	int32_t	 fs_bmask;		/* ``blkoff'' calc of blk offsets */
+	int32_t	 fs_fmask;		/* ``fragoff'' calc of frag offsets */
+	int32_t	 fs_bshift;		/* ``lblkno'' calc of logical blkno */
+	int32_t	 fs_fshift;		/* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+	int32_t	 fs_maxcontig;		/* max number of contiguous blks */
+	int32_t	 fs_maxbpg;		/* max number of blks per cyl group */
+/* these fields can be computed from the others */
+	int32_t	 fs_fragshift;		/* block to frag shift */
+	int32_t	 fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
+	int32_t	 fs_sbsize;		/* actual size of super block */
+	int32_t	 fs_spare1[2];		/* old fs_csmask */
+					/* old fs_csshift */
+	int32_t	 fs_nindir;		/* value of NINDIR */
+	int32_t	 fs_inopb;		/* value of INOPB */
+	int32_t	 fs_old_nspf;		/* value of NSPF */
+/* yet another configuration parameter */
+	int32_t	 fs_optim;		/* optimization preference, see below */
+	int32_t	 fs_old_npsect;		/* # sectors/track including spares */
+	int32_t	 fs_old_interleave;	/* hardware sector interleave */
+	int32_t	 fs_old_trackskew;	/* sector 0 skew, per track */
+	int32_t	 fs_id[2];		/* unique filesystem id */
+/* sizes determined by number of cylinder groups and their sizes */
+	int32_t	 fs_old_csaddr;		/* blk addr of cyl grp summary area */
+	int32_t	 fs_cssize;		/* size of cyl grp summary area */
+	int32_t	 fs_cgsize;		/* cylinder group size */
+	int32_t	 fs_spare2;		/* old fs_ntrak */
+	int32_t	 fs_old_nsect;		/* sectors per track */
+	int32_t  fs_old_spc;		/* sectors per cylinder */
+	int32_t	 fs_old_ncyl;		/* cylinders in filesystem */
+	int32_t	 fs_old_cpg;		/* cylinders per group */
+	int32_t	 fs_ipg;		/* inodes per group */
+	int32_t	 fs_fpg;		/* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+	struct	csum fs_old_cstotal;	/* cylinder summary information */
+/* these fields are cleared at mount time */
+	int8_t   fs_fmod;		/* super block modified flag */
+	int8_t   fs_clean;		/* filesystem is clean flag */
+	int8_t 	 fs_ronly;		/* mounted read-only flag */
+	int8_t   fs_old_flags;		/* old FS_ flags */
+	u_char	 fs_fsmnt[MAXMNTLEN];	/* name mounted on */
+/* these fields retain the current block allocation info */
+	int32_t	 fs_cgrotor;		/* last cg searched */
+	void 	*fs_ocsp[NOCSPTRS];	/* padding; was list of fs_cs buffers */
+	u_int8_t *fs_contigdirs;	/* # of contiguously allocated dirs */
+	struct	csum *fs_csp;		/* cg summary info buffer for fs_cs */
+	int32_t	*fs_maxcluster;		/* max cluster in each cyl group */
+	u_int	*fs_active;		/* used by snapshots to track fs */
+	int32_t	 fs_old_cpc;		/* cyl per cycle in postbl */
+	int32_t	 fs_maxbsize;		/* maximum blocking factor permitted */
+	int64_t	 fs_sparecon64[17];	/* old rotation block list head */
+	int64_t	 fs_sblockloc;		/* byte offset of standard superblock */
+	struct	csum_total fs_cstotal;	/* cylinder summary information */
+	ufs_time_t fs_time;		/* last time written */
+	int64_t	 fs_size;		/* number of blocks in fs */
+	int64_t	 fs_dsize;		/* number of data blocks in fs */
+	ufs2_daddr_t fs_csaddr;		/* blk addr of cyl grp summary area */
+	int64_t	 fs_pendingblocks;	/* blocks in process of being freed */
+	int32_t	 fs_pendinginodes;	/* inodes in process of being freed */
+	int32_t	 fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
+	int32_t	 fs_avgfilesize;	/* expected average file size */
+	int32_t	 fs_avgfpdir;		/* expected # of files per directory */
+	int32_t	 fs_save_cgsize;	/* save real cg size to use fs_bsize */
+	int32_t	 fs_sparecon32[26];	/* reserved for future constants */
+	int32_t  fs_flags;		/* see FS_ flags below */
+	int32_t	 fs_contigsumsize;	/* size of cluster summary array */ 
+	int32_t	 fs_maxsymlinklen;	/* max length of an internal symlink */
+	int32_t	 fs_old_inodefmt;	/* format of on-disk inodes */
+	u_int64_t fs_maxfilesize;	/* maximum representable file size */
+	int64_t	 fs_qbmask;		/* ~fs_bmask for use with 64-bit size */
+	int64_t	 fs_qfmask;		/* ~fs_fmask for use with 64-bit size */
+	int32_t	 fs_state;		/* validate fs_clean field */
+	int32_t	 fs_old_postblformat;	/* format of positional layout tables */
+	int32_t	 fs_old_nrpos;		/* number of rotational positions */
+	int32_t	 fs_spare5[2];		/* old fs_postbloff */
+					/* old fs_rotbloff */
+	int32_t	 fs_magic;		/* magic number */
+};
+
+/*
+ * Filesystem identification
+ */
+#define FS_UFS1_MAGIC   0x011954        /* UFS1 fast filesystem magic number */
+#define	FS_UFS2_MAGIC	0x19540119	/* UFS2 fast filesystem magic number */
+
+/*
+ * Turn filesystem block numbers into disk block addresses.
+ * This maps filesystem blocks to device size blocks.
+ */
+#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
+#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
+
+/*
+ * Cylinder group macros to locate things in cylinder groups.
+ * They calc filesystem addresses of cylinder group data structures.
+ */
+#define	cgbase(fs, c)	((ufs2_daddr_t)((fs)->fs_fpg * (c)))
+#define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
+#define cgstart(fs, c)							\
+       ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) :		\
+       (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask))))
+
+/*
+ * Macros for handling inode numbers:
+ *     inode number to filesystem block offset.
+ *     inode number to cylinder group number.
+ *     inode number to filesystem block address.
+ */
+#define	ino_to_cg(fs, x)	((x) / (fs)->fs_ipg)
+#define	ino_to_fsba(fs, x)						\
+	((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +			\
+	    (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
+#define	ino_to_fsbo(fs, x)	((x) % INOPB(fs))
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
+	((loc) & (fs)->fs_qbmask)
+
+/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
+#define smalllblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
+	((blk) << (fs)->fs_bshift)
+
+
+#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
+	((loc) >> (fs)->fs_bshift)
+
+#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
+	(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
+
+#define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
+	((frags) >> (fs)->fs_fragshift)
+#define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
+	((blks) << (fs)->fs_fragshift)
+#define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
+	((fsb) & ((fs)->fs_frag - 1))
+#define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
+	((fsb) &~ ((fs)->fs_frag - 1))
+
+/*
+ * Determining the size of a file block in the filesystem.
+ */
+#define blksize(fs, ip, lbn) \
+	(((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
+	    ? (fs)->fs_bsize \
+	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define sblksize(fs, size, lbn) \
+	(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
+	  ? (fs)->fs_bsize \
+	  : (fragroundup(fs, blkoff(fs, (size)))))
+
+
+/*
+ * Number of inodes in a secondary storage block/fragment.
+ */
+#define	INOPB(fs)	((fs)->fs_inopb)
+#define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * Number of indirects in a filesystem block.
+ */
+#define	NINDIR(fs)	((fs)->fs_nindir)
+
+#define FS_UNCLEAN    0x01      /* filesystem not clean at mount */
+#define FS_DOSOFTDEP  0x02      /* filesystem using soft dependencies */
+#define FS_NEEDSFSCK  0x04      /* filesystem needs sync fsck before mount */
+#define FS_INDEXDIRS  0x08      /* kernel supports indexed directories */
+#define FS_ACLS       0x10      /* file system has ACLs enabled */
+#define FS_MULTILABEL 0x20      /* file system is MAC multi-label */
+#define FS_FLAGS_UPDATED 0x80   /* flags have been moved to new location */
+
+#endif /* _GRUB_UFS2_H_ */
OpenPOWER on IntegriCloud