Date: Mon, 6 May 2019 19:15:59 +0000 (UTC) From: Kirk McKusick <mckusick@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r347200 - stable/11/sbin/fsck_ffs Message-ID: <201905061915.x46JFxBY004453@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mckusick Date: Mon May 6 19:15:59 2019 New Revision: 347200 URL: https://svnweb.freebsd.org/changeset/base/347200 Log: MFC of 346185 Properly calculate last block of large sparse files. Sponsored by: Netflix Modified: stable/11/sbin/fsck_ffs/fsck.h stable/11/sbin/fsck_ffs/inode.c stable/11/sbin/fsck_ffs/pass1.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sbin/fsck_ffs/fsck.h ============================================================================== --- stable/11/sbin/fsck_ffs/fsck.h Mon May 6 19:13:04 2019 (r347199) +++ stable/11/sbin/fsck_ffs/fsck.h Mon May 6 19:15:59 2019 (r347200) @@ -229,6 +229,7 @@ struct inodesc { ino_t id_parent; /* for DATA nodes, their parent */ ufs_lbn_t id_lbn; /* logical block number of current block */ ufs2_daddr_t id_blkno; /* current block number being examined */ + int id_level; /* level of indirection of this block */ int id_numfrags; /* number of frags contained in block */ ufs_lbn_t id_lballoc; /* pass1: last LBN that is allocated */ off_t id_filesize; /* for DATA nodes, the size of the directory */ Modified: stable/11/sbin/fsck_ffs/inode.c ============================================================================== --- stable/11/sbin/fsck_ffs/inode.c Mon May 6 19:13:04 2019 (r347199) +++ stable/11/sbin/fsck_ffs/inode.c Mon May 6 19:15:59 2019 (r347200) @@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$"); static ino_t startinum; -static int iblock(struct inodesc *, long ilevel, off_t isize, int type); +static int iblock(struct inodesc *, off_t isize, int type); int ckinode(union dinode *dp, struct inodesc *idesc) @@ -67,6 +67,8 @@ ckinode(union dinode *dp, struct inodesc *idesc) if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_lbn = -1; + idesc->id_lballoc = -1; + idesc->id_level = 0; idesc->id_entryno = 0; idesc->id_filesize = DIP(dp, di_size); mode = DIP(dp, di_mode) & IFMT; @@ -119,9 +121,10 @@ ckinode(union dinode *dp, struct inodesc *idesc) sizepb = sblock.fs_bsize; for (i = 0; i < NIADDR; i++) { sizepb *= NINDIR(&sblock); + idesc->id_level = i + 1; if (DIP(&dino, di_ib[i])) { idesc->id_blkno = DIP(&dino, di_ib[i]); - ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i); + ret = iblock(idesc, remsize, BT_LEVEL1 + i); if (ret & STOP) return (ret); } else if (remsize > 0) { @@ -151,7 +154,7 @@ ckinode(union dinode *dp, struct inodesc *idesc) } static int -iblock(struct inodesc *idesc, long ilevel, off_t isize, int type) +iblock(struct inodesc *idesc, off_t isize, int type) { struct bufarea *bp; int i, n, (*func)(struct inodesc *), nif; @@ -169,8 +172,8 @@ iblock(struct inodesc *idesc, long ilevel, off_t isize if (chkrange(idesc->id_blkno, idesc->id_numfrags)) return (SKIP); bp = getdatablk(idesc->id_blkno, sblock.fs_bsize, type); - ilevel--; - for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) + idesc->id_level--; + for (sizepb = sblock.fs_bsize, i = 0; i < idesc->id_level; i++) sizepb *= NINDIR(&sblock); if (howmany(isize, sizepb) > NINDIR(&sblock)) nif = NINDIR(&sblock); @@ -192,19 +195,21 @@ iblock(struct inodesc *idesc, long ilevel, off_t isize flush(fswritefd, bp); } for (i = 0; i < nif; i++) { - if (ilevel == 0) - idesc->id_lbn++; if (IBLK(bp, i)) { idesc->id_blkno = IBLK(bp, i); - if (ilevel == 0) + if (idesc->id_level == 0) { + idesc->id_lbn++; n = (*func)(idesc); - else - n = iblock(idesc, ilevel, isize, type); + } else { + n = iblock(idesc, isize, type); + idesc->id_level++; + } if (n & STOP) { bp->b_flags &= ~B_INUSE; return (n); } } else { + idesc->id_lbn += sizepb / sblock.fs_bsize; if (idesc->id_type == DATA && isize > 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, idesc->id_number, Modified: stable/11/sbin/fsck_ffs/pass1.c ============================================================================== --- stable/11/sbin/fsck_ffs/pass1.c Mon May 6 19:13:04 2019 (r347199) +++ stable/11/sbin/fsck_ffs/pass1.c Mon May 6 19:15:59 2019 (r347200) @@ -376,7 +376,6 @@ checkinode(ino_t inumber, struct inodesc *idesc, int r idesc->id_type = SNAP; else idesc->id_type = ADDR; - idesc->id_lballoc = -1; (void)ckinode(dp, idesc); if (sblock.fs_magic == FS_UFS2_MAGIC && dp->dp2.di_extsize > 0) { idesc->id_type = ADDR; @@ -563,7 +562,7 @@ pass1check(struct inodesc *idesc) */ idesc->id_entryno++; } - if (idesc->id_lballoc == -1 || idesc->id_lballoc < idesc->id_lbn) + if (idesc->id_level == 0 && idesc->id_lballoc < idesc->id_lbn) idesc->id_lballoc = idesc->id_lbn; return (res); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905061915.x46JFxBY004453>