fix
diff --git a/lib/fuse.c b/lib/fuse.c
index ea17a3d..f930404 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -90,6 +90,7 @@
struct fuse_dirhandle {
pthread_mutex_t lock;
struct fuse *fuse;
+ fuse_req_t req;
char *contents;
int allocated;
unsigned len;
@@ -1446,13 +1447,32 @@
fuse_reply_open(req, llfi);
}
+static int extend_contents(struct fuse_dirhandle *dh, unsigned minsize)
+{
+ if (minsize > dh->size) {
+ char *newptr;
+ unsigned newsize = dh->size;
+ if (!newsize)
+ newsize = 1024;
+ while (newsize < minsize)
+ newsize *= 2;
+
+ newptr = (char *) realloc(dh->contents, newsize);
+ if (!newptr) {
+ dh->error = -ENOMEM;
+ return -1;
+ }
+ dh->contents = newptr;
+ dh->size = newsize;
+ }
+ return 0;
+}
+
static int fill_dir_common(struct fuse_dirhandle *dh, const char *name,
const struct stat *statp, off_t off)
{
struct stat stbuf;
- unsigned namelen = strlen(name);
- unsigned entsize;
- unsigned newlen;
+ size_t newlen;
if (statp)
stbuf = *statp;
@@ -1473,31 +1493,24 @@
}
}
- entsize = fuse_dirent_size(namelen);
- newlen = dh->len + entsize;
-
if (off) {
+ if (extend_contents(dh, dh->needlen) == -1)
+ return 1;
+
dh->filled = 0;
+ newlen = dh->len + fuse_add_direntry(dh->req, dh->contents + dh->len,
+ dh->needlen - dh->len, name,
+ &stbuf, off);
if (newlen > dh->needlen)
return 1;
- }
-
- if (newlen > dh->size) {
- char *newptr;
-
- if (!dh->size)
- dh->size = 1024;
- while (newlen > dh->size)
- dh->size *= 2;
-
- newptr = (char *) realloc(dh->contents, dh->size);
- if (!newptr) {
- dh->error = -ENOMEM;
+ } else {
+ newlen = dh->len + fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
+ if (extend_contents(dh, newlen) == -1)
return 1;
- }
- dh->contents = newptr;
+
+ fuse_add_direntry(dh->req, dh->contents + dh->len, dh->size - dh->len,
+ name, &stbuf, newlen);
}
- fuse_add_dirent(dh->contents + dh->len, name, &stbuf, off ? off : newlen);
dh->len = newlen;
return 0;
}
@@ -1521,8 +1534,8 @@
return dh->error;
}
-static int readdir_fill(struct fuse *f, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_dirhandle *dh,
+static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
+ size_t size, off_t off, struct fuse_dirhandle *dh,
struct fuse_file_info *fi)
{
int err = -ENOENT;
@@ -1534,11 +1547,13 @@
dh->error = 0;
dh->needlen = size;
dh->filled = 1;
+ dh->req = req;
err = -ENOSYS;
if (f->op.readdir)
err = f->op.readdir(path, dh, fill_dir, off, fi);
else if (f->op.getdir)
err = f->op.getdir(path, dh, fill_dir_old);
+ dh->req = NULL;
if (!err)
err = dh->error;
if (err)
@@ -1563,7 +1578,7 @@
dh->filled = 0;
if (!dh->filled) {
- int err = readdir_fill(f, ino, size, off, dh, &fi);
+ int err = readdir_fill(f, req, ino, size, off, dh, &fi);
if (err) {
reply_err(req, err);
goto out;