* [PATCH] vfs: namei operations should pass nameidata when available
@ 2005-03-28 20:06 Jeff Mahoney
2005-03-28 20:17 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Jeff Mahoney @ 2005-03-28 20:06 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds, Linux Kernel Mailing List
[-- Attachment #1: Type: text/plain, Size: 5170 bytes --]
This patch replaces calls to lookup_hash with calls to __lookup_hash at the
vfs level where complete paths (struct nameidata) are available.
AF_UNIX sockets also open a complete path terminated with a lookup_hash. Since
it's conceivable for modules to do the same, I've exported __lookup_hash and
made lookup_hash a static inline.
The reason for the change is that I recently reworked subfs to eliminate
rather questionable behavior, such as walking the vfsmount tree lockless and
then caching a pointer. Since the mountpoint is still required to mount the
sub-filesystem, I chose to use nameidata->nd_mnt at ->open or ->lookup. This
led to quick oopsen when any create/remove/rename operation was performed with
the sub-filesystem umounted. This patch supplies the needed data.
This change shouldn't have any effect on the call paths, since the lookup path
for each filesystem is already passed valid nameidata from open_namei in the
existing code.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Index: linux-2.6.11/fs/namei.c
===================================================================
--- linux-2.6.11.orig/fs/namei.c
+++ linux-2.6.11/fs/namei.c
@@ -992,7 +992,7 @@ int fastcall path_lookup(const char *nam
* needs parent already locked. Doesn't follow mounts.
* SMP-safe.
*/
-static struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd)
+struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd)
{
struct dentry * dentry;
struct inode *inode;
@@ -1031,11 +1031,6 @@ out:
return dentry;
}
-struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
-{
- return __lookup_hash(name, base, NULL);
-}
-
/* SMP-safe */
struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
{
@@ -1519,7 +1519,7 @@ struct dentry *lookup_create(struct name
if (nd->last_type != LAST_NORM)
goto fail;
nd->flags &= ~LOOKUP_PARENT;
- dentry = lookup_hash(&nd->last, nd->dentry);
+ dentry = __lookup_hash(&nd->last, nd->dentry, nd);
if (IS_ERR(dentry))
goto fail;
if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
@@ -1760,7 +1755,7 @@ asmlinkage long sys_rmdir(const char __u
goto exit1;
}
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = __lookup_hash(&nd.last, nd.dentry, &nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1829,7 +1824,7 @@ asmlinkage long sys_unlink(const char __
if (nd.last_type != LAST_NORM)
goto exit1;
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = __lookup_hash(&nd.last, nd.dentry, &nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
/* Why not before? Because we want correct error value */
@@ -2178,7 +2173,7 @@ static inline int do_rename(const char *
trap = lock_rename(new_dir, old_dir);
- old_dentry = lookup_hash(&oldnd.last, old_dir);
+ old_dentry = __lookup_hash(&oldnd.last, old_dir, &oldnd);
error = PTR_ERR(old_dentry);
if (IS_ERR(old_dentry))
goto exit3;
@@ -2198,7 +2193,7 @@ static inline int do_rename(const char *
error = -EINVAL;
if (old_dentry == trap)
goto exit4;
- new_dentry = lookup_hash(&newnd.last, new_dir);
+ new_dentry = __lookup_hash(&newnd.last, new_dir, &oldnd);
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto exit4;
@@ -2391,7 +2386,7 @@ EXPORT_SYMBOL(follow_up);
EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
EXPORT_SYMBOL(getname);
EXPORT_SYMBOL(lock_rename);
-EXPORT_SYMBOL(lookup_hash);
+EXPORT_SYMBOL(__lookup_hash);
EXPORT_SYMBOL(lookup_one_len);
EXPORT_SYMBOL(page_follow_link_light);
EXPORT_SYMBOL(page_put_link);
Index: linux-2.6.11/include/linux/namei.h
===================================================================
--- linux-2.6.11.orig/include/linux/namei.h
+++ linux-2.6.11/include/linux/namei.h
@@ -64,7 +64,11 @@ extern void path_release(struct nameidat
extern void path_release_on_umount(struct nameidata *);
extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+extern struct dentry * __lookup_hash(struct qstr *, struct dentry *, struct nameidata *);
+static inline struct dentry * lookup_hash(struct qstr *name, struct dentry *base)
+{
+ return __lookup_hash(name, base, NULL);
+}
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
Index: linux-2.6.11/net/unix/af_unix.c
===================================================================
--- linux-2.6.11.orig/net/unix/af_unix.c
+++ linux-2.6.11/net/unix/af_unix.c
@@ -776,7 +776,7 @@ static int unix_bind(struct socket *sock
/*
* Do the final lookup.
*/
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = __lookup_hash(&nd.last, nd.dentry, &nd);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out_mknod_unlock;
--
Jeff Mahoney
SuSE Labs
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] vfs: namei operations should pass nameidata when available
2005-03-28 20:06 [PATCH] vfs: namei operations should pass nameidata when available Jeff Mahoney
@ 2005-03-28 20:17 ` Christoph Hellwig
2005-06-10 19:05 ` Ram
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2005-03-28 20:17 UTC (permalink / raw)
To: Jeff Mahoney; +Cc: Andrew Morton, Linus Torvalds, Linux Kernel Mailing List
> + dentry = __lookup_hash(&nd->last, nd->dentry, nd);
Please add a tiny wrapper lookup_hash_nd(struct nameidata *nd)
that expands to the above instead of opencoding it everywhere.
Or just call it lookup_hash() after you removed the original version..
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] vfs: namei operations should pass nameidata when available
2005-03-28 20:17 ` Christoph Hellwig
@ 2005-06-10 19:05 ` Ram
2005-06-10 20:09 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Ram @ 2005-06-10 19:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jeff Mahoney, Andrew Morton, Linus Torvalds,
Linux Kernel Mailing List
[-- Attachment #1: Type: text/plain, Size: 778 bytes --]
On Mon, 2005-03-28 at 12:17, Christoph Hellwig wrote:
> > + dentry = __lookup_hash(&nd->last, nd->dentry, nd);
>
> Please add a tiny wrapper lookup_hash_nd(struct nameidata *nd)
> that expands to the above instead of opencoding it everywhere.
>
> Or just call it lookup_hash() after you removed the original version..
Jeff,
I have incorporated the Christophs' comments.
lookup_hash() now takes a third
nameidata argument. I touch tested it. If you like the patch can
your forward it to Andrew.
Thanks,
RP
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
[-- Attachment #2: lookup.patch --]
[-- Type: text/x-patch, Size: 7880 bytes --]
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/drivers/usb/core/inode.c linux-2.6.12-rc4/drivers/usb/core/inode.c
--- /home/linux/views/linux-2.6.12-rc4/drivers/usb/core/inode.c 2005-05-06 23:22:26.000000000 -0700
+++ linux-2.6.12-rc4/drivers/usb/core/inode.c 2005-05-23 13:41:10.000000000 -0700
@@ -460,7 +460,7 @@ static struct dentry * get_dentry(struct
qstr.name = name;
qstr.len = strlen(name);
qstr.hash = full_name_hash(name,qstr.len);
- return lookup_hash(&qstr,parent);
+ return lookup_hash(&qstr,parent,NULL);
}
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/fs/debugfs/inode.c linux-2.6.12-rc4/fs/debugfs/inode.c
--- /home/linux/views/linux-2.6.12-rc4/fs/debugfs/inode.c 2005-03-02 02:59:59.000000000 -0800
+++ linux-2.6.12-rc4/fs/debugfs/inode.c 2005-05-23 13:41:46.000000000 -0700
@@ -117,7 +117,7 @@ static struct dentry * get_dentry(struct
qstr.name = name;
qstr.len = strlen(name);
qstr.hash = full_name_hash(name,qstr.len);
- return lookup_hash(&qstr,parent);
+ return lookup_hash(&qstr,parent,NULL);
}
static struct super_block *debug_get_sb(struct file_system_type *fs_type,
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/fs/ext3/super.c linux-2.6.12-rc4/fs/ext3/super.c
--- /home/linux/views/linux-2.6.12-rc4/fs/ext3/super.c 2005-05-06 23:22:29.000000000 -0700
+++ linux-2.6.12-rc4/fs/ext3/super.c 2005-05-23 13:42:07.000000000 -0700
@@ -2346,7 +2346,7 @@ static int ext3_quota_on_mount(struct su
.hash = 0,
.len = strlen(EXT3_SB(sb)->s_qf_names[type])};
- dentry = lookup_hash(&name, sb->s_root);
+ dentry = lookup_hash(&name, sb->s_root, NULL);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
err = vfs_quota_on_mount(type, EXT3_SB(sb)->s_jquota_fmt, dentry);
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/fs/namei.c linux-2.6.12-rc4/fs/namei.c
--- /home/linux/views/linux-2.6.12-rc4/fs/namei.c 2005-05-06 23:22:29.000000000 -0700
+++ linux-2.6.12-rc4/fs/namei.c 2005-05-23 13:42:56.000000000 -0700
@@ -1075,9 +1075,10 @@ out:
return dentry;
}
-struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
+struct dentry * lookup_hash(struct qstr *name, struct dentry * base,
+ struct nameidata *nd)
{
- return __lookup_hash(name, base, NULL);
+ return __lookup_hash(name, base, nd);
}
/* SMP-safe */
@@ -1101,7 +1102,7 @@ struct dentry * lookup_one_len(const cha
}
this.hash = end_name_hash(hash);
- return lookup_hash(&this, base);
+ return lookup_hash(&this, base, NULL);
access:
return ERR_PTR(-EACCES);
}
@@ -1568,7 +1569,7 @@ struct dentry *lookup_create(struct name
if (nd->last_type != LAST_NORM)
goto fail;
nd->flags &= ~LOOKUP_PARENT;
- dentry = lookup_hash(&nd->last, nd->dentry);
+ dentry = lookup_hash(&nd->last, nd->dentry, nd);
if (IS_ERR(dentry))
goto fail;
if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
@@ -1800,7 +1801,7 @@ asmlinkage long sys_rmdir(const char __u
goto exit1;
}
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd.last, nd.dentry, &nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1869,7 +1870,7 @@ asmlinkage long sys_unlink(const char __
if (nd.last_type != LAST_NORM)
goto exit1;
down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd.last, nd.dentry, &nd);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
/* Why not before? Because we want correct error value */
@@ -2218,7 +2219,7 @@ static inline int do_rename(const char *
trap = lock_rename(new_dir, old_dir);
- old_dentry = lookup_hash(&oldnd.last, old_dir);
+ old_dentry = lookup_hash(&oldnd.last, old_dir, &oldnd);
error = PTR_ERR(old_dentry);
if (IS_ERR(old_dentry))
goto exit3;
@@ -2238,7 +2239,7 @@ static inline int do_rename(const char *
error = -EINVAL;
if (old_dentry == trap)
goto exit4;
- new_dentry = lookup_hash(&newnd.last, new_dir);
+ new_dentry = lookup_hash(&newnd.last, new_dir, &newnd);
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto exit4;
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/fs/reiserfs/super.c linux-2.6.12-rc4/fs/reiserfs/super.c
--- /home/linux/views/linux-2.6.12-rc4/fs/reiserfs/super.c 2005-05-06 23:22:29.000000000 -0700
+++ linux-2.6.12-rc4/fs/reiserfs/super.c 2005-05-23 13:43:11.000000000 -0700
@@ -1941,7 +1941,7 @@ static int reiserfs_quota_on_mount(struc
.hash = 0,
.len = strlen(REISERFS_SB(sb)->s_qf_names[type])};
- dentry = lookup_hash(&name, sb->s_root);
+ dentry = lookup_hash(&name, sb->s_root, NULL);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
err = vfs_quota_on_mount(type, REISERFS_SB(sb)->s_jquota_fmt, dentry);
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/fs/sysfs/inode.c linux-2.6.12-rc4/fs/sysfs/inode.c
--- /home/linux/views/linux-2.6.12-rc4/fs/sysfs/inode.c 2005-05-06 23:22:30.000000000 -0700
+++ linux-2.6.12-rc4/fs/sysfs/inode.c 2005-05-23 13:43:35.000000000 -0700
@@ -83,7 +83,7 @@ struct dentry * sysfs_get_dentry(struct
qstr.name = name;
qstr.len = strlen(name);
qstr.hash = full_name_hash(name,qstr.len);
- return lookup_hash(&qstr,parent);
+ return lookup_hash(&qstr,parent,NULL);
}
/*
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/include/linux/namei.h linux-2.6.12-rc4/include/linux/namei.h
--- /home/linux/views/linux-2.6.12-rc4/include/linux/namei.h 2005-05-06 23:22:33.000000000 -0700
+++ linux-2.6.12-rc4/include/linux/namei.h 2005-05-23 13:28:44.000000000 -0700
@@ -66,7 +66,8 @@ extern void path_release(struct nameidat
extern void path_release_on_umount(struct nameidata *);
extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+extern struct dentry * lookup_hash(struct qstr *, struct dentry *,
+ struct nameidata *);
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/net/sunrpc/rpc_pipe.c linux-2.6.12-rc4/net/sunrpc/rpc_pipe.c
--- /home/linux/views/linux-2.6.12-rc4/net/sunrpc/rpc_pipe.c 2005-03-02 03:00:24.000000000 -0800
+++ linux-2.6.12-rc4/net/sunrpc/rpc_pipe.c 2005-05-23 13:51:08.000000000 -0700
@@ -601,7 +601,7 @@ rpc_lookup_negative(char *path, struct n
return ERR_PTR(error);
dir = nd->dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd->last, nd->dentry);
+ dentry = lookup_hash(&nd->last, nd->dentry, nd);
if (IS_ERR(dentry))
goto out_err;
if (dentry->d_inode) {
@@ -663,7 +663,7 @@ rpc_rmdir(char *path)
return error;
dir = nd.dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd.last, nd.dentry, &nd);
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
goto out_release;
@@ -724,7 +724,7 @@ rpc_unlink(char *path)
return error;
dir = nd.dentry->d_inode;
down(&dir->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd.last, nd.dentry, &nd);
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
goto out_release;
diff -Nrup -X dontdiff /home/linux/views/linux-2.6.12-rc4/net/unix/af_unix.c linux-2.6.12-rc4/net/unix/af_unix.c
--- /home/linux/views/linux-2.6.12-rc4/net/unix/af_unix.c 2005-05-06 23:22:35.000000000 -0700
+++ linux-2.6.12-rc4/net/unix/af_unix.c 2005-05-23 13:51:22.000000000 -0700
@@ -784,7 +784,7 @@ static int unix_bind(struct socket *sock
/*
* Do the final lookup.
*/
- dentry = lookup_hash(&nd.last, nd.dentry);
+ dentry = lookup_hash(&nd.last, nd.dentry, &nd);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out_mknod_unlock;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] vfs: namei operations should pass nameidata when available
2005-06-10 19:05 ` Ram
@ 2005-06-10 20:09 ` Christoph Hellwig
0 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2005-06-10 20:09 UTC (permalink / raw)
To: Ram
Cc: Christoph Hellwig, Jeff Mahoney, Andrew Morton, Linus Torvalds,
Linux Kernel Mailing List
On Fri, Jun 10, 2005 at 12:05:11PM -0700, Ram wrote:
> On Mon, 2005-03-28 at 12:17, Christoph Hellwig wrote:
> > > + dentry = __lookup_hash(&nd->last, nd->dentry, nd);
> >
> > Please add a tiny wrapper lookup_hash_nd(struct nameidata *nd)
> > that expands to the above instead of opencoding it everywhere.
> >
> > Or just call it lookup_hash() after you removed the original version..
>
> Jeff,
>
> I have incorporated the Christophs' comments.
> lookup_hash() now takes a third
> nameidata argument. I touch tested it. If you like the patch can
> your forward it to Andrew.
No, please wait. I have a patch series pending for post 2.6.12 that
revamps this code area little, lookup_hash will only take a nameidata *
after that.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-06-10 20:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-28 20:06 [PATCH] vfs: namei operations should pass nameidata when available Jeff Mahoney
2005-03-28 20:17 ` Christoph Hellwig
2005-06-10 19:05 ` Ram
2005-06-10 20:09 ` Christoph Hellwig
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.