
On Fri, Jul 20, 2018 at 07:14:21PM +0200, Heinrich Schuchardt wrote:
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.
Good point, but I'd like to put this issue into future TODO list as it will end up introducing a new API, such as gettimeofday()?
(and this is not a FAT-specific issue.)
Thanks, -Takahiro AKASHI
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_ */