Or to reiterate - if you want this working in 4.9 now is the time to
make time to test it :)


On 14 January 2011 09:42, Marco Peereboom <[email protected]> wrote:
> This one needs lots of testing folks.  Please oblige.
>
> On Sat, Jan 15, 2011 at 01:22:24AM +1100, Joel Sing wrote:
>> The following diff factors out the block I/O code that is used within
>> softraid(4) and also allows it to handle I/Os that exceeds MAXPHYS in
>> size. This is necessary for some upcoming work.
>>
>> This diff needs extensive testing since the main purpose is to read and
>> write the softraid metadata. Bugs in this area will eat softraid metadata
>> and therefore destroy softraid volumes. If you are testing please ensure
>> that you have backed up your data or that the volume does not have
>> critical information. Please report test successes/failures directly to
me.
>>
>> Index: softraidvar.h
>> ===================================================================
>> RCS file: /cvs/src/sys/dev/softraidvar.h,v
>> retrieving revision 1.96
>> diff -u -p -r1.96 softraidvar.h
>> --- softraidvar.h     6 Nov 2010 23:01:56 -0000       1.96
>> +++ softraidvar.h     6 Jan 2011 12:41:26 -0000
>> @@ -624,6 +624,8 @@ int                       sr_check_io_collision(struct
sr_wo
>>  void                 sr_scsi_done(struct sr_discipline *,
>>                           struct scsi_xfer *);
>>  int                  sr_chunk_in_use(struct sr_softc *, dev_t);
>> +int                  sr_rw(struct sr_softc *, dev_t, char *, size_t,
>> +                         daddr64_t, long);
>>
>>  /* discipline functions */
>>  int                  sr_raid_inquiry(struct sr_workunit *);
>> Index: softraid.c
>> ===================================================================
>> RCS file: /cvs/src/sys/dev/softraid.c,v
>> retrieving revision 1.217
>> diff -u -p -r1.217 softraid.c
>> --- softraid.c        20 Dec 2010 17:47:48 -0000      1.217
>> +++ softraid.c        6 Jan 2011 12:41:26 -0000
>> @@ -387,57 +387,93 @@ sr_meta_getdevname(struct sr_softc *sc,
>>  }
>>
>>  int
>> -sr_meta_rw(struct sr_discipline *sd, dev_t dev, void *md, size_t sz,
>> -    daddr64_t ofs, long flags)
>> +sr_rw(struct sr_softc *sc, dev_t dev, char *buf, size_t size, daddr64_t
>> offset,
>> +    long flags)
>>  {
>> -     struct sr_softc         *sc = sd->sd_sc;
>> +     struct vnode            *vp;
>>       struct buf              b;
>> +     size_t                  bufsize;
>>       int                     rv = 1;
>>
>> -     DNPRINTF(SR_D_META, "%s: sr_meta_rw(0x%x, %p, %d, %llu 0x%x)\n",
>> -         DEVNAME(sc), dev, md, sz, ofs, flags);
>> -
>> -     bzero(&b, sizeof(b));
>> +     DNPRINTF(SR_D_MISC, "%s: sr_rw(0x%x, %p, %d, %llu 0x%x)\n",
>> +         DEVNAME(sc), dev, buf, size, offset, flags);
>>
>> -     if (md == NULL) {
>> -             printf("%s: read invalid metadata pointer\n", DEVNAME(sc));
>> +     if (bdevvp(dev, &vp)) {
>> +             printf("%s: sr_rw: failed to allocate vnode\n",
DEVNAME(sc));
>>               goto done;
>>       }
>> -     b.b_flags = flags | B_PHYS;
>> -     b.b_blkno = ofs;
>> -     b.b_bcount = sz;
>> -     b.b_bufsize = sz;
>> -     b.b_resid = sz;
>> -     b.b_data = md;
>> -     b.b_error = 0;
>> -     b.b_proc = curproc;
>> -     b.b_dev = dev;
>> -     b.b_iodone = NULL;
>> -     if (bdevvp(dev, &b.b_vp)) {
>> -             printf("%s: sr_meta_rw: can't allocate vnode\n",
DEVNAME(sc));
>> -             goto done;
>> -     }
>> -     if ((b.b_flags & B_READ) == 0)
>> -             b.b_vp->v_numoutput++;
>> -
>> -     LIST_INIT(&b.b_dep);
>> -     VOP_STRATEGY(&b);
>> -     biowait(&b);
>> -
>> -     if (b.b_flags & B_ERROR) {
>> -             printf("%s: 0x%x i/o error on block %llu while reading "
>> -                 "metadata %d\n", DEVNAME(sc), dev, b.b_blkno,
b.b_error);
>> -             goto done;
>> +
>> +     while (size > 0) {
>> +
>> +             DNPRINTF(SR_D_MISC, "%s: buf %p, size %d, offset %llu)\n",
>> +                 DEVNAME(sc), buf, size, offset);
>> +
>> +             bufsize = (size > MAXPHYS) ? MAXPHYS : size;
>> +
>> +             bzero(&b, sizeof(b));
>> +
>> +             b.b_flags = flags | B_PHYS;
>> +             b.b_proc = curproc;
>> +             b.b_dev = dev;
>> +             b.b_iodone = NULL;
>> +             b.b_error = 0;
>> +             b.b_blkno = offset;
>> +             b.b_data = buf;
>> +             b.b_bcount = bufsize;
>> +             b.b_bufsize = bufsize;
>> +             b.b_resid = bufsize;
>> +             b.b_vp = vp;
>> +
>> +             if ((b.b_flags & B_READ) == 0)
>> +                     vp->v_numoutput++;
>> +
>> +             LIST_INIT(&b.b_dep);
>> +             VOP_STRATEGY(&b);
>> +             biowait(&b);
>> +
>> +             if (b.b_flags & B_ERROR) {
>> +                     printf("%s: I/O error %d on dev 0x%x at block
%llu\n",
>> +                         DEVNAME(sc), b.b_error, dev, b.b_blkno);
>> +                     goto done;
>> +             }
>> +
>> +             size -= bufsize;
>> +             buf += bufsize;
>> +             offset += howmany(bufsize, DEV_BSIZE);
>> +
>>       }
>> +
>>       rv = 0;
>> +
>>  done:
>> -     if (b.b_vp)
>> -             vput(b.b_vp);
>> +     if (vp)
>> +             vput(vp);
>>
>>       return (rv);
>>  }
>>
>>  int
>> +sr_meta_rw(struct sr_discipline *sd, dev_t dev, void *md, size_t size,
>> +    daddr64_t offset, long flags)
>> +{
>> +     int                     rv = 1;
>> +
>> +     DNPRINTF(SR_D_META, "%s: sr_meta_rw(0x%x, %p, %d, %llu 0x%x)\n",
>> +         DEVNAME(sd->sd_sc), dev, md, size, offset, flags);
>> +
>> +     if (md == NULL) {
>> +             printf("%s: sr_meta_rw: invalid metadata pointer\n",
>> +                 DEVNAME(sd->sd_sc));
>> +             goto done;
>> +     }
>> +
>> +     rv = sr_rw(sd->sd_sc, dev, md, size, offset, flags);
>> +
>> +done:
>> +     return (rv);
>> +}
>> +
>> +int
>>  sr_meta_clear(struct sr_discipline *sd)
>>  {
>>       struct sr_softc         *sc = sd->sd_sc;
>> @@ -3167,7 +3203,6 @@ sr_ioctl_installboot(struct sr_softc *sc
>>       void                    *bootblk = NULL, *bootldr = NULL;
>>       struct sr_discipline    *sd = NULL;
>>       struct sr_chunk         *chunk;
>> -     struct buf              b;
>>       u_int32_t               bbs, bls;
>>       int                     rv = EINVAL;
>>       int                     i;
>> @@ -3216,34 +3251,9 @@ sr_ioctl_installboot(struct sr_softc *sc
>>                   "sr_ioctl_installboot: saving boot block to %s "
>>                   "(%u bytes)\n", chunk->src_devname, bbs);
>>
>> -             bzero(&b, sizeof(b));
>> -             b.b_flags = B_WRITE | B_PHYS;
>> -             b.b_blkno = SR_BOOT_BLOCKS_OFFSET;
>> -             b.b_bcount = bbs;
>> -             b.b_bufsize = bbs;
>> -             b.b_resid = bbs;
>> -             b.b_data = bootblk;
>> -             b.b_error = 0;
>> -             b.b_proc = curproc;
>> -             b.b_dev = chunk->src_dev_mm;
>> -             b.b_vp = NULL;
>> -             b.b_iodone = NULL;
>> -             if (bdevvp(chunk->src_dev_mm, &b.b_vp)) {
>> -                     printf("%s: sr_ioctl_installboot: vnode allocation "
>> -                         "failed\n", DEVNAME(sc));
>> -                     goto done;
>> -             }
>> -             if ((b.b_flags & B_READ) == 0)
>> -                     b.b_vp->v_numoutput++;
>> -             LIST_INIT(&b.b_dep);
>> -             VOP_STRATEGY(&b);
>> -             biowait(&b);
>> -             vput(b.b_vp);
>> -
>> -             if (b.b_flags & B_ERROR) {
>> -                     printf("%s: 0x%x i/o error on block %llu while "
>> -                         "writing boot block %d\n", DEVNAME(sc),
>> -                         chunk->src_dev_mm, b.b_blkno, b.b_error);
>> +             if (sr_rw(sc, chunk->src_dev_mm, bootblk, bbs,
>> +                 SR_BOOT_BLOCKS_OFFSET, B_WRITE)) {
>> +                     printf("%s: failed to write boot block\n",
DEVNAME(sc));
>>                       goto done;
>>               }
>>
>> @@ -3252,34 +3262,10 @@ sr_ioctl_installboot(struct sr_softc *sc
>>                   "sr_ioctl_installboot: saving boot loader to %s "
>>                   "(%u bytes)\n", chunk->src_devname, bls);
>>
>> -             bzero(&b, sizeof(b));
>> -             b.b_flags = B_WRITE | B_PHYS;
>> -             b.b_blkno = SR_BOOT_LOADER_OFFSET;
>> -             b.b_bcount = bls;
>> -             b.b_bufsize = bls;
>> -             b.b_resid = bls;
>> -             b.b_data = bootldr;
>> -             b.b_error = 0;
>> -             b.b_proc = curproc;
>> -             b.b_dev = chunk->src_dev_mm;
>> -             b.b_vp = NULL;
>> -             b.b_iodone = NULL;
>> -             if (bdevvp(chunk->src_dev_mm, &b.b_vp)) {
>> -                     printf("%s: sr_ioctl_installboot: vnode alocation "
>> -                         "failed\n", DEVNAME(sc));
>> -                     goto done;
>> -             }
>> -             if ((b.b_flags & B_READ) == 0)
>> -                     b.b_vp->v_numoutput++;
>> -             LIST_INIT(&b.b_dep);
>> -             VOP_STRATEGY(&b);
>> -             biowait(&b);
>> -             vput(b.b_vp);
>> -
>> -             if (b.b_flags & B_ERROR) {
>> -                     printf("%s: 0x%x i/o error on block %llu while "
>> -                         "writing boot blocks %d\n", DEVNAME(sc),
>> -                         chunk->src_dev_mm, b.b_blkno, b.b_error);
>> +             if (sr_rw(sc, chunk->src_dev_mm, bootldr, bls,
>> +                 SR_BOOT_LOADER_OFFSET, B_WRITE)) {
>> +                     printf("%s: failed to write boot loader\n",
>> +                        DEVNAME(sc));
>>                       goto done;
>>               }
>> --
>>
>>    "Stop assuming that systems are secure unless demonstrated insecure;
>>     start assuming that systems are insecure unless designed securely."
>>           - Bruce Schneier

Reply via email to