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>
23 #include <sys/param.h>
24 #define VICE /* allow us to put our changes in at will */
27 #include <sys/vnode.h>
28 #include <sys/mount.h>
29 #include <ufs/inode.h>
37 #else /* AFS_OSF_ENV */
38 #ifdef AFS_VFSINCL_ENV
39 #include <sys/vnode.h>
44 #include <sys/fs/ufs_inode.h>
45 #include <sys/fs/ufs_fs.h>
47 #include <sys/fs/ufs_fsdir.h>
49 #include <sys/fs/ufs_mount.h>
51 #include <ufs/inode.h>
53 #include <ufs/fsdir.h>
55 #else /* AFS_VFSINCL_ENV */
56 #include <sys/inode.h>
59 #define LONGFILENAMES 1
60 #include <sys/sysmacros.h>
62 #include <sys/signal.h>
69 #endif /* AFS_VFSINCL_ENV */
70 #endif /* AFS_OSF_ENV */
76 #if defined(AFS_HPUX101_ENV)
80 #if defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
86 long diskreads, totalreads; /* Disk cache statistics */
87 #if !defined(AFS_HPUX101_ENV)
91 #if defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV)
98 #include <sys/mntent.h>
99 #include <sys/mnttab.h>
100 #include <sys/stat.h>
101 #include <sys/vfstab.h>
109 switch (dp->di_mode & IFMT) {
131 printf("bad file type 0%o\n", dp->di_mode);
146 pfatal("INTERNAL ERROR: GOT TO reply()");
147 persevere = !strcmp(question, "CONTINUE");
149 if (!persevere && (nflag || fswritefd < 0)) {
150 printf("%s? no\n\n", question);
151 #if defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV)
152 iscorrupt = 1; /* known to be corrupt */
156 if (yflag || (persevere && nflag)) {
157 printf("%s? yes\n\n", question);
161 printf("%s? [yn] ", question);
162 (void) fflush(stdout);
164 while (c != '\n' && getc(stdin) != '\n')
167 } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
169 if (c == 'y' || c == 'Y')
174 #if defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV)
175 iscorrupt = 1; /* known to be corrupt */
181 * Malloc buffers and set up cache.
185 register struct bufarea *bp;
189 bufp = malloc((unsigned int)sblock.fs_bsize);
191 errexit("cannot allocate buffer pool\n");
192 cgblk.b_un.b_buf = bufp;
194 bufhead.b_next = bufhead.b_prev = &bufhead;
195 bufcnt = MAXBUFSPACE / sblock.fs_bsize;
196 if (bufcnt < MINBUFS)
198 for (i = 0; i < bufcnt; i++) {
199 bp = (struct bufarea *)malloc(sizeof(struct bufarea));
200 bufp = malloc((unsigned int)sblock.fs_bsize);
201 if (bp == NULL || bufp == NULL) {
204 errexit("cannot allocate buffer pool\n");
206 bp->b_un.b_buf = bufp;
207 bp->b_prev = &bufhead;
208 bp->b_next = bufhead.b_next;
209 bufhead.b_next->b_prev = bp;
213 bufhead.b_size = i; /* save number of buffers */
220 * Manage a cache of directory blocks.
223 getdatablk(blkno, size)
227 register struct bufarea *bp;
229 for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
230 if (bp->b_bno == fsbtodb(&sblock, blkno))
232 for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
233 if ((bp->b_flags & B_INUSE) == 0)
236 errexit("deadlocked buffer pool\n");
237 getblk(bp, blkno, size);
241 bp->b_prev->b_next = bp->b_next;
242 bp->b_next->b_prev = bp->b_prev;
243 bp->b_prev = &bufhead;
244 bp->b_next = bufhead.b_next;
245 bufhead.b_next->b_prev = bp;
247 bp->b_flags |= B_INUSE;
252 getblk(bp, blk, size)
253 register struct bufarea *bp;
259 dblk = fsbtodb(&sblock, blk);
260 if (bp->b_bno == dblk)
262 flush(fswritefd, bp);
264 bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
272 register struct bufarea *bp;
280 if (bp->b_errs != 0) {
281 pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n",
282 (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ", bp->b_bno);
289 bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
292 #if defined(AFS_HPUX101_ENV)
293 #if defined(AFS_HPUX110_ENV)
294 /* jpm: Need a fix here */
296 #else /* AFS_HPUX110_ENV */
297 if ( bwrite(fswritefd, (char *)sblock.fs_csp[0],
298 fsbtodb(&sblock, sblock.fs_csaddr),
299 fragroundup(&sblock, sblock.fs_cssize)) == 1 )
300 #endif /* else AFS_HPUX110_ENV */
302 printf("\nUnable to write to cylinder group summary area (fs_csaddr)\n");
303 printf("\tDisk write error at block %u\n",fsbtodb(&sblock,sblock.fs_csaddr));
307 #if defined(AFS_SUN56_ENV)
308 sip = (caddr_t)sblock.fs_u.fs_csp;
309 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
310 size = sblock.fs_cssize - i < sblock.fs_bsize ?
311 sblock.fs_cssize - i : sblock.fs_bsize;
312 bwrite(fswritefd, sip,
313 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
318 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
319 bwrite(fswritefd, (char *)sblock.fs_csp[j],
320 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
321 sblock.fs_cssize - i < sblock.fs_bsize ?
322 sblock.fs_cssize - i : sblock.fs_bsize);
324 #endif /* AFS_SUN56_ENV */
325 #endif /* AFS_HPUX101_ENV */
335 pfatal("CANNOT %s: BLK %ld", mesg, blk);
336 if (reply("CONTINUE") == 0)
337 errexit("Program terminated\n");
342 register struct bufarea *bp, *nbp;
345 flush(fswritefd, &sblk);
347 if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
348 !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
349 sblk.b_bno = SBOFF / dev_bsize;
350 #else /* AFS_NEWCG_ENV */
351 if (havesb && sblk.b_bno != SBLOCK &&
352 !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
354 #endif /* AFS_NEWCG_ENV */
356 flush(fswritefd, &sblk);
358 flush(fswritefd, &cgblk);
359 if (cgblk.b_un.b_buf) {
360 free(cgblk.b_un.b_buf);
361 cgblk.b_un.b_buf = NULL;
363 for (bp = bufhead.b_prev; bp != &bufhead; bp = nbp) {
365 flush(fswritefd, bp);
367 free(bp->b_un.b_buf);
373 if (bufhead.b_size != cnt)
374 errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
376 printf("cache missed %d of %d (%d%%)\n", diskreads,
377 totalreads, diskreads * 100 / totalreads);
378 (void)close(fsreadfd);
379 (void)close(fswritefd);
382 #if !defined(AFS_HPUX101_ENV)
383 bread(fd, buf, blk, size)
392 offset_t offset = (offset_t)blk << DEV_BSHIFT;
397 /* To fix a stripping related bug?? */
398 if (lseek(fd, blk * dev_bsize, 0) == -1)
401 if (llseek(fd, offset , 0) < 0)
403 if (lseek(fd, blk * dev_bsize, 0) < 0)
406 rwerror("SEEK", blk);
407 else if (read(fd, buf, (int)size) == size)
409 rwerror("READ", blk);
411 /* To fix a stripping related bug?? */
412 if (lseek(fd, blk * dev_bsize, 0) == -1)
415 if (llseek(fd, offset , 0) < 0)
417 if (lseek(fd, blk * dev_bsize, 0) < 0)
420 rwerror("SEEK", blk);
422 memset(buf, 0, (int)size);
423 printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
425 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
426 addr = (offset_t)(blk + i) << DEV_BSHIFT;
427 if (llseek(fd, addr, SEEK_CUR) < 0 ||
428 read(fd, cp, (int)secsize) < 0) {
429 printf(" %d", blk + i);
431 for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
432 if (read(fd, cp, (int)secsize) < 0) {
433 lseek(fd, blk * dev_bsize + i + secsize, 0);
434 if (secsize != dev_bsize && dev_bsize != 1)
436 (blk * dev_bsize + i) / secsize,
437 blk + i / dev_bsize);
439 printf(" %d,", blk + i / dev_bsize);
448 bwrite(fd, buf, blk, size)
457 offset_t offset = (offset_t)blk << DEV_BSHIFT;
462 sprintf(msg, "WARNING: Attempt to write illegal blkno %d on %s\n", blk, devname);
463 if(debug) printf(msg);
471 /* To fix a stripping related bug?? */
472 if (lseek(fd, blk * dev_bsize, 0) == -1)
475 if (llseek(fd, offset , 0) < 0)
477 if (lseek(fd, blk * dev_bsize, 0) < 0)
480 rwerror("SEEK", blk);
481 else if (write(fd, buf, (int)size) == size) {
485 rwerror("WRITE", blk);
487 /* To fix a stripping related bug?? */
488 if (lseek(fd, blk * dev_bsize, 0) == -1)
491 if (llseek(fd, offset , 0) < 0)
493 if (lseek(fd, blk * dev_bsize, 0) < 0)
496 rwerror("SEEK", blk);
497 printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
499 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) {
501 addr = (offset_t)(blk + i) << DEV_BSHIFT;
502 if (llseek(fd, addr, SEEK_CUR) < 0 ||
503 (n = write(fd, cp, DEV_BSIZE)) < 0) {
504 printf(" %d", blk + i);
511 for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
512 if (write(fd, cp, (int)dev_bsize) < 0) {
513 lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
514 printf(" %d,", blk + i / dev_bsize);
520 #endif /* AFS_HPUX101_ENV */
522 * allocate a data block with the specified number of fragments
527 register int i, j, k;
529 if (frags <= 0 || frags > sblock.fs_frag)
531 for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) {
532 for (j = 0; j <= sblock.fs_frag - frags; j++) {
535 for (k = 1; k < frags; k++)
536 if (testbmap(i + j + k))
542 for (k = 0; k < frags; k++)
552 * Free a previously allocated block
554 freeblk(blkno, frags)
558 struct inodesc idesc;
560 idesc.id_blkno = blkno;
561 idesc.id_numfrags = frags;
568 getpathname(namebuf, curdir, ino)
574 struct inodesc idesc;
575 extern int findname();
577 if (statemap[ino] != DSTATE && statemap[ino] != DFOUND) {
578 strcpy(namebuf, "?");
581 memset((char *)&idesc, 0, sizeof(struct inodesc));
582 idesc.id_type = DATA;
583 cp = &namebuf[BUFSIZ - 1];
586 idesc.id_parent = curdir;
589 while (ino != ROOTINO) {
590 idesc.id_number = ino;
591 idesc.id_func = findino;
592 idesc.id_name = "..";
594 idesc.id_fix = NOFIX;
596 if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
599 idesc.id_number = idesc.id_parent;
600 idesc.id_parent = ino;
601 idesc.id_func = findname;
602 idesc.id_name = namebuf;
604 idesc.id_fix = NOFIX;
606 if ((ckinode(ginode(idesc.id_number), &idesc) & FOUND) == 0)
608 len = strlen(namebuf);
610 if (cp < &namebuf[MAXNAMLEN])
612 memcpy(cp, namebuf, len);
614 ino = idesc.id_number;
616 if (ino != ROOTINO) {
617 strcpy(namebuf, "?");
620 memcpy(namebuf, cp, &namebuf[BUFSIZ] - cp);
635 * When preening, allow a single quit to signal
636 * a special exit after filesystem checks complete
637 * so that reboot sequence may be interrupted.
642 extern returntosingle;
644 printf("returning to single-user after filesystem check\n");
646 (void)signal(SIGQUIT, SIG_DFL);
650 * Ignore a single quit signal; wait and flush just in case.
651 * Used by child processes in preen.
658 (void)signal(SIGQUIT, SIG_IGN);
659 (void)signal(SIGQUIT, SIG_DFL);
663 * determine whether an inode should be fixed.
666 register struct inodesc *idesc;
670 switch (idesc->id_fix) {
673 if (idesc->id_type == DATA)
674 direrror(idesc->id_number, msg);
678 printf(" (SALVAGED)\n");
682 if (reply("SALVAGE") == 0) {
683 idesc->id_fix = NOFIX;
696 errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
702 errexit(s1, s2, s3, s4)
706 printf(s1, s2, s3, s4);
715 * An unexpected inconsistency occured.
716 * Die if preening, otherwise just print message and continue.
719 pfatal(s, a1, a2, a3)
724 printf("%s: ", devname);
725 printf(s, a1, a2, a3);
727 printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
735 printf(s, a1, a2, a3);
739 * Pwarn just prints a message when not preening,
740 * or a warning (preceded by filename) when preening.
743 pwarn(s, a1, a2, a3, a4, a5, a6)
745 long a1, a2, a3, a4, a5, a6;
748 printf("%s: ", devname);
749 printf(s, a1, a2, a3, a4, a5, a6);
753 * Pwarn just prints a message when not preening,
754 * or a warning (preceded by filename) when preening.
757 pinfo(s, a1, a2, a3, a4, a5, a6)
759 long a1, a2, a3, a4, a5, a6;
762 printf("%s: ", devname);
763 printf(s, a1, a2, a3, a4, a5, a6);
768 * Stub for routines from kernel.
774 pfatal("INTERNAL INCONSISTENCY:");
779 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN3_ENV)
786 if ((iscorrupt == 0) && (isdirty == 0))
788 if ((sblock.fs_clean != FSSTABLE) && (sblock.fs_clean != FSCLEAN))
791 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
793 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
797 sprintf(s, "WARNING: inconsistencies detected on `%s' filesystem %s",
798 sblock.fs_clean == FSSTABLE ? "stable" : "clean", devname);
804 struct bufarea cleanbuf;
807 unsigned int fsclean;
808 #if defined(AFS_SUN56_ENV)
813 /* set fsclean to its appropriate value */
814 fsclean = sblock.fs_clean;
816 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
818 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
822 /* if necessary, update fs_clean and fs_state */
825 if (iscorrupt == 0) fsclean = FSSTABLE;
829 if (iscorrupt) fsclean = FSACTIVE;
837 /* if fs_clean and fs_state are ok, do nothing */
838 if ( (sblock.fs_clean == fsclean) &&
840 (FSOKAY == (sblock.fs_state + sblock.fs_time)) )
842 (FSOKAY == (fs_get_state(&sblock) + sblock.fs_time)) )
845 sblock.fs_clean = fsclean;
847 sblock.fs_state = sblock.fs_time;
849 fs_set_state(&sblock, sblock.fs_time);
851 /* if superblock can't be written, return */
854 /* read private copy of superblock, update clean flag, and write it */
857 #if defined(AFS_SUN56_ENV)
858 sblkoff = (OFF_T)(bno) << DEV_BSHIFT;
859 if (llseek(fsreadfd, sblkoff, 0) == -1)
862 if (lseek(fsreadfd, (off_t)dbtob(bno), 0) == -1)
865 if ((cleanbuf.b_un.b_buf = malloc(size)) == NULL)
866 errexit("out of memory");
867 if (read(fsreadfd, cleanbuf.b_un.b_buf, (int)size) != size)
869 cleanbuf.b_un.b_fs->fs_clean = sblock.fs_clean;
871 cleanbuf.b_un.b_fs->fs_state = sblock.fs_state;
873 fs_set_state(cleanbuf.b_un.b_fs, fs_get_state(&sblock));
875 cleanbuf.b_un.b_fs->fs_time = sblock.fs_time;
876 #if defined(AFS_SUN56_ENV)
877 if (llseek(fswritefd, sblkoff, 0) == -1)
880 if (lseek(fswritefd, (off_t)dbtob(bno), 0) == -1)
883 if (write(fswritefd, cleanbuf.b_un.b_buf, (int)size) != size)
892 if (FSOKAY != (sblock.fs_state + sblock.fs_time))
894 if (FSOKAY != (fs_get_state(&sblock) + sblock.fs_time))
899 switch(sblock.fs_clean) {
913 pwarn("is %s.\n", s);
915 printf("** %s is %s.\n", devname, s);
920 char *hasvfsopt(vfs, opt)
921 register struct vfstab *vfs;
925 static char *tmpopts;
927 if (vfs->vfs_mntopts == NULL)
930 tmpopts = (char *)calloc(256, sizeof (char));
934 strncpy(tmpopts, vfs->vfs_mntopts, (sizeof (tmpopts) - 1));
937 for (; *f; f = mntopt(&opts)) {
938 if (strncmp(opt, f, strlen(opt)) == 0)
939 return (f - tmpopts + vfs->vfs_mntopts);
949 struct vfstab vfsbuf;
951 char *blkname, *unrawname();
953 vfstab = fopen(VFSTAB, "r");
954 if (vfstab == NULL) {
955 printf("can't open %s\n", VFSTAB);
958 blkname = unrawname(name);
959 if ((getvfsspec(vfstab, &vfsbuf, blkname) == 0) &&
960 (vfsbuf.vfs_fstype != NULL) &&
961 (strcmp(vfsbuf.vfs_fstype, MNTTYPE_UFS) == 0) &&
962 (hasvfsopt(&vfsbuf, MNTOPT_RO))) {
975 struct stat device_stat, mount_stat;
976 char *blkname, *unrawname();
978 mnttab = fopen(MNTTAB, "r");
979 if (mnttab == NULL) {
980 printf("can't open %s\n", MNTTAB);
983 blkname = unrawname(name);
984 while ((getmntent(mnttab, &mnt)) == NULL) {
985 if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) != 0) {
988 if (strcmp(blkname, mnt.mnt_special) == 0) {
989 stat(mnt.mnt_mountp, &mount_stat);
990 stat(mnt.mnt_special, &device_stat);
991 if (device_stat.st_rdev == mount_stat.st_dev) {
992 if (hasmntopt (&mnt, MNTOPT_RO) != 0)
993 found = 2; /* mounted as RO */
995 found = 1; /* mounted as R/W */
1006 #if defined(AFS_HPUX101_ENV)
1009 #include <sys/stat.h>
1010 #include <sys/fcntl.h>
1014 bread(fd, buf, blk, size)
1023 switch( seek_options )
1025 case BLKSEEK_ENABLED:
1029 case BLKSEEK_NOT_ENABLED: /* File */
1030 #if defined(AFS_HPUX102_ENV)
1031 lseek_offset = dbtoo(blk);
1033 lseek_offset = dbtob(blk);
1038 rwerror("BLKSEEK", blk);
1040 if (lseek(fd,(off_t) lseek_offset, 0) == (off_t) -1)
1041 rwerror("SEEK", blk);
1042 else if (read(fd, buf, (int)size) == size)
1044 rwerror("READ", blk);
1048 bwrite(fd, buf, blk, size)
1059 switch( seek_options )
1061 case BLKSEEK_ENABLED:
1065 case BLKSEEK_NOT_ENABLED: /* File */
1066 #if defined(AFS_HPUX102_ENV)
1067 lseek_offset = dbtoo(blk);
1069 lseek_offset = dbtob(blk);
1074 rwerror("BLKSEEK", blk);
1076 if (lseek(fd,(off_t) lseek_offset, 0) == (off_t) -1)
1077 rwerror("SEEK", blk);
1078 else if (write(fd, buf, (int)size) == size)
1083 rwerror("WRITE", blk);
1088 setup_block_seek(fd)
1089 int fd; /* File descriptor */
1091 int flags=0; /* Flags to/from fcntl() */
1093 return setup_block_seek_2(fd, &flags);
1095 #define set_fserror printf
1098 setup_block_seek_2(fd, cntl_flags)
1099 int fd; /* Input. File descriptor */
1100 int *cntl_flags; /* Returned. Flags from fcntl() */
1102 int flags=0; /* Flags to/from fcntl() */
1103 off_t lstatus; /* Status from lseek() */
1104 struct stat statarea;
1105 char dummy[MAXBSIZE];
1111 if ((flags = fcntl(fd, F_GETFL)) == -1) {
1112 set_fserror("Cannot get file control flags.");
1113 return(BLKSEEK_PROCESSING_ERROR);
1117 * Check if fd is a non-device file
1120 if (fstat(fd, &statarea) == -1) {
1121 set_fserror("Cannot get status information on file descriptor.")
1123 return(BLKSEEK_PROCESSING_ERROR);
1125 if (((statarea.st_mode & S_IFMT) != S_IFCHR) &&
1126 ((statarea.st_mode & S_IFMT) != S_IFBLK)) {
1127 /* Not a device file -- BLKSEEK only works on device files */
1128 *cntl_flags = flags; /* O_BLKSEEK bit never set */
1129 return(BLKSEEK_NOT_ENABLED);
1133 * Set the fd to O_BLKSEEK
1135 if (fcntl(fd, F_SETFL, flags | O_BLKSEEK) == -1) {
1136 set_fserror("Cannot set file control flags.");
1137 return(BLKSEEK_PROCESSING_ERROR);
1139 if (flags & O_WRONLY) {
1140 /* Set lseek to location 0 before returning */
1141 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) {
1142 set_fserror("Cannot lseek the device.");
1143 return(BLKSEEK_PROCESSING_ERROR);
1146 set_fserror("File is write only. Cannot Verify O_BLKSEEK mode set.");
1147 *cntl_flags = flags | O_BLKSEEK;
1148 return(BLKSEEK_FILE_WRITEONLY);
1152 * Verify that kernel knows how to do O_BLKSEEK
1154 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) {
1155 set_fserror("Cannot lseek the device.");
1156 return(BLKSEEK_PROCESSING_ERROR);
1158 if (read(fd, &dummy[0], BBSIZE) != BBSIZE) { /* BBSIZE = 8192 */
1159 set_fserror("Cannot read from the device");
1160 return(BLKSEEK_PROCESSING_ERROR);
1163 if ((lstatus = lseek(fd, (off_t) 0, SEEK_CUR)) == (off_t) -1) {
1164 set_fserror("Cannot lseek the device.");
1165 return(BLKSEEK_PROCESSING_ERROR);
1169 * Set lseek to location 0
1171 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) {
1172 set_fserror("Cannot lseek the device.");
1173 return(BLKSEEK_PROCESSING_ERROR);
1176 if (lstatus == (off_t) (BBSIZE / DEV_BSIZE)) {
1177 *cntl_flags = flags | O_BLKSEEK;
1178 return(BLKSEEK_ENABLED); /* Successfully enabled O_BLKSEEK */
1180 *cntl_flags = flags & (~O_BLKSEEK); /* Turn off O_BLKSEEK bit */
1181 return(BLKSEEK_NOT_ENABLED); /* O_BLKSEEK not enabled */
1184 setup_all_block_seek()
1187 seek_options = setup_block_seek(fsreadfd);
1188 switch( seek_options )
1190 case BLKSEEK_ENABLED:
1191 case BLKSEEK_NOT_ENABLED:
1194 errexit("setup_block_seek on fsreadfd");
1197 if( fswritefd == -1 )
1199 switch( opt = setup_block_seek(fswritefd))
1201 case BLKSEEK_FILE_WRITEONLY: /* WO block or char device. */
1202 case BLKSEEK_NOT_ENABLED: /* regular file. */
1203 if ( seek_options != opt )
1204 printf("seek_options on fsreadfd (%d) and fswritefd (%d) do not match",
1208 errexit("setup_block_seek on fswritefd");
1213 printf("read option = %d write option = %d\n",
1219 #endif /* AFS_HPUX101_ENV */