summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu/build/file-systems.scm24
1 files changed, 24 insertions, 0 deletions
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index b06a4cc25c..1d3b33e7bd 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -52,6 +52,8 @@
             read-partition-uuid
             read-luks-partition-uuid
 
+            cleanly-unmounted-ext2?
+
             bind-mount
 
             system*/tty
@@ -193,6 +195,23 @@ NUL terminator, return the size of the bytevector."
 if DEVICE does not contain an ext2 file system."
   (read-superblock device 1024 264 ext2-superblock?))
 
+(define (ext2-superblock-cleanly-unmounted? sblock)
+  "Return true if SBLOCK denotes a file system that was cleanly unmounted,
+false otherwise."
+  (define EXT2_VALID_FS 1)                        ;cleanly unmounted
+  (define EXT2_ERROR_FS 2)                        ;errors detected
+
+  (define EXT3_FEATURE_INCOMPAT_RECOVER #x0004)   ;journal needs recovery
+
+  (let ((state (bytevector-u16-ref sblock 58 %ext2-endianness)))
+    (cond ((= state EXT2_VALID_FS)
+           (let ((incompatible-features
+                  (bytevector-u32-ref sblock 96 %ext2-endianness)))
+             (zero? (logand incompatible-features
+                            EXT3_FEATURE_INCOMPAT_RECOVER))))
+          ((= state EXT2_ERROR_FS) #f)
+          (else (error "invalid ext2 superblock state" state)))))
+
 (define (ext2-superblock-uuid sblock)
   "Return the UUID of ext2 superblock SBLOCK as a 16-byte bytevector."
   (sub-bytevector sblock 104 16))
@@ -220,6 +239,11 @@ errors.  Otherwise, fix only those considered safe to repair automatically."
     (2 'reboot-required)
     (_ 'fatal-error)))
 
+(define (cleanly-unmounted-ext2? device)          ;convenience procedure
+  "Return true if DEVICE is an ext2 file system and if it was cleanly
+unmounted."
+  (ext2-superblock-cleanly-unmounted? (read-ext2-superblock device)))
+
 
 ;;;
 ;;; Linux swap.