From nobody Sun Feb 20 21:21:32 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 2FB0D19D136C; Sun, 20 Feb 2022 21:21:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4K1yzd0trCz3kJ0; Sun, 20 Feb 2022 21:21:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1645392093; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=X/7ZDyaCTEFDYFlXzlLB6rh1ZuLA4IWaCxzb3hWvxeg=; b=gAZGW5LpIneR1T+taeiGFpmIcPoiaM6OkbxIrPN3PtBsgWtbkwTuVFIOmrygrsJ+D3eYUa eFocNoRD4vBEuclUxxqOxQ4Qa7cg7apV6cgRqUfXA6XkK5ls8oeYgBzTbx4h2SPVkIMcnQ GP5JtmK+kImnj9wh+1UwhkGt7c16uTWAdLPbxrH6SMBnumkART4MMDY74VN2be0xivuq1k vc3h75Fzfb+Mq8sdtply6wUULVS2pS9O9Q+snzH2Ja15G4S6NPCceqCV+mk/ngJsSXWs/P /b+gqegJPZEACEI4LFaSij90EDELaUZQNY/rVIdprTsAMhZsDP7KKVadNkO/2g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id F28D6234F2; Sun, 20 Feb 2022 21:21:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 21KLLWD8077226; Sun, 20 Feb 2022 21:21:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 21KLLW7t077225; Sun, 20 Feb 2022 21:21:32 GMT (envelope-from git) Date: Sun, 20 Feb 2022 21:21:32 GMT Message-Id: <202202202121.21KLLW7t077225@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kirk McKusick Subject: git: 7a1c1f6a0332 - main - Avoid unaligned writes by fsck_ffs(8). List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7a1c1f6a0332c5b60349a5df0e3ce64e5005b2ff Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1645392093; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=X/7ZDyaCTEFDYFlXzlLB6rh1ZuLA4IWaCxzb3hWvxeg=; b=EzM52QTF9yH1sEokPNilMjPf7nUxhcaOKiZ1BXtlrUPObKF846w9bIS6V1RTza+9G/qTD6 WFCqplY0eHFf6O+6lhVOoJD+yTjVTPXdGagdzJ2wuOQQ1VPF19Rx6BOnCconhdluQeNZgz mi3cWHuWHBEQwKJHNMxLfQjgmVPAOwqsszE5a5CqHhI7SwZvkyJIYshOGVIG4gtYwP4YP5 cf/GbanhK/8cxE5ngaHs6/dFIvZ3/jnH/ahyAc46ouH6IKrsvGtkasWXPUoVu/kP4qNEFU g2CNU6it9tniPUh6wxQjoLEsaZDbnF5AlBKxuyqzK5aY4B/BHNyC87rhhDcCVA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1645392093; a=rsa-sha256; cv=none; b=KJykbogVOLz7ePk0MoAPheUIDIATr606Sl4bGn13BKayABUPiEuHbGv9VYOTR57j4vQig2 liHZDX5+2CnbFTr6uM+fy4OGGoCpzHR2lfbAHH2tKjBWccS4MhyeDyi8Mu+e8NOEF6I54V MRz+moEUhslQsv8Tb8pqmmWP7N9pChd76MCh2Ay50zbY+xuw2zrI5zwAi5KIqMdT8FcZli q2TMMZ14N0TxDHlYXLry+tRzRlvw1YT+ipbthUApw4LFfbVrReHTocQMArncTc6Ui/zlAS IPZeCPQCfxwtFeBs9+RA/ux9ZC5tGilUNlCd8AGOfl1Lsh4JY+yYg63bN569bg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=7a1c1f6a0332c5b60349a5df0e3ce64e5005b2ff commit 7a1c1f6a0332c5b60349a5df0e3ce64e5005b2ff Author: Kirk McKusick AuthorDate: 2022-02-20 21:18:05 +0000 Commit: Kirk McKusick CommitDate: 2022-02-20 21:21:12 +0000 Avoid unaligned writes by fsck_ffs(8). Normally fsck_ffs never does reads or writes that are not aligned to the size of one of the checked filesystems fragments. The one exception is when it finds that it needs to write the superblock recovery information. Here it will write with the alignment reported by the underlying disk as its sector size as reported by an ioctl(diskfd, DIOCGSECTORSIZE, &secsize). Modern disks have a sector size of 4096, but for backward compatibility with older disks will report that they have a sector size of 512. When presented with a 512 byte write, they have to read the associated 4096 byte sector, replace the 512 bytes to be written, and write the updated 4096 byte sector back to the disk. Unfortunately, some disks report that they have 512 sectors, but fail writes that are not aligned to 4096 boundaries and are a multiple of 4096 bytes in size. This commit updates fsck_ffs(8) so that it uses the filesystem fragment size as the smallest size and alignment for doing writes rather than the disk's reported sector size. Reported by: Andriy Gapon MFC after: 1 week --- sbin/fsck_ffs/setup.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 506a027f40ac..bbb8a854e999 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -399,17 +399,19 @@ chkrecovery(int devfd) { struct fsrecovery *fsr; char *fsrbuf; - u_int secsize; + u_int secsize, rdsize; /* * Could not determine if backup material exists, so do not * offer to create it. */ fsrbuf = NULL; + rdsize = sblock.fs_fsize; if (ioctl(devfd, DIOCGSECTORSIZE, &secsize) == -1 || - (fsrbuf = Malloc(secsize)) == NULL || - blread(devfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize, - secsize) != 0) { + rdsize % secsize != 0 || + (fsrbuf = Malloc(rdsize)) == NULL || + blread(devfd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize, + rdsize) != 0) { free(fsrbuf); return (1); } @@ -417,7 +419,7 @@ chkrecovery(int devfd) * Recovery material has already been created, so do not * need to create it again. */ - fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr]; + fsr = (struct fsrecovery *)&fsrbuf[rdsize - sizeof *fsr]; if (fsr->fsr_magic == FS_UFS2_MAGIC) { free(fsrbuf); return (1); @@ -430,8 +432,8 @@ chkrecovery(int devfd) } /* - * Read the last sector of the boot block, replace the last - * 20 bytes with the recovery information, then write it back. + * Read the last filesystem-size piece of the boot block, replace the + * last 20 bytes with the recovery information, then write it back. * The recovery information only works for UFS2 filesystems. */ static void @@ -439,24 +441,26 @@ saverecovery(int readfd, int writefd) { struct fsrecovery *fsr; char *fsrbuf; - u_int secsize; + u_int secsize, rdsize; fsrbuf = NULL; + rdsize = sblock.fs_fsize; if (sblock.fs_magic != FS_UFS2_MAGIC || ioctl(readfd, DIOCGSECTORSIZE, &secsize) == -1 || - (fsrbuf = Malloc(secsize)) == NULL || - blread(readfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize, - secsize) != 0) { + rdsize % secsize != 0 || + (fsrbuf = Malloc(rdsize)) == NULL || + blread(readfd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize, + rdsize) != 0) { printf("RECOVERY DATA COULD NOT BE CREATED\n"); free(fsrbuf); return; } - fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr]; + fsr = (struct fsrecovery *)&fsrbuf[rdsize - sizeof *fsr]; fsr->fsr_magic = sblock.fs_magic; fsr->fsr_fpg = sblock.fs_fpg; fsr->fsr_fsbtodb = sblock.fs_fsbtodb; fsr->fsr_sblkno = sblock.fs_sblkno; fsr->fsr_ncg = sblock.fs_ncg; - blwrite(writefd, fsrbuf, (SBLOCK_UFS2 - secsize) / secsize, secsize); + blwrite(writefd, fsrbuf, (SBLOCK_UFS2 - rdsize) / dev_bsize, rdsize); free(fsrbuf); }