What is the structure of a transaction ID.  This is generated by the client
(or transaction manager) and is passed through to the disk by Lfs.

Can't store the next Lsn in a log record header because its exact location
may not be known when a log record is being written (in-memory) or a
page block is being written to disk.  This is because the write to disk
may occur before the next log record is received and there is no way to
know if it will fit in the remaining part of the file or will wrap and
be written to the beginning of the file.

Log records that require multi-page allocation blocks will begin at the
beginning of a page block.  Then the fields which describe the data shift
can be in a page header record and not a log record header.

We restrict the data size of a log record to 32 bits.

Log record types:  We have an enumerated type for all log record, not
a main type and subtypes.  i.e. all commit protocol records are defined
at the top level.

Multi-page blocks:  Page headers indicate whether they are the first
or last page.  During Lfs restart these pages may be walked through.
As far as the analysis algorithm goes, these can be thought of as a
single unit.  All page(s) must be found or this will be considered
a bad page(s), the next page then must be read to discover if this is
a fatal error or the point where the system crashed.

Looking up multipage via Lsn:  Given Lsn pin appropriate page and look
at log record.  If single page then done.  Otherwise, unpin page and
pin multiple pages.

For what operations do we need to check the update sequence array in
the page headers.

Log file header prior to restart areas.  This will be a single system page
and contain the log file base values which will allow both copies of the
restart area to be found.  This information will be duplicated in the restart
areas so that if the sector containing the file header goes bad, an
intelligent choice can be made for where to search for the first Lfs
restart area.  (Or we could duplicate it in the first x sectors).

Should we checksum the log file header.

Added client Id to the log record header.

Is it reasonable to use a USHORT to index into the client array and a USHORT
for the client sequence number.

Do we even need a sequence number.  Will the index number be sufficient to
walk forward through the log records.  When will the index be reused, only
when a client closes his loghandle.  In that case it will be impossible to
start searching from an out of date Lsn.

Change InitializeReadContext to LfsContextReadFirst and return the first Lsn.
Read Next is LfsContextReadNext.

May not need the LfsPreviousLsn in the log record header.

Log record enumeration.  Walking forwards, client will probably run
out unexpectedly.

Log record enumeration.  Walking backwards, take Lsn, determine Log page
boundary.  Pin log page, if multiple pages unpin and repin multiple pages.

Walking backwards, how likely are we to want to stay in the same log
page for several records.

Enumerating.  It is possible we are pinning pages for read and may be trying
to write them at the same time.

If we have a page pinned multiple times, will that prevent it from being
flushed with a ccflush call.

Will a client want to look at several log records at once, or only one
at a time.  The current interface supports only one at a time.

LOG CONTEXT BLOCK

        No synchronization of access to the log context block.  Client
        shares the block at his own risk.

        How to resolve that enumeration may pin (for a while) a block of
        pages that are trying to be flushed.

        Enumeration (in the forward direction) may be trying to read a lsn
        as it is being written.  Solution, write the log record before updating
        the last Lsn in the page header.

        This may make the LastLsn number in the context block obsolete as it
        may be outdated.  However, any later Lsn's wouldn't have existed when
        the client started this call.  Should we hide all new log records
        from him.

Log file.  How big may it be (ULONG, LARGE_INT)

Log buffer control block.  Access via global spinlock.  Sets up frame for
next write and then releases it.  Count is kept in block of active writers,
can't be flushed until active count is zero.  Does this make sense, how
do we wait until active count is zero.

Lsn should be 96 bits.  64 bit file offset and 32 bit sequence value.
The interface with the Lfs provides that the address of this structure
be passed.

Is it expensive to allocate and deallocate an event each time a new buffer
is used.

Can the restart areas offset safely be a ULONG.

How can log service initiate a sector revectoring.

Start log file sequence number at 1, then 0 indicates we have just wrapped.

Since write operations to the log file must be serialized, there is no
reason not to let the worker thread perform all the writes.

Operations:

    Given an Lsn:

        Find the next Lsn
        Find the previous client Lsn
        Find the client undo next lsn.

    Given a log record.

        Find the client owner of the record
        Find the transaction ID for the record

    Log context blocks

        Allocate and deallocate
        Write into the fields.
        Determine if the next/prev Lsn resides in the same block of pages.
        Pin and unpin pages in the log file.
        Allocate and deallocate the user's buffer.
        Synchronize access to the context block (is this needed)

    Log client area

        Allocate and deallocate
        Verify the client as valid.

    Log buffer control blocks

        Allocate and deallocate
        Link into control block list for a particular log file.
        Allocate and deallocate buffer associated with control block.
        Determine the size required for the buffer.
        Determine where buffer fits in log file.
        Determine where the next log record should be in the buffer.
        Determine when all the authorized writes to the file have completed.
        Syncronize access to the fields of the contol block.
        Find the last Lsn for the page block.
        Determine when the flush operation to the log file has completed.
        Determine if the flush operation to the file was successful.
        Determine if the next log record fits in this buffer.
        Determine if user thread can be used to write log pages to the log file


    Log file control block.

        Allocate/Deallocate structure.
        Link log file control blocks to global record
        Know whether the sequence number has wrapped.
        Modify the fields of the structure.
        Write a restart area to the disk.
        Change the current restart area.

    Log data area

        Allocate and Deallocate structure
        Sychronize access to the fields.
        Add and remove fields from the workque.

We need a structure to use for a log file information block.

July 1,

How do we store the update sequence stride on disk to read on a different
system??

What do we do when there is an I/O error writing to the disk??  How does
an operation know that a previous I/O error has occurred??

Do multiple clients open the same log file with the same file object or
the same file??  (We could always check if the context pointers match)

How do we disable the update sequence mechanics in order to originally
recognize the log file.
