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>
22 /* We need the old directory type headers (included below), so don't include
23 * the normal dirent.h, or it will conflict. */
25 # include <sys/inode.h>
26 # define LONGFILENAMES 1
27 # include <sys/sysmacros.h>
29 # include <sys/signal.h>
31 # ifdef HAVE_USR_OLD_USR_INCLUDE_NDIR_H
32 # include </usr/old/usr/include/ndir.h>
42 #define VICE /* allow us to put our changes in at will */
43 #ifdef AFS_VFSINCL_ENV
44 #include <sys/vnode.h>
46 #include <sys/fs/ufs_inode.h>
47 #include <sys/fs/ufs_fs.h>
49 #include <sys/fs/ufs_fsdir.h>
51 #include <sys/fs/ufs_mount.h>
53 #include <ufs/inode.h>
55 #include <ufs/fsdir.h>
57 #else /* AFS_VFSINCL_ENV */
58 #include <sys/inode.h>
63 #endif /* AFS_VFSINCL_ENV */
67 #if defined(AFS_SUN_ENV)
73 long diskreads, totalreads; /* Disk cache statistics */
74 #if !defined(AFS_HPUX101_ENV)
77 #if defined(AFS_SUN_ENV)
84 #include <sys/mntent.h>
85 #include <sys/mnttab.h>
86 #include <sys/vfstab.h>
94 switch (dp->di_mode & IFMT) {
116 printf("bad file type 0%o\n", dp->di_mode);
131 pfatal("INTERNAL ERROR: GOT TO reply()");
132 persevere = !strcmp(question, "CONTINUE");
134 if (!persevere && (nflag || fswritefd < 0)) {
135 printf("%s? no\n\n", question);
136 #if defined(AFS_SUN_ENV)
137 iscorrupt = 1; /* known to be corrupt */
141 if (yflag || (persevere && nflag)) {
142 printf("%s? yes\n\n", question);
146 printf("%s? [yn] ", question);
147 (void)fflush(stdout);
149 while (c != '\n' && getc(stdin) != '\n')
152 } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
154 if (c == 'y' || c == 'Y')
159 #if defined(AFS_SUN_ENV)
160 iscorrupt = 1; /* known to be corrupt */
166 * Malloc buffers and set up cache.
174 bufp = malloc((unsigned int)sblock.fs_bsize);
176 errexit("cannot allocate buffer pool\n");
177 cgblk.b_un.b_buf = bufp;
179 bufhead.b_next = bufhead.b_prev = &bufhead;
180 bufcnt = MAXBUFSPACE / sblock.fs_bsize;
181 if (bufcnt < MINBUFS)
183 for (i = 0; i < bufcnt; i++) {
184 bp = malloc(sizeof(struct bufarea));
185 bufp = malloc((unsigned int)sblock.fs_bsize);
186 if (bp == NULL || bufp == NULL) {
189 errexit("cannot allocate buffer pool\n");
191 bp->b_un.b_buf = bufp;
192 bp->b_prev = &bufhead;
193 bp->b_next = bufhead.b_next;
194 bufhead.b_next->b_prev = bp;
198 bufhead.b_size = i; /* save number of buffers */
205 * Manage a cache of directory blocks.
208 getdatablk(blkno, size)
214 for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
215 if (bp->b_bno == fsbtodb(&sblock, blkno))
217 for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
218 if ((bp->b_flags & B_INUSE) == 0)
221 errexit("deadlocked buffer pool\n");
222 getblk(bp, blkno, size);
226 bp->b_prev->b_next = bp->b_next;
227 bp->b_next->b_prev = bp->b_prev;
228 bp->b_prev = &bufhead;
229 bp->b_next = bufhead.b_next;
230 bufhead.b_next->b_prev = bp;
232 bp->b_flags |= B_INUSE;
237 getblk(bp, blk, size)
244 dblk = fsbtodb(&sblock, blk);
245 if (bp->b_bno == dblk)
247 flush(fswritefd, bp);
249 bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
265 if (bp->b_errs != 0) {
266 pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n",
267 (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
272 bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
275 #if defined(AFS_HPUX101_ENV)
276 #if defined(AFS_HPUX110_ENV)
277 /* jpm: Need a fix here */
279 #else /* AFS_HPUX110_ENV */
281 (fswritefd, (char *)sblock.fs_csp[0],
282 fsbtodb(&sblock, sblock.fs_csaddr), fragroundup(&sblock,
283 sblock.fs_cssize)) ==
285 #endif /* else AFS_HPUX110_ENV */
288 ("\nUnable to write to cylinder group summary area (fs_csaddr)\n");
289 printf("\tDisk write error at block %u\n",
290 fsbtodb(&sblock, sblock.fs_csaddr));
293 #if defined(AFS_SUN5_ENV)
294 sip = (caddr_t) sblock.fs_u.fs_csp;
295 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
297 sblock.fs_cssize - i <
298 sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize;
299 bwrite(fswritefd, sip,
300 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), size);
304 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
305 bwrite(fswritefd, (char *)sblock.fs_csp[j],
306 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
307 sblock.fs_cssize - i <
308 sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize);
310 #endif /* AFS_SUN5_ENV */
311 #endif /* AFS_HPUX101_ENV */
321 pfatal("CANNOT %s: BLK %ld", mesg, blk);
322 if (reply("CONTINUE") == 0)
323 errexit("Program terminated\n");
328 struct bufarea *bp, *nbp;
331 flush(fswritefd, &sblk);
333 if (havesb && sblk.b_bno != SBOFF / dev_bsize && !preen
334 && reply("UPDATE STANDARD SUPERBLOCK")) {
335 sblk.b_bno = SBOFF / dev_bsize;
336 #else /* AFS_NEWCG_ENV */
337 if (havesb && sblk.b_bno != SBLOCK && !preen
338 && reply("UPDATE STANDARD SUPERBLOCK")) {
340 #endif /* AFS_NEWCG_ENV */
342 flush(fswritefd, &sblk);
344 flush(fswritefd, &cgblk);
345 if (cgblk.b_un.b_buf) {
346 free(cgblk.b_un.b_buf);
347 cgblk.b_un.b_buf = NULL;
349 for (bp = bufhead.b_prev; bp != &bufhead; bp = nbp) {
351 flush(fswritefd, bp);
353 free(bp->b_un.b_buf);
359 if (bufhead.b_size != cnt)
360 errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
362 printf("cache missed %d of %d (%d%%)\n", diskreads, totalreads,
363 diskreads * 100 / totalreads);
364 (void)close(fsreadfd);
365 (void)close(fswritefd);
368 #if !defined(AFS_HPUX101_ENV)
369 bread(fd, buf, blk, size)
382 offset_t offset = (offset_t) blk << DEV_BSHIFT;
387 /* To fix a stripping related bug?? */
388 if (lseek(fd, blk * dev_bsize, 0) == -1)
391 if (llseek(fd, offset, 0) < 0)
393 if (lseek(fd, blk * dev_bsize, 0) < 0)
396 rwerror("SEEK", blk);
397 else if (read(fd, buf, (int)size) == size)
399 rwerror("READ", blk);
401 /* To fix a stripping related bug?? */
402 if (lseek(fd, blk * dev_bsize, 0) == -1)
405 if (llseek(fd, offset, 0) < 0)
407 if (lseek(fd, blk * dev_bsize, 0) < 0)
410 rwerror("SEEK", blk);
412 memset(buf, 0, (int)size);
413 printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
415 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
416 addr = (offset_t) (blk + i) << DEV_BSHIFT;
417 if (llseek(fd, addr, SEEK_CUR) < 0 || read(fd, cp, (int)secsize) < 0) {
418 printf(" %d", blk + i);
420 for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
421 if (read(fd, cp, (int)secsize) < 0) {
422 lseek(fd, blk * dev_bsize + i + secsize, 0);
423 if (secsize != dev_bsize && dev_bsize != 1)
424 printf(" %d (%d),", (blk * dev_bsize + i) / secsize,
425 blk + i / dev_bsize);
427 printf(" %d,", blk + i / dev_bsize);
436 bwrite(fd, buf, blk, size)
449 offset_t offset = (offset_t) blk << DEV_BSHIFT;
454 sprintf(msg, "WARNING: Attempt to write illegal blkno %d on %s\n",
465 /* To fix a stripping related bug?? */
466 if (lseek(fd, blk * dev_bsize, 0) == -1)
469 if (llseek(fd, offset, 0) < 0)
471 if (lseek(fd, blk * dev_bsize, 0) < 0)
474 rwerror("SEEK", blk);
475 else if (write(fd, buf, (int)size) == size) {
479 rwerror("WRITE", blk);
481 /* To fix a stripping related bug?? */
482 if (lseek(fd, blk * dev_bsize, 0) == -1)
485 if (llseek(fd, offset, 0) < 0)
487 if (lseek(fd, blk * dev_bsize, 0) < 0)
490 rwerror("SEEK", blk);
491 printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
493 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
495 addr = (offset_t) (blk + i) << DEV_BSHIFT;
496 if (llseek(fd, addr, SEEK_CUR) < 0
497 || (n = write(fd, cp, DEV_BSIZE)) < 0) {
498 printf(" %d", blk + i);
505 for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
506 if (write(fd, cp, (int)dev_bsize) < 0) {
507 lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
508 printf(" %d,", blk + i / dev_bsize);
514 #endif /* AFS_HPUX101_ENV */
516 * allocate a data block with the specified number of fragments
523 if (frags <= 0 || frags > sblock.fs_frag)
525 for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) {
526 for (j = 0; j <= sblock.fs_frag - frags; j++) {
529 for (k = 1; k < frags; k++)
530 if (testbmap(i + j + k))
536 for (k = 0; k < frags; k++)
546 * Free a previously allocated block
548 freeblk(blkno, frags)
552 struct inodesc idesc;
554 idesc.id_blkno = blkno;
555 idesc.id_numfrags = frags;
562 getpathname(namebuf, curdir, ino)
568 struct inodesc idesc;
569 extern int findname();
571 if (statemap[ino] != DSTATE && statemap[ino] != DFOUND) {
572 strcpy(namebuf, "?");
575 memset(&idesc, 0, sizeof(struct inodesc));
576 idesc.id_type = DATA;
577 cp = &namebuf[BUFSIZ - 1];
580 idesc.id_parent = curdir;
583 while (ino != ROOTINO) {
584 idesc.id_number = ino;
585 idesc.id_func = findino;
586 idesc.id_name = "..";
588 idesc.id_fix = NOFIX;
590 if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
593 idesc.id_number = idesc.id_parent;
594 idesc.id_parent = ino;
595 idesc.id_func = findname;
596 idesc.id_name = namebuf;
598 idesc.id_fix = NOFIX;
600 if ((ckinode(ginode(idesc.id_number), &idesc) & FOUND) == 0)
602 len = strlen(namebuf);
604 if (cp < &namebuf[MAXNAMLEN])
606 memcpy(cp, namebuf, len);
608 ino = idesc.id_number;
610 if (ino != ROOTINO) {
611 strcpy(namebuf, "?");
614 memcpy(namebuf, cp, &namebuf[BUFSIZ] - cp);
629 * When preening, allow a single quit to signal
630 * a special exit after filesystem checks complete
631 * so that reboot sequence may be interrupted.
636 extern returntosingle;
638 printf("returning to single-user after filesystem check\n");
640 (void)signal(SIGQUIT, SIG_DFL);
644 * Ignore a single quit signal; wait and flush just in case.
645 * Used by child processes in preen.
652 (void)signal(SIGQUIT, SIG_IGN);
653 (void)signal(SIGQUIT, SIG_DFL);
657 * determine whether an inode should be fixed.
660 struct inodesc *idesc;
664 switch (idesc->id_fix) {
667 if (idesc->id_type == DATA)
668 direrror(idesc->id_number, msg);
672 printf(" (SALVAGED)\n");
676 if (reply("SALVAGE") == 0) {
677 idesc->id_fix = NOFIX;
690 errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
696 errexit(s1, s2, s3, s4)
700 printf(s1, s2, s3, s4);
709 * An unexpected inconsistency occured.
710 * Die if preening, otherwise just print message and continue.
713 pfatal(s, a1, a2, a3)
718 printf("%s: ", devname);
719 printf(s, a1, a2, a3);
721 printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname);
728 printf(s, a1, a2, a3);
732 * Pwarn just prints a message when not preening,
733 * or a warning (preceded by filename) when preening.
736 pwarn(s, a1, a2, a3, a4, a5, a6)
738 long a1, a2, a3, a4, a5, a6;
741 printf("%s: ", devname);
742 printf(s, a1, a2, a3, a4, a5, a6);
746 * Pwarn just prints a message when not preening,
747 * or a warning (preceded by filename) when preening.
750 pinfo(s, a1, a2, a3, a4, a5, a6)
752 long a1, a2, a3, a4, a5, a6;
755 printf("%s: ", devname);
756 printf(s, a1, a2, a3, a4, a5, a6);
761 * Stub for routines from kernel.
767 pfatal("INTERNAL INCONSISTENCY:");
772 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
779 if ((iscorrupt == 0) && (isdirty == 0))
781 if ((sblock.fs_clean != FSSTABLE) && (sblock.fs_clean != FSCLEAN))
784 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
786 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
790 sprintf(s, "WARNING: inconsistencies detected on `%s' filesystem %s",
791 sblock.fs_clean == FSSTABLE ? "stable" : "clean", devname);
797 struct bufarea cleanbuf;
800 unsigned int fsclean;
801 #if defined(AFS_SUN5_ENV)
806 /* set fsclean to its appropriate value */
807 fsclean = sblock.fs_clean;
809 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
811 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
815 /* if necessary, update fs_clean and fs_state */
832 /* if fs_clean and fs_state are ok, do nothing */
833 if ((sblock.fs_clean == fsclean) &&
835 (FSOKAY == (sblock.fs_state + sblock.fs_time)))
837 (FSOKAY == (fs_get_state(&sblock) + sblock.fs_time)))
840 sblock.fs_clean = fsclean;
842 sblock.fs_state = sblock.fs_time;
844 fs_set_state(&sblock, sblock.fs_time);
846 /* if superblock can't be written, return */
849 /* read private copy of superblock, update clean flag, and write it */
852 #if defined(AFS_SUN5_ENV)
853 sblkoff = (OFF_T) (bno) << DEV_BSHIFT;
854 if (llseek(fsreadfd, sblkoff, 0) == -1)
857 if (lseek(fsreadfd, (off_t) dbtob(bno), 0) == -1)
860 if ((cleanbuf.b_un.b_buf = malloc(size)) == NULL)
861 errexit("out of memory");
862 if (read(fsreadfd, cleanbuf.b_un.b_buf, (int)size) != size)
864 cleanbuf.b_un.b_fs->fs_clean = sblock.fs_clean;
866 cleanbuf.b_un.b_fs->fs_state = sblock.fs_state;
868 fs_set_state(cleanbuf.b_un.b_fs, fs_get_state(&sblock));
870 cleanbuf.b_un.b_fs->fs_time = sblock.fs_time;
871 #if defined(AFS_SUN5_ENV)
872 if (llseek(fswritefd, sblkoff, 0) == -1)
875 if (lseek(fswritefd, (off_t) dbtob(bno), 0) == -1)
878 if (write(fswritefd, cleanbuf.b_un.b_buf, (int)size) != size)
887 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
889 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
894 switch (sblock.fs_clean) {
908 pwarn("is %s.\n", s);
910 printf("** %s is %s.\n", devname, s);
921 static char *tmpopts;
923 if (vfs->vfs_mntopts == NULL)
926 tmpopts = calloc(256, sizeof(char));
930 strncpy(tmpopts, vfs->vfs_mntopts, (sizeof(tmpopts) - 1));
933 for (; *f; f = mntopt(&opts)) {
934 if (strncmp(opt, f, strlen(opt)) == 0)
935 return (f - tmpopts + vfs->vfs_mntopts);
945 struct vfstab vfsbuf;
947 char *blkname, *unrawname();
949 vfstab = fopen(VFSTAB, "r");
950 if (vfstab == NULL) {
951 printf("can't open %s\n", VFSTAB);
954 blkname = unrawname(name);
955 if ((getvfsspec(vfstab, &vfsbuf, blkname) == 0)
956 && (vfsbuf.vfs_fstype != NULL)
957 && (strcmp(vfsbuf.vfs_fstype, MNTTYPE_UFS) == 0)
958 && (hasvfsopt(&vfsbuf, MNTOPT_RO))) {
971 struct stat device_stat, mount_stat;
972 char *blkname, *unrawname();
974 mnttab = fopen(MNTTAB, "r");
975 if (mnttab == NULL) {
976 printf("can't open %s\n", MNTTAB);
979 blkname = unrawname(name);
980 while ((getmntent(mnttab, &mnt)) == NULL) {
981 if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) != 0) {
984 if (strcmp(blkname, mnt.mnt_special) == 0) {
985 stat(mnt.mnt_mountp, &mount_stat);
986 stat(mnt.mnt_special, &device_stat);
987 if (device_stat.st_rdev == mount_stat.st_dev) {
988 if (hasmntopt(&mnt, MNTOPT_RO) != 0)
989 found = 2; /* mounted as RO */
991 found = 1; /* mounted as R/W */
1002 #if defined(AFS_HPUX101_ENV)
1005 #include <sys/fcntl.h>
1009 bread(fd, buf, blk, size)
1018 switch (seek_options) {
1019 case BLKSEEK_ENABLED:
1023 case BLKSEEK_NOT_ENABLED: /* File */
1024 #if defined(AFS_HPUX102_ENV)
1025 lseek_offset = dbtoo(blk);
1027 lseek_offset = dbtob(blk);
1032 rwerror("BLKSEEK", blk);
1034 if (lseek(fd, (off_t) lseek_offset, 0) == (off_t) - 1)
1035 rwerror("SEEK", blk);
1036 else if (read(fd, buf, (int)size) == size)
1038 rwerror("READ", blk);
1042 bwrite(fd, buf, blk, size)
1053 switch (seek_options) {
1054 case BLKSEEK_ENABLED:
1058 case BLKSEEK_NOT_ENABLED: /* File */
1059 #if defined(AFS_HPUX102_ENV)
1060 lseek_offset = dbtoo(blk);
1062 lseek_offset = dbtob(blk);
1067 rwerror("BLKSEEK", blk);
1069 if (lseek(fd, (off_t) lseek_offset, 0) == (off_t) - 1)
1070 rwerror("SEEK", blk);
1071 else if (write(fd, buf, (int)size) == size) {
1075 rwerror("WRITE", blk);
1080 setup_block_seek(fd)
1081 int fd; /* File descriptor */
1083 int flags = 0; /* Flags to/from fcntl() */
1085 return setup_block_seek_2(fd, &flags);
1088 #define set_fserror printf
1091 setup_block_seek_2(fd, cntl_flags)
1092 int fd; /* Input. File descriptor */
1093 int *cntl_flags; /* Returned. Flags from fcntl() */
1095 int flags = 0; /* Flags to/from fcntl() */
1096 off_t lstatus; /* Status from lseek() */
1097 struct stat statarea;
1098 char dummy[MAXBSIZE];
1104 if ((flags = fcntl(fd, F_GETFL)) == -1) {
1105 set_fserror("Cannot get file control flags.");
1106 return (BLKSEEK_PROCESSING_ERROR);
1110 * Check if fd is a non-device file
1113 if (fstat(fd, &statarea) == -1) {
1114 set_fserror("Cannot get status information on file descriptor.");
1115 return (BLKSEEK_PROCESSING_ERROR);
1117 if (((statarea.st_mode & S_IFMT) != S_IFCHR)
1118 && ((statarea.st_mode & S_IFMT) != S_IFBLK)) {
1119 /* Not a device file -- BLKSEEK only works on device files */
1120 *cntl_flags = flags; /* O_BLKSEEK bit never set */
1121 return (BLKSEEK_NOT_ENABLED);
1125 * Set the fd to O_BLKSEEK
1127 if (fcntl(fd, F_SETFL, flags | O_BLKSEEK) == -1) {
1128 set_fserror("Cannot set file control flags.");
1129 return (BLKSEEK_PROCESSING_ERROR);
1131 if (flags & O_WRONLY) {
1132 /* Set lseek to location 0 before returning */
1133 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1134 set_fserror("Cannot lseek the device.");
1135 return (BLKSEEK_PROCESSING_ERROR);
1139 ("File is write only. Cannot Verify O_BLKSEEK mode set.");
1140 *cntl_flags = flags | O_BLKSEEK;
1141 return (BLKSEEK_FILE_WRITEONLY);
1145 * Verify that kernel knows how to do O_BLKSEEK
1147 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1148 set_fserror("Cannot lseek the device.");
1149 return (BLKSEEK_PROCESSING_ERROR);
1151 if (read(fd, &dummy[0], BBSIZE) != BBSIZE) { /* BBSIZE = 8192 */
1152 set_fserror("Cannot read from the device");
1153 return (BLKSEEK_PROCESSING_ERROR);
1156 if ((lstatus = lseek(fd, (off_t) 0, SEEK_CUR)) == (off_t) - 1) {
1157 set_fserror("Cannot lseek the device.");
1158 return (BLKSEEK_PROCESSING_ERROR);
1162 * Set lseek to location 0
1164 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1165 set_fserror("Cannot lseek the device.");
1166 return (BLKSEEK_PROCESSING_ERROR);
1169 if (lstatus == (off_t) (BBSIZE / DEV_BSIZE)) {
1170 *cntl_flags = flags | O_BLKSEEK;
1171 return (BLKSEEK_ENABLED); /* Successfully enabled O_BLKSEEK */
1173 *cntl_flags = flags & (~O_BLKSEEK); /* Turn off O_BLKSEEK bit */
1174 return (BLKSEEK_NOT_ENABLED); /* O_BLKSEEK not enabled */
1177 setup_all_block_seek()
1180 seek_options = setup_block_seek(fsreadfd);
1181 switch (seek_options) {
1182 case BLKSEEK_ENABLED:
1183 case BLKSEEK_NOT_ENABLED:
1186 errexit("setup_block_seek on fsreadfd");
1189 if (fswritefd == -1)
1191 switch (opt = setup_block_seek(fswritefd)) {
1192 case BLKSEEK_FILE_WRITEONLY: /* WO block or char device. */
1193 case BLKSEEK_NOT_ENABLED: /* regular file. */
1194 if (seek_options != opt)
1196 ("seek_options on fsreadfd (%d) and fswritefd (%d) do not match",
1200 errexit("setup_block_seek on fswritefd");
1205 printf("read option = %d write option = %d\n", seek_options, opt);
1210 #endif /* AFS_HPUX101_ENV */