From patchwork Mon May 13 05:49:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1098658 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="s2pCmrv+"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 452VK05WR0z9sML for ; Mon, 13 May 2019 15:50:12 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7AEE4C21E9F; Mon, 13 May 2019 05:50:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 06773C21EFF; Mon, 13 May 2019 05:50:02 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6E071C21ECC; Mon, 13 May 2019 05:49:50 +0000 (UTC) Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by lists.denx.de (Postfix) with ESMTPS id 53CEDC21EBA for ; Mon, 13 May 2019 05:49:47 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id t87so6583294pfa.2 for ; Sun, 12 May 2019 22:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AAhQEX44O5X3JEUnudGCfeufOkZXjDBNdVxokerRGyg=; b=s2pCmrv+yspi4WOh9vi/L/Qgugtnk24wakGp1V842mbH9nLJ8LSWT2eLDI8kLl1fsV KBGz4ijxnL+dEmah7R0TCpDEBiVlQc8unf4VG6AJG9dQUmaKnm/421z61ZAFTS7gdP9q LXs/Qs8P6uYkxuc5qgcqaJO4BB17xlGH/zWIRY20LxKM0yGAm41d/KNJB4EXmrSquQ/K oR7XyIa4S46+4vLDarGO0bixR7Qv8qfcLINvfzXVyR4HN0DADMfdJwSPoM361pXRrt4A 8Xs7DtPjycgvgoVWuRiz8PbIhBio+WMxulWAk2iraReCe/5f7iKwvLmsmZlM5CPaZZvO 7CNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AAhQEX44O5X3JEUnudGCfeufOkZXjDBNdVxokerRGyg=; b=bstWS+uIZm0R4CuXQPQhiYid3VPzWL9v3Vqy+eXL15NqCjGQ9dNq7s3Yt9z9OgC4fz bQkYT6Z9w9WgHV79d5sGez78XNfasFAm9zoR7gzEGkXjkvgKbYxTCNDxLVEq5036rSDV t7bMej1zg7kOtGSNKvbWrLgnfDAaGMktphHI+DG+vBRYNOYY0FUBQSbpY15YkVocLGKS EaOip4aFDx7kHQRItpZk9cOqFriS8BhCq4ECxkbzU2bLyWa9TwdK2xsDbwy7nuClTVPW KPEoS1tzac0yBJZhdVzO7f0zsOZyJMoz3N3YeiuThFoCqkKq+AjYFng+j96RITwKJBxv zL4Q== X-Gm-Message-State: APjAAAVEP6VcO2pmLjRo+dClnEtNzmfAShhLqWkabChyqt/YfFNPLWQV 52oJ1UFhp2mpILDrf6kEfuDDmQ== X-Google-Smtp-Source: APXvYqx1S+77Ox7uKO/9JKdjfzGHqjjbq6qiOasKNdAhIgNvZp7X/aEfA92NN6M2bT2h7Bnzryggjw== X-Received: by 2002:a63:d016:: with SMTP id z22mr29419915pgf.116.1557726585604; Sun, 12 May 2019 22:49:45 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id r9sm15966560pfc.173.2019.05.12.22.49.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 12 May 2019 22:49:45 -0700 (PDT) From: AKASHI Takahiro To: trini@konsulko.com Date: Mon, 13 May 2019 14:49:24 +0900 Message-Id: <20190513054927.17890-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190513054927.17890-1-takahiro.akashi@linaro.org> References: <20190513054927.17890-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 1/4] fs: fat: write to non-cluster-aligned root directory X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" With the commit below, fat now correctly handles a file read under a non-cluster-aligned root directory of fat12/16. Write operation should be fixed in the same manner. Fixes: commit 9b18358dc05d ("fs: fat: fix reading non-cluster-aligned root directory") Signed-off-by: AKASHI Takahiro Cc: Anssi Hannula Tested-by: Heinrich Schuchardt --- fs/fat/fat.c | 15 ++++----- fs/fat/fat_write.c | 78 +++++++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index c5997c21735f..fccaa385d187 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -619,13 +619,14 @@ static int get_fs_info(fsdata *mydata) return -1; } - debug("FAT%d, fat_sect: %d, fatlength: %d\n", - mydata->fatsize, mydata->fat_sect, mydata->fatlength); - debug("Rootdir begins at cluster: %d, sector: %d, offset: %x\n" - "Data begins at: %d\n", - mydata->root_cluster, - mydata->rootdir_sect, - mydata->rootdir_sect * mydata->sect_size, mydata->data_begin); + debug("FAT%d, fat_sect: %d, fatlength: %d, num: %d\n", + mydata->fatsize, mydata->fat_sect, mydata->fatlength, + mydata->fats); + debug("Rootdir begins at cluster: %d, sector: %d, size: %x\n" + "Data begins at: %d\n", + mydata->root_cluster, + mydata->rootdir_sect, + mydata->rootdir_size * mydata->sect_size, mydata->data_begin); debug("Sector size: %d, cluster size: %d\n", mydata->sect_size, mydata->clust_size); diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index 852f874e5817..3bc0dd637521 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -388,29 +388,23 @@ static __u32 determine_fatent(fsdata *mydata, __u32 entry) } /** - * set_cluster() - write data to cluster + * set_sectors() - write data to sectors * - * Write 'size' bytes from 'buffer' into the specified cluster. + * Write 'size' bytes from 'buffer' into the specified sector. * * @mydata: data to be written - * @clustnum: cluster to be written to + * @startsect: sector to be written to * @buffer: data to be written * @size: bytes to be written (but not more than the size of a cluster) * Return: 0 on success, -1 otherwise */ static int -set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size) +set_sectors(fsdata *mydata, u32 startsect, u8 *buffer, u32 size) { - u32 idx = 0; - u32 startsect; + u32 nsects = 0; int ret; - if (clustnum > 0) - startsect = clust_to_sect(mydata, clustnum); - else - startsect = mydata->rootdir_sect; - - debug("clustnum: %d, startsect: %d\n", clustnum, startsect); + debug("startsect: %d\n", startsect); if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) { ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size); @@ -429,17 +423,16 @@ set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size) size -= mydata->sect_size; } } else if (size >= mydata->sect_size) { - idx = size / mydata->sect_size; - ret = disk_write(startsect, idx, buffer); - if (ret != idx) { + nsects = size / mydata->sect_size; + ret = disk_write(startsect, nsects, buffer); + if (ret != nsects) { debug("Error writing data (got %d)\n", ret); return -1; } - startsect += idx; - idx *= mydata->sect_size; - buffer += idx; - size -= idx; + startsect += nsects; + buffer += nsects * mydata->sect_size; + size -= nsects * mydata->sect_size; } if (size) { @@ -457,6 +450,44 @@ set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size) return 0; } +/** + * set_cluster() - write data to cluster + * + * Write 'size' bytes from 'buffer' into the specified cluster. + * + * @mydata: data to be written + * @clustnum: cluster to be written to + * @buffer: data to be written + * @size: bytes to be written (but not more than the size of a cluster) + * Return: 0 on success, -1 otherwise + */ +static int +set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size) +{ + return set_sectors(mydata, clust_to_sect(mydata, clustnum), + buffer, size); +} + +static int +flush_dir(fat_itr *itr) +{ + fsdata *mydata = itr->fsdata; + u32 startsect, sect_offset, nsects; + + if (!itr->is_root || mydata->fatsize == 32) + return set_cluster(mydata, itr->clust, itr->block, + mydata->clust_size * mydata->sect_size); + + sect_offset = itr->clust * mydata->clust_size; + startsect = mydata->rootdir_sect + sect_offset; + /* do not write past the end of rootdir */ + nsects = min_t(u32, mydata->clust_size, + mydata->rootdir_size - sect_offset); + + return set_sectors(mydata, startsect, itr->block, + nsects * mydata->sect_size); +} + static __u8 tmpbuf_cluster[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); /* @@ -1171,8 +1202,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer, } /* Write directory table to device */ - ret = set_cluster(mydata, itr->clust, itr->block, - mydata->clust_size * mydata->sect_size); + ret = flush_dir(itr); if (ret) { printf("Error: writing directory entry\n"); ret = -EIO; @@ -1249,8 +1279,7 @@ static int delete_dentry(fat_itr *itr) memset(dentptr, 0, sizeof(*dentptr)); dentptr->name[0] = 0xe5; - if (set_cluster(mydata, itr->clust, itr->block, - mydata->clust_size * mydata->sect_size) != 0) { + if (flush_dir(itr)) { printf("error: writing directory entry\n"); return -EIO; } @@ -1452,8 +1481,7 @@ int fat_mkdir(const char *new_dirname) } /* Write directory table to device */ - ret = set_cluster(mydata, itr->clust, itr->block, - mydata->clust_size * mydata->sect_size); + ret = flush_dir(itr); if (ret) printf("Error: writing directory entry\n");