diff --git a/protocol.md b/protocol.md index 6cedbbec..9cc333c6 100644 --- a/protocol.md +++ b/protocol.md @@ -353,7 +353,7 @@ At most count bytes will be returned in data. If count is not zero in the respon #### fsync - flush any cached data to disk ``` -size[4] Tfsync tag[2] fid[4] +size[4] Tfsync tag[2] fid[4] datasync[4] size[4] Rfsync tag[2] ``` fsync tells the server to flush any cached data associated with fid, previously opened with lopen. diff --git a/src/daemon/ioctx.c b/src/daemon/ioctx.c index c5ba1d4f..09529251 100644 --- a/src/daemon/ioctx.c +++ b/src/daemon/ioctx.c @@ -348,8 +348,10 @@ ioctx_readdir(IOCtx ioctx, long *offset) } int -ioctx_fsync(IOCtx ioctx) +ioctx_fsync(IOCtx ioctx, int datasync) { + if (datasync) + return fdatasync (ioctx->fd); return fsync (ioctx->fd); } diff --git a/src/daemon/ioctx.h b/src/daemon/ioctx.h index 0b8a24b6..74e08ccf 100644 --- a/src/daemon/ioctx.h +++ b/src/daemon/ioctx.h @@ -27,7 +27,7 @@ int ioctx_pwrite (IOCtx ioctx, const void *buf, size_t count, off_t offset); struct dirent *ioctx_readdir(IOCtx ioctx, long *new_offset); void ioctx_rewinddir (IOCtx ioctx); void ioctx_seekdir (IOCtx ioctx, long offset); -int ioctx_fsync (IOCtx ioctx); +int ioctx_fsync (IOCtx ioctx, int datasync); int ioctx_flock (IOCtx ioctx, int operation); int ioctx_testlock (IOCtx ioctx, int operation); diff --git a/src/daemon/ops.c b/src/daemon/ops.c index 9b07f84c..f3de61d0 100644 --- a/src/daemon/ops.c +++ b/src/daemon/ops.c @@ -130,7 +130,7 @@ Npfcall *diod_getattr(Npfid *fid, u64 request_mask); Npfcall *diod_setattr (Npfid *fid, u32 valid, u32 mode, u32 uid, u32 gid, u64 size, u64 atime_sec, u64 atime_nsec, u64 mtime_sec, u64 mtime_nsec); Npfcall *diod_readdir(Npfid *fid, u64 offset, u32 count, Npreq *req); -Npfcall *diod_fsync (Npfid *fid); +Npfcall *diod_fsync (Npfid *fid, u32 datasync); Npfcall *diod_lock (Npfid *fid, u8 type, u32 flags, u64 start, u64 length, u32 proc_id, Npstr *client_id); Npfcall *diod_getlock (Npfid *fid, u8 type, u64 start, u64 length, @@ -1226,7 +1226,7 @@ diod_readdir(Npfid *fid, u64 offset, u32 count, Npreq *req) } Npfcall* -diod_fsync (Npfid *fid) +diod_fsync (Npfid *fid, u32 datasync) { Fid *f = fid->aux; Npfcall *ret; @@ -1236,7 +1236,7 @@ diod_fsync (Npfid *fid) np_uerror (EBADF); goto error; } - if (ioctx_fsync (f->ioctx) < 0) { + if (ioctx_fsync (f->ioctx, datasync) < 0) { np_uerror (errno); goto error_quiet; } diff --git a/src/libnpfs/9p.h b/src/libnpfs/9p.h index 4d20c793..7912c642 100644 --- a/src/libnpfs/9p.h +++ b/src/libnpfs/9p.h @@ -445,6 +445,7 @@ struct p9_rreaddir { }; struct p9_tfsync { u32 fid; + u32 datasync; }; struct p9_rfsync { }; diff --git a/src/libnpfs/fcall.c b/src/libnpfs/fcall.c index 8eae19de..0e1f4f99 100644 --- a/src/libnpfs/fcall.c +++ b/src/libnpfs/fcall.c @@ -1045,7 +1045,7 @@ np_fsync(Npreq *req, Npfcall *tc) np_uerror (ENOSYS); goto done; } - rc = (*req->conn->srv->fsync)(fid); + rc = (*req->conn->srv->fsync)(fid, tc->u.tfsync.datasync); } done: return rc; diff --git a/src/libnpfs/np.c b/src/libnpfs/np.c index b1bf42d2..267e2f04 100644 --- a/src/libnpfs/np.c +++ b/src/libnpfs/np.c @@ -1105,9 +1105,9 @@ np_create_treaddir(u32 fid, u64 offset, u32 count) } Npfcall * -np_create_tfsync(u32 fid) +np_create_tfsync(u32 fid, u32 datasync) { - int size = sizeof(u32); + int size = sizeof(u32) + sizeof(u32); struct cbuf buffer; struct cbuf *bufp = &buffer; Npfcall *fc; @@ -1115,6 +1115,7 @@ np_create_tfsync(u32 fid) if (!(fc = np_create_common(bufp, size, P9_TFSYNC))) return NULL; buf_put_int32(bufp, fid, &fc->u.tfsync.fid); + buf_put_int32(bufp, datasync, &fc->u.tfsync.datasync); return np_post_check(fc, bufp); } @@ -1593,6 +1594,7 @@ np_deserialize(Npfcall *fc) break; case P9_TFSYNC: fc->u.tfsync.fid = buf_get_int32(bufp); + fc->u.tfsync.datasync = buf_get_int32(bufp); break; case P9_RFSYNC: break; diff --git a/src/libnpfs/npfs.h b/src/libnpfs/npfs.h index 8a399866..eb78cc50 100644 --- a/src/libnpfs/npfs.h +++ b/src/libnpfs/npfs.h @@ -309,7 +309,7 @@ struct Npsrv { Npfcall* (*xattrwalk)(Npfid *, Npfid *, Npstr *); Npfcall* (*xattrcreate)(Npfid *, Npstr *, u64, u32); Npfcall* (*readdir)(Npfid *, u64, u32, Npreq *); - Npfcall* (*fsync)(Npfid *); + Npfcall* (*fsync)(Npfid *, u32); Npfcall* (*llock)(Npfid *, u8, u32, u64, u64, u32, Npstr *); Npfcall* (*getlock)(Npfid *, u8 type, u64, u64, u32, Npstr *); Npfcall* (*link)(Npfid *, Npfid *, Npstr *); @@ -472,7 +472,7 @@ Npfcall *np_create_rxattrcreate(void); Npfcall *np_create_treaddir(u32 fid, u64 offset, u32 count); Npfcall *np_create_rreaddir(u32 count); void np_finalize_rreaddir(Npfcall *fc, u32 count); -Npfcall *np_create_tfsync(u32 fid); +Npfcall *np_create_tfsync(u32 fid, u32 datasync); Npfcall *np_create_rfsync(void); Npfcall * np_create_tlock(u32 fid, u8 type, u32 flags, u64 start, u64 length, u32 proc_id, char *client_id); diff --git a/tests/misc/t07.exp b/tests/misc/t07.exp index cd87af7a..ba48fcf0 100644 --- a/tests/misc/t07.exp +++ b/tests/misc/t07.exp @@ -52,7 +52,7 @@ test_rreaddir(41): 92 P9_RREADDIR tag 42 count 81 01020000 00030000 00000000 00000000 00000000 00010300 61626304 05000000 06000000 00000000 32000000 00000000 02030064 65660708 00000009 00000000 -test_tfsync(50): 11 +test_tfsync(50): 15 P9_TFSYNC tag 42 fid 1 test_rfsync(51): 7 P9_RFSYNC tag 42 diff --git a/tests/misc/tserialize.c b/tests/misc/tserialize.c index d1aab1ea..571fe7b5 100644 --- a/tests/misc/tserialize.c +++ b/tests/misc/tserialize.c @@ -644,11 +644,12 @@ test_tfsync (void) { Npfcall *fc, *fc2; - if (!(fc = np_create_tfsync(1))) + if (!(fc = np_create_tfsync(1, 42))) msg_exit ("out of memory"); fc2 = _rcv_buf (fc, P9_TFSYNC, __FUNCTION__); - assert (fc->u.tfsync.fid == fc2->u.treaddir.fid); + assert (fc->u.tfsync.fid == fc2->u.tfsync.fid); + assert (fc->u.tfsync.datasync == fc2->u.tfsync.datasync); free (fc); free (fc2); diff --git a/tests/user/tflush.c b/tests/user/tflush.c index aae0d6f4..d4b1970e 100644 --- a/tests/user/tflush.c +++ b/tests/user/tflush.c @@ -93,7 +93,8 @@ _flush_series (Npcfsys *fs, Npcfid *root) err_exit ("open)"); for (i = 0; i < 100; i++) { - if (!(tc = np_create_tfsync (f->fid))) + // alternate with datasync set to 1 or 0 + if (!(tc = np_create_tfsync (f->fid, i % 2 == 0 ? 0 : 1))) msg_exit ("out of memory"); flushtag = tag = npc_get_id(fs->tagpool); np_set_tag(tc, tag); @@ -115,7 +116,7 @@ _flush_series (Npcfsys *fs, Npcfid *root) msg ("sent 1 Tflush"); for (i = 0; i < 100; i++) { - if (!(tc = np_create_tfsync (f->fid))) + if (!(tc = np_create_tfsync (f->fid, i % 2 == 0 ? 0 : 1))) msg_exit ("out of memory"); tag = npc_get_id(fs->tagpool); np_set_tag(tc, tag);