Take the 2-minute tour ×
Server Fault is a question and answer site for professional 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
add comment

2 Answers

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
add comment

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

You can change the first move command to an 'rm -rf' on the source directory, which is simpler, but the move is faster. Speed from start to finish here was important for us, since we needed to take downtime to do this operation during our maintenance window.

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 to sync an empty directory into this directory, effectively deleting everything.

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

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.