* [PATCH 0/2] libosd: Support for device lookup by osd_device_info @ 2009-06-30 17:08 Boaz Harrosh 2009-06-30 17:10 ` [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device Boaz Harrosh 2009-06-30 17:10 ` [PATCH 2/2] libosd: osd_dev_is_ver1 - Minor API cleanup Boaz Harrosh 0 siblings, 2 replies; 4+ messages in thread From: Boaz Harrosh @ 2009-06-30 17:08 UTC (permalink / raw) To: Benny Halevy, open-osd mailing-list, pNFS Mailing List, linux-scsi These two patches are for Linux=2.6.32 They are for supporting what is needed by the pNFS-objects layout driver and exofs when exporting osd(s) on the network. Benny you will need to carry these in the pnfs tree until 2.6.32-rc1 as prerequisite of the osd get_device_info support (will send next) list of patches: [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device [PATCH 2/2] libosd: osd_dev_is_ver1 - Minor API cleanup Please review Thanks Boaz ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device 2009-06-30 17:08 [PATCH 0/2] libosd: Support for device lookup by osd_device_info Boaz Harrosh @ 2009-06-30 17:10 ` Boaz Harrosh 2009-06-30 17:42 ` Benny Halevy 2009-06-30 17:10 ` [PATCH 2/2] libosd: osd_dev_is_ver1 - Minor API cleanup Boaz Harrosh 1 sibling, 1 reply; 4+ messages in thread From: Boaz Harrosh @ 2009-06-30 17:10 UTC (permalink / raw) To: Benny Halevy, open-osd mailing-list, pNFS Mailing List, linux-scsi Define an osd_dev_info structure that Uniquely identifies an OSD device lun on the network. The identification is built from unique target attributes and is the same for all network/SAN machines. osduld_info_lookup() - NEW New API that will lookup an osd_dev by its osd_dev_info. This is used by pNFS-objects for cross network global device identification. osduld_device_info() - NEW Given an osd_dev handle returns its associated osd_dev_info. This is used by exofs to encode the device information for network clients. (Get-device-info). The ULD fetches this information at startup and hangs it on each OSD device. (This is a fast operation that can be called at any condition) osd_auto_detect_ver() - REVISED Now returns an osd_dev_info structure. Is only called once by ULD as before. See added comments for how to use. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> --- drivers/scsi/osd/osd_initiator.c | 19 ++++++++++---- drivers/scsi/osd/osd_uld.c | 50 +++++++++++++++++++++++++++++++++++++- include/scsi/osd_initiator.h | 37 +++++++++++++++++++++++++--- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 7a117c1..c36697e 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -73,7 +73,8 @@ static const char *_osd_ver_desc(struct osd_request *or) #define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len) -static int _osd_print_system_info(struct osd_dev *od, void *caps) +static int _osd_print_system_info(struct osd_dev *od, + void *caps, struct osd_dev_info *odi) { struct osd_request *or; struct osd_attr get_attrs[] = { @@ -137,8 +138,10 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps) OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n", (char *)pFirst); - pFirst = get_attrs[a].val_ptr; - OSD_INFO("OSD_NAME [%s]\n", (char *)pFirst); + odi->osdname_len = get_attrs[a].len; + odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL); + memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len); + OSD_INFO("OSD_NAME [%s]\n", odi->osdname); a++; pFirst = get_attrs[a++].val_ptr; @@ -171,6 +174,9 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps) sid_dump, sizeof(sid_dump), true); OSD_INFO("OSD_SYSTEM_ID(%d)\n" " [%s]\n", len, sid_dump); + + odi->systemid_len = len; + memcpy(odi->systemid, get_attrs[a].val_ptr, len); a++; } out: @@ -178,16 +184,17 @@ out: return ret; } -int osd_auto_detect_ver(struct osd_dev *od, void *caps) +int osd_auto_detect_ver(struct osd_dev *od, + void *caps, struct osd_dev_info *odi) { int ret; /* Auto-detect the osd version */ - ret = _osd_print_system_info(od, caps); + ret = _osd_print_system_info(od, caps, odi); if (ret) { osd_dev_set_ver(od, OSD_VER1); OSD_DEBUG("converting to OSD1\n"); - ret = _osd_print_system_info(od, caps); + ret = _osd_print_system_info(od, caps, odi); } return ret; diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 0bdef33..77e63f1 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -87,6 +87,7 @@ struct osd_uld_device { struct osd_dev od; struct gendisk *disk; struct device *class_member; + struct osd_dev_info odi; }; static void __uld_get(struct osd_uld_device *oud); @@ -216,6 +217,45 @@ free_od: } EXPORT_SYMBOL(osduld_path_lookup); +static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len, + const u8 *a2, unsigned a2_len) +{ + if (a1_len && a2_len && (a1_len != a2_len)) + return false; + + return !a1_len || !a2_len || (0 == memcmp(a1, a2, a1_len)); +} + +struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi) +{ + unsigned i; + + for (i = 0; i < SCSI_OSD_MAX_MINOR; i++) { + char dev_str[16]; + struct osd_uld_device *oud; + struct osd_dev *od; + + sprintf(dev_str, "/dev/osd%d", i); + od = osduld_path_lookup(dev_str); + if (IS_ERR(od)) + continue; + + oud = od->file->private_data; + if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len, + odi->systemid, odi->systemid_len) && + _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len, + odi->osdname, odi->osdname_len)) { + OSD_DEBUG("found device sysid_len=%d osdname=%d\n", + odi->systemid_len, odi->osdname_len); + return od; + } + osduld_put_device(od); + } + + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL(osduld_info_lookup); + void osduld_put_device(struct osd_dev *od) { @@ -230,6 +270,13 @@ void osduld_put_device(struct osd_dev *od) } EXPORT_SYMBOL(osduld_put_device); +const struct osd_dev_info *osduld_device_info(struct osd_dev *od) +{ + struct osd_uld_device *oud = od->file->private_data; + return &oud->odi; +} +EXPORT_SYMBOL(osduld_device_info); + /* * Scsi Device operations */ @@ -250,7 +297,7 @@ static int __detect_osd(struct osd_uld_device *oud) OSD_ERR("warning: scsi_test_unit_ready failed\n"); osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true); - if (osd_auto_detect_ver(&oud->od, caps)) + if (osd_auto_detect_ver(&oud->od, caps, &oud->odi)) return -ENODEV; return 0; @@ -402,6 +449,7 @@ static void __remove(struct kref *kref) put_disk(oud->disk); ida_remove(&osd_minor_ida, oud->minor); + kfree(oud->odi.osdname); kfree(oud); } diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 02bd9f7..0d29cc3 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -56,10 +56,23 @@ struct osd_dev { #endif }; -/* Retrieve/return osd_dev(s) for use by Kernel clients */ -struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/ +/* Unique Identification of an OSD device */ +struct osd_dev_info { + unsigned systemid_len; + u8 systemid[OSD_SYSTEMID_LEN]; + unsigned osdname_len; + u8 *osdname; +}; + +/* Retrieve/return osd_dev(s) for use by Kernel clients + * Use IS_ERR/ERR_PTR on returned "osd_dev *". + */ +struct osd_dev *osduld_path_lookup(const char *dev_name); +struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi); void osduld_put_device(struct osd_dev *od); +const struct osd_dev_info *osduld_device_info(struct osd_dev *od); + /* Add/remove test ioctls from external modules */ typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg); int osduld_register_test(unsigned ioctl, do_test_fn *do_test); @@ -69,8 +82,24 @@ void osduld_unregister_test(unsigned ioctl); void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); void osd_dev_fini(struct osd_dev *od); -/* some hi level device operations */ -int osd_auto_detect_ver(struct osd_dev *od, void *caps); /* GFP_KERNEL */ +/** + * osd_auto_detect_ver - Detect the OSD version, return Unique Identification + * + * @od: OSD target lun handle + * @caps: Capabilities authorizing OSD root read attributes access + * @odi: Retrieved information uniquely identifying the osd target lun + * Note: odi->osdname must be kfreed by caller. + * + * Auto detects the OSD version of the OSD target and sets the @od + * accordingly. Meanwhile also returns the "system id" and "osd name" root + * attributes which uniquely identify the OSD target. This member is usually + * called by the ULD. ULD users should call osduld_device_info(). + * This rutine allocates osd requests and memory at GFP_KERNEL level and might + * sleep. + */ +int osd_auto_detect_ver(struct osd_dev *od, + void *caps, struct osd_dev_info *odi); + static inline struct request_queue *osd_request_queue(struct osd_dev *od) { return od->scsi_device->request_queue; -- 1.6.2.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device 2009-06-30 17:10 ` [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device Boaz Harrosh @ 2009-06-30 17:42 ` Benny Halevy 0 siblings, 0 replies; 4+ messages in thread From: Benny Halevy @ 2009-06-30 17:42 UTC (permalink / raw) To: Boaz Harrosh; +Cc: open-osd mailing-list, pNFS Mailing List, linux-scsi On Jun. 30, 2009, 20:10 +0300, Boaz Harrosh <bharrosh@panasas.com> wrote: > Define an osd_dev_info structure that Uniquely identifies an OSD > device lun on the network. The identification is built from unique > target attributes and is the same for all network/SAN machines. > > osduld_info_lookup() - NEW > New API that will lookup an osd_dev by its osd_dev_info. > This is used by pNFS-objects for cross network global device > identification. > > osduld_device_info() - NEW > Given an osd_dev handle returns its associated osd_dev_info. > This is used by exofs to encode the device information for > network clients. (Get-device-info). The ULD fetches this > information at startup and hangs it on each OSD device. (This is > a fast operation that can be called at any condition) > > osd_auto_detect_ver() - REVISED > Now returns an osd_dev_info structure. Is only called once > by ULD as before. See added comments for how to use. > > Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> > --- > drivers/scsi/osd/osd_initiator.c | 19 ++++++++++---- > drivers/scsi/osd/osd_uld.c | 50 +++++++++++++++++++++++++++++++++++++- > include/scsi/osd_initiator.h | 37 +++++++++++++++++++++++++--- > 3 files changed, 95 insertions(+), 11 deletions(-) > > diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c > index 7a117c1..c36697e 100644 > --- a/drivers/scsi/osd/osd_initiator.c > +++ b/drivers/scsi/osd/osd_initiator.c > @@ -73,7 +73,8 @@ static const char *_osd_ver_desc(struct osd_request *or) > > #define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len) > > -static int _osd_print_system_info(struct osd_dev *od, void *caps) > +static int _osd_print_system_info(struct osd_dev *od, > + void *caps, struct osd_dev_info *odi) Now that it's doing much more than printing how about renaming it to _osd_prep_system_info or _osd_get_system_info? > { > struct osd_request *or; > struct osd_attr get_attrs[] = { > @@ -137,8 +138,10 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps) > OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n", > (char *)pFirst); > > - pFirst = get_attrs[a].val_ptr; > - OSD_INFO("OSD_NAME [%s]\n", (char *)pFirst); > + odi->osdname_len = get_attrs[a].len; > + odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL); > + memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len); > + OSD_INFO("OSD_NAME [%s]\n", odi->osdname); The osd name isn't necessarily a (printable) string... I'd treat it the same as the systemid and not even bother allocating space for it if osdname_len==0 (and handle the null pointer correctly in this case where it's accessed) > a++; > > pFirst = get_attrs[a++].val_ptr; > @@ -171,6 +174,9 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps) > sid_dump, sizeof(sid_dump), true); > OSD_INFO("OSD_SYSTEM_ID(%d)\n" > " [%s]\n", len, sid_dump); > + > + odi->systemid_len = len; > + memcpy(odi->systemid, get_attrs[a].val_ptr, len); > a++; > } > out: > @@ -178,16 +184,17 @@ out: > return ret; > } > > -int osd_auto_detect_ver(struct osd_dev *od, void *caps) > +int osd_auto_detect_ver(struct osd_dev *od, > + void *caps, struct osd_dev_info *odi) > { > int ret; > > /* Auto-detect the osd version */ > - ret = _osd_print_system_info(od, caps); > + ret = _osd_print_system_info(od, caps, odi); > if (ret) { > osd_dev_set_ver(od, OSD_VER1); > OSD_DEBUG("converting to OSD1\n"); > - ret = _osd_print_system_info(od, caps); > + ret = _osd_print_system_info(od, caps, odi); > } > > return ret; > diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c > index 0bdef33..77e63f1 100644 > --- a/drivers/scsi/osd/osd_uld.c > +++ b/drivers/scsi/osd/osd_uld.c > @@ -87,6 +87,7 @@ struct osd_uld_device { > struct osd_dev od; > struct gendisk *disk; > struct device *class_member; > + struct osd_dev_info odi; > }; > > static void __uld_get(struct osd_uld_device *oud); > @@ -216,6 +217,45 @@ free_od: > } > EXPORT_SYMBOL(osduld_path_lookup); > > +static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len, > + const u8 *a2, unsigned a2_len) > +{ > + if (a1_len && a2_len && (a1_len != a2_len)) > + return false; > + > + return !a1_len || !a2_len || (0 == memcmp(a1, a2, a1_len)); > +} > + > +struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi) > +{ > + unsigned i; > + > + for (i = 0; i < SCSI_OSD_MAX_MINOR; i++) { > + char dev_str[16]; > + struct osd_uld_device *oud; > + struct osd_dev *od; > + > + sprintf(dev_str, "/dev/osd%d", i); > + od = osduld_path_lookup(dev_str); > + if (IS_ERR(od)) > + continue; > + > + oud = od->file->private_data; > + if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len, > + odi->systemid, odi->systemid_len) && > + _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len, > + odi->osdname, odi->osdname_len)) { This will match null oud->odi.systemid regardless of oud->odi.osdname. Shouldn't we check any non-NULL lookup key first? for example: static inline bool _same(const u8 *a1, unsigned a1_len, const u8 *a2, unsigned a2_len) { if (a1_len != a2_len) return false; return !a1_len || (0 == memcmp(a1, a2, a1_len)); } found = 1; if ((odi->systemid_len && !_same(oud->odi.systemid, oud->odi.systemid_len, odi->systemid, odi->systemid_len)) || (odi->osdname_len && !_same(oud->odi.osdname, oud->odi.osdname_len, odi->osdname, odi->osdname_len))) found = 0; if (found) { > + OSD_DEBUG("found device sysid_len=%d osdname=%d\n", > + odi->systemid_len, odi->osdname_len); > + return od; > + } > + osduld_put_device(od); > + } Benny > + > + return ERR_PTR(-ENODEV); > +} > +EXPORT_SYMBOL(osduld_info_lookup); > + > void osduld_put_device(struct osd_dev *od) > { > > @@ -230,6 +270,13 @@ void osduld_put_device(struct osd_dev *od) > } > EXPORT_SYMBOL(osduld_put_device); > > +const struct osd_dev_info *osduld_device_info(struct osd_dev *od) > +{ > + struct osd_uld_device *oud = od->file->private_data; > + return &oud->odi; > +} > +EXPORT_SYMBOL(osduld_device_info); > + > /* > * Scsi Device operations > */ > @@ -250,7 +297,7 @@ static int __detect_osd(struct osd_uld_device *oud) > OSD_ERR("warning: scsi_test_unit_ready failed\n"); > > osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true); > - if (osd_auto_detect_ver(&oud->od, caps)) > + if (osd_auto_detect_ver(&oud->od, caps, &oud->odi)) > return -ENODEV; > > return 0; > @@ -402,6 +449,7 @@ static void __remove(struct kref *kref) > put_disk(oud->disk); > > ida_remove(&osd_minor_ida, oud->minor); > + kfree(oud->odi.osdname); > kfree(oud); > } > > diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h > index 02bd9f7..0d29cc3 100644 > --- a/include/scsi/osd_initiator.h > +++ b/include/scsi/osd_initiator.h > @@ -56,10 +56,23 @@ struct osd_dev { > #endif > }; > > -/* Retrieve/return osd_dev(s) for use by Kernel clients */ > -struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/ > +/* Unique Identification of an OSD device */ > +struct osd_dev_info { > + unsigned systemid_len; > + u8 systemid[OSD_SYSTEMID_LEN]; > + unsigned osdname_len; > + u8 *osdname; > +}; > + > +/* Retrieve/return osd_dev(s) for use by Kernel clients > + * Use IS_ERR/ERR_PTR on returned "osd_dev *". > + */ > +struct osd_dev *osduld_path_lookup(const char *dev_name); > +struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi); > void osduld_put_device(struct osd_dev *od); > > +const struct osd_dev_info *osduld_device_info(struct osd_dev *od); > + > /* Add/remove test ioctls from external modules */ > typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg); > int osduld_register_test(unsigned ioctl, do_test_fn *do_test); > @@ -69,8 +82,24 @@ void osduld_unregister_test(unsigned ioctl); > void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); > void osd_dev_fini(struct osd_dev *od); > > -/* some hi level device operations */ > -int osd_auto_detect_ver(struct osd_dev *od, void *caps); /* GFP_KERNEL */ > +/** > + * osd_auto_detect_ver - Detect the OSD version, return Unique Identification > + * > + * @od: OSD target lun handle > + * @caps: Capabilities authorizing OSD root read attributes access > + * @odi: Retrieved information uniquely identifying the osd target lun > + * Note: odi->osdname must be kfreed by caller. > + * > + * Auto detects the OSD version of the OSD target and sets the @od > + * accordingly. Meanwhile also returns the "system id" and "osd name" root > + * attributes which uniquely identify the OSD target. This member is usually > + * called by the ULD. ULD users should call osduld_device_info(). > + * This rutine allocates osd requests and memory at GFP_KERNEL level and might > + * sleep. > + */ > +int osd_auto_detect_ver(struct osd_dev *od, > + void *caps, struct osd_dev_info *odi); > + > static inline struct request_queue *osd_request_queue(struct osd_dev *od) > { > return od->scsi_device->request_queue; ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] libosd: osd_dev_is_ver1 - Minor API cleanup 2009-06-30 17:08 [PATCH 0/2] libosd: Support for device lookup by osd_device_info Boaz Harrosh 2009-06-30 17:10 ` [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device Boaz Harrosh @ 2009-06-30 17:10 ` Boaz Harrosh 1 sibling, 0 replies; 4+ messages in thread From: Boaz Harrosh @ 2009-06-30 17:10 UTC (permalink / raw) To: Benny Halevy, open-osd mailing-list, pNFS Mailing List, linux-scsi define a new osd_dev_is_ver1 that operates on devices and the old osd_req_is_ver1 uses that new API. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> --- include/scsi/osd_initiator.h | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 0d29cc3..7bda109 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -113,6 +113,15 @@ static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) #endif } +static inline bool osd_dev_is_ver1(struct osd_dev *od) +{ +#ifdef OSD_VER1_SUPPORT + return od->version == OSD_VER1; +#else + return false; +#endif +} + struct osd_request; typedef void (osd_req_done_fn)(struct osd_request *or, void *private); @@ -149,14 +158,9 @@ struct osd_request { int async_error; }; -/* OSD Version control */ static inline bool osd_req_is_ver1(struct osd_request *or) { -#ifdef OSD_VER1_SUPPORT - return or->osd_dev->version == OSD_VER1; -#else - return false; -#endif + return osd_dev_is_ver1(or->osd_dev); } /* -- 1.6.2.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-06-30 17:42 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-06-30 17:08 [PATCH 0/2] libosd: Support for device lookup by osd_device_info Boaz Harrosh 2009-06-30 17:10 ` [PATCH 1/2] libosd: osd_dev_info: Unique Identification of an OSD device Boaz Harrosh 2009-06-30 17:42 ` Benny Halevy 2009-06-30 17:10 ` [PATCH 2/2] libosd: osd_dev_is_ver1 - Minor API cleanup Boaz Harrosh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox