diff options
Diffstat (limited to 'fs/dcache.c')
| -rw-r--r-- | fs/dcache.c | 16 | 
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index fbfae008ba4..e8bc3420d63 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2542,7 +2542,6 @@ static int prepend_path(const struct path *path,  	bool slash = false;  	int error = 0; -	br_read_lock(&vfsmount_lock);  	while (dentry != root->dentry || vfsmnt != root->mnt) {  		struct dentry * parent; @@ -2572,8 +2571,6 @@ static int prepend_path(const struct path *path,  	if (!error && !slash)  		error = prepend(buffer, buflen, "/", 1); -out: -	br_read_unlock(&vfsmount_lock);  	return error;  global_root: @@ -2590,7 +2587,7 @@ global_root:  		error = prepend(buffer, buflen, "/", 1);  	if (!error)  		error = is_mounted(vfsmnt) ? 1 : 2; -	goto out; +	return error;  }  /** @@ -2617,9 +2614,11 @@ char *__d_path(const struct path *path,  	int error;  	prepend(&res, &buflen, "\0", 1); +	br_read_lock(&vfsmount_lock);  	write_seqlock(&rename_lock);  	error = prepend_path(path, root, &res, &buflen);  	write_sequnlock(&rename_lock); +	br_read_unlock(&vfsmount_lock);  	if (error < 0)  		return ERR_PTR(error); @@ -2636,9 +2635,11 @@ char *d_absolute_path(const struct path *path,  	int error;  	prepend(&res, &buflen, "\0", 1); +	br_read_lock(&vfsmount_lock);  	write_seqlock(&rename_lock);  	error = prepend_path(path, &root, &res, &buflen);  	write_sequnlock(&rename_lock); +	br_read_unlock(&vfsmount_lock);  	if (error > 1)  		error = -EINVAL; @@ -2702,11 +2703,13 @@ char *d_path(const struct path *path, char *buf, int buflen)  		return path->dentry->d_op->d_dname(path->dentry, buf, buflen);  	get_fs_root(current->fs, &root); +	br_read_lock(&vfsmount_lock);  	write_seqlock(&rename_lock);  	error = path_with_deleted(path, &root, &res, &buflen); +	write_sequnlock(&rename_lock); +	br_read_unlock(&vfsmount_lock);  	if (error < 0)  		res = ERR_PTR(error); -	write_sequnlock(&rename_lock);  	path_put(&root);  	return res;  } @@ -2830,6 +2833,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)  	get_fs_root_and_pwd(current->fs, &root, &pwd);  	error = -ENOENT; +	br_read_lock(&vfsmount_lock);  	write_seqlock(&rename_lock);  	if (!d_unlinked(pwd.dentry)) {  		unsigned long len; @@ -2839,6 +2843,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)  		prepend(&cwd, &buflen, "\0", 1);  		error = prepend_path(&pwd, &root, &cwd, &buflen);  		write_sequnlock(&rename_lock); +		br_read_unlock(&vfsmount_lock);  		if (error < 0)  			goto out; @@ -2859,6 +2864,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)  		}  	} else {  		write_sequnlock(&rename_lock); +		br_read_unlock(&vfsmount_lock);  	}  out:  |