Hi Kai, Thanks for the changes the HPE DAT72 DDS5 drive now works as expected: # ./mt -f /dev/st1 stsetoption debug # ./mt -f /dev/st1 stsetoption can-partitions # ./mt -f /dev/st1 mkpartition 1000 [ 980.241139] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 980.241481] st 6:0:3:0: [st1] Mode 0 options: buffer writes: 1, async writes: 1, read ahead: 1 [ 980.241487] st 6:0:3:0: [st1] can bsr: 1, two FMs: 0, fast mteom: 0, auto lock: 0, [ 980.241490] st 6:0:3:0: [st1] defs for wr: 0, no block limits: 0, partitions: 0, s2 log: 0 [ 980.241493] st 6:0:3:0: [st1] sysv: 0 nowait: 0 sili: 0 nowait_filemark: 0 [ 980.241496] st 6:0:3:0: [st1] debugging: 1 [ 980.241502] st 6:0:3:0: [st1] Rewinding tape. [ 986.785288] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 986.785658] st 6:0:3:0: [st1] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 986.785663] st 6:0:3:0: [st1] Density 47, tape length: 0, drv buffer: 1 [ 986.785666] st 6:0:3:0: [st1] Block size: 0, buffer size: 4096 (1 blocks). [ 986.785686] st 6:0:3:0: [st1] Mode 0 options: buffer writes: 1, async writes: 1, read ahead: 1 [ 986.785690] st 6:0:3:0: [st1] can bsr: 1, two FMs: 0, fast mteom: 0, auto lock: 0, [ 986.785693] st 6:0:3:0: [st1] defs for wr: 0, no block limits: 0, partitions: 1, s2 log: 0 [ 986.785696] st 6:0:3:0: [st1] sysv: 0 nowait: 0 sili: 0 nowait_filemark: 0 [ 986.785699] st 6:0:3:0: [st1] debugging: 1 [ 986.785703] st 6:0:3:0: [st1] Rewinding tape. [ 994.642650] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 994.643219] st 6:0:3:0: [st1] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 994.643225] st 6:0:3:0: [st1] Density 47, tape length: 0, drv buffer: 1 [ 994.643229] st 6:0:3:0: [st1] Block size: 0, buffer size: 4096 (1 blocks). [ 994.643231] st 6:0:3:0: [st1] Updating partition number in status. [ 994.643681] st 6:0:3:0: [st1] Got tape pos. blk 0 part 0. [ 994.643699] st 6:0:3:0: [st1] Loading tape. [ 994.644655] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 994.644972] st 6:0:3:0: [st1] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 994.644976] st 6:0:3:0: [st1] Density 47, tape length: 0, drv buffer: 1 [ 994.644980] st 6:0:3:0: [st1] Block size: 0, buffer size: 4096 (1 blocks). [ 994.645346] st 6:0:3:0: [st1] Partition page length is 10 bytes. [ 994.645352] st 6:0:3:0: [st1] PP: max 1, add 1, xdp 0, psum 02, pofmetc 0, rec 03, units 00, sizes: 1000 65535 [ 994.645356] st 6:0:3:0: [st1] MP: 11 08 01 01 10 03 00 00 03 e8 ff ff [ 994.645359] st 6:0:3:0: [st1] psd_cnt 1, max.parts 1, nbr_parts 1 [ 994.645362] st 6:0:3:0: [st1] Formatting tape with two partitions (1 = 1000 MB). [ 994.645366] st 6:0:3:0: [st1] Sent partition page length is 10 bytes. needs_format: 0 [ 994.645370] st 6:0:3:0: [st1] PP: max 1, add 1, xdp 1, psum 02, pofmetc 0, rec 03, units 00, sizes: 1000 65535 [ 994.645374] st 6:0:3:0: [st1] MP: 11 08 01 01 30 03 00 00 03 e8 ff ff [ 1372.970312] st 6:0:3:0: [st1] Rewinding tape. # ./mt -f /dev/st1 status SCSI 2 tape drive: File number=0, block number=0, partition=0. Tape block size 0 bytes. Density code 0x47 (DDS-5 or TR-5). Soft error count since last status=0 General status bits on (41010000): BOT ONLINE IM_REP_EN # ./mt -f /dev/st1 setpartition 1 # ./mt -f /dev/st1 status SCSI 2 tape drive: File number=0, block number=0, partition=1. Tape block size 0 bytes. Density code 0x47 (DDS-5 or TR-5). Soft error count since last status=0 General status bits on (41010000): BOT ONLINE IM_REP_EN And since you can only set the size of partition 1 on those drives as expected using a negative size fails: # ./mt -f /dev/st1 mkpartition -500 /dev/st1: Invalid argument [ 3937.384419] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 3937.384710] st 6:0:3:0: [st1] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 3937.384715] st 6:0:3:0: [st1] Density 47, tape length: 0, drv buffer: 1 [ 3937.384718] st 6:0:3:0: [st1] Block size: 0, buffer size: 4096 (1 blocks). [ 3937.384736] st 6:0:3:0: [st1] Loading tape. [ 3937.385682] st 6:0:3:0: [st1] Block limits 1 - 16777215 bytes. [ 3937.385983] st 6:0:3:0: [st1] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 3937.385988] st 6:0:3:0: [st1] Density 47, tape length: 0, drv buffer: 1 [ 3937.385991] st 6:0:3:0: [st1] Block size: 0, buffer size: 4096 (1 blocks). [ 3937.386443] st 6:0:3:0: [st1] Partition page length is 10 bytes. [ 3937.386450] st 6:0:3:0: [st1] PP: max 1, add 1, xdp 0, psum 02, pofmetc 0, rec 03, units 00, sizes: 1000 65535 [ 3937.386455] st 6:0:3:0: [st1] MP: 11 08 01 01 10 03 00 00 03 e8 ff ff [ 3937.386577] st 6:0:3:0: [st1] Rewinding tape. As expected LTO3 fails since it cannot be partitioned: [ 4599.012299] st 5:0:1:0: [st0] Block limits 1 - 16777215 bytes. [ 4599.014281] st 5:0:1:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 4599.014286] st 5:0:1:0: [st0] Density 44, tape length: 0, drv buffer: 1 [ 4599.014290] st 5:0:1:0: [st0] Block size: 0, buffer size: 4096 (1 blocks). [ 4599.014356] st 5:0:1:0: [st0] Rewinding tape. [ 4631.811295] st 5:0:1:0: [st0] Block limits 1 - 16777215 bytes. [ 4631.813313] st 5:0:1:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 4631.813318] st 5:0:1:0: [st0] Density 44, tape length: 0, drv buffer: 1 [ 4631.813321] st 5:0:1:0: [st0] Block size: 0, buffer size: 4096 (1 blocks). [ 4631.813342] st 5:0:1:0: [st0] Mode 0 options: buffer writes: 1, async writes: 1, read ahead: 1 [ 4631.813345] st 5:0:1:0: [st0] can bsr: 1, two FMs: 0, fast mteom: 0, auto lock: 0, [ 4631.813348] st 5:0:1:0: [st0] defs for wr: 0, no block limits: 0, partitions: 1, s2 log: 0 [ 4631.813351] st 5:0:1:0: [st0] sysv: 0 nowait: 0 sili: 0 nowait_filemark: 0 [ 4631.813354] st 5:0:1:0: [st0] debugging: 1 [ 4631.813359] st 5:0:1:0: [st0] Rewinding tape. [ 4648.170712] st 5:0:1:0: [st0] Block limits 1 - 16777215 bytes. [ 4648.172774] st 5:0:1:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 4648.172779] st 5:0:1:0: [st0] Density 44, tape length: 0, drv buffer: 1 [ 4648.172783] st 5:0:1:0: [st0] Block size: 0, buffer size: 4096 (1 blocks). [ 4648.172786] st 5:0:1:0: [st0] Updating partition number in status. [ 4648.175584] st 5:0:1:0: [st0] Got tape pos. blk 0 part 0. [ 4648.175604] st 5:0:1:0: [st0] Loading tape. [ 4648.209689] st 5:0:1:0: [st0] Block limits 1 - 16777215 bytes. [ 4648.212799] st 5:0:1:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8 [ 4648.212804] st 5:0:1:0: [st0] Density 44, tape length: 0, drv buffer: 1 [ 4648.212808] st 5:0:1:0: [st0] Block size: 0, buffer size: 4096 (1 blocks). [ 4648.215855] st 5:0:1:0: [st0] Partition page length is 10 bytes. [ 4648.215861] st 5:0:1:0: [st0] PP: max 0, add 0, xdp 0, psum 03, pofmetc 0, rec 03, units 09, sizes: 400 65535 [ 4648.215866] st 5:0:1:0: [st0] MP: 11 08 00 00 18 03 09 00 01 90 ff ff [ 4648.215869] st 5:0:1:0: [st0] psd_cnt 1, max.parts 0, nbr_parts 0 [ 4648.215872] st 5:0:1:0: [st0] Formatting tape with two partitions (1 = 1000 MB). [ 4648.215875] st 5:0:1:0: [st0] Sent partition page length is 10 bytes. needs_format: 0 [ 4648.215879] st 5:0:1:0: [st0] PP: max 0, add 1, xdp 1, psum 03, pofmetc 0, rec 03, units 09, sizes: 65535 1 [ 4648.215883] st 5:0:1:0: [st0] MP: 11 08 00 01 38 03 09 00 ff ff 00 01 [ 4648.220140] st 5:0:1:0: [st0] Error: 8000002, cmd: 15 10 0 0 16 0 [ 4648.220145] st 5:0:1:0: [st0] Sense Key : Illegal Request [current] [ 4648.220149] st 5:0:1:0: [st0] Add. Sense: Invalid field in parameter list [ 4648.220153] st 5:0:1:0: [st0] Partitioning of tape failed. [ 4648.220269] st 5:0:1:0: [st0] Rewinding tape. I'm asking around again one final time to see if I can lay my hands on a LTO5 or greater drive so I can test LTO partitioning as well. The only other thing I can think of (I'm not sure if this is an improvement or not) is if bp[pgo + PP_OFF_MAX_ADD_PARTS] + bp[pgo + PP_OFF_NBR_ADD_PARTS] (max.parts and nbr_parts in the debug message) is zero just return -EINVAL unless you know of any take drives that report them both as 0 but can be partitioned? That is after this: DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n", psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS], bp[pgo + PP_OFF_NBR_ADD_PARTS]); add (and also turn off the can-partitions option): if ((bp[pgo + PP_OFF_MAX_ADD_PARTS] + bp[pgo + PP_OFF_NBR_ADD_PARTS]) == 0) { DEBC_printk(STp, "Drive not partitionable - max.parts+nbr_parts is 0\n"); STp->can_partitions = 0; return -EINVAL; } I'm not especially fussed if you don't want to add that though. Thanks Shane > -----Original Message----- > From: makisara@kai.makisara.private [mailto:makisara@kai.makisara.private] > On Behalf Of Kai Makisara > Sent: Saturday, January 30, 2016 4:22 AM > To: Seymour, Shane M > Cc: Laurence Oberman; Emmanuel Florac; Laurence Oberman; linux- > scsi@xxxxxxxxxxxxxxx > Subject: RE: What partition should the MTMKPART argument specify? Was: > Re: st driver doesn't seem to grok LTO partitioning > > On Friday 2016-01-29 01:12, Seymour, Shane M wrote: > > >Date: Fri, 29 Jan 2016 01:12:41 > >From: "Seymour, Shane M" <shane.seymour@xxxxxxx> > >To: "\"Kai Mäkisara (Kolumbus)\"" <kai.makisara@xxxxxxxxxxx> > >Cc: Laurence Oberman <loberman@xxxxxxxxxx>, > > Emmanuel Florac <eflorac@xxxxxxxxxxxxxx>, > > Laurence Oberman <oberman.l@xxxxxxxxx>, > > "linux-scsi@xxxxxxxxxxxxxxx" <linux-scsi@xxxxxxxxxxxxxxx> > >Subject: RE: What partition should the MTMKPART argument specify? Was: > Re: st > > driver doesn't seem to grok LTO partitioning > > > >Hi Kai, > > > >$ pwd > >/sys/class/scsi_tape/st1/device > >$ cat scsi_level > >4 > > > OK. The previous patch set the number of partition size descriptors to > one for HP DATs only if the SCSI level was <= SCSI_2. > > The patch below uses that logic for all drives that don't need FORMAT > MEDIUM. For the drives needing FORMAT MEDIUM the value is set to 2. > These drives include LTOs and other modern drives. > > Thanks, Kai > ---------------------------------8<---------------------------------- > --- ref/drivers/scsi/st.c 2015-12-21 18:54:05.068882001 +0200 > +++ new/drivers/scsi/st.c 2016-01-29 19:12:06.139738037 +0200 > @@ -9,7 +9,7 @@ > Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, > Michael Schaefer, J"org Weule, and Eric Youngdale. > > - Copyright 1992 - 2010 Kai Makisara > + Copyright 1992 - 2016 Kai Makisara > email Kai.Makisara@xxxxxxxxxxx > > Some small formal changes - aeb, 950809 > @@ -17,7 +17,7 @@ > Last modified: 18-JAN-1998 Richard Gooch <rgooch@xxxxxxxxxxxxx> Devfs > support > */ > > -static const char *verstr = "20101219"; > +static const char *verstr = "20160129"; > > #include <linux/module.h> > > @@ -3296,7 +3296,10 @@ > #define PP_OFF_RESERVED 7 > > #define PP_BIT_IDP 0x20 > +#define PP_BIT_FDP 0x80 > #define PP_MSK_PSUM_MB 0x10 > +#define PP_MSK_PSUM_UNITS 0x18 > +#define PP_MSK_POFM 0x04 > > /* Get the number of partitions on the tape. As a side effect reads the > mode page into the tape buffer. */ > @@ -3322,6 +3325,29 @@ > } > > > +static int format_medium(struct scsi_tape *STp, int format) > +{ > + int result = 0; > + int timeout = STp->long_timeout; > + unsigned char scmd[MAX_COMMAND_SIZE]; > + struct st_request *SRpnt; > + > + memset(scmd, 0, MAX_COMMAND_SIZE); > + scmd[0] = FORMAT_UNIT; > + scmd[2] = format; > + if (STp->immediate) { > + scmd[1] |= 1; /* Don't wait for completion */ > + timeout = STp->device->request_queue->rq_timeout; > + } > + DEBC_printk(STp, "Sending FORMAT MEDIUM\n"); > + SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE, > + timeout, MAX_RETRIES, 1); > + if (!SRpnt) > + result = STp->buffer->syscall_result; > + return result; > +} > + > + > /* Partition the tape into two partitions if size > 0 or one partition if > size == 0. > > @@ -3340,11 +3366,16 @@ > and 10 when 1 partition is defined (information from Eric Lee Green). This is > is acceptable also to some other old drives and enforced if the first > partition > size field is used for the first additional partition size. > + > + For drives that advertize SCSI-3 or newer, use the SSC-3 methods. > */ > static int partition_tape(struct scsi_tape *STp, int size) > { > int result; > + int target_partition; > + bool scsi3 = STp->device->scsi_level >= SCSI_3, needs_format = false; > int pgo, psd_cnt, psdo; > + int psum = PP_MSK_PSUM_MB, units = 0; > unsigned char *bp; > > result = read_mode_page(STp, PART_PAGE, 0); > @@ -3352,16 +3383,72 @@ > DEBC_printk(STp, "Can't read partition mode page.\n"); > return result; > } > + target_partition = 1; > + if (size < 0) { > + target_partition = 0; > + size = -size; > + } > + > /* The mode page is in the buffer. Let's modify it and write it. */ > bp = (STp->buffer)->b_data; > pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH]; > DEBC_printk(STp, "Partition page length is %d bytes.\n", > bp[pgo + MP_OFF_PAGE_LENGTH] + 2); > + DEBC_printk(STp, "PP: max %u, add %u, xdp %u, psum %02x, > pofmetc %u, " > + "rec %02x, units %02x, sizes: %u %u\n", > + bp[pgo + PP_OFF_MAX_ADD_PARTS], > + bp[pgo + PP_OFF_NBR_ADD_PARTS], > + (bp[pgo + PP_OFF_FLAGS] & 0xe0) >> 5, > + (bp[pgo + PP_OFF_FLAGS] & 0x18) >> 3, > + bp[pgo + PP_OFF_FLAGS] & 0x07, > + bp[pgo + 5], > + bp[pgo + PP_OFF_PART_UNITS], > + bp[pgo + 8] * 256 + bp[pgo + 9], > + bp[pgo + 10] * 256 + bp[pgo + 11]); > + DEBC_printk(STp, > "MP: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n > ", > + bp[pgo], bp[pgo+1], bp[pgo+2], bp[pgo+3], bp[pgo+4], > bp[pgo+5], > + bp[pgo+6], bp[pgo+7], bp[pgo+8], bp[pgo+9], bp[pgo+10], > bp[pgo+11]); > > psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - > PART_PAGE_FIXED_LENGTH) / 2; > + > + if (scsi3) { > + needs_format = (bp[pgo + PP_OFF_FLAGS] & > PP_MSK_POFM) != 0; > + if (needs_format && size == 0) { > + /* No need to write the mode page when clearing > partitioning */ > + result = format_medium(STp, 0); > + goto out; > + } > + if (needs_format) /* Leave the old value for HP DATs > claiming SCSI_3 */ > + psd_cnt = 2; > + if ((bp[pgo + PP_OFF_FLAGS] & PP_MSK_PSUM_UNITS) == > PP_MSK_PSUM_UNITS) { > + /* Use units scaling for large partitions if the device > suggests > + it and no precision lost. Required for IBM TS1140/50 > drives > + that don't support MB units. */ > + if (size >= 1000 && (size % 1000) == 0) { > + size /= 1000; > + psum = PP_MSK_PSUM_UNITS; > + units = 9; /* GB */ > + } > + } > + /* Try it anyway if too large to specify in MB */ > + if (psum == PP_MSK_PSUM_MB && size >= 65534) { > + size /= 1000; > + psum = PP_MSK_PSUM_UNITS; > + units = 9; /* GB */ > + } > + } > + > + if (size >= 65535 || /* Does not fit into two bytes */ > + (target_partition == 0 && psd_cnt < 2)) { > + result = -EINVAL; > + goto out; > + } > + > psdo = pgo + PART_PAGE_FIXED_LENGTH; > - if (psd_cnt > bp[pgo + PP_OFF_MAX_ADD_PARTS]) { > - bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape */ > + /* The second condition is for HP DDS which use only one partition > size > + descriptor */ > + if (target_partition > 0 && psd_cnt > bp[pgo + > PP_OFF_MAX_ADD_PARTS]) { > + bp[psdo] = bp[psdo + 1] = 0xff; /* Rest of the tape to > partition 0 */ > psdo += 2; > } > memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2); > @@ -3370,7 +3457,7 @@ > psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS], > bp[pgo + PP_OFF_NBR_ADD_PARTS]); > > - if (size <= 0) { > + if (size == 0) { > bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0; > if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS]) > bp[pgo + MP_OFF_PAGE_LENGTH] = 6; > @@ -3378,22 +3465,54 @@ > } else { > bp[psdo] = (size >> 8) & 0xff; > bp[psdo + 1] = size & 0xff; > + if (target_partition == 0) > + bp[psdo + 2] = bp[psdo + 3] = 0xff; > bp[pgo + 3] = 1; > if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8) > bp[pgo + MP_OFF_PAGE_LENGTH] = 8; > DEBC_printk(STp, "Formatting tape with two partitions " > - "(1 = %d MB).\n", size); > + "(1 = %d MB).\n", > + units > 0 ? size * 1000 : size); > } > bp[pgo + PP_OFF_PART_UNITS] = 0; > bp[pgo + PP_OFF_RESERVED] = 0; > - bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB; > + if (size != 1 || units != 0) { > + bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | psum | > + (bp[pgo + PP_OFF_FLAGS] & 0x07); > + bp[pgo + PP_OFF_PART_UNITS] = units; > + } else > + bp[pgo + PP_OFF_FLAGS] = PP_BIT_FDP | > + (bp[pgo + PP_OFF_FLAGS] & 0x1f); > + bp[pgo + MP_OFF_PAGE_LENGTH] = 6 + psd_cnt * 2; > + > + DEBC_printk(STp, "Sent partition page length is %d bytes. > needs_format: %d\n", > + bp[pgo + MP_OFF_PAGE_LENGTH] + 2, needs_format); > + DEBC_printk(STp, "PP: max %u, add %u, xdp %u, psum %02x, > pofmetc %u, " > + "rec %02x, units %02x, sizes: %u %u\n", > + bp[pgo + PP_OFF_MAX_ADD_PARTS], > + bp[pgo + PP_OFF_NBR_ADD_PARTS], > + (bp[pgo + PP_OFF_FLAGS] & 0xe0) >> 5, > + (bp[pgo + PP_OFF_FLAGS] & 0x18) >> 3, > + bp[pgo + PP_OFF_FLAGS] & 0x07, > + bp[pgo + 5], > + bp[pgo + PP_OFF_PART_UNITS], > + bp[pgo + 8] * 256 + bp[pgo + 9], > + bp[pgo + 10] * 256 + bp[pgo + 11]); > + DEBC_printk(STp, > "MP: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n > ", > + bp[pgo], bp[pgo+1], bp[pgo+2], bp[pgo+3], bp[pgo+4], > bp[pgo+5], > + bp[pgo+6], bp[pgo+7], bp[pgo+8], bp[pgo+9], bp[pgo+10], > bp[pgo+11]); > > result = write_mode_page(STp, PART_PAGE, 1); > + > + if (!result && needs_format) > + result = format_medium(STp, 1); > + > if (result) { > st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n"); > result = (-EIO); > } > > +out: > return result; > } > > @@ -3570,7 +3689,7 @@ > retval = (-EINVAL); > goto out; > } > - if ((i = st_int_ioctl(STp, MTREW, 0)) < 0 || > + if ((i = do_load_unload(STp, file, 1)) < 0 || > (i = partition_tape(STp, mtc.mt_count)) < 0) { > retval = i; > goto out; > @@ -3581,7 +3700,7 @@ > STp->ps[i].last_block_valid = 0; > } > STp->partition = STp->new_partition = 0; > - STp->nbr_partitions = 1; /* Bad guess ?-) */ > + STp->nbr_partitions = mtc.mt_count > 0 ? 2 : 1; > STps->drv_block = STps->drv_file = 0; > retval = 0; > goto out; ��.n��������+%������w��{.n�����{������ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f