Skip to contentSkip to conversation

Lustre VFS patches for 2.6

PATCH In review Oleg Drokin 2 participants 3 messages Jul 7, 2004 – Jul 8, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
Index: linus-2.6.7-bk-latest/include/linux/namei.h
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/include/linux/fs.h
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/fs/open.c
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/fs/stat.c
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/fs/namespace.c
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/fs/exec.c
===================================================================
@@ -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
Index: linus-2.6.7-bk-latest/fs/xattr.c
===================================================================
@@ -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);
#1 lore raw
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

#2 lore raw

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_FOLLOW might 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