mirror of https://gitee.com/openkylin/linux.git
ceph: introduce an inode flag to indicates if snapflush is needed
Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
13c2b57d81
commit
70220ac8c2
|
@ -1368,6 +1368,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
|
||||||
{
|
{
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
__ceph_flush_snaps(ci, NULL);
|
__ceph_flush_snaps(ci, NULL);
|
||||||
|
ci->i_ceph_flags &= ~CEPH_I_FLUSH_SNAPS;
|
||||||
spin_unlock(&ci->i_ceph_lock);
|
spin_unlock(&ci->i_ceph_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,8 +1564,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
|
||||||
flags |= CHECK_CAPS_FLUSH;
|
flags |= CHECK_CAPS_FLUSH;
|
||||||
|
|
||||||
/* flush snaps first time around only */
|
/* flush snaps first time around only */
|
||||||
if (!list_empty(&ci->i_cap_snaps))
|
if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS) {
|
||||||
__ceph_flush_snaps(ci, &session);
|
__ceph_flush_snaps(ci, &session);
|
||||||
|
ci->i_ceph_flags &= ~CEPH_I_FLUSH_SNAPS;
|
||||||
|
}
|
||||||
goto retry_locked;
|
goto retry_locked;
|
||||||
retry:
|
retry:
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
|
@ -2498,7 +2501,8 @@ void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
|
||||||
* drop cap_snap that is not associated with any snapshot.
|
* drop cap_snap that is not associated with any snapshot.
|
||||||
* we don't need to send FLUSHSNAP message for it.
|
* we don't need to send FLUSHSNAP message for it.
|
||||||
*/
|
*/
|
||||||
static int ceph_try_drop_cap_snap(struct ceph_cap_snap *capsnap)
|
static int ceph_try_drop_cap_snap(struct ceph_inode_info *ci,
|
||||||
|
struct ceph_cap_snap *capsnap)
|
||||||
{
|
{
|
||||||
if (!capsnap->need_flush &&
|
if (!capsnap->need_flush &&
|
||||||
!capsnap->writing && !capsnap->dirty_pages) {
|
!capsnap->writing && !capsnap->dirty_pages) {
|
||||||
|
@ -2506,6 +2510,9 @@ static int ceph_try_drop_cap_snap(struct ceph_cap_snap *capsnap)
|
||||||
capsnap, capsnap->follows);
|
capsnap, capsnap->follows);
|
||||||
BUG_ON(capsnap->cap_flush.tid > 0);
|
BUG_ON(capsnap->cap_flush.tid > 0);
|
||||||
ceph_put_snap_context(capsnap->context);
|
ceph_put_snap_context(capsnap->context);
|
||||||
|
if (!list_is_last(&capsnap->ci_item, &ci->i_cap_snaps))
|
||||||
|
ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS;
|
||||||
|
|
||||||
list_del(&capsnap->ci_item);
|
list_del(&capsnap->ci_item);
|
||||||
ceph_put_cap_snap(capsnap);
|
ceph_put_cap_snap(capsnap);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2553,7 +2560,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
|
||||||
struct ceph_cap_snap,
|
struct ceph_cap_snap,
|
||||||
ci_item);
|
ci_item);
|
||||||
capsnap->writing = 0;
|
capsnap->writing = 0;
|
||||||
if (ceph_try_drop_cap_snap(capsnap))
|
if (ceph_try_drop_cap_snap(ci, capsnap))
|
||||||
put++;
|
put++;
|
||||||
else if (__ceph_finish_cap_snap(ci, capsnap))
|
else if (__ceph_finish_cap_snap(ci, capsnap))
|
||||||
flushsnaps = 1;
|
flushsnaps = 1;
|
||||||
|
@ -2596,15 +2603,19 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
|
||||||
struct ceph_snap_context *snapc)
|
struct ceph_snap_context *snapc)
|
||||||
{
|
{
|
||||||
struct inode *inode = &ci->vfs_inode;
|
struct inode *inode = &ci->vfs_inode;
|
||||||
int last = 0;
|
|
||||||
int complete_capsnap = 0;
|
|
||||||
int drop_capsnap = 0;
|
|
||||||
int found = 0;
|
|
||||||
struct ceph_cap_snap *capsnap = NULL;
|
struct ceph_cap_snap *capsnap = NULL;
|
||||||
|
int put = 0;
|
||||||
|
bool last = false;
|
||||||
|
bool found = false;
|
||||||
|
bool flush_snaps = false;
|
||||||
|
bool complete_capsnap = false;
|
||||||
|
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
ci->i_wrbuffer_ref -= nr;
|
ci->i_wrbuffer_ref -= nr;
|
||||||
last = !ci->i_wrbuffer_ref;
|
if (ci->i_wrbuffer_ref == 0) {
|
||||||
|
last = true;
|
||||||
|
put++;
|
||||||
|
}
|
||||||
|
|
||||||
if (ci->i_head_snapc == snapc) {
|
if (ci->i_head_snapc == snapc) {
|
||||||
ci->i_wrbuffer_ref_head -= nr;
|
ci->i_wrbuffer_ref_head -= nr;
|
||||||
|
@ -2624,15 +2635,22 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
|
||||||
} else {
|
} else {
|
||||||
list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
|
list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
|
||||||
if (capsnap->context == snapc) {
|
if (capsnap->context == snapc) {
|
||||||
found = 1;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BUG_ON(!found);
|
BUG_ON(!found);
|
||||||
capsnap->dirty_pages -= nr;
|
capsnap->dirty_pages -= nr;
|
||||||
if (capsnap->dirty_pages == 0) {
|
if (capsnap->dirty_pages == 0) {
|
||||||
complete_capsnap = 1;
|
complete_capsnap = true;
|
||||||
drop_capsnap = ceph_try_drop_cap_snap(capsnap);
|
if (!capsnap->writing) {
|
||||||
|
if (ceph_try_drop_cap_snap(ci, capsnap)) {
|
||||||
|
put++;
|
||||||
|
} else {
|
||||||
|
ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS;
|
||||||
|
flush_snaps = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dout("put_wrbuffer_cap_refs on %p cap_snap %p "
|
dout("put_wrbuffer_cap_refs on %p cap_snap %p "
|
||||||
" snap %lld %d/%d -> %d/%d %s%s\n",
|
" snap %lld %d/%d -> %d/%d %s%s\n",
|
||||||
|
@ -2647,12 +2665,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
|
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
|
||||||
iput(inode);
|
} else if (flush_snaps) {
|
||||||
} else if (complete_capsnap) {
|
|
||||||
ceph_flush_snaps(ci);
|
ceph_flush_snaps(ci);
|
||||||
wake_up_all(&ci->i_cap_wq);
|
|
||||||
}
|
}
|
||||||
if (drop_capsnap)
|
if (complete_capsnap)
|
||||||
|
wake_up_all(&ci->i_cap_wq);
|
||||||
|
while (put-- > 0)
|
||||||
iput(inode);
|
iput(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -601,6 +601,8 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
|
||||||
capsnap->dirty_pages);
|
capsnap->dirty_pages);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ci->i_ceph_flags |= CEPH_I_FLUSH_SNAPS;
|
||||||
dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
|
dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
|
||||||
inode, capsnap, capsnap->context,
|
inode, capsnap, capsnap->context,
|
||||||
capsnap->context->seq, ceph_cap_string(capsnap->dirty),
|
capsnap->context->seq, ceph_cap_string(capsnap->dirty),
|
||||||
|
|
|
@ -469,6 +469,7 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
|
||||||
#define CEPH_I_SEC_INITED (1 << 7) /* security initialized */
|
#define CEPH_I_SEC_INITED (1 << 7) /* security initialized */
|
||||||
#define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */
|
#define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */
|
||||||
#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */
|
#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */
|
||||||
|
#define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */
|
||||||
|
|
||||||
static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci,
|
static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci,
|
||||||
long long release_count,
|
long long release_count,
|
||||||
|
|
Loading…
Reference in New Issue