diff options
Diffstat (limited to 'fs/gfs2/ops_file.c')
-rw-r--r-- | fs/gfs2/ops_file.c | 81 |
1 files changed, 28 insertions, 53 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 93fe41b67f97..70b9b8548945 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -20,9 +20,10 @@ | |||
20 | #include <linux/gfs2_ondisk.h> | 20 | #include <linux/gfs2_ondisk.h> |
21 | #include <linux/ext2_fs.h> | 21 | #include <linux/ext2_fs.h> |
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/lm_interface.h> | ||
24 | #include <linux/writeback.h> | 23 | #include <linux/writeback.h> |
25 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <linux/dlm.h> | ||
26 | #include <linux/dlm_plock.h> | ||
26 | 27 | ||
27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
28 | #include "incore.h" | 29 | #include "incore.h" |
@@ -336,8 +337,9 @@ static int gfs2_allocate_page_backing(struct page *page) | |||
336 | * blocks allocated on disk to back that page. | 337 | * blocks allocated on disk to back that page. |
337 | */ | 338 | */ |
338 | 339 | ||
339 | static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | 340 | static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) |
340 | { | 341 | { |
342 | struct page *page = vmf->page; | ||
341 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 343 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
342 | struct gfs2_inode *ip = GFS2_I(inode); | 344 | struct gfs2_inode *ip = GFS2_I(inode); |
343 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 345 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -354,7 +356,9 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
354 | if (ret) | 356 | if (ret) |
355 | goto out; | 357 | goto out; |
356 | 358 | ||
359 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); | ||
357 | set_bit(GIF_SW_PAGED, &ip->i_flags); | 360 | set_bit(GIF_SW_PAGED, &ip->i_flags); |
361 | |||
358 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); | 362 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); |
359 | if (ret || !alloc_required) | 363 | if (ret || !alloc_required) |
360 | goto out_unlock; | 364 | goto out_unlock; |
@@ -409,6 +413,8 @@ out_unlock: | |||
409 | gfs2_glock_dq(&gh); | 413 | gfs2_glock_dq(&gh); |
410 | out: | 414 | out: |
411 | gfs2_holder_uninit(&gh); | 415 | gfs2_holder_uninit(&gh); |
416 | if (ret) | ||
417 | ret = VM_FAULT_SIGBUS; | ||
412 | return ret; | 418 | return ret; |
413 | } | 419 | } |
414 | 420 | ||
@@ -560,57 +566,24 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
560 | return ret; | 566 | return ret; |
561 | } | 567 | } |
562 | 568 | ||
569 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | ||
570 | |||
563 | /** | 571 | /** |
564 | * gfs2_setlease - acquire/release a file lease | 572 | * gfs2_setlease - acquire/release a file lease |
565 | * @file: the file pointer | 573 | * @file: the file pointer |
566 | * @arg: lease type | 574 | * @arg: lease type |
567 | * @fl: file lock | 575 | * @fl: file lock |
568 | * | 576 | * |
577 | * We don't currently have a way to enforce a lease across the whole | ||
578 | * cluster; until we do, disable leases (by just returning -EINVAL), | ||
579 | * unless the administrator has requested purely local locking. | ||
580 | * | ||
569 | * Returns: errno | 581 | * Returns: errno |
570 | */ | 582 | */ |
571 | 583 | ||
572 | static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) | 584 | static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) |
573 | { | 585 | { |
574 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | 586 | return -EINVAL; |
575 | |||
576 | /* | ||
577 | * We don't currently have a way to enforce a lease across the whole | ||
578 | * cluster; until we do, disable leases (by just returning -EINVAL), | ||
579 | * unless the administrator has requested purely local locking. | ||
580 | */ | ||
581 | if (!sdp->sd_args.ar_localflocks) | ||
582 | return -EINVAL; | ||
583 | return generic_setlease(file, arg, fl); | ||
584 | } | ||
585 | |||
586 | static int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name, | ||
587 | struct file *file, struct file_lock *fl) | ||
588 | { | ||
589 | int error = -EIO; | ||
590 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
591 | error = sdp->sd_lockstruct.ls_ops->lm_plock_get( | ||
592 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); | ||
593 | return error; | ||
594 | } | ||
595 | |||
596 | static int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name, | ||
597 | struct file *file, int cmd, struct file_lock *fl) | ||
598 | { | ||
599 | int error = -EIO; | ||
600 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
601 | error = sdp->sd_lockstruct.ls_ops->lm_plock( | ||
602 | sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl); | ||
603 | return error; | ||
604 | } | ||
605 | |||
606 | static int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name, | ||
607 | struct file *file, struct file_lock *fl) | ||
608 | { | ||
609 | int error = -EIO; | ||
610 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
611 | error = sdp->sd_lockstruct.ls_ops->lm_punlock( | ||
612 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); | ||
613 | return error; | ||
614 | } | 587 | } |
615 | 588 | ||
616 | /** | 589 | /** |
@@ -626,9 +599,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
626 | { | 599 | { |
627 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 600 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
628 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | 601 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); |
629 | struct lm_lockname name = | 602 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
630 | { .ln_number = ip->i_no_addr, | ||
631 | .ln_type = LM_TYPE_PLOCK }; | ||
632 | 603 | ||
633 | if (!(fl->fl_flags & FL_POSIX)) | 604 | if (!(fl->fl_flags & FL_POSIX)) |
634 | return -ENOLCK; | 605 | return -ENOLCK; |
@@ -640,12 +611,14 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
640 | cmd = F_SETLK; | 611 | cmd = F_SETLK; |
641 | fl->fl_type = F_UNLCK; | 612 | fl->fl_type = F_UNLCK; |
642 | } | 613 | } |
614 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
615 | return -EIO; | ||
643 | if (IS_GETLK(cmd)) | 616 | if (IS_GETLK(cmd)) |
644 | return gfs2_lm_plock_get(sdp, &name, file, fl); | 617 | return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); |
645 | else if (fl->fl_type == F_UNLCK) | 618 | else if (fl->fl_type == F_UNLCK) |
646 | return gfs2_lm_punlock(sdp, &name, file, fl); | 619 | return dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl); |
647 | else | 620 | else |
648 | return gfs2_lm_plock(sdp, &name, file, cmd, fl); | 621 | return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl); |
649 | } | 622 | } |
650 | 623 | ||
651 | static int do_flock(struct file *file, int cmd, struct file_lock *fl) | 624 | static int do_flock(struct file *file, int cmd, struct file_lock *fl) |
@@ -732,7 +705,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
732 | } | 705 | } |
733 | } | 706 | } |
734 | 707 | ||
735 | const struct file_operations gfs2_file_fops = { | 708 | const struct file_operations *gfs2_file_fops = &(const struct file_operations){ |
736 | .llseek = gfs2_llseek, | 709 | .llseek = gfs2_llseek, |
737 | .read = do_sync_read, | 710 | .read = do_sync_read, |
738 | .aio_read = generic_file_aio_read, | 711 | .aio_read = generic_file_aio_read, |
@@ -750,7 +723,7 @@ const struct file_operations gfs2_file_fops = { | |||
750 | .setlease = gfs2_setlease, | 723 | .setlease = gfs2_setlease, |
751 | }; | 724 | }; |
752 | 725 | ||
753 | const struct file_operations gfs2_dir_fops = { | 726 | const struct file_operations *gfs2_dir_fops = &(const struct file_operations){ |
754 | .readdir = gfs2_readdir, | 727 | .readdir = gfs2_readdir, |
755 | .unlocked_ioctl = gfs2_ioctl, | 728 | .unlocked_ioctl = gfs2_ioctl, |
756 | .open = gfs2_open, | 729 | .open = gfs2_open, |
@@ -760,7 +733,9 @@ const struct file_operations gfs2_dir_fops = { | |||
760 | .flock = gfs2_flock, | 733 | .flock = gfs2_flock, |
761 | }; | 734 | }; |
762 | 735 | ||
763 | const struct file_operations gfs2_file_fops_nolock = { | 736 | #endif /* CONFIG_GFS2_FS_LOCKING_DLM */ |
737 | |||
738 | const struct file_operations *gfs2_file_fops_nolock = &(const struct file_operations){ | ||
764 | .llseek = gfs2_llseek, | 739 | .llseek = gfs2_llseek, |
765 | .read = do_sync_read, | 740 | .read = do_sync_read, |
766 | .aio_read = generic_file_aio_read, | 741 | .aio_read = generic_file_aio_read, |
@@ -773,10 +748,10 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
773 | .fsync = gfs2_fsync, | 748 | .fsync = gfs2_fsync, |
774 | .splice_read = generic_file_splice_read, | 749 | .splice_read = generic_file_splice_read, |
775 | .splice_write = generic_file_splice_write, | 750 | .splice_write = generic_file_splice_write, |
776 | .setlease = gfs2_setlease, | 751 | .setlease = generic_setlease, |
777 | }; | 752 | }; |
778 | 753 | ||
779 | const struct file_operations gfs2_dir_fops_nolock = { | 754 | const struct file_operations *gfs2_dir_fops_nolock = &(const struct file_operations){ |
780 | .readdir = gfs2_readdir, | 755 | .readdir = gfs2_readdir, |
781 | .unlocked_ioctl = gfs2_ioctl, | 756 | .unlocked_ioctl = gfs2_ioctl, |
782 | .open = gfs2_open, | 757 | .open = gfs2_open, |