- fs/dcache.c | 15 ++++++-
- fs/namei.c | 97 +++++++++++++++++++++++++++++++++++++------------
+ fs/dcache.c | 15 +++++-
+ fs/namei.c | 114 ++++++++++++++++++++++++++++++++++++++++---------
fs/namespace.c | 1
- fs/open.c | 24 +++++++++---
- fs/sysfs/inode.c | 2 -
- include/linux/dcache.h | 28 ++++++++++++++
- include/linux/fs.h | 9 ++++
- include/linux/namei.h | 3 +
+ fs/open.c | 70 ++++++++++++++++++++----------
+ fs/sysfs/inode.c | 2
+ include/linux/dcache.h | 28 ++++++++++++
+ include/linux/fs.h | 9 +++
+ include/linux/namei.h | 3 -
kernel/ksyms.c | 7 +++
- net/unix/af_unix.c | 2 -
- 10 files changed, 154 insertions(+), 34 deletions(-)
+ net/unix/af_unix.c | 2
+ 10 files changed, 203 insertions(+), 48 deletions(-)
---- uml-2.5/fs/sysfs/inode.c~vfs_intent_2.5.69_rev1 2003-05-25 20:47:10.000000000 -0600
-+++ uml-2.5-braam/fs/sysfs/inode.c 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/fs/sysfs/inode.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:15.000000000 -0600
++++ uml-2.5-braam/fs/sysfs/inode.c 2003-05-30 02:53:42.000000000 -0600
@@ -80,7 +80,7 @@ struct dentry * sysfs_get_dentry(struct
qstr.name = name;
qstr.len = strlen(name);
}
void sysfs_hash_and_remove(struct dentry * dir, const char * name)
---- uml-2.5/fs/namei.c~vfs_intent_2.5.69_rev1 2003-05-25 20:46:58.000000000 -0600
-+++ uml-2.5-braam/fs/namei.c 2003-05-29 08:30:20.000000000 -0600
+--- uml-2.5/fs/namei.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:13.000000000 -0600
++++ uml-2.5-braam/fs/namei.c 2003-05-30 03:00:32.000000000 -0600
@@ -263,8 +263,15 @@ int deny_write_access(struct file * file
return 0;
}
/*
* namei()
*
-@@ -1093,7 +1137,7 @@ void unlock_rename(struct dentry *p1, st
+@@ -1093,6 +1137,32 @@ void unlock_rename(struct dentry *p1, st
}
}
--int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
+int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
- {
- int error = may_create(dir, dentry);
-
-@@ -1108,7 +1152,7 @@ int vfs_create(struct inode *dir, struct
- if (error)
- return error;
- DQUOT_INIT(dir);
-- error = dir->i_op->create(dir, dentry, mode);
-+ error = dir->i_op->create_it(dir, dentry, mode, nd);
- if (!error) {
- inode_dir_notify(dir, DN_CREATE);
- security_inode_post_create(dir, dentry, mode);
-@@ -1116,6 +1160,11 @@ int vfs_create(struct inode *dir, struct
- return error;
- }
-
-+int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
-+ return vfs_create_it(dir, dentry, mode, NULL);
++ int error = may_create(dir, dentry);
++
++ if (error)
++ return error;
++
++ if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it))
++ return -EACCES; /* shouldn't it be ENOSYS? */
++ mode &= S_IALLUGO;
++ mode |= S_IFREG;
++ error = security_inode_create(dir, dentry, mode);
++ if (error)
++ return error;
++ DQUOT_INIT(dir);
++ if (dir->i_op->create_it)
++ error = dir->i_op->create_it(dir, dentry, mode, nd);
++ else
++ error = dir->i_op->create(dir, dentry, mode);
++ if (!error) {
++ inode_dir_notify(dir, DN_CREATE);
++ security_inode_post_create(dir, dentry, mode);
++ }
++ return error;
+}
+
- int may_open(struct nameidata *nd, int acc_mode, int flag)
+ int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
- struct dentry *dentry = nd->dentry;
-@@ -1232,6 +1281,9 @@ int open_namei(const char * pathname, in
+ int error = may_create(dir, dentry);
+@@ -1232,6 +1302,9 @@ int open_namei(const char * pathname, in
/*
* Create - we need to know the parent.
*/
error = path_lookup(pathname, LOOKUP_PARENT, nd);
if (error)
return error;
-@@ -1247,7 +1299,7 @@ int open_namei(const char * pathname, in
+@@ -1247,7 +1320,7 @@ int open_namei(const char * pathname, in
dir = nd->dentry;
down(&dir->d_inode->i_sem);
do_last:
error = PTR_ERR(dentry);
-@@ -1255,12 +1307,13 @@ do_last:
+@@ -1255,12 +1328,13 @@ do_last:
up(&dir->d_inode->i_sem);
goto exit;
}
up(&dir->d_inode->i_sem);
dput(nd->dentry);
nd->dentry = dentry;
-@@ -1285,7 +1338,7 @@ do_last:
+@@ -1285,7 +1359,7 @@ do_last:
error = -ELOOP;
if (flag & O_NOFOLLOW)
goto exit_dput;
}
error = -ENOENT;
if (!dentry->d_inode)
-@@ -1328,7 +1381,7 @@ do_link:
+@@ -1328,7 +1402,7 @@ do_link:
if (error)
goto exit_dput;
UPDATE_ATIME(dentry->d_inode);
dput(dentry);
if (error)
return error;
-@@ -1350,7 +1403,7 @@ do_link:
+@@ -1350,7 +1424,7 @@ do_link:
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
putname(nd->last.name);
goto do_last;
}
-@@ -1364,7 +1417,7 @@ static struct dentry *lookup_create(stru
+@@ -1364,7 +1438,7 @@ static struct dentry *lookup_create(stru
dentry = ERR_PTR(-EEXIST);
if (nd->last_type != LAST_NORM)
goto fail;
if (IS_ERR(dentry))
goto fail;
if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
---- uml-2.5/fs/dcache.c~vfs_intent_2.5.69_rev1 2003-05-25 20:46:58.000000000 -0600
-+++ uml-2.5-braam/fs/dcache.c 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/fs/dcache.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:12.000000000 -0600
++++ uml-2.5-braam/fs/dcache.c 2003-05-30 02:53:42.000000000 -0600
@@ -1134,14 +1134,23 @@ void d_delete(struct dentry * dentry)
* Adds a dentry to the hash according to its name.
*/
}
#define do_switch(x,y) do { \
---- uml-2.5/fs/namespace.c~vfs_intent_2.5.69_rev1 2003-05-25 20:46:58.000000000 -0600
-+++ uml-2.5-braam/fs/namespace.c 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/fs/namespace.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:13.000000000 -0600
++++ uml-2.5-braam/fs/namespace.c 2003-05-30 02:53:42.000000000 -0600
@@ -927,6 +927,7 @@ void set_fs_pwd(struct fs_struct *fs, st
mntput(old_pwdmnt);
}
static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
{
---- uml-2.5/fs/open.c~vfs_intent_2.5.69_rev1 2003-05-25 20:46:58.000000000 -0600
-+++ uml-2.5-braam/fs/open.c 2003-05-29 08:30:20.000000000 -0600
+--- uml-2.5/fs/open.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:13.000000000 -0600
++++ uml-2.5-braam/fs/open.c 2003-05-30 02:53:42.000000000 -0600
@@ -97,7 +97,8 @@ static inline long do_sys_truncate(const
struct nameidata nd;
struct inode * inode;
error = -EPERM;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
goto dput_and_out;
-@@ -619,7 +627,10 @@ asmlinkage long sys_fchown(unsigned int
- struct file *filp_open(const char * filename, int flags, int mode)
- {
- int namei_flags, error;
-+ struct file * temp_filp;
- struct nameidata nd;
-+ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
-+ nd.it=it;
-
- namei_flags = flags;
- if ((namei_flags+1) & O_ACCMODE)
-@@ -628,9 +639,10 @@ struct file *filp_open(const char * file
- namei_flags |= 2;
-
- error = open_namei(filename, namei_flags, mode, &nd);
+@@ -616,29 +624,13 @@ asmlinkage long sys_fchown(unsigned int
+ * for the internal routines (ie open_namei()/follow_link() etc). 00 is
+ * used by symlinks.
+ */
+-struct file *filp_open(const char * filename, int flags, int mode)
+-{
+- int namei_flags, error;
+- struct nameidata nd;
+-
+- namei_flags = flags;
+- if ((namei_flags+1) & O_ACCMODE)
+- namei_flags++;
+- if (namei_flags & O_TRUNC)
+- namei_flags |= 2;
+-
+- error = open_namei(filename, namei_flags, mode, &nd);
- if (!error)
- return dentry_open(nd.dentry, nd.mnt, flags);
-
-+ if (!error) {
-+ temp_filp = dentry_open(nd.dentry, nd.mnt, flags);
-+ return temp_filp;
-+ }
- return ERR_PTR(error);
- }
+- return ERR_PTR(error);
+-}
+-
+-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++struct file *dentry_open_nd(struct nameidata *nd, int flags)
+ {
+ struct file * f;
+ struct inode *inode;
+ int error;
++ struct dentry *dentry = nd->dentry;
++ struct vfsmount *mnt = nd->mnt;
+
+ error = -ENFILE;
+ f = get_empty_filp();
+@@ -646,6 +638,7 @@ struct file *dentry_open(struct dentry *
+ goto cleanup_dentry;
+ f->f_flags = flags;
+ f->f_mode = (flags+1) & O_ACCMODE;
++ f->private_data = &nd->it;
+ inode = dentry->d_inode;
+ if (f->f_mode & FMODE_WRITE) {
+ error = get_write_access(inode);
+@@ -664,6 +657,7 @@ struct file *dentry_open(struct dentry *
+ error = f->f_op->open(inode,f);
+ if (error)
+ goto cleanup_all;
++ intent_release(nd->dentry, &nd->it);
+ }
+ f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-@@ -675,7 +687,7 @@ struct file *dentry_open(struct dentry *
+@@ -675,7 +669,7 @@ struct file *dentry_open(struct dentry *
goto cleanup_all;
}
}
return f;
cleanup_all:
---- uml-2.5/include/linux/dcache.h~vfs_intent_2.5.69_rev1 2003-05-25 20:47:22.000000000 -0600
-+++ uml-2.5-braam/include/linux/dcache.h 2003-05-29 01:54:37.000000000 -0600
+@@ -693,6 +687,38 @@ cleanup_dentry:
+ return ERR_PTR(error);
+ }
+
++struct file *filp_open(const char * filename, int flags, int mode)
++{
++ int namei_flags, error;
++ struct file * temp_filp;
++ struct nameidata nd;
++ nd.it= ((struct lookup_intent) { .it_op = IT_OPEN, .it_flags = flags });
++
++ namei_flags = flags;
++ if ((namei_flags+1) & O_ACCMODE)
++ namei_flags++;
++ if (namei_flags & O_TRUNC)
++ namei_flags |= 2;
++
++ error = open_namei(filename, namei_flags, mode, &nd);
++ if (!error) {
++ temp_filp = dentry_open_nd(&nd, flags);
++ return temp_filp;
++ }
++ return ERR_PTR(error);
++}
++
++
++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
++{
++ struct nameidata nd;
++ nd.dentry = dentry;
++ nd.mnt = mnt;
++ nd.it = ((struct lookup_intent) { 0} );
++
++ return dentry_open_nd(&nd, flags);
++}
++
+ /*
+ * Find an empty file descriptor entry, and mark it busy.
+ */
+--- uml-2.5/include/linux/dcache.h~vfs_intent_2.5.69_rev1 2003-05-30 02:20:28.000000000 -0600
++++ uml-2.5-braam/include/linux/dcache.h 2003-05-30 02:53:42.000000000 -0600
@@ -12,6 +12,27 @@
struct vfsmount;
extern spinlock_t dcache_lock;
---- uml-2.5/include/linux/fs.h~vfs_intent_2.5.69_rev1 2003-05-25 20:47:22.000000000 -0600
-+++ uml-2.5-braam/include/linux/fs.h 2003-05-29 08:30:20.000000000 -0600
+--- uml-2.5/include/linux/fs.h~vfs_intent_2.5.69_rev1 2003-05-30 02:20:29.000000000 -0600
++++ uml-2.5-braam/include/linux/fs.h 2003-05-30 02:53:42.000000000 -0600
@@ -237,6 +237,9 @@ typedef int (get_blocks_t)(struct inode
#define ATTR_ATTR_FLAG 1024
#define ATTR_KILL_SUID 2048
extern int permission(struct inode *, int);
extern int vfs_permission(struct inode *, int);
extern int get_write_access(struct inode *);
---- uml-2.5/include/linux/namei.h~vfs_intent_2.5.69_rev1 2003-05-25 20:47:23.000000000 -0600
-+++ uml-2.5-braam/include/linux/namei.h 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/include/linux/namei.h~vfs_intent_2.5.69_rev1 2003-05-30 02:20:30.000000000 -0600
++++ uml-2.5-braam/include/linux/namei.h 2003-05-30 02:53:42.000000000 -0600
@@ -11,6 +11,7 @@ struct nameidata {
struct qstr last;
unsigned int flags;
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
---- uml-2.5/kernel/ksyms.c~vfs_intent_2.5.69_rev1 2003-05-25 20:47:36.000000000 -0600
-+++ uml-2.5-braam/kernel/ksyms.c 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/kernel/ksyms.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:37.000000000 -0600
++++ uml-2.5-braam/kernel/ksyms.c 2003-05-30 02:53:42.000000000 -0600
@@ -374,6 +374,7 @@ EXPORT_SYMBOL(unregister_filesystem);
EXPORT_SYMBOL(kern_mount);
EXPORT_SYMBOL(__mntput);
/* waitqueue handling */
EXPORT_SYMBOL(add_wait_queue);
EXPORT_SYMBOL(add_wait_queue_exclusive);
---- uml-2.5/net/unix/af_unix.c~vfs_intent_2.5.69_rev1 2003-05-25 20:47:44.000000000 -0600
-+++ uml-2.5-braam/net/unix/af_unix.c 2003-05-29 01:54:37.000000000 -0600
+--- uml-2.5/net/unix/af_unix.c~vfs_intent_2.5.69_rev1 2003-05-30 02:20:48.000000000 -0600
++++ uml-2.5-braam/net/unix/af_unix.c 2003-05-30 02:53:42.000000000 -0600
@@ -721,7 +721,7 @@ static int unix_bind(struct socket *sock
/*
* Do the final lookup.