id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	blockedby	blocking	branch_state	votes
4635	Fuse mounted directory under kopia does not show contents in mc	rahrah		"OS:      Slackware64-current
LIBC:    glibc-2.40
Kernel:  6.12.10
ARCH:   x86_64

{{{
mc -V
GNU Midnight Commander 4.8.33
Built with GLib 2.82.4
Built with S-Lang 2.3.3 with terminfo database
Built with libssh2 1.11.1 
With builtin editor and aspell support
With subshell support as default
With support for background operations
With mouse support on xterm and Linux console
With support for X11 events
With internationalisation support
With multiple codepages support
With ext2fs attributes support
Virtual File Systems:
 cpiofs, tarfs, sfs, extfs, ftpfs, sftpfs, shell
Data types:
 char: 8; int: 32; long: 64; void *: 64; size_t: 64; off_t: 64; uintmax_t: 64;

}}}

== Description

Using mc with kopia (fuse) mounted snapshots.  Cli commands work fine, but mc sees an empty directory.

I found mc 4.8.25 did not show this problem, but mc 4.8.26 did.  I used a git bisection to find the issue.

== Kopia

Kopia is a backup program written in Go.  It uses go-fuse for its fuse kernel module interface.  Backups are accessed in directory hierarchies.  Inserted into the hierarchy path string are machine names and date and time stamps.

Kopia can be found here:

https://kopia.io

and

https://github.com/kopia/kopia/

The

mount -l

gives this after a kopia mount operation on my Linux test machine:

{{{
kopia on /mnt-test/kopia/mount type fuse.kopia (rw,nosuid,nodev,noatime,user_id=0,group_id=0,max_read=131072)
}}}

== Git Bisection

I did a git bisection to find the commit causing the problem. The commit introducing the bad behaviour was:

{{{
commit 27de03754fb790c82e70356daf859ff4de11f85d (HEAD)
Author: Andrij Abyzov <aabyzov@slb.com>
Date:   Tue Nov 24 18:58:06 2020 +0100

    Ticket #3987: implement a workaround if readdir() system call returns with EINTR.

    On Linux >= 5.1, MC sometimes shows empty directpries on mounted CIFS
    shares. Rereading directory restores the directory content.

    (local_opendir): reopen directory, if first readdir() returns NULL and
    errno == EINTR.

    Signed-off-by: Andrij Abyzov <aabyzov@slb.com>
    Signed-off-by: Andrew Borodin <aborodin@vmail.ru>

 src/vfs/local/local.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)



}}}

== Experimental Fix
Reverting 27de03754fb790c8

by using the following function fixed the problem:

{{{
#!C
/* ------------------- */

static void *
local_opendir (const vfs_path_t *vpath)
{
    DIR **local_info;
    DIR *dir = NULL;
    const char *path;

    path = vfs_path_get_last_path_str (vpath);
    dir = opendir (path);
    if (dir == NULL)
        return 0;

    local_info = (DIR **) g_new (DIR *, 1);
    *local_info = dir;

    return local_info;
}

/* ------------------- */
}}}

=== Original Code

{{{
#!C
/* ------------------- */

static void *
local_opendir (const vfs_path_t *vpath)
{
    DIR **local_info;
    DIR *dir = NULL;
    const char *path;

    path = vfs_path_get_last_path_str (vpath);

    /* On Linux >= 5.1, MC sometimes shows empty directories on mounted CIFS shares.
     * Rereading directory restores the directory content.
     *
     * Reopen directory, if first readdir() returns NULL and errno == EINTR.
     */
    while (dir == NULL)
    {
        dir = opendir (path);
        if (dir == NULL)
            return NULL;

        if (readdir (dir) == NULL && errno == EINTR)
        {
            closedir (dir);
            dir = NULL;
        }
        else
            rewinddir (dir);
    }

    local_info = (DIR **) g_new (DIR *, 1);
    *local_info = dir;

    return local_info;
}

/* ------------------- */
}}}

== Notes on Testing

In my bisection tests, I, at first, mounted the kopia mount, then tried the various bisection builds. Doing this seemed to allow all the failed builds to work.

For more consistent test results, the kopia mount was umounted then remounted between tests.  Indeed, opening the any dir in the mounted tree with a faulty __local_open_dir()__ would certainly create the correct test conditions.  Only good builds would then open the directory.

I'd be happy to provide more granular steps to reproduce this problem using kopia commands.

== Possible Similar Bug

https://github.com/littlefs-project/littlefs-fuse/issues/43

== Thank You

Thank you for all the time and effort you put into making Midnight Commander, and distributing it under the GPL."	defect	closed	major		mc-vfs	master	invalid					no branch	
