misc/113889: fsck_ffs does not do mount reload when preening mounted gjournal fs

Niki Denev niki at totalterror.net
Wed Jun 20 21:00:13 UTC 2007


>Number:         113889
>Category:       misc
>Synopsis:       fsck_ffs does not do mount reload when preening mounted gjournal fs
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 20 21:00:12 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Niki Denev
>Release:        7.0-CURRENT
>Organization:
>Environment:
FreeBSD nomad.totalterror.net 7.0-CURRENT FreeBSD 7.0-CURRENT #7: Wed Jun 20 02:07:10 UTC 2007 root at nomad.totalterror.net:/usr/obj/usr/src/sys/PCGU3 i386
>Description:
When using a gjournaled ffs as root filesystem and it has been marked unclead due to power failure, etc. on the next reboot fsck_ffs in preed mode will try to do the minimal garbage collection needed for gjournaled filesystems and mark it clean. The problem is when this is root filesystem, as it is already mounted read-only and to propagate the changes to the filesystem (being marked clean) fsck needs to do MNT_RELOAD so the superblock can be re-read from the disk, otherwise the kernel complains that the filesystem is still dirty, regardless of the fact that on-disk it is already checked and marked clean.
>How-To-Repeat:
Unplug your power while using gjournaled ffs as root filesystem, and then on the next boot r/w remount after fsck will fail and you will be dropped to shell to do manual fsck.
>Fix:
The attached patch works for me, and makes two of my machines startup normally when booted with unclean root filesystems.

Patch attached with submission follows:

--- src/sbin/fsck_ffs/main.c.orig	Wed Jun 20 22:55:58 2007
+++ src/sbin/fsck_ffs/main.c	Wed Jun 20 23:42:03 2007
@@ -67,6 +67,7 @@
 static void usage(void) __dead2;
 static int argtoi(int flag, const char *req, const char *str, int base);
 static int checkfilesys(char *filesys);
+static int chkdoreload(struct statfs *mntp);
 static struct statfs *getmntpt(const char *);
 
 int
@@ -253,7 +254,10 @@
 			}
 			if ((sblock.fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0) {
 				gjournal_check(filesys);
-				exit(0);
+				ret = chkdoreload(mntp);
+				if (ret == 0)
+					exit(0);
+				exit(4);
 			} else {
 				pfatal("UNEXPECTED INCONSISTENCY, %s\n",
 				    "CANNOT RUN FAST FSCK\n");
@@ -483,29 +487,45 @@
 		printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
 	if (rerun)
 		printf("\n***** PLEASE RERUN FSCK *****\n");
-	if (mntp != NULL) {
-		/*
-		 * We modified a mounted file system.  Do a mount update on
-		 * it unless it is read-write, so we can continue using it
-		 * as safely as possible.
-		 */
-		if (mntp->f_flags & MNT_RDONLY) {
-			args.fspec = 0;
-			args.export.ex_flags = 0;
-			args.export.ex_root = 0;
-			ret = mount("ufs", mntp->f_mntonname,
-			    mntp->f_flags | MNT_UPDATE | MNT_RELOAD, &args);
-			if (ret == 0)
-				return (0);
-			pwarn("mount reload of '%s' failed: %s\n\n",
-			    mntp->f_mntonname, strerror(errno));
-		}
+	ret = chkdoreload(mntp);
+	if (ret) {
 		if (!fsmodified)
 			return (0);
 		if (!preen)
 			printf("\n***** REBOOT NOW *****\n");
 		sync();
 		return (4);
+	}
+	return (0);
+}
+
+static int
+chkdoreload(struct statfs *mntp)
+{
+	struct ufs_args args;
+	int ret;
+
+	if (mntp == NULL)
+		return (0);
+	/*
+	 * We modified a mounted file system.  Do a mount update on
+	 * it unless it is read-write, so we can continue using it
+	 * as safely as possible.
+	 */
+	if (mntp->f_flags & MNT_RDONLY) {
+		memset(&args, 0, sizeof args);
+		/*
+		 * args.fspec = 0;
+		 * args.export.ex_flags = 0;
+		 * args.export.ex_root = 0;
+		 */
+		ret = mount("ufs", mntp->f_mntonname,
+		    mntp->f_flags | MNT_UPDATE | MNT_RELOAD, &args);
+		if (ret == 0)
+			return (0);
+		pwarn("mount reload of '%s' failed: %s\n\n",
+		    mntp->f_mntonname, strerror(errno));
+		return (1);
 	}
 	return (0);
 }


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list