kern/156545: mv could break UFS on SMP systems

Konstantin konstantin.malov at kaspersky.com
Thu Apr 21 10:20:09 UTC 2011


>Number:         156545
>Category:       kern
>Synopsis:       mv could break UFS on SMP systems
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 21 10:20:08 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Konstantin
>Release:        8.X/7.X
>Organization:
Kasperksy Lab
>Environment:
# uname -a
FreeBSD test-host 8.2-RELEASE FreeBSD 8.2-RELEASE #1: Thu Apr  7 14:23:20 UTC 2011     root at host:/usr/obj/amd64/usr/src/sys/GENERIC  amd64

>Description:
We have found out a strange mv(1) behaviour on SMP systems with UFS. If two or more processes are trying to move the same dir from one source, it could break UFS.
It works on 7.X/8.X amd64 systems. Actually, i think, it works on all systems with SMP on all platforms.
I guess that the problem is somewhere in ./sys/ufs/ufs/ufs_vnops.c because i can't repeat it for an example on ZFS partition.

After UFS break you will see this: 

# mount
/dev/da0p2 on / (ufs, local, noatime)
devfs on /dev (devfs, local, multilabel)
/dev/da0p4 on /data (ufs, local, noatime, soft-updates)

# cd /data/test

# ls -lai
total 40
11540480 drwxr-xr-x  5 root  wheel    512 Apr 21 17:30 .
       2 drwxr-xr-x  8 root  wheel    512 Apr 21 17:29 ..
11543482 drwxr-xr-x  3 root  wheel  16384 Apr 21 17:37 dst1
11543483 drwxr-xr-x  3 root  wheel    512 Apr 21 17:37 dst2
11540481 drwxr-xr-x  2 root  wheel  16384 Apr 21 17:37 src
       4 -rw-r--r--  1 root  wheel    738 Apr 21 17:33 test.pl

# ls -lai dst1
total 20
11543482 drwxr-xr-x  3 root  wheel  16384 Apr 21 17:37 .
11540480 drwxr-xr-x  5 root  wheel    512 Apr 21 17:30 ..
11541475 drwx------  3 root  wheel    512 Apr 21 17:36 03qOT

# ls -lai dst2
total 6
11543483 drwxr-xr-x  3 root  wheel  512 Apr 21 17:37 .
11540480 drwxr-xr-x  5 root  wheel  512 Apr 21 17:30 ..
11541475 drwx------  3 root  wheel  512 Apr 21 17:36 03qOT

# rm -rf dst1/03qOT
rm: dst1/03qOT: Invalid argument

# rm -rf dst2/03qOT
rm: dst2/03qOT: Invalid argument

The only way to fix it is to unmount the partition and run the fsck on it. 

# fsck -vy /data
start /data wait fsck_ufs -y /dev/da0p4
** /dev/da0p4
** Last Mounted on /data
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
/test/dst1/03qOT IS AN EXTRANEOUS HARD LINK TO DIRECTORY /test/dst1/03qOT

REMOVE? yes

BAD INODE NUMBER FOR '..'  I=11541475  OWNER=root MODE=40700
SIZE=512 MTIME=Apr 21 17:36 2011
DIR=/test/dst2/03qOT

UNEXPECTED SOFT UPDATE INCONSISTENCY

FIX? yes

** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
LINK COUNT DIR I=11541475  OWNER=root MODE=40700
SIZE=512 MTIME=Apr 21 17:36 2011  COUNT 3 SHOULD BE 2
ADJUST? yes

LINK COUNT DIR I=11543482  OWNER=root MODE=40755
SIZE=16384 MTIME=Apr 21 17:37 2011  COUNT 3 SHOULD BE 2
ADJUST? yes

** Phase 5 - Check Cyl groups
7757 files, 87291 used, 134202352 free (256 frags, 16775262 blocks, 0.0% fragmentation)

***** FILE SYSTEM IS CLEAN *****

***** FILE SYSTEM WAS MODIFIED *****
>How-To-Repeat:
You can use this script to repeat the problem:

#!/usr/local/bin/perl
use strict;

my $iterations = 50;
my $dirs = 1000;

mkdir 'src';

for(1..$iterations)
{
  print "Iterations $_\n";
  do_test();
}

sub do_test
{
  print "Creating $dirs sample directories...\n";

  for(1..$dirs)
  {
    my $dirname = `mktemp -d src/XXXXX`;
    chomp $dirname;
    system("touch $dirname/data && touch $dirname/meta");
    print "$_ ";
    }

    print "done\n";

    my ($pid1, $pid2) = (do_job('src', 'dst1'), do_job('src', 'dst2'));
    waitpid($pid1, 0);
    waitpid($pid2, 0);
}

sub do_job
{
  my ($src, $dst) = @_;
  
  my $pid = fork();
  return $pid if $pid != 0;
  
  system("mkdir -p $dst && ls $src | xargs -I _ mv -n $src/_ $dst");
  system("rm -rf $dst/*") == 0 or die;
  
  exit(0);
}
>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list