diff options
Diffstat (limited to 'fs/gfs2/file.c')
-rw-r--r-- | fs/gfs2/file.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index b3333371aebb..f99f9e8a325f 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -531,21 +531,30 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) | |||
531 | } | 531 | } |
532 | 532 | ||
533 | /** | 533 | /** |
534 | * gfs2_open - open a file | 534 | * gfs2_open_common - This is common to open and atomic_open |
535 | * @inode: the inode to open | 535 | * @inode: The inode being opened |
536 | * @file: the struct file for this opening | 536 | * @file: The file being opened |
537 | * | 537 | * |
538 | * Returns: errno | 538 | * This maybe called under a glock or not depending upon how it has |
539 | * been called. We must always be called under a glock for regular | ||
540 | * files, however. For other file types, it does not matter whether | ||
541 | * we hold the glock or not. | ||
542 | * | ||
543 | * Returns: Error code or 0 for success | ||
539 | */ | 544 | */ |
540 | 545 | ||
541 | static int gfs2_open(struct inode *inode, struct file *file) | 546 | int gfs2_open_common(struct inode *inode, struct file *file) |
542 | { | 547 | { |
543 | struct gfs2_inode *ip = GFS2_I(inode); | ||
544 | struct gfs2_holder i_gh; | ||
545 | struct gfs2_file *fp; | 548 | struct gfs2_file *fp; |
546 | int error; | 549 | int ret; |
547 | 550 | ||
548 | fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL); | 551 | if (S_ISREG(inode->i_mode)) { |
552 | ret = generic_file_open(inode, file); | ||
553 | if (ret) | ||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | fp = kzalloc(sizeof(struct gfs2_file), GFP_NOFS); | ||
549 | if (!fp) | 558 | if (!fp) |
550 | return -ENOMEM; | 559 | return -ENOMEM; |
551 | 560 | ||
@@ -553,29 +562,43 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
553 | 562 | ||
554 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 563 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
555 | file->private_data = fp; | 564 | file->private_data = fp; |
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * gfs2_open - open a file | ||
570 | * @inode: the inode to open | ||
571 | * @file: the struct file for this opening | ||
572 | * | ||
573 | * After atomic_open, this function is only used for opening files | ||
574 | * which are already cached. We must still get the glock for regular | ||
575 | * files to ensure that we have the file size uptodate for the large | ||
576 | * file check which is in the common code. That is only an issue for | ||
577 | * regular files though. | ||
578 | * | ||
579 | * Returns: errno | ||
580 | */ | ||
581 | |||
582 | static int gfs2_open(struct inode *inode, struct file *file) | ||
583 | { | ||
584 | struct gfs2_inode *ip = GFS2_I(inode); | ||
585 | struct gfs2_holder i_gh; | ||
586 | int error; | ||
587 | bool need_unlock = false; | ||
556 | 588 | ||
557 | if (S_ISREG(ip->i_inode.i_mode)) { | 589 | if (S_ISREG(ip->i_inode.i_mode)) { |
558 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 590 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
559 | &i_gh); | 591 | &i_gh); |
560 | if (error) | 592 | if (error) |
561 | goto fail; | 593 | return error; |
594 | need_unlock = true; | ||
595 | } | ||
562 | 596 | ||
563 | if (!(file->f_flags & O_LARGEFILE) && | 597 | error = gfs2_open_common(inode, file); |
564 | i_size_read(inode) > MAX_NON_LFS) { | ||
565 | error = -EOVERFLOW; | ||
566 | goto fail_gunlock; | ||
567 | } | ||
568 | 598 | ||
599 | if (need_unlock) | ||
569 | gfs2_glock_dq_uninit(&i_gh); | 600 | gfs2_glock_dq_uninit(&i_gh); |
570 | } | ||
571 | |||
572 | return 0; | ||
573 | 601 | ||
574 | fail_gunlock: | ||
575 | gfs2_glock_dq_uninit(&i_gh); | ||
576 | fail: | ||
577 | file->private_data = NULL; | ||
578 | kfree(fp); | ||
579 | return error; | 602 | return error; |
580 | } | 603 | } |
581 | 604 | ||