From patchwork Tue Sep 11 06:59:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 146418 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp3321757ljw; Tue, 11 Sep 2018 00:12:46 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbOmoBhopPp2TE/DIkA1T+96rmUzh5yPDwUd7cCsYXf4I5aS4acGToDPjX3QfJ+L6TXQf3p X-Received: by 2002:a50:ae03:: with SMTP id c3-v6mr27118340edd.114.1536649966349; Tue, 11 Sep 2018 00:12:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536649966; cv=none; d=google.com; s=arc-20160816; b=xjPcOx6WMZYNId5cCA1Bm5p8xFpf5h08q+Lxmn3qkq96uCjcOtm2LqMCBeLusAUhe/ srfa5Mu7a3MhHmE73XOSjtd0uF2uBEjdzfUsUjXhsjpbLgmw0oA/Sar/JFEsY9z43QxI oiplMB5gIr5jPbO4qYQGlW5mUen96fg+Fgsmjn3y1YbQRFaH3kvdMtIPCFffA8RKentp AAz7t2lEqqD97UVl4KkmQuUt2D7bK4KuNzsf31LJYD3l2Xsu+GBGUCigkpixck3EB5TZ Sl1Pjq1+qCL+qhmjNw+BeW5zOyXR7QzVpUqGuu6EyVC8AeFp3Aqyn/C6MfaH1NwVwm8E 4C1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature; bh=LacOXEnvvUjh2NI/UhmWCXdGxOsgDU8FjqMkSAlnsQM=; b=gePTYV1UAnT6cwVBMg9qEqjNBMlO/79iQbVqxE/VKON24vp3Iw/fdDRwkZ6NYjzHdB 2U+U4S+Ood9fdyyChiC/jNMlCzsb8mpte1yc/6ePUgEIh85amIQl37Vebiw7RGYy58Qa lLaIpsa4fCRCMPso6Mrpd5SOO36BXBPYnigI7tyiAmotoYxmW3wjutIgnGnAXzbWwovF Rg50fSAJhcGWpLaOzgIrygM08SE59AfJ9q6M+ev/ovnz6Asq4r+IlCST3Ma+3LqJGlDm G6TVxz9VodT/AixkbLz70EWE7Z4iBy1v0Iboagv4InqwdpRG5wBL0qaonznZbaoFQXaQ 1uKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=f5cgcMvv; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id n4-v6si990195eda.62.2018.09.11.00.12.46; Tue, 11 Sep 2018 00:12:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=f5cgcMvv; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by lists.denx.de (Postfix, from userid 105) id C7039C21EF7; Tue, 11 Sep 2018 07:07:18 +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 D383AC21F27; Tue, 11 Sep 2018 07:01:09 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 3EA3EC21E38; Tue, 11 Sep 2018 07:00:01 +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 D3F30C21ECA for ; Tue, 11 Sep 2018 06:59:56 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id j26-v6so11734571pfi.10 for ; Mon, 10 Sep 2018 23:59:56 -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; bh=YhoD+noqvIgNmZenXk13qZKT62iVkeAGtESN5aQgv+Y=; b=f5cgcMvv+Fyl6Yhsh6vMZqRUm1wn8ze0AB/xNXK9WnXa7zlddu6irDAhB0Kd1LtfoB /7OHZCSBsyARDCYAw0bisUjIqJ9hM28sK8h9q4Msmo5X1XETWy7O5qD02M6gUMuaJWPH AfRoNs9FmOcORdSzqxEqewMrp5+EN15vt4g8E= 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; bh=YhoD+noqvIgNmZenXk13qZKT62iVkeAGtESN5aQgv+Y=; b=mU1NJ2x7DjWVE5/n7TZp6Tff999XjkSlAXXUkU4QpklMnTerdx1RvIGrfX4SkthzP0 9rP+enJaYSOzSudT/Yh0g2qC8YM3fGPK3ck2YXdrs69mudwISrgAll8hHqUNs5PJKOZR PNB/X2DeOC3534lQfIC+9ivsOjhG2Pv7dRqRDi4BV+pBuWBMiAGNGbDOld/nJfk1stcz imNuH2yOYMP7NXbAYAdAnI/jtT2Ku6NOrKe62lx9JAQbHms4bzzYVPeXmGLlaw73JsK3 3Pu9A19nhtl6FuW8yxMTwdC/8oYuspZH8iEWUvsb86W+560ydvy0CiB/jtLDBXga48FT a5Ow== X-Gm-Message-State: APzg51CY5Uaoex6OLJWO66tzB0tVHmEDub1u5qn1UnKGFDnrGhLVQlbv FbdffISvojpX2RnDbXLZsTVD1Q== X-Received: by 2002:aa7:800f:: with SMTP id j15-v6mr27840020pfi.174.1536649195471; Mon, 10 Sep 2018 23:59:55 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id 143-v6sm27074993pfy.156.2018.09.10.23.59.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Sep 2018 23:59:54 -0700 (PDT) From: "Akashi, Takahiro" To: trini@konsulko.com Date: Tue, 11 Sep 2018 15:59:10 +0900 Message-Id: <20180911065922.19141-15-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180911065922.19141-1-takahiro.akashi@linaro.org> References: <20180911065922.19141-1-takahiro.akashi@linaro.org> Cc: u-boot@lists.denx.de, xypron.glpk@gmx.de, agraf@suse.de Subject: [U-Boot] [PATCH v3 14/26] fs: fat: support mkdir 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: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: AKASHI Takahiro In this patch, mkdir support is added to FAT file system. A newly created directory contains only "." and ".." entries. Signed-off-by: AKASHI Takahiro --- fs/fat/fat_write.c | 136 +++++++++++++++++++++++++++++++++++++++++++++ fs/fs.c | 3 +- include/fat.h | 1 + 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index 651c7866debc..035469f31c8d 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -1183,3 +1183,139 @@ int file_fat_write(const char *filename, void *buffer, loff_t offset, { return file_fat_write_at(filename, offset, buffer, maxsize, actwrite); } + +int fat_mkdir(const char *new_dirname) +{ + dir_entry *retdent; + fsdata datablock = { .fatbuf = NULL, }; + fsdata *mydata = &datablock; + fat_itr *itr = NULL; + char *dirname_copy, *parent, *dirname; + char l_dirname[VFAT_MAXLEN_BYTES]; + int ret = -1; + loff_t actwrite; + unsigned int bytesperclust; + dir_entry *dotdent = NULL; + + dirname_copy = strdup(new_dirname); + if (!dirname_copy) + goto exit; + + split_filename(dirname_copy, &parent, &dirname); + if (!strlen(dirname)) { + ret = -EINVAL; + goto exit; + } + + if (normalize_longname(l_dirname, dirname)) { + printf("FAT: illegal filename (%s)\n", dirname); + ret = -EINVAL; + goto exit; + } + + itr = malloc_cache_aligned(sizeof(fat_itr)); + if (!itr) { + ret = -ENOMEM; + goto exit; + } + + ret = fat_itr_root(itr, &datablock); + if (ret) + goto exit; + + total_sector = datablock.total_sect; + + ret = fat_itr_resolve(itr, parent, TYPE_DIR); + if (ret) { + printf("%s: doesn't exist (%d)\n", parent, ret); + goto exit; + } + + retdent = find_directory_entry(itr, l_dirname); + + if (retdent) { + printf("%s: already exists\n", l_dirname); + ret = -EEXIST; + goto exit; + } else { + if (itr->is_root) { + /* root dir cannot have "." or ".." */ + if (!strcmp(l_dirname, ".") || + !strcmp(l_dirname, "..")) { + ret = -EINVAL; + goto exit; + } + } + + if (!itr->dent) { + printf("Error: allocating new dir entry\n"); + ret = -EIO; + goto exit; + } + + memset(itr->dent, 0, sizeof(*itr->dent)); + + /* Set short name to set alias checksum field in dir_slot */ + set_name(itr->dent, dirname); + fill_dir_slot(itr, dirname); + + /* Set attribute as archive for regular file */ + fill_dentry(itr->fsdata, itr->dent, dirname, 0, 0, + ATTR_DIR | ATTR_ARCH); + + retdent = itr->dent; + } + + /* Default entries */ + bytesperclust = mydata->clust_size * mydata->sect_size; + dotdent = malloc_cache_aligned(bytesperclust); + if (!dotdent) { + ret = -ENOMEM; + goto exit; + } + memset(dotdent, 0, bytesperclust); + + memcpy(dotdent[0].name, ". ", 8); + memcpy(dotdent[0].ext, " ", 3); + dotdent[0].attr = ATTR_DIR | ATTR_ARCH; + + memcpy(dotdent[1].name, ".. ", 8); + memcpy(dotdent[1].ext, " ", 3); + dotdent[1].attr = ATTR_DIR | ATTR_ARCH; + set_start_cluster(mydata, &dotdent[1], itr->start_clust); + + ret = set_contents(mydata, retdent, 0, (__u8 *)dotdent, + bytesperclust, &actwrite); + if (ret < 0) { + printf("Error: writing contents\n"); + goto exit; + } + /* Write twice for "." */ + set_start_cluster(mydata, &dotdent[0], START(retdent)); + ret = set_contents(mydata, retdent, 0, (__u8 *)dotdent, + bytesperclust, &actwrite); + if (ret < 0) { + printf("Error: writing contents\n"); + goto exit; + } + + /* Flush fat buffer */ + ret = flush_dirty_fat_buffer(mydata); + if (ret) { + printf("Error: flush fat buffer\n"); + goto exit; + } + + /* Write directory table to device */ + ret = set_cluster(mydata, itr->clust, itr->block, + mydata->clust_size * mydata->sect_size); + if (ret) + printf("Error: writing directory entry\n"); + +exit: + free(dirname_copy); + free(mydata->fatbuf); + free(itr); + free(dotdent); + return ret; +} diff --git a/fs/fs.c b/fs/fs.c index 62165d5c5701..099540f38a10 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -164,14 +164,15 @@ static struct fstype_info fstypes[] = { .read = fat_read_file, #ifdef CONFIG_FAT_WRITE .write = file_fat_write, + .mkdir = fat_mkdir, #else .write = fs_write_unsupported, + .mkdir = fs_mkdir_unsupported, #endif .uuid = fs_uuid_unsupported, .opendir = fat_opendir, .readdir = fat_readdir, .closedir = fat_closedir, - .mkdir = fs_mkdir_unsupported, }, #endif #ifdef CONFIG_FS_EXT4 diff --git a/include/fat.h b/include/fat.h index 127e6622a9b0..97460a3cdff1 100644 --- a/include/fat.h +++ b/include/fat.h @@ -205,6 +205,7 @@ int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, int fat_opendir(const char *filename, struct fs_dir_stream **dirsp); int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); void fat_closedir(struct fs_dir_stream *dirs); +int fat_mkdir(const char *dirname); void fat_close(void); #endif /* CONFIG_FS_FAT */ #endif /* _FAT_H_ */