Whamcloud - gitweb
create_inode: Find subdirectory in do_write_internal
authorEarl Chew <earl_chew@yahoo.com>
Sat, 20 Feb 2021 16:47:46 +0000 (08:47 -0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 22 Feb 2021 16:27:14 +0000 (11:27 -0500)
Follow the example in do_mkdir_internal, and do_symlink_internal,
and find the correct parent directory if the destination
is not just a plain basename.

https://github.com/tytso/e2fsprogs/issues/61

Signed-off-by: Earl Chew <earl_chew@yahoo.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/create_inode.c
tests/t_write_subdirectory/name [new file with mode: 0644]
tests/t_write_subdirectory/script [new file with mode: 0644]

index 67bf94c..c6a79c3 100644 (file)
@@ -626,9 +626,10 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
 {
        int             fd;
        struct stat     statbuf;
 {
        int             fd;
        struct stat     statbuf;
-       ext2_ino_t      newfile;
+       ext2_ino_t      newfile, parent_ino;
        errcode_t       retval;
        struct ext2_inode inode;
        errcode_t       retval;
        struct ext2_inode inode;
+       char            *cp;
 
        fd = ext2fs_open_file(src, O_RDONLY, 0);
        if (fd < 0) {
 
        fd = ext2fs_open_file(src, O_RDONLY, 0);
        if (fd < 0) {
@@ -642,25 +643,37 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
                goto out;
        }
 
                goto out;
        }
 
-       retval = ext2fs_namei(fs, root, cwd, dest, &newfile);
+       cp = strrchr(dest, '/');
+       if (cp) {
+               *cp = 0;
+               retval = ext2fs_namei(fs, root, cwd, dest, &parent_ino);
+               if (retval) {
+                       com_err(dest, retval, _("while looking up \"%s\""),
+                               dest);
+                       return retval;
+               }
+               dest = cp+1;
+       } else
+               parent_ino = cwd;
+
+       retval = ext2fs_namei(fs, root, parent_ino, dest, &newfile);
        if (retval == 0) {
                retval = EXT2_ET_FILE_EXISTS;
                goto out;
        }
 
        if (retval == 0) {
                retval = EXT2_ET_FILE_EXISTS;
                goto out;
        }
 
-       retval = ext2fs_new_inode(fs, cwd, 010755, 0, &newfile);
+       retval = ext2fs_new_inode(fs, parent_ino, 010755, 0, &newfile);
        if (retval)
                goto out;
 #ifdef DEBUGFS
        printf("Allocated inode: %u\n", newfile);
 #endif
        if (retval)
                goto out;
 #ifdef DEBUGFS
        printf("Allocated inode: %u\n", newfile);
 #endif
-       retval = ext2fs_link(fs, cwd, dest, newfile,
-                               EXT2_FT_REG_FILE);
+       retval = ext2fs_link(fs, parent_ino, dest, newfile, EXT2_FT_REG_FILE);
        if (retval == EXT2_ET_DIR_NO_SPACE) {
        if (retval == EXT2_ET_DIR_NO_SPACE) {
-               retval = ext2fs_expand_dir(fs, cwd);
+               retval = ext2fs_expand_dir(fs, parent_ino);
                if (retval)
                        goto out;
                if (retval)
                        goto out;
-               retval = ext2fs_link(fs, cwd, dest, newfile,
+               retval = ext2fs_link(fs, parent_ino, dest, newfile,
                                        EXT2_FT_REG_FILE);
        }
        if (retval)
                                        EXT2_FT_REG_FILE);
        }
        if (retval)
diff --git a/tests/t_write_subdirectory/name b/tests/t_write_subdirectory/name
new file mode 100644 (file)
index 0000000..740c409
--- /dev/null
@@ -0,0 +1 @@
+debugfs write creates file in subdirectory
diff --git a/tests/t_write_subdirectory/script b/tests/t_write_subdirectory/script
new file mode 100644 (file)
index 0000000..bb354f8
--- /dev/null
@@ -0,0 +1,29 @@
+FSCK_OPT=-nf
+
+$MKE2FS -q -F -o Linux -I 256 -b 4096 $TMPFILE 10000 > $test_name.log 2>&1
+status=$?
+if [ "$status" != 0 ] ; then
+       echo "mke2fs failed" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return $status
+fi
+
+touch $TMPFILE.1
+cat <<- EOF | $DEBUGFS -w $TMPFILE >> $test_name.log 2>&1
+       mkdir aaa
+       mkdir aaa/bbb
+       write $TMPFILE.1 aaa/bbb/ccc
+EOF
+rm -f $TMPFILE.1
+
+$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" = 0 ] ; then
+       echo "$test_name: $test_description: ok"
+       touch $test_name.ok
+else
+       echo "e2fsck with failed with $status" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return $status
+fi
+rm -f $TMPFILE