aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/psdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r--fs/coda/psdev.c88
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 */
55int coda_hard; /* allows signals during upcalls */ 52int coda_hard; /* allows signals during upcalls */
56unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ 53unsigned 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);
267out: 265out:
268 unlock_kernel(); 266 unlock_kernel();
269 return (count ? count : retval); 267 return (count ? count : retval);
@@ -271,71 +269,70 @@ out:
271 269
272static int coda_psdev_open(struct inode * inode, struct file * file) 270static 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
305static int coda_psdev_release(struct inode * inode, struct file * file) 301static 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 376MODULE_AUTHOR("Jan Harkes, Peter J. Braam");
380MODULE_AUTHOR("Peter J. Braam <braam@cs.cmu.edu>"); 377MODULE_DESCRIPTION("Coda Distributed File System VFS interface");
378MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR);
381MODULE_LICENSE("GPL"); 379MODULE_LICENSE("GPL");
380#ifdef CONFIG_CODA_FS_OLD_API
381MODULE_VERSION("5.3.21");
382#else
383MODULE_VERSION("6.6");
384#endif
382 385
383static int __init init_coda(void) 386static 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)