Re: [U-Boot] [PATCH v2 4/8] fs: add fs_readdir()

2017-09-05 Thread Rob Clark
On Tue, Sep 5, 2017 at 4:56 AM, Simon Glass  wrote:
> Hi Rob,
>
> On 3 September 2017 at 23:16, Łukasz Majewski  wrote:
>> On 09/02/2017 06:37 PM, Rob Clark wrote:
>>>
>>> Needed to support efi file protocol.  The fallback.efi loader wants
>>> to be able to read the contents of the /EFI directory to find an OS
>>> to boot.
>>>
>>> Modelled after POSIX opendir()/readdir()/closedir().  Unlike the other
>>> fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
>>> stream"), to avoid re-traversing of the directory structure at each
>>> step.  The directory stream must be released with closedir() when it
>>> is no longer needed.
>>>
>>
>> Reviewed-by: Łukasz Majewski 
>>
>>
>>> Signed-off-by: Rob Clark 
>>> ---
>>>   disk/part.c| 31 
>>>   fs/fs.c| 91
>>> ++
>>>   include/fs.h   | 55 +++
>>>   include/part.h |  4 +++
>>>   4 files changed, 169 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/disk/part.c b/disk/part.c
>>> index c67fdacc79..aa9183d696 100644
>>> --- a/disk/part.c
>>> +++ b/disk/part.c
>>> @@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int
>>> part,
>>> return -1;
>>>   }
>>>   +int part_get_info_whole_disk(struct blk_desc *dev_desc,
>>> disk_partition_t *info)
>>> +{
>>> +   info->start = 0;
>>> +   info->size = dev_desc->lba;
>>> +   info->blksz = dev_desc->blksz;
>>> +   info->bootable = 0;
>>> +   strcpy((char *)info->type, BOOT_PART_TYPE);
>>> +   strcpy((char *)info->name, "Whole Disk");
>>> +#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
>
> Can you use if() instead of #if for this one? And below. It helps to
> reduce the number of code paths at build-time.

I don't think so, at least not without dropping the corresponding
#ifdef in disk_partition_t

>>> +   info->uuid[0] = 0;
>>> +#endif
>>> +#ifdef CONFIG_PARTITION_TYPE_GUID
>
> Here too. And below.

same thing

>>> +   info->type_guid[0] = 0;
>>> +#endif
>>> +
>>> +   return 0;
>>> +}
>>> +
>>>   int blk_get_device_by_str(const char *ifname, const char
>>> *dev_hwpart_str,
>>>   struct blk_desc **dev_desc)
>>>   {
>>> @@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const
>>> char *dev_part_str,
>>> (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
>>>   - info->start = 0;
>>> -   info->size = (*dev_desc)->lba;
>>> -   info->blksz = (*dev_desc)->blksz;
>>> -   info->bootable = 0;
>>> -   strcpy((char *)info->type, BOOT_PART_TYPE);
>>> -   strcpy((char *)info->name, "Whole Disk");
>>> -#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
>>> -   info->uuid[0] = 0;
>>> -#endif
>>> -#ifdef CONFIG_PARTITION_TYPE_GUID
>>> -   info->type_guid[0] = 0;
>>> -#endif
>>> +   part_get_info_whole_disk(*dev_desc, info);
>>> ret = 0;
>>> goto cleanup;
>>> diff --git a/fs/fs.c b/fs/fs.c
>>> index 13cd3626c6..441c880654 100644
>>> --- a/fs/fs.c
>>> +++ b/fs/fs.c
>>> @@ -21,6 +21,7 @@
>>>   DECLARE_GLOBAL_DATA_PTR;
>>> static struct blk_desc *fs_dev_desc;
>>> +static int fs_dev_part;
>>>   static disk_partition_t fs_partition;
>>>   static int fs_type = FS_TYPE_ANY;
>>>   @@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)
>>> return -1;
>>>   }
>>>   +static inline int fs_opendir_unsupported(const char *filename, FS_DIR
>>> **dirp)
>>> +{
>>> +   return -EACCES;
>>> +}
>>> +
>>>   struct fstype_info {
>>> int fstype;
>>> char *name;
>>> @@ -92,6 +98,9 @@ struct fstype_info {
>>>  loff_t len, loff_t *actwrite);
>>> void (*close)(void);
>>> int (*uuid)(char *uuid_str);
>>> +   int (*opendir)(const char *filename, FS_DIR **dirp);
>>> +   int (*readdir)(FS_DIR *dirp);
>>> +   void (*closedir)(FS_DIR *dirp);
>
> Please comment these. Also can you use struct instead of typedef?

typedef-struct-caps here was based on how posix readdir() works.  I
guess we can deviate, it isn't 100% clone of readdir().. but I figured
it was more clear to be more similar to posix.

>>>   };
>>> static struct fstype_info fstypes[] = {
>>> @@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
>>> .write = fs_write_unsupported,
>>>   #endif
>>> .uuid = fs_uuid_unsupported,
>>> +   .opendir = fs_opendir_unsupported,
>>> },
>>>   #endif
>>>   #ifdef CONFIG_FS_EXT4
>>> @@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
>>> .write = fs_write_unsupported,
>>>   #endif
>>> .uuid = ext4fs_uuid,
>>> +   .opendir = fs_opendir_unsupported,
>>> },
>>>   #endif
>>>   #ifdef CONFIG_SANDBOX
>>> @@ -146,6 +157,7 @@ static struct 

