From owner-svn-src-head@FreeBSD.ORG Mon Aug 4 19:01:54 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 39395675; Mon, 4 Aug 2014 19:01:54 +0000 (UTC) Received: from mail107.syd.optusnet.com.au (mail107.syd.optusnet.com.au [211.29.132.53]) by mx1.freebsd.org (Postfix) with ESMTP id F05B12B16; Mon, 4 Aug 2014 19:01:53 +0000 (UTC) Received: from c122-106-147-133.carlnfd1.nsw.optusnet.com.au (c122-106-147-133.carlnfd1.nsw.optusnet.com.au [122.106.147.133]) by mail107.syd.optusnet.com.au (Postfix) with ESMTPS id 2C04CD436BE; Tue, 5 Aug 2014 05:01:45 +1000 (EST) Date: Tue, 5 Aug 2014 05:01:39 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: "Pedro F. Giffuni" Subject: Re: svn commit: r269523 - head/sys/fs/ext2fs In-Reply-To: <53dfb7a3.5e19.37746e44@svn.freebsd.org> Message-ID: <20140805041657.A1066@besplex.bde.org> References: <53dfb7a3.5e19.37746e44@svn.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=eojmkOZX c=1 sm=1 tr=0 a=7NqvjVvQucbO2RlWB8PEog==:117 a=PO7r1zJSAAAA:8 a=4TvIEQ0Y17sA:10 a=LETNmsYq37QA:10 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=7AIIN_0c3wSrVntzkGMA:9 a=CjuIK1q_8ugA:10 Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Aug 2014 19:01:54 -0000 On Mon, 4 Aug 2014, Pedro F. Giffuni wrote: > Log: > set EXT2_LINK_MAX to LINK_MAX > > In linux EXT4_LINK_MAX is now 64000. We can't really do that > since i_nlink and va_nlink are signed so setting higher values > is likely to cause trouble. Hmm, va_nlink doesn't use nlink_t and is inconsistent with nlink_t since nlink_t is unsigned. The bug is nlink_t being unsigned. Signed for i_nlink is more reasonable although it is inconsistent with unsigned for e2di_nlink. The implementation might want to use the better arithmetic of signed types. However, it blindly converts from unsigned to signed when converting e2di_nlink to i_nlink, so it overflows for corrupt file systems with e2di_nlink larger than 32767. > This is a system limitation so set the EXT_LINK_MAX to > what the system can handle. > > MFC after: 3 days > > Modified: > head/sys/fs/ext2fs/ext2_dir.h > > Modified: head/sys/fs/ext2fs/ext2_dir.h > ============================================================================== > --- head/sys/fs/ext2fs/ext2_dir.h Mon Aug 4 16:32:08 2014 (r269522) > +++ head/sys/fs/ext2fs/ext2_dir.h Mon Aug 4 16:41:06 2014 (r269523) > @@ -72,7 +72,7 @@ struct ext2fs_direct_2 { > /* > * Maximal count of links to a file > */ > -#define EXT2_LINK_MAX 32000 > +#define EXT2_LINK_MAX LINK_MAX > > /* > * Ext2 directory file types. Only the low 3 bits are used. The This breaks ext2 where the limit is 32000. It allows creating corrupt file systems containing inodes with more than 32000 links. The corruption would be noticed by ext2fs implemenations with a non-broken limit and should be noticed by ext2fsck. The failure modes in the previous version of ext2fs in FreeBSD seem to be limited to operations that increase the link count further (including temporary increases for rename?). Old versions of ext2fs in FreeBSD had the same bug in a worse way. They defined EXT2_LINK_MAX as 32000 but never used it. They used the system LINK_MAX instead. Old versions of linux (2.6.10) have many bugs related to LINK_MAX, but not this one. {LINK_MAX} is variable. Thus LINK_MAX must not be defined in . But it is defined in , with a value of 127 that is too small for most file systems. Many nearby variable limits that must not be defined are defined (the worst one in practice is {OPEN_MAX}. Similarly in FreeBSD, except the LINK_MAX that must not be defined in is defined as large enough for all file systems. Back in linux, nlink_t is uint16_t on some arches including x86, but JFS_LINK_MAX is 0xffffffff. I can't see where pathconf() returns an fs-dependent (or file-dependent) limit. Bruce