Bug 866

Summary: BUG at fs/jfs/namei.c:492 assert(!test_cflag(COMMIT_Nolink, ip))
Product: File System Reporter: Robbie Williamson (robbiew)
Component: JFSAssignee: Dave Kleikamp (shaggy)
Status: CLOSED CODE_FIX    
Severity: normal CC: sglass
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.5.73 Subsystem:
Regression: --- Bisected commit-id:
Attachments: File System race tester script
Patch to disallow link to a file with i_nlink == 0

Description Robbie Williamson 2003-07-02 12:09:32 UTC
Distribution: SuSE 8.0



Hardware Environment:
---------------------
 # cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 10
model name      : Pentium III (Cascades)
stepping        : 1
cpu MHz         : 702.267
cache size      : 1024 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov 
pat pse36 mmx fxsr sse
bogomips        : 1380.35

# cat /proc/meminfo
MemTotal:      4306492 kB
MemFree:          5564 kB
Buffers:        384620 kB
Cached:        3615820 kB
SwapCached:          0 kB
Active:         463532 kB
Inactive:      3543660 kB
HighTotal:     3440612 kB
HighFree:         1280 kB
LowTotal:       865880 kB
LowFree:          4284 kB
SwapTotal:     2097136 kB
SwapFree:      2097136 kB
Dirty:           56052 kB
Writeback:           0 kB
Mapped:          10548 kB
Slab:           215456 kB
Committed_AS:    22476 kB
PageTables:        364 kB
VmallocTotal:   114680 kB
VmallocUsed:      2184 kB
VmallocChunk:   112496 kB

 # mount
/dev/sda3 on / type ext2 (rw)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw)
/dev/sda1 on /boot type ext2 (rw)
/dev/sdb1 on /nfsserver/ext3 type ext3 (rw)
/dev/sdc1 on /nfsserver/jfs type jfs (rw)
/dev/sdd1 on /nfsserver/reiserfs type reiserfs (rw)
usbdevfs on /proc/bus/usb type usbdevfs (rw)




Software Environment:
 # sh ./ver_linux
If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.

Linux vega 2.5.73 #3 SMP Mon Jun 23 16:18:55 CDT 2003 i686 unknown

Gnu C                  2.95.3
Gnu make               3.79.1
util-linux             2.11n
mount                  2.11z
module-init-tools      2.4.12
e2fsprogs              1.26
jfsutils               1.0.15
xfsprogs               2.0.0
PPP                    2.4.1
isdn4k-utils           3.1pre4
Linux C Library        x    1 root     root      1394238 Mar 23  
2002 /lib/libc.so.6
Dynamic linker (ldd)   2.2.5
Procps                 2.0.7
Net-tools              1.60
Kbd                    1.06
Sh-utils               2.0

CONFIG_SOUND=y

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_SEQUENCER=y
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set

#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set

#
# ISA devices
#
# CONFIG_SND_AD1848 is not set
# CONFIG_SND_CS4231 is not set
# CONFIG_SND_CS4232 is not set
# CONFIG_SND_CS4236 is not set
# CONFIG_SND_ES1688 is not set
# CONFIG_SND_ES18XX is not set
# CONFIG_SND_GUSCLASSIC is not set
# CONFIG_SND_GUSEXTREME is not set
# CONFIG_SND_GUSMAX is not set
# CONFIG_SND_INTERWAVE is not set
# CONFIG_SND_INTERWAVE_STB is not set
# CONFIG_SND_OPTI92X_AD1848 is not set
# CONFIG_SND_OPTI92X_CS4231 is not set
# CONFIG_SND_OPTI93X is not set
# CONFIG_SND_SB8 is not set
# CONFIG_SND_SB16 is not set
# CONFIG_SND_SBAWE is not set
# CONFIG_SND_WAVEFRONT is not set
# CONFIG_SND_CMI8330 is not set
# CONFIG_SND_OPL3SA2 is not set
# CONFIG_SND_SGALAXY is not set
# CONFIG_SND_SSCAPE is not set

#
# PCI devices
#
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
CONFIG_SND_INTEL8X0=y
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VX222 is not set

#
# ALSA USB devices
#
# CONFIG_SND_USB_AUDIO is not set

#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_VXP440 is not set

#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set

#
# USB support
#
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
CONFIG_USB_BANDWIDTH=y
# CONFIG_USB_DYNAMIC_MINORS is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y

#
# USB Device Class drivers
#
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_HP8200e is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set

#
# USB Human Interface Devices (HID)
#
# CONFIG_USB_HID is not set

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_XPAD is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_HPUSBSCSI is not set

#
# USB Multimedia devices
#
# CONFIG_USB_DABUSB is not set

#
# Video4Linux support is needed for USB Multimedia device support
#

#
# USB Network adaptors
#
# CONFIG_USB_AX8817X is not set
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set

#
# USB port drivers
#
# CONFIG_USB_USS720 is not set

