bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fwd: [bug #17877] Invalid "No such file or directory" error on files


From: Miklos Szeredi
Subject: Re: Fwd: [bug #17877] Invalid "No such file or directory" error on filesystem without stable inode numbers
Date: Wed, 04 Oct 2006 13:06:25 +0200

> Thanks for forwarding that.
> I confess I hadn't looked at the original bug report.
> Just did, and see that it's a different problem than I first thought.
> I now see that this is about the dev/ino check when traversing "up"
> to return to a previously visited directory.
> 
> I find it hard to believe that a commonly used file system implementation
> fails to preserve the dev/ino of a component of some process's working
> directory.  IMHO, even when it's been unlinked, such a directory cannot
> be considered "unreferenced" when a process is still using it.

Ahh, but fts doesn't seem to have cwd or ancestor of cwd in the "lost"
directory.

Look at this strace snipplet from 'find /mnt/fuse/tmp/test':

open(".", O_RDONLY|O_LARGEFILE)         = 3
fchdir(3)                               = 0
lstat64("/mnt/fuse/tmp/test", {st_dev=makedev(0, 14), st_ino=3, 
st_mode=S_IFDIR|0755, st_nlink=4, st_uid=1001, st_gid=1001, st_blksize=4096, 
st_blocks=8, st_size=4096, st_atime=2006/10/03-17:08:07, 
st_mtime=2006/10/04-10:34:06, st_ctime=2006/10/04-10:34:06}) = 0
open(".", O_RDONLY|O_NONBLOCK|O_NOCTTY|O_LARGEFILE|O_DIRECTORY) = 4
fchdir(4)                               = 0
fstat64(1, {st_dev=makedev(3, 1), st_ino=1358669, st_mode=S_IFCHR|0666, 
st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, 
st_rdev=makedev(1, 3), st_atime=2006/09/17-18:39:13, 
st_mtime=2006/09/17-18:39:13, st_ctime=2006/09/17-18:39:13}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfc86ed4) = -1 ENOTTY (Inappropriate 
ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7f72000
open("/mnt/fuse/tmp/test", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY) = 5
fstat64(5, {st_dev=makedev(0, 14), st_ino=5, st_mode=S_IFDIR|0755, st_nlink=4, 
st_uid=1001, st_gid=1001, st_blksize=4096, st_blocks=8, st_size=4096, 
st_atime=2006/10/03-17:08:07, st_mtime=2006/10/04-10:34:06, 
st_ctime=2006/10/04-10:34:06}) = 0
fcntl64(5, F_SETFD, FD_CLOEXEC)         = 0
fstat64(5, {st_dev=makedev(0, 14), st_ino=5, st_mode=S_IFDIR|0755, st_nlink=4, 
st_uid=1001, st_gid=1001, st_blksize=4096, st_blocks=8, st_size=4096, 
st_atime=2006/10/03-17:08:07, st_mtime=2006/10/04-10:34:06, 
st_ctime=2006/10/04-10:34:06}) = 0
close(5)                                = 0
write(1, "/mnt/fuse/tmp/test\n", 19)    = 19
write(2, "/tmp/findutils-4.3.1/find/find: ", 32) = 32
write(2, "/mnt/fuse/tmp/test", 18)      = 18
write(2, ": No such file or directory", 27) = 27

No file decriptor or cwd refers to /mnt/fuse/tmp/test between the
lsta64 and the later ftstat64 on the open file.

> Miklos, you wrote this:
> 
>     There are several Linux filesystems (including smbfs, fat,
>     and some FUSE based ones) which cannot provide stable inode
>     numbers for unreferenced files or directories.
> 
> In the above, context, I don't know what you mean by "unreferenced
> files or directories."  Can you clarify?  FYI, as far as fts is
> concerned, dev/ino numbers matter for directories, not non-directories.
> 
> Can you provide instructions by which to reproduce the failure
> you've witnessed?

I'm reproducing it with a patched fuse version (see attached patch
against fuse-2.5.3).  What the patch does is to release the inode as
soon as there are no more references to it.  It's the same behaviour
you would get with extremely heavy memory pressure on any of the
mentioned filesystems.

- compile/install patched fuse-2.5.3 (./configure --enable-kernel-module)
- modprobe fuse
- example/fusexmp_fh -d /mnt/fuse
- find /mnt/fuse/tmp/test-tree

Miklos

Index: kernel/dir.c
===================================================================
RCS file: /cvsroot/fuse/fuse/kernel/dir.c,v
retrieving revision 1.101.2.1
diff -u -r1.101.2.1 dir.c
--- kernel/dir.c        10 Apr 2006 08:56:41 -0000      1.101.2.1
+++ kernel/dir.c        2 Oct 2006 10:12:29 -0000
@@ -185,12 +185,18 @@
 }
 #endif
 
+static int fuse_dentry_delete(struct dentry *entry)
+{
+       return 1;
+}
+
 static struct dentry_operations fuse_dentry_operations = {
 #ifdef KERNEL_2_6
        .d_revalidate   = fuse_dentry_revalidate,
 #else
        .d_revalidate   = fuse_dentry_revalidate_2_4,
 #endif
+       .d_delete = fuse_dentry_delete,
 };
 
 static inline int valid_mode(int m)
Index: kernel/inode.c
===================================================================
RCS file: /cvsroot/fuse/fuse/kernel/inode.c,v
retrieving revision 1.89
diff -u -r1.89 inode.c
--- kernel/inode.c      6 Jan 2006 18:29:39 -0000       1.89
+++ kernel/inode.c      2 Oct 2006 10:12:30 -0000
@@ -599,6 +599,7 @@
        .destroy_inode  = fuse_destroy_inode,
        .read_inode     = fuse_read_inode,
        .clear_inode    = fuse_clear_inode,
+       .drop_inode     = generic_delete_inode,
        .put_super      = fuse_put_super,
        .statfs         = fuse_statfs,
        .show_options   = fuse_show_options,





reply via email to

[Prev in Thread] Current Thread [Next in Thread]