In linux, how do you check if a disk is fragmented?

29

6

At boot, fsck sometimes reports the frgmentation for a disk: "5.3% non-contiguous".

How can I get this information myself? Is there a specific fsck invocation?

Peltier

Posted 2012-09-15T13:06:58.807

Reputation: 4 834

Answers

28

You can safely run fsck.ext2 on an ext2 ext3 or ext4 filesystem even if it's mounted like this

sudo fsck.ext2 -fn /dev/sdXY

If the drive is mounted, it will output a lot of errors, but the -n argument tells it not to touch the drive.

$ sudo fsck.ext2 -fn /dev/sda1
e2fsck 1.42 (29-Nov-2011)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Ubuntu_Rescue: 291595/1222992 files (0.2% non-contiguous), 1927790/4882432 blocks

Rucent88

Posted 2012-09-15T13:06:58.807

Reputation: 632

Thanks! fsck.ext2 found several errors on my home partition. Now I would like to repair it. This begs the question: how do I repair my home partition, which I need to keep mounted in order to login? – Michael – 2014-06-18T21:25:53.550

3@Michael If your drive is mounted, running a check on it will always report errors. Anyway, if you want check to the filesystem on next reboot, run this sudo tune2fs -C 16000 /dev/sda1 and reboot. – Rucent88 – 2014-06-27T09:36:54.967

1fsck checks what is on the disk/storage, but if mounted then there will be stuff in progress (half written). That is why you will see errors, they are not real errors, they are false errors. Ignore them. – ctrl-alt-delor – 2016-03-26T10:12:49.390

8

The modern ext family of filesystems take balancing and contiguity into consideration when allocating files. In ext3 and ext4 balancing is generally taken care of by applying journal entries in order, and in ext4 specifically, by pre-allocating file-system extents to increase contiguous blocks. Chasing fragmentation levels lower than 20% might not be worth your time, especially if your system is accessing a few files repeatedly. I suggest pursuing these tactics for increasing read speed for a single disk system:

  • increase ram: this increases filesystem cache

  • increase block size: by moving from 1k towards 4k block sizes, you get better performance on reads for files near or larger than your block size

  • if you are pedantic, you can organize large files and small files into partitions by their block size, you might only want to do this if you stored photos, videos and source code in separate directories

  • increase your read-ahead setting using hdparm and/or laptop-mode utility

  • backup and restore your filesystem in a linear fashion such as with tar

If you have multiple disks and are using raid striping and/or LVM, you other factors to consider, such as stripe size.

memnoch_proxy

Posted 2012-09-15T13:06:58.807

Reputation: 271

5

Yes, there is a specific fsck invocation (as root, or sudo):

$ fsck /dev/sdXY

Replace X and Y with the correct parameters for your case (e.g. /dev/sda1).

DO NOT RUN THIS ON A MOUNTED PARTITION! It can seriously damage your filesystem.

For some more information on Linux and defragmenting, see my answer here.


If you do not need to specifically run fsck, but just want to check your drive's fragmentation, the following script (taken from here) should do the trick:

#!/usr/bin/perl -w

#this script search for frag on a fs
use strict;

#number of files
my $files = 0;
#number of fragment
my $fragments = 0;
#number of fragmented files
my $fragfiles = 0;

#search fs for all file
open (FILES, '-|', "find '$ARGV[0]' -xdev -type f -print0");

$/ = "\0";

while (defined (my $file = <FILES>)) {
        open (FRAG, "-|", "filefrag", $file);
        my $res = <FRAG>;
        if ($res =~ m/.*:\s+(\d+) extents? found/) {
                my $fragment = $1;
                $fragments += $fragment;
                if ($fragment > 1) {
                        $fragfiles++;
                }
                $files++;
        } else {
                print ("$res : not understand for $file.\n");
        }
        close (FRAG);
}
close (FILES);

print ( $fragfiles / $files * 100 . "% non contiguous files, " . $fragments / $files . " average fragments.\n"); 

You can then run it on the directory (or mount point) in question:

$ frag_check.pl $HOME/
  1.32410691664555% non contiguous files, 1.05380668862427 average fragments.

terdon

Posted 2012-09-15T13:06:58.807

Reputation: 45 216

