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

2007-04-16 Thread Randy Dunlap

Andreas Gruenbacher wrote:

On Monday 16 April 2007 18:42, Randy Dunlap wrote:

Please don't use the kernel-doc begin-marker "/**" when the comment block
isn't in kernel-doc format.


Sigh, kernel-doc should improve things, not get in the way ...


Well, I see it as sort of a language that is embedded in C source code.

But what are you suggesting?

--
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2007-04-16 Thread Andreas Gruenbacher
On Monday 16 April 2007 18:42, Randy Dunlap wrote:
> Please don't use the kernel-doc begin-marker "/**" when the comment block
> isn't in kernel-doc format.

Sigh, kernel-doc should improve things, not get in the way ...
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2007-04-16 Thread Randy Dunlap
On Mon, 16 Apr 2007 18:29:20 +0200 Andreas Gruenbacher wrote:

> Here is a patch with request for comment.
> 
> --- a/include/linux/namei.h
> +++ b/include/linux/namei.h
> @@ -14,21 +14,39 @@ struct open_intent {
>  
>  enum { MAX_NESTED_LINKS = 8 };
>  
> +/**

Please don't use the kernel-doc begin-marker "/**" when the comment block
isn't in kernel-doc format.

> + * Fields shared between nameidata and nameidata2 -- nameidata2 could
> + * be embedded in nameidata, but then the vfs code would become
> + * cluttered with dereferences.
> + */
> +#define __NAMEIDATA2 \
> + struct dentry   *dentry;\
> + struct vfsmount *mnt;   \
> + unsigned intflags;  \
> + \
> + union { \
> + struct open_intent open;\
> + } intent;
> +

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2007-04-16 Thread Christoph Hellwig
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 intflags;  \
> + \
> + 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..
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2007-04-16 Thread Andreas Gruenbacher
Here is a patch with request for comment.

The create, lookup, and permission inode operations are all passed a full
nameidata.  This is unfortunate because in nfsd and the mqueue filesystem we
must instantiate a struct nameidata, but cannot provide all of the same
information of a regular lookup.  The unused fields take up space on the
stack, but more importantly, it is not obvious which fields have meaningful
values and which don't, and so things might easily break.

This patch introduces struct nameidata2 with only the fields that make sense
independent of an actual lookup, and uses that struct in those places where a
full nameidata is not needed.

The entire patch is a little big so I'm only including the key parts here. The
complete version is here:

 
http://forgeftp.novell.com/apparmor/LKML_Submission-April_07/split-up-nameidata.diff

Signed-off-by: Andreas Gruenbacher <[EMAIL PROTECTED]>

--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -14,21 +14,39 @@ struct open_intent {
 
 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.
+ */
+#define __NAMEIDATA2   \
+   struct dentry   *dentry;\
+   struct vfsmount *mnt;   \
+   unsigned intflags;  \
+   \
+   union { \
+   struct open_intent open;\
+   } intent;
+
 struct nameidata {
-   struct dentry   *dentry;
-   struct vfsmount *mnt;
+   __NAMEIDATA2
struct qstr last;
-   unsigned intflags;
int last_type;
unsigneddepth;
char *saved_names[MAX_NESTED_LINKS + 1];
+};
 
-   /* Intent data */
-   union {
-   struct open_intent open;
-   } intent;
+struct nameidata2 {
+   __NAMEIDATA2
 };
 
+#undef __NAMEIDATA2
+
+static inline struct nameidata2 *ND2(struct nameidata *nd)
+{
+   return container_of(&nd->dentry, struct nameidata2, dentry);
+}
+
 struct path {
struct vfsmount *mnt;
struct dentry *dentry;
@@ -76,10 +94,9 @@ extern void path_release_on_umount(struc
 
 extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, 
struct nameidata *nd, int open_flags);
 extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, 
struct nameidata *, int open_flags);
-extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct 
dentry *dentry,
-   int (*open)(struct inode *, struct file *));
+extern struct file *lookup_instantiate_filp(struct nameidata2 *nd, struct 
dentry *dentry, int (*open)(struct inode *, struct file *));
 extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
-extern void release_open_intent(struct nameidata *);
+extern void release_open_intent(struct nameidata2 *);
 
 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
 
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -225,7 +225,7 @@ int generic_permission(struct inode *ino
return -EACCES;
 }
 
-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.
  */
-int vfs_permission(struct nameidata *nd, int mask)
+int vfs_permission(struct nameidata2 *nd, int mask)
 {
return permission(nd->dentry->d_inode, mask, nd);
 }
@@ -366,7 +366,7 @@ void path_release_on_umount(struct namei
  * release_open_intent - free up open intent resources
  * @nd: pointer to nameidata
  */
-void release_open_intent(struct nameidata *nd)
+void release_open_intent(struct nameidata2 *nd)
 {
if (nd->intent.open.file->f_path.dentry == NULL)
put_filp(nd->intent.open.file);
@@ -377,7 +377,7 @@ void release_open_intent(struct nameidat
 static inline struct dentry *
 do_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-   int status = dentry->d_op->d_revalidate(dentry, nd);
+   int status = dentry->d_op->d_revalidate(dentry, ND2(nd));
if (unlikely(status <= 0)) {
/*
 * The dentry failed validation.
@@ -455,7 +455,7 @@ static int exec_permission_lite(struct i
 
return -EACCES;
 ok:
-   return security_inode_permission(inode, MAY_EXEC, nd);
+   return security_inode_permission(inode, MAY_EXEC, ND2(nd));
 }
 
 /*
@@ -491,7 +491,7 @@ static struct dentry * real_lookup(struc
struct dentry * dentry = d_alloc(parent, name);
result = ERR_PTR(-ENOMEM);
if (dentry) {
-   result = dir->i_op->lo