From owner-freebsd-fs@freebsd.org Tue Aug 22 14:42:45 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 B2156DEF6C1 for ; Tue, 22 Aug 2017 14:42:45 +0000 (UTC) (envelope-from cse.cem@gmail.com) Received: from mail-oi0-f46.google.com (mail-oi0-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 60A3064194 for ; Tue, 22 Aug 2017 14:42:44 +0000 (UTC) (envelope-from cse.cem@gmail.com) Received: by mail-oi0-f46.google.com with SMTP id j144so59896650oib.1 for ; Tue, 22 Aug 2017 07:42:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:reply-to:in-reply-to:references :from:date:message-id:subject:to:content-transfer-encoding; bh=ba+jaIp0qAjRFNlK1YPVMk7/oooKothTuksgPO4sGyU=; b=PcyDD+YidGnTHLLLzcrG0RufNgY9dvCSnWeaBRK9kwv32hPiTycHtb1lnrZDlaufVM 7/2d5WwDH3zVTn3Ifqfbn7FREGKFHv2EX/dF0VdcsH5uij+xBUIB6kRPM9qTZMbAabsd 1cI0l/yyKxVe4ZSd8Np5ihMDZD7jtbnnF5T+bXJe4s6W4Q+RBwlG5Gw7LH5hoOFh/pKn Dv8CjiRAymUqVyfBwr9nxgSbn1fuZDoFEothUMPQ5yhYmzkUId9eQ2BOjkvd0yIFOvGO xoo3xyB9I+oJDpCZ+kfhY4TycBdJmNnRoItuEXnlIEFdZUgvgK2IeHjh2zfOHLDt6NES j2zA== X-Gm-Message-State: AHYfb5iRkGuHpPIG8qyz+IeAB94TIAYAThe8oXj/MfIQfPNBHu2zu/jm 0gRj0fAsIm8MNPR52lC87w== X-Received: by 10.202.190.196 with SMTP id o187mr1121926oif.264.1503412957446; Tue, 22 Aug 2017 07:42:37 -0700 (PDT) Received: from mail-io0-f176.google.com (mail-io0-f176.google.com. [209.85.223.176]) by smtp.gmail.com with ESMTPSA id d95sm3004350oic.14.2017.08.22.07.42.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Aug 2017 07:42:37 -0700 (PDT) Received: by mail-io0-f176.google.com with SMTP id y4so16339099iod.4 for ; Tue, 22 Aug 2017 07:42:37 -0700 (PDT) X-Received: by 10.107.185.196 with SMTP id j187mr774775iof.248.1503412956784; Tue, 22 Aug 2017 07:42:36 -0700 (PDT) MIME-Version: 1.0 Reply-To: cem@freebsd.org Received: by 10.2.81.131 with HTTP; Tue, 22 Aug 2017 07:42:36 -0700 (PDT) In-Reply-To: <87bmn7kf3b.fsf@vostro.rath.org> References: <87bmn7kf3b.fsf@vostro.rath.org> From: Conrad Meyer Date: Tue, 22 Aug 2017 07:42:36 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: Can telldir() == 0 value be made special? To: freebsd-fs@freebsd.org 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 14:42:45 -0000 Hi Nikolaus, As you have surmised, DIR* seekpoints are created dynamically whenever requested by user's telldir() call: https://github.com/freebsd/freebsd/blob/master/lib/libc/gen/telldir.c#L53 I believe we could special case zero without breaking ABI compatibility of correct programs. Something like this: --- a/lib/libc/gen/telldir.c +++ b/lib/libc/gen/telldir.c @@ -70,6 +70,20 @@ telldir(DIR *dirp) } } if (lp =3D=3D NULL) { + /* Create special zero telldir entry, similar to Linux */ + if (dirp->dd_td->td_loccnt =3D=3D 0 && dirp->dd_loc !=3D 0)= { + lp =3D malloc(sizeof(struct ddloc)); + if (lp =3D=3D NULL) { + if (__isthreaded) + _pthread_mutex_unlock(&dirp->dd_loc= k); + return (-1); + } + lp->loc_index =3D dirp->dd_td->td_loccnt++; + lp->loc_seek =3D 0; + lp->loc_loc =3D 0; + LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe= ); + } + lp =3D malloc(sizeof(struct ddloc)); if (lp =3D=3D NULL) { if (__isthreaded) I don't know if there are any downsides to special-casing zero like this, other than additional code complexity. Best, Conrad On Tue, Aug 22, 2017 at 4:38 AM, Nikolaus Rath wrote: > 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); > > 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); > > return 0; > } > > > Under FreeBSD, running it gives: > > # ./simple > 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 > > -- > 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 > _______________________________________________ > freebsd-fs@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-fs > To unsubscribe, send any mail to "freebsd-fs-unsubscribe@freebsd.org"