Moving every file in the subdirectory into the parent is one way, but if there are a huge number of entries in /mnt/data/mydata/mydata/
, and that's the only entry in /mnt/data/mydata
, you might consider this sequence of 3 metadata operations that doesn't change the contents of the big directory, just moves it to a different place in the filesystem. And removes 1 entry from a small directory then unlinks it.
Thus it won't affect the ctime of any of the files in the subdirectory or even have to list the contents of that big directory.
mv /mnt/data/mydata /mnt/data/mydata.old # rename parent
mv /mnt/data/mydata.old/mydata /mnt/data/mydata # subdir -> sibling of parent
rmdir /mnt/data/mydata.old # fails if not empty
The directory inode that was originally /mnt/data/mydata/mydata
is now /mnt/data/mydata
, and its contents haven't changed. If it contained millions of files, that's faster and takes less i/o. But more typing because mv
won't invent a temporary name for you.
If the original /mnt/data/mydata
wasn't empty, you can still do this but instead of rmdir
, mv /mnt/data/mydata.old/* /mnt/data/mydata/
. If it had a couple entries vs. a couple million for the child directory, that's saving some I/O.
You do need write access to /mnt/data
, which the other way doesn't need. But this doesn't need write access to /mnt/data/mydata/mydata
.
Script this however you like, and/or cd
and use relative paths. Pick any temporary name you want, like foo
or tmp
, or xyz123
. (If other users can write /mnt/data
, and you're scripting it, check on what mv
will do if they create a file with the same random name you pick; or use mktemp -p /mnt/data/
to get a temp dir there to move the child mydata
into while you unlink /mnt/data/mydata
.)
It has the downside that there is a moment between operations when no /mnt/data/mydata
exists at all. Unless there's a shell wrapper for the renameat2
system call with RENAME_EXCHANGE
to atomically exchange two paths. (Linux kernel 3.15, glibc 2.28, so it's been around for a while, but rename(1)
and mv(1)
don't have options to use it.)
If you're running a server, this might matter to you, otherwise you likely don't care.
Interactively, you might also use imv /mnt/data/mydata
to interactively edit the path with readline line-editing (the same as bash uses for command-line editing.)