diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 12:02:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 12:02:13 -0500 |
commit | 2608e3d0fa63b892f37a9f1921c2d2b37c7933c1 (patch) | |
tree | aca8b61fd63390edf5ddfe17b8ae35dfd56ed74d | |
parent | 33673dcb372b5d8179c22127ca71deb5f3dc7016 (diff) | |
parent | b6f4bee02f682d1c86ece297871b78ae01afaaf4 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull v9fs updates from Eric Van Hensbergen:
"Just fixes and simplifications"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
fs/9p: Fix atomic_open
fs/9p: Don't use O_TRUNC flag in TOPEN and TLOPEN request
locking in fs/9p ->readdir()
-rw-r--r-- | fs/9p/vfs_dir.c | 92 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 4 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 3 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 11 |
4 files changed, 31 insertions, 79 deletions
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index ff911e779651..be1e34adc3c6 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -52,10 +52,9 @@ | |||
52 | */ | 52 | */ |
53 | 53 | ||
54 | struct p9_rdir { | 54 | struct p9_rdir { |
55 | struct mutex mutex; | ||
56 | int head; | 55 | int head; |
57 | int tail; | 56 | int tail; |
58 | uint8_t *buf; | 57 | uint8_t buf[]; |
59 | }; | 58 | }; |
60 | 59 | ||
61 | /** | 60 | /** |
@@ -93,33 +92,12 @@ static void p9stat_init(struct p9_wstat *stbuf) | |||
93 | * | 92 | * |
94 | */ | 93 | */ |
95 | 94 | ||
96 | static int v9fs_alloc_rdir_buf(struct file *filp, int buflen) | 95 | static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen) |
97 | { | 96 | { |
98 | struct p9_rdir *rdir; | 97 | struct p9_fid *fid = filp->private_data; |
99 | struct p9_fid *fid; | 98 | if (!fid->rdir) |
100 | int err = 0; | 99 | fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL); |
101 | 100 | return fid->rdir; | |
102 | fid = filp->private_data; | ||
103 | if (!fid->rdir) { | ||
104 | rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL); | ||
105 | |||
106 | if (rdir == NULL) { | ||
107 | err = -ENOMEM; | ||
108 | goto exit; | ||
109 | } | ||
110 | spin_lock(&filp->f_dentry->d_lock); | ||
111 | if (!fid->rdir) { | ||
112 | rdir->buf = (uint8_t *)rdir + sizeof(struct p9_rdir); | ||
113 | mutex_init(&rdir->mutex); | ||
114 | rdir->head = rdir->tail = 0; | ||
115 | fid->rdir = (void *) rdir; | ||
116 | rdir = NULL; | ||
117 | } | ||
118 | spin_unlock(&filp->f_dentry->d_lock); | ||
119 | kfree(rdir); | ||
120 | } | ||
121 | exit: | ||
122 | return err; | ||
123 | } | 101 | } |
124 | 102 | ||
125 | /** | 103 | /** |
@@ -145,20 +123,16 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
145 | 123 | ||
146 | buflen = fid->clnt->msize - P9_IOHDRSZ; | 124 | buflen = fid->clnt->msize - P9_IOHDRSZ; |
147 | 125 | ||
148 | err = v9fs_alloc_rdir_buf(filp, buflen); | 126 | rdir = v9fs_alloc_rdir_buf(filp, buflen); |
149 | if (err) | 127 | if (!rdir) |
150 | goto exit; | 128 | return -ENOMEM; |
151 | rdir = (struct p9_rdir *) fid->rdir; | ||
152 | 129 | ||
153 | err = mutex_lock_interruptible(&rdir->mutex); | 130 | while (1) { |
154 | if (err) | ||
155 | return err; | ||
156 | while (err == 0) { | ||
157 | if (rdir->tail == rdir->head) { | 131 | if (rdir->tail == rdir->head) { |
158 | err = v9fs_file_readn(filp, rdir->buf, NULL, | 132 | err = v9fs_file_readn(filp, rdir->buf, NULL, |
159 | buflen, filp->f_pos); | 133 | buflen, filp->f_pos); |
160 | if (err <= 0) | 134 | if (err <= 0) |
161 | goto unlock_and_exit; | 135 | return err; |
162 | 136 | ||
163 | rdir->head = 0; | 137 | rdir->head = 0; |
164 | rdir->tail = err; | 138 | rdir->tail = err; |
@@ -169,9 +143,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
169 | rdir->tail - rdir->head, &st); | 143 | rdir->tail - rdir->head, &st); |
170 | if (err) { | 144 | if (err) { |
171 | p9_debug(P9_DEBUG_VFS, "returned %d\n", err); | 145 | p9_debug(P9_DEBUG_VFS, "returned %d\n", err); |
172 | err = -EIO; | ||
173 | p9stat_free(&st); | 146 | p9stat_free(&st); |
174 | goto unlock_and_exit; | 147 | return -EIO; |
175 | } | 148 | } |
176 | reclen = st.size+2; | 149 | reclen = st.size+2; |
177 | 150 | ||
@@ -180,19 +153,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
180 | 153 | ||
181 | p9stat_free(&st); | 154 | p9stat_free(&st); |
182 | 155 | ||
183 | if (over) { | 156 | if (over) |
184 | err = 0; | 157 | return 0; |
185 | goto unlock_and_exit; | 158 | |
186 | } | ||
187 | rdir->head += reclen; | 159 | rdir->head += reclen; |
188 | filp->f_pos += reclen; | 160 | filp->f_pos += reclen; |
189 | } | 161 | } |
190 | } | 162 | } |
191 | |||
192 | unlock_and_exit: | ||
193 | mutex_unlock(&rdir->mutex); | ||
194 | exit: | ||
195 | return err; | ||
196 | } | 163 | } |
197 | 164 | ||
198 | /** | 165 | /** |
@@ -218,21 +185,16 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent, | |||
218 | 185 | ||
219 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; | 186 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; |
220 | 187 | ||
221 | err = v9fs_alloc_rdir_buf(filp, buflen); | 188 | rdir = v9fs_alloc_rdir_buf(filp, buflen); |
222 | if (err) | 189 | if (!rdir) |
223 | goto exit; | 190 | return -ENOMEM; |
224 | rdir = (struct p9_rdir *) fid->rdir; | ||
225 | 191 | ||
226 | err = mutex_lock_interruptible(&rdir->mutex); | 192 | while (1) { |
227 | if (err) | ||
228 | return err; | ||
229 | |||
230 | while (err == 0) { | ||
231 | if (rdir->tail == rdir->head) { | 193 | if (rdir->tail == rdir->head) { |
232 | err = p9_client_readdir(fid, rdir->buf, buflen, | 194 | err = p9_client_readdir(fid, rdir->buf, buflen, |
233 | filp->f_pos); | 195 | filp->f_pos); |
234 | if (err <= 0) | 196 | if (err <= 0) |
235 | goto unlock_and_exit; | 197 | return err; |
236 | 198 | ||
237 | rdir->head = 0; | 199 | rdir->head = 0; |
238 | rdir->tail = err; | 200 | rdir->tail = err; |
@@ -245,8 +207,7 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent, | |||
245 | &curdirent); | 207 | &curdirent); |
246 | if (err < 0) { | 208 | if (err < 0) { |
247 | p9_debug(P9_DEBUG_VFS, "returned %d\n", err); | 209 | p9_debug(P9_DEBUG_VFS, "returned %d\n", err); |
248 | err = -EIO; | 210 | return -EIO; |
249 | goto unlock_and_exit; | ||
250 | } | 211 | } |
251 | 212 | ||
252 | /* d_off in dirent structure tracks the offset into | 213 | /* d_off in dirent structure tracks the offset into |
@@ -261,20 +222,13 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent, | |||
261 | curdirent.d_type); | 222 | curdirent.d_type); |
262 | oldoffset = curdirent.d_off; | 223 | oldoffset = curdirent.d_off; |
263 | 224 | ||
264 | if (over) { | 225 | if (over) |
265 | err = 0; | 226 | return 0; |
266 | goto unlock_and_exit; | ||
267 | } | ||
268 | 227 | ||
269 | filp->f_pos = curdirent.d_off; | 228 | filp->f_pos = curdirent.d_off; |
270 | rdir->head += err; | 229 | rdir->head += err; |
271 | } | 230 | } |
272 | } | 231 | } |
273 | |||
274 | unlock_and_exit: | ||
275 | mutex_unlock(&rdir->mutex); | ||
276 | exit: | ||
277 | return err; | ||
278 | } | 232 | } |
279 | 233 | ||
280 | 234 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c2483e97beee..7a3399767570 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -80,10 +80,6 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
80 | p9_client_clunk(fid); | 80 | p9_client_clunk(fid); |
81 | return err; | 81 | return err; |
82 | } | 82 | } |
83 | if (file->f_flags & O_TRUNC) { | ||
84 | i_size_write(inode, 0); | ||
85 | inode->i_blocks = 0; | ||
86 | } | ||
87 | if ((file->f_flags & O_APPEND) && | 83 | if ((file->f_flags & O_APPEND) && |
88 | (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses))) | 84 | (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses))) |
89 | generic_file_llseek(file, 0, SEEK_END); | 85 | generic_file_llseek(file, 0, SEEK_END); |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 890bed538f9b..57d017ac68e4 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -192,9 +192,6 @@ int v9fs_uflags2omode(int uflags, int extended) | |||
192 | break; | 192 | break; |
193 | } | 193 | } |
194 | 194 | ||
195 | if (uflags & O_TRUNC) | ||
196 | ret |= P9_OTRUNC; | ||
197 | |||
198 | if (extended) { | 195 | if (extended) { |
199 | if (uflags & O_EXCL) | 196 | if (uflags & O_EXCL) |
200 | ret |= P9_OEXCL; | 197 | ret |= P9_OEXCL; |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 40895546e103..8d24ad66dfb8 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -186,7 +186,6 @@ static int v9fs_mapped_dotl_flags(int flags) | |||
186 | { O_CREAT, P9_DOTL_CREATE }, | 186 | { O_CREAT, P9_DOTL_CREATE }, |
187 | { O_EXCL, P9_DOTL_EXCL }, | 187 | { O_EXCL, P9_DOTL_EXCL }, |
188 | { O_NOCTTY, P9_DOTL_NOCTTY }, | 188 | { O_NOCTTY, P9_DOTL_NOCTTY }, |
189 | { O_TRUNC, P9_DOTL_TRUNC }, | ||
190 | { O_APPEND, P9_DOTL_APPEND }, | 189 | { O_APPEND, P9_DOTL_APPEND }, |
191 | { O_NONBLOCK, P9_DOTL_NONBLOCK }, | 190 | { O_NONBLOCK, P9_DOTL_NONBLOCK }, |
192 | { O_DSYNC, P9_DOTL_DSYNC }, | 191 | { O_DSYNC, P9_DOTL_DSYNC }, |
@@ -268,8 +267,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
268 | } | 267 | } |
269 | 268 | ||
270 | /* Only creates */ | 269 | /* Only creates */ |
271 | if (!(flags & O_CREAT) || dentry->d_inode) | 270 | if (!(flags & O_CREAT)) |
272 | return finish_no_open(file, res); | 271 | return finish_no_open(file, res); |
272 | else if (dentry->d_inode) { | ||
273 | if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | ||
274 | return -EEXIST; | ||
275 | else | ||
276 | return finish_no_open(file, res); | ||
277 | } | ||
273 | 278 | ||
274 | v9ses = v9fs_inode2v9ses(dir); | 279 | v9ses = v9fs_inode2v9ses(dir); |
275 | 280 | ||