How to best overload the fileops ?

Yuri yuri at rawbw.com
Wed Aug 21 18:37:41 UTC 2013


I am working on linux epoll functionality for linuxlator. It implements 
epoll through kqueue, but there is the need to overload fo_close 
function in fileops to free some memory.

There is no generic mechanism defined in the kernel sources allowing to 
do this, and it isn't desirable to do this in a hackish way. So I am 
suggesting this particular way, see code snippets below.
This approach is inspired by how C++ classes are sub-classed, with C++ 
class being similar to kernel file descriptor type and C++ vtbl being 
similar to fileops.

I am looking for an opinion(s) on these questions:
* Is such code is acceptable for kernel?
* Does it look too ugly?
* Any suggestions on how to improve it?

As the system develops, other places may require to do such overloading 
too, so this approach can be reused.

Thank you,
Yuri


*** In sys/file.h add these macros (they define how overloading is done):
#define FDCLASS_DEFINE(cls)                        \
     struct fileops* fdcls_##cls##_fileops(void);            \
     struct fileops* fdcls_##cls##_fileops(void) {            \
         return (&cls##ops);                    \
     }
#define FDCLASS_INHERIT(cls, cls_parent, cls_init_func)            \
     extern struct fileops* fdcls_##cls_parent##_fileops(void);    \
     static void cls##_fdcls_init(void *dummy __unused) {        \
         cls##ops = *fdcls_##cls_parent##_fileops();        \
         cls_init_func();                    \
     }                                \
     SYSINIT(cls##_fdcls, SI_SUB_PSEUDO, SI_ORDER_ANY, cls##_fdcls_init, 
NULL);

*** In the end of kern/kern_event.c add the line exposing kqueue's fileops:
FDCLASS_DEFINE(kqueue)

*** In linux_epoll.c add code that would initialize epoll fileops with 
the base class fileops:
/* overload kqueue fileops */
static struct fileops epollops;
static struct fileops epollops_base;
static void
epoll_init(void) {
     /* overload only fo_close operation */
     epollops_base = epollops;
     epollops.fo_close = epoll_close;
}
FDCLASS_INHERIT(epoll, kqueue, epoll_init)




More information about the freebsd-current mailing list