diff options
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r-- | fs/coda/psdev.c | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 803aacf0d49c..dcc6aead70f5 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -45,12 +45,9 @@ | |||
45 | #include <linux/coda_linux.h> | 45 | #include <linux/coda_linux.h> |
46 | #include <linux/coda_fs_i.h> | 46 | #include <linux/coda_fs_i.h> |
47 | #include <linux/coda_psdev.h> | 47 | #include <linux/coda_psdev.h> |
48 | #include <linux/coda_proc.h> | ||
49 | 48 | ||
50 | #include "coda_int.h" | 49 | #include "coda_int.h" |
51 | 50 | ||
52 | #define upc_free(r) kfree(r) | ||
53 | |||
54 | /* statistics */ | 51 | /* statistics */ |
55 | int coda_hard; /* allows signals during upcalls */ | 52 | int coda_hard; /* allows signals during upcalls */ |
56 | unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ | 53 | unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ |
@@ -195,7 +192,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
195 | if (req->uc_opcode == CODA_OPEN_BY_FD) { | 192 | if (req->uc_opcode == CODA_OPEN_BY_FD) { |
196 | struct coda_open_by_fd_out *outp = | 193 | struct coda_open_by_fd_out *outp = |
197 | (struct coda_open_by_fd_out *)req->uc_data; | 194 | (struct coda_open_by_fd_out *)req->uc_data; |
198 | outp->fh = fget(outp->fd); | 195 | if (!outp->oh.result) |
196 | outp->fh = fget(outp->fd); | ||
199 | } | 197 | } |
200 | 198 | ||
201 | wake_up(&req->uc_sleep); | 199 | wake_up(&req->uc_sleep); |
@@ -263,7 +261,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
263 | } | 261 | } |
264 | 262 | ||
265 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 263 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
266 | upc_free(req); | 264 | kfree(req); |
267 | out: | 265 | out: |
268 | unlock_kernel(); | 266 | unlock_kernel(); |
269 | return (count ? count : retval); | 267 | return (count ? count : retval); |
@@ -271,71 +269,70 @@ out: | |||
271 | 269 | ||
272 | static int coda_psdev_open(struct inode * inode, struct file * file) | 270 | static int coda_psdev_open(struct inode * inode, struct file * file) |
273 | { | 271 | { |
274 | struct venus_comm *vcp; | 272 | struct venus_comm *vcp; |
275 | int idx; | 273 | int idx, err; |
276 | 274 | ||
277 | lock_kernel(); | ||
278 | idx = iminor(inode); | 275 | idx = iminor(inode); |
279 | if(idx >= MAX_CODADEVS) { | 276 | if (idx < 0 || idx >= MAX_CODADEVS) |
280 | unlock_kernel(); | ||
281 | return -ENODEV; | 277 | return -ENODEV; |
282 | } | ||
283 | 278 | ||
279 | lock_kernel(); | ||
280 | |||
281 | err = -EBUSY; | ||
284 | vcp = &coda_comms[idx]; | 282 | vcp = &coda_comms[idx]; |
285 | if(vcp->vc_inuse) { | 283 | if (!vcp->vc_inuse) { |
286 | unlock_kernel(); | 284 | vcp->vc_inuse++; |
287 | return -EBUSY; | 285 | |
288 | } | ||
289 | |||
290 | if (!vcp->vc_inuse++) { | ||
291 | INIT_LIST_HEAD(&vcp->vc_pending); | 286 | INIT_LIST_HEAD(&vcp->vc_pending); |
292 | INIT_LIST_HEAD(&vcp->vc_processing); | 287 | INIT_LIST_HEAD(&vcp->vc_processing); |
293 | init_waitqueue_head(&vcp->vc_waitq); | 288 | init_waitqueue_head(&vcp->vc_waitq); |
294 | vcp->vc_sb = NULL; | 289 | vcp->vc_sb = NULL; |
295 | vcp->vc_seq = 0; | 290 | vcp->vc_seq = 0; |
291 | |||
292 | file->private_data = vcp; | ||
293 | err = 0; | ||
296 | } | 294 | } |
297 | |||
298 | file->private_data = vcp; | ||
299 | 295 | ||
300 | unlock_kernel(); | 296 | unlock_kernel(); |
301 | return 0; | 297 | return err; |
302 | } | 298 | } |
303 | 299 | ||
304 | 300 | ||
305 | static int coda_psdev_release(struct inode * inode, struct file * file) | 301 | static int coda_psdev_release(struct inode * inode, struct file * file) |
306 | { | 302 | { |
307 | struct venus_comm *vcp = (struct venus_comm *) file->private_data; | 303 | struct venus_comm *vcp = (struct venus_comm *) file->private_data; |
308 | struct upc_req *req, *tmp; | 304 | struct upc_req *req, *tmp; |
309 | 305 | ||
310 | lock_kernel(); | 306 | if (!vcp || !vcp->vc_inuse ) { |
311 | if ( !vcp->vc_inuse ) { | ||
312 | unlock_kernel(); | ||
313 | printk("psdev_release: Not open.\n"); | 307 | printk("psdev_release: Not open.\n"); |
314 | return -1; | 308 | return -1; |
315 | } | 309 | } |
316 | 310 | ||
317 | if (--vcp->vc_inuse) { | 311 | lock_kernel(); |
318 | unlock_kernel(); | 312 | |
319 | return 0; | 313 | /* Wakeup clients so they can return. */ |
320 | } | ||
321 | |||
322 | /* Wakeup clients so they can return. */ | ||
323 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { | 314 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { |
315 | list_del(&req->uc_chain); | ||
316 | |||
324 | /* Async requests need to be freed here */ | 317 | /* Async requests need to be freed here */ |
325 | if (req->uc_flags & REQ_ASYNC) { | 318 | if (req->uc_flags & REQ_ASYNC) { |
326 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 319 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
327 | upc_free(req); | 320 | kfree(req); |
328 | continue; | 321 | continue; |
329 | } | 322 | } |
330 | req->uc_flags |= REQ_ABORT; | 323 | req->uc_flags |= REQ_ABORT; |
331 | wake_up(&req->uc_sleep); | 324 | wake_up(&req->uc_sleep); |
332 | } | 325 | } |
333 | 326 | ||
334 | list_for_each_entry(req, &vcp->vc_processing, uc_chain) { | 327 | list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { |
328 | list_del(&req->uc_chain); | ||
329 | |||
335 | req->uc_flags |= REQ_ABORT; | 330 | req->uc_flags |= REQ_ABORT; |
336 | wake_up(&req->uc_sleep); | 331 | wake_up(&req->uc_sleep); |
337 | } | 332 | } |
338 | 333 | ||
334 | file->private_data = NULL; | ||
335 | vcp->vc_inuse--; | ||
339 | unlock_kernel(); | 336 | unlock_kernel(); |
340 | return 0; | 337 | return 0; |
341 | } | 338 | } |
@@ -376,21 +373,20 @@ out: | |||
376 | return err; | 373 | return err; |
377 | } | 374 | } |
378 | 375 | ||
379 | 376 | MODULE_AUTHOR("Jan Harkes, Peter J. Braam"); | |
380 | MODULE_AUTHOR("Peter J. Braam <braam@cs.cmu.edu>"); | 377 | MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); |
378 | MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); | ||
381 | MODULE_LICENSE("GPL"); | 379 | MODULE_LICENSE("GPL"); |
380 | #ifdef CONFIG_CODA_FS_OLD_API | ||
381 | MODULE_VERSION("5.3.21"); | ||
382 | #else | ||
383 | MODULE_VERSION("6.6"); | ||
384 | #endif | ||
382 | 385 | ||
383 | static int __init init_coda(void) | 386 | static int __init init_coda(void) |
384 | { | 387 | { |
385 | int status; | 388 | int status; |
386 | int i; | 389 | int i; |
387 | printk(KERN_INFO "Coda Kernel/Venus communications, " | ||
388 | #ifdef CONFIG_CODA_FS_OLD_API | ||
389 | "v5.3.20" | ||
390 | #else | ||
391 | "v6.0.0" | ||
392 | #endif | ||
393 | ", coda@cs.cmu.edu\n"); | ||
394 | 390 | ||
395 | status = coda_init_inodecache(); | 391 | status = coda_init_inodecache(); |
396 | if (status) | 392 | if (status) |