Re: 2.1.118 Tons of oopes

Alexander Kjeldaas (astor@guardian.no)
Tue, 1 Sep 1998 16:38:37 +0200


On Mon, Aug 31, 1998 at 08:32:38PM +0000, Linus Torvalds wrote:
>
> No, some functions are NULL quite normally, simply because it's
> something that the low-level driver or FS doesn't want to bother with.
>
> For example, networked filesystems often need more hooks to tell the
> system that "ok, something changed", while a local filesystem doesn't
> need that and can just let the VFS layer do whatever it wants to do
> without having to worry about anybody else doing something over the
> network.
>
> As such, NULL pointers can often be the _default_ rather than being a
> sign of error cases. And the NULL case may be the fast and
> timing-sensitive one. This is true of the dcache hashing stuff, for
> example, where there are special (and slow) routines for certain
> filesystems that want to do stupid name mangling.
>

It isn't difficult to put all the policy in one place using
macros. Something like (not tested of course):

#define null_checked(struc,op,args...) \
extern inline int struc##_##op##_invoke(struct *struc, args)\
{ \
return struc->op ? struc->op(args) : -EWHAT?; \
} \
\
extern inline struc##_##op##_replace(struct *struc) \
{ \
}

#define defl_checked(struc,op,args...) \
extern inline int struc##_##op##_invoke(struct *struc, args)\
{ \
return struc->op(args); \
} \
\
extern inline struc##_##op##_replace(struct *struc) \
{ \
if (!struc->op) \
struc->op = default_##struc##_##op; \
}

struct inode_operations {
struct file_operations * default_file_ops;
int (*create) (struct inode *,struct dentry *,int);
int (*lookup) (struct inode *,struct dentry *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,int);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,int,int);
...
}

null_checked(inode_operations, create, struct inode *,struct dentry *,int)
null_checked(inode_operations, lookup, struct inode *,struct dentry *)
defl_checked(inode_operations, mknod, struct inode *,struct dentry *,int,int)

...

You would use the xxx_replace routines to replace appropriate
NULL-entries during registering of filesystems, and the xxx_invoke
routines to invoke functions. Of course, to be efficient, this relies
on a non-braindead compiler.

Btw, this is backwards compatible.

astor

-- 
 Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway
 http://www.guardian.no/

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html