From owner-freebsd-fs@FreeBSD.ORG Mon Apr 18 09:44:05 2011 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1FA13106566B for ; Mon, 18 Apr 2011 09:44:05 +0000 (UTC) (envelope-from aavzz@yandex.ru) Received: from forward5.mail.yandex.net (forward5.mail.yandex.net [77.88.46.21]) by mx1.freebsd.org (Postfix) with ESMTP id 8F5D28FC12 for ; Mon, 18 Apr 2011 09:44:04 +0000 (UTC) Received: from smtp3.mail.yandex.net (smtp3.mail.yandex.net [77.88.46.103]) by forward5.mail.yandex.net (Yandex) with ESMTP id EE2E412011A0 for ; Mon, 18 Apr 2011 13:28:46 +0400 (MSD) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1303118926; bh=l3/xyW9PAkr+VyY1DE4Zd6pTb6KjkcXT1JFhrsUdsGQ=; h=Subject:From:To:Content-Type:Date:Message-ID:Mime-Version: Content-Transfer-Encoding; b=A1JR+DIKfnlQ39rMTWffwe1rMLzkW/cJVUQvPOgXhH1TJH8PDfYIXDgZRW6JeARQC X7uQ1UFN+f/IYVGhL6iOsqxoHcmwe6z/6JP0hMPt9mzHIUQlKTvV4hkidxSAlgdWjn 5JbEPmD6sS/3qTJTBMLV2PuXUKXTy46uZO9cGJeg= Received: from [10.88.1.200] (unknown [91.210.24.47]) by smtp3.mail.yandex.net (Yandex) with ESMTPA id B544069800B1 for ; Mon, 18 Apr 2011 13:28:46 +0400 (MSD) From: Alex Zimnitsky To: freebsd-fs@freebsd.org Content-Type: text/plain; charset="UTF-8" Date: Mon, 18 Apr 2011 13:29:08 +0400 Message-ID: <1303118948.2112.40.camel@localhost> Mime-Version: 1.0 X-Mailer: Evolution 2.32.2 (2.32.2-1.fc14) Content-Transfer-Encoding: 7bit X-Yandex-Spam: 1 Subject: unionfs kernel panic while mounting (i386, R8.2) X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Apr 2011 09:44:05 -0000 Hi everyone! There is a problem with unionfs mount procedure which consistently causes system crash. I observed this behavior (freshly installed release 8.2) on two i386 boxes one of which was an ancient laptop with 256MB RAM and the other was a not-so-old desktop with more than 4GB jf RAM. ******* How to reproduce: ************** mkdir /var/ftp mkdir /var/ftpdata1 mkdir /var/ftpdata2 ... mkdir /var/ftpdata15 mount -t unionfs /var/ftpdata1 /var/ftp mount -t unionfs /var/ftpdata2 /var/ftp ... mount -t unionfs /var/ftpdata15 /var/ftp mounting /var/ftpdata12 reliably caused kernel panic on the laptop in my case (desktop reliably crashed while mounting ftpdata10-12) ************ Possible cause **************** A little investigation revealed that this crash happens in unionfs_statfs which lives in /usr/src/sys/fs/unionfs/union_vfsops.c Debug printing showed that it calls itself recursively n+1 times depending on the quantity of previously mounted dirs: mount -t unionfs /var/ftpdata1 /var/ftp - 2 times mount -t unionfs /var/ftpdata2 /var/ftp - 3 times ... mount -t unionfs /var/ftpdata10 /var/ftp - 11 times ... It appears that the crash is caused by lack of system resources (stack I guess) The crash itself writes something like "double fault" or "double error" (I'm sure about that "double") **************** Workaround ************************ Reducing recursion eliminates the problem. unionfs_statfs part: old (with the problem): --------------------------------------------------------------- struct unionfs_mount *ump; int error; struct statfs mstat; uint64_t lbsize; ump = MOUNTTOUNIONFSMOUNT(mp); UNIONFSDEBUG("unionfs_statfs(mp = %p, lvp = %p, uvp = %p)\n", (void *)mp, (void *)ump->um_lowervp, (void *)ump->um_uppervp); bzero(&mstat, sizeof(mstat)); error = VFS_STATFS(ump->um_lowervp->v_mount, &mstat); ----------------------------------------------------------------------- new (without crashes): ----------------------------------------------------------------------- struct unionfs_mount *ump; int error; struct statfs mstat; uint64_t lbsize; struct unionfs_mount *ump_aavzz; /*AAVZZ*/ /*ump = MOUNTTOUNIONFSMOUNT(mp);*/ /*AAVZZ*/ ump_aavzz = MOUNTTOUNIONFSMOUNT(mp); /*AAVZZ*/ UNIONFSDEBUG("unionfs_statfs(mp = %p, lvp = %p, uvp = %p)\n", (void *)mp, (void *)ump->um_lowervp, (void *)ump->um_uppervp); bzero(&mstat, sizeof(mstat)); /*Dirty hack to fast forward*/ while (! strcmp(ump_aavzz->um_lowervp->v_mount->mnt_stat.f_fstypename, "unionfs")) { ump_aavzz=MOUNTTOUNIONFSMOUNT(ump_aavzz->um_lowervp->v_mount); } ump=ump_aavzz; /*end of dirty hack*/ error = VFS_STATFS(ump->um_lowervp->v_mount, &mstat); ------------------------------------------------------------------------------- **************************** Considerations ************************** I'm sure that the above is not the way to treat the problem. But I do not have deep understanding of the internal workings of filesystems in general and unionfs in particular and cannot come up with anything better. Probably this growing recursion should not take place at all, which requires defferent handling of ump->um_lowervp->v_mount during list creation (mount?). Regards, Alex