[RTEMS Project] #3089: Inconsistent blocking addressing in RFS

RTEMS trac trac at rtems.org
Thu Aug 3 04:22:04 UTC 2017


#3089: Inconsistent blocking addressing in RFS
------------------------+----------------------
 Reporter:  Fan Deng    |      Owner:  Fan Deng
     Type:  defect      |     Status:  assigned
 Priority:  normal      |  Milestone:  4.12.0
Component:  filesystem  |    Version:  4.11
 Severity:  normal      |   Keywords:
------------------------+----------------------
 **Background**
 There are two ways to address a block in RFS:
 1. Via a single 32bit block number (bno)
 2. Via a group number(gno) and a bit offset (bit)
 They should be fully convertible (1-1 mapping). In other words, the
 equation to convert 1 to 2 should be unique within the RFS implementation.

 **The bug**
 The RFS implementation contains two different conversions between 1 and 2.

 **Details**
 1. In rtems_rfs_group_bitmap_alloc (rtems-rfs-group.c, line 172)
 {{{
 bno = gno * group_blocks + bit
 }}}

 2. In rtems_rfs_group_bitmap_alloc (rtems-rfs-group.c, line 228)
 {{{
 bno = gno * group_blocks + bit + 1 (via rtems_rfs_group_block() function)
 }}}

 3. In rtems_rfs_group_bitmap_free (rtems-rfs-group.c, line 283)
 {{{
 bno = gno * group_blocks + bit + 1 (RTEMS_RFS_SUPERBLOCK_SIZE)
 }}}

 4. In rtems_rfs_group_bitmap_test (rtems-rfs-group.c, line 332)
 {{{
 bno = gno * group_blocks + bit
 }}}

 To summarize, the implementation contains two ways of converting a bno to
 a (gno, bit) pair:

 Either:
 {{{
 bno = gno * group_blocks + bit
 }}}
 Or:
 {{{
 bno = gno * group_blocks + bit + 1
 }}}

 **The Fix**
 The RFS implementation should consistently convert a bno to a (gno, bit)
 pair with:
 {{{
 bno = gno * group_blocks + bit + RTEMS_RFS_SUPERBLOCK_SIZE
 }}}

 This is because the superblock is not accounted for in the block bitmaps.
 So places to change:

 1. rtems-rfs-group.c: all references to the conversion must be updated to
 use RTEMS_RFS_SUPERBLOCK_SIZE explicitly.

 2. rtems_rfs_group_block converts the pair to bno via:
 {{{
 #define rtems_rfs_group_block(_g, _b) (((_g)->base) + (_b))
 }}}

 (_g)->base is calculated via rtems-rfs-format.c from:
 {{{
 #define rtems_rfs_fs_block(_fs, _grp, _blk) \
   ((((_fs)->group_blocks) * (_grp)) + (_blk) + 1)
 }}}

 The "+ 1" part should really be "+ RTEMS_RFS_SUPERBLOCK_SIZE" to be
 logically correct. As RTEMS_RFS_SUPERBLOCK_SIZE itself has a comment
 saying:
 {{{
 /**
  * Number of blocks in the superblock. Yes I know it is a superblock and
 not
  * superblocks but if for any reason this needs to change it is handled.
  */
 #define RTEMS_RFS_SUPERBLOCK_SIZE (1)
 }}}

--
Ticket URL: <http://devel.rtems.org/ticket/3089>
RTEMS Project <http://www.rtems.org/>
RTEMS Project


More information about the bugs mailing list