From owner-freebsd-fs@freebsd.org Tue Aug 22 11:38:05 2017 Return-Path: Delivered-To: freebsd-fs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 534B5DE40AA for ; Tue, 22 Aug 2017 11:38:05 +0000 (UTC) (envelope-from Nikolaus@rath.org) Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 293AF81F6A for ; Tue, 22 Aug 2017 11:38:04 +0000 (UTC) (envelope-from Nikolaus@rath.org) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 2992A20BCE for ; Tue, 22 Aug 2017 07:38:03 -0400 (EDT) Received: from frontend1 ([10.202.2.160]) by compute1.internal (MEProxy); Tue, 22 Aug 2017 07:38:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-sender :x-me-sender:x-sasl-enc:x-sasl-enc; s=fm1; bh=1GmQhsFDtSMt537kTU CIiBkYErvEhiXkYmq9+IURroQ=; b=nReHfBY8n3cQt5eINx2CHDLYvNyzFuZ88D hVwC1e6qaLafsU1RMIWlkcdGhWD3UEeMMOFpokRJhETeBIPoiW58Pg9KjQPutdF3 0Atm9gVChwsu4lxebKNomJ2bapR+sw31dmDW9U9F2BU/2Fg7EreyxOH9XNbejoP5 tWcIxFvaL8I8cHTEFaQwSpFS0L3pHjwqpXs67ixz8SQQxEKBE2HBRDbcil9K9QG+ pDkgBnA3rBbOKPqYRI+qlVut3xt4SLWR9NxaAsFIEgcpqJwTpxxJoSDpPydHVgAo 5+/INY0YOTIXzg1KyuMiAJrUYfZDTVAYc6Mb+qhQTBVQq0z/ctxQ== X-ME-Sender: X-Sasl-enc: 9G7uaXBuS8xpHJ3fAKDhLWVN3yLcomupKvUdy6e7bOYl 1503401882 Received: from ebox.rath.org (ebox.rath.org [45.79.69.51]) by mail.messagingengine.com (Postfix) with ESMTPA id E0EDD7E6AD for ; Tue, 22 Aug 2017 07:38:02 -0400 (EDT) Received: from vostro.rath.org (vostro [192.168.12.4]) by ebox.rath.org (Postfix) with ESMTPS id E68D4D5 for ; Tue, 22 Aug 2017 11:38:01 +0000 (UTC) Received: by vostro.rath.org (Postfix, from userid 1000) id 7223F1031FD; Tue, 22 Aug 2017 13:38:00 +0200 (CEST) From: Nikolaus Rath To: freebsd-fs@freebsd.org Subject: Can telldir() == 0 value be made special? Mail-Copies-To: never Mail-Followup-To: freebsd-fs@freebsd.org Date: Tue, 22 Aug 2017 13:38:00 +0200 Message-ID: <87bmn7kf3b.fsf@vostro.rath.org> User-Agent: Gnus/5.130014 (Ma Gnus v0.14) Emacs/25.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Aug 2017 11:38:05 -0000 Hello, I am trying to debug a test failure of libfuse under FreeBSD. I believe I have reduced it to the following root cause: Consider the following program: #include #include #include int main(void) { struct dirent *e =3D NULL; DIR *dirp; printf("opendir...\n"); dirp =3D opendir("/"); if(dirp =3D=3D NULL) { perror("opendir"); return 1; } printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("closedir..\n"); closedir(dirp); =20=20=20=20 printf("opendir...\n"); dirp =3D opendir("/"); if(dirp =3D=3D NULL) { perror("opendir"); return 1; } e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("closedir..\n"); closedir(dirp); =20=20=20=20 return 0; } Under FreeBSD, running it gives: # ./simple=20 opendir... telldir: 0 readdir: . telldir: 1 readdir: .. closedir.. opendir... readdir: . telldir: 0 readdir: .. closedir.. In other words, if telldir() is called right after opendir(), it gives an offset of zero. But if telldir() is called only after the first readdir() call, it also gives an offset of zero. My hypothesis is that FreeBSD actually just enumerates the different telldir() calls - is that correct? Now, the offsets returned by telldir() are documented to be valid only within a given *dirp, so FreeBSD isn't doing anything wrong. However, having different meanings even for an offset of zero causes problems for libfuse, because under Linux an offset of zero is guaranteed to mean "first entry". This is reflected in the definition of the fuse readdir() function which always receives an *offset* parameter that needs to have a definite value even when telldir() was never called. If zero is suddenly also a valid telldir() return value that may indicate some other position in the stream, things get complicated. Now, I think I managed to work around that by shifting all offsets by one, but that is awkward (and I may have overlooked some problems that the unit tests don't cover). So I am wondering: Is there a reason why the FreeBSD kernel could not start enumerating telldir() offsets with 1, so that 0 can always have the same meaning? Best, -Nikolaus --=20 GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F =C2=BBTime flies like an arrow, fruit flies like a Banana.=C2= =AB