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>
24 #include <sys/param.h>
25 #define VICE /* allow us to put our changes in at will */
28 #include <sys/vnode.h>
29 #include <sys/mount.h>
30 #include <ufs/inode.h>
38 #else /* AFS_OSF_ENV */
39 #ifdef AFS_VFSINCL_ENV
40 #include <sys/vnode.h>
45 #include <sys/fs/ufs_inode.h>
46 #include <sys/fs/ufs_fs.h>
48 #include <sys/fs/ufs_fsdir.h>
50 #include <sys/fs/ufs_mount.h>
52 #include <ufs/inode.h>
54 #include <ufs/fsdir.h>
56 #else /* AFS_VFSINCL_ENV */
57 #include <sys/inode.h>
60 #define LONGFILENAMES 1
61 #include <sys/sysmacros.h>
63 #include <sys/signal.h>
65 #ifdef HAVE_USR_OLD_USR_INCLUDE_NDIR_H
66 #include </usr/old/usr/include/ndir.h>
74 #endif /* AFS_VFSINCL_ENV */
75 #endif /* AFS_OSF_ENV */
81 #if defined(AFS_HPUX101_ENV)
85 #if defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
91 long diskreads, totalreads; /* Disk cache statistics */
92 #if !defined(AFS_HPUX101_ENV)
96 #if defined(AFS_SUN_ENV)
103 #include <sys/mntent.h>
104 #include <sys/mnttab.h>
105 #include <sys/stat.h>
106 #include <sys/vfstab.h>
114 switch (dp->di_mode & IFMT) {
136 printf("bad file type 0%o\n", dp->di_mode);
151 pfatal("INTERNAL ERROR: GOT TO reply()");
152 persevere = !strcmp(question, "CONTINUE");
154 if (!persevere && (nflag || fswritefd < 0)) {
155 printf("%s? no\n\n", question);
156 #if defined(AFS_SUN_ENV)
157 iscorrupt = 1; /* known to be corrupt */
161 if (yflag || (persevere && nflag)) {
162 printf("%s? yes\n\n", question);
166 printf("%s? [yn] ", question);
167 (void)fflush(stdout);
169 while (c != '\n' && getc(stdin) != '\n')
172 } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
174 if (c == 'y' || c == 'Y')
179 #if defined(AFS_SUN_ENV)
180 iscorrupt = 1; /* known to be corrupt */
186 * Malloc buffers and set up cache.
190 register struct bufarea *bp;
194 bufp = malloc((unsigned int)sblock.fs_bsize);
196 errexit("cannot allocate buffer pool\n");
197 cgblk.b_un.b_buf = bufp;
199 bufhead.b_next = bufhead.b_prev = &bufhead;
200 bufcnt = MAXBUFSPACE / sblock.fs_bsize;
201 if (bufcnt < MINBUFS)
203 for (i = 0; i < bufcnt; i++) {
204 bp = (struct bufarea *)malloc(sizeof(struct bufarea));
205 bufp = malloc((unsigned int)sblock.fs_bsize);
206 if (bp == NULL || bufp == NULL) {
209 errexit("cannot allocate buffer pool\n");
211 bp->b_un.b_buf = bufp;
212 bp->b_prev = &bufhead;
213 bp->b_next = bufhead.b_next;
214 bufhead.b_next->b_prev = bp;
218 bufhead.b_size = i; /* save number of buffers */
225 * Manage a cache of directory blocks.
228 getdatablk(blkno, size)
232 register struct bufarea *bp;
234 for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
235 if (bp->b_bno == fsbtodb(&sblock, blkno))
237 for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
238 if ((bp->b_flags & B_INUSE) == 0)
241 errexit("deadlocked buffer pool\n");
242 getblk(bp, blkno, size);
246 bp->b_prev->b_next = bp->b_next;
247 bp->b_next->b_prev = bp->b_prev;
248 bp->b_prev = &bufhead;
249 bp->b_next = bufhead.b_next;
250 bufhead.b_next->b_prev = bp;
252 bp->b_flags |= B_INUSE;
257 getblk(bp, blk, size)
258 register struct bufarea *bp;
264 dblk = fsbtodb(&sblock, blk);
265 if (bp->b_bno == dblk)
267 flush(fswritefd, bp);
269 bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
277 register struct bufarea *bp;
285 if (bp->b_errs != 0) {
286 pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n",
287 (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
292 bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
295 #if defined(AFS_HPUX101_ENV)
296 #if defined(AFS_HPUX110_ENV)
297 /* jpm: Need a fix here */
299 #else /* AFS_HPUX110_ENV */
301 (fswritefd, (char *)sblock.fs_csp[0],
302 fsbtodb(&sblock, sblock.fs_csaddr), fragroundup(&sblock,
303 sblock.fs_cssize)) ==
305 #endif /* else AFS_HPUX110_ENV */
308 ("\nUnable to write to cylinder group summary area (fs_csaddr)\n");
309 printf("\tDisk write error at block %u\n",
310 fsbtodb(&sblock, sblock.fs_csaddr));
313 #if defined(AFS_SUN56_ENV)
314 sip = (caddr_t) sblock.fs_u.fs_csp;
315 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
317 sblock.fs_cssize - i <
318 sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize;
319 bwrite(fswritefd, sip,
320 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), size);
324 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
325 bwrite(fswritefd, (char *)sblock.fs_csp[j],
326 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
327 sblock.fs_cssize - i <
328 sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize);
330 #endif /* AFS_SUN56_ENV */
331 #endif /* AFS_HPUX101_ENV */
341 pfatal("CANNOT %s: BLK %ld", mesg, blk);
342 if (reply("CONTINUE") == 0)
343 errexit("Program terminated\n");
348 register struct bufarea *bp, *nbp;
351 flush(fswritefd, &sblk);
353 if (havesb && sblk.b_bno != SBOFF / dev_bsize && !preen
354 && reply("UPDATE STANDARD SUPERBLOCK")) {
355 sblk.b_bno = SBOFF / dev_bsize;
356 #else /* AFS_NEWCG_ENV */
357 if (havesb && sblk.b_bno != SBLOCK && !preen
358 && reply("UPDATE STANDARD SUPERBLOCK")) {
360 #endif /* AFS_NEWCG_ENV */
362 flush(fswritefd, &sblk);
364 flush(fswritefd, &cgblk);
365 if (cgblk.b_un.b_buf) {
366 free(cgblk.b_un.b_buf);
367 cgblk.b_un.b_buf = NULL;
369 for (bp = bufhead.b_prev; bp != &bufhead; bp = nbp) {
371 flush(fswritefd, bp);
373 free(bp->b_un.b_buf);
379 if (bufhead.b_size != cnt)
380 errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
382 printf("cache missed %d of %d (%d%%)\n", diskreads, totalreads,
383 diskreads * 100 / totalreads);
384 (void)close(fsreadfd);
385 (void)close(fswritefd);
388 #if !defined(AFS_HPUX101_ENV)
389 bread(fd, buf, blk, size)
402 offset_t offset = (offset_t) blk << DEV_BSHIFT;
407 /* To fix a stripping related bug?? */
408 if (lseek(fd, blk * dev_bsize, 0) == -1)
411 if (llseek(fd, offset, 0) < 0)
413 if (lseek(fd, blk * dev_bsize, 0) < 0)
416 rwerror("SEEK", blk);
417 else if (read(fd, buf, (int)size) == size)
419 rwerror("READ", blk);
421 /* To fix a stripping related bug?? */
422 if (lseek(fd, blk * dev_bsize, 0) == -1)
425 if (llseek(fd, offset, 0) < 0)
427 if (lseek(fd, blk * dev_bsize, 0) < 0)
430 rwerror("SEEK", blk);
432 memset(buf, 0, (int)size);
433 printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
435 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
436 addr = (offset_t) (blk + i) << DEV_BSHIFT;
437 if (llseek(fd, addr, SEEK_CUR) < 0 || read(fd, cp, (int)secsize) < 0) {
438 printf(" %d", blk + i);
440 for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
441 if (read(fd, cp, (int)secsize) < 0) {
442 lseek(fd, blk * dev_bsize + i + secsize, 0);
443 if (secsize != dev_bsize && dev_bsize != 1)
444 printf(" %d (%d),", (blk * dev_bsize + i) / secsize,
445 blk + i / dev_bsize);
447 printf(" %d,", blk + i / dev_bsize);
456 bwrite(fd, buf, blk, size)
469 offset_t offset = (offset_t) blk << DEV_BSHIFT;
474 sprintf(msg, "WARNING: Attempt to write illegal blkno %d on %s\n",
485 /* To fix a stripping related bug?? */
486 if (lseek(fd, blk * dev_bsize, 0) == -1)
489 if (llseek(fd, offset, 0) < 0)
491 if (lseek(fd, blk * dev_bsize, 0) < 0)
494 rwerror("SEEK", blk);
495 else if (write(fd, buf, (int)size) == size) {
499 rwerror("WRITE", blk);
501 /* To fix a stripping related bug?? */
502 if (lseek(fd, blk * dev_bsize, 0) == -1)
505 if (llseek(fd, offset, 0) < 0)
507 if (lseek(fd, blk * dev_bsize, 0) < 0)
510 rwerror("SEEK", blk);
511 printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
513 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
515 addr = (offset_t) (blk + i) << DEV_BSHIFT;
516 if (llseek(fd, addr, SEEK_CUR) < 0
517 || (n = write(fd, cp, DEV_BSIZE)) < 0) {
518 printf(" %d", blk + i);
525 for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
526 if (write(fd, cp, (int)dev_bsize) < 0) {
527 lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
528 printf(" %d,", blk + i / dev_bsize);
534 #endif /* AFS_HPUX101_ENV */
536 * allocate a data block with the specified number of fragments
541 register int i, j, k;
543 if (frags <= 0 || frags > sblock.fs_frag)
545 for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) {
546 for (j = 0; j <= sblock.fs_frag - frags; j++) {
549 for (k = 1; k < frags; k++)
550 if (testbmap(i + j + k))
556 for (k = 0; k < frags; k++)
566 * Free a previously allocated block
568 freeblk(blkno, frags)
572 struct inodesc idesc;
574 idesc.id_blkno = blkno;
575 idesc.id_numfrags = frags;
582 getpathname(namebuf, curdir, ino)
588 struct inodesc idesc;
589 extern int findname();
591 if (statemap[ino] != DSTATE && statemap[ino] != DFOUND) {
592 strcpy(namebuf, "?");
595 memset((char *)&idesc, 0, sizeof(struct inodesc));
596 idesc.id_type = DATA;
597 cp = &namebuf[BUFSIZ - 1];
600 idesc.id_parent = curdir;
603 while (ino != ROOTINO) {
604 idesc.id_number = ino;
605 idesc.id_func = findino;
606 idesc.id_name = "..";
608 idesc.id_fix = NOFIX;
610 if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
613 idesc.id_number = idesc.id_parent;
614 idesc.id_parent = ino;
615 idesc.id_func = findname;
616 idesc.id_name = namebuf;
618 idesc.id_fix = NOFIX;
620 if ((ckinode(ginode(idesc.id_number), &idesc) & FOUND) == 0)
622 len = strlen(namebuf);
624 if (cp < &namebuf[MAXNAMLEN])
626 memcpy(cp, namebuf, len);
628 ino = idesc.id_number;
630 if (ino != ROOTINO) {
631 strcpy(namebuf, "?");
634 memcpy(namebuf, cp, &namebuf[BUFSIZ] - cp);
649 * When preening, allow a single quit to signal
650 * a special exit after filesystem checks complete
651 * so that reboot sequence may be interrupted.
656 extern returntosingle;
658 printf("returning to single-user after filesystem check\n");
660 (void)signal(SIGQUIT, SIG_DFL);
664 * Ignore a single quit signal; wait and flush just in case.
665 * Used by child processes in preen.
672 (void)signal(SIGQUIT, SIG_IGN);
673 (void)signal(SIGQUIT, SIG_DFL);
677 * determine whether an inode should be fixed.
680 register struct inodesc *idesc;
684 switch (idesc->id_fix) {
687 if (idesc->id_type == DATA)
688 direrror(idesc->id_number, msg);
692 printf(" (SALVAGED)\n");
696 if (reply("SALVAGE") == 0) {
697 idesc->id_fix = NOFIX;
710 errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
716 errexit(s1, s2, s3, s4)
720 printf(s1, s2, s3, s4);
729 * An unexpected inconsistency occured.
730 * Die if preening, otherwise just print message and continue.
733 pfatal(s, a1, a2, a3)
738 printf("%s: ", devname);
739 printf(s, a1, a2, a3);
741 printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname);
748 printf(s, a1, a2, a3);
752 * Pwarn just prints a message when not preening,
753 * or a warning (preceded by filename) when preening.
756 pwarn(s, a1, a2, a3, a4, a5, a6)
758 long a1, a2, a3, a4, a5, a6;
761 printf("%s: ", devname);
762 printf(s, a1, a2, a3, a4, a5, a6);
766 * Pwarn just prints a message when not preening,
767 * or a warning (preceded by filename) when preening.
770 pinfo(s, a1, a2, a3, a4, a5, a6)
772 long a1, a2, a3, a4, a5, a6;
775 printf("%s: ", devname);
776 printf(s, a1, a2, a3, a4, a5, a6);
781 * Stub for routines from kernel.
787 pfatal("INTERNAL INCONSISTENCY:");
792 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
799 if ((iscorrupt == 0) && (isdirty == 0))
801 if ((sblock.fs_clean != FSSTABLE) && (sblock.fs_clean != FSCLEAN))
804 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
806 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
810 sprintf(s, "WARNING: inconsistencies detected on `%s' filesystem %s",
811 sblock.fs_clean == FSSTABLE ? "stable" : "clean", devname);
817 struct bufarea cleanbuf;
820 unsigned int fsclean;
821 #if defined(AFS_SUN56_ENV)
826 /* set fsclean to its appropriate value */
827 fsclean = sblock.fs_clean;
829 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
831 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
835 /* if necessary, update fs_clean and fs_state */
852 /* if fs_clean and fs_state are ok, do nothing */
853 if ((sblock.fs_clean == fsclean) &&
855 (FSOKAY == (sblock.fs_state + sblock.fs_time)))
857 (FSOKAY == (fs_get_state(&sblock) + sblock.fs_time)))
860 sblock.fs_clean = fsclean;
862 sblock.fs_state = sblock.fs_time;
864 fs_set_state(&sblock, sblock.fs_time);
866 /* if superblock can't be written, return */
869 /* read private copy of superblock, update clean flag, and write it */
872 #if defined(AFS_SUN56_ENV)
873 sblkoff = (OFF_T) (bno) << DEV_BSHIFT;
874 if (llseek(fsreadfd, sblkoff, 0) == -1)
877 if (lseek(fsreadfd, (off_t) dbtob(bno), 0) == -1)
880 if ((cleanbuf.b_un.b_buf = malloc(size)) == NULL)
881 errexit("out of memory");
882 if (read(fsreadfd, cleanbuf.b_un.b_buf, (int)size) != size)
884 cleanbuf.b_un.b_fs->fs_clean = sblock.fs_clean;
886 cleanbuf.b_un.b_fs->fs_state = sblock.fs_state;
888 fs_set_state(cleanbuf.b_un.b_fs, fs_get_state(&sblock));
890 cleanbuf.b_un.b_fs->fs_time = sblock.fs_time;
891 #if defined(AFS_SUN56_ENV)
892 if (llseek(fswritefd, sblkoff, 0) == -1)
895 if (lseek(fswritefd, (off_t) dbtob(bno), 0) == -1)
898 if (write(fswritefd, cleanbuf.b_un.b_buf, (int)size) != size)
907 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
909 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
914 switch (sblock.fs_clean) {
928 pwarn("is %s.\n", s);
930 printf("** %s is %s.\n", devname, s);
937 register struct vfstab *vfs;
941 static char *tmpopts;
943 if (vfs->vfs_mntopts == NULL)
946 tmpopts = (char *)calloc(256, sizeof(char));
950 strncpy(tmpopts, vfs->vfs_mntopts, (sizeof(tmpopts) - 1));
953 for (; *f; f = mntopt(&opts)) {
954 if (strncmp(opt, f, strlen(opt)) == 0)
955 return (f - tmpopts + vfs->vfs_mntopts);
965 struct vfstab vfsbuf;
967 char *blkname, *unrawname();
969 vfstab = fopen(VFSTAB, "r");
970 if (vfstab == NULL) {
971 printf("can't open %s\n", VFSTAB);
974 blkname = unrawname(name);
975 if ((getvfsspec(vfstab, &vfsbuf, blkname) == 0)
976 && (vfsbuf.vfs_fstype != NULL)
977 && (strcmp(vfsbuf.vfs_fstype, MNTTYPE_UFS) == 0)
978 && (hasvfsopt(&vfsbuf, MNTOPT_RO))) {
991 struct stat device_stat, mount_stat;
992 char *blkname, *unrawname();
994 mnttab = fopen(MNTTAB, "r");
995 if (mnttab == NULL) {
996 printf("can't open %s\n", MNTTAB);
999 blkname = unrawname(name);
1000 while ((getmntent(mnttab, &mnt)) == NULL) {
1001 if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) != 0) {
1004 if (strcmp(blkname, mnt.mnt_special) == 0) {
1005 stat(mnt.mnt_mountp, &mount_stat);
1006 stat(mnt.mnt_special, &device_stat);
1007 if (device_stat.st_rdev == mount_stat.st_dev) {
1008 if (hasmntopt(&mnt, MNTOPT_RO) != 0)
1009 found = 2; /* mounted as RO */
1011 found = 1; /* mounted as R/W */
1022 #if defined(AFS_HPUX101_ENV)
1025 #include <sys/stat.h>
1026 #include <sys/fcntl.h>
1030 bread(fd, buf, blk, size)
1039 switch (seek_options) {
1040 case BLKSEEK_ENABLED:
1044 case BLKSEEK_NOT_ENABLED: /* File */
1045 #if defined(AFS_HPUX102_ENV)
1046 lseek_offset = dbtoo(blk);
1048 lseek_offset = dbtob(blk);
1053 rwerror("BLKSEEK", blk);
1055 if (lseek(fd, (off_t) lseek_offset, 0) == (off_t) - 1)
1056 rwerror("SEEK", blk);
1057 else if (read(fd, buf, (int)size) == size)
1059 rwerror("READ", blk);
1063 bwrite(fd, buf, blk, size)
1074 switch (seek_options) {
1075 case BLKSEEK_ENABLED:
1079 case BLKSEEK_NOT_ENABLED: /* File */
1080 #if defined(AFS_HPUX102_ENV)
1081 lseek_offset = dbtoo(blk);
1083 lseek_offset = dbtob(blk);
1088 rwerror("BLKSEEK", blk);
1090 if (lseek(fd, (off_t) lseek_offset, 0) == (off_t) - 1)
1091 rwerror("SEEK", blk);
1092 else if (write(fd, buf, (int)size) == size) {
1096 rwerror("WRITE", blk);
1101 setup_block_seek(fd)
1102 int fd; /* File descriptor */
1104 int flags = 0; /* Flags to/from fcntl() */
1106 return setup_block_seek_2(fd, &flags);
1109 #define set_fserror printf
1112 setup_block_seek_2(fd, cntl_flags)
1113 int fd; /* Input. File descriptor */
1114 int *cntl_flags; /* Returned. Flags from fcntl() */
1116 int flags = 0; /* Flags to/from fcntl() */
1117 off_t lstatus; /* Status from lseek() */
1118 struct stat statarea;
1119 char dummy[MAXBSIZE];
1125 if ((flags = fcntl(fd, F_GETFL)) == -1) {
1126 set_fserror("Cannot get file control flags.");
1127 return (BLKSEEK_PROCESSING_ERROR);
1131 * Check if fd is a non-device file
1134 if (fstat(fd, &statarea) == -1) {
1135 set_fserror("Cannot get status information on file descriptor.");
1136 return (BLKSEEK_PROCESSING_ERROR);
1138 if (((statarea.st_mode & S_IFMT) != S_IFCHR)
1139 && ((statarea.st_mode & S_IFMT) != S_IFBLK)) {
1140 /* Not a device file -- BLKSEEK only works on device files */
1141 *cntl_flags = flags; /* O_BLKSEEK bit never set */
1142 return (BLKSEEK_NOT_ENABLED);
1146 * Set the fd to O_BLKSEEK
1148 if (fcntl(fd, F_SETFL, flags | O_BLKSEEK) == -1) {
1149 set_fserror("Cannot set file control flags.");
1150 return (BLKSEEK_PROCESSING_ERROR);
1152 if (flags & O_WRONLY) {
1153 /* Set lseek to location 0 before returning */
1154 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1155 set_fserror("Cannot lseek the device.");
1156 return (BLKSEEK_PROCESSING_ERROR);
1160 ("File is write only. Cannot Verify O_BLKSEEK mode set.");
1161 *cntl_flags = flags | O_BLKSEEK;
1162 return (BLKSEEK_FILE_WRITEONLY);
1166 * Verify that kernel knows how to do O_BLKSEEK
1168 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1169 set_fserror("Cannot lseek the device.");
1170 return (BLKSEEK_PROCESSING_ERROR);
1172 if (read(fd, &dummy[0], BBSIZE) != BBSIZE) { /* BBSIZE = 8192 */
1173 set_fserror("Cannot read from the device");
1174 return (BLKSEEK_PROCESSING_ERROR);
1177 if ((lstatus = lseek(fd, (off_t) 0, SEEK_CUR)) == (off_t) - 1) {
1178 set_fserror("Cannot lseek the device.");
1179 return (BLKSEEK_PROCESSING_ERROR);
1183 * Set lseek to location 0
1185 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) - 1) {
1186 set_fserror("Cannot lseek the device.");
1187 return (BLKSEEK_PROCESSING_ERROR);
1190 if (lstatus == (off_t) (BBSIZE / DEV_BSIZE)) {
1191 *cntl_flags = flags | O_BLKSEEK;
1192 return (BLKSEEK_ENABLED); /* Successfully enabled O_BLKSEEK */
1194 *cntl_flags = flags & (~O_BLKSEEK); /* Turn off O_BLKSEEK bit */
1195 return (BLKSEEK_NOT_ENABLED); /* O_BLKSEEK not enabled */
1198 setup_all_block_seek()
1201 seek_options = setup_block_seek(fsreadfd);
1202 switch (seek_options) {
1203 case BLKSEEK_ENABLED:
1204 case BLKSEEK_NOT_ENABLED:
1207 errexit("setup_block_seek on fsreadfd");
1210 if (fswritefd == -1)
1212 switch (opt = setup_block_seek(fswritefd)) {
1213 case BLKSEEK_FILE_WRITEONLY: /* WO block or char device. */
1214 case BLKSEEK_NOT_ENABLED: /* regular file. */
1215 if (seek_options != opt)
1217 ("seek_options on fsreadfd (%d) and fswritefd (%d) do not match",
1221 errexit("setup_block_seek on fswritefd");
1226 printf("read option = %d write option = %d\n", seek_options, opt);
1231 #endif /* AFS_HPUX101_ENV */