Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Is there a way to shrink a directory entry?

My dovecot maildir directories have increased in size from the default 4096 to several megs, and it is messing with disk quotas.

The only way that I have found, is to delete and recreate the directory. I am hoping there is a magical function somewhere - I am open to anything, except for hand-coded assembler.

Edit: For posterity, to find dirents>4096:

 find / -type d -size +4k -printf "%s\t%p\t%i\n" | sort -nr
share|improve this question

2 Answers 2

up vote 6 down vote accepted

See also rm on a directory with millions of files; tangentially related, but we discuss it there.

As far as I'm aware, at least on ext2/3, no, there's no (online) way to shrink them short of delete + recreate. Unmounted, several sources suggest e2fsck -D might work, though I can claim no personal experience with that option.

Some references for further reading:

share|improve this answer
1  
The first link was especially helpful: it addressed my problem specifically (mail servers), and the fact that Ted Tso weighed in on the dialogue is pretty cool ;) –  mikewaters Apr 28 '11 at 13:13

I recently had to delete and recreate an NFS directory to shrink its size after it had previously bloated. In the process, I found a fairly efficient way to do this using rsync and hard links. This method avoids copying the actual files, while still accomplishing the goal of recreating the directory with the same contents.

Since we needed to take downtime to do this operation during our maintenance window, making the rebuilt directory available as soon as possible was important for us. If simplicity is more important to you, change the first move command to an 'rm -rf' on the source directory, and skip the other 'rm -rf' command.

I extracted these commands from a larger process, and abstracted the directory names, so apologies if I've made a mistake in that translation.

mkdir /tmp/holding_dir/
rsync -ai --delete --link-dest=/path/to/source_dir/ /path/to/source_dir/ /tmp/holding_dir/
mv /path/to/source_dir/ /tmp/deleteme/
mv /tmp/holding_dir/ /path/to/source_dir/

Then later, we remove the directory. Depending on size, you may need to use a more sophisticated technique to do this. For example, using rsync with the --delete flag to sync an empty directory into this directory may be more efficient.

rm -rf /tmp/deleteme/
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.