Commit 85d217f4 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] Re: 2.5.11 breakage

	OK, here comes.  Patch below is an attempt to do the fastwalk
stuff in right way and so far it seems to be working.

 - dentry leak is plugged
 - locked/unlocked state of nameidata doesn't depend on history - it
   depends only on point in code.
 - LOOKUP_LOCKED is gone.
 - following mounts and .. doesn't drop dcache_lock
 - light-weight permission check distinguishes between "don't know" and
   "permission denied", so we don't call full-blown permission() unless
   we have to.
 - code that changes root/pwd holds dcache_lock _and_ write lock on
   current->fs->lock.  I.e. if we hold dcache_lock we can safely
   access our ->fs->{root,pwd}{,mnt}
 - __d_lookup() does not increment refcount; callers do dget_locked()
   if they need it (behaviour of d_lookup() didn't change, obviously).
 - link_path_walk() logics had been (somewhat) cleaned up.
parent 7ca32047
...@@ -849,6 +849,8 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) ...@@ -849,6 +849,8 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
struct dentry * dentry; struct dentry * dentry;
spin_lock(&dcache_lock); spin_lock(&dcache_lock);
dentry = __d_lookup(parent,name); dentry = __d_lookup(parent,name);
if (dentry)
__dget_locked(dentry);
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
return dentry; return dentry;
} }
...@@ -881,7 +883,6 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) ...@@ -881,7 +883,6 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
if (memcmp(dentry->d_name.name, str, len)) if (memcmp(dentry->d_name.name, str, len))
continue; continue;
} }
__dget_locked(dentry);
dentry->d_vfs_flags |= DCACHE_REFERENCED; dentry->d_vfs_flags |= DCACHE_REFERENCED;
return dentry; return dentry;
} }
......
This diff is collapsed.
...@@ -654,6 +654,8 @@ struct nameidata { ...@@ -654,6 +654,8 @@ struct nameidata {
struct qstr last; struct qstr last;
unsigned int flags; unsigned int flags;
int last_type; int last_type;
struct dentry *old_dentry;
struct vfsmount *old_mnt;
}; };
#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */ #define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
...@@ -1395,7 +1397,6 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *); ...@@ -1395,7 +1397,6 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *);
#define LOOKUP_CONTINUE (4) #define LOOKUP_CONTINUE (4)
#define LOOKUP_PARENT (16) #define LOOKUP_PARENT (16)
#define LOOKUP_NOALT (32) #define LOOKUP_NOALT (32)
#define LOOKUP_LOCKED (64)
/* /*
* Type of the last component on LOOKUP_PARENT * Type of the last component on LOOKUP_PARENT
......
...@@ -35,10 +35,12 @@ static inline void set_fs_root(struct fs_struct *fs, ...@@ -35,10 +35,12 @@ static inline void set_fs_root(struct fs_struct *fs,
struct dentry *old_root; struct dentry *old_root;
struct vfsmount *old_rootmnt; struct vfsmount *old_rootmnt;
write_lock(&fs->lock); write_lock(&fs->lock);
spin_lock(&dcache_lock);
old_root = fs->root; old_root = fs->root;
old_rootmnt = fs->rootmnt; old_rootmnt = fs->rootmnt;
fs->rootmnt = mntget(mnt); fs->rootmnt = mntget(mnt);
fs->root = dget(dentry); fs->root = dget(dentry);
spin_unlock(&dcache_lock);
write_unlock(&fs->lock); write_unlock(&fs->lock);
if (old_root) { if (old_root) {
dput(old_root); dput(old_root);
...@@ -58,10 +60,12 @@ static inline void set_fs_pwd(struct fs_struct *fs, ...@@ -58,10 +60,12 @@ static inline void set_fs_pwd(struct fs_struct *fs,
struct dentry *old_pwd; struct dentry *old_pwd;
struct vfsmount *old_pwdmnt; struct vfsmount *old_pwdmnt;
write_lock(&fs->lock); write_lock(&fs->lock);
spin_lock(&dcache_lock);
old_pwd = fs->pwd; old_pwd = fs->pwd;
old_pwdmnt = fs->pwdmnt; old_pwdmnt = fs->pwdmnt;
fs->pwdmnt = mntget(mnt); fs->pwdmnt = mntget(mnt);
fs->pwd = dget(dentry); fs->pwd = dget(dentry);
spin_unlock(&dcache_lock);
write_unlock(&fs->lock); write_unlock(&fs->lock);
if (old_pwd) { if (old_pwd) {
dput(old_pwd); dput(old_pwd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment