This patch updates the SCSI-3 Persistent Reservation code to add support
for reservations of type=7 (Write Exclusive, All Registrants) and type=8
(Exclusive Access, All Registrants), as these newer reservation types
are needed by some types of clustering software.
Existing behavior for other reservation types does not change.
Target tested on SLES 11 SP2, with one initiator on the same system, and
one on a OpenSUSE 12.1 system, and one on a SLES 11 SP2 VM (all using
open-iscsi).
Tested:
- REGISTER [and unregister]
- REPORT CAPABILITIES
- READ FULL STATUS
- RESERVE
- RELEASE
- CLEAR
- PREEMPT
Signed-of-by: Lee Duncan <ldu...@suse.com>
persist.c | 115
+++++++++++++++++++++++++++++++++++++-------------------------
persist.h | 7 +++
volume.c | 2 +
3 files changed, 79 insertions(+), 45 deletions(-)
Index: trunk/kernel/persist.h
===================================================================
--- trunk/kernel/persist.h (revision 470)
+++ trunk/kernel/persist.h (working copy)
@@ -224,6 +224,13 @@ pr_is_reserved(const struct reservation* res)
return res->reservation_type != RESERVATION_TYPE_NONE;
}
+static inline bool
+pr_type_is_all_registrants(const struct reservation *res)
+{
+ return ((res->persistent_type ==
PR_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS) ||
+ (res->persistent_type == PR_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS));
+}
+
struct iscsi_session;
bool
Index: trunk/kernel/volume.c
===================================================================
--- trunk/kernel/volume.c (revision 470)
+++ trunk/kernel/volume.c (working copy)
@@ -420,9 +420,11 @@ int is_volume_reserved(struct iet_volume *volume,
excl_access = true;
break;
case PR_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY:
+ case PR_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
write_excl_ro = true;
break;
case PR_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY:
+ case PR_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
excl_access_ro = true;
break;
default:
Index: trunk/kernel/persist.c
===================================================================
--- trunk/kernel/persist.c (revision 470)
+++ trunk/kernel/persist.c (working copy)
@@ -9,21 +9,28 @@
#include "iscsi_dbg.h"
#include "persist.h"
-bool
-pr_is_reserved_by_session(const struct reservation *res,
- const struct iscsi_session *sess)
-{
- return (pr_is_reserved(res) && res->sid == sess->sid);
-}
-
static bool
pr_is_reserved_by_sid(const struct reservation *res,
const u64 sid)
{
- return (pr_is_reserved(res) && res->sid == sid);
+ if (!pr_is_reserved(res))
+ return false;
+
+ if (pr_type_is_all_registrants(res)) {
+ return pr_initiator_has_registered(res, sid);
+ } else {
+ return res->sid == sid;
+ }
}
bool
+pr_is_reserved_by_session(const struct reservation *res,
+ const struct iscsi_session *sess)
+{
+ return pr_is_reserved_by_sid(res, sess->sid);
+}
+
+bool
pr_initiator_has_registered(const struct reservation *res,
u64 sid)
{
@@ -44,7 +51,9 @@ static const struct pr_in_report_capabilities_data
.type_mask = cpu_to_be16(PR_TYPE_WR_EX|
PR_TYPE_EX_AC|
PR_TYPE_WR_EX_RO|
- PR_TYPE_EX_AC_RO),
+ PR_TYPE_EX_AC_RO|
+ PR_TYPE_WR_EX_AR|
+ PR_TYPE_EX_AC_AR),
};
static void
@@ -79,7 +88,10 @@ pr_in_read_reservation(struct iscsi_cmnd *cmnd,
pin_data->generation = cpu_to_be32(reservation->generation);
if (pr_is_reserved(reservation)) {
- pin_data->reservation_key = reservation->reservation_key;
+ if (pr_type_is_all_registrants(reservation))
+ pin_data->reservation_key = 0;
+ else
+ pin_data->reservation_key = reservation->reservation_key;
pin_data->scope_type = PR_SCOPE_LU | reservation->persistent_type;
/*
* SPC-3, 6.11.3.2
@@ -350,7 +362,8 @@ pr_out_register(struct iscsi_cmnd *cmnd, bool igno
}
if (!param->service_action_key) {
- if (pr_is_reserved_by_session(reservation, session)) {
+ if (pr_is_reserved_by_session(reservation, session) &&
+ !pr_type_is_all_registrants(reservation)) {
reservation->reservation_type = RESERVATION_TYPE_NONE;
reservation->persistent_type = 0;
reservation->reservation_key = 0;
@@ -361,6 +374,12 @@ pr_out_register(struct iscsi_cmnd *cmnd, bool igno
}
list_del(®->r_list);
kfree(reg);
+ if (list_empty(&reservation->registration_list) &&
+ pr_type_is_all_registrants(reservation)) {
+ reservation->reservation_type = RESERVATION_TYPE_NONE;
+ reservation->persistent_type = 0;
+ reservation->reservation_key = 0;
+ }
} else {
reg->reservation_key = param->service_action_key;
}
@@ -410,6 +429,8 @@ persistent_type_valid(int type)
case PR_TYPE_EXCLUSIVE_ACCESS:
case PR_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY:
case PR_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY:
+ case PR_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
+ case PR_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
return true;
default:
return false;
@@ -500,17 +521,20 @@ pr_out_release(struct iscsi_cmnd *cmnd,
goto out;
}
- if (reservation->sid != session->sid)
- goto out;
-
- if (reservation->reservation_key != param->reservation_key) {
- cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
- goto out;
+ if (!pr_type_is_all_registrants(reservation)) {
+ if (reservation->sid != session->sid)
+ goto out;
+ if (reservation->reservation_key != param->reservation_key) {
+ cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
+ goto out;
+ }
}
switch (reservation->persistent_type) {
case PR_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY:
case PR_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY:
+ case PR_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
+ case PR_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
send_ua = true;
break;
default:
@@ -601,54 +625,55 @@ pr_out_preempt(struct iscsi_cmnd *cmnd,
struct reservation *reservation = &volume->reservation;
bool all = 0;
- if (!param->service_action_key) {
+ spin_lock(&volume->reserve_lock);
+ if (!param->service_action_key &&
+ !pr_type_is_all_registrants(reservation)) {
iscsi_cmnd_set_sense(cmnd,
ILLEGAL_REQUEST,
INVALID_FIELD_IN_PARAMETER_LIST_ASC,
INVALID_FIELD_IN_PARAMETER_LIST_ASCQ);
- return;
+ goto out;
}
- spin_lock(&volume->reserve_lock);
registered = pr_initiator_has_registered(reservation, session->sid);
if (!registered) {
cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
goto out;
}
- if (pr_is_reserved(reservation) &&
- reservation->reservation_key == param->service_action_key &&
- reservation->sid != session->sid) {
- if (!persistent_type_valid(pr_type)) {
- iscsi_cmnd_set_sense(cmnd,
- ILLEGAL_REQUEST,
- INVALID_FIELD_IN_CDB_ASC,
- INVALID_FIELD_IN_CDB_ASCQ);
- goto out;
- }
+ if (pr_is_reserved(reservation)) {
+ if ((!pr_type_is_all_registrants(reservation) &&
+ reservation->reservation_key == param->service_action_key &&
+ reservation->sid != session->sid) ||
+ (pr_type_is_all_registrants(reservation) &&
+ !param->service_action_key)) {
- reserv_session = session_lookup(target, reservation->sid);
- if (reserv_session) {
- if (abort)
- session_abort_tasks(reserv_session, volume->lun);
- ua_establish_for_session(reserv_session,
- volume->lun,
- RESERVATIONS_PREEMPTED_ASC,
- RESERVATIONS_PREEMPTED_ASCQ);
+ reserv_session = session_lookup(target, reservation->sid);
+ if (reserv_session) {
+ if (abort)
+ session_abort_tasks(reserv_session,
+ volume->lun);
+ ua_establish_for_session(reserv_session,
+ volume->lun,
+ RESERVATIONS_PREEMPTED_ASC,
+ RESERVATIONS_PREEMPTED_ASCQ);
+ }
+
+ reservation->reservation_type = RESERVATION_TYPE_PERSISTENT;
+ reservation->sid = session->sid;
+ reservation->reservation_key = param->reservation_key;
+ reservation->persistent_type = pr_type;
+ all = true;
}
-
- reservation->reservation_type = RESERVATION_TYPE_PERSISTENT;
- reservation->sid = session->sid;
- reservation->reservation_key = param->reservation_key;
- reservation->persistent_type = pr_type;
- all = true;
}
list_for_each_entry_safe(reg, tmp_reg,
&reservation->registration_list, r_list) {
if (reg->sid == session->sid)
continue;
- if (!all && reg->reservation_key != param->service_action_key)
+ if (!all &&
+ reg->reservation_key != param->service_action_key &&
+ !pr_type_is_all_registrants(reservation))
continue;
reserv_session = session_lookup(target, reg->sid);
------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
Iscsitarget-devel mailing list
Iscsitar...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iscsitarget-devel
On 03/25/2012 11:44 PM, Arne Redlich wrote:
> 2012/3/23 Lee Duncan <ldu...@suse.com>:
>> Hi All:
>>
>> This patch updates the SCSI-3 Persistent Reservation code to add support
>> for reservations of type=7 (Write Exclusive, All Registrants) and type=8
>> (Exclusive Access, All Registrants), as these newer reservation types
>> are needed by some types of clustering software.
>>
>> Existing behavior for other reservation types does not change.
>>
>> Target tested on SLES 11 SP2, with one initiator on the same system, and
>> one on a OpenSUSE 12.1 system, and one on a SLES 11 SP2 VM (all using
>> open-iscsi).
>>
>> Tested:
>> - REGISTER [and unregister]
>> - REPORT CAPABILITIES
>> - READ FULL STATUS
>> - RESERVE
>> - RELEASE
>> - CLEAR
>> - PREEMPT
>>
>> Signed-of-by: Lee Duncan <ldu...@suse.com>
>
> Lee,
>
> Thanks a lot for the patch! FYI, I'm travelling this week, so unless
> Ross has time to pick it up it might take a bit to review and merge
> it.
>
> Cheers,
> Arne
>
--
Lee Duncan
SUSE Labs