aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/addr.c
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-05-02 00:15:58 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:15:58 -0400
commit7971bd92baf729fcebe04d7330ac22dc668d0261 (patch)
tree78a8ea3b4e072e52840dac968dfacfff737765bd /fs/ceph/addr.c
parenta8673d61ad77ddf2118599507bd40cc345e95368 (diff)
ceph: revert commit 22cddde104
commit 22cddde104 breaks the atomicity of write operation, it also introduces a deadlock between write and truncate. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Greg Farnum <greg@inktank.com> Conflicts: fs/ceph/addr.c
Diffstat (limited to 'fs/ceph/addr.c')
-rw-r--r--fs/ceph/addr.c51
1 files changed, 4 insertions, 47 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index a60ea977af6f..2a571fb4803b 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1067,51 +1067,23 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
1067 struct page **pagep, void **fsdata) 1067 struct page **pagep, void **fsdata)
1068{ 1068{
1069 struct inode *inode = file_inode(file); 1069 struct inode *inode = file_inode(file);
1070 struct ceph_inode_info *ci = ceph_inode(inode);
1071 struct ceph_file_info *fi = file->private_data;
1072 struct page *page; 1070 struct page *page;
1073 pgoff_t index = pos >> PAGE_CACHE_SHIFT; 1071 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1074 int r, want, got = 0; 1072 int r;
1075
1076 if (fi->fmode & CEPH_FILE_MODE_LAZY)
1077 want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
1078 else
1079 want = CEPH_CAP_FILE_BUFFER;
1080
1081 dout("write_begin %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
1082 inode, ceph_vinop(inode), pos, len, inode->i_size);
1083 r = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, pos+len);
1084 if (r < 0)
1085 return r;
1086 dout("write_begin %p %llx.%llx %llu~%u got cap refs on %s\n",
1087 inode, ceph_vinop(inode), pos, len, ceph_cap_string(got));
1088 if (!(got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO))) {
1089 ceph_put_cap_refs(ci, got);
1090 return -EAGAIN;
1091 }
1092 1073
1093 do { 1074 do {
1094 /* get a page */ 1075 /* get a page */
1095 page = grab_cache_page_write_begin(mapping, index, 0); 1076 page = grab_cache_page_write_begin(mapping, index, 0);
1096 if (!page) { 1077 if (!page)
1097 r = -ENOMEM; 1078 return -ENOMEM;
1098 break; 1079 *pagep = page;
1099 }
1100 1080
1101 dout("write_begin file %p inode %p page %p %d~%d\n", file, 1081 dout("write_begin file %p inode %p page %p %d~%d\n", file,
1102 inode, page, (int)pos, (int)len); 1082 inode, page, (int)pos, (int)len);
1103 1083
1104 r = ceph_update_writeable_page(file, pos, len, page); 1084 r = ceph_update_writeable_page(file, pos, len, page);
1105 if (r)
1106 page_cache_release(page);
1107 } while (r == -EAGAIN); 1085 } while (r == -EAGAIN);
1108 1086
1109 if (r) {
1110 ceph_put_cap_refs(ci, got);
1111 } else {
1112 *pagep = page;
1113 *(int *)fsdata = got;
1114 }
1115 return r; 1087 return r;
1116} 1088}
1117 1089
@@ -1125,12 +1097,10 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
1125 struct page *page, void *fsdata) 1097 struct page *page, void *fsdata)
1126{ 1098{
1127 struct inode *inode = file_inode(file); 1099 struct inode *inode = file_inode(file);
1128 struct ceph_inode_info *ci = ceph_inode(inode);
1129 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 1100 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
1130 struct ceph_mds_client *mdsc = fsc->mdsc; 1101 struct ceph_mds_client *mdsc = fsc->mdsc;
1131 unsigned from = pos & (PAGE_CACHE_SIZE - 1); 1102 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
1132 int check_cap = 0; 1103 int check_cap = 0;
1133 int got = (unsigned long)fsdata;
1134 1104
1135 dout("write_end file %p inode %p page %p %d~%d (%d)\n", file, 1105 dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
1136 inode, page, (int)pos, (int)copied, (int)len); 1106 inode, page, (int)pos, (int)copied, (int)len);
@@ -1153,19 +1123,6 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
1153 up_read(&mdsc->snap_rwsem); 1123 up_read(&mdsc->snap_rwsem);
1154 page_cache_release(page); 1124 page_cache_release(page);
1155 1125
1156 if (copied > 0) {
1157 int dirty;
1158 spin_lock(&ci->i_ceph_lock);
1159 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
1160 spin_unlock(&ci->i_ceph_lock);
1161 if (dirty)
1162 __mark_inode_dirty(inode, dirty);
1163 }
1164
1165 dout("write_end %p %llx.%llx %llu~%u dropping cap refs on %s\n",
1166 inode, ceph_vinop(inode), pos, len, ceph_cap_string(got));
1167 ceph_put_cap_refs(ci, got);
1168
1169 if (check_cap) 1126 if (check_cap)
1170 ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL); 1127 ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);
1171 1128