From: Earl Chew Date: Sat, 20 Feb 2021 16:47:46 +0000 (-0800) Subject: create_inode: Find subdirectory in do_write_internal X-Git-Tag: v1.46.2~27 X-Git-Url: https://git.whamcloud.com/?p=tools%2Fe2fsprogs.git;a=commitdiff_plain;h=bc50f5abd7697e6c1c396983c1a083d560b29bff create_inode: Find subdirectory in do_write_internal 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 Signed-off-by: Theodore Ts'o --- diff --git a/misc/create_inode.c b/misc/create_inode.c index 67bf94c..c6a79c3 100644 --- a/misc/create_inode.c +++ b/misc/create_inode.c @@ -626,9 +626,10 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src, { int fd; struct stat statbuf; - ext2_ino_t newfile; + ext2_ino_t newfile, parent_ino; errcode_t retval; struct ext2_inode inode; + char *cp; 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; } - 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; } - 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 - 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) { - retval = ext2fs_expand_dir(fs, cwd); + retval = ext2fs_expand_dir(fs, parent_ino); 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) diff --git a/tests/t_write_subdirectory/name b/tests/t_write_subdirectory/name new file mode 100644 index 0000000..740c409 --- /dev/null +++ b/tests/t_write_subdirectory/name @@ -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 index 0000000..bb354f8 --- /dev/null +++ b/tests/t_write_subdirectory/script @@ -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