diff --git a/servers/mfs/misc.c b/servers/mfs/misc.c index 6b0a79d6d..b4af8d98e 100644 --- a/servers/mfs/misc.c +++ b/servers/mfs/misc.c @@ -39,7 +39,7 @@ int fs_flush() * to disk. */ dev_t dev = fs_m_in.REQ_DEV; - if(dev == fs_dev) return(EBUSY); + if(dev == fs_dev && lmfs_bufs_in_use() > 0) return(EBUSY); lmfs_flushall(); lmfs_invalidate(dev); diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index d9548cbda..7ab76b072 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -223,6 +223,24 @@ int do_fcntl(void) fl = (O_NOSIGPIPE); f->filp_flags = (f->filp_flags & ~fl) | (fcntl_argx & fl); break; + case F_FLUSH_FS_CACHE: + { + struct vnode *vn = f->filp_vno; + mode_t mode = f->filp_vno->v_mode; + if (!super_user) { + r = EPERM; + } else if (S_ISBLK(mode)) { + /* Block device; flush corresponding device blocks. */ + r = req_flush(vn->v_bfs_e, vn->v_sdev); + } else if (S_ISREG(mode) || S_ISDIR(mode)) { + /* Directory or regular file; flush hosting FS blocks. */ + r = req_flush(vn->v_fs_e, vn->v_dev); + } else { + /* Remaining cases.. Meaning unclear. */ + r = ENODEV; + } + break; + } default: r = EINVAL; } diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 3c96ad224..6caaf290e 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -326,6 +326,7 @@ __END_DECLS #if defined(__minix) #define F_FREESP 100 +#define F_FLUSH_FS_CACHE 101 /* invalidate cache on associated FS */ #endif /* defined(__minix) */ #endif /* !_SYS_FCNTL_H_ */