
On 07/20/2018 04:57 AM, AKASHI Takahiro wrote:
In this patch, mkdir support is added to FAT file system. A newly created directory contains only "." and ".." entries.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org
The patch does set the creation date of the directory according to the real time clock but to 1980-01-01T00:00:00Z.
$ ls /mnt/dir1/ -la --full-time drwxr-xr-x 2 root root 2048 1980-01-01 01:00:00.000000000 +0100 dir3
Please, set the time correctly if the real time clock is available.
Best regards
Heinrich
fs/fat/fat_write.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ fs/fs.c | 3 +- include/fat.h | 1 + 3 files changed, 141 insertions(+), 1 deletion(-)
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index cc45a33876..781883c9f4 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -1185,3 +1185,141 @@ 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.bs_total_sect;
- if (total_sector == 0)
total_sector = (int)cur_part_info.size; /* cast of lbaint_t */
- 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 archieve 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 3cb6b21fe9..a92e060296 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 295da0f243..039b6e03de 100644 --- a/include/fat.h +++ b/include/fat.h @@ -237,5 +237,6 @@ 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 /* _FAT_H_ */