Wednesday, May 3, 2017

Re: Strange behavior with x! and permissions

Hi Gary!

On Mi, 03 Mai 2017, Gary Johnson wrote:

> > > If that was true, I would expect the inode number of the file to be
> > > different after Vim had edited it, but that is not what I observe.
> > > The inode number is unchanged.
> > >
> > > I created a file with only read permissions and successfully edited
> > > it with Vim. I repeated the experiment in a directory with only
> > > read and execute permissions and was able to edit that file as well.
> >
> > Did you check the backupcopy option?
>
> 'backupcopy' is set to "yes".

Okay, so apparently it is not so easy (as usual).

I made a little test:

#v+
~$ mkdir /tmp/cb && cd /tmp/cb && touch file{1,2} && sudo chown root:root file2
[sudo] password for chrisbra:
4197366 -rw-r--r-- 1 chrisbra chrisbra 0 Mai 3 21:03 file1
4197367 -rw-r--r-- 1 root root 0 Mai 3 21:03 file2
/tmp/cb$ strace -o trace.log vim -u NONE -N --noplugin -c ':wq!' file2
/tmp/cb$ ls -li file*
4197366 -rw-r--r-- 1 chrisbra chrisbra 0 Mai 3 21:03 file1
4197367 -rw-r--r-- 1 chrisbra chrisbra 0 Mai 3 21:04 file2
#v-

So the files inode did indeed not change. However let's have a look into
the trace file:
#v+
[…]
access("file2", W_OK) = -1 EACCES (Permission denied)
getxattr("file2", "system.posix_acl_access", 0x7ffc05784db0, 132) = -1 ENODATA (No data available)
stat("file2", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("file2", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
getuid() = 1002
unlink("file2") = 0
open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
fsync(3) = 0
close(3) = 0
chmod("file2", 0644) = 0
[…]
#v-

So we can clearly see Vim first tries to open the file. That does not
work, and it gets an error EACCESS. It then unlinks (deletes) the file
and re-creates it (open(), fsync() and close()).

It did some more research. It seems, that inodes are indeed reused. This
is of course filesystem dependent and for my case ext4 this seems to be
the case.

Googling around, I found this Stackoverflow answer:
http://stackoverflow.com/a/25559643/789222 which states:

"There are two policies for allocating an inode. If the new inode is a
directory, […]. For other inodes, search forward from the
parent directory's block group to find a free inode."

I haven't looked at the source, but assume that ext4 is similar enough
to ext3 that this behaves the same. So I did another test :)

#v+
/tmp/cb$ sudo chown root:root file2
[sudo] password for chrisbra:
/tmp/cb$ ls -li file*
4197366 -rw-r--r-- 1 chrisbra chrisbra 0 Mai 3 21:03 file1
4197367 -rw-r--r-- 1 root root 0 Mai 3 21:04 file2
/tmp/cb$ vim -u NONE -N --noplugin -c '! rm file1' -c ':wq!' file2
/tmp/cb$ ls -li file*
4197366 -rw-r--r-- 1 chrisbra chrisbra 0 Mai 3 21:06 file2
#v-

So it is clear, by removing a file with a lower inode number before
trying to write file2, that inode number of the deleted file file1 is
re-used when re-creating file2.

So it looks like ext3/ext4 always uses the first free inode number for a
directory it can find and therefore, when deleting a file and
re-creating the file, it is possible that the same inode is re-used.

Today I learned something new ;)

Best,
Christian
--
Was die neuen Unwissenden holen müssen:
12er Getriebesand (rot)

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: