tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

patch for raidframe and non 512 byte sector devices



hi folks.


the following patch let's me access both 512 byte and 4K
sector disks at the same time, as long as they are in
separate raids.  the existing rf code assumes/enforces
this part, i just made it support other sets concurrently.

the main change is moving the parity bitmap to the sector
after the component label sector(s), instead of being
immediately after the label, which meant it was on the same
sector as the label for >1024 byte devices.

i'm a little annoyed at having to add a 2nd call to
getdisksize() to enable auto-configure to work, but i 
don't see another way that wasn't much uglier.

i'll probably commit this in a week or so after i've done
a bunch more testing.


.mrg.


Index: rf_disks.c
===================================================================
RCS file: /cvsroot/src/sys/dev/raidframe/rf_disks.c,v
retrieving revision 1.74
diff -p -r1.74 rf_disks.c
*** rf_disks.c  1 Nov 2010 02:35:25 -0000       1.74
--- rf_disks.c  6 Nov 2010 20:58:16 -0000
*************** rf_ConfigureDisk(RF_Raid_t *raidPtr, cha
*** 599,614 ****
                if (error == ENXIO) {
                        /* the component isn't there... must be dead :-( */
                        diskPtr->status = rf_ds_failed;
                } else {
                        return (error);
                }
        }
-       if (diskPtr->status == rf_ds_optimal) {
  
                if ((error = VOP_GETATTR(vp, &va, curlwp->l_cred)) != 0) 
                        return (error);
-               if ((error = rf_getdisksize(vp, curlwp, diskPtr)) != 0)
-                       return (error);
  
                raidPtr->raid_cinfo[col].ci_vp = vp;
                raidPtr->raid_cinfo[col].ci_dev = va.va_rdev;
--- 599,624 ----
                if (error == ENXIO) {
                        /* the component isn't there... must be dead :-( */
                        diskPtr->status = rf_ds_failed;
+                       return 0;
                } else {
                        return (error);
                }
        }
  
