Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 310068
b: refs/heads/master
c: 16b1c1c
h: refs/heads/master
v: v3
  • Loading branch information
Miklos Szeredi authored and Al Viro committed Jun 1, 2012
1 parent f645dff commit ba1871d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 50ee93afcaa970620d1fb5a9894109a2ab152868
refs/heads/master: 16b1c1cd71176ab0a76b26818fbf12db9183ed57
37 changes: 35 additions & 2 deletions trunk/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -2202,6 +2202,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
struct file *filp;
struct inode *inode;
int symlink_ok = 0;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
int error;

nd->flags &= ~LOOKUP_PARENT;
Expand Down Expand Up @@ -2267,6 +2269,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
if (nd->last.name[nd->last.len])
goto exit;

retry_lookup:
mutex_lock(&dir->d_inode->i_mutex);

dentry = lookup_hash(nd);
Expand Down Expand Up @@ -2349,12 +2352,21 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
return NULL;
}

path_to_nameidata(path, nd);
if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) {
path_to_nameidata(path, nd);
} else {
save_parent.dentry = nd->path.dentry;
save_parent.mnt = mntget(path->mnt);
nd->path.dentry = path->dentry;

}
nd->inode = inode;
/* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */
error = complete_walk(nd);
if (error)
if (error) {
path_put(&save_parent);
return ERR_PTR(error);
}
error = -EISDIR;
if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
goto exit;
Expand All @@ -2377,6 +2389,20 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
if (error)
goto exit;
filp = nameidata_to_filp(nd);
if (filp == ERR_PTR(-EOPENSTALE) && save_parent.dentry && !retried) {
BUG_ON(save_parent.dentry != dir);
path_put(&nd->path);
nd->path = save_parent;
nd->inode = dir->d_inode;
save_parent.mnt = NULL;
save_parent.dentry = NULL;
if (want_write) {
mnt_drop_write(nd->path.mnt);
want_write = 0;
}
retried = true;
goto retry_lookup;
}
if (!IS_ERR(filp)) {
error = ima_file_check(filp, op->acc_mode);
if (error) {
Expand All @@ -2396,6 +2422,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
out:
if (want_write)
mnt_drop_write(nd->path.mnt);
path_put(&save_parent);
terminate_walk(nd);
return filp;

Expand Down Expand Up @@ -2459,6 +2486,12 @@ static struct file *path_openat(int dfd, const char *pathname,
if (base)
fput(base);
release_open_intent(nd);
if (filp == ERR_PTR(-EOPENSTALE)) {
if (flags & LOOKUP_RCU)
filp = ERR_PTR(-ECHILD);
else
filp = ERR_PTR(-ESTALE);
}
return filp;

out_filp:
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define ENOIOCTLCMD 515 /* No ioctl command */
#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
#define EPROBE_DEFER 517 /* Driver requests probe retry */
#define EOPENSTALE 518 /* open found a stale dentry */

/* Defined for the NFSv3 protocol */
#define EBADHANDLE 521 /* Illegal NFS file handle */
Expand Down

0 comments on commit ba1871d

Please sign in to comment.