#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_GADGET is not set

#
# Bluetooth support
#
# CONFIG_BT is not set

#
# Profiling support
#
# CONFIG_PROFILING is not set

#
# Kernel hacking
#
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_SLAB=y
# CONFIG_DEBUG_IOVIRT is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_HIGHMEM=y
CONFIG_KALLSYMS=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
CONFIG_FRAME_POINTER=y

#
# Security options
#
# CONFIG_SECURITY is not set

#
# Cryptographic options
#
# CONFIG_CRYPTO is not set

#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_X86_BIOS_REBOOT=y


Problem Description: While attempting to run the test scenario described at 
http://ltp.sf.net/nfs, the following BUG was caught on the NFS server:
=========================================
BUG at fs/jfs/namei.c:492 assert(!test_cflag(COMMIT_Nolink, ip))
------------[ cut here ]------------
kernel BUG at fs/jfs/namei.c:492!
invalid operand: 0000 [#1]
CPU:    0
EIP:    0060:[<c0200999>]    Not tainted
EFLAGS: 00010202
EIP is at jfs_unlink+0x239/0x47c
eax: 00000044   ebx: df2e920c   ecx: c052d4e8   edx: c0488f04
esi: f32e9ed8   edi: 00000000   ebp: f32e9ee8   esp: f32e9e88
ds: 007b   es: 007b   ss: 0068
Process nfsd (pid: 1845, threadinfo=f32e8000 task=f330ecc0)
Stack: c0404900 c04048f1 000001ec c0404920 fffffff0 e7884690 e2387a64 df2e920c
       e238785c df2e927c e23878cc e238785c df2e926c 00000000 00000000 df2e9414
       0000000e 3f032494 014bf620 0000b16c e2387a64 df2e9414 00000003 d4a974f4
Call Trace:
 [<c015a8b8>] vfs_unlink+0x118/0x160
 [<c01b9d22>] nfsd_unlink+0x1e6/0x240
 [<c01b5f8d>] nfsd_proc_remove+0x81/0x94
 [<c01b4b6a>] nfsd_dispatch+0xde/0x199
 [<c03c92bd>] svc_process+0x3cd/0x65a
 [<c01b4918>] nfsd+0x1ac/0x320
 [<c01b476c>] nfsd+0x0/0x320
 [<c0108cf5>] kernel_thread_helper+0x5/0xc

Code: 0f 0b ec 01 f1 48 40 c0 83 c4 10 8b 45 dc 50 8b 55 e0 52 e8
==================================
Afterwards all NFS server activity ceased, but the server was still up and 
responsive to commands.

Steps to reproduce: Execute the test scenario described in the NFS 2.5 Test 
Plan for approximately 2 hours.
Comment 1 Dan Carpenter 2003-07-02 22:44:21 UTC
I'm a complete newbie at this so I could be wrong.

It seems like in jfs_rename() ...
  1271          if (new_ip && (new_ip->i_nlink == 0))
  1272                  set_cflag(COMMIT_Nolink, new_ip);
... should be under lock but new_ip is unlocked.

  1256          if (new_ip)
  1257                  up(&JFS_IP(new_ip)->commit_sem);
  1258  
  1259          while (new_size && (rc == 0)) {
  1260                  tid = txBegin(new_ip->i_sb, 0);
  1261                  down(&JFS_IP(new_ip)->commit_sem);
  1262                  new_size = xtTruncate_pmap(tid, new_ip, new_size);
  1263                  if (new_size < 0) {
  1264                          txAbort(tid, 1);
  1265                          rc = -new_size;         /* We return -rc */
  1266                  } else
  1267                          rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
  1268                  txEnd(tid);
  1269                  up(&JFS_IP(new_ip)->commit_sem);
  1270          }
  1271          if (new_ip && (new_ip->i_nlink == 0))
  1272                  set_cflag(COMMIT_Nolink, new_ip);

Comment 2 Dave Kleikamp 2003-07-03 11:52:35 UTC
i_sem is held during rename and unlink, so I don't think there is a problem with
the inode being unlocked in this code.  That said, there must be a race in the
code somewhere for you to get this error.
Comment 3 Dan Carpenter 2003-07-05 21:49:13 UTC
Created attachment 480 [details]
File System race tester script
Comment 4 Dan Carpenter 2003-07-05 21:52:42 UTC
(still learning how bugzilla works)

I added an attachment which is a small script that can be used to trigger the
bug within a minute or two.

zcat racer.tar.gz
cd racer
./racer.sh

It uses files in racer/race/ to try create race situations.

Comment 5 Dave Kleikamp 2003-10-30 07:36:37 UTC
Created attachment 1287 [details]
Patch to disallow link to a file with i_nlink == 0

Sorry for sitting on this one so long.

There is a race where unlink can decrement i_nlink to zero, and then link() can

increment it back to 1.  The unlink code only expects the link count to go to
zero once.  The fix is to have link() fail if i_nlink was previously zero.