Re: [U-Boot] [PATCH v2 4/8] fs: add fs_readdir()

2017-09-05 Thread Simon Glass
Hi Rob,

On 3 September 2017 at 23:16, Łukasz Majewski  wrote:
> On 09/02/2017 06:37 PM, Rob Clark wrote:
>>
>> Needed to support efi file protocol.  The fallback.efi loader wants
>> to be able to read the contents of the /EFI directory to find an OS
>> to boot.
>>
>> Modelled after POSIX opendir()/readdir()/closedir().  Unlike the other
>> fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
>> stream"), to avoid re-traversing of the directory structure at each
>> step.  The directory stream must be released with closedir() when it
>> is no longer needed.
>>
>
> Reviewed-by: Łukasz Majewski 
>
>
>> Signed-off-by: Rob Clark 
>> ---
>>   disk/part.c| 31 
>>   fs/fs.c| 91
>> ++
>>   include/fs.h   | 55 +++
>>   include/part.h |  4 +++
>>   4 files changed, 169 insertions(+), 12 deletions(-)
>>
>> diff --git a/disk/part.c b/disk/part.c
>> index c67fdacc79..aa9183d696 100644
>> --- a/disk/part.c
>> +++ b/disk/part.c
>> @@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int
>> part,
>> return -1;
>>   }
>>   +int part_get_info_whole_disk(struct blk_desc *dev_desc,
>> disk_partition_t *info)
>> +{
>> +   info->start = 0;
>> +   info->size = dev_desc->lba;
>> +   info->blksz = dev_desc->blksz;
>> +   info->bootable = 0;
>> +   strcpy((char *)info->type, BOOT_PART_TYPE);
>> +   strcpy((char *)info->name, "Whole Disk");
>> +#if CONFIG_IS_ENABLED(PARTITION_UUIDS)

Can you use if() instead of #if for this one? And below. It helps to
reduce the number of code paths at build-time.

>> +   info->uuid[0] = 0;
>> +#endif
>> +#ifdef CONFIG_PARTITION_TYPE_GUID

Here too. And below.

>> +   info->type_guid[0] = 0;
>> +#endif
>> +
>> +   return 0;
>> +}
>> +
>>   int blk_get_device_by_str(const char *ifname, const char
>> *dev_hwpart_str,
>>   struct blk_desc **dev_desc)
>>   {
>> @@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const
>> char *dev_part_str,
>> (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
>>   - info->start = 0;
>> -   info->size = (*dev_desc)->lba;
>> -   info->blksz = (*dev_desc)->blksz;
>> -   info->bootable = 0;
>> -   strcpy((char *)info->type, BOOT_PART_TYPE);
>> -   strcpy((char *)info->name, "Whole Disk");
>> -#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
>> -   info->uuid[0] = 0;
>> -#endif
>> -#ifdef CONFIG_PARTITION_TYPE_GUID
>> -   info->type_guid[0] = 0;
>> -#endif
>> +   part_get_info_whole_disk(*dev_desc, info);
>> ret = 0;
>> goto cleanup;
>> diff --git a/fs/fs.c b/fs/fs.c
>> index 13cd3626c6..441c880654 100644
>> --- a/fs/fs.c
>> +++ b/fs/fs.c
>> @@ -21,6 +21,7 @@
>>   DECLARE_GLOBAL_DATA_PTR;
>> static struct blk_desc *fs_dev_desc;
>> +static int fs_dev_part;
>>   static disk_partition_t fs_partition;
>>   static int fs_type = FS_TYPE_ANY;
>>   @@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)
>> return -1;
>>   }
>>   +static inline int fs_opendir_unsupported(const char *filename, FS_DIR
>> **dirp)
>> +{
>> +   return -EACCES;
>> +}
>> +
>>   struct fstype_info {
>> int fstype;
>> char *name;
>> @@ -92,6 +98,9 @@ struct fstype_info {
>>  loff_t len, loff_t *actwrite);
>> void (*close)(void);
>> int (*uuid)(char *uuid_str);
>> +   int (*opendir)(const char *filename, FS_DIR **dirp);
>> +   int (*readdir)(FS_DIR *dirp);
>> +   void (*closedir)(FS_DIR *dirp);

Please comment these. Also can you use struct instead of typedef?

>>   };
>> static struct fstype_info fstypes[] = {
>> @@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
>> .write = fs_write_unsupported,
>>   #endif
>> .uuid = fs_uuid_unsupported,
>> +   .opendir = fs_opendir_unsupported,
>> },
>>   #endif
>>   #ifdef CONFIG_FS_EXT4
>> @@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
>> .write = fs_write_unsupported,
>>   #endif
>> .uuid = ext4fs_uuid,
>> +   .opendir = fs_opendir_unsupported,
>> },
>>   #endif
>>   #ifdef CONFIG_SANDBOX
>> @@ -146,6 +157,7 @@ static struct fstype_info fstypes[] = {
>> .read = fs_read_sandbox,
>> .write = fs_write_sandbox,
>> .uuid = fs_uuid_unsupported,
>> +   .opendir = fs_opendir_unsupported,
>> },
>>   #endif
>>   #ifdef CONFIG_CMD_UBIFS
>> @@ -161,6 +173,7 @@ static struct fstype_info fstypes[] = {
>> .read = ubifs_read,
>> .write = fs_write_unsupported,
>> .uuid = fs_uuid_unsupported,
>> +   .opendir = 

Re: [U-Boot] [PATCH v2 4/8] fs: add fs_readdir()

2017-09-03 Thread Łukasz Majewski

On 09/02/2017 06:37 PM, Rob Clark wrote:

Needed to support efi file protocol.  The fallback.efi loader wants
to be able to read the contents of the /EFI directory to find an OS
to boot.

Modelled after POSIX opendir()/readdir()/closedir().  Unlike the other
fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
stream"), to avoid re-traversing of the directory structure at each
step.  The directory stream must be released with closedir() when it
is no longer needed.



Reviewed-by: Łukasz Majewski 


Signed-off-by: Rob Clark 
---
  disk/part.c| 31 
  fs/fs.c| 91 ++
  include/fs.h   | 55 +++
  include/part.h |  4 +++
  4 files changed, 169 insertions(+), 12 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index c67fdacc79..aa9183d696 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int part,
return -1;
  }
  
