linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Stef Bon <stefbon@gmail.com>
Cc: "fuse-devel@lists.sourceforge.net"
	<fuse-devel@lists.sourceforge.net>,
	"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>
Subject: Re: [fuse-devel] Changes in 4.7.
Date: Wed, 1 Jun 2016 14:52:09 +0100	[thread overview]
Message-ID: <20160601135209.GG14480@ZenIV.linux.org.uk> (raw)
In-Reply-To: <CANXojcxrfDtDeOPmL1VRP3YZOoQPPc63BYDN0uyiRQJrnpUuYg@mail.gmail.com>

On Wed, Jun 01, 2016 at 02:32:46PM +0200, Stef Bon wrote:

> I understand that a directory is simular to a file, and the struct
> file also applies
> to a directory.
> Thanks a lot for your detailed explanation!
> 
> When does a lseek not affect another? Does this depend on how the
> filesystem deals with
> a directory right? How is it stored? When a directory is nothing more
> than a linked list, where
> new entries are appended at the end, seeking through the linked list
> will not get mixed up
> compared to  using another method, like I use skiplists (and only
> that) for directories.

No, it has nothing to do with the way directory is stored, etc.  After
	int fd1 = open("foo", O_DIRECTORY);
	int fd2 = dup(fd1);
	int fd3 = open("foo", O_DIRECTORY);
lseek() on fd1 and fd2 manipulate the same object; that on fd3 is independent.
Current IO position, both for regular files and directories, is a property
of an object created by open(); dup()/dup2()/fork() create aliases for those
objects.  getdents(2) is serialized on per-open() basis; if two descriptors
are aliases ultimately coming from the same open() call, the calls of
getdents() on them will be treated as if they were sequential calls of
getdents() on the same descriptor - each call will read a new chunk of
directory.  If descriptors result from separate open() calls, getdents() on
one of them has no effect on getdents() on another.

It's exactly the same as for regular files - if you have
	int fd1 = open("bar", 0);	// first channel opened
	int fd2 = dup(fd1);		// fd2 refers to the same channel
	int fd3 = open("bar", 0);	// second channel opened
	char c1, c2, c3;
	read(fd1, &c1, 1);	// offset of the first channel goes 0 -> 1
	read(fd2, &c2, 1);	// offset of the first channel goes 1 -> 2
	read(fd3, &c3, 1);	// offset of the second channel goes 0 -> 1
c1 and c3 will contain the first byte of our file and c2 - the second one.
If you continue that with
	lseek(fd2, 0, SEEK_SET);// offset of the first channel goes 2 -> 0
	read(fd1, &c1, 1);
c1 will be the first byte.  If that lseek() had been done to fd3 instead of
fd2, c1 would be the third byte, since the offset in the first channel would've
been unaffected by the operation on the second one.

For regular files, the kernel serializes read()/write()/lseek() done on
descriptors aliasing each other.  Now it does the same for getdents()/lseek()
of directories.

>From the filesystem point of view, you might see two getdents() called
in parallel only if their results should be unaffected by the order of
operations.

  reply	other threads:[~2016-06-01 13:52 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CANXojcwuLVpyqkXxcUhKdG=nDEp-XspR4PtDerpoqO2FmMLp5w@mail.gmail.com>
2016-05-31  7:17 ` [fuse-devel] Changes in 4.7 Miklos Szeredi
2016-05-31 10:57   ` Stef Bon
2016-05-31 11:09     ` Miklos Szeredi
     [not found]   ` <nijg09$6k0$1@ger.gmane.org>
     [not found]     ` <CAJfpegvJoSK6fQEGWj_uEQF8q2jYmdqUyKy1-m5DxFMUFc0rEg@mail.gmail.com>
     [not found]       ` <CAJfpeguV3H_oC=5FM3G8tVsrY7Fiy2LX0JKttFBGQWN+SC6_YQ@mail.gmail.com>
     [not found]         ` <87shwy8b38.fsf@thinkpad.rath.org>
2016-05-31 16:25           ` Stef Bon
2016-05-31 17:22             ` Stef Bon
2016-05-31 17:44             ` Al Viro
2016-05-31 18:44               ` Stef Bon
2016-05-31 20:29                 ` Al Viro
2016-06-01 12:32                   ` Stef Bon
2016-06-01 13:52                     ` Al Viro [this message]
2016-06-01 14:44                       ` Stef Bon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160601135209.GG14480@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=stefbon@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).