aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEarl Chew <earl_chew@yahoo.com>2021-02-20 08:47:46 -0800
committerTheodore Ts'o <tytso@mit.edu>2021-02-22 11:27:14 -0500
commitbc50f5abd7697e6c1c396983c1a083d560b29bff (patch)
tree1f91ce89738ca5a10b5c459de257b908ec02c577
parentea82add307c4bc820423abc8acc2f155720cf914 (diff)
downloade2fsprogs-bc50f5abd7697e6c1c396983c1a083d560b29bff.tar.gz
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 <earl_chew@yahoo.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--misc/create_inode.c27
-rw-r--r--tests/t_write_subdirectory/name1
-rw-r--r--tests/t_write_subdirectory/script29
3 files changed, 50 insertions, 7 deletions
diff --git a/misc/create_inode.c b/misc/create_inode.c
index 67bf94cfd..c6a79c35f 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 000000000..740c40949
--- /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 000000000..bb354f8b4
--- /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