Transition from getdir() to readdir(), temporarily disable cache

This commit enables the use of readdir() instead of getdir(). It also
completely disables the cache and the nullpath_ok feature. This will
be fixed in the next commits.
This commit is contained in:
Nikolaus Rath 2017-06-20 17:33:51 -07:00
parent 5f4619bac3
commit 3033dbc22e
2 changed files with 35 additions and 18 deletions

47
sshfs.c
View File

@ -836,8 +836,8 @@ static int buf_get_statvfs(struct buffer *buf, struct statvfs *stbuf)
return 0;
}
static int buf_get_entries(struct buffer *buf, fuse_cache_dirh_t h,
fuse_cache_dirfil_t filler)
static int buf_get_entries(struct buffer *buf, void *dbuf,
fuse_fill_dir_t filler)
{
uint32_t count;
unsigned i;
@ -860,7 +860,7 @@ static int buf_get_entries(struct buffer *buf, fuse_cache_dirh_t h,
S_ISLNK(stbuf.st_mode)) {
stbuf.st_mode = 0;
}
filler(h, name, &stbuf);
filler(dbuf, name, &stbuf, 0);
}
}
free(name);
@ -2029,8 +2029,8 @@ static int sshfs_req_pending(struct request *req)
return 0;
}
static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h,
fuse_cache_dirfil_t filler)
static int sftp_readdir_async(struct buffer *handle, void *buf, off_t offset,
fuse_fill_dir_t filler)
{
int err = 0;
int outstanding = 0;
@ -2039,6 +2039,7 @@ static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h,
int done = 0;
assert(offset == 0);
while (!done || outstanding) {
struct request *req;
struct buffer name;
@ -2084,7 +2085,7 @@ static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h,
done = 1;
}
if (!done) {
err = buf_get_entries(&name, h, filler);
err = buf_get_entries(&name, buf, filler);
buf_free(&name);
/* increase number of outstanding requests */
@ -2101,15 +2102,16 @@ static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h,
return err;
}
static int sftp_readdir_sync(struct buffer *handle, fuse_cache_dirh_t h,
fuse_cache_dirfil_t filler)
static int sftp_readdir_sync(struct buffer *handle, void *buf, off_t offset,
fuse_fill_dir_t filler)
{
int err;
assert(offset == 0);
do {
struct buffer name;
err = sftp_request(SSH_FXP_READDIR, handle, SSH_FXP_NAME, &name);
if (!err) {
err = buf_get_entries(&name, h, filler);
err = buf_get_entries(&name, buf, filler);
buf_free(&name);
}
} while (!err);
@ -2119,23 +2121,32 @@ static int sftp_readdir_sync(struct buffer *handle, fuse_cache_dirh_t h,
return err;
}
static int sshfs_getdir(const char *path, fuse_cache_dirh_t h,
fuse_cache_dirfil_t filler)
static int sshfs_readdir(const char *path, void *dbuf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
int err;
struct buffer buf;
struct buffer handle;
/* FIXME: Handle this */
(void) fi;
if(path == NULL) {
fprintf(stderr, "Don't yet know how to do readdir() without path\n");
return -EIO;
}
buf_init(&buf, 0);
buf_add_path(&buf, path);
// TODO: This should really go into sshfs_opendir() and sshfs_closedir()
err = sftp_request(SSH_FXP_OPENDIR, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
int err2;
buf_finish(&handle);
if (sshfs.sync_readdir)
err = sftp_readdir_sync(&handle, h, filler);
err = sftp_readdir_sync(&handle, dbuf, offset, filler);
else
err = sftp_readdir_async(&handle, h, filler);
err = sftp_readdir_async(&handle, dbuf, offset, filler);
err2 = sftp_request(SSH_FXP_CLOSE, &handle, 0, NULL);
if (!err)
@ -3212,6 +3223,7 @@ static struct fuse_cache_operations sshfs_oper = {
.init = sshfs_init,
.getattr = sshfs_getattr,
.access = sshfs_access,
.readdir = sshfs_readdir,
.readlink = sshfs_readlink,
.mknod = sshfs_mknod,
.mkdir = sshfs_mkdir,
@ -3234,10 +3246,10 @@ static struct fuse_cache_operations sshfs_oper = {
.create = sshfs_create,
.ftruncate = sshfs_ftruncate,
.fgetattr = sshfs_fgetattr,
.flag_nullpath_ok = 1,
.flag_nopath = 1,
.flag_nullpath_ok = 0,
.flag_nopath = 0,
},
.cache_getdir = sshfs_getdir,
// .cache_readdir = sshfs_readdir,
};
static void usage(const char *progname)
@ -3948,7 +3960,8 @@ int main(int argc, char *argv[])
#endif
sshfs.op = cache_init(&sshfs_oper);
fuse = fuse_new(ch, &args, sshfs.op,
// FIXME: Bypass cache for now
fuse = fuse_new(ch, &args, &sshfs_oper.oper,
sizeof(struct fuse_operations), NULL);
if (fuse == NULL) {
fuse_unmount(mountpoint, ch);

View File

@ -31,7 +31,8 @@ def name_generator(__ctr=[0]):
@pytest.mark.parametrize("debug", (False, True))
@pytest.mark.parametrize("cache_timeout", (0, 1))
def test_sshfs(tmpdir, debug, cache_timeout, capfd):
@pytest.mark.parametrize("sync_rd", (True, False))
def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, capfd):
# Avoid false positives from debug messages
#if debug:
@ -58,6 +59,9 @@ def test_sshfs(tmpdir, debug, cache_timeout, capfd):
if debug:
cmdline += [ '-o', 'sshfs_debug' ]
if sync_rd:
cmdline += [ '-o', 'sync_readdir' ]
# SSHFS Cache
if cache_timeout == 0:
cmdline += [ '-o', 'cache=no' ]