@@ -720,6 +720,38 @@ module Make(Sectors: Mirage_block.S)(Clock : Mirage_clock.PCLOCK) = struct
720720
721721 end
722722
723+ (* [block_size_device] is the block size used by the underlying block device which
724+ * we're trying to mount a filesystem from,
725+ * as opposed to the block size recorded in the filesystem's superblock *)
726+ let check_superblock ~program_block_size ~block_size_device cs =
727+ match Chamelon.Block. of_cstruct ~program_block_size cs with
728+ | Error (`Msg s ) ->
729+ Log. err (fun f -> f " error parsing block when checking superblock: %s" s);
730+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
731+ | Ok parsed_block ->
732+ (* does this block have the expected superblock entries? *)
733+ (* the order of entries is strictly specified: name, then the inline struct, then
734+ * any other entries in the superblock *)
735+ match Chamelon.Block. entries parsed_block with
736+ | maybe_name :: maybe_struct :: _ when
737+ Chamelon.Superblock. is_valid_name maybe_name &&
738+ Chamelon.Superblock. is_valid_superblock maybe_struct -> begin
739+ match Chamelon.Superblock. parse (snd maybe_struct) with
740+ | Error (`Msg s ) ->
741+ Log. err (fun f -> f " error parsing block when checking superblock: %s" s);
742+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
743+ | Ok sb ->
744+ if sb.version_major != fst Chamelon.Superblock. version then begin
745+ Log. err (fun f -> f " filesystem is an incompatible version" );
746+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
747+ end else if not @@ Int32. equal sb.block_size block_size_device then begin
748+ Log. err (fun f -> f " filesystem expects a block device with size %ld but the device block size is %ld" sb.block_size block_size_device);
749+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
750+ end else Lwt. return @@ Ok ()
751+ end
752+ | _ -> Log. err (fun f -> f " expected entries not found on parsed superblock" );
753+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
754+
723755 (* `device` should be an already-connected block device *)
724756 let connect ~program_block_size ~block_size device : (t, error) result Lwt.t =
725757 This_Block. connect ~block_size device >> = fun block ->
@@ -728,23 +760,27 @@ module Make(Sectors: Mirage_block.S)(Clock : Mirage_clock.PCLOCK) = struct
728760 This_Block. read block 0L [first_block] >> = function
729761 | Error e ->
730762 Log. err (fun f -> f " first block read failed: %a" This_Block. pp_error e);
731- Lwt. return @@ Error (`Not_found ( Mirage_kv.Key. empty) )
763+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
732764 | Ok () ->
733- let lookahead = ref {offset = 0 ; blocks = [] } in
734- let t = {block; block_size; program_block_size; lookahead; new_block_mutex = Lwt_mutex. create () } in
735- Lwt_mutex. lock t.new_block_mutex >> = fun () ->
736- Traverse. follow_links t [] (Chamelon.Entry. Metadata root_pair) >> = function
737- | Error _e ->
738- Lwt_mutex. unlock t.new_block_mutex;
739- Log. err (fun f -> f " couldn't get list of used blocks" );
740- Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
741- | Ok used_blocks ->
742- Log. debug (fun f -> f " found %d used blocks on block-based key-value store: %a" (List. length used_blocks) Fmt. (list ~sep: sp int64 ) used_blocks);
743- let open Allocate in
744- let offset, blocks = unused t used_blocks in
745- let lookahead = ref {blocks; offset} in
746- Lwt_mutex. unlock t.new_block_mutex;
747- Lwt. return @@ Ok {t with lookahead; block; block_size; program_block_size}
765+ (* make sure the block is parseable and block size matches *)
766+ check_superblock ~program_block_size ~block_size_device: (Int32. of_int block_size) first_block >> = function
767+ | Error _ as e -> Lwt. return e
768+ | Ok () ->
769+ let lookahead = ref {offset = 0 ; blocks = [] } in
770+ let t = {block; block_size; program_block_size; lookahead; new_block_mutex = Lwt_mutex. create () } in
771+ Lwt_mutex. lock t.new_block_mutex >> = fun () ->
772+ Traverse. follow_links t [] (Chamelon.Entry. Metadata root_pair) >> = function
773+ | Error _e ->
774+ Lwt_mutex. unlock t.new_block_mutex;
775+ Log. err (fun f -> f " couldn't get list of used blocks" );
776+ Lwt. return @@ Error (`Not_found Mirage_kv.Key. empty)
777+ | Ok used_blocks ->
778+ Log. debug (fun f -> f " found %d used blocks on block-based key-value store: %a" (List. length used_blocks) Fmt. (list ~sep: sp int64 ) used_blocks);
779+ let open Allocate in
780+ let offset, blocks = unused t used_blocks in
781+ let lookahead = ref {blocks; offset} in
782+ Lwt_mutex. unlock t.new_block_mutex;
783+ Lwt. return @@ Ok {t with lookahead; block; block_size; program_block_size}
748784
749785 let format ~program_block_size ~block_size (sectors : Sectors.t ) :
750786 (unit , write_error ) result Lwt. t =
0 commit comments