+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)

+{
+   info->start = 0;
+   info->size = dev_desc->lba;
+   info->blksz = dev_desc->blksz;
+   info->bootable = 0;
+   strcpy((char *)info->type, BOOT_PART_TYPE);
+   strcpy((char *)info->name, "Whole Disk");
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
+   info->uuid[0] = 0;
+#endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+   info->type_guid[0] = 0;
+#endif
+
+   return 0;
+}
+
  int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
  struct blk_desc **dev_desc)
  {
@@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const char 
*dev_part_str,
  
  		(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
  
-		info->start = 0;

-   info->size = (*dev_desc)->lba;
-   info->blksz = (*dev_desc)->blksz;
-   info->bootable = 0;
-   strcpy((char *)info->type, BOOT_PART_TYPE);
-   strcpy((char *)info->name, "Whole Disk");
-#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
-   info->uuid[0] = 0;
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
-   info->type_guid[0] = 0;
-#endif
+   part_get_info_whole_disk(*dev_desc, info);
  
  		ret = 0;

goto cleanup;
diff --git a/fs/fs.c b/fs/fs.c
index 13cd3626c6..441c880654 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -21,6 +21,7 @@
  DECLARE_GLOBAL_DATA_PTR;
  
  static struct blk_desc *fs_dev_desc;

+static int fs_dev_part;
  static disk_partition_t fs_partition;
  static int fs_type = FS_TYPE_ANY;
  
@@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)

return -1;
  }
  
+static inline int fs_opendir_unsupported(const char *filename, FS_DIR **dirp)

