aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_address.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_address.c')
-rw-r--r--fs/gfs2/ops_address.c54
1 files changed, 16 insertions, 38 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 031270ad55e2..d33f6aa79731 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -589,8 +589,9 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset)
589 return; 589 return;
590} 590}
591 591
592static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov, 592static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
593 loff_t offset, unsigned long nr_segs) 593 const struct iovec *iov, loff_t offset,
594 unsigned long nr_segs)
594{ 595{
595 struct file *file = iocb->ki_filp; 596 struct file *file = iocb->ki_filp;
596 struct inode *inode = file->f_mapping->host; 597 struct inode *inode = file->f_mapping->host;
@@ -598,8 +599,10 @@ static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
598 struct gfs2_holder gh; 599 struct gfs2_holder gh;
599 int rv; 600 int rv;
600 601
602 if (rw == READ)
603 mutex_lock(&inode->i_mutex);
601 /* 604 /*
602 * Shared lock, even though its write, since we do no allocation 605 * Shared lock, even if its a write, since we do no allocation
603 * on this path. All we need change is atime. 606 * on this path. All we need change is atime.
604 */ 607 */
605 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); 608 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
@@ -607,6 +610,9 @@ static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
607 if (rv) 610 if (rv)
608 goto out; 611 goto out;
609 612
613 if (offset > i_size_read(inode))
614 goto out;
615
610 /* 616 /*
611 * Should we return an error here? I can't see that O_DIRECT for 617 * Should we return an error here? I can't see that O_DIRECT for
612 * a journaled file makes any sense. For now we'll silently fall 618 * a journaled file makes any sense. For now we'll silently fall
@@ -619,48 +625,20 @@ static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
619 if (gfs2_is_stuffed(ip)) 625 if (gfs2_is_stuffed(ip))
620 goto out; 626 goto out;
621 627
622 rv = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev, 628 rv = blockdev_direct_IO_own_locking(rw, iocb, inode,
623 iov, offset, nr_segs, gfs2_get_block, 629 inode->i_sb->s_bdev,
624 NULL, DIO_OWN_LOCKING); 630 iov, offset, nr_segs,
631 gfs2_get_block, NULL);
625out: 632out:
626 gfs2_glock_dq_m(1, &gh); 633 gfs2_glock_dq_m(1, &gh);
627 gfs2_holder_uninit(&gh); 634 gfs2_holder_uninit(&gh);
635 if (rw == READ)
636 mutex_unlock(&inode->i_mutex);
628 637
629 return rv; 638 return rv;
630} 639}
631 640
632/** 641/**
633 * gfs2_direct_IO
634 *
635 * This is called with a shared lock already held for the read path.
636 * Currently, no locks are held when the write path is called.
637 */
638static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
639 const struct iovec *iov, loff_t offset,
640 unsigned long nr_segs)
641{
642 struct file *file = iocb->ki_filp;
643 struct inode *inode = file->f_mapping->host;
644 struct gfs2_inode *ip = GFS2_I(inode);
645 struct gfs2_sbd *sdp = GFS2_SB(inode);
646 int ret;
647
648 if (rw == WRITE)
649 return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);
650
651 if (gfs2_assert_warn(sdp, gfs2_glock_is_locked_by_me(ip->i_gl)) ||
652 gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
653 return -EINVAL;
654
655 mutex_lock(&inode->i_mutex);
656 ret = __blockdev_direct_IO(READ, iocb, inode, inode->i_sb->s_bdev, iov,
657 offset, nr_segs, gfs2_get_block, NULL,
658 DIO_OWN_LOCKING);
659 mutex_unlock(&inode->i_mutex);
660 return ret;
661}
662
663/**
664 * stuck_releasepage - We're stuck in gfs2_releasepage(). Print stuff out. 642 * stuck_releasepage - We're stuck in gfs2_releasepage(). Print stuff out.
665 * @bh: the buffer we're stuck on 643 * @bh: the buffer we're stuck on
666 * 644 *
@@ -765,7 +743,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
765 } 743 }
766 while (bh != head); 744 while (bh != head);
767 745
768 out: 746out:
769 return try_to_free_buffers(page); 747 return try_to_free_buffers(page);
770} 748}
771 749