diff options
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 6251a1574b94..8c044a4f0457 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -265,7 +265,7 @@ int ceph_release(struct inode *inode, struct file *file) | |||
265 | kmem_cache_free(ceph_file_cachep, cf); | 265 | kmem_cache_free(ceph_file_cachep, cf); |
266 | 266 | ||
267 | /* wake up anyone waiting for caps on this inode */ | 267 | /* wake up anyone waiting for caps on this inode */ |
268 | wake_up(&ci->i_cap_wq); | 268 | wake_up_all(&ci->i_cap_wq); |
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
271 | 271 | ||
@@ -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, |