[U-Boot] [PATCH v2 1/2] fs: fat: dynamically allocate memory for temporary buffer
Marek Vasut
marex at denx.de
Tue Feb 5 08:30:45 UTC 2019
On 2/1/19 4:20 PM, Chee, Tien Fong wrote:
> On Fri, 2019-02-01 at 09:19 +0100, Marek Vasut wrote:
>> On 2/1/19 9:11 AM, Chee, Tien Fong wrote:
>>>
>>> On Thu, 2019-01-31 at 15:22 +0100, Marek Vasut wrote:
>>>>
>>>> On 1/31/19 1:42 PM, tien.fong.chee at intel.com wrote:
>>>>>
>>>>>
>>>>> From: Tien Fong Chee <tien.fong.chee at intel.com>
>>>>>
>>>>> Drop the statically allocated get_contents_vfatname_block and
>>>>> dynamically allocate a buffer only if required. This saves
>>>>> 64KiB of memory.
>>>>>
>>>>> Signed-off-by: Stefan Agner <stefan.ag... at toradex.com>
>>>>> Signed-off-by: Tien Fong Chee <tien.fong.chee at intel.com>
>>>>>
>>>>> ---
>>>>>
>>>>> changes for v2
>>>>> - Removed the change for debug message.
>>>>> - Set allocation based on actual required size instead of
>>>>> default
>>>>> max
>>>>> cluster size
>>>>> ---
>>>>> fs/fat/fat.c | 17 ++++++++++++-----
>>>>> 1 file changed, 12 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/fs/fat/fat.c b/fs/fat/fat.c
>>>>> index ecfa255..347787e 100644
>>>>> --- a/fs/fat/fat.c
>>>>> +++ b/fs/fat/fat.c
>>>>> @@ -306,9 +306,6 @@ get_cluster(fsdata *mydata, __u32 clustnum,
>>>>> __u8 *buffer, unsigned long size)
>>>>> * into 'buffer'.
>>>>> * Update the number of bytes read in *gotsize or return -1 on
>>>>> fatal errors.
>>>>> */
>>>>> -__u8 get_contents_vfatname_block[MAX_CLUSTSIZE]
>>>>> - __aligned(ARCH_DMA_MINALIGN);
>>>>> -
>>>>> static int get_contents(fsdata *mydata, dir_entry *dentptr,
>>>>> loff_t
>>>>> pos,
>>>>> __u8 *buffer, loff_t maxsize, loff_t
>>>>> *gotsize)
>>>>> {
>>>>> @@ -351,15 +348,25 @@ static int get_contents(fsdata *mydata,
>>>>> dir_entry *dentptr, loff_t pos,
>>>>>
>>>>> /* align to beginning of next cluster if any */
>>>>> if (pos) {
>>>>> + __u8 *tmp_buffer;
>>>>> +
>>>>> actsize = min(filesize,
>>>>> (loff_t)bytesperclust);
>>>>> - if (get_cluster(mydata, curclust,
>>>>> get_contents_vfatname_block,
>>>>> + tmp_buffer = malloc_cache_aligned(actsize);
>>>>> + if (!tmp_buffer) {
>>>>> + debug("Error: allocating buffer\n");
>>>>> + return -ENOMEM;
>>>>> + }
>>>>> +
>>>>> + if (get_cluster(mydata, curclust, tmp_buffer,
>>>>> (int)actsize) != 0) {
>>>> Is the cast of actsize needed ?
>>> Okay, i would remove it.
>>>>
>>>>
>>>>>
>>>>>
>>>>> printf("Error reading cluster\n");
>>>>> + free(tmp_buffer);
>>>>> return -1;
>>>>> }
>>>>> filesize -= actsize;
>>>>> actsize -= pos;
>>>>> - memcpy(buffer, get_contents_vfatname_block +
>>>>> pos,
>>>>> actsize);
>>>>> + memcpy(buffer, tmp_buffer + pos, actsize);
>>>> Hmmm, tmp_buffer is actsize big , but you're memcpy-ing actsize
>>>> here,
>>>> so
>>>> this would mean you memcpy data past the end of tmp_buffer if pos
>>>>>
>>>> 0, no?
>>> This wouldn't happen because the pos and actsize are reset based on
>>> beginning of current cluster instead of beginning of a file. So,
>>> the
>>> memcpy would start at pos based on beginning of current cluster
>>> until
>>> the end of current cluster, that means the size it copies is still
>>> within a cluster size.
>> So pos is always 0 ?
> Nop, reset here means the pos offset would be adjusted accordingly when
> the base change from beginning of the file to beginning of the cluster
> where the pos resides in.
>
> You know the driver getting the content based on cluster by cluster.
OK, reading the code again, after simplification we get:
tmp_buffer = malloc_cache_aligned(actsize);
...
actsize -= pos;
memcpy(buffer, tmp_buffer + pos, actsize);
so there shouldn't be any read past the end of buffer.
--
Best regards,
Marek Vasut
More information about the U-Boot
mailing list