This answer is dangerous. @terdon, you should at least use -h, --help or read the man page before answering here. – trapicki – 2014-09-26T23:59:10.190

@trapicki it's only dangerous if you run it on a mounted filesystem and I make it quite clear that it's a bad idea to do so. Which part of the manpage was I supposed to read? Also, please don't leave comments like that. If you're going to accuse me of negligence, at least take the time to point my error out. As it stands, your comment just belittles my answer without offering any suggestions of how it could be improved. Next time, if you see an error, explain it. – terdon – 2014-09-27T03:04:17.060

@terdon, you are right. What I wanted to say: O downvoted your answer, here's the reason: Running fsck without -n should really only be done if you mean to check the filesystem and are willing and prepared to make changes on errors. Here in this case, only information is needed, so -nf would be sensible. Recommending a full check just to get information is IMO not advisable, even if you follow it up by a big fat warning, especially without hints how to do it in a safe way. There are ways to do that safe, and it's clearly stated in the help and manpage. – trapicki – 2014-09-29T09:28:28.660

1@KentFredric Ah! Yes, indeed. I see what you mean now. I edited accordingly, thanks. Let's delete the comments to remove clutter. – terdon – 2016-02-06T19:18:34.863

D'oh! Yup, completely missed that :) Thanks again. – terdon – 2016-02-06T19:28:22.903

I forgot about the stupid review queue. You don't need to quote things manually, you can use an array of arguments and that avoids the problem entirely by avoiding the shell call, as shown here: https://gist.github.com/kentfredric/12cf408ce32215b2e3f4

– Kent Fredric – 2016-02-06T19:31:34.900

Here's an accelerated alternative that doesn't use system() at all, and uses Path::Iterator::Rule for traversal and uses FS_IOC_FIEMAP ioctls to extract the number of extents instead of a system(filefrags) call, which should be much faster due to the lack of elf startup overhead. https://gist.github.com/kentfredric/ede160396eb96aea37dc

– Kent Fredric – 2016-02-07T09:38:45.700

That's just calling fsck on the partition, and as we both know, it will destroy a mounted partition. Is there any way to use fsck in a read-only, tell-me-how-fragmented-my-disk-is way? – Peltier – 2012-09-15T13:33:16.263

Not as far as I know, @Peltier. I was thinking you can boot into a lower runlevel, unmount the relevant disk and run fsck. In any case, seriously, you can almost certainly ignore fragmentation on most linux systems. – terdon – 2012-09-15T13:39:22.820

@Peltier, see my updated answer. – terdon – 2012-09-15T14:04:06.950

I appreciate the effort, but this is going to be extremely slow. I'll wait for a few days to see if anyone has a better solution to offer. – Peltier – 2012-09-15T14:08:11.903

1Yeah, it is slow. Mind you it took ~2-3mins on my 500GB /home/ partition. Again, I stress, drive fragmentation is not really a problem any more. Especially if you are using an EXT3-4 filesystem. – terdon – 2012-09-15T14:11:28.260

0

You can use a tool like e2defrag to get this information.

Do mind that because of the nature of Linux file systems, defragging is normally unnecessary.

Lucas Kauffman

Posted 2012-09-15T13:06:58.807

Reputation: 2 545

Non-privileged users can execute e4defrag to their own file, but the score is not printed if -c option is specified -- man e4defrag – Kent Fredric – 2016-02-08T12:40:35.510

Would you mind detailing your answer? I tried getting that information with e4defrag -c, but it didn't work. – Peltier – 2012-09-15T13:19:03.453

@Peltier Point it to an Ext3 or Ext4 moint point after the -c option as the last argument. And... "didn't work"? What is the error you get? – gertvdijk – 2012-09-15T13:20:39.523

It says "Done". I didn't, however, point it directly to the device, but to the mount point. I am trying again with the device. – Peltier – 2012-09-15T13:23:36.843

Note that it takes a lot of time, whereas fsck is very fast. – Peltier – 2012-09-15T13:23:55.760

Just tried it again with the device, it only says "Done.". – Peltier – 2012-09-15T13:24:13.757

Ok, I wasn't doing as root. – Peltier – 2012-09-15T13:32:20.697

Of course it does. Note that e4defrag does work without root, and it certainly didn't complain. – Peltier – 2012-09-15T13:38:49.467