diff mbox

[U-Boot] Add support for offset of a filesystem within a block-device

Message ID 1394112635-21016-1-git-send-email-oe5hpm@oevsv.at
State RFC
Delegated to: Tom Rini
Headers show

Commit Message

Hannes Schmelzer March 6, 2014, 1:30 p.m. UTC
For clear separation of user's (OS) filesystem to U-Boot and other's
stuff it is now possible to give the filesystem a specific offset and a
specific size.
For full consistency OS storage driver also has to support this and
has to use same offset and size.

Following new parameters has been added to the block_dev_desc_t
structure:
- lba_offset : offset in blocks from which fs is reading/writing
- lba_fs     : size in blocks of fs

This two parameters are filled from the underlaying device-driver.
As default they are initialized for giving whole size of block-device
to the filesystem.

In case of mmc-driver a function for modifiying drive geometry is
called 'board_mmc_geometry', this function is implemented as
'__weak', so it can be replaced by a board-specific function, which
can setup suitable offset and size for the filesystem.
This function is responsible for giving reasonable values, e.g.
lba_offset+lba_fs must not exceed available blocks of the device.

Only MMC Driver and FATFS are modified to support this.

Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
---
 disk/part_dos.c    |   11 ++++++++---
 drivers/mmc/mmc.c  |    8 ++++++++
 fs/fat/fat.c       |    5 +++--
 fs/fat/fat_write.c |    7 ++++---
 include/part.h     |   10 +++++++++-
 5 files changed, 32 insertions(+), 9 deletions(-)

Comments

Tom Rini March 12, 2014, 4:08 p.m. UTC | #1
On Thu, Mar 06, 2014 at 02:30:35PM +0100, Hannes Petermaier wrote:

> For clear separation of user's (OS) filesystem to U-Boot and other's
> stuff it is now possible to give the filesystem a specific offset and a
> specific size.
> For full consistency OS storage driver also has to support this and
> has to use same offset and size.
> 
> Following new parameters has been added to the block_dev_desc_t
> structure:
> - lba_offset : offset in blocks from which fs is reading/writing
> - lba_fs     : size in blocks of fs
> 
> This two parameters are filled from the underlaying device-driver.
> As default they are initialized for giving whole size of block-device
> to the filesystem.
> 
> In case of mmc-driver a function for modifiying drive geometry is
> called 'board_mmc_geometry', this function is implemented as
> '__weak', so it can be replaced by a board-specific function, which
> can setup suitable offset and size for the filesystem.
> This function is responsible for giving reasonable values, e.g.
> lba_offset+lba_fs must not exceed available blocks of the device.
> 
> Only MMC Driver and FATFS are modified to support this.
> 
> Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>

Sorry if I'm being dense here, but what is the usecase exactly?  When we
don't have a partition table of some sort?
Hannes Schmelzer March 12, 2014, 5:19 p.m. UTC | #2
On 2014-03-12 17:08, Tom Rini wrote:
> On Thu, Mar 06, 2014 at 02:30:35PM +0100, Hannes Petermaier wrote:
>
>> For clear separation of user's (OS) filesystem to U-Boot and other's
>> stuff it is now possible to give the filesystem a specific offset and a
>> specific size.
>> For full consistency OS storage driver also has to support this and
>> has to use same offset and size.
>>
>> Following new parameters has been added to the block_dev_desc_t
>> structure:
>> - lba_offset : offset in blocks from which fs is reading/writing
>> - lba_fs     : size in blocks of fs
>>
>> This two parameters are filled from the underlaying device-driver.
>> As default they are initialized for giving whole size of block-device
>> to the filesystem.
>>
>> In case of mmc-driver a function for modifiying drive geometry is
>> called 'board_mmc_geometry', this function is implemented as
>> '__weak', so it can be replaced by a board-specific function, which
>> can setup suitable offset and size for the filesystem.
>> This function is responsible for giving reasonable values, e.g.
>> lba_offset+lba_fs must not exceed available blocks of the device.
>>
>> Only MMC Driver and FATFS are modified to support this.
>>
>> Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
> Sorry if I'm being dense here, but what is the usecase exactly?  When we
> don't have a partition table of some sort?
>
Hi Tom,

I try to explain the use case with my application as example:

