diff options
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 89 |
1 files changed, 72 insertions, 17 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 4f1dc7120916..a888df6f2d71 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -192,6 +192,59 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * try renew caps after session gets killed. | ||
196 | */ | ||
197 | int ceph_renew_caps(struct inode *inode) | ||
198 | { | ||
199 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | ||
200 | struct ceph_inode_info *ci = ceph_inode(inode); | ||
201 | struct ceph_mds_request *req; | ||
202 | int err, flags, wanted; | ||
203 | |||
204 | spin_lock(&ci->i_ceph_lock); | ||
205 | wanted = __ceph_caps_file_wanted(ci); | ||
206 | if (__ceph_is_any_real_caps(ci) && | ||
207 | (!(wanted & CEPH_CAP_ANY_WR) == 0 || ci->i_auth_cap)) { | ||
208 | int issued = __ceph_caps_issued(ci, NULL); | ||
209 | spin_unlock(&ci->i_ceph_lock); | ||
210 | dout("renew caps %p want %s issued %s updating mds_wanted\n", | ||
211 | inode, ceph_cap_string(wanted), ceph_cap_string(issued)); | ||
212 | ceph_check_caps(ci, 0, NULL); | ||
213 | return 0; | ||
214 | } | ||
215 | spin_unlock(&ci->i_ceph_lock); | ||
216 | |||
217 | flags = 0; | ||
218 | if ((wanted & CEPH_CAP_FILE_RD) && (wanted & CEPH_CAP_FILE_WR)) | ||
219 | flags = O_RDWR; | ||
220 | else if (wanted & CEPH_CAP_FILE_RD) | ||
221 | flags = O_RDONLY; | ||
222 | else if (wanted & CEPH_CAP_FILE_WR) | ||
223 | flags = O_WRONLY; | ||
224 | #ifdef O_LAZY | ||
225 | if (wanted & CEPH_CAP_FILE_LAZYIO) | ||
226 | flags |= O_LAZY; | ||
227 | #endif | ||
228 | |||
229 | req = prepare_open_request(inode->i_sb, flags, 0); | ||
230 | if (IS_ERR(req)) { | ||
231 | err = PTR_ERR(req); | ||
232 | goto out; | ||
233 | } | ||
234 | |||
235 | req->r_inode = inode; | ||
236 | ihold(inode); | ||
237 | req->r_num_caps = 1; | ||
238 | req->r_fmode = -1; | ||
239 | |||
240 | err = ceph_mdsc_do_request(mdsc, NULL, req); | ||
241 | ceph_mdsc_put_request(req); | ||
242 | out: | ||
243 | dout("renew caps %p open result=%d\n", inode, err); | ||
244 | return err < 0 ? err : 0; | ||
245 | } | ||
246 | |||
247 | /* | ||
195 | * If we already have the requisite capabilities, we can satisfy | 248 | * If we already have the requisite capabilities, we can satisfy |
196 | * the open request locally (no need to request new caps from the | 249 | * the open request locally (no need to request new caps from the |
197 | * MDS). We do, however, need to inform the MDS (asynchronously) | 250 | * MDS). We do, however, need to inform the MDS (asynchronously) |
@@ -616,8 +669,7 @@ static void ceph_aio_complete(struct inode *inode, | |||
616 | kfree(aio_req); | 669 | kfree(aio_req); |
617 | } | 670 | } |
618 | 671 | ||
619 | static void ceph_aio_complete_req(struct ceph_osd_request *req, | 672 | static void ceph_aio_complete_req(struct ceph_osd_request *req) |
620 | struct ceph_msg *msg) | ||
621 | { | 673 | { |
622 | int rc = req->r_result; | 674 | int rc = req->r_result; |
623 | struct inode *inode = req->r_inode; | 675 | struct inode *inode = req->r_inode; |
@@ -714,14 +766,21 @@ static void ceph_aio_retry_work(struct work_struct *work) | |||
714 | req->r_flags = CEPH_OSD_FLAG_ORDERSNAP | | 766 | req->r_flags = CEPH_OSD_FLAG_ORDERSNAP | |
715 | CEPH_OSD_FLAG_ONDISK | | 767 | CEPH_OSD_FLAG_ONDISK | |
716 | CEPH_OSD_FLAG_WRITE; | 768 | CEPH_OSD_FLAG_WRITE; |
717 | req->r_base_oloc = orig_req->r_base_oloc; | 769 | ceph_oloc_copy(&req->r_base_oloc, &orig_req->r_base_oloc); |
718 | req->r_base_oid = orig_req->r_base_oid; | 770 | ceph_oid_copy(&req->r_base_oid, &orig_req->r_base_oid); |
771 | |||
772 | ret = ceph_osdc_alloc_messages(req, GFP_NOFS); | ||
773 | if (ret) { | ||
774 | ceph_osdc_put_request(req); | ||
775 | req = orig_req; | ||
776 | goto out; | ||
777 | } | ||
719 | 778 | ||
720 | req->r_ops[0] = orig_req->r_ops[0]; | 779 | req->r_ops[0] = orig_req->r_ops[0]; |
721 | osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); | 780 | osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); |
722 | 781 | ||
723 | ceph_osdc_build_request(req, req->r_ops[0].extent.offset, | 782 | req->r_mtime = aio_req->mtime; |
724 | snapc, CEPH_NOSNAP, &aio_req->mtime); | 783 | req->r_data_offset = req->r_ops[0].extent.offset; |
725 | 784 | ||
726 | ceph_osdc_put_request(orig_req); | 785 | ceph_osdc_put_request(orig_req); |
727 | 786 | ||
@@ -733,7 +792,7 @@ static void ceph_aio_retry_work(struct work_struct *work) | |||
733 | out: | 792 | out: |
734 | if (ret < 0) { | 793 | if (ret < 0) { |
735 | req->r_result = ret; | 794 | req->r_result = ret; |
736 | ceph_aio_complete_req(req, NULL); | 795 | ceph_aio_complete_req(req); |
737 | } | 796 | } |
738 | 797 | ||
739 | ceph_put_snap_context(snapc); | 798 | ceph_put_snap_context(snapc); |
@@ -764,6 +823,8 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe) | |||
764 | list_add_tail(&req->r_unsafe_item, | 823 | list_add_tail(&req->r_unsafe_item, |
765 | &ci->i_unsafe_writes); | 824 | &ci->i_unsafe_writes); |
766 | spin_unlock(&ci->i_unsafe_lock); | 825 | spin_unlock(&ci->i_unsafe_lock); |
826 | |||
827 | complete_all(&req->r_completion); | ||
767 | } else { | 828 | } else { |
768 | spin_lock(&ci->i_unsafe_lock); | 829 | spin_lock(&ci->i_unsafe_lock); |
769 | list_del_init(&req->r_unsafe_item); | 830 | list_del_init(&req->r_unsafe_item); |
@@ -875,14 +936,12 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
875 | (pos+len) | (PAGE_SIZE - 1)); | 936 | (pos+len) | (PAGE_SIZE - 1)); |
876 | 937 | ||
877 | osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); | 938 | osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); |
939 | req->r_mtime = mtime; | ||
878 | } | 940 | } |
879 | 941 | ||
880 | |||
881 | osd_req_op_extent_osd_data_pages(req, 0, pages, len, start, | 942 | osd_req_op_extent_osd_data_pages(req, 0, pages, len, start, |
882 | false, false); | 943 | false, false); |
883 | 944 | ||
884 | ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime); | ||
885 | |||
886 | if (aio_req) { | 945 | if (aio_req) { |
887 | aio_req->total_len += len; | 946 | aio_req->total_len += len; |
888 | aio_req->num_reqs++; | 947 | aio_req->num_reqs++; |
@@ -956,7 +1015,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, | |||
956 | req, false); | 1015 | req, false); |
957 | if (ret < 0) { | 1016 | if (ret < 0) { |
958 | req->r_result = ret; | 1017 | req->r_result = ret; |
959 | ceph_aio_complete_req(req, NULL); | 1018 | ceph_aio_complete_req(req); |
960 | } | 1019 | } |
961 | } | 1020 | } |
962 | return -EIOCBQUEUED; | 1021 | return -EIOCBQUEUED; |
@@ -1067,9 +1126,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, | |||
1067 | osd_req_op_extent_osd_data_pages(req, 0, pages, len, 0, | 1126 | osd_req_op_extent_osd_data_pages(req, 0, pages, len, 0, |
1068 | false, true); | 1127 | false, true); |
1069 | 1128 | ||
1070 | /* BUG_ON(vino.snap != CEPH_NOSNAP); */ | 1129 | req->r_mtime = mtime; |
1071 | ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime); | ||
1072 | |||
1073 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); | 1130 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); |
1074 | if (!ret) | 1131 | if (!ret) |
1075 | ret = ceph_osdc_wait_request(&fsc->client->osdc, req); | 1132 | ret = ceph_osdc_wait_request(&fsc->client->osdc, req); |
@@ -1524,9 +1581,7 @@ static int ceph_zero_partial_object(struct inode *inode, | |||
1524 | goto out; | 1581 | goto out; |
1525 | } | 1582 | } |
1526 | 1583 | ||
1527 | ceph_osdc_build_request(req, offset, NULL, ceph_vino(inode).snap, | 1584 | req->r_mtime = inode->i_mtime; |
1528 | &inode->i_mtime); | ||
1529 | |||
1530 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); | 1585 | ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); |
1531 | if (!ret) { | 1586 | if (!ret) { |
1532 | ret = ceph_osdc_wait_request(&fsc->client->osdc, req); | 1587 | ret = ceph_osdc_wait_request(&fsc->client->osdc, req); |