Lustre VFS patches for 2.6
Subsystems (2)
PATCH 3/9 Lustre VFS patches for 2.6
This patch adds intent opertion and intent release callback to struct open_intent, so that interested code
can know what is about to be performed. Also magic is added to ease tracing of use of uninitialized intents. Initialize intents on usage, fill in correct intent operation. Make wrappers that initialize intents to some sane values for intent-unaware code and old-API compatibility.
fs/exec.c | 10 ++++--- fs/namei.c | 69 ++++++++++++++++++++++++++++++++++++++++++++------ fs/namespace.c | 1 fs/open.c | 28 +++++++++++++++----- fs/stat.c | 10 +++++-- fs/xattr.c | 12 +++++--- include/linux/fs.h | 2 + include/linux/namei.h | 34 ++++++++++++++++++++++++ 8 files changed, 141 insertions(+), 25 deletions(-)
include/linux/namei.h +34 -0
@@ -2,14 +2,40 @@#define _LINUX_NAMEI_H#include <linux/linkage.h> +#include <linux/string.h> struct vfsmount ; +/* intent opcodes */ +#define IT_OPEN (1) +#define IT_CREAT (1<<1) +#define IT_READDIR (1<<2) +#define IT_GETATTR (1<<3) +#define IT_LOOKUP (1<<4) +#define IT_UNLINK (1<<5) +#define IT_TRUNC (1<<6) +#define IT_GETXATTR (1<<7) + +#define INTENT_MAGIC 0x19620323 +struct open_intent { +int magic; +int op; +void (*op_release)(struct open_intent *);int flags;int create_mode; +union { +void *fs_data;/* FS-specific intent data */ + } d; }; +static inline void intent_init (struct open_intent *it,int op) +{ +memset (it,0 ,sizeof (*it)); + it->magic =INTENT_MAGIC ; + it->op = op; +} +enum {MAX_NESTED_LINKS =5 };struct nameidata {
@@ -53,14 +76,22 @@#define LOOKUP_ACCESS (0x0400)extern int FASTCALL (__user_walk (const char __user *,unsigned ,struct nameidata *)); +extern int FASTCALL (__user_walk_it (const char __user *,unsigned ,struct nameidata *));#define user_path_walk (name,nd) \ __user_walk(name, LOOKUP_FOLLOW, nd) +#define user_path_walk_it (name,nd) \ + __user_walk_it(name, LOOKUP_FOLLOW, nd)#define user_path_walk_link (name,nd) \ __user_walk(name, 0, nd) +#define user_path_walk_link_it (name,nd) \ + __user_walk_it(name, 0, nd)extern int FASTCALL (path_lookup (const char *,unsigned ,struct nameidata *)); +extern int FASTCALL (path_lookup_it (const char *,unsigned ,struct nameidata *));extern int FASTCALL (path_walk (const char *,struct nameidata *)); +extern int FASTCALL (path_walk_it (const char *,struct nameidata *));extern int FASTCALL (link_path_walk (const char *,struct nameidata *));extern void path_release (struct nameidata *); +extern void intent_release (struct open_intent *);extern struct dentry *lookup_one_len (const char *,struct dentry *,int );extern struct dentry *lookup_hash (struct qstr *,struct dentry *);
include/linux/fs.h +2 -0
@@ -583,6 +583,7 @@spinlock_t f_ep_lock;#endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; +struct open_intent *f_it; };extern spinlock_t files_lock;#define file_list_lock () spin_lock(&files_lock);
@@ -1201,6 +1202,7 @@extern int do_truncate (struct dentry *,loff_t start);extern struct file *filp_open (const char *,int ,int );extern struct file *dentry_open (struct dentry *,struct vfsmount *,int ); +extern struct file *dentry_open_it (struct dentry *,struct vfsmount *,int ,struct open_intent *);extern int filp_close (struct file *,fl_owner_t id);extern char *getname (const char __user *);
fs/namei.c +61 -8
173 lines not on this page · raw message
fs/open.c +22 -6
@@ -216,11 +216,12 @@struct inode * inode;int error; +intent_init (&nd.intent.open,IT_GETATTR ); error = -EINVAL ;if (length <0 )/* sorry, but loff_t says... */ goto out; - error =user_path_walk (path, &nd); + error =user_path_walk_it (path, &nd);if (error) goto out; inode = nd.dentry->d_inode;
@@ -475,6 +476,7 @@kernel_cap_t old_cap;int res; +intent_init (&nd.intent.open,IT_GETATTR );if (mode & ~S_IRWXO )/* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL ;
@@ -498,7 +500,7 @@else current->cap_effective = current->cap_permitted; - res =__user_walk (filename,LOOKUP_FOLLOW |LOOKUP_ACCESS , &nd); + res =__user_walk_it (filename,LOOKUP_FOLLOW |LOOKUP_ACCESS , &nd);if (!res) { res =permission (nd.dentry->d_inode, mode, &nd);/* SuS v2 requires we report a read only fs too */
@@ -520,7 +522,8 @@struct nameidata nd;int error; - error =__user_walk (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &nd); +intent_init (&nd.intent.open,IT_GETATTR ); + error =__user_walk_it (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &nd);if (error) goto out;
@@ -571,7 +574,8 @@struct nameidata nd;int error; - error =__user_walk (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY |LOOKUP_NOALT , &nd); +intent_init (&nd.intent.open,IT_GETATTR ); + error =__user_walk_it (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY |LOOKUP_NOALT , &nd);if (error) goto out;
@@ -754,6 +758,7 @@ {int namei_flags, error;struct nameidata nd; +intent_init (&nd.intent.open,IT_OPEN ); namei_flags = flags;if ((namei_flags+1 ) &O_ACCMODE )
@@ -763,14 +768,14 @@ error =open_namei (filename, namei_flags, mode, &nd);if (!error) -return dentry_open (nd.dentry, nd.mnt, flags); +return dentry_open_it (nd.dentry, nd.mnt, flags, &nd.intent.open);return ERR_PTR (error); }EXPORT_SYMBOL (filp_open); -struct file *dentry_open (struct dentry *dentry,struct vfsmount *mnt,int flags) +struct file *dentry_open_it (struct dentry *dentry,struct vfsmount *mnt,int flags,struct open_intent *it) {struct file * f;struct inode *inode;
@@ -782,6 +787,7 @@ goto cleanup_dentry; f->f_flags = flags; f->f_mode = (flags+1 ) &O_ACCMODE ; + f->f_it = it; inode = dentry->d_inode;if (f->f_mode &FMODE_WRITE ) { error =get_write_access (inode);
@@ -800,6 +806,7 @@ error = f->f_op->open (inode,f);if (error) goto cleanup_all; +intent_release (it); } f->f_flags &= ~(O_CREAT |O_EXCL |O_NOCTTY |O_TRUNC );
@@ -825,11 +832,20 @@ cleanup_file:put_filp (f); cleanup_dentry: +intent_release (it);dput (dentry);mntput (mnt);return ERR_PTR (error); } +struct file *dentry_open (struct dentry *dentry,struct vfsmount *mnt,int flags) +{ +struct open_intent it; +intent_init (&it,IT_LOOKUP ); + +return dentry_open_it (dentry, mnt, flags, &it); +} +EXPORT_SYMBOL (dentry_open);/*
fs/stat.c +7 -3
@@ -59,15 +59,15 @@ }return 0 ; } -EXPORT_SYMBOL (vfs_getattr);int vfs_stat (char __user *name,struct kstat *stat) {struct nameidata nd;int error; +intent_init (&nd.intent.open,IT_GETATTR ); - error =user_path_walk (name, &nd); + error =user_path_walk_it (name, &nd);if (!error) { error =vfs_getattr (nd.mnt, nd.dentry, stat);path_release (&nd);
@@ -81,8 +81,9 @@ {struct nameidata nd;int error; +intent_init (&nd.intent.open,IT_GETATTR ); - error =user_path_walk_link (name, &nd); + error =user_path_walk_link_it (name, &nd);if (!error) { error =vfs_getattr (nd.mnt, nd.dentry, stat);path_release (&nd);
@@ -96,9 +97,12 @@ {struct file *f =fget (fd);int error = -EBADF ; +struct nameidata nd; +intent_init (&nd.intent.open,IT_GETATTR );if (f) { error =vfs_getattr (f->f_vfsmnt, f->f_dentry, stat); +intent_release (&nd.intent.open);fput (f); }return error;
fs/namespace.c +1 -0
@@ -117,6 +117,7 @@static void detach_mnt (struct vfsmount *mnt,struct nameidata *old_nd) { +memset (old_nd,0 ,sizeof (*old_nd)); old_nd->dentry = mnt->mnt_mountpoint; old_nd->mnt = mnt->mnt_parent; mnt->mnt_parent = mnt;
fs/exec.c +6 -4
@@ -121,8 +121,9 @@struct nameidata nd;int error; +intent_init (&nd.intent.open,IT_OPEN ); nd.intent.open.flags =FMODE_READ ; - error =__user_walk (library,LOOKUP_FOLLOW |LOOKUP_OPEN , &nd); + error =user_path_walk_it (library, &nd);if (error) goto out;
@@ -134,7 +135,7 @@if (error) goto exit; - file =dentry_open (nd.dentry, nd.mnt,O_RDONLY ); + file =dentry_open_it (nd.dentry, nd.mnt,O_RDONLY , &nd.intent.open); error =PTR_ERR (file);if (IS_ERR (file)) goto out;
@@ -474,8 +475,9 @@int err;struct file *file; +intent_init (&nd.intent.open,IT_OPEN ); nd.intent.open.flags =FMODE_READ ; - err =path_lookup (name,LOOKUP_FOLLOW |LOOKUP_OPEN , &nd); + err =path_lookup_it (name,LOOKUP_FOLLOW , &nd); file =ERR_PTR (err);if (!err) {
@@ -488,7 +490,7 @@ err = -EACCES ; file =ERR_PTR (err);if (!err) { - file =dentry_open (nd.dentry, nd.mnt,O_RDONLY ); + file =dentry_open_it (nd.dentry, nd.mnt,O_RDONLY , &nd.intent.open);if (!IS_ERR (file)) { err =deny_write_access (file);if (err) {
fs/xattr.c +8 -4
@@ -161,7 +161,8 @@struct nameidata nd;ssize_t error; - error =user_path_walk (path, &nd); +intent_init (&nd.intent.open,IT_GETXATTR ); + error =user_path_walk_it (path, &nd);if (error)return error; error =getxattr (nd.dentry, name, value, size);
@@ -176,7 +177,8 @@struct nameidata nd;ssize_t error; - error =user_path_walk_link (path, &nd); +intent_init (&nd.intent.open,IT_GETXATTR ); + error =user_path_walk_link_it (path, &nd);if (error)return error; error =getxattr (nd.dentry, name, value, size);
@@ -242,7 +244,8 @@struct nameidata nd;ssize_t error; - error =user_path_walk (path, &nd); +intent_init (&nd.intent.open,IT_GETXATTR ); + error =user_path_walk_it (path, &nd);if (error)return error; error =listxattr (nd.dentry, list, size);
@@ -256,7 +259,8 @@struct nameidata nd;ssize_t error; - error =user_path_walk_link (path, &nd); +intent_init (&nd.intent.open,IT_GETXATTR ); + error =user_path_walk_link_it (path, &nd);if (error)return error; error =listxattr (nd.dentry, list, size);
Quoted 5 lines · Oleg Drokin
Index:
linus-2.6.7-bk-latest/fs/exec.c
===================================================================
fs/exec.c line 129
Quoted 10 lines
fs/exec.c +2
-1@@ -121,8 +121,9 @@struct nameidata nd;int error; +intent_init (&nd.intent.open,IT_OPEN ); nd.intent.open.flags =FMODE_READ ; - error =__user_walk (library,LOOKUP_FOLLOW |LOOKUP_OPEN , &nd); + error =user_path_walk_it (library, &nd);if (error) goto out;
I don't have source available right now (I'll check later) but droping LOOKUP_FOLLOW might break autofs4.
Ian
Hello!
Quoted 6 lines · Ian Kent
fs/exec.c line 126
Quoted 4 lines
fs/exec.c +2
-1+intent_init (&nd.intent.open,IT_OPEN ); nd.intent.open.flags =FMODE_READ ; - error =__user_walk (library,LOOKUP_FOLLOW |LOOKUP_OPEN , &nd); + error =user_path_walk_it (library, &nd);I don't have source available right now (I'll check later) but droping
LOOKUP_FOLLOWmight break autofs4.
It is not dropped,user_path_walk_it is defined like this:
#define user_path_walk_it(name,nd) \
__user_walk_it(name, LOOKUP_FOLLOW, nd)
Bye,
Oleg