* Make it compile on 2.4.19.
- * Add dummy fsync operation (write file failed on xemacs & vi)
+ * Add fsync operation (write file failed on xemacs & vi)
2003-12-12 David McNab <david@rebirthing.co.nz>
read: xmp_read,
write: xmp_write,
statfs: xmp_statfs,
- release: NULL
+ release: NULL,
+ fsync: NULL
+
};
int main(int argc, char *argv[])
read: hello_read,
write: NULL,
statfs: NULL,
- release: NULL
+ release: NULL,
+ fsync: NULL
};
int main(int argc, char *argv[])
#include <time.h>
#include <errno.h>
-#define UNUSED __attribute__((unused))
+#define UNUSED(x) x __attribute__((unused))
static int null_getattr(const char *path, struct stat *stbuf)
{
read: null_read,
write: null_write,
statfs: null_statfs,
- release: NULL
+ release: NULL,
+ fsync: NULL
};
int main(int argc, char *argv[])
* 2) all memory mappings unmapped
* This call need only be implemented if this information is required,
* otherwise set this function to NULL.
- *
+ *
+ * - fsync() has a boolean 'datasync' parameter which if TRUE then do
+ * an fdatasync() operation.
*/
struct fuse_operations {
int (*getattr) (const char *, struct stat *);
int (*write) (const char *, const char *, size_t, off_t);
int (*statfs) (struct fuse_statfs *);
int (*release) (const char *, int);
+ int (*fsync) (const char *, int);
};
/** Extra context that may be needed by some filesystems */
FUSE_WRITE = 16,
FUSE_STATFS = 17,
FUSE_RELEASE = 18, /* no reply */
- FUSE_INVALIDATE = 19 /* user initiated */
+ FUSE_INVALIDATE = 19, /* user initiated */
+ FUSE_FSYNC = 20
};
/* Conservative buffer size for the client */
struct fuse_kstatfs st;
};
+struct fuse_fsync_in {
+ int datasync;
+};
+
struct fuse_in_header {
int unique;
enum fuse_opcode opcode;
static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
{
- return 0;
+ struct inode *inode = de->d_inode;
+ struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_in in = FUSE_IN_INIT;
+ struct fuse_out out = FUSE_OUT_INIT;
+ struct fuse_fsync_in inarg;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.datasync = datasync;
+
+ in.h.opcode = FUSE_FSYNC;
+ in.h.ino = inode->i_ino;
+ in.numargs = 1;
+ in.args[0].size = sizeof(inarg);
+ in.args[0].value = &inarg;
+ request_send(fc, &in, &out);
+ return out.h.error;
}
static int fuse_readpage(struct file *file, struct page *page)
case FUSE_WRITE: return "WRITE";
case FUSE_STATFS: return "STATFS";
case FUSE_RELEASE: return "RELEASE";
+ case FUSE_FSYNC: return "FSYNC";
default: return "???";
}
}
send_reply(f, in, res, &arg, sizeof(arg));
}
+static void do_fsync(struct fuse *f, struct fuse_in_header *in,
+ struct fuse_fsync_in *inarg)
+{
+ int res;
+ char *path;
+
+ res = -ENOENT;
+ path = get_path(f, in->ino);
+ if(path != NULL) {
+ /* fsync is not mandatory, so don't return ENOSYS */
+ res = 0;
+ if(f->op.fsync)
+ res = f->op.fsync(path, inarg->datasync);
+ free(path);
+ }
+ send_reply(f, in, res, NULL, 0);
+}
+
static void free_cmd(struct fuse_cmd *cmd)
{
free(cmd->buf);
do_statfs(f, in);
break;
+ case FUSE_FSYNC:
+ do_fsync(f, in, (struct fuse_fsync_in *) inarg);
+ break;
+
default:
send_reply(f, in, -ENOSYS, NULL, 0);
}