Re: [nameidata 2/2] Pass no useless nameidata to the create, lookup, and permission IOPs

Christoph Hellwig
2007-04-16T16:39:58Z

On Mon, Apr 16, 2007 at 06:29:20PM +0200, Andreas Gruenbacher wrote:
> enum { MAX_NESTED_LINKS = 8 };
>
> +/**
> + * Fields shared between nameidata and nameidata2 -- nameidata2 could
> + * be embedded in nameidata, but then the vfs code would become
> + * cluttered with dereferences.

you could use an anonymous struct embedeed in both.

> + */
> +#define __NAMEIDATA2 \
> + struct dentry *dentry; \
> + struct vfsmount *mnt; \
> + unsigned int flags; \
> + \
> + union { \
> + struct open_intent open; \
> + } intent;

Or better just pass argument directly. We really
should only pass down the the dentry and the
intent to the filesystem. The filesystem has
not business looking at mnt in the operations,
and the relevant bits of flags (mostly whether it's
O_EXCLUSIVE) should be stored in the intent, because
that's the only way it should be used.

Doing it that way also allows to fix some braindead calling conventions
like this one:

> -int permission(struct inode *inode, int mask, struct nameidata *nd)
> +int permission(struct inode *inode, int mask, struct nameidata2 *nd)
> {
> umode_t mode = inode->i_mode;
> int retval, submask;
> @@ -278,7 +278,7 @@ int permission(struct inode *inode, int
> * for filesystem access without changing the "normal" uids which
> * are used for other things.
> */

> static inline struct dentry *
> do_revalidate(struct dentry *dentry, struct nameidata *nd)

Or this one.

> - result = dir->i_op->lookup(dir, dentry, nd);
> + result = dir->i_op->lookup(dir, dentry, ND2(nd));

or this one.

etc..