* Re: Probleam reading fdinfo symlinks after 30a08bf2d31d275c6fc71dd1811342777e95c831
2012-06-04 15:14 Probleam reading fdinfo symlinks after 30a08bf2d31d275c6fc71dd1811342777e95c831 Cyrill Gorcunov
@ 2012-06-04 17:59 ` Linus Torvalds
2012-06-04 18:11 ` Cyrill Gorcunov
0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2012-06-04 17:59 UTC (permalink / raw)
To: Cyrill Gorcunov; +Cc: LKML, LINUXFS-ML, Al Viro, Eric Biederman
[-- Attachment #1: Type: text/plain, Size: 449 bytes --]
On Mon, Jun 4, 2012 at 8:14 AM, Cyrill Gorcunov <gorcunov@openvz.org> wrote:
>
> just tried 3.5-rc1 out and found that with commit
> 30a08bf2d31d275c6fc71dd1811342777e95c831 the reading
> of fdinfo files returns "Too many levels of symbolic links"
> error.
Ugh. The fdinfo files aren't symlinks at all, and share the revalidate function.
My bad. The fix isn't pretty, but still better than reverting things.
This should fix it.
Linus
[-- Attachment #2: patch.diff --]
[-- Type: application/octet-stream, Size: 1423 bytes --]
fs/proc/base.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 616f41a7cde6..437195f204e1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1803,7 +1803,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
- unsigned i_mode, f_mode = file->f_mode;
+ unsigned f_mode = file->f_mode;
rcu_read_unlock();
put_files_struct(files);
@@ -1819,12 +1819,14 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
inode->i_gid = GLOBAL_ROOT_GID;
}
- i_mode = S_IFLNK;
- if (f_mode & FMODE_READ)
- i_mode |= S_IRUSR | S_IXUSR;
- if (f_mode & FMODE_WRITE)
- i_mode |= S_IWUSR | S_IXUSR;
- inode->i_mode = i_mode;
+ if (S_ISLNK(inode->i_mode)) {
+ unsigned i_mode = S_IFLNK;
+ if (f_mode & FMODE_READ)
+ i_mode |= S_IRUSR | S_IXUSR;
+ if (f_mode & FMODE_WRITE)
+ i_mode |= S_IWUSR | S_IXUSR;
+ inode->i_mode = i_mode;
+ }
security_task_to_inode(task, inode);
put_task_struct(task);
@@ -1859,6 +1861,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
ei = PROC_I(inode);
ei->fd = fd;
+ inode->i_mode = S_IFLNK;
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link;
^ permalink raw reply related [flat|nested] 3+ messages in thread