diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h index c3541a0..a16d82b 100644 --- a/lib/libufs/libufs.h +++ b/lib/libufs/libufs.h @@ -31,34 +31,6 @@ #define __LIBUFS_H__ /* - * libufs macros (internal, non-exported). - */ -#ifdef _LIBUFS -#ifdef _LIBUFS_DEBUGGING -/* - * Trace steps through libufs, to be used at entry and erroneous return. - */ -#define ERROR(uufsd, str) \ -do { \ - fprintf(stderr, "libufs in %s", __func__); \ - if (str != NULL) \ - fprintf(stderr, ": %s", str); \ - if (errno) \ - fprintf(stderr, ": %s", strerror(errno)); \ - fprintf(stderr, "\n"); \ - if ((uufsd) != NULL) \ - (uufsd)->d_error = str; \ -} while (0) -#else /* _LIBUFS_DEBUGGING */ -#define ERROR(uufsd, str) \ -do { \ - if ((uufsd) != NULL) \ - (uufsd)->d_error = str; \ -} while (0) -#endif /* _LIBUFS_DEBUGGING */ -#endif /* _LIBUFS */ - -/* * libufs structures. */ @@ -94,6 +66,30 @@ struct uufsd { #define d_cg d_cgunion.d_cg }; +/* + * libufs macros (internal, non-exported). + */ +#ifdef _LIBUFS +/* + * Trace steps through libufs, to be used at entry and erroneous return. + */ +static inline void +ERROR(struct uufsd *u, const char *str) +{ + +#ifdef _LIBUFS_DEBUGGING + if (str != NULL) { + fprintf(stderr, "libufs: %s", str); + if (errno != 0) + fprintf(stderr, ": %s", strerror(errno)); + fprintf(stderr, "\n"); + } +#endif + if (u != NULL) + u->d_error = str; +} +#endif /* _LIBUFS */ + __BEGIN_DECLS /* diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 08f9ef5..342b95f 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -268,6 +268,7 @@ char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */ char *cdevname; /* name of device being checked */ long dev_bsize; /* computed value of DEV_BSIZE */ long secsize; /* actual disk sector size */ +long real_dev_bsize; char nflag; /* assume a no response */ char yflag; /* assume a yes response */ int bkgrdflag; /* use a snapshot to run on an active system */ diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 8ee140d..4bf6294 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -79,6 +79,7 @@ main(int argc, char *argv[]) struct itimerval itimerval; int ret = 0; + debug = 1; sync(); skipclean = 1; inoopt = 0; diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 1628ffb..e51c0a9 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -446,7 +446,7 @@ sblock_init(void) if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) errx(EEXIT, "cannot allocate space for superblock"); if ((lp = getdisklabel(NULL, fsreadfd))) - dev_bsize = secsize = lp->d_secsize; + real_dev_bsize = dev_bsize = secsize = lp->d_secsize; else dev_bsize = secsize = DEV_BSIZE; } diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c index 60e3b33..7dda78e 100644 --- a/sbin/fsck_ffs/suj.c +++ b/sbin/fsck_ffs/suj.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -201,6 +202,11 @@ opendisk(const char *devnam) disk->d_error); } fs = &disk->d_fs; + if (real_dev_bsize == 0 && ioctl(disk->d_fd, DIOCGSECTORSIZE, + &real_dev_bsize) == -1) + real_dev_bsize = secsize; + if (debug) + printf("dev_bsize %ld\n", real_dev_bsize); } /* @@ -2262,7 +2268,7 @@ suj_build(void) rec = (union jrec *)seg->ss_blk; for (i = 0; i < seg->ss_rec.jsr_cnt; off += JREC_SIZE, rec++) { /* skip the segrec. */ - if ((off % DEV_BSIZE) == 0) + if ((off % real_dev_bsize) == 0) continue; switch (rec->rec_jrefrec.jr_op) { case JOP_ADDREF: @@ -2340,7 +2346,7 @@ suj_prune(void) TAILQ_FOREACH_SAFE(seg, &allsegs, ss_next, segn) { if (!discard && newseq++ == seg->ss_rec.jsr_seq) { jrecs += seg->ss_rec.jsr_cnt; - jbytes += seg->ss_rec.jsr_blocks * DEV_BSIZE; + jbytes += seg->ss_rec.jsr_blocks * real_dev_bsize; continue; } discard = 1; @@ -2440,7 +2446,7 @@ jblocks_next(struct jblocks *jblocks, int bytes, int *actual) int freecnt; int blocks; - blocks = bytes / DEV_BSIZE; + blocks = bytes / disk->d_bsize; jext = &jblocks->jb_extent[jblocks->jb_head]; freecnt = jext->je_blocks - jblocks->jb_off; if (freecnt == 0) { @@ -2452,7 +2458,7 @@ jblocks_next(struct jblocks *jblocks, int bytes, int *actual) } if (freecnt > blocks) freecnt = blocks; - *actual = freecnt * DEV_BSIZE; + *actual = freecnt * disk->d_bsize; daddr = jext->je_daddr + jblocks->jb_off; return (daddr); @@ -2466,7 +2472,7 @@ static void jblocks_advance(struct jblocks *jblocks, int bytes) { - jblocks->jb_off += bytes / DEV_BSIZE; + jblocks->jb_off += bytes / disk->d_bsize; } static void @@ -2563,7 +2569,7 @@ restart: } for (rec = (void *)block; size; size -= recsize, rec = (struct jsegrec *)((uintptr_t)rec + recsize)) { - recsize = DEV_BSIZE; + recsize = real_dev_bsize; if (rec->jsr_time != fs->fs_mtime) { if (debug) printf("Rec time %jd != fs mtime %jd\n", @@ -2579,7 +2585,7 @@ restart: continue; } blocks = rec->jsr_blocks; - recsize = blocks * DEV_BSIZE; + recsize = blocks * real_dev_bsize; if (recsize > size) { /* * We may just have run out of buffer, restart @@ -2592,7 +2598,7 @@ restart: if (debug) printf("Found invalid segsize %d > %d\n", recsize, size); - recsize = DEV_BSIZE; + recsize = real_dev_bsize; jblocks_advance(suj_jblocks, recsize); continue; } @@ -2600,15 +2606,15 @@ restart: * Verify that all blocks in the segment are present. */ for (i = 1; i < blocks; i++) { - recn = (void *) - ((uintptr_t)rec) + i * DEV_BSIZE; + recn = (void *)((uintptr_t)rec) + i * + real_dev_bsize; if (recn->jsr_seq == rec->jsr_seq && recn->jsr_time == rec->jsr_time) continue; if (debug) printf("Incomplete record %jd (%d)\n", rec->jsr_seq, i); - recsize = i * DEV_BSIZE; + recsize = i * real_dev_bsize; jblocks_advance(suj_jblocks, recsize); goto restart; } diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c index 08c127d..aee33fb 100644 --- a/sbin/tunefs/tunefs.c +++ b/sbin/tunefs/tunefs.c @@ -688,6 +688,19 @@ journal_findfile(void) return (0); } +static void +dir_clear_block(char *block, off_t off) +{ + struct direct *dp; + + for (; off < sblock.fs_bsize; off += DIRBLKSIZ) { + dp = (struct direct *)&block[off]; + dp->d_ino = 0; + dp->d_reclen = DIRBLKSIZ; + dp->d_type = DT_UNKNOWN; + } +} + /* * Insert the journal at inode 'ino' into directory blk 'blk' at the first * free offset of 'off'. DIRBLKSIZ blocks after off are initialized as @@ -710,13 +723,7 @@ dir_insert(ufs2_daddr_t blk, off_t off, ino_t ino) dp->d_type = DT_REG; dp->d_namlen = strlen(SUJ_FILE); bcopy(SUJ_FILE, &dp->d_name, strlen(SUJ_FILE)); - off += DIRBLKSIZ; - for (; off < sblock.fs_bsize; off += DIRBLKSIZ) { - dp = (struct direct *)&block[off]; - dp->d_ino = 0; - dp->d_reclen = DIRBLKSIZ; - dp->d_type = DT_UNKNOWN; - } + dir_clear_block(block, off + DIRBLKSIZ); if (bwrite(&disk, fsbtodb(&sblock, blk), block, sblock.fs_bsize) <= 0) { warn("Failed to write dir block"); return (-1); @@ -733,16 +740,19 @@ dir_extend(ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino) { char block[MAXBSIZE]; - if (bread(&disk, fsbtodb(&sblock, blk), block, size) <= 0) { + if (bread(&disk, fsbtodb(&sblock, blk), block, + roundup(size, sblock.fs_fsize)) <= 0) { warn("Failed to read dir block"); return (-1); } - if (bwrite(&disk, fsbtodb(&sblock, nblk), block, size) <= 0) { + dir_clear_block(block, size); + if (bwrite(&disk, fsbtodb(&sblock, nblk), block, sblock.fs_bsize) + <= 0) { warn("Failed to write dir block"); return (-1); } - return dir_insert(nblk, size, ino); + return (dir_insert(nblk, size, ino)); } /* diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 0e790d6..fa52358 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -747,7 +747,7 @@ static void handle_written_jnewblk(struct jnewblk *); static void handle_written_jfreeblk(struct jfreeblk *); static void handle_written_jfreefrag(struct jfreefrag *); static void complete_jseg(struct jseg *); -static void jseg_write(struct fs *, struct jblocks *, struct jseg *, +static void jseg_write(struct ufsmount *ump, struct jblocks *, struct jseg *, uint8_t *); static void jaddref_write(struct jaddref *, struct jseg *, uint8_t *); static void jremref_write(struct jremref *, struct jseg *, uint8_t *); @@ -2554,8 +2554,8 @@ softdep_prelink(dvp, vp) } static void -jseg_write(fs, jblocks, jseg, data) - struct fs *fs; +jseg_write(ump, jblocks, jseg, data) + struct ufsmount *ump; struct jblocks *jblocks; struct jseg *jseg; uint8_t *data; @@ -2566,9 +2566,9 @@ jseg_write(fs, jblocks, jseg, data) rec->jsr_seq = jseg->js_seq; rec->jsr_oldest = jblocks->jb_oldestseq; rec->jsr_cnt = jseg->js_cnt; - rec->jsr_blocks = jseg->js_size / DEV_BSIZE; + rec->jsr_blocks = jseg->js_size / ump->um_devvp->v_bufobj.bo_bsize; rec->jsr_crc = 0; - rec->jsr_time = fs->fs_mtime; + rec->jsr_time = ump->um_fs->fs_mtime; } static inline void @@ -2718,19 +2718,21 @@ softdep_process_journal(mp, flags) int size; int cnt; int off; + int devbsize; if ((mp->mnt_kern_flag & MNTK_SUJ) == 0) return; ump = VFSTOUFS(mp); fs = ump->um_fs; jblocks = ump->softdep_jblocks; + devbsize = ump->um_devvp->v_bufobj.bo_bsize; /* * We write anywhere between a disk block and fs block. The upper * bound is picked to prevent buffer cache fragmentation and limit * processing time per I/O. */ - jrecmin = (DEV_BSIZE / JREC_SIZE) - 1; /* -1 for seg header */ - jrecmax = (fs->fs_bsize / DEV_BSIZE) * jrecmin; + jrecmin = (devbsize / JREC_SIZE) - 1; /* -1 for seg header */ + jrecmax = (fs->fs_bsize / devbsize) * jrecmin; segwritten = 0; while ((cnt = ump->softdep_on_journal) != 0) { /* @@ -2785,7 +2787,7 @@ softdep_process_journal(mp, flags) */ cnt = ump->softdep_on_journal; if (cnt < jrecmax) - size = howmany(cnt, jrecmin) * DEV_BSIZE; + size = howmany(cnt, jrecmin) * devbsize; else size = fs->fs_bsize; /* @@ -2805,7 +2807,7 @@ softdep_process_journal(mp, flags) * sequence number to it and link it in-order. */ cnt = MIN(ump->softdep_on_journal, - (size / DEV_BSIZE) * jrecmin); + (size / devbsize) * jrecmin); jseg->js_buf = bp; jseg->js_cnt = cnt; jseg->js_refs = cnt + 1; /* Self ref. */ @@ -2824,8 +2826,8 @@ softdep_process_journal(mp, flags) while ((wk = LIST_FIRST(&ump->softdep_journal_pending)) != NULL) { /* Place a segment header on every device block. */ - if ((off % DEV_BSIZE) == 0) { - jseg_write(fs, jblocks, jseg, data); + if ((off % devbsize) == 0) { + jseg_write(ump, jblocks, jseg, data); off += JREC_SIZE; data = bp->b_data + off; } diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index 13d9ede..0b7e908 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -682,7 +682,7 @@ struct jsegrec { uint64_t jsr_seq; /* Our sequence number */ uint64_t jsr_oldest; /* Oldest valid sequence number */ uint16_t jsr_cnt; /* Count of valid records */ - uint16_t jsr_blocks; /* Count of DEV_BSIZE blocks. */ + uint16_t jsr_blocks; /* Count of device bsize blocks. */ uint32_t jsr_crc; /* 32bit crc of the valid space */ ufs_time_t jsr_time; /* timestamp for mount instance */ };