I have an eMMC flash with 4GB space. On my target OS vxWorks is running, 
which has as filesystem a simple DOS-FAT.

I would like to give an offset to the filesystem due to two reasons:
a) U-Boot with its environment should / can not remain within the DOSFS 
(it should not be accessible by the user/OS). Also U-Boot must be at 
least with the MLO "in front" of the flash since i am booting from the 
eMMC flash.
b) i want limit the user-accessible space to the flash to about 512MB.

There are, for my unterstanding, two ways to achieve this:

a) give no offset for the "blockdevice" at all and have a partition 
table at the bottom of flash (ROM code searches in my case (am3352) at 
several places for a bootable code, so this method would be suitable for 
booting) - i don't know how it is on other processors, the rest would be 
magic of the following partioning software (OS) - but many os (vxworks 
for example) cannot have specific start-cylinder for the first 
partition, we would have to rewrite the partitioner. Making a change 
within the partitioning section at the OS is therefore a bit critical, 
not at least because changes there affects all other block devices too.

So plan b) looked best for my opinion:
Give a specific offset/size to the 'blockdevice' within raw-flash.
We have to adapt only the specific blockdevice driver to detect/have a 
specific offset/size and rest of OS don't need to know about this 
special situation. We don't use the space laying before the offset 
within the OS at all (clear separation). Within U-Boot we can use the 
whole flash in "raw-mode" and use "FAT" with the beginning of specified 
offset.
With the offset i also can control how much space is left for the OS and 
its filesystem.

Is my explanation clear ? please feel free to ask me more.
Whats your opinion about this ?

best regards,
Hannes
Tom Rini March 12, 2014, 7 p.m. UTC | #3
On Wed, Mar 12, 2014 at 06:19:00PM +0100, Hannes Petermaier wrote:
> 
> On 2014-03-12 17:08, Tom Rini wrote:
> >On Thu, Mar 06, 2014 at 02:30:35PM +0100, Hannes Petermaier wrote:
> >
> >>For clear separation of user's (OS) filesystem to U-Boot and other's
> >>stuff it is now possible to give the filesystem a specific offset and a
> >>specific size.
> >>For full consistency OS storage driver also has to support this and
> >>has to use same offset and size.
> >>
> >>Following new parameters has been added to the block_dev_desc_t
> >>structure:
> >>- lba_offset : offset in blocks from which fs is reading/writing
> >>- lba_fs     : size in blocks of fs
> >>
> >>This two parameters are filled from the underlaying device-driver.
> >>As default they are initialized for giving whole size of block-device
> >>to the filesystem.
> >>
> >>In case of mmc-driver a function for modifiying drive geometry is
> >>called 'board_mmc_geometry', this function is implemented as
> >>'__weak', so it can be replaced by a board-specific function, which
> >>can setup suitable offset and size for the filesystem.
> >>This function is responsible for giving reasonable values, e.g.
> >>lba_offset+lba_fs must not exceed available blocks of the device.
> >>
> >>Only MMC Driver and FATFS are modified to support this.
> >>
> >>Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
> >Sorry if I'm being dense here, but what is the usecase exactly?  When we
> >don't have a partition table of some sort?
> >
> Hi Tom,
> 
> I try to explain the use case with my application as example:
> 
> I have an eMMC flash with 4GB space. On my target OS vxWorks is
> running, which has as filesystem a simple DOS-FAT.
> 
> I would like to give an offset to the filesystem due to two reasons:
> a) U-Boot with its environment should / can not remain within the
> DOSFS (it should not be accessible by the user/OS). Also U-Boot must
> be at least with the MLO "in front" of the flash since i am booting
> from the eMMC flash.
> b) i want limit the user-accessible space to the flash to about 512MB.
> 
> There are, for my unterstanding, two ways to achieve this:
> 
> a) give no offset for the "blockdevice" at all and have a partition
> table at the bottom of flash (ROM code searches in my case (am3352)
> at several places for a bootable code, so this method would be
> suitable for booting) - i don't know how it is on other processors,
> the rest would be magic of the following partioning software (OS) -
> but many os (vxworks for example) cannot have specific
> start-cylinder for the first partition, we would have to rewrite the
> partitioner. Making a change within the partitioning section at the
> OS is therefore a bit critical, not at least because changes there
> affects all other block devices too.
> 
> So plan b) looked best for my opinion:
> Give a specific offset/size to the 'blockdevice' within raw-flash.
> We have to adapt only the specific blockdevice driver to detect/have
> a specific offset/size and rest of OS don't need to know about this
> special situation. We don't use the space laying before the offset
> within the OS at all (clear separation). Within U-Boot we can use
> the whole flash in "raw-mode" and use "FAT" with the beginning of
> specified offset.
> With the offset i also can control how much space is left for the OS
> and its filesystem.
> 
> Is my explanation clear ? please feel free to ask me more.
> Whats your opinion about this ?

