diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2008-10-16 01:02:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 14:21:38 -0400 |
commit | 7d6c7045581d3736c5f14053eb59342aa0b2cc07 (patch) | |
tree | 3906a3e8b0d4a2e4752c4eb19defc62691d200d7 /fs/ecryptfs/file.c | |
parent | 9d793b0bcbbbc37d80241862dfa5257963d5415e (diff) |
eCryptfs: remove retry loop in ecryptfs_readdir()
The retry block in ecryptfs_readdir() has been in the eCryptfs code base
for a while, apparently for no good reason. This loop could potentially
run without terminating. This patch removes the loop, instead erroring
out if vfs_readdir() on the lower file fails.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Reported-by: Al Viro <viro@ZinIV.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 9244d653743e..eb3dc4c7ac06 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -71,12 +71,11 @@ struct ecryptfs_getdents_callback { | |||
71 | void *dirent; | 71 | void *dirent; |
72 | struct dentry *dentry; | 72 | struct dentry *dentry; |
73 | filldir_t filldir; | 73 | filldir_t filldir; |
74 | int err; | ||
75 | int filldir_called; | 74 | int filldir_called; |
76 | int entries_written; | 75 | int entries_written; |
77 | }; | 76 | }; |
78 | 77 | ||
79 | /* Inspired by generic filldir in fs/readir.c */ | 78 | /* Inspired by generic filldir in fs/readdir.c */ |
80 | static int | 79 | static int |
81 | ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset, | 80 | ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset, |
82 | u64 ino, unsigned int d_type) | 81 | u64 ino, unsigned int d_type) |
@@ -125,18 +124,18 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
125 | buf.dirent = dirent; | 124 | buf.dirent = dirent; |
126 | buf.dentry = file->f_path.dentry; | 125 | buf.dentry = file->f_path.dentry; |
127 | buf.filldir = filldir; | 126 | buf.filldir = filldir; |
128 | retry: | ||
129 | buf.filldir_called = 0; | 127 | buf.filldir_called = 0; |
130 | buf.entries_written = 0; | 128 | buf.entries_written = 0; |
131 | buf.err = 0; | ||
132 | rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf); | 129 | rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf); |
133 | if (buf.err) | ||
134 | rc = buf.err; | ||
135 | if (buf.filldir_called && !buf.entries_written) | ||
136 | goto retry; | ||
137 | file->f_pos = lower_file->f_pos; | 130 | file->f_pos = lower_file->f_pos; |
131 | if (rc < 0) | ||
132 | goto out; | ||
133 | if (buf.filldir_called && !buf.entries_written) | ||
134 | goto out; | ||
138 | if (rc >= 0) | 135 | if (rc >= 0) |
139 | fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode); | 136 | fsstack_copy_attr_atime(inode, |
137 | lower_file->f_path.dentry->d_inode); | ||
138 | out: | ||
140 | return rc; | 139 | return rc; |
141 | } | 140 | } |
142 | 141 | ||