git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.3
[linux-2.6.git]
/
fs
/
namei.c
diff --git
a/fs/namei.c
b/fs/namei.c
index
8a1943d
..
aac4502
100644
(file)
--- a/
fs/namei.c
+++ b/
fs/namei.c
@@
-886,29
+886,31
@@
static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
return 0; /* something went wrong... */
if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
return 0; /* something went wrong... */
if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
- struct nameidata nd_root;
+ struct dentry *old_dentry = nd->dentry;
+ struct vfsmount *old_mnt = nd->mnt;
+ struct qstr last = nd->last;
+ int last_type = nd->last_type;
/*
* NAME was not found in alternate root or it's a directory. Try to find
* it in the normal root:
*/
/*
* NAME was not found in alternate root or it's a directory. Try to find
* it in the normal root:
*/
- nd_root.last_type = LAST_ROOT;
- nd_root.flags = nd->flags;
- nd_root.depth = 0;
- memcpy(&nd_root.intent, &nd->intent, sizeof(nd_root.intent));
+ nd->last_type = LAST_ROOT;
read_lock(¤t->fs->lock);
read_lock(¤t->fs->lock);
- nd
_root.
mnt = mntget(current->fs->rootmnt);
- nd
_root.
dentry = dget(current->fs->root);
+ nd
->
mnt = mntget(current->fs->rootmnt);
+ nd
->
dentry = dget(current->fs->root);
read_unlock(¤t->fs->lock);
read_unlock(¤t->fs->lock);
- if (path_walk(name, &nd_root))
- return 1;
- if (nd_root.dentry->d_inode) {
+ if (path_walk(name, nd) == 0) {
+ if (nd->dentry->d_inode) {
+ dput(old_dentry);
+ mntput(old_mnt);
+ return 1;
+ }
path_release(nd);
path_release(nd);
- nd->dentry = nd_root.dentry;
- nd->mnt = nd_root.mnt;
- nd->last = nd_root.last;
- return 1;
}
}
- path_release(&nd_root);
+ nd->dentry = old_dentry;
+ nd->mnt = old_mnt;
+ nd->last = last;
+ nd->last_type = last_type;
}
return 1;
}
}
return 1;
}
@@
-961,8
+963,7
@@
int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
}
nd->mnt = mntget(current->fs->rootmnt);
nd->dentry = dget(current->fs->root);
}
nd->mnt = mntget(current->fs->rootmnt);
nd->dentry = dget(current->fs->root);
- }
- else{
+ } else {
nd->mnt = mntget(current->fs->pwdmnt);
nd->dentry = dget(current->fs->pwd);
}
nd->mnt = mntget(current->fs->pwdmnt);
nd->dentry = dget(current->fs->pwd);
}
@@
-1112,8
+1113,12
@@
static inline int check_sticky(struct inode *dir, struct inode *inode)
static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir)
{
int error;
static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir)
{
int error;
- if (!victim->d_inode || victim->d_parent->d_inode != dir)
+
+ if (!victim->d_inode)
return -ENOENT;
return -ENOENT;
+
+ BUG_ON(victim->d_parent->d_inode != dir);
+
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
return error;
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
return error;
@@
-1677,7
+1682,7
@@
out:
* if it cannot handle the case of removing a directory
* that is still in use by something else..
*/
* if it cannot handle the case of removing a directory
* that is still in use by something else..
*/
-
static void d
_unhash(struct dentry *dentry)
+
void dentry
_unhash(struct dentry *dentry)
{
dget(dentry);
spin_lock(&dcache_lock);
{
dget(dentry);
spin_lock(&dcache_lock);
@@
-1707,7
+1712,7
@@
int vfs_rmdir(struct inode *dir, struct dentry *dentry)
DQUOT_INIT(dir);
down(&dentry->d_inode->i_sem);
DQUOT_INIT(dir);
down(&dentry->d_inode->i_sem);
- d_unhash(dentry);
+ d
entry
_unhash(dentry);
if (d_mountpoint(dentry))
error = -EBUSY;
else {
if (d_mountpoint(dentry))
error = -EBUSY;
else {
@@
-1838,13
+1843,12
@@
asmlinkage long sys_unlink(const char __user * pathname)
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
+ if (inode)
+ iput(inode); /* truncate the inode here */
exit1:
path_release(&nd);
exit:
putname(name);
exit1:
path_release(&nd);
exit:
putname(name);
-
- if (inode)
- iput(inode); /* truncate the inode here */
return error;
slashes:
return error;
slashes:
@@
-2050,7
+2054,7
@@
int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
target = new_dentry->d_inode;
if (target) {
down(&target->i_sem);
target = new_dentry->d_inode;
if (target) {
down(&target->i_sem);
- d_unhash(new_dentry);
+ d
entry
_unhash(new_dentry);
}
if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
error = -EBUSY;
}
if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
error = -EBUSY;
@@
-2317,12
+2321,8
@@
int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
{
struct page *page;
int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
{
struct page *page;
- char *s = page_getlink(dentry, &page);
- if (!IS_ERR(s)) {
- nd_set_link(nd, s);
- s = NULL;
- }
- return PTR_ERR(s);
+ nd_set_link(nd, page_getlink(dentry, &page));
+ return 0;
}
void page_put_link(struct dentry *dentry, struct nameidata *nd)
}
void page_put_link(struct dentry *dentry, struct nameidata *nd)
@@
-2428,4
+2428,5
@@
EXPORT_SYMBOL(vfs_rename);
EXPORT_SYMBOL(vfs_rmdir);
EXPORT_SYMBOL(vfs_symlink);
EXPORT_SYMBOL(vfs_unlink);
EXPORT_SYMBOL(vfs_rmdir);
EXPORT_SYMBOL(vfs_symlink);
EXPORT_SYMBOL(vfs_unlink);
+EXPORT_SYMBOL(dentry_unhash);
EXPORT_SYMBOL(generic_readlink);
EXPORT_SYMBOL(generic_readlink);