VFS: add F_FLUSH_FS_CACHE fcntl

This fcntl requests all cached blocks associated with the minor device
number associated with the regular file are invalidated. If the file
is a block special, invalidate the blocks associated with that minor
device instead.

This is to be used for a test that tests unmapped file-mapped memory
ranges whose blocks are not in the cache and therefore must be fetched
from a FS.

Change-Id: Ide914b2e88413aa90bd731ae587ca06fa5f13ebc
This commit is contained in:
Ben Gras 2014-02-28 16:26:13 +01:00 committed by Lionel Sambuc
parent 565f13088f
commit 58b8ff5ffa
3 changed files with 20 additions and 1 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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_ */