2 * Copyright (c) 1980, 1986 The Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 #include <afsconfig.h>
19 #include <afs/param.h>
27 #if defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
34 #define msgprintf vfscklogprintf
35 extern vfscklogprintf();
41 #include <sys/vnode.h>
42 #include <sys/mount.h>
43 #include <ufs/inode.h>
50 #else /* AFS_OSF_ENV */
51 #ifdef AFS_VFSINCL_ENV
52 #include <sys/vnode.h>
54 #include <sys/fs/ufs_inode.h>
55 #include <sys/fs/ufs_fs.h>
57 #include <sys/fs/ufs_fsdir.h>
59 #include <sys/fs/ufs_mount.h>
61 #include <ufs/inode.h>
64 #else /* AFS_VFSINCL_ENV */
65 #include <sys/inode.h>
67 #define LONGFILENAMES 1
68 #include <sys/sysmacros.h>
72 #endif /* AFS_VFSINCL_ENV */
73 #endif /* AFS_OSF_ENV */
77 #include <sys/mntent.h>
78 #include <sys/vfstab.h>
81 #include <afs/osi_inode.h>
87 #define altsblock (*asblk.b_un.b_fs)
88 #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
91 * The size of a cylinder group is calculated by CGSIZE. The maximum size
92 * is limited by the fact that cylinder groups are at most one block.
93 * Its size is derived from the size of the maps maintained in the
94 * cylinder group and the (struct cg) size.
97 /* base cg */ (sizeof(struct cg) + \
98 /* blktot size */ (fs)->fs_cpg * sizeof(afs_int32) + \
99 /* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \
100 /* inode map */ howmany((fs)->fs_ipg, NBBY) + \
101 /* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY))
103 struct disklabel
*getdisklabel();
109 long cg
, size
, asked
, i
, j
;
111 struct disklabel
*lp
;
114 #if defined(AFS_SUN5_ENV)
115 static char sname
[MAXPATHLEN
];
118 /* reset static variables that may have been damaged by parent fork */
122 #if defined(ACLS) && defined(AFS_HPUX_ENV)
126 if (stat("/", &statb
) < 0)
127 errexit("Can't stat root\n");
128 rootdev
= statb
.st_dev
;
129 #if defined(AFS_SUN5_ENV)
130 strncpy(sname
, dev
, sizeof(sname
));
132 if (stat(sname
, &statb
) < 0) {
134 msgprintf("Can't stat %s\n", sname
);
136 if (stat(dev
, &statb
) < 0) {
138 printf("Can't stat %s\n", dev
);
143 if ((statb
.st_mode
& S_IFMT
) == S_IFDIR
) {
147 if ((fp
= fopen(VFSTAB
, "r")) == NULL
) {
148 pfatal("Can't open %s file\n", VFSTAB
);
151 while (!getvfsent(fp
, &vtab
)) {
152 if (vtab
.vfs_mountp
&& !strcmp(vtab
.vfs_mountp
, sname
)) {
153 strcpy(sname
, vtab
.vfs_special
);
155 char *s
= vtab
.vfs_fsckdev
;
164 if ((statb
.st_mode
& S_IFMT
) != S_IFBLK
165 && (statb
.st_mode
& S_IFMT
) != S_IFCHR
) {
166 pfatal("device is not a block or character device");
167 if (reply("file is not a block or character device; OK") == 0)
175 printf("%s is mounted, fsck on BLOCK device ignored\n", sname
);
179 char bname
[MAXPATHLEN
], *tname
;
181 strcpy(bname
, sname
);
182 tname
= unrawname(bname
);
183 if (stat(tname
, &statb
) < 0) {
184 pfatal("Can't stat %s\n", tname
);
190 hotroot
= is_hotroot(dev
);
193 * The following code is added to improve usability of fsck.
194 * we need to give user a warning if the device being checked is
195 * a hotroot, a mounted file system, or a swap device.
197 * 1) if nflag is set, it's pretty safe to fsck the target dev
198 * 2) if the target device is a swap, exit
199 * 3) if hotroot is set, and "-F" is not specified prompt the
200 * user and wait for reply
201 * 4) if the target is a mounted file system, and "-F" is not
202 * specified, prompt the user and wait for reply
203 * 5) if the "-m" is specifed, do no prompting since only a sanity
204 * check is being done. important during booting
206 * Caveat: There is no way to tell the current run level, so we cannot
207 * tell whether or not we are in single user mode.
211 struct stat st_mounted
;
215 mounted
= is_mounted(dev
, &st_mounted
);
217 swap
= is_swap(st_mounted
.st_rdev
);
226 msgprintf("fsck: %s: root file system", dev
);
228 msgprintf(" (CONTINUING)\n");
230 if (!freply("continue (y/n)"))
233 } else if (mounted
) {
234 msgprintf("fsck: %s: mounted file system", dev
);
236 msgprintf(" (CONTINUING)\n");
238 if (!freply("continue (y/n)"))
242 msgprintf("fsck: %s: swap device\n", dev
);
244 msgprintf(" (CONTINUING)\n");
246 if (!freply("continue (y/n)"))
252 if (rootdev
== statb
.st_rdev
)
254 if ((fsreadfd
= open(dev
, O_RDONLY
)) < 0) {
256 msgprintf("Can't open %s\n", dev
);
260 msgprintf("** %s", dev
);
261 if (nflag
|| (fswritefd
= open(dev
, O_WRONLY
)) < 0) {
263 msgprintf(" (NO WRITE)");
266 pfatal("NO WRITE ACCESS");
272 #if defined(AFS_HPUX101_ENV)
273 setup_all_block_seek();
277 printf(" pid %d\n", getpid());
278 if (debug
&& (hotroot
|| mountedfs
)) {
279 printf("** %s", sname
);
281 printf(" is root fs");
286 printf(" is mounted");
295 sblk
.b_un
.b_buf
= malloc(SBSIZE
+ ALPHA_EXT
);
296 asblk
.b_un
.b_buf
= malloc(SBSIZE
+ ALPHA_EXT
);
298 sblk
.b_un
.b_buf
= malloc(SBSIZE
);
299 asblk
.b_un
.b_buf
= malloc(SBSIZE
);
301 if (sblk
.b_un
.b_buf
== NULL
|| asblk
.b_un
.b_buf
== NULL
)
302 errexit("cannot allocate space for superblock\n");
303 dev_bsize
= secsize
= DEV_BSIZE
;
306 * Read in the superblock, looking for alternates if necessary
308 if (readsb(1) == 0) {
309 if (bflag
|| preen
|| calcsb(dev
, fsreadfd
, &proto
) == 0)
311 if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
313 for (cg
= 0; cg
< proto
.fs_ncg
; cg
++) {
314 bflag
= fsbtodb(&proto
, cgsblock(&proto
, cg
));
318 if (cg
>= proto
.fs_ncg
) {
319 msgprintf("%s %s\n%s %s\n%s %s\n",
320 "SEARCH FOR ALTERNATE SUPER-BLOCK",
321 "FAILED. YOU MUST USE THE",
322 "-b OPTION TO FSCK TO SPECIFY THE",
323 "LOCATION OF AN ALTERNATE",
324 "SUPER-BLOCK TO SUPPLY NEEDED",
325 "INFORMATION; SEE fsck(8).");
328 pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag
);
330 maxfsblock
= sblock
.fs_size
;
331 maxino
= sblock
.fs_ncg
* sblock
.fs_ipg
;
333 * Check and potentially fix certain fields in the super block.
335 if (sblock
.fs_optim
!= FS_OPTTIME
&& sblock
.fs_optim
!= FS_OPTSPACE
) {
336 pfatal("UNDEFINED OPTIMIZATION IN SUPERBLOCK");
337 if (reply("SET TO DEFAULT") == 1) {
338 sblock
.fs_optim
= FS_OPTTIME
;
342 if ((sblock
.fs_minfree
< 0 || sblock
.fs_minfree
> 99)) {
343 pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK", sblock
.fs_minfree
);
344 if (reply("SET TO DEFAULT") == 1) {
345 sblock
.fs_minfree
= 10;
351 * Do we need to continue ?
353 if (pclean
&& sblock
.fs_clean
== FS_CLEAN
)
355 if (pclean
&& hotroot
&& sblock
.fs_clean
== FS_OK
)
359 # ifndef AFS_SUN59_ENV
360 if (sblock
.fs_interleave
< 1) {
361 pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK", sblock
.fs_interleave
);
362 sblock
.fs_interleave
= 1;
364 msgprintf(" (FIXED)\n");
365 if (preen
|| reply("SET TO DEFAULT") == 1) {
370 # endif /* AFS_SUN59_ENV */
371 #endif /* AFS_NEWCG_ENV */
373 if (sblock
.fs_npsect
< sblock
.fs_nsect
) {
374 pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK", sblock
.fs_npsect
);
375 sblock
.fs_npsect
= sblock
.fs_nsect
;
377 msgprintf(" (FIXED)\n");
378 if (preen
|| reply("SET TO DEFAULT") == 1) {
383 #endif /* AFS_NEWCG_ENV */
386 if (sblock
.fs_postblformat
== FS_42POSTBLFMT
) {
388 * Requested to convert from old format to new format
391 pwarn("CONVERTING TO NEW FILE SYSTEM FORMAT\n");
392 else if (!reply("CONVERT TO NEW FILE SYSTEM FORMAT"))
395 sblock
.fs_postblformat
= FS_DYNAMICPOSTBLFMT
;
397 sblock
.fs_postbloff
=
398 (char *)(&sblock
.fs_opostbl
[0][0]) -
399 (char *)(&sblock
.fs_link
);
401 &sblock
.fs_space
[0] - (u_char
*) (&sblock
.fs_link
);
402 sblock
.fs_cgsize
= fragroundup(&sblock
, CGSIZE(&sblock
));
404 * Planning now for future expansion.
406 # if (BYTE_ORDER == BIG_ENDIAN)
407 sblock
.fs_qbmask
.val
[0] = 0;
408 sblock
.fs_qbmask
.val
[1] = ~sblock
.fs_bmask
;
409 sblock
.fs_qfmask
.val
[0] = 0;
410 sblock
.fs_qfmask
.val
[1] = ~sblock
.fs_fmask
;
411 # endif /* BIG_ENDIAN */
412 # if (BYTE_ORDER == LITTLE_ENDIAN)
413 sblock
.fs_qbmask
.val
[0] = ~sblock
.fs_bmask
;
414 sblock
.fs_qbmask
.val
[1] = 0;
415 sblock
.fs_qfmask
.val
[0] = ~sblock
.fs_fmask
;
416 sblock
.fs_qfmask
.val
[1] = 0;
417 # endif /* LITTLE_ENDIAN */
418 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
420 sblock
.fs_state
= FSOKAY
- sblock
.fs_time
; /* make mountable */
422 fs_set_state(&sblock
, FSOKAY
- sblock
.fs_time
);
424 sblock
.fs_clean
= FSCLEAN
;
428 } else if (sblock
.fs_postblformat
== FS_DYNAMICPOSTBLFMT
) {
430 * Requested to convert from new format to old format
432 if (sblock
.fs_nrpos
!= 8 || sblock
.fs_ipg
> 2048
433 || sblock
.fs_cpg
> 32 || sblock
.fs_cpc
> 16) {
434 msgprintf("PARAMETERS OF CURRENT FILE SYSTEM DO NOT\n\t");
435 msgprintf("ALLOW CONVERSION TO OLD FILE SYSTEM FORMAT\n");
440 pwarn("CONVERTING TO OLD FILE SYSTEM FORMAT\n");
441 else if (!reply("CONVERT TO OLD FILE SYSTEM FORMAT"))
444 sblock
.fs_postblformat
= FS_42POSTBLFMT
;
447 sizeof(struct ocg
) + howmany(sblock
.fs_fpg
,
449 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
451 sblock
.fs_npsect
= 0;
452 # ifndef AFS_SUN59_ENV
453 sblock
.fs_interleave
= 0;
455 sblock
.fs_state
= FSOKAY
- sblock
.fs_time
; /* make mountable */
457 fs_set_state(&sblock
, FSOKAY
- sblock
.fs_time
);
459 sblock
.fs_clean
= FSCLEAN
;
464 errexit("UNKNOWN FILE SYSTEM FORMAT\n");
467 #endif /* AFS_NEWCG_ENV */
469 memcpy((char *)&altsblock
, (char *)&sblock
, (int)sblock
.fs_sbsize
);
470 flush(fswritefd
, &asblk
);
473 * read in the summary info.
476 #if defined(AFS_SUN5_ENV)
479 sip
= calloc(1, sblock
.fs_cssize
);
480 sblock
.fs_u
.fs_csp
= (struct csum
*)sip
;
481 for (i
= 0, j
= 0; i
< sblock
.fs_cssize
; i
+= sblock
.fs_bsize
, j
++) {
483 sblock
.fs_cssize
- i
<
484 sblock
.fs_bsize
? sblock
.fs_cssize
- i
: sblock
.fs_bsize
;
487 fsbtodb(&sblock
, sblock
.fs_csaddr
+ j
* sblock
.fs_frag
),
488 size
) != 0 && !asked
) {
489 pfatal("BAD SUMMARY INFORMATION");
490 if (reply("CONTINUE") == 0)
497 #else /* AFS_SUN5_ENV */
498 #if defined(AFS_HPUX110_ENV)
499 size
= fragroundup(&sblock
, sblock
.fs_cssize
);
500 sblock
.fs_csp
= calloc(1, (unsigned)size
);
502 (fsreadfd
, (char *)sblock
.fs_csp
, fsbtodb(&sblock
, sblock
.fs_csaddr
),
503 size
) != 0) && !asked
) {
504 pfatal("BAD SUMMARY INFORMATION");
505 if (reply("CONTINUE") == 0)
509 #else /* AFS_HPUX110_ENV */
510 #if defined(AFS_HPUX101_ENV)
513 size
= fragroundup(&sblock
, sblock
.fs_cssize
);
515 for (i
= 0, j
= 0; i
< sblock
.fs_cssize
; i
+= sblock
.fs_bsize
, j
++) {
517 sblock
.fs_cssize
- i
<
518 sblock
.fs_bsize
? sblock
.fs_cssize
- i
: sblock
.fs_bsize
;
519 #endif /* AFS_HPUX101_ENV */
520 sblock
.fs_csp
[j
] = calloc(1, (unsigned)size
);
522 (fsreadfd
, (char *)sblock
.fs_csp
[j
],
523 fsbtodb(&sblock
, sblock
.fs_csaddr
+ j
* sblock
.fs_frag
),
524 size
) != 0 && !asked
) {
525 pfatal("BAD SUMMARY INFORMATION");
526 if (reply("CONTINUE") == 0)
535 #endif /* else AFS_HPUX110_ENV */
536 #endif /* else AFS_SUN5_ENV */
538 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
540 * if not forced, preening, not converting, and is clean; stop checking
543 if ((fflag
== 0) && preen
&& (isconvert
== 0)
544 && (FSOKAY
== (sblock
.fs_state
+ sblock
.fs_time
)) &&
546 if (preen
&& (isconvert
== 0)
547 && (FSOKAY
== (fs_get_state(&sblock
) + sblock
.fs_time
)) &&
549 ((sblock
.fs_clean
== FSCLEAN
) || (sblock
.fs_clean
== FSSTABLE
))) {
556 if (!fflag
&& !bflag
&& !nflag
&& !hotroot
&& sblock
.fs_clean
== FS_CLEAN
558 pwarn("Clean file system - skipping fsck\n");
561 #endif /* AFS_OSF_ENV */
564 * allocate and initialize the necessary maps
566 bmapsize
= roundup(howmany(maxfsblock
, NBBY
), sizeof(short));
567 blockmap
= calloc((unsigned)bmapsize
, sizeof(char));
568 if (blockmap
== NULL
) {
569 msgprintf("cannot alloc %d bytes for blockmap\n", bmapsize
);
572 statemap
= calloc((unsigned)(maxino
+ 1), sizeof(char));
573 if (statemap
== NULL
) {
574 msgprintf("cannot alloc %d bytes for statemap\n", maxino
+ 1);
577 lncntp
= calloc((unsigned)(maxino
+ 1), sizeof(short));
578 if (lncntp
== NULL
) {
579 msgprintf("cannot alloc %d bytes for lncntp\n",
580 (maxino
+ 1) * sizeof(short));
593 * Read in the super block and its summary info.
599 daddr_t super
= bflag
? bflag
: SBOFF
/ dev_bsize
;
600 #else /* AFS_NEWCG_ENV */
601 daddr_t super
= bflag
? bflag
: SBLOCK
;
603 #endif /* AFS_NEWCG_ENV */
604 if (bread(fsreadfd
, (char *)&sblock
, super
, (long)SBSIZE
) != 0)
607 sblk
.b_size
= SBSIZE
;
609 * run a few consistency checks of the super block
612 #if defined(FD_FSMAGIC)
613 if ((sblock
.fs_magic
!= FS_MAGIC
) && (sblock
.fs_magic
!= FS_MAGIC_LFN
)
614 && (sblock
.fs_magic
!= FD_FSMAGIC
)
615 #if defined(AFS_HPUX101_ENV)
616 && (sblock
.fs_magic
!= FD_FSMAGIC_2
)
619 #else /* not new magic number */
620 if ((sblock
.fs_magic
!= FS_MAGIC
) && (sblock
.fs_magic
!= FS_MAGIC_LFN
))
621 #endif /* new magic number */
623 if (sblock
.fs_magic
!= FS_MAGIC
)
626 badsb(listerr
, "MAGIC NUMBER WRONG");
629 if (sblock
.fs_ncg
< 1) {
630 badsb(listerr
, "NCG OUT OF RANGE");
633 if (sblock
.fs_cpg
< 1) {
634 printf("fs_cpg= %d\n", sblock
.fs_cpg
);
635 badsb(listerr
, "CPG OUT OF RANGE");
638 if (sblock
.fs_ncg
* sblock
.fs_cpg
< sblock
.fs_ncyl
639 || (sblock
.fs_ncg
- 1) * sblock
.fs_cpg
>= sblock
.fs_ncyl
) {
640 badsb(listerr
, "NCYL LESS THAN NCG*CPG");
643 if (sblock
.fs_sbsize
> SBSIZE
) {
644 badsb(listerr
, "SIZE PREPOSTEROUSLY LARGE");
648 * Compute block size that the filesystem is based on,
649 * according to fsbtodb, and adjust superblock block number
650 * so we can tell if this is an alternate later.
653 dev_bsize
= sblock
.fs_fsize
/ fsbtodb(&sblock
, 1);
654 sblk
.b_bno
= super
/ dev_bsize
;
656 * Set all possible fields that could differ, then do check
657 * of whole super block against an alternate super block.
658 * When an alternate super-block is specified this check is skipped.
660 getblk(&asblk
, cgsblock(&sblock
, sblock
.fs_ncg
- 1), sblock
.fs_sbsize
);
667 altsblock
.fs_link
= sblock
.fs_link
;
668 #ifdef STRUCT_FS_HAS_FS_ROLLED
669 altsblock
.fs_rolled
= sblock
.fs_rolled
;
671 altsblock
.fs_rlink
= sblock
.fs_rlink
;
673 altsblock
.fs_time
= sblock
.fs_time
;
674 altsblock
.fs_cstotal
= sblock
.fs_cstotal
;
675 altsblock
.fs_cgrotor
= sblock
.fs_cgrotor
;
676 altsblock
.fs_fmod
= sblock
.fs_fmod
;
678 altsblock
.fs_clean
= sblock
.fs_clean
;
679 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
681 altsblock
.fs_state
= sblock
.fs_state
;
683 fs_set_state(&altsblock
, fs_get_state(&sblock
));
686 altsblock
.fs_ronly
= sblock
.fs_ronly
;
687 altsblock
.fs_flags
= sblock
.fs_flags
;
688 altsblock
.fs_maxcontig
= sblock
.fs_maxcontig
;
689 altsblock
.fs_minfree
= sblock
.fs_minfree
;
690 altsblock
.fs_optim
= sblock
.fs_optim
;
691 altsblock
.fs_rotdelay
= sblock
.fs_rotdelay
;
692 altsblock
.fs_maxbpg
= sblock
.fs_maxbpg
;
693 #if !defined(__alpha) && !defined(AFS_SUN5_ENV)
694 #if !defined(AFS_HPUX110_ENV)
695 /* HPUX110 will use UpdateAlternateSuper() below */
696 memcpy((char *)altsblock
.fs_csp
, (char *)sblock
.fs_csp
,
697 sizeof sblock
.fs_csp
);
698 #endif /* ! AFS_HPUX110_ENV */
699 #endif /* ! __alpha */
700 #if defined(AFS_SUN5_ENV)
701 memcpy((char *)altsblock
.fs_u
.fs_csp_pad
, (char *)sblock
.fs_u
.fs_csp_pad
,
702 sizeof(sblock
.fs_u
.fs_csp_pad
));
704 memcpy((char *)altsblock
.fs_fsmnt
, (char *)sblock
.fs_fsmnt
,
705 sizeof sblock
.fs_fsmnt
);
707 memcpy((char *)altsblock
.fs_sparecon
, (char *)sblock
.fs_sparecon
,
708 sizeof sblock
.fs_sparecon
);
711 * The following should not have to be copied.
713 altsblock
.fs_fsbtodb
= sblock
.fs_fsbtodb
;
715 # if defined(AFS_SUN59_ENV) && defined(FS_SI_OK)
716 /* fs_interleave replaced with fs_si and FS_SI_OK defined in */
717 /* ufs_fs.h version 2.63 don't need to compare either */
718 altsblock
.fs_si
= sblock
.fs_si
;
720 altsblock
.fs_interleave
= sblock
.fs_interleave
;
722 altsblock
.fs_npsect
= sblock
.fs_npsect
;
723 altsblock
.fs_nrpos
= sblock
.fs_nrpos
;
724 #endif /* AFS_NEWCG_ENV */
725 #if defined(AFS_HPUX110_ENV)
726 UpdateAlternateSuper(&sblock
, &altsblock
);
727 #endif /* AFS_HPUX110_ENV */
728 if (memcmp((char *)&sblock
, (char *)&altsblock
, (int)sblock
.fs_sbsize
)) {
731 ((char *)&sblock
.fs_blank
[0], (char *)&altsblock
.fs_blank
[0],
732 MAXCSBUFS
* sizeof(int))) {
733 memset(sblock
.fs_blank
, 0, sizeof(sblock
.fs_blank
));
737 "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
755 msgprintf("%s: ", devname
);
756 pfatal("BAD SUPER BLOCK: %s\n", s
);
758 pwarn("USE AN ALTERNATE SUPER-BLOCK TO SUPPLY NEEDED INFORMATION;\n");
759 pwarn("eg. fsck [-F ufs] -o b=# [special ...] \n");
760 pfatal("where # is the alternate super block. SEE fsck_ufs(1M). \n");
764 /* dummy function that fails if ever called */
765 calcsb(dev
, devfd
, fs
)
773 #include <sys/ustat.h>
775 #include <sys/pstat.h>
777 #include <sys/errno.h>
781 is_mounted(device
, dev_st
)
785 char blockdev
[BUFSIZ
];
789 strcpy(blockdev
, device
);
790 if (stat(blockdev
, dev_st
) < 0)
793 if (is_pre_init(dev_st
->st_rdev
))
796 if ((dev_st
->st_mode
& S_IFMT
) == S_IFCHR
) {
797 dp
= strrchr(blockdev
, '/');
798 if (strncmp(dp
, "/r", 2) != 0)
799 while (dp
>= blockdev
&& *--dp
!= '/');
800 if (*(dp
+ 1) == 'r')
801 (void)strcpy(dp
+ 1, dp
+ 2);
802 if (stat(blockdev
, dev_st
) < 0)
805 if (ustat(dev_st
->st_rdev
, &ust
) >= 0) {
806 /* make sure we are not in pre_init_rc. If we are 0 should be returned in here. */
807 if ((is_root(dev_st
->st_rdev
)) && is_roroot())
817 #ifdef AFS_HPUX102_ENV
818 #define PSTAT(P, N, I) pstat_getswap(P, sizeof(*P), (size_t)N, I)
820 #define PSTAT(P, N, I) pstat(PSTAT_SWAPINFO, P, sizeof(*P), (size_t)N, I)
825 struct pst_swapinfo pst
[PS_BURST
];
826 struct pst_swapinfo
*psp
= &pst
[0];
827 int idx
= 0, count
, match
= 0;
829 while ((count
= PSTAT(psp
, PS_BURST
, idx
) != 0)) {
830 idx
= pst
[count
- 1].pss_idx
+ 1;
831 if ((psp
->pss_flags
& SW_BLOCK
) && (psp
->pss_major
== major(devno
))
832 && (psp
->pss_minor
== minor(devno
))) {
840 #endif /* AFS_HPUX_ENV */
853 #ifndef UID_NO_CHANGE
856 if (stat("/", &stslash
) < 0)
858 if (chown("/", stslash
.st_uid
, stslash
.st_gid
) == 0)
861 if (chown("/", UID_NO_CHANGE
, GID_NO_CHANGE
) == 0)
864 else if (errno
!= EROFS
) {
865 printf("fsck: chown failed: %d\n", errno
);
871 is_hotroot(fs_device
)
874 struct stat stslash
, stblock
, stchar
;
875 char blockdev
[BUFSIZ
];
877 strcpy(blockdev
, fs_device
);
878 if (stat("/", &stslash
) < 0) {
879 pfatal("Can't stat root\n");
883 if (stat(blockdev
, &stblock
) < 0) {
884 pfatal("Can't stat %s\n", blockdev
);
888 if (is_pre_init(stblock
.st_rdev
))
891 /* convert the device name to be block device name */
892 if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
) {
894 if (stat(blockdev
, &stblock
) < 0)
897 if ((stblock
.st_mode
& S_IFMT
) != S_IFBLK
)
899 if (stslash
.st_dev
!= stblock
.st_rdev
)
901 /* is root file system mounted read only? */
912 if (stat("/", &stslash
) < 0)
914 if (stslash
.st_dev
!= rdev_num
)
919 vfsck_getline(fp
, loc
, maxlen
)
927 lastloc
= &p
[maxlen
- 1];
928 while ((n
= getc(fp
)) != '\n') {
931 if (!isspace(n
) && p
< lastloc
)
939 * freply - prints the string, s, gets a reply fromterminal and returns
940 * 0 - no (don't continue), and 1 - yes (continue)
948 errexit("exiting\n");
950 if (vfsck_getline(stdin
, line
, sizeof(line
)) == EOF
)
952 if (line
[0] == 'y' || line
[0] == 'Y')
958 #if defined(AFS_HPUX110_ENV)
960 * Refer to function compare_sblocks() in HP's fsck.c
963 * This routine will compare the primary superblock (PRIM_SBLOCK) to the
964 * alternate superblock (ALT_SBLOCK). This routine will take into account
965 * that certain fields in the alternate superblock could be different than
966 * in the primary superblock. This routine checks the "static" fields
967 * and ignores the "dynamic" fields. Superblocks with the same "static"
968 * fields are considered equivalent.
971 UpdateAlternateSuper(prim_sblock
, alt_sblock
)
972 struct fs
*prim_sblock
;
973 struct fs
*alt_sblock
; /* will be modified */
976 * Set all possible fields that could differ, then do check
977 * of whole super block against an alternate super block.
979 * Copy dynamic fields of prim_sblock into alt_sblock
981 alt_sblock
->fs_time
= prim_sblock
->fs_time
;
982 alt_sblock
->fs_minfree
= prim_sblock
->fs_minfree
;
983 alt_sblock
->fs_rotdelay
= prim_sblock
->fs_rotdelay
;
984 alt_sblock
->fs_maxcontig
= prim_sblock
->fs_maxcontig
;
985 alt_sblock
->fs_maxbpg
= prim_sblock
->fs_maxbpg
;
986 alt_sblock
->fs_mirror
= prim_sblock
->fs_mirror
;
987 alt_sblock
->fs_cstotal
= prim_sblock
->fs_cstotal
;
988 alt_sblock
->fs_fmod
= prim_sblock
->fs_fmod
;
989 alt_sblock
->fs_clean
= prim_sblock
->fs_clean
;
990 alt_sblock
->fs_ronly
= prim_sblock
->fs_ronly
;
991 alt_sblock
->fs_flags
= prim_sblock
->fs_flags
;
992 alt_sblock
->fs_cgrotor
= prim_sblock
->fs_cgrotor
;
994 alt_sblock
->fs_csp
= prim_sblock
->fs_csp
;
995 #else /* not __LP64__ */
996 alt_sblock
->fs_csp
= prim_sblock
->fs_csp
;
997 alt_sblock
->fs_csp_pad
= prim_sblock
->fs_csp_pad
;
998 #endif /* not __LP64__ */
999 memcpy((char *)alt_sblock
->fs_fsmnt
, (char *)prim_sblock
->fs_fsmnt
,
1000 sizeof prim_sblock
->fs_fsmnt
);
1001 memcpy((char *)alt_sblock
->fs_fname
, (char *)prim_sblock
->fs_fname
,
1002 sizeof prim_sblock
->fs_fname
);
1003 memcpy((char *)alt_sblock
->fs_fpack
, (char *)prim_sblock
->fs_fpack
,
1004 sizeof prim_sblock
->fs_fpack
);
1005 if (prim_sblock
->fs_featurebits
& FSF_LARGEUIDS
)
1006 alt_sblock
->fs_featurebits
|= FSF_LARGEUIDS
;
1008 alt_sblock
->fs_featurebits
&= ~FSF_LARGEUIDS
;
1010 #endif /* AFS_HPUX110_ENV */