Dirty flag
============================

Overview

    A volume is "dirty" if we cannot guarantee that an incremental
    snapshot being applied to previous snapshot will produce a reliable image.

    All volumes are dirty by default . That is, the user must start with a
    base snapshot. A volume becomes clean once an on-disk changelog store is
    mapped and the block tree is populated. It is the user's responsibility to
    make sure no writing to the volume occur prior to attachment.

    Logic of dirty flag mutations is resistant to sequence of mapping
    metadata store and changelog store.

Dirty flag mutations

    1. Initialization of volume
        Use case:   bsctl --attach-to-device /dev/xxxx
        Location:   blksnap-main.c: attach_volume()
        Turns true: always
        changed_while_detached = true: if volume has been attached being mounted
            in rw mode.
        changed_while_detached = false: in otherwise.

    2. Сompletion of snapshot.
        Use case:    bsctl --complete-snapshot /dev/xxxx
        Location:    blksnap-main.c: void stop_snapshot()
        Turns false: if snapshot has been completed by command
            <bsctl --complete-snapshot /dev/xxxx>.

    3. Mapping metadata store
        Use case:    bsctl --map-metadata /dev/xxxx
        Location:    blksnap-main.c: blksnap_ioctl_map_metadata()
        Turns true:  if changelog is mapped and volume was attached while it's
            being mounted in rw mode.
        Turns false: if volume was attached while it isn't being mounted in rw
            mode and hash-sum of volume superblock matches .blksnap/metadata.
        Description:
            Dirty and changed_while_detached flags are initialised by true and
            false respectively during allocating volume (see 1. Initialization).
            Afterwards, before metadata mapping occurs, their values may vary
            due to snapshot completion (see 2) or changelog mapping (see 4).

            Within mapping metadata procedure there are two strong conditions
            for flags input values:
            dirty == false - only if snapshot had been completed.
            changed_while_detached == true - only if volume has been attached
            being mounted in rw mode.

            If one of these conditions presents (see (1), (2), (5), (6) in
            matrix), superblock' hash-sum validation is ignored. That is, if
            the volume has been attached being mounted in rw, superblock hash
            will be different from .blksnap/metadata value due to mount-counter
            in struct of superblock. From the other side - if snapshot had been
            completed - changelog is pruned (also, this flag state covers use
            case of module update to version >= 5.4 - when metadata store
            feature is only appears and blksnap had no store file).

            If one of flags matches its initial state (see (3), (4), (7), (8)) -
            the result will depend on superblock' hash sum value and changelog
            state.

            Logical matrix:
                Statements:
                    C - changed_while_detached input value
                    D - dirty input value
                    H - hash_sums_equals() result.
                If cl_store_valid(volume->clstore) == true
                    | D | С | H || D | C |
                    | 0 | - | - || 0 | 0 | (1)
                    | 1 | 1 | - || 1 | 1 | (2)
                    | 1 | 0 | 0 || 1 | 1 | (3)
                    | 1 | 0 | 1 || 0 | 0 | (4)
                If cl_store_valid(volume->clstore) == false
                    | D | С | H || D | C |
                    | 0 | - | - || 0 | 0 | (5)
                    | 1 | 1 | - || 1 | 1 | (6)
                    | 1 | 0 | 0 || 1 | 1 | (7)
                    | 1 | 0 | 1 || 1 | 0 | (8)

    4. Updating metadata store
        Use case:    bsctl --update-metadata-store /dev/xxx
        Location:    blksnap-main.c: blksnap_ioctl_map_metadata()
        Turns true:  if volume has been attached when it was mounted in rw.
        Turns false: if volume has been attached when it wasn't mounted in rw.
        Description: this command is applies to volumes after roll-back to reha-
            bilitate their consistency.  

    5. Mapping changelog store
        Use case:   bsctl --map-chlog-store /dev/xxx
        Location:   blksnap-main.c: blksnap_ioctl_map_chlog()
        Turns true: during merging changelog store: if an error has been
            occurred while copying blocks from .blksnap/changelog to changelog
            tree.
        Turns false: after mapping changelog if:
            - mapping of changelog store has been completed succesfully,
            - metadata is mapped,
            - mapping of metadata reveals that hash-sum of volume' superblock
              matches .blksnap/metadata,
            - volume hadn't been being mounted in rw-mode at the attach.

    6. Accumulation of changelog tree or store
        Use case:   any write request to attached volume.
        Location:   blksnap-snapshot.c: filter_write_copy() and
            filter_write_record().
        Turns true: if an error has occured while inserting requested block to
            the changelog tree or to the changelog buffer.
