summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/exfat/io.c124
-rw-r--r--fs/exfat/lookup.c3
-rw-r--r--fs/fs.c1
-rw-r--r--include/exfat.h1
-rw-r--r--test/py/tests/test_fs/conftest.py2
-rw-r--r--test/py/tests/test_fs/test_basic.py13
6 files changed, 93 insertions, 51 deletions
diff --git a/fs/exfat/io.c b/fs/exfat/io.c
index 81e82829c72..c56f5675987 100644
--- a/fs/exfat/io.c
+++ b/fs/exfat/io.c
@@ -597,15 +597,13 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
}
#ifdef __UBOOT__
+#define PATH_MAX FS_DIRENT_NAME_LEN
+
struct exfat_dir_stream {
+ char dirname[PATH_MAX];
struct fs_dir_stream fs_dirs;
struct fs_dirent dirent;
-
- struct exfat_node* node;
- struct exfat_iterator it;
- /* State tracker flags for emulated . and .. dirents */
- bool dot;
- bool dotdot;
+ int offset;
};
int exfat_fs_probe(struct blk_desc *fs_dev_desc,
@@ -626,8 +624,6 @@ error:
return ret;
}
-#define PATH_MAX FS_DIRENT_NAME_LEN
-
/* Adapted from uclibc 1.0.35 */
static char *exfat_realpath(const char *path, char got_path[])
{
@@ -721,31 +717,31 @@ int exfat_lookup_realpath(struct exfat* ef, struct exfat_node** node,
int exfat_fs_opendir(const char *filename, struct fs_dir_stream **dirsp)
{
struct exfat_dir_stream *dirs;
+ struct exfat_node *dnode;
int err;
- dirs = calloc(1, sizeof(*dirs));
- if (!dirs)
- return -ENOMEM;
-
- err = exfat_lookup_realpath(&ctxt.ef, &dirs->node, filename);
+ err = exfat_lookup_realpath(&ctxt.ef, &dnode, filename);
if (err)
- goto err_out;
+ return err;
- if (!(dirs->node->attrib & EXFAT_ATTRIB_DIR)) {
+ if (!(dnode->attrib & EXFAT_ATTRIB_DIR))
err = -ENOTDIR;
- goto err_out;
- }
- err = exfat_opendir(&ctxt.ef, dirs->node, &dirs->it);
+ exfat_put_node(&ctxt.ef, dnode);
+
if (err)
- goto err_out;
+ return err;
+
+ dirs = calloc(1, sizeof(*dirs));
+ if (!dirs)
+ return -ENOMEM;
+
+ strcpy(dirs->dirname, filename);
+ dirs->offset = -1;
*dirsp = &dirs->fs_dirs;
return 0;
-err_out:
- free(dirs);
- return err;
}
int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
@@ -753,50 +749,77 @@ int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
struct exfat_dir_stream *dirs =
container_of(fs_dirs, struct exfat_dir_stream, fs_dirs);
struct fs_dirent *dent = &dirs->dirent;
- struct exfat_node* node;
+ struct exfat_node *dnode, *node;
+ struct exfat_iterator it;
+ int offset = 0;
+ int err;
+
+ err = exfat_lookup_realpath(&ctxt.ef, &dnode, dirs->dirname);
+ if (err)
+ return err;
+
+ if (!(dnode->attrib & EXFAT_ATTRIB_DIR)) {
+ err = -ENOTDIR;
+ goto err_out;
+ }
/* Emulate current directory ./ */
- if (!dirs->dot) {
- dirs->dot = true;
+ if (dirs->offset == -1) {
+ dirs->offset++;
snprintf(dent->name, FS_DIRENT_NAME_LEN, ".");
dent->type = FS_DT_DIR;
*dentp = dent;
- return 0;
+ goto err_out;
}
/* Emulate parent directory ../ */
- if (!dirs->dotdot) {
- dirs->dotdot = true;
+ if (dirs->offset == 0) {
+ dirs->offset++;
snprintf(dent->name, FS_DIRENT_NAME_LEN, "..");
dent->type = FS_DT_DIR;
*dentp = dent;
- return 0;
+ goto err_out;
}
+ err = exfat_opendir(&ctxt.ef, dnode, &it);
+ if (err)
+ goto err_out;
+
+ *dentp = NULL;
+
/* Read actual directory content */
- node = exfat_readdir(&dirs->it);
- if (!node) { /* No more content, reset . and .. emulation */
- dirs->dot = false;
- dirs->dotdot = false;
- return 1;
- }
+ while ((node = exfat_readdir(&it))) {
+ if (dirs->offset != ++offset) {
+ exfat_put_node(&ctxt.ef, node);
+ continue;
+ }
- exfat_get_name(node, dent->name);
- if (node->attrib & EXFAT_ATTRIB_DIR) {
- dent->type = FS_DT_DIR;
- } else {
- dent->type = FS_DT_REG;
- dent->size = node->size;
+ exfat_get_name(node, dent->name);
+ if (node->attrib & EXFAT_ATTRIB_DIR) {
+ dent->type = FS_DT_DIR;
+ } else {
+ dent->type = FS_DT_REG;
+ dent->size = node->size;
+ }
+ exfat_put_node(&ctxt.ef, node);
+ *dentp = dent;
+ dirs->offset++;
+ break;
}
- *dentp = dent;
+ exfat_closedir(&ctxt.ef, &it);
- return 0;
+err_out:
+ exfat_put_node(&ctxt.ef, dnode);
+ return err;
}
void exfat_fs_closedir(struct fs_dir_stream *fs_dirs)
{
- free(fs_dirs);
+ struct exfat_dir_stream *dirs =
+ container_of(fs_dirs, struct exfat_dir_stream, fs_dirs);
+
+ free(dirs);
}
int exfat_fs_ls(const char *dirname)
@@ -852,11 +875,11 @@ int exfat_fs_exists(const char *filename)
err = exfat_lookup_realpath(&ctxt.ef, &node, filename);
if (err)
- return err;
+ return 0;
exfat_put_node(&ctxt.ef, node);
- return 0;
+ return 1;
}
int exfat_fs_size(const char *filename, loff_t *size)
@@ -898,9 +921,7 @@ int exfat_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
*actread = sz;
- exfat_put_node(&ctxt.ef, node);
-
- return exfat_flush_node(&ctxt.ef, node);
+ err = exfat_flush_node(&ctxt.ef, node);
exit:
exfat_put_node(&ctxt.ef, node);
return err;
@@ -992,6 +1013,11 @@ exit:
return err;
}
+int exfat_fs_rename(const char *old_path, const char *new_path)
+{
+ return exfat_rename(&ctxt.ef, old_path, new_path);
+}
+
void exfat_fs_close(void)
{
exfat_unmount(&ctxt.ef);
diff --git a/fs/exfat/lookup.c b/fs/exfat/lookup.c
index 9867aab95f3..1d9aae9e036 100644
--- a/fs/exfat/lookup.c
+++ b/fs/exfat/lookup.c
@@ -218,8 +218,9 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent,
exfat_put_node(ef, *parent);
*parent = *node;
}
+#ifndef __UBOOT__
exfat_bug("impossible");
-#ifdef __UBOOT__
+#else
return 0;
#endif
}
diff --git a/fs/fs.c b/fs/fs.c
index 0b62217fd59..1f36872fb9a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -401,6 +401,7 @@ static struct fstype_info fstypes[] = {
.ln = fs_ln_unsupported,
.unlink = exfat_fs_unlink,
.mkdir = exfat_fs_mkdir,
+ .rename = exfat_fs_rename,
},
#endif
{
diff --git a/include/exfat.h b/include/exfat.h
index 7e43beeb348..75fce5b6566 100644
--- a/include/exfat.h
+++ b/include/exfat.h
@@ -20,5 +20,6 @@ int exfat_fs_unlink(const char *filename);
int exfat_fs_mkdir(const char *dirname);
int exfat_fs_write(const char *filename, void *buf, loff_t offset,
loff_t len, loff_t *actwrite);
+int exfat_fs_rename(const char *old_path, const char *new_path);
#endif /* _EXFAT_H */
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index c73fb4abbcb..0205048e73a 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -17,7 +17,7 @@ supported_fs_fat = ['fat12', 'fat16']
supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_symlink = ['ext4']
-supported_fs_rename = ['fat12', 'fat16', 'fat32']
+supported_fs_rename = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
#
# Filesystem test specific setup
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
index 64a3b50f52a..88b163ce305 100644
--- a/test/py/tests/test_fs/test_basic.py
+++ b/test/py/tests/test_fs/test_basic.py
@@ -35,6 +35,19 @@ class TestFsBasic(object):
'%sls host 0:0 invalid_d' % fs_cmd_prefix)
assert('' == output)
+ with ubman.log.section('Test Case 1c - test -e'):
+ # Test Case 1 - test -e
+ output = ubman.run_command_list([
+ 'host bind 0 %s' % fs_img,
+ 'test -e host 0:0 1MB.file && echo PASS'])
+ assert('PASS' in ''.join(output))
+
+ with ubman.log.section('Test Case 1d - test -e (invalid file)'):
+ # In addition, test with a nonexistent file to see if we crash.
+ output = ubman.run_command(
+ 'test -e host 0:0 2MB.file || echo PASS')
+ assert('PASS' in ''.join(output))
+
def test_fs2(self, ubman, fs_obj_basic):
"""
Test Case 2 - size command for a small file