yaffs direct: Fix renaming file over directory or directory over file
authorCharles Manning <cdhmanning@gmail.com>
Thu, 6 Dec 2012 00:47:55 +0000 (13:47 +1300)
committerCharles Manning <cdhmanning@gmail.com>
Thu, 6 Dec 2012 00:47:55 +0000 (13:47 +1300)
It was possible to rename a directory over a file or a file over a
directory. This is no longer allowed.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
direct/test-framework/basic-tests/dtest.c
direct/yaffsfs.c

index 3cd13ab..006aad7 100644 (file)
@@ -3172,6 +3172,37 @@ void format_test(const char *mountpt)
        printf("mount should return -1 returned %d\n", ret);
 }
 
+void dir_rename_test(const char *mountpt)
+{
+         char fname[100];
+         char dname[100];
+         int h;
+         int ret;
+
+         yaffs_start_up();
+         yaffs_mount(mountpt);
+
+         sprintf(fname,"%s/file",mountpt);
+         sprintf(dname,"%s/directory",mountpt);
+
+         h = yaffs_open(fname,O_CREAT | O_RDWR | O_TRUNC, 0666);
+         yaffs_close(h);
+
+         yaffs_mkdir(dname, 0666);
+
+         dump_directory_tree(mountpt);
+
+         printf("Try to rename %s to %s\n", fname, dname);
+         ret = yaffs_rename(fname, dname);
+         printf("result %d, %d\n", ret, yaffs_get_error());
+
+         printf("Try to rename %s to %s\n", dname, fname);
+         ret = yaffs_rename(dname, fname);
+         printf("result %d, %d\n", ret, yaffs_get_error());
+
+
+}
+
 int random_seed;
 int simulate_power_failure;
 
@@ -3252,8 +3283,8 @@ int main(int argc, char *argv[])
         //basic_utime_test("/yaffs2");
         //case_insensitive_test("/yaffs2");
 
-        yy_test("/yaffs2");
-
+        //yy_test("/yaffs2");
+        dir_rename_test("/yaffs2");
 
         return 0;
 
index a269984..27bc572 100644 (file)
@@ -1482,6 +1482,24 @@ int yaffs_unlink(const YCHAR *path)
        return yaffsfs_DoUnlink(path, 0);
 }
 
+static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj)
+{
+       if (obj && obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY &&
+           newobj && newobj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
+               return 1;
+       else
+               return 0;
+}
+
+static int rename_dir_over_file(struct yaffs_obj *obj, struct yaffs_obj *newobj)
+{
+       if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
+           newobj && newobj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
+               return 1;
+       else
+               return 0;
+}
+
 int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
 {
        struct yaffs_obj *olddir = NULL;
@@ -1551,6 +1569,12 @@ int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
        } else if (obj->my_dev->read_only) {
                yaffsfs_SetError(-EROFS);
                rename_allowed = 0;
+       } else if (rename_file_over_dir(obj, newobj)) {
+               yaffsfs_SetError(-EISDIR);
+               rename_allowed = 0;
+       } else if (rename_dir_over_file(obj, newobj)) {
+               yaffsfs_SetError(-ENOTDIR);
+               rename_allowed = 0;
        } else if (yaffs_is_non_empty_dir(newobj)) {
                yaffsfs_SetError(-ENOTEMPTY);
                rename_allowed = 0;