X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fcoda%2Fpsdev.c;h=e3eb3556622b6808c6d15515e18e597a0ddc4f5b;hb=1df5a8d004f64b1aa3fb93e0556886ba00ebc979;hp=7caee8d8ea3b9a24656f40a20c247986f796d39f;hpb=8f7c58814eb75bf97b8bc18d107b2e26f28b6585;p=linux-2.6 diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 7caee8d8ea..e3eb355662 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -46,12 +45,9 @@ #include #include #include -#include #include "coda_int.h" -#define upc_free(r) kfree(r) - /* statistics */ int coda_hard; /* allows signals during upcalls */ unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ @@ -196,7 +192,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, if (req->uc_opcode == CODA_OPEN_BY_FD) { struct coda_open_by_fd_out *outp = (struct coda_open_by_fd_out *)req->uc_data; - outp->fh = fget(outp->fd); + if (!outp->oh.result) + outp->fh = fget(outp->fd); } wake_up(&req->uc_sleep); @@ -264,7 +261,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, } CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); - upc_free(req); + kfree(req); out: unlock_kernel(); return (count ? count : retval); @@ -272,71 +269,70 @@ out: static int coda_psdev_open(struct inode * inode, struct file * file) { - struct venus_comm *vcp; - int idx; + struct venus_comm *vcp; + int idx, err; - lock_kernel(); idx = iminor(inode); - if(idx >= MAX_CODADEVS) { - unlock_kernel(); + if (idx < 0 || idx >= MAX_CODADEVS) return -ENODEV; - } + lock_kernel(); + + err = -EBUSY; vcp = &coda_comms[idx]; - if(vcp->vc_inuse) { - unlock_kernel(); - return -EBUSY; - } - - if (!vcp->vc_inuse++) { + if (!vcp->vc_inuse) { + vcp->vc_inuse++; + INIT_LIST_HEAD(&vcp->vc_pending); INIT_LIST_HEAD(&vcp->vc_processing); init_waitqueue_head(&vcp->vc_waitq); vcp->vc_sb = NULL; vcp->vc_seq = 0; + + file->private_data = vcp; + err = 0; } - - file->private_data = vcp; unlock_kernel(); - return 0; + return err; } static int coda_psdev_release(struct inode * inode, struct file * file) { - struct venus_comm *vcp = (struct venus_comm *) file->private_data; - struct upc_req *req, *tmp; + struct venus_comm *vcp = (struct venus_comm *) file->private_data; + struct upc_req *req, *tmp; - lock_kernel(); - if ( !vcp->vc_inuse ) { - unlock_kernel(); + if (!vcp || !vcp->vc_inuse ) { printk("psdev_release: Not open.\n"); return -1; } - if (--vcp->vc_inuse) { - unlock_kernel(); - return 0; - } - - /* Wakeup clients so they can return. */ + lock_kernel(); + + /* Wakeup clients so they can return. */ list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { + list_del(&req->uc_chain); + /* Async requests need to be freed here */ if (req->uc_flags & REQ_ASYNC) { CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); - upc_free(req); + kfree(req); continue; } req->uc_flags |= REQ_ABORT; wake_up(&req->uc_sleep); - } - - list_for_each_entry(req, &vcp->vc_processing, uc_chain) { + } + + list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { + list_del(&req->uc_chain); + req->uc_flags |= REQ_ABORT; - wake_up(&req->uc_sleep); - } + wake_up(&req->uc_sleep); + } + file->private_data = NULL; + vcp->vc_inuse--; unlock_kernel(); return 0; } @@ -365,43 +361,32 @@ static int init_coda_psdev(void) err = PTR_ERR(coda_psdev_class); goto out_chrdev; } - devfs_mk_dir ("coda"); - for (i = 0; i < MAX_CODADEVS; i++) { - class_device_create(coda_psdev_class, NULL, - MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i); - err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i), - S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i); - if (err) - goto out_class; - } + for (i = 0; i < MAX_CODADEVS; i++) + device_create(coda_psdev_class, NULL, + MKDEV(CODA_PSDEV_MAJOR,i), "cfs%d", i); coda_sysctl_init(); goto out; -out_class: - for (i = 0; i < MAX_CODADEVS; i++) - class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); - class_destroy(coda_psdev_class); out_chrdev: unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); out: return err; } - -MODULE_AUTHOR("Peter J. Braam "); +MODULE_AUTHOR("Jan Harkes, Peter J. Braam"); +MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); +MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); MODULE_LICENSE("GPL"); +#ifdef CONFIG_CODA_FS_OLD_API +MODULE_VERSION("5.3.21"); +#else +MODULE_VERSION("6.6"); +#endif static int __init init_coda(void) { int status; int i; - printk(KERN_INFO "Coda Kernel/Venus communications, " -#ifdef CONFIG_CODA_FS_OLD_API - "v5.3.20" -#else - "v6.0.0" -#endif - ", coda@cs.cmu.edu\n"); status = coda_init_inodecache(); if (status) @@ -419,12 +404,9 @@ static int __init init_coda(void) } return 0; out: - for (i = 0; i < MAX_CODADEVS; i++) { - class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); - devfs_remove("coda/%d", i); - } + for (i = 0; i < MAX_CODADEVS; i++) + device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); class_destroy(coda_psdev_class); - devfs_remove("coda"); unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); coda_sysctl_clean(); out1: @@ -441,12 +423,9 @@ static void __exit exit_coda(void) if ( err != 0 ) { printk("coda: failed to unregister filesystem\n"); } - for (i = 0; i < MAX_CODADEVS; i++) { - class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); - devfs_remove("coda/%d", i); - } + for (i = 0; i < MAX_CODADEVS; i++) + device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); class_destroy(coda_psdev_class); - devfs_remove("coda"); unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); coda_sysctl_clean(); coda_destroy_inodecache();