+       if ((error = rf_getdisksize(vp, curlwp, diskPtr)) != 0)
+               return (error);
+ 
+       /*
+        * If this raidPtr's bytesPerSector is zero, fill it in with this
+        * components blockSize.  This will give us something to work with
+        * initially, and if it is wrong, we'll get errors later.
+        */
+       if (raidPtr->bytesPerSector == 0)
+               raidPtr->bytesPerSector = diskPtr->blockSize;
+ 
+       if (diskPtr->status == rf_ds_optimal) {
                if ((error = VOP_GETATTR(vp, &va, curlwp->l_cred)) != 0) 
                        return (error);
  
                raidPtr->raid_cinfo[col].ci_vp = vp;
                raidPtr->raid_cinfo[col].ci_dev = va.va_rdev;
Index: rf_netbsdkintf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/raidframe/rf_netbsdkintf.c,v
retrieving revision 1.275
diff -p -r1.275 rf_netbsdkintf.c
*** rf_netbsdkintf.c    1 Nov 2010 02:35:25 -0000       1.275
--- rf_netbsdkintf.c    6 Nov 2010 20:58:20 -0000
*************** static int raidread_component_area(dev_t
*** 227,236 ****
  static int raidwrite_component_area(dev_t, struct vnode *, void *, size_t,
      daddr_t, daddr_t, int);
  
! static int raidwrite_component_label(dev_t, struct vnode *,
!     RF_ComponentLabel_t *);
! static int raidread_component_label(dev_t, struct vnode *,
!     RF_ComponentLabel_t *);
  
  
  dev_type_open(raidopen);
--- 227,236 ----
  static int raidwrite_component_area(dev_t, struct vnode *, void *, size_t,
      daddr_t, daddr_t, int);
  
! static int raidwrite_component_label(unsigned,
!     dev_t, struct vnode *, RF_ComponentLabel_t *);
! static int raidread_component_label(unsigned,
!     dev_t, struct vnode *, RF_ComponentLabel_t *);
  
  
  dev_type_open(raidopen);
*************** raidioctl(dev_t dev, u_long cmd, void *d
*** 1033,1040 ****
        rs = &raid_softc[unit];
        raidPtr = raidPtrs[unit];
  
!       db1_printf(("raidioctl: %d %d %d %d\n", (int) dev,
!               (int) DISKPART(dev), (int) unit, (int) cmd));
  
        /* Must be open for writes for these commands... */
        switch (cmd) {
--- 1033,1040 ----
        rs = &raid_softc[unit];
        raidPtr = raidPtrs[unit];
  
!       db1_printf(("raidioctl: %d %d %d %lu\n", (int) dev,
!               (int) DISKPART(dev), (int) unit, cmd));
  
        /* Must be open for writes for these commands... */
        switch (cmd) {
*************** raidunlock(struct raid_softc *rs)
*** 2441,2450 ****
  
  #define RF_COMPONENT_INFO_OFFSET  16384 /* bytes */
  #define RF_COMPONENT_INFO_SIZE     1024 /* bytes */
- #define RF_PARITY_MAP_OFFSET \
-       (RF_COMPONENT_INFO_OFFSET + RF_COMPONENT_INFO_SIZE)
  #define RF_PARITY_MAP_SIZE   RF_PARITYMAP_NBYTE
  
  int
  raidmarkclean(RF_Raid_t *raidPtr, RF_RowCol_t col)
  {
--- 2441,2497 ----
  
  #define RF_COMPONENT_INFO_OFFSET  16384 /* bytes */
  #define RF_COMPONENT_INFO_SIZE     1024 /* bytes */
  #define RF_PARITY_MAP_SIZE   RF_PARITYMAP_NBYTE
  
+ static daddr_t
+ rf_component_info_offset(void)
+ {
+ 
+       return RF_COMPONENT_INFO_OFFSET;
+ }
+ 
+ static daddr_t
+ rf_component_info_size(unsigned secsize)
+ {
+       daddr_t info_size;
+ 
+       KASSERT(secsize);
+       if (secsize > RF_COMPONENT_INFO_SIZE)
+               info_size = secsize;
+       else
+               info_size = RF_COMPONENT_INFO_SIZE;
+ 
+       return info_size;
+ }
+ 
+ static daddr_t
+ rf_parity_map_offset(RF_Raid_t *raidPtr)
+ {
+       daddr_t map_offset;
+ 
+       KASSERT(raidPtr->bytesPerSector);
+       if (raidPtr->bytesPerSector > RF_COMPONENT_INFO_SIZE)
+               map_offset = raidPtr->bytesPerSector;
+       else
+               map_offset = RF_COMPONENT_INFO_SIZE;
+       map_offset += rf_component_info_offset();
+ 
+       return map_offset;
+ }
+ 
+ static daddr_t
+ rf_parity_map_size(RF_Raid_t *raidPtr)
+ {
+       daddr_t map_size;
+ 
+       if (raidPtr->bytesPerSector > RF_PARITY_MAP_SIZE)
+               map_size = raidPtr->bytesPerSector;
+       else
+               map_size = RF_PARITY_MAP_SIZE;
+ 
+       return map_size;
+ }
+ 
  int
  raidmarkclean(RF_Raid_t *raidPtr, RF_RowCol_t col)
  {
*************** raidmarkdirty(RF_Raid_t *raidPtr, RF_Row
*** 2471,2477 ****
  int
  raidfetch_component_label(RF_Raid_t *raidPtr, RF_RowCol_t col)
  {
!       return raidread_component_label(raidPtr->Disks[col].dev,
            raidPtr->raid_cinfo[col].ci_vp, 
            &raidPtr->raid_cinfo[col].ci_label);
  }
--- 2518,2526 ----
  int
  raidfetch_component_label(RF_Raid_t *raidPtr, RF_RowCol_t col)
  {
!       KASSERT(raidPtr->bytesPerSector);
!       return raidread_component_label(raidPtr->bytesPerSector,
!           raidPtr->Disks[col].dev,
            raidPtr->raid_cinfo[col].ci_vp, 
            &raidPtr->raid_cinfo[col].ci_label);
  }
*************** raidflush_component_label(RF_Raid_t *rai
*** 2492,2509 ****
  #ifndef RF_NO_PARITY_MAP
        label->parity_map_modcount = label->mod_counter;
  #endif
!       return raidwrite_component_label(raidPtr->Disks[col].dev,
            raidPtr->raid_cinfo[col].ci_vp, label);
  }
  
  
  static int
! raidread_component_label(dev_t dev, struct vnode *b_vp,
      RF_ComponentLabel_t *clabel)
  {
        return raidread_component_area(dev, b_vp, clabel, 
            sizeof(RF_ComponentLabel_t),
!           RF_COMPONENT_INFO_OFFSET, RF_COMPONENT_INFO_SIZE);
  }
  
  /* ARGSUSED */
--- 2541,2560 ----
  #ifndef RF_NO_PARITY_MAP
        label->parity_map_modcount = label->mod_counter;
  #endif
!       return raidwrite_component_label(raidPtr->bytesPerSector,
!           raidPtr->Disks[col].dev,
            raidPtr->raid_cinfo[col].ci_vp, label);
  }
  
  
  static int
! raidread_component_label(unsigned secsize, dev_t dev, struct vnode *b_vp,
      RF_ComponentLabel_t *clabel)
  {
        return raidread_component_area(dev, b_vp, clabel, 
            sizeof(RF_ComponentLabel_t),
!           rf_component_info_offset(),
!           rf_component_info_size(secsize));
  }
  
  /* ARGSUSED */
*************** raidread_component_area(dev_t dev, struc
*** 2551,2562 ****
  
  
  static int
! raidwrite_component_label(dev_t dev, struct vnode *b_vp,
!       RF_ComponentLabel_t *clabel)
  {
        return raidwrite_component_area(dev, b_vp, clabel,
            sizeof(RF_ComponentLabel_t),
!           RF_COMPONENT_INFO_OFFSET, RF_COMPONENT_INFO_SIZE, 0);
  }
  
  /* ARGSUSED */
--- 2602,2614 ----
  
  
  static int
! raidwrite_component_label(unsigned secsize, dev_t dev, struct vnode *b_vp,
!     RF_ComponentLabel_t *clabel)
  {
        return raidwrite_component_area(dev, b_vp, clabel,
            sizeof(RF_ComponentLabel_t),
!           rf_component_info_offset(),
!           rf_component_info_size(secsize), 0);
  }
  
  /* ARGSUSED */
*************** rf_paritymap_kern_write(RF_Raid_t *raidP
*** 2611,2617 ****
                raidwrite_component_area(raidPtr->Disks[c].dev,
                    raidPtr->raid_cinfo[c].ci_vp, map,
                    RF_PARITYMAP_NBYTE,
!                   RF_PARITY_MAP_OFFSET, RF_PARITY_MAP_SIZE, 0);
        }
  }
  
--- 2663,2670 ----
                raidwrite_component_area(raidPtr->Disks[c].dev,
                    raidPtr->raid_cinfo[c].ci_vp, map,
                    RF_PARITYMAP_NBYTE,
!                   rf_parity_map_offset(raidPtr),
!                   rf_parity_map_size(raidPtr), 0);
        }
  }
  
*************** rf_paritymap_kern_read(RF_Raid_t *raidPt
*** 2629,2635 ****
                raidread_component_area(raidPtr->Disks[c].dev,
                    raidPtr->raid_cinfo[c].ci_vp, &tmp,
                    RF_PARITYMAP_NBYTE,
!                   RF_PARITY_MAP_OFFSET, RF_PARITY_MAP_SIZE);
                if (first) {
                        memcpy(map, &tmp, sizeof(*map));
                        first = 0;
--- 2682,2689 ----
                raidread_component_area(raidPtr->Disks[c].dev,
                    raidPtr->raid_cinfo[c].ci_vp, &tmp,
                    RF_PARITYMAP_NBYTE,
!                   rf_parity_map_offset(raidPtr),
!                   rf_parity_map_size(raidPtr));
                if (first) {
                        memcpy(map, &tmp, sizeof(*map));
                        first = 0;
*************** rf_ReconstructInPlaceThread(struct rf_re
*** 2909,2915 ****
  
  static RF_AutoConfig_t *
  rf_get_component(RF_AutoConfig_t *ac_list, dev_t dev, struct vnode *vp,
!     const char *cname, RF_SectorCount_t size)
  {
        int good_one = 0;
        RF_ComponentLabel_t *clabel; 
--- 2963,2969 ----
  
  static RF_AutoConfig_t *
  rf_get_component(RF_AutoConfig_t *ac_list, dev_t dev, struct vnode *vp,
!     const char *cname, RF_SectorCount_t size, unsigned secsize)
  {
        int good_one = 0;
        RF_ComponentLabel_t *clabel; 
*************** oomem:
*** 2929,2935 ****
                    return NULL; /* XXX probably should panic? */
        }
  
!       if (!raidread_component_label(dev, vp, clabel)) {
                    /* Got the label.  Does it look reasonable? */
                    if (rf_reasonable_label(clabel) && 
                        (clabel->partitionSize <= size)) {
--- 2983,2989 ----
                    return NULL; /* XXX probably should panic? */
        }
  
!       if (!raidread_component_label(secsize, dev, vp, clabel)) {
                    /* Got the label.  Does it look reasonable? */
                    if (rf_reasonable_label(clabel) && 
                        (clabel->partitionSize <= size)) {
*************** rf_find_raid_components(void)
*** 2976,2982 ****
--- 3030,3039 ----
        int error;
        int i;
        RF_AutoConfig_t *ac_list;
+       uint64_t numsecs;
+       unsigned secsize;
  
+       RF_ASSERT(raidPtr->bytesPerSector < rf_component_info_offset());
  
        /* initialize the AutoConfig list */
        ac_list = NULL;
*************** rf_find_raid_components(void)
*** 3036,3041 ****
--- 3093,3103 ----
                        continue;
                }
  
+               error = getdisksize(vp, &numsecs, &secsize);
+               if (error) {
+                       vput(vp);
+                       continue;
+               }
                if (wedge) {
                        struct dkwedge_info dkw;
                        error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
*************** rf_find_raid_components(void)
*** 3057,3063 ****
                        }
                                
                        ac_list = rf_get_component(ac_list, dev, vp,
!                           device_xname(dv), dkw.dkw_size);
                        continue;
                }
  
--- 3119,3125 ----
                        }
                                
                        ac_list = rf_get_component(ac_list, dev, vp,
!                           device_xname(dv), dkw.dkw_size, secsize);
                        continue;
                }
  
*************** rf_find_raid_components(void)
*** 3102,3108 ****
                        snprintf(cname, sizeof(cname), "%s%c",
                            device_xname(dv), 'a' + i);
                        ac_list = rf_get_component(ac_list, dev, vp, cname,
!                               label.d_partitions[i].p_size);
                }
        }
        deviter_release(&di);
--- 3164,3170 ----
                        snprintf(cname, sizeof(cname), "%s%c",
                            device_xname(dv), 'a' + i);
                        ac_list = rf_get_component(ac_list, dev, vp, cname,
!                               label.d_partitions[i].p_size, secsize);
                }
        }
        deviter_release(&di);


Home | Main Index | Thread Index | Old Index