Thanks for explaining.  But you should be able to have this work without
changing U-Boot or VxWorks code by doing:
1) Create a partition table at the start of eMMC
2) Write SPL to offset 128KB
2b) If you like, put a backup copy at 256KB
3) Write U-Boot to offset 384KB as usual

Now here's where I'm hindered a bit by my (lack of) knowledge of
VxWorks.  If you cannot say that the first partition in the table is
wherever you like (which seems odd, this is fine elsewhere), just create
a dummy partition that covers from the start until end-512MB, and then
make the next partiton, where you want the user to see next and make it
be 512MB.
Hannes Schmelzer March 12, 2014, 7:17 p.m. UTC | #4
On 2014-03-12 20:00, Tom Rini wrote:
> On Wed, Mar 12, 2014 at 06:19:00PM +0100, Hannes Petermaier wrote:
>> On 2014-03-12 17:08, Tom Rini wrote:
>>> On Thu, Mar 06, 2014 at 02:30:35PM +0100, Hannes Petermaier wrote:
>>>
>>>> For clear separation of user's (OS) filesystem to U-Boot and other's
>>>> stuff it is now possible to give the filesystem a specific offset and a
>>>> specific size.
>>>> For full consistency OS storage driver also has to support this and
>>>> has to use same offset and size.
>>>>
>>>> Following new parameters has been added to the block_dev_desc_t
>>>> structure:
>>>> - lba_offset : offset in blocks from which fs is reading/writing
>>>> - lba_fs     : size in blocks of fs
>>>>
>>>> This two parameters are filled from the underlaying device-driver.
>>>> As default they are initialized for giving whole size of block-device
>>>> to the filesystem.
>>>>
>>>> In case of mmc-driver a function for modifiying drive geometry is
>>>> called 'board_mmc_geometry', this function is implemented as
>>>> '__weak', so it can be replaced by a board-specific function, which
>>>> can setup suitable offset and size for the filesystem.
>>>> This function is responsible for giving reasonable values, e.g.
>>>> lba_offset+lba_fs must not exceed available blocks of the device.
>>>>
>>>> Only MMC Driver and FATFS are modified to support this.
>>>>
>>>> Signed-off-by: Hannes Petermaier <oe5hpm@oevsv.at>
>>> Sorry if I'm being dense here, but what is the usecase exactly?  When we
>>> don't have a partition table of some sort?
>>>
>> Hi Tom,
>>
>> I try to explain the use case with my application as example:
>>
>> I have an eMMC flash with 4GB space. On my target OS vxWorks is
>> running, which has as filesystem a simple DOS-FAT.
>>
>> I would like to give an offset to the filesystem due to two reasons:
>> a) U-Boot with its environment should / can not remain within the
>> DOSFS (it should not be accessible by the user/OS). Also U-Boot must
>> be at least with the MLO "in front" of the flash since i am booting
>> from the eMMC flash.
>> b) i want limit the user-accessible space to the flash to about 512MB.
>>
>> There are, for my unterstanding, two ways to achieve this:
>>
>> a) give no offset for the "blockdevice" at all and have a partition
>> table at the bottom of flash (ROM code searches in my case (am3352)
>> at several places for a bootable code, so this method would be
>> suitable for booting) - i don't know how it is on other processors,
>> the rest would be magic of the following partioning software (OS) -
>> but many os (vxworks for example) cannot have specific
>> start-cylinder for the first partition, we would have to rewrite the
>> partitioner. Making a change within the partitioning section at the
>> OS is therefore a bit critical, not at least because changes there
>> affects all other block devices too.
>>
>> So plan b) looked best for my opinion:
>> Give a specific offset/size to the 'blockdevice' within raw-flash.
>> We have to adapt only the specific blockdevice driver to detect/have
>> a specific offset/size and rest of OS don't need to know about this
>> special situation. We don't use the space laying before the offset
>> within the OS at all (clear separation). Within U-Boot we can use
>> the whole flash in "raw-mode" and use "FAT" with the beginning of
>> specified offset.
>> With the offset i also can control how much space is left for the OS
>> and its filesystem.
>>
>> Is my explanation clear ? please feel free to ask me more.
>> Whats your opinion about this ?
> Thanks for explaining.  But you should be able to have this work without
> changing U-Boot or VxWorks code by doing:
> 1) Create a partition table at the start of eMMC
> 2) Write SPL to offset 128KB
> 2b) If you like, put a backup copy at 256KB
> 3) Write U-Boot to offset 384KB as usual
>
> Now here's where I'm hindered a bit by my (lack of) knowledge of
> VxWorks.  If you cannot say that the first partition in the table is
> wherever you like (which seems odd, this is fine elsewhere), just create
> a dummy partition that covers from the start until end-512MB, and then
> make the next partiton, where you want the user to see next and make it
> be 512MB.
>
Thanks for reply.

