diff options
-rw-r--r-- | fs/ceph/caps.c | 2 | ||||
-rw-r--r-- | fs/ceph/snap.c | 23 | ||||
-rw-r--r-- | fs/ceph/super.h | 8 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 1 |
4 files changed, 23 insertions, 11 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 0ac2703f3bd..ba5bbf318fe 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1282,7 +1282,7 @@ retry: | |||
1282 | &capsnap->mtime, &capsnap->atime, | 1282 | &capsnap->mtime, &capsnap->atime, |
1283 | capsnap->time_warp_seq, | 1283 | capsnap->time_warp_seq, |
1284 | capsnap->uid, capsnap->gid, capsnap->mode, | 1284 | capsnap->uid, capsnap->gid, capsnap->mode, |
1285 | 0, NULL, | 1285 | capsnap->xattr_version, capsnap->xattr_blob, |
1286 | capsnap->follows); | 1286 | capsnap->follows); |
1287 | 1287 | ||
1288 | next_follows = capsnap->follows + 1; | 1288 | next_follows = capsnap->follows + 1; |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index c0b26b6badb..2cb190c2bd9 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -435,7 +435,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
435 | { | 435 | { |
436 | struct inode *inode = &ci->vfs_inode; | 436 | struct inode *inode = &ci->vfs_inode; |
437 | struct ceph_cap_snap *capsnap; | 437 | struct ceph_cap_snap *capsnap; |
438 | int used; | 438 | int used, dirty; |
439 | 439 | ||
440 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); | 440 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); |
441 | if (!capsnap) { | 441 | if (!capsnap) { |
@@ -445,6 +445,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
445 | 445 | ||
446 | spin_lock(&inode->i_lock); | 446 | spin_lock(&inode->i_lock); |
447 | used = __ceph_caps_used(ci); | 447 | used = __ceph_caps_used(ci); |
448 | dirty = __ceph_caps_dirty(ci); | ||
448 | if (__ceph_have_pending_cap_snap(ci)) { | 449 | if (__ceph_have_pending_cap_snap(ci)) { |
449 | /* there is no point in queuing multiple "pending" cap_snaps, | 450 | /* there is no point in queuing multiple "pending" cap_snaps, |
450 | as no new writes are allowed to start when pending, so any | 451 | as no new writes are allowed to start when pending, so any |
@@ -452,11 +453,13 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
452 | cap_snap. lucky us. */ | 453 | cap_snap. lucky us. */ |
453 | dout("queue_cap_snap %p already pending\n", inode); | 454 | dout("queue_cap_snap %p already pending\n", inode); |
454 | kfree(capsnap); | 455 | kfree(capsnap); |
455 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { | 456 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR) || |
457 | (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| | ||
458 | CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) { | ||
456 | struct ceph_snap_context *snapc = ci->i_head_snapc; | 459 | struct ceph_snap_context *snapc = ci->i_head_snapc; |
457 | 460 | ||
458 | igrab(inode); | 461 | igrab(inode); |
459 | 462 | ||
460 | atomic_set(&capsnap->nref, 1); | 463 | atomic_set(&capsnap->nref, 1); |
461 | capsnap->ci = ci; | 464 | capsnap->ci = ci; |
462 | INIT_LIST_HEAD(&capsnap->ci_item); | 465 | INIT_LIST_HEAD(&capsnap->ci_item); |
@@ -464,15 +467,21 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
464 | 467 | ||
465 | capsnap->follows = snapc->seq - 1; | 468 | capsnap->follows = snapc->seq - 1; |
466 | capsnap->issued = __ceph_caps_issued(ci, NULL); | 469 | capsnap->issued = __ceph_caps_issued(ci, NULL); |
467 | capsnap->dirty = __ceph_caps_dirty(ci); | 470 | capsnap->dirty = dirty; |
468 | 471 | ||
469 | capsnap->mode = inode->i_mode; | 472 | capsnap->mode = inode->i_mode; |
470 | capsnap->uid = inode->i_uid; | 473 | capsnap->uid = inode->i_uid; |
471 | capsnap->gid = inode->i_gid; | 474 | capsnap->gid = inode->i_gid; |
472 | 475 | ||
473 | /* fixme? */ | 476 | if (dirty & CEPH_CAP_XATTR_EXCL) { |
474 | capsnap->xattr_blob = NULL; | 477 | __ceph_build_xattrs_blob(ci); |
475 | capsnap->xattr_len = 0; | 478 | capsnap->xattr_blob = |
479 | ceph_buffer_get(ci->i_xattrs.blob); | ||
480 | capsnap->xattr_version = ci->i_xattrs.version; | ||
481 | } else { | ||
482 | capsnap->xattr_blob = NULL; | ||
483 | capsnap->xattr_version = 0; | ||
484 | } | ||
476 | 485 | ||
477 | /* dirty page count moved from _head to this cap_snap; | 486 | /* dirty page count moved from _head to this cap_snap; |
478 | all subsequent writes page dirties occur _after_ this | 487 | all subsequent writes page dirties occur _after_ this |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2482d696f0d..b33929d8f28 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -216,8 +216,7 @@ struct ceph_cap_snap { | |||
216 | uid_t uid; | 216 | uid_t uid; |
217 | gid_t gid; | 217 | gid_t gid; |
218 | 218 | ||
219 | void *xattr_blob; | 219 | struct ceph_buffer *xattr_blob; |
220 | int xattr_len; | ||
221 | u64 xattr_version; | 220 | u64 xattr_version; |
222 | 221 | ||
223 | u64 size; | 222 | u64 size; |
@@ -229,8 +228,11 @@ struct ceph_cap_snap { | |||
229 | 228 | ||
230 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) | 229 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) |
231 | { | 230 | { |
232 | if (atomic_dec_and_test(&capsnap->nref)) | 231 | if (atomic_dec_and_test(&capsnap->nref)) { |
232 | if (capsnap->xattr_blob) | ||
233 | ceph_buffer_put(capsnap->xattr_blob); | ||
233 | kfree(capsnap); | 234 | kfree(capsnap); |
235 | } | ||
234 | } | 236 | } |
235 | 237 | ||
236 | /* | 238 | /* |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 097a2654c00..9578af610b7 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -485,6 +485,7 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | |||
485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; | 485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; |
486 | ci->i_xattrs.prealloc_blob = NULL; | 486 | ci->i_xattrs.prealloc_blob = NULL; |
487 | ci->i_xattrs.dirty = false; | 487 | ci->i_xattrs.dirty = false; |
488 | ci->i_xattrs.version++; | ||
488 | } | 489 | } |
489 | } | 490 | } |
490 | 491 | ||