[stgt] RFC [PATCH] Implement PERSISTENT RESERVE IN/OUT

Mark Harvey markh794 at gmail.com
Fri Aug 22 01:29:17 CEST 2008


On Fri, Aug 22, 2008 at 4:53 AM, Arne Redlich <agr at powerkom-dd.de> wrote:
> Am Donnerstag, den 21.08.2008, 19:25 +1000 schrieb Mark Harvey:
>> Arne Redlich wrote:
>> > [re-adding stgt list]
>> >
>> > Am Mittwoch, den 20.08.2008, 13:49 -0700 schrieb Richard Sharpe:
>> >> On Wed, Aug 20, 2008 at 1:08 PM, Arne Redlich <agr at powerkom-dd.de> wrote:
>> >>> [dropping stgt-devel at berlios]
>> >>>
>> >>> Am Mittwoch, den 20.08.2008, 15:01 +1000 schrieb Mark Harvey:
>> >>>> Apologies for sending as an attachment... gmail and all.
>> >>>>
>> >>> Though I'm not sure it will differ at all in this area, but SPC-3 should
>> >>> be used as reference when implementing it - cf. spc_inquiry().
>> >> I agree ...
>> >>
>> >>> [snip]
>> >>>
>> >>>> +struct scsi_pr {
>> >>>> +     /* Persistent Reservation Generation */
>> >>>> +     uint32_t PRgeneration;
>> >>>> +     uint8_t pr_key[PR_RESERVATION_SZ][PR_KEY_SZ];
>> >>>> +};
>> >>>> +
>> >>> Too bad the most interesting part is missing - an efficient way to
>> >>> lookup the registered keys. I could imagine using a hashtable, but then
>> >>> again finding a good hash function is not easy - (u64)key % tablesize
>> >>> possibly? So:
>> >> However, for a first implementation, and given the nature of the usage
>> >> of these commands, how efficient does this need to be?
>> >>
>> >> I could only imagine reservations being placed by say, no more than a
>> >> dozen to two dozen initiators in an environment consisting of FC
>> >> initiators and targets and so forth.
>> >>
>> >> What I am saying is I am having a hard time understanding why
>> >> efficiency is a concern here, but maybe that is because I lack
>> >> experience in the environments you deal with.
>> It really needs to be checked for EVERY scsi command received by the lu. And then there is the 'exclusive' reservation vs any initiator with a registered key.
>>
>> >
>> > Once a reservation is placed on the LU you have to check if a command
>> > is allowed or whether it leads to a reservation conflict. And this is
>> > done by looking at the registered keys, so you really want this lookup
>> > to be as fast as possible.
>>
>> I plan on using the PRgeneration which appears to be updated each time something within the reservation status change.
>>
>> i.e. Most performance hit can be over-come by storing the 'last PRgeneration' and if it is greater, then do the intensive checks.
>>
>> Unfortunately, until I get enough of the code in place - I won't really know :)
>
> I'm afraid you lost me on the PR generation thing. How does it help you
> to find out whether an initiator's WRITE 10 is "legitimate" if another
> initiator placed a, say, Registrants Only Reservation on the targetted
> SBC LU?
>
> Arne

My current line of thinking is:
- storing a 'bit mask' for each initiator (containing registrant only,
exclusive.... that this initiator has registered / is permitted).
which is tagged by PRgeneration value.
- Each lu contains a mask of of permitted actions (e.g. ssc would most
likely not allow shared access, while sbc devices may allow shared
read access).
- On each SCSI cmd:
   Test PRgeneration is not latter then lu's PRgeneration recorded
value. If PRgeneration is later, walk thru initiator list and
re-calculate bit mask & update lu's PRgeneration.
   Compare two masks and allow/reject SCSI cmd on outcome.


Really, really rough pseudo code which is not even thought thru yet...

(Incremented by RESERVATION-OUT)
pr->PRgeneration

struct pr_nexus {
     i_t_nexus; (vague hand-waving pointing to some unknown way to
identify i_t_nexus)
     pr_generation; (Value of PRgeneration at time this struct was updated)
     uint mask; (permission mask allowed by this i_t_nexus)
} pr_nexus;

lu->mask; (Contains mask of allowed operations - exclusive access,
shared access by i_t with registered keys etc)

case WRITE_10:
    if (pr->PRgeneration != pr_nexus->pr_generation)
          recalculate_i_t_nexus_mask_because_keys_changed();
    if (i_t_nexus->mask & lu->mask)
          return SAM_STAT_RESERVATION_CONFLICT;

>
>
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list