@@ -24,6 +24,25 @@ CHECK_hypfs_dirlistentry;
(DIRENTRY_NAME_OFF + \
ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
+struct hypfs_funcs hypfs_dir_funcs = {
+ .read = hypfs_read_dir,
+};
+struct hypfs_funcs hypfs_leaf_ro_funcs = {
+ .read = hypfs_read_leaf,
+};
+struct hypfs_funcs hypfs_leaf_wr_funcs = {
+ .read = hypfs_read_leaf,
+ .write = hypfs_write_leaf,
+};
+struct hypfs_funcs hypfs_bool_wr_funcs = {
+ .read = hypfs_read_leaf,
+ .write = hypfs_write_bool,
+};
+struct hypfs_funcs hypfs_custom_wr_funcs = {
+ .read = hypfs_read_leaf,
+ .write = hypfs_write_custom,
+};
+
static DEFINE_RWLOCK(hypfs_lock);
enum hypfs_lock_state {
hypfs_unlocked,
@@ -284,7 +303,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
guest_handle_add_offset(uaddr, sizeof(e));
- ret = entry->read(entry, uaddr);
+ ret = entry->funcs->read(entry, uaddr);
out:
return ret;
@@ -387,14 +406,14 @@ static int hypfs_write(struct hypfs_entry *entry,
{
struct hypfs_entry_leaf *l;
- if ( !entry->write )
+ if ( !entry->funcs->write )
return -EACCES;
ASSERT(entry->max_size);
l = container_of(entry, struct hypfs_entry_leaf, e);
- return entry->write(l, uaddr, ulen);
+ return entry->funcs->write(l, uaddr, ulen);
}
long do_hypfs_op(unsigned int cmd,
@@ -7,6 +7,20 @@
#include <public/hypfs.h>
struct hypfs_entry_leaf;
+struct hypfs_entry;
+
+struct hypfs_funcs {
+ int (*read)(const struct hypfs_entry *entry,
+ XEN_GUEST_HANDLE_PARAM(void) uaddr);
+ int (*write)(struct hypfs_entry_leaf *leaf,
+ XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+};
+
+extern struct hypfs_funcs hypfs_dir_funcs;
+extern struct hypfs_funcs hypfs_leaf_ro_funcs;
+extern struct hypfs_funcs hypfs_leaf_wr_funcs;
+extern struct hypfs_funcs hypfs_bool_wr_funcs;
+extern struct hypfs_funcs hypfs_custom_wr_funcs;
struct hypfs_entry {
unsigned short type;
@@ -15,10 +29,7 @@ struct hypfs_entry {
unsigned int max_size;
const char *name;
struct list_head list;
- int (*read)(const struct hypfs_entry *entry,
- XEN_GUEST_HANDLE_PARAM(void) uaddr);
- int (*write)(struct hypfs_entry_leaf *leaf,
- XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+ struct hypfs_funcs *funcs;
};
struct hypfs_entry_leaf {
@@ -42,7 +53,7 @@ struct hypfs_entry_dir {
.e.size = 0, \
.e.max_size = 0, \
.e.list = LIST_HEAD_INIT(var.e.list), \
- .e.read = hypfs_read_dir, \
+ .e.funcs = &hypfs_dir_funcs, \
.dirlist = LIST_HEAD_INIT(var.dirlist), \
}
@@ -52,7 +63,7 @@ struct hypfs_entry_dir {
.e.encoding = XEN_HYPFS_ENC_PLAIN, \
.e.name = (nam), \
.e.max_size = (msz), \
- .e.read = hypfs_read_leaf, \
+ .e.funcs = &hypfs_leaf_ro_funcs, \
}
/* Content and size need to be set via hypfs_string_set_reference(). */
@@ -72,35 +83,37 @@ static inline void hypfs_string_set_reference(struct hypfs_entry_leaf *leaf,
leaf->e.size = strlen(str) + 1;
}
-#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, wr) \
- struct hypfs_entry_leaf __read_mostly var = { \
- .e.type = (typ), \
- .e.encoding = XEN_HYPFS_ENC_PLAIN, \
- .e.name = (nam), \
- .e.size = sizeof(contvar), \
- .e.max_size = (wr) ? sizeof(contvar) : 0, \
- .e.read = hypfs_read_leaf, \
- .e.write = (wr), \
- .u.content = &(contvar), \
+#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, fn, wr) \
+ struct hypfs_entry_leaf __read_mostly var = { \
+ .e.type = (typ), \
+ .e.encoding = XEN_HYPFS_ENC_PLAIN, \
+ .e.name = (nam), \
+ .e.size = sizeof(contvar), \
+ .e.max_size = (wr) ? sizeof(contvar) : 0, \
+ .e.funcs = (fn), \
+ .u.content = &(contvar), \
}
#define HYPFS_UINT_INIT(var, nam, contvar) \
- HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, NULL)
+ HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
+ &hypfs_leaf_ro_funcs, 0)
#define HYPFS_UINT_INIT_WRITABLE(var, nam, contvar) \
HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
- hypfs_write_leaf)
+ &hypfs_leaf_wr_funcs, 1)
#define HYPFS_INT_INIT(var, nam, contvar) \
- HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, NULL)
+ HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, \
+ &hypfs_leaf_ro_funcs, 0)
#define HYPFS_INT_INIT_WRITABLE(var, nam, contvar) \
HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, \
- hypfs_write_leaf)
+ &hypfs_leaf_wr_funcs, 1)
#define HYPFS_BOOL_INIT(var, nam, contvar) \
- HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, NULL)
+ HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
+ &hypfs_leaf_ro_funcs, 0)
#define HYPFS_BOOL_INIT_WRITABLE(var, nam, contvar) \
HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
- hypfs_write_bool)
+ &hypfs_bool_wr_funcs, 1)
extern struct hypfs_entry_dir hypfs_root;
@@ -116,8 +116,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
{ .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
.hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
.hypfs.e.name = (nam), \
- .hypfs.e.read = hypfs_read_leaf, \
- .hypfs.e.write = hypfs_write_custom, \
+ .hypfs.e.funcs = &hypfs_custom_wr_funcs, \
.init_leaf = (initfunc), \
.func = (variable) }
#define boolean_runtime_only_param(nam, variable) \
@@ -127,8 +126,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
.hypfs.e.name = (nam), \
.hypfs.e.size = sizeof(variable), \
.hypfs.e.max_size = sizeof(variable), \
- .hypfs.e.read = hypfs_read_leaf, \
- .hypfs.e.write = hypfs_write_bool, \
+ .hypfs.e.funcs = &hypfs_bool_wr_funcs, \
.hypfs.u.content = &(variable) }
#define integer_runtime_only_param(nam, variable) \
__paramfs __parfs_##variable = \
@@ -137,8 +135,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
.hypfs.e.name = (nam), \
.hypfs.e.size = sizeof(variable), \
.hypfs.e.max_size = sizeof(variable), \
- .hypfs.e.read = hypfs_read_leaf, \
- .hypfs.e.write = hypfs_write_leaf, \
+ .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
.hypfs.u.content = &(variable) }
#define size_runtime_only_param(nam, variable) \
__paramfs __parfs_##variable = \
@@ -147,8 +144,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
.hypfs.e.name = (nam), \
.hypfs.e.size = sizeof(variable), \
.hypfs.e.max_size = sizeof(variable), \
- .hypfs.e.read = hypfs_read_leaf, \
- .hypfs.e.write = hypfs_write_leaf, \
+ .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
.hypfs.u.content = &(variable) }
#define string_runtime_only_param(nam, variable) \
__paramfs __parfs_##variable = \
@@ -157,8 +153,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
.hypfs.e.name = (nam), \
.hypfs.e.size = 0, \
.hypfs.e.max_size = sizeof(variable), \
- .hypfs.e.read = hypfs_read_leaf, \
- .hypfs.e.write = hypfs_write_leaf, \
+ .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
.hypfs.u.content = &(variable) }
#else
Move the function pointers currently stored in each hypfs node into a dedicated structure in order to save some space for each node. This will save even more space with additional callbacks added in future. Provide some standard function vectors. Signed-off-by: Juergen Gross <jgross@suse.com> --- xen/common/hypfs.c | 25 +++++++++++++++--- xen/include/xen/hypfs.h | 57 +++++++++++++++++++++++++---------------- xen/include/xen/param.h | 15 ++++------- 3 files changed, 62 insertions(+), 35 deletions(-)