From cc1e31d103c5c5a00b696f30286c97287ce58f18 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@cloudius-systems.com>
Date: Tue, 3 Dec 2013 15:02:41 +0200
Subject: [PATCH] file: add virtual functions corresponding to f_ops

The default is to dispatch directly to the corresponding member of f_ops,
but that can be overridden.

The fo_*() functions are redirected to dispatch via the virtual functions.

Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
---
 fs/vfs/kern_descrip.cc | 56 ++++++++++++++++++++++++++++++++++++------
 include/osv/file.h     | 12 ++++++++-
 2 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/fs/vfs/kern_descrip.cc b/fs/vfs/kern_descrip.cc
index 3b9892e4b..333184cc6 100644
--- a/fs/vfs/kern_descrip.cc
+++ b/fs/vfs/kern_descrip.cc
@@ -166,6 +166,46 @@ file::file(unsigned flags, filetype_t type, void *opaque,
     fo_init(fp);
 }
 
+int file::read(struct uio *uio, int flags)
+{
+    return f_ops->fo_read(this, uio, flags);
+}
+
+int file::write(struct uio *uio, int flags)
+{
+    return f_ops->fo_write(this, uio, flags);
+}
+
+int file::truncate(off_t len)
+{
+    return f_ops->fo_truncate(this, len);
+}
+
+int file::ioctl(u_long com, void *data)
+{
+    return f_ops->fo_ioctl(this, com, data);
+}
+
+int file::poll(int events)
+{
+    return f_ops->fo_poll(this, events);
+}
+
+int file::stat(struct stat* buf)
+{
+    return f_ops->fo_stat(this, buf);
+}
+
+int file::close()
+{
+    return f_ops->fo_close(this);
+}
+
+int file::chmod(mode_t mode)
+{
+    return f_ops->fo_chmod(this, mode);
+}
+
 void fhold(struct file* fp)
 {
     __sync_fetch_and_add(&fp->f_count, 1);
@@ -279,49 +319,49 @@ fo_init(struct file *fp)
  int
 fo_read(struct file *fp, struct uio *uio, int flags)
 {
-        return fp->f_ops->fo_read(fp, uio, flags);
+        return fp->read(uio, flags);
 }
 
  int
 fo_write(struct file *fp, struct uio *uio, int flags)
 {
-        return fp->f_ops->fo_write(fp, uio, flags);
+        return fp->write(uio, flags);
 }
 
  int
 fo_truncate(struct file *fp, off_t length)
 {
-        return fp->f_ops->fo_truncate(fp, length);
+        return fp->truncate(length);
 }
 
  int
 fo_ioctl(struct file *fp, u_long com, void *data)
 {
-        return fp->f_ops->fo_ioctl(fp, com, data);
+        return fp->ioctl(com, data);
 }
 
  int
 fo_poll(struct file *fp, int events)
 {
-        return fp->f_ops->fo_poll(fp, events);
+        return fp->poll(events);
 }
 
  int
 fo_stat(struct file *fp, struct stat *sb)
 {
-        return fp->f_ops->fo_stat(fp, sb);
+        return fp->stat(sb);
 }
 
  int
 fo_close(struct file *fp)
 {
-        return fp->f_ops->fo_close(fp);
+        return fp->close();
 }
 
  int
 fo_chmod(struct file *fp, mode_t mode)
 {
-        return fp->f_ops->fo_chmod(fp, mode);
+        return fp->chmod(mode);
 }
 
 bool is_nonblock(struct file *f)
diff --git a/include/osv/file.h b/include/osv/file.h
index 7e7a9cc62..766f9fa3b 100755
--- a/include/osv/file.h
+++ b/include/osv/file.h
@@ -76,8 +76,18 @@ struct file;
 struct file {
 	file(unsigned flags, filetype_t type, void *opaque,
 		struct fileops *ops);
-	~file();
+	virtual ~file();
 	void operator delete(void *p) { osv::rcu_dispose(p); }
+
+	virtual int read(struct uio *uio, int flags);
+	virtual int write(struct uio *uio, int flags);
+	virtual int truncate(off_t len);
+	virtual int ioctl(u_long com, void *data);
+	virtual int poll(int events);
+	virtual int stat(struct stat* buf);
+	virtual int close();
+	virtual int chmod(mode_t mode);
+
 	int		f_flags;	/* open flags */
 	int		f_count;	/* reference count, see below */
 	off_t		f_offset = 0;	/* current position in file */
-- 
GitLab