+{
+   return -EACCES;
+}
+
  struct fstype_info {
int fstype;
char *name;
@@ -92,6 +98,9 @@ struct fstype_info {
 loff_t len, loff_t *actwrite);
void (*close)(void);
int (*uuid)(char *uuid_str);
+   int (*opendir)(const char *filename, FS_DIR **dirp);
+   int (*readdir)(FS_DIR *dirp);
+   void (*closedir)(FS_DIR *dirp);
  };
  
  static struct fstype_info fstypes[] = {

@@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
  #endif
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
  #endif
  #ifdef CONFIG_FS_EXT4
@@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
  #endif
.uuid = ext4fs_uuid,
+   .opendir = fs_opendir_unsupported,
},
  #endif
  #ifdef CONFIG_SANDBOX
@@ -146,6 +157,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_sandbox,
.write = fs_write_sandbox,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
  #endif
  #ifdef CONFIG_CMD_UBIFS
@@ -161,6 +173,7 @@ static struct fstype_info fstypes[] = {
.read = ubifs_read,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
  #endif
{
@@ -175,6 +188,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_unsupported,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
  };
  
@@ -228,6 +242,31 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
  
  		if (!info->probe(fs_dev_desc, _partition)) {

fs_type = info->fstype;
+   fs_dev_part = part;
+   return 0;
+   }
+   }
+
+   return -1;
+}
+
+/* set current blk device w/ blk_desc + 

[U-Boot] [PATCH v2 4/8] fs: add fs_readdir()

2017-09-02 Thread Rob Clark
Needed to support efi file protocol.  The fallback.efi loader wants
to be able to read the contents of the /EFI directory to find an OS
to boot.

Modelled after POSIX opendir()/readdir()/closedir().  Unlike the other
fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
stream"), to avoid re-traversing of the directory structure at each
step.  The directory stream must be released with closedir() when it
is no longer needed.

Signed-off-by: Rob Clark 
---
 disk/part.c| 31 
 fs/fs.c| 91 ++
 include/fs.h   | 55 +++
 include/part.h |  4 +++
 4 files changed, 169 insertions(+), 12 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index c67fdacc79..aa9183d696 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int part,
return -1;
 }
 
+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
+{
+   info->start = 0;
+   info->size = dev_desc->lba;
+   info->blksz = dev_desc->blksz;
+   info->bootable = 0;
+   strcpy((char *)info->type, BOOT_PART_TYPE);
+   strcpy((char *)info->name, "Whole Disk");
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
+   info->uuid[0] = 0;
+#endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+   info->type_guid[0] = 0;
+#endif
+
+   return 0;
+}
+
 int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
  struct blk_desc **dev_desc)
 {
@@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const char 
*dev_part_str,
 
(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
 
-   info->start = 0;
-   info->size = (*dev_desc)->lba;
-   info->blksz = (*dev_desc)->blksz;
-   info->bootable = 0;
-   strcpy((char *)info->type, BOOT_PART_TYPE);
-   strcpy((char *)info->name, "Whole Disk");
-#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
-   info->uuid[0] = 0;
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
-   info->type_guid[0] = 0;
-#endif
+   part_get_info_whole_disk(*dev_desc, info);
 
ret = 0;
goto cleanup;
diff --git a/fs/fs.c b/fs/fs.c
index 13cd3626c6..441c880654 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -21,6 +21,7 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct blk_desc *fs_dev_desc;
+static int fs_dev_part;
 static disk_partition_t fs_partition;
 static int fs_type = FS_TYPE_ANY;
 
@@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)
return -1;
 }
 
+static inline int fs_opendir_unsupported(const char *filename, FS_DIR **dirp)
+{
+   return -EACCES;
+}
+
 struct fstype_info {
int fstype;
char *name;
@@ -92,6 +98,9 @@ struct fstype_info {
 loff_t len, loff_t *actwrite);
void (*close)(void);
int (*uuid)(char *uuid_str);
+   int (*opendir)(const char *filename, FS_DIR **dirp);
+   int (*readdir)(FS_DIR *dirp);
+   void (*closedir)(FS_DIR *dirp);
 };
 
 static struct fstype_info fstypes[] = {
@@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
 #endif
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_FS_EXT4
@@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
 #endif
.uuid = ext4fs_uuid,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_SANDBOX
@@ -146,6 +157,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_sandbox,
.write = fs_write_sandbox,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_CMD_UBIFS
@@ -161,6 +173,7 @@ static struct fstype_info fstypes[] = {
.read = ubifs_read,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
{
@@ -175,6 +188,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_unsupported,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 };
 
@@ -228,6 +242,31 @@ int fs_set_blk_dev(const char *ifname, const char 
*dev_part_str, int fstype)
 
if (!info->probe(fs_dev_desc, _partition)) {
fs_type = info->fstype;
+   fs_dev_part = part;
+   return 0;
+   }
+   }
+
+   return -1;
+}
+
+/* set current blk device w/ blk_desc + partition # */
+int fs_set_blk_dev2(struct blk_desc *desc, int part)
+{
+   struct 

[U-Boot] [PATCH v2 4/8] fs: add fs_readdir()

2017-08-14 Thread Rob Clark
Needed to support efi file protocol.  The fallback.efi loader wants
to be able to read the contents of the /EFI directory to find an OS
to boot.

Modelled after POSIX opendir()/readdir()/closedir().  Unlike the other
fs APIs, this is stateful (ie. state is held in the FS_DIR "directory
stream"), to avoid re-traversing of the directory structure at each
step.  The directory stream must be released with closedir() when it
is no longer needed.

Signed-off-by: Rob Clark 
---
 disk/part.c| 31 
 fs/fs.c| 91 ++
 include/fs.h   | 55 +++
 include/part.h |  4 +++
 4 files changed, 169 insertions(+), 12 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index e640a55163..3eb58a4805 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -327,6 +327,24 @@ int part_get_info(struct blk_desc *dev_desc, int part,
return -1;
 }
 
+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
+{
+   info->start = 0;
+   info->size = dev_desc->lba;
+   info->blksz = dev_desc->blksz;
+   info->bootable = 0;
+   strcpy((char *)info->type, BOOT_PART_TYPE);
+   strcpy((char *)info->name, "Whole Disk");
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
+   info->uuid[0] = 0;
+#endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+   info->type_guid[0] = 0;
+#endif
+
+   return 0;
+}
+
 int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
  struct blk_desc **dev_desc)
 {
@@ -519,18 +537,7 @@ int blk_get_device_part_str(const char *ifname, const char 
*dev_part_str,
 
(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
 
-   info->start = 0;
-   info->size = (*dev_desc)->lba;
-   info->blksz = (*dev_desc)->blksz;
-   info->bootable = 0;
-   strcpy((char *)info->type, BOOT_PART_TYPE);
-   strcpy((char *)info->name, "Whole Disk");
-#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
-   info->uuid[0] = 0;
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
-   info->type_guid[0] = 0;
-#endif
+   part_get_info_whole_disk(*dev_desc, info);
 
ret = 0;
goto cleanup;
diff --git a/fs/fs.c b/fs/fs.c
index 595ff1fe69..1b4f41920d 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -21,6 +21,7 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct blk_desc *fs_dev_desc;
+static int fs_dev_part;
 static disk_partition_t fs_partition;
 static int fs_type = FS_TYPE_ANY;
 
@@ -69,6 +70,11 @@ static inline int fs_uuid_unsupported(char *uuid_str)
return -1;
 }
 
+static inline int fs_opendir_unsupported(const char *filename, FS_DIR **dirp)
+{
+   return -EACCES;
+}
+
 struct fstype_info {
int fstype;
char *name;
@@ -92,6 +98,9 @@ struct fstype_info {
 loff_t len, loff_t *actwrite);
void (*close)(void);
int (*uuid)(char *uuid_str);
+   int (*opendir)(const char *filename, FS_DIR **dirp);
+   int (*readdir)(FS_DIR *dirp);
+   void (*closedir)(FS_DIR *dirp);
 };
 
 static struct fstype_info fstypes[] = {
@@ -112,6 +121,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
 #endif
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_FS_EXT4
@@ -131,6 +141,7 @@ static struct fstype_info fstypes[] = {
.write = fs_write_unsupported,
 #endif
.uuid = ext4fs_uuid,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_SANDBOX
@@ -146,6 +157,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_sandbox,
.write = fs_write_sandbox,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
 #ifdef CONFIG_CMD_UBIFS
@@ -161,6 +173,7 @@ static struct fstype_info fstypes[] = {
.read = ubifs_read,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 #endif
{
@@ -175,6 +188,7 @@ static struct fstype_info fstypes[] = {
.read = fs_read_unsupported,
.write = fs_write_unsupported,
.uuid = fs_uuid_unsupported,
+   .opendir = fs_opendir_unsupported,
},
 };
 
@@ -228,6 +242,31 @@ int fs_set_blk_dev(const char *ifname, const char 
*dev_part_str, int fstype)
 
if (!info->probe(fs_dev_desc, _partition)) {
fs_type = info->fstype;
+   fs_dev_part = part;
+   return 0;
+   }
+   }
+
+   return -1;
+}
+
+/* set current blk device w/ blk_desc + partition # */
+int fs_set_blk_dev2(struct blk_desc *desc, int part)
+{
+   struct