Good idea, i've also thougt about this way ....
but what happens in case of OS is going to re-partitioning the drive 
(flash), delete all partitions (dummy-part also) an puts the first (new) 
partition behind the part-table (vxWorks can handle up to four 
partitions and we give end-user the possibility to create/delete 
partitions) ? First partition becomes laying over U-Boot @ 384k (and 
some other stuff which may be stored there).
To prevent this case we would have to modify "fdisk" of vxWorks, which i 
would like to prevent because this is a common part of OS and would 
affect all mass-storage.
With my solution, OS never can see/delete any other (dummy) partitiion - 
it has always "a normal drive" accessible.

best regards,
Hannes
Tom Rini March 12, 2014, 7:33 p.m. UTC | #5
On Wed, Mar 12, 2014 at 08:17:47PM +0100, Hannes Petermaier wrote:

> Good idea, i've also thougt about this way ....
> but what happens in case of OS is going to re-partitioning the drive
> (flash), delete all partitions (dummy-part also) an puts the first
> (new) partition behind the part-table (vxWorks can handle up to four
> partitions and we give end-user the possibility to create/delete
> partitions) ? First partition becomes laying over U-Boot @ 384k (and
> some other stuff which may be stored there).
> To prevent this case we would have to modify "fdisk" of vxWorks,
> which i would like to prevent because this is a common part of OS
> and would affect all mass-storage.
> With my solution, OS never can see/delete any other (dummy)
> partitiion - it has always "a normal drive" accessible.

Since this is really eMMC, mark SPL/U-Boot as protected?  I'd swear such
a thing is allowed, but I've just been looking at QSPI things recently
not eMMC so I might have some mental mismatch.
Hannes Schmelzer March 12, 2014, 8:14 p.m. UTC | #6
On 2014-03-12 20:33, Tom Rini wrote:
> On Wed, Mar 12, 2014 at 08:17:47PM +0100, Hannes Petermaier wrote:
>
>> Good idea, i've also thougt about this way ....
>> but what happens in case of OS is going to re-partitioning the drive
>> (flash), delete all partitions (dummy-part also) an puts the first
>> (new) partition behind the part-table (vxWorks can handle up to four
>> partitions and we give end-user the possibility to create/delete
>> partitions) ? First partition becomes laying over U-Boot @ 384k (and
>> some other stuff which may be stored there).
>> To prevent this case we would have to modify "fdisk" of vxWorks,
>> which i would like to prevent because this is a common part of OS
>> and would affect all mass-storage.
>> With my solution, OS never can see/delete any other (dummy)
>> partitiion - it has always "a normal drive" accessible.
> Since this is really eMMC, mark SPL/U-Boot as protected?  I'd swear such
> a thing is allowed, but I've just been looking at QSPI things recently
> not eMMC so I might have some mental mismatch.
>
Hi Tom,
You're right. SPL could be marked as protected.
But how to deal here with u-boot itself ? its address is within a 
possible area of a partition.
Fdisk doesn't know about that :-(
We also cannot protect #0 where partition-table is stored, because user 
should able to create/delete partitions.

So - maybe be a solution, but unfortunately not for me :-(
Today we give to our end-users up to 4 partitiions, exact that what 
VxWorks can support - so i will be hard to have a 5th one ...

best regards,
Hannes
Tom Rini March 12, 2014, 8:27 p.m. UTC | #7
On Wed, Mar 12, 2014 at 09:14:31PM +0100, Hannes Petermaier wrote:
> 
> On 2014-03-12 20:33, Tom Rini wrote:
> >On Wed, Mar 12, 2014 at 08:17:47PM +0100, Hannes Petermaier wrote:
> >
> >>Good idea, i've also thougt about this way ....
> >>but what happens in case of OS is going to re-partitioning the drive
> >>(flash), delete all partitions (dummy-part also) an puts the first
> >>(new) partition behind the part-table (vxWorks can handle up to four
> >>partitions and we give end-user the possibility to create/delete
> >>partitions) ? First partition becomes laying over U-Boot @ 384k (and
> >>some other stuff which may be stored there).
> >>To prevent this case we would have to modify "fdisk" of vxWorks,
> >>which i would like to prevent because this is a common part of OS
> >>and would affect all mass-storage.
> >>With my solution, OS never can see/delete any other (dummy)
> >>partitiion - it has always "a normal drive" accessible.
> >Since this is really eMMC, mark SPL/U-Boot as protected?  I'd swear such
> >a thing is allowed, but I've just been looking at QSPI things recently
> >not eMMC so I might have some mental mismatch.
> >
> Hi Tom,
> You're right. SPL could be marked as protected.
> But how to deal here with u-boot itself ? its address is within a
> possible area of a partition.
> Fdisk doesn't know about that :-(
> We also cannot protect #0 where partition-table is stored, because
> user should able to create/delete partitions.

Block size then wouldn't let 0->128K be writable, 128->whatever
read-only, whatever->end writable ?

> So - maybe be a solution, but unfortunately not for me :-(
> Today we give to our end-users up to 4 partitiions, exact that what
> VxWorks can support - so i will be hard to have a 5th one ...

Well, I guess there's two ways to look at this, either just
documentation or seeing how hard it would be to make VxWorks behave like
other OSes and let partition 1 be wherever it says it is, or some
combination of both.

I do appreciate you posting the code as it may be useful to others but
at least right now, barring an outcry of "oh wait, I need this too!" I'm
inclined to mark this as RFC in patchwork.  Thanks again!
Hannes Schmelzer March 12, 2014, 8:51 p.m. UTC | #8
On 2014-03-12 21:27, Tom Rini wrote:
>>
>> Hi Tom,
>> You're right. SPL could be marked as protected.
>> But how to deal here with u-boot itself ? its address is within a
>> possible area of a partition.
>> Fdisk doesn't know about that :-(
>> We also cannot protect #0 where partition-table is stored, because
>> user should able to create/delete partitions.
> Block size then wouldn't let 0->128K be writable, 128->whatever
> read-only, whatever->end writable ?
>
>> So - maybe be a solution, but unfortunately not for me :-(
>> Today we give to our end-users up to 4 partitiions, exact that what
>> VxWorks can support - so i will be hard to have a 5th one ...
> Well, I guess there's two ways to look at this, either just
> documentation or seeing how hard it would be to make VxWorks behave like
> other OSes and let partition 1 be wherever it says it is, or some
> combination of both.
>
> I do appreciate you posting the code as it may be useful to others but
> at least right now, barring an outcry of "oh wait, I need this too!" I'm
> inclined to mark this as RFC in patchwork.  Thanks again!
>
Ok Tom, we can do so ... please mark it for now as RFC.
Maybe in the future other people say "i like this too ..." and we can 
apply this feature to the mainline code.

Until this day comes, "block-device offset within flash" will be my 
personal "nursing-case" and i have to patch it into my build.

many thanks for your time and best regards,
Hannes
diff mbox

Patch

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 05c3933..aa38819 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,8 @@  int test_part_dos (block_dev_desc_t *dev_desc)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
-	if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1)
+	if (dev_desc->block_read(dev_desc->dev, dev_desc->lba_offset, 1,
+				 (ulong *)buffer) != 1)
 		return -1;
 
 	if (test_block_type(buffer) != DOS_MBR)
@@ -106,7 +107,9 @@  static void print_partition_extended(block_dev_desc_t *dev_desc,
 	dos_partition_t *pt;
 	int i;
 
-	if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
+	if (dev_desc->block_read(dev_desc->dev,
+				 ext_part_sector + dev_desc->lba_offset, 1,
+				 (ulong *)buffer) != 1) {
 		printf ("** Can't read partition table on %d:%d **\n",
 			dev_desc->dev, ext_part_sector);
 		return;
@@ -169,7 +172,9 @@  static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part
 	dos_partition_t *pt;
 	int i;
 
-	if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
+	if (dev_desc->block_read(dev_desc->dev,
+				 ext_part_sector + dev_desc->lba_offset, 1,
+				 (ulong *)buffer) != 1) {
 		printf ("** Can't read partition table on %d:%d **\n",
 			dev_desc->dev, ext_part_sector);
 		return -1;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8ab0bc9..4acce73 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -526,6 +526,12 @@  static int mmc_change_freq(struct mmc *mmc)
 	return 0;
 }
 
+void __weak board_mmc_geometry(struct mmc *mmc)
+{
+	mmc->block_dev.lba_fs = mmc->block_dev.lba;
+	mmc->block_dev.lba_offset = 0;
+}
+
 static int mmc_set_capacity(struct mmc *mmc, int part_num)
 {
 	switch (part_num) {
@@ -551,6 +557,8 @@  static int mmc_set_capacity(struct mmc *mmc, int part_num)
 
 	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
 
+	board_mmc_geometry(mmc);
+
 	return 0;
 }
 
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 54f42ea..dba0989 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -49,7 +49,8 @@  static int disk_read(__u32 block, __u32 nr_blocks, void *buf)
 		return -1;
 
 	return cur_dev->block_read(cur_dev->dev,
-			cur_part_info.start + block, nr_blocks, buf);
+			cur_part_info.start + block + cur_dev->lba_offset,
+			nr_blocks, buf);
 }
 
 int fat_set_blk_dev(block_dev_desc_t *dev_desc, disk_partition_t *info)
@@ -97,7 +98,7 @@  int fat_register_device(block_dev_desc_t *dev_desc, int part_no)
 		}
 
 		info.start = 0;
-		info.size = dev_desc->lba;
+		info.size = dev_desc->lba_fs;
 		info.blksz = dev_desc->blksz;
 		info.name[0] = 0;
 		info.type[0] = 0;
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 9f5e911..6238a8e 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -31,14 +31,15 @@  static int disk_write(__u32 block, __u32 nr_blocks, void *buf)
 	if (!cur_dev || !cur_dev->block_write)
 		return -1;
 
-	if (cur_part_info.start + block + nr_blocks >
-		cur_part_info.start + total_sector) {
+	if (cur_part_info.start + block + nr_blocks + cur_dev->lba_offset >
+		cur_part_info.start + total_sector + cur_dev->lba_offset) {
 		printf("error: overflow occurs\n");
 		return -1;
 	}
 
 	return cur_dev->block_write(cur_dev->dev,
-			cur_part_info.start + block, nr_blocks,	buf);
+			cur_part_info.start + block + cur_dev->lba_offset,
+			nr_blocks, buf);
 }
 
 /*
diff --git a/include/part.h b/include/part.h
index 4beb6db..29a227a 100644
--- a/include/part.h
+++ b/include/part.h
@@ -20,7 +20,15 @@  typedef struct block_dev_desc {
 #ifdef CONFIG_LBA48
 	unsigned char	lba48;		/* device can use 48bit addr (ATA/ATAPI v7) */
 #endif
-	lbaint_t	lba;		/* number of blocks */
+	lbaint_t	lba_offset;	/*
+					 * offset from which file-systems
+					 * do their work
+					 */
+	lbaint_t	lba_fs;		/*
+					 * number of blocks available to the
+					 * file-system
+					 */
+	lbaint_t	lba;		/* total number of blocks-available */
 	unsigned long	blksz;		/* block size */
 	int		log2blksz;	/* for convenience: log2(blksz) */
 	char		vendor [40+1];	/* IDE model, SCSI Vendor */