Re: fsck_ffs: faster with lots of cylinder groups
On Sun, 12 Jul 2020 09:13:47 +0200 Otto Moerbeek : > On Mon, Jun 29, 2020 at 02:30:41PM +0200, Otto Moerbeek wrote: > > > On Sun, Jun 21, 2020 at 03:35:21PM +0200, Otto Moerbeek wrote: > > > > > Hi, > > > > > > both phase 1 and phase 5 need cylinder group metadata. This diff > > > keeps the cg data read in phase 1 in memory to be used by phase 5 if > > > possible. From FreeBSD. > > > > > > -Otto > > > > > > On an empty 30T fileystem: > > > > > > $ time obj/fsck_ffs -f /dev/sd3a > > > 2m44.10s real 0m13.21s user 0m07.38s system > > > > > > $ time doas obj/fsck_ffs -f /dev/sd3a > > > 1m32.81s real 0m12.86s user 0m05.25s system > > > > > > The difference will be less if a fileystem is filled up, but still nice. > > > > Any takers? > > No feedback. I'm getting discouraged in doing more filesystem work... > > What to do? > > 1) Abondon the diff > 2) Commit without ok > > I did quite extensive testing, but both options are unsatisfactory. > > -Otto I'm not sure how to test your diff. Would running fsck on a sane filesystem enough? Are you using Vms that you halt to force a fsck on them? Would this be a good test too?
Re: fsck_ffs: faster with lots of cylinder groups
On Sun, Jul 12, 2020 at 11:07:05AM +0200, Solene Rapenne wrote: > On Sun, 12 Jul 2020 09:13:47 +0200 > Otto Moerbeek : > > > On Mon, Jun 29, 2020 at 02:30:41PM +0200, Otto Moerbeek wrote: > > > > > On Sun, Jun 21, 2020 at 03:35:21PM +0200, Otto Moerbeek wrote: > > > > > > > Hi, > > > > > > > > both phase 1 and phase 5 need cylinder group metadata. This diff > > > > keeps the cg data read in phase 1 in memory to be used by phase 5 if > > > > possible. From FreeBSD. > > > > > > > > -Otto > > > > > > > > On an empty 30T fileystem: > > > > > > > > $ time obj/fsck_ffs -f /dev/sd3a > > > > 2m44.10s real 0m13.21s user 0m07.38s system > > > > > > > > $ time doas obj/fsck_ffs -f /dev/sd3a > > > > 1m32.81s real 0m12.86s user 0m05.25s system > > > > > > > > The difference will be less if a fileystem is filled up, but still > > > > nice. > > > > > > Any takers? > > > > No feedback. I'm getting discouraged in doing more filesystem work... > > > > What to do? > > > > 1) Abondon the diff > > 2) Commit without ok > > > > I did quite extensive testing, but both options are unsatisfactory. > > > > -Otto > > I'm not sure how to test your diff. > Would running fsck on a sane filesystem enough? > > Are you using Vms that you halt to force a > fsck on them? Would this be a good test too? I have used both large and small fieysystems, clean and with inconsistencies, both ffs1 and ffs2. Sometimes I create inconsistencies by power cycling a machine, buut I have created faulty filesystems by carefully overwriting meta data with dd in the past as well. In this case running with a restricted ulimit -d to force the fallback code to kick in is also an good idea. -Otto
Re: fsck_ffs: faster with lots of cylinder groups
On Mon, Jun 29, 2020 at 02:30:41PM +0200, Otto Moerbeek wrote: > On Sun, Jun 21, 2020 at 03:35:21PM +0200, Otto Moerbeek wrote: > > > Hi, > > > > both phase 1 and phase 5 need cylinder group metadata. This diff > > keeps the cg data read in phase 1 in memory to be used by phase 5 if > > possible. From FreeBSD. > > > > -Otto > > > > On an empty 30T fileystem: > > > > $ time obj/fsck_ffs -f /dev/sd3a > > 2m44.10s real 0m13.21s user 0m07.38s system > > > > $ time doas obj/fsck_ffs -f /dev/sd3a > > 1m32.81s real 0m12.86s user 0m05.25s system > > > > The difference will be less if a fileystem is filled up, but still nice. > > Any takers? No feedback. I'm getting discouraged in doing more filesystem work... What to do? 1) Abondon the diff 2) Commit without ok I did quite extensive testing, but both options are unsatisfactory. -Otto > > > > > Index: fsck.h > > === > > RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v > > retrieving revision 1.32 > > diff -u -p -r1.32 fsck.h > > --- fsck.h 5 Jan 2018 09:33:47 - 1.32 > > +++ fsck.h 21 Jun 2020 12:48:50 - > > @@ -136,7 +136,6 @@ struct bufarea { > > struct bufarea bufhead;/* head of list of other blks in > > filesys */ > > struct bufarea sblk; /* file system superblock */ > > struct bufarea asblk; /* alternate file system superblock */ > > -struct bufarea cgblk; /* cylinder group blocks */ > > struct bufarea *pdirbp;/* current directory contents */ > > struct bufarea *pbp; /* current inode block */ > > struct bufarea *getdatablk(daddr_t, long); > > @@ -148,9 +147,7 @@ struct bufarea *getdatablk(daddr_t, long > > (bp)->b_flags = 0; > > > > #definesbdirty() sblk.b_dirty = 1 > > -#definecgdirty() cgblk.b_dirty = 1 > > #definesblock (*sblk.b_un.b_fs) > > -#definecgrp(*cgblk.b_un.b_cg) > > > > enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; > > > > @@ -275,9 +272,13 @@ struct ufs2_dinode ufs2_zino; > > #defineFOUND 0x10 > > > > union dinode *ginode(ino_t); > > +struct bufarea *cglookup(u_int cg); > > struct inoinfo *getinoinfo(ino_t); > > void getblk(struct bufarea *, daddr_t, long); > > ino_t allocino(ino_t, int); > > +void *Malloc(size_t); > > +void *Calloc(size_t, size_t); > > +void *Reallocarray(void *, size_t, size_t); > > > > int(*info_fn)(char *, size_t); > > char *info_filesys; > > Index: inode.c > > === > > RCS file: /cvs/src/sbin/fsck_ffs/inode.c,v > > retrieving revision 1.49 > > diff -u -p -r1.49 inode.c > > --- inode.c 16 Sep 2018 02:43:11 - 1.49 > > +++ inode.c 21 Jun 2020 12:48:50 - > > @@ -370,7 +370,7 @@ setinodebuf(ino_t inum) > > partialsize = inobufsize; > > } > > if (inodebuf == NULL && > > - (inodebuf = malloc((unsigned)inobufsize)) == NULL) > > + (inodebuf = Malloc((unsigned)inobufsize)) == NULL) > > errexit("Cannot allocate space for inode buffer\n"); > > } > > > > @@ -401,7 +401,7 @@ cacheino(union dinode *dp, ino_t inumber > > blks = howmany(DIP(dp, di_size), sblock.fs_bsize); > > if (blks > NDADDR) > > blks = NDADDR + NIADDR; > > - inp = malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); > > + inp = Malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); > > if (inp == NULL) > > errexit("cannot allocate memory for inode cache\n"); > > inpp = &inphead[inumber % numdirs]; > > @@ -423,10 +423,10 @@ cacheino(union dinode *dp, ino_t inumber > > inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); > > if (inplast == listmax) { > > newlistmax = listmax + 100; > > - newinpsort = reallocarray(inpsort, > > + newinpsort = Reallocarray(inpsort, > > (unsigned)newlistmax, sizeof(struct inoinfo *)); > > if (newinpsort == NULL) > > - errexit("cannot increase directory list"); > > + errexit("cannot increase directory list\n"); > > inpsort = newinpsort; > > listmax = newlistmax; > > } > > @@ -582,7 +582,8 @@ allocino(ino_t request, int type) > > { > > ino_t ino; > > union dinode *dp; > > - struct cg *cgp = &cgrp; > > + struct bufarea *cgbp; > > + struct cg *cgp; > > int cg; > > time_t t; > > struct inostat *info; > > @@ -602,7 +603,7 @@ allocino(ino_t request, int type) > > unsigned long newalloced, i; > > newalloced = MINIMUM(sblock.fs_ipg, > > MAXIMUM(2 * inostathead[cg].il_numalloced, 10)); > > - info = calloc(newalloced, sizeof(struct inostat)); > > + info = Calloc(newalloced, sizeof(struct inostat)); > > if (info == NULL) { > >
Re: fsck_ffs: faster with lots of cylinder groups
On Sun, Jun 21, 2020 at 03:35:21PM +0200, Otto Moerbeek wrote: > Hi, > > both phase 1 and phase 5 need cylinder group metadata. This diff > keeps the cg data read in phase 1 in memory to be used by phase 5 if > possible. From FreeBSD. > > -Otto > > On an empty 30T fileystem: > > $ time obj/fsck_ffs -f /dev/sd3a > 2m44.10s real 0m13.21s user 0m07.38s system > > $ time doas obj/fsck_ffs -f /dev/sd3a > 1m32.81s real 0m12.86s user 0m05.25s system > > The difference will be less if a fileystem is filled up, but still nice. Any takers? -Otto > > Index: fsck.h > === > RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v > retrieving revision 1.32 > diff -u -p -r1.32 fsck.h > --- fsck.h5 Jan 2018 09:33:47 - 1.32 > +++ fsck.h21 Jun 2020 12:48:50 - > @@ -136,7 +136,6 @@ struct bufarea { > struct bufarea bufhead; /* head of list of other blks in > filesys */ > struct bufarea sblk; /* file system superblock */ > struct bufarea asblk;/* alternate file system superblock */ > -struct bufarea cgblk;/* cylinder group blocks */ > struct bufarea *pdirbp; /* current directory contents */ > struct bufarea *pbp; /* current inode block */ > struct bufarea *getdatablk(daddr_t, long); > @@ -148,9 +147,7 @@ struct bufarea *getdatablk(daddr_t, long > (bp)->b_flags = 0; > > #define sbdirty() sblk.b_dirty = 1 > -#define cgdirty() cgblk.b_dirty = 1 > #define sblock (*sblk.b_un.b_fs) > -#define cgrp(*cgblk.b_un.b_cg) > > enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; > > @@ -275,9 +272,13 @@ struct ufs2_dinode ufs2_zino; > #define FOUND 0x10 > > union dinode *ginode(ino_t); > +struct bufarea *cglookup(u_int cg); > struct inoinfo *getinoinfo(ino_t); > void getblk(struct bufarea *, daddr_t, long); > ino_t allocino(ino_t, int); > +void *Malloc(size_t); > +void *Calloc(size_t, size_t); > +void *Reallocarray(void *, size_t, size_t); > > int (*info_fn)(char *, size_t); > char *info_filesys; > Index: inode.c > === > RCS file: /cvs/src/sbin/fsck_ffs/inode.c,v > retrieving revision 1.49 > diff -u -p -r1.49 inode.c > --- inode.c 16 Sep 2018 02:43:11 - 1.49 > +++ inode.c 21 Jun 2020 12:48:50 - > @@ -370,7 +370,7 @@ setinodebuf(ino_t inum) > partialsize = inobufsize; > } > if (inodebuf == NULL && > - (inodebuf = malloc((unsigned)inobufsize)) == NULL) > + (inodebuf = Malloc((unsigned)inobufsize)) == NULL) > errexit("Cannot allocate space for inode buffer\n"); > } > > @@ -401,7 +401,7 @@ cacheino(union dinode *dp, ino_t inumber > blks = howmany(DIP(dp, di_size), sblock.fs_bsize); > if (blks > NDADDR) > blks = NDADDR + NIADDR; > - inp = malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); > + inp = Malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); > if (inp == NULL) > errexit("cannot allocate memory for inode cache\n"); > inpp = &inphead[inumber % numdirs]; > @@ -423,10 +423,10 @@ cacheino(union dinode *dp, ino_t inumber > inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); > if (inplast == listmax) { > newlistmax = listmax + 100; > - newinpsort = reallocarray(inpsort, > + newinpsort = Reallocarray(inpsort, > (unsigned)newlistmax, sizeof(struct inoinfo *)); > if (newinpsort == NULL) > - errexit("cannot increase directory list"); > + errexit("cannot increase directory list\n"); > inpsort = newinpsort; > listmax = newlistmax; > } > @@ -582,7 +582,8 @@ allocino(ino_t request, int type) > { > ino_t ino; > union dinode *dp; > - struct cg *cgp = &cgrp; > + struct bufarea *cgbp; > + struct cg *cgp; > int cg; > time_t t; > struct inostat *info; > @@ -602,7 +603,7 @@ allocino(ino_t request, int type) > unsigned long newalloced, i; > newalloced = MINIMUM(sblock.fs_ipg, > MAXIMUM(2 * inostathead[cg].il_numalloced, 10)); > - info = calloc(newalloced, sizeof(struct inostat)); > + info = Calloc(newalloced, sizeof(struct inostat)); > if (info == NULL) { > pwarn("cannot alloc %zu bytes to extend inoinfo\n", > sizeof(struct inostat) * newalloced); > @@ -619,7 +620,8 @@ allocino(ino_t request, int type) > inostathead[cg].il_numalloced = newalloced; > info = inoinfo(ino); > } > - getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); > + cgbp = cglookup(cg); > + cgp = cgbp->b_
fsck_ffs: faster with lots of cylinder groups
Hi, both phase 1 and phase 5 need cylinder group metadata. This diff keeps the cg data read in phase 1 in memory to be used by phase 5 if possible. From FreeBSD. -Otto On an empty 30T fileystem: $ time obj/fsck_ffs -f /dev/sd3a 2m44.10s real 0m13.21s user 0m07.38s system $ time doas obj/fsck_ffs -f /dev/sd3a 1m32.81s real 0m12.86s user 0m05.25s system The difference will be less if a fileystem is filled up, but still nice. -Otto Index: fsck.h === RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v retrieving revision 1.32 diff -u -p -r1.32 fsck.h --- fsck.h 5 Jan 2018 09:33:47 - 1.32 +++ fsck.h 21 Jun 2020 12:48:50 - @@ -136,7 +136,6 @@ struct bufarea { struct bufarea bufhead;/* head of list of other blks in filesys */ struct bufarea sblk; /* file system superblock */ struct bufarea asblk; /* alternate file system superblock */ -struct bufarea cgblk; /* cylinder group blocks */ struct bufarea *pdirbp;/* current directory contents */ struct bufarea *pbp; /* current inode block */ struct bufarea *getdatablk(daddr_t, long); @@ -148,9 +147,7 @@ struct bufarea *getdatablk(daddr_t, long (bp)->b_flags = 0; #definesbdirty() sblk.b_dirty = 1 -#definecgdirty() cgblk.b_dirty = 1 #definesblock (*sblk.b_un.b_fs) -#definecgrp(*cgblk.b_un.b_cg) enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; @@ -275,9 +272,13 @@ struct ufs2_dinode ufs2_zino; #defineFOUND 0x10 union dinode *ginode(ino_t); +struct bufarea *cglookup(u_int cg); struct inoinfo *getinoinfo(ino_t); void getblk(struct bufarea *, daddr_t, long); ino_t allocino(ino_t, int); +void *Malloc(size_t); +void *Calloc(size_t, size_t); +void *Reallocarray(void *, size_t, size_t); int(*info_fn)(char *, size_t); char *info_filesys; Index: inode.c === RCS file: /cvs/src/sbin/fsck_ffs/inode.c,v retrieving revision 1.49 diff -u -p -r1.49 inode.c --- inode.c 16 Sep 2018 02:43:11 - 1.49 +++ inode.c 21 Jun 2020 12:48:50 - @@ -370,7 +370,7 @@ setinodebuf(ino_t inum) partialsize = inobufsize; } if (inodebuf == NULL && - (inodebuf = malloc((unsigned)inobufsize)) == NULL) + (inodebuf = Malloc((unsigned)inobufsize)) == NULL) errexit("Cannot allocate space for inode buffer\n"); } @@ -401,7 +401,7 @@ cacheino(union dinode *dp, ino_t inumber blks = howmany(DIP(dp, di_size), sblock.fs_bsize); if (blks > NDADDR) blks = NDADDR + NIADDR; - inp = malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); + inp = Malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); if (inp == NULL) errexit("cannot allocate memory for inode cache\n"); inpp = &inphead[inumber % numdirs]; @@ -423,10 +423,10 @@ cacheino(union dinode *dp, ino_t inumber inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); if (inplast == listmax) { newlistmax = listmax + 100; - newinpsort = reallocarray(inpsort, + newinpsort = Reallocarray(inpsort, (unsigned)newlistmax, sizeof(struct inoinfo *)); if (newinpsort == NULL) - errexit("cannot increase directory list"); + errexit("cannot increase directory list\n"); inpsort = newinpsort; listmax = newlistmax; } @@ -582,7 +582,8 @@ allocino(ino_t request, int type) { ino_t ino; union dinode *dp; - struct cg *cgp = &cgrp; + struct bufarea *cgbp; + struct cg *cgp; int cg; time_t t; struct inostat *info; @@ -602,7 +603,7 @@ allocino(ino_t request, int type) unsigned long newalloced, i; newalloced = MINIMUM(sblock.fs_ipg, MAXIMUM(2 * inostathead[cg].il_numalloced, 10)); - info = calloc(newalloced, sizeof(struct inostat)); + info = Calloc(newalloced, sizeof(struct inostat)); if (info == NULL) { pwarn("cannot alloc %zu bytes to extend inoinfo\n", sizeof(struct inostat) * newalloced); @@ -619,7 +620,8 @@ allocino(ino_t request, int type) inostathead[cg].il_numalloced = newalloced; info = inoinfo(ino); } - getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); + cgbp = cglookup(cg); + cgp = cgbp->b_un.b_cg; if (!cg_chkmagic(cgp)) pfatal("CG %d: BAD MAGIC NUMBER\n", cg); setbit(cg_inosused(cgp), ino % sblock.fs_ipg); @@ -637,7 +639,7 @@ allocino(ino_t request, int type