All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Theodore Y. Ts'o" <tytso@mit.edu>
To: Vijay Chidambaram <vijay@cs.utexas.edu>
Cc: Dave Chinner <david@fromorbit.com>,
	Jayashree Mohan <jayashree2912@gmail.com>,
	Amir Goldstein <amir73il@gmail.com>,
	linux-btrfs <linux-btrfs@vger.kernel.org>,
	fstests <fstests@vger.kernel.org>,
	linux-f2fs-devel@lists.sourceforge.net
Subject: Re: Symlink not persisted even after fsync
Date: Sat, 14 Apr 2018 21:30:15 -0400	[thread overview]
Message-ID: <20180415013015.GC21830@thunk.org> (raw)
In-Reply-To: <CAPaz=ELn5GNbw4z5e30Og1ExyRTFNxHhPM9K_qn-EKWQ_Y7jXQ@mail.gmail.com>

On Sat, Apr 14, 2018 at 08:13:28PM -0500, Vijay Chidambaram wrote:
> 
> We are *not* saying an fsync on a symlink file has to result in any
> action on the original file. We understand the lack of ordering
> constraints here.

The problem is you're not being precise here.  The fsync(2) system
call operates on a file descriptor, not a file.  This is an important
distinction.

Suppose you have a symlink called "foo" which points to  "/tmp/bar/quux"

	fd = open("foo", O_CREAT|O_RDWR);

It will _fail_ if /tmp/bar does not exist:

% ls -l foo
0 lrwxrwxrwx 1 tytso tytso 13 Apr 14 21:21 foo -> /tmp/bar/quux
% echo test > foo
bash: foo: No such file or directory
% mkdir /tmp/bar
% echo test > foo
% ls -l /tmp/bar
total 4
4 -rw-r--r-- 1 tytso tytso 5 Apr 14 21:22 quux

When you open "foo", the restulting file descriptor is not associated
with the symlink.  The resulting file descriptor is the exact same
thing you would get if you had instead called:

	fd = open("/tmp/bar/quux", O_CREAT|O_RDWR);

Hence, when you call

       fsync(fd);

What you are calling fsync on is not the _symlink_, but the inode
which is named by /tmp/bar/quux.


Now, as I said in the e-mail I just sent, you _can_ do this:

	fd = open ("foo", O_PATH | O_NOFOLLOW);

And this *will* give you a file descriptor which is associated with
the symlink, and not the inode (if it exists) which the symlink points
at.  However, there is a very limited number of system calls can
operate on that file descriptor --- and read(2), write(2), and
fsync(2) are not among them.

> fsync(fd) -> succeeds
> 
> So perhaps fsync on "symlink" is unsupported behavior that varies from
> file system to file system? We saw ext4 and xfs had this behavior, so
> we assumed it to be the default.

fsync on "symlink" doesn't exist at all today.  You were mistaken as
to what you were doing; what you were fsync'ing was the inode that was
created as the result of:

	fd = open("symlink", O_CREAT|O_RDWR);

... if you were able to create file in the first place.  If "symlink"
points at /tmp/bar/quux, and /tmp/bar does not exist, the open will
fail.  Not because it was a symlink, but because the equivalent
open("/tmp/bar/quux", O_CREAT|O_RDWR) would have failed.

Regards,

						- Ted

WARNING: multiple messages have this Message-ID (diff)
From: "Theodore Y. Ts'o" <tytso@mit.edu>
To: Vijay Chidambaram <vijay@cs.utexas.edu>
Cc: Amir Goldstein <amir73il@gmail.com>,
	Dave Chinner <david@fromorbit.com>,
	fstests <fstests@vger.kernel.org>,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-btrfs <linux-btrfs@vger.kernel.org>
Subject: Re: Symlink not persisted even after fsync
Date: Sat, 14 Apr 2018 21:30:15 -0400	[thread overview]
Message-ID: <20180415013015.GC21830@thunk.org> (raw)
In-Reply-To: <CAPaz=ELn5GNbw4z5e30Og1ExyRTFNxHhPM9K_qn-EKWQ_Y7jXQ@mail.gmail.com>

On Sat, Apr 14, 2018 at 08:13:28PM -0500, Vijay Chidambaram wrote:
> 
> We are *not* saying an fsync on a symlink file has to result in any
> action on the original file. We understand the lack of ordering
> constraints here.

