diff options
author | Yan, Zheng <zyan@redhat.com> | 2014-11-14 09:38:29 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@redhat.com> | 2014-12-17 12:09:52 -0500 |
commit | 28127bdd2f843e996f24b51a70a0592c7ec5c763 (patch) | |
tree | f6053dbabcc606d7a5270f6069bc70e305cafe9d /fs/ceph/file.c | |
parent | 83701246aee8f83b4b42483051b439fbe96ed47d (diff) |
ceph: convert inline data to normal data before data write
Before any data write, convert inline data to normal data and set
i_inline_version to CEPH_INLINE_NONE. The OSD request that saves
inline data to object contains 3 operations (CMPXATTR, WRITE and
SETXATTR). It compares a xattr named 'inline_version' to prevent
old data overwrites newer data.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 5b092bda9284..9b5901fefbf8 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -963,6 +963,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
963 | if (err) | 963 | if (err) |
964 | goto out; | 964 | goto out; |
965 | 965 | ||
966 | if (ci->i_inline_version != CEPH_INLINE_NONE) { | ||
967 | err = ceph_uninline_data(file, NULL); | ||
968 | if (err < 0) | ||
969 | goto out; | ||
970 | } | ||
971 | |||
966 | retry_snap: | 972 | retry_snap: |
967 | if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL)) { | 973 | if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL)) { |
968 | err = -ENOSPC; | 974 | err = -ENOSPC; |
@@ -1024,6 +1030,7 @@ retry_snap: | |||
1024 | if (written >= 0) { | 1030 | if (written >= 0) { |
1025 | int dirty; | 1031 | int dirty; |
1026 | spin_lock(&ci->i_ceph_lock); | 1032 | spin_lock(&ci->i_ceph_lock); |
1033 | ci->i_inline_version = CEPH_INLINE_NONE; | ||
1027 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); | 1034 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); |
1028 | spin_unlock(&ci->i_ceph_lock); | 1035 | spin_unlock(&ci->i_ceph_lock); |
1029 | if (dirty) | 1036 | if (dirty) |
@@ -1269,6 +1276,12 @@ static long ceph_fallocate(struct file *file, int mode, | |||
1269 | goto unlock; | 1276 | goto unlock; |
1270 | } | 1277 | } |
1271 | 1278 | ||
1279 | if (ci->i_inline_version != CEPH_INLINE_NONE) { | ||
1280 | ret = ceph_uninline_data(file, NULL); | ||
1281 | if (ret < 0) | ||
1282 | goto unlock; | ||
1283 | } | ||
1284 | |||
1272 | size = i_size_read(inode); | 1285 | size = i_size_read(inode); |
1273 | if (!(mode & FALLOC_FL_KEEP_SIZE)) | 1286 | if (!(mode & FALLOC_FL_KEEP_SIZE)) |
1274 | endoff = offset + length; | 1287 | endoff = offset + length; |
@@ -1295,6 +1308,7 @@ static long ceph_fallocate(struct file *file, int mode, | |||
1295 | 1308 | ||
1296 | if (!ret) { | 1309 | if (!ret) { |
1297 | spin_lock(&ci->i_ceph_lock); | 1310 | spin_lock(&ci->i_ceph_lock); |
1311 | ci->i_inline_version = CEPH_INLINE_NONE; | ||
1298 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); | 1312 | dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); |
1299 | spin_unlock(&ci->i_ceph_lock); | 1313 | spin_unlock(&ci->i_ceph_lock); |
1300 | if (dirty) | 1314 | if (dirty) |