From owner-freebsd-current@FreeBSD.ORG Wed Aug 21 18:37:41 2013 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 4CEF65BB; Wed, 21 Aug 2013 18:37:41 +0000 (UTC) (envelope-from yuri@rawbw.com) Received: from shell0.rawbw.com (shell0.rawbw.com [198.144.192.45]) by mx1.freebsd.org (Postfix) with ESMTP id 3532F20A0; Wed, 21 Aug 2013 18:37:41 +0000 (UTC) Received: from eagle.yuri.org (stunnel@localhost [127.0.0.1]) (authenticated bits=0) by shell0.rawbw.com (8.14.4/8.14.4) with ESMTP id r7LIbedS001911; Wed, 21 Aug 2013 11:37:40 -0700 (PDT) (envelope-from yuri@rawbw.com) Message-ID: <521508F4.6030502@rawbw.com> Date: Wed, 21 Aug 2013 11:37:40 -0700 From: Yuri User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:17.0) Gecko/20130628 Thunderbird/17.0.7 MIME-Version: 1.0 To: current@freebsd.org Subject: How to best overload the fileops ? Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Roman Divacky X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Aug 2013 18:37:41 -0000 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)