fix
diff --git a/lib/fuse.c b/lib/fuse.c
index 237dee1..7f8ed3d 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -612,13 +612,16 @@
     fuse_reply_none(req);
 }
 
-static void fuse_getattr(fuse_req_t req, fuse_ino_t ino)
+static void fuse_getattr(fuse_req_t req, fuse_ino_t ino,
+                         struct fuse_file_info *fi)
 {
     struct fuse *f = req_fuse_prepare(req);
     struct stat buf;
     char *path;
     int err;
 
+    (void) fi;
+
     err = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, ino);
@@ -661,12 +664,15 @@
     return err;
 }
 
-static int do_truncate(struct fuse *f, const char *path, struct stat *attr)
+static int do_truncate(struct fuse *f, const char *path, struct stat *attr,
+                       struct fuse_file_info *fi)
 {
     int err;
 
     err = -ENOSYS;
-    if (f->op.truncate)
+    if (fi && f->op.ftruncate)
+        err = f->op.ftruncate(path, attr->st_size, fi);
+    else if (f->op.truncate)
         err = f->op.truncate(path, attr->st_size);
 
     return err;
@@ -686,7 +692,7 @@
 }
 
 static void fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
-                         int valid)
+                         int valid, struct fuse_file_info *fi)
 {
     struct fuse *f = req_fuse_prepare(req);
     struct stat buf;
@@ -705,7 +711,7 @@
             if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)))
                 err = do_chown(f, path, attr, valid);
             if (!err && (valid & FUSE_SET_ATTR_SIZE))
-                err = do_truncate(f, path, attr);
+                err = do_truncate(f, path, attr, fi);
             if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
                 err = do_utime(f, path, attr);
             if (!err)