diff options
Diffstat (limited to 'fs/ceph/file.c')
| -rw-r--r-- | fs/ceph/file.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 7c08698fad3e..8c044a4f0457 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
| @@ -317,7 +317,7 @@ void ceph_release_page_vector(struct page **pages, int num_pages) | |||
| 317 | /* | 317 | /* |
| 318 | * allocate a vector new pages | 318 | * allocate a vector new pages |
| 319 | */ | 319 | */ |
| 320 | struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags) | 320 | static struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags) |
| 321 | { | 321 | { |
| 322 | struct page **pages; | 322 | struct page **pages; |
| 323 | int i; | 323 | int i; |
| @@ -665,7 +665,7 @@ more: | |||
| 665 | * throw out any page cache pages in this range. this | 665 | * throw out any page cache pages in this range. this |
| 666 | * may block. | 666 | * may block. |
| 667 | */ | 667 | */ |
| 668 | truncate_inode_pages_range(inode->i_mapping, pos, | 668 | truncate_inode_pages_range(inode->i_mapping, pos, |
| 669 | (pos+len) | (PAGE_CACHE_SIZE-1)); | 669 | (pos+len) | (PAGE_CACHE_SIZE-1)); |
| 670 | } else { | 670 | } else { |
| 671 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); | 671 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); |
| @@ -740,28 +740,32 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 740 | unsigned long nr_segs, loff_t pos) | 740 | unsigned long nr_segs, loff_t pos) |
| 741 | { | 741 | { |
| 742 | struct file *filp = iocb->ki_filp; | 742 | struct file *filp = iocb->ki_filp; |
| 743 | struct ceph_file_info *fi = filp->private_data; | ||
| 743 | loff_t *ppos = &iocb->ki_pos; | 744 | loff_t *ppos = &iocb->ki_pos; |
| 744 | size_t len = iov->iov_len; | 745 | size_t len = iov->iov_len; |
| 745 | struct inode *inode = filp->f_dentry->d_inode; | 746 | struct inode *inode = filp->f_dentry->d_inode; |
| 746 | struct ceph_inode_info *ci = ceph_inode(inode); | 747 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 747 | void *base = iov->iov_base; | 748 | void __user *base = iov->iov_base; |
| 748 | ssize_t ret; | 749 | ssize_t ret; |
| 749 | int got = 0; | 750 | int want, got = 0; |
| 750 | int checkeof = 0, read = 0; | 751 | int checkeof = 0, read = 0; |
| 751 | 752 | ||
| 752 | dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", | 753 | dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", |
| 753 | inode, ceph_vinop(inode), pos, (unsigned)len, inode); | 754 | inode, ceph_vinop(inode), pos, (unsigned)len, inode); |
| 754 | again: | 755 | again: |
| 755 | __ceph_do_pending_vmtruncate(inode); | 756 | __ceph_do_pending_vmtruncate(inode); |
| 756 | ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE, | 757 | if (fi->fmode & CEPH_FILE_MODE_LAZY) |
| 757 | &got, -1); | 758 | want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO; |
| 759 | else | ||
| 760 | want = CEPH_CAP_FILE_CACHE; | ||
| 761 | ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, &got, -1); | ||
| 758 | if (ret < 0) | 762 | if (ret < 0) |
| 759 | goto out; | 763 | goto out; |
| 760 | dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", | 764 | dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", |
| 761 | inode, ceph_vinop(inode), pos, (unsigned)len, | 765 | inode, ceph_vinop(inode), pos, (unsigned)len, |
| 762 | ceph_cap_string(got)); | 766 | ceph_cap_string(got)); |
| 763 | 767 | ||
| 764 | if ((got & CEPH_CAP_FILE_CACHE) == 0 || | 768 | if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 || |
| 765 | (iocb->ki_filp->f_flags & O_DIRECT) || | 769 | (iocb->ki_filp->f_flags & O_DIRECT) || |
| 766 | (inode->i_sb->s_flags & MS_SYNCHRONOUS)) | 770 | (inode->i_sb->s_flags & MS_SYNCHRONOUS)) |
| 767 | /* hmm, this isn't really async... */ | 771 | /* hmm, this isn't really async... */ |
| @@ -807,11 +811,12 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 807 | unsigned long nr_segs, loff_t pos) | 811 | unsigned long nr_segs, loff_t pos) |
| 808 | { | 812 | { |
| 809 | struct file *file = iocb->ki_filp; | 813 | struct file *file = iocb->ki_filp; |
| 814 | struct ceph_file_info *fi = file->private_data; | ||
| 810 | struct inode *inode = file->f_dentry->d_inode; | 815 | struct inode *inode = file->f_dentry->d_inode; |
| 811 | struct ceph_inode_info *ci = ceph_inode(inode); | 816 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 812 | struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc; | 817 | struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc; |
| 813 | loff_t endoff = pos + iov->iov_len; | 818 | loff_t endoff = pos + iov->iov_len; |
| 814 | int got = 0; | 819 | int want, got = 0; |
| 815 | int ret, err; | 820 | int ret, err; |
| 816 | 821 | ||
| 817 | if (ceph_snap(inode) != CEPH_NOSNAP) | 822 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| @@ -824,8 +829,11 @@ retry_snap: | |||
| 824 | dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n", | 829 | dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n", |
| 825 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, | 830 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, |
| 826 | inode->i_size); | 831 | inode->i_size); |
| 827 | ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, | 832 | if (fi->fmode & CEPH_FILE_MODE_LAZY) |
| 828 | &got, endoff); | 833 | want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO; |
| 834 | else | ||
| 835 | want = CEPH_CAP_FILE_BUFFER; | ||
| 836 | ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, endoff); | ||
| 829 | if (ret < 0) | 837 | if (ret < 0) |
| 830 | goto out; | 838 | goto out; |
| 831 | 839 | ||
| @@ -833,7 +841,7 @@ retry_snap: | |||
| 833 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, | 841 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, |
| 834 | ceph_cap_string(got)); | 842 | ceph_cap_string(got)); |
| 835 | 843 | ||
| 836 | if ((got & CEPH_CAP_FILE_BUFFER) == 0 || | 844 | if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || |
| 837 | (iocb->ki_filp->f_flags & O_DIRECT) || | 845 | (iocb->ki_filp->f_flags & O_DIRECT) || |
| 838 | (inode->i_sb->s_flags & MS_SYNCHRONOUS)) { | 846 | (inode->i_sb->s_flags & MS_SYNCHRONOUS)) { |
| 839 | ret = ceph_sync_write(file, iov->iov_base, iov->iov_len, | 847 | ret = ceph_sync_write(file, iov->iov_base, iov->iov_len, |
| @@ -930,6 +938,8 @@ const struct file_operations ceph_file_fops = { | |||
| 930 | .aio_write = ceph_aio_write, | 938 | .aio_write = ceph_aio_write, |
| 931 | .mmap = ceph_mmap, | 939 | .mmap = ceph_mmap, |
| 932 | .fsync = ceph_fsync, | 940 | .fsync = ceph_fsync, |
| 941 | .lock = ceph_lock, | ||
| 942 | .flock = ceph_flock, | ||
| 933 | .splice_read = generic_file_splice_read, | 943 | .splice_read = generic_file_splice_read, |
| 934 | .splice_write = generic_file_splice_write, | 944 | .splice_write = generic_file_splice_write, |
| 935 | .unlocked_ioctl = ceph_ioctl, | 945 | .unlocked_ioctl = ceph_ioctl, |
