dir.c (47237687d73cbeae1dd7a133c3fc3d7239094568) | dir.c (d95852777bc8ba6b3ad3397d495c5f9dd8ca8383) |
---|---|
1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 355 unchanged lines hidden (view full) --- 364} 365 366/* 367 * Atomic create+open operation 368 * 369 * If the filesystem doesn't support this, then fall back to separate 370 * 'mknod' + 'open' requests. 371 */ | 1/* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU GPL. 6 See the file COPYING. 7*/ 8 --- 355 unchanged lines hidden (view full) --- 364} 365 366/* 367 * Atomic create+open operation 368 * 369 * If the filesystem doesn't support this, then fall back to separate 370 * 'mknod' + 'open' requests. 371 */ |
372static struct file *fuse_create_open(struct inode *dir, struct dentry *entry, 373 struct opendata *od, unsigned flags, 374 umode_t mode, int *opened) | 372static int fuse_create_open(struct inode *dir, struct dentry *entry, 373 struct opendata *od, unsigned flags, 374 umode_t mode, int *opened) |
375{ 376 int err; 377 struct inode *inode; 378 struct fuse_conn *fc = get_fuse_conn(dir); 379 struct fuse_req *req; 380 struct fuse_forget_link *forget; 381 struct fuse_create_in inarg; 382 struct fuse_open_out outopen; --- 64 unchanged lines hidden (view full) --- 447 goto out_err; 448 } 449 kfree(forget); 450 d_instantiate(entry, inode); 451 fuse_change_entry_timeout(entry, &outentry); 452 fuse_invalidate_attr(dir); 453 file = finish_open(od, entry, generic_file_open, opened); 454 if (IS_ERR(file)) { | 375{ 376 int err; 377 struct inode *inode; 378 struct fuse_conn *fc = get_fuse_conn(dir); 379 struct fuse_req *req; 380 struct fuse_forget_link *forget; 381 struct fuse_create_in inarg; 382 struct fuse_open_out outopen; --- 64 unchanged lines hidden (view full) --- 447 goto out_err; 448 } 449 kfree(forget); 450 d_instantiate(entry, inode); 451 fuse_change_entry_timeout(entry, &outentry); 452 fuse_invalidate_attr(dir); 453 file = finish_open(od, entry, generic_file_open, opened); 454 if (IS_ERR(file)) { |
455 err = PTR_ERR(file); |
|
455 fuse_sync_release(ff, flags); 456 } else { 457 file->private_data = fuse_file_get(ff); 458 fuse_finish_open(inode, file); | 456 fuse_sync_release(ff, flags); 457 } else { 458 file->private_data = fuse_file_get(ff); 459 fuse_finish_open(inode, file); |
460 err = 0; |
|
459 } | 461 } |
460 return file; | 462 return err; |
461 462out_free_ff: 463 fuse_file_free(ff); 464out_put_request: 465 fuse_put_request(fc, req); 466out_put_forget_req: 467 kfree(forget); 468out_err: | 463 464out_free_ff: 465 fuse_file_free(ff); 466out_put_request: 467 fuse_put_request(fc, req); 468out_put_forget_req: 469 kfree(forget); 470out_err: |
469 return ERR_PTR(err); | 471 return err; |
470} 471 472static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); | 472} 473 474static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); |
473static struct file *fuse_atomic_open(struct inode *dir, struct dentry *entry, 474 struct opendata *od, unsigned flags, 475 umode_t mode, int *opened) | 475static int fuse_atomic_open(struct inode *dir, struct dentry *entry, 476 struct opendata *od, unsigned flags, 477 umode_t mode, int *opened) |
476{ 477 int err; 478 struct fuse_conn *fc = get_fuse_conn(dir); | 478{ 479 int err; 480 struct fuse_conn *fc = get_fuse_conn(dir); |
479 struct file *file; | |
480 struct dentry *res = NULL; 481 482 if (d_unhashed(entry)) { 483 res = fuse_lookup(dir, entry, NULL); 484 if (IS_ERR(res)) | 481 struct dentry *res = NULL; 482 483 if (d_unhashed(entry)) { 484 res = fuse_lookup(dir, entry, NULL); 485 if (IS_ERR(res)) |
485 return ERR_CAST(res); | 486 return PTR_ERR(res); |
486 487 if (res) 488 entry = res; 489 } 490 491 if (!(flags & O_CREAT) || entry->d_inode) 492 goto no_open; 493 494 /* Only creates */ 495 *opened |= FILE_CREATED; 496 497 if (fc->no_create) 498 goto mknod; 499 | 487 488 if (res) 489 entry = res; 490 } 491 492 if (!(flags & O_CREAT) || entry->d_inode) 493 goto no_open; 494 495 /* Only creates */ 496 *opened |= FILE_CREATED; 497 498 if (fc->no_create) 499 goto mknod; 500 |
500 file = fuse_create_open(dir, entry, od, flags, mode, opened); 501 if (PTR_ERR(file) == -ENOSYS) { | 501 err = fuse_create_open(dir, entry, od, flags, mode, opened); 502 if (err == -ENOSYS) { |
502 fc->no_create = 1; 503 goto mknod; 504 } 505out_dput: 506 dput(res); | 503 fc->no_create = 1; 504 goto mknod; 505 } 506out_dput: 507 dput(res); |
507 return file; | 508 return err; |
508 509mknod: 510 err = fuse_mknod(dir, entry, mode, 0); | 509 510mknod: 511 err = fuse_mknod(dir, entry, mode, 0); |
511 if (err) { 512 file = ERR_PTR(err); | 512 if (err) |
513 goto out_dput; | 513 goto out_dput; |
514 } | |
515no_open: 516 finish_no_open(od, res); | 514no_open: 515 finish_no_open(od, res); |
517 return NULL; | 516 return 1; |
518} 519 520/* 521 * Code shared between mknod, mkdir, symlink and link 522 */ 523static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, 524 struct inode *dir, struct dentry *entry, 525 umode_t mode) --- 1220 unchanged lines hidden --- | 517} 518 519/* 520 * Code shared between mknod, mkdir, symlink and link 521 */ 522static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, 523 struct inode *dir, struct dentry *entry, 524 umode_t mode) --- 1220 unchanged lines hidden --- |