The problem is you're not being precise here.  The fsync(2) system
call operates on a file descriptor, not a file.  This is an important
distinction.

Suppose you have a symlink called "foo" which points to  "/tmp/bar/quux"

	fd = open("foo", O_CREAT|O_RDWR);

It will _fail_ if /tmp/bar does not exist:

% ls -l foo
0 lrwxrwxrwx 1 tytso tytso 13 Apr 14 21:21 foo -> /tmp/bar/quux
% echo test > foo
bash: foo: No such file or directory
% mkdir /tmp/bar
% echo test > foo
% ls -l /tmp/bar
total 4
4 -rw-r--r-- 1 tytso tytso 5 Apr 14 21:22 quux

When you open "foo", the restulting file descriptor is not associated
with the symlink.  The resulting file descriptor is the exact same
thing you would get if you had instead called:

	fd = open("/tmp/bar/quux", O_CREAT|O_RDWR);

Hence, when you call

       fsync(fd);

What you are calling fsync on is not the _symlink_, but the inode
which is named by /tmp/bar/quux.


Now, as I said in the e-mail I just sent, you _can_ do this:

	fd = open ("foo", O_PATH | O_NOFOLLOW);

And this *will* give you a file descriptor which is associated with
the symlink, and not the inode (if it exists) which the symlink points
at.  However, there is a very limited number of system calls can
operate on that file descriptor --- and read(2), write(2), and
fsync(2) are not among them.

> fsync(fd) -> succeeds
> 
> So perhaps fsync on "symlink" is unsupported behavior that varies from
> file system to file system? We saw ext4 and xfs had this behavior, so
> we assumed it to be the default.

fsync on "symlink" doesn't exist at all today.  You were mistaken as
to what you were doing; what you were fsync'ing was the inode that was
created as the result of:

	fd = open("symlink", O_CREAT|O_RDWR);

... if you were able to create file in the first place.  If "symlink"
points at /tmp/bar/quux, and /tmp/bar does not exist, the open will
fail.  Not because it was a symlink, but because the equivalent
open("/tmp/bar/quux", O_CREAT|O_RDWR) would have failed.

Regards,

						- Ted

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

  reply	other threads:[~2018-04-15  1:30 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-12 17:51 Symlink not persisted even after fsync Jayashree Mohan
2018-04-13  5:52 ` Amir Goldstein
2018-04-13 12:57   ` Vijay Chidambaram
     [not found]   ` <CAPaz=E+-baGSWhL3nD-8X4jn6rKdn2AVGLeqWh3EY5Nh-RodRA@mail.gmail.com>
2018-04-13 13:16     ` Amir Goldstein
2018-04-13 14:39       ` Jayashree Mohan
2018-04-14  1:20         ` Dave Chinner
2018-04-14  3:27           ` Vijay Chidambaram
2018-04-14 21:55             ` Dave Chinner
2018-04-14 21:55               ` Dave Chinner
2018-04-15  1:13               ` Vijay Chidambaram
2018-04-15  1:30                 ` Theodore Y. Ts'o [this message]
2018-04-15  1:30                   ` Theodore Y. Ts'o
2018-04-15  1:40                   ` Vijay Chidambaram
2018-04-15  1:17               ` Theodore Y. Ts'o
2018-04-15  1:17                 ` Theodore Y. Ts'o
2018-04-15  1:38                 ` Vijay Chidambaram
     [not found]                 ` <CAHWVdUXAyyeTGNXrtTTc+tUbA3t9TUjJPSF=M4Cetj4+d1w3eQ@mail.gmail.com>
2018-04-15 14:13                   ` Theodore Y. Ts'o
2018-04-16  0:10                     ` Vijay Chidambaram
2018-04-16  5:39                       ` Amir Goldstein
2018-04-16 15:17                         ` Vijay Chidambaram
2018-04-16  5:52                       ` Theodore Y. Ts'o
2018-04-16 15:09                         ` Vijay Chidambaram
2018-04-17  0:07                       ` Dave Chinner
2018-04-17  2:56                         ` Vijay Chidambaram
2018-04-13 14:06   ` Dave Chinner

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=20180415013015.GC21830@thunk.org \
    --to=tytso@mit.edu \
    --cc=amir73il@gmail.com \
    --cc=david@fromorbit.com \
    --cc=fstests@vger.kernel.org \
    --cc=jayashree2912@gmail.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=vijay@cs.utexas.edu \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.