Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: O2net: Disallow o2net accept connection request from itself. ocfs2/dlm: remove potential deadlock -V3 ocfs2/dlm: avoid incorrect bit set in refmap on recovery master Fix the nested PR lock calling issue in ACL ocfs2: Count more refcount records in file system fragmentation. ocfs2 fix o2dlm dlm run purgelist (rev 3) ocfs2/dlm: fix a dead lock ocfs2: do not overwrite error codes in ocfs2_init_acl
This commit is contained in:
commit
a30bfd6cd4
@ -290,12 +290,30 @@ static int ocfs2_set_acl(handle_t *handle,
|
|||||||
|
|
||||||
int ocfs2_check_acl(struct inode *inode, int mask)
|
int ocfs2_check_acl(struct inode *inode, int mask)
|
||||||
{
|
{
|
||||||
struct posix_acl *acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
|
struct buffer_head *di_bh = NULL;
|
||||||
|
struct posix_acl *acl;
|
||||||
|
int ret = -EAGAIN;
|
||||||
|
|
||||||
if (IS_ERR(acl))
|
if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ocfs2_read_inode_block(inode, &di_bh);
|
||||||
|
if (ret < 0) {
|
||||||
|
mlog_errno(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, di_bh);
|
||||||
|
|
||||||
|
brelse(di_bh);
|
||||||
|
|
||||||
|
if (IS_ERR(acl)) {
|
||||||
|
mlog_errno(PTR_ERR(acl));
|
||||||
return PTR_ERR(acl);
|
return PTR_ERR(acl);
|
||||||
|
}
|
||||||
if (acl) {
|
if (acl) {
|
||||||
int ret = posix_acl_permission(inode, acl, mask);
|
ret = posix_acl_permission(inode, acl, mask);
|
||||||
posix_acl_release(acl);
|
posix_acl_release(acl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -344,7 +362,7 @@ int ocfs2_init_acl(handle_t *handle,
|
|||||||
{
|
{
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
struct posix_acl *acl = NULL;
|
struct posix_acl *acl = NULL;
|
||||||
int ret = 0;
|
int ret = 0, ret2;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
|
|
||||||
if (!S_ISLNK(inode->i_mode)) {
|
if (!S_ISLNK(inode->i_mode)) {
|
||||||
@ -381,7 +399,12 @@ int ocfs2_init_acl(handle_t *handle,
|
|||||||
mode = inode->i_mode;
|
mode = inode->i_mode;
|
||||||
ret = posix_acl_create_masq(clone, &mode);
|
ret = posix_acl_create_masq(clone, &mode);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
|
ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
|
||||||
|
if (ret2) {
|
||||||
|
mlog_errno(ret2);
|
||||||
|
ret = ret2;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
ret = ocfs2_set_acl(handle, inode,
|
ret = ocfs2_set_acl(handle, inode,
|
||||||
di_bh, ACL_TYPE_ACCESS,
|
di_bh, ACL_TYPE_ACCESS,
|
||||||
|
@ -1759,6 +1759,7 @@ static int o2net_accept_one(struct socket *sock)
|
|||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct socket *new_sock = NULL;
|
struct socket *new_sock = NULL;
|
||||||
struct o2nm_node *node = NULL;
|
struct o2nm_node *node = NULL;
|
||||||
|
struct o2nm_node *local_node = NULL;
|
||||||
struct o2net_sock_container *sc = NULL;
|
struct o2net_sock_container *sc = NULL;
|
||||||
struct o2net_node *nn;
|
struct o2net_node *nn;
|
||||||
|
|
||||||
@ -1796,11 +1797,15 @@ static int o2net_accept_one(struct socket *sock)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o2nm_this_node() > node->nd_num) {
|
if (o2nm_this_node() >= node->nd_num) {
|
||||||
mlog(ML_NOTICE, "unexpected connect attempted from a lower "
|
local_node = o2nm_get_node_by_num(o2nm_this_node());
|
||||||
"numbered node '%s' at " "%pI4:%d with num %u\n",
|
mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' ("
|
||||||
node->nd_name, &sin.sin_addr.s_addr,
|
"%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n",
|
||||||
ntohs(sin.sin_port), node->nd_num);
|
local_node->nd_name, local_node->nd_num,
|
||||||
|
&(local_node->nd_ipv4_address),
|
||||||
|
ntohs(local_node->nd_ipv4_port),
|
||||||
|
node->nd_name, node->nd_num, &sin.sin_addr.s_addr,
|
||||||
|
ntohs(sin.sin_port));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1857,6 +1862,8 @@ out:
|
|||||||
sock_release(new_sock);
|
sock_release(new_sock);
|
||||||
if (node)
|
if (node)
|
||||||
o2nm_node_put(node);
|
o2nm_node_put(node);
|
||||||
|
if (local_node)
|
||||||
|
o2nm_node_put(local_node);
|
||||||
if (sc)
|
if (sc)
|
||||||
sc_put(sc);
|
sc_put(sc);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -511,8 +511,6 @@ static void dlm_lockres_release(struct kref *kref)
|
|||||||
|
|
||||||
atomic_dec(&dlm->res_cur_count);
|
atomic_dec(&dlm->res_cur_count);
|
||||||
|
|
||||||
dlm_put(dlm);
|
|
||||||
|
|
||||||
if (!hlist_unhashed(&res->hash_node) ||
|
if (!hlist_unhashed(&res->hash_node) ||
|
||||||
!list_empty(&res->granted) ||
|
!list_empty(&res->granted) ||
|
||||||
!list_empty(&res->converting) ||
|
!list_empty(&res->converting) ||
|
||||||
@ -585,8 +583,6 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
|
|||||||
res->migration_pending = 0;
|
res->migration_pending = 0;
|
||||||
res->inflight_locks = 0;
|
res->inflight_locks = 0;
|
||||||
|
|
||||||
/* put in dlm_lockres_release */
|
|
||||||
dlm_grab(dlm);
|
|
||||||
res->dlm = dlm;
|
res->dlm = dlm;
|
||||||
|
|
||||||
kref_init(&res->refs);
|
kref_init(&res->refs);
|
||||||
@ -3050,8 +3046,6 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
|
|||||||
/* check for pre-existing lock */
|
/* check for pre-existing lock */
|
||||||
spin_lock(&dlm->spinlock);
|
spin_lock(&dlm->spinlock);
|
||||||
res = __dlm_lookup_lockres(dlm, name, namelen, hash);
|
res = __dlm_lookup_lockres(dlm, name, namelen, hash);
|
||||||
spin_lock(&dlm->master_lock);
|
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
spin_lock(&res->spinlock);
|
spin_lock(&res->spinlock);
|
||||||
if (res->state & DLM_LOCK_RES_RECOVERING) {
|
if (res->state & DLM_LOCK_RES_RECOVERING) {
|
||||||
@ -3069,14 +3063,15 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
|
|||||||
spin_unlock(&res->spinlock);
|
spin_unlock(&res->spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock(&dlm->master_lock);
|
||||||
/* ignore status. only nonzero status would BUG. */
|
/* ignore status. only nonzero status would BUG. */
|
||||||
ret = dlm_add_migration_mle(dlm, res, mle, &oldmle,
|
ret = dlm_add_migration_mle(dlm, res, mle, &oldmle,
|
||||||
name, namelen,
|
name, namelen,
|
||||||
migrate->new_master,
|
migrate->new_master,
|
||||||
migrate->master);
|
migrate->master);
|
||||||
|
|
||||||
unlock:
|
|
||||||
spin_unlock(&dlm->master_lock);
|
spin_unlock(&dlm->master_lock);
|
||||||
|
unlock:
|
||||||
spin_unlock(&dlm->spinlock);
|
spin_unlock(&dlm->spinlock);
|
||||||
|
|
||||||
if (oldmle) {
|
if (oldmle) {
|
||||||
|
@ -1997,6 +1997,8 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
|
|||||||
struct list_head *queue;
|
struct list_head *queue;
|
||||||
struct dlm_lock *lock, *next;
|
struct dlm_lock *lock, *next;
|
||||||
|
|
||||||
|
assert_spin_locked(&dlm->spinlock);
|
||||||
|
assert_spin_locked(&res->spinlock);
|
||||||
res->state |= DLM_LOCK_RES_RECOVERING;
|
res->state |= DLM_LOCK_RES_RECOVERING;
|
||||||
if (!list_empty(&res->recovering)) {
|
if (!list_empty(&res->recovering)) {
|
||||||
mlog(0,
|
mlog(0,
|
||||||
@ -2326,19 +2328,15 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
|
|||||||
/* zero the lvb if necessary */
|
/* zero the lvb if necessary */
|
||||||
dlm_revalidate_lvb(dlm, res, dead_node);
|
dlm_revalidate_lvb(dlm, res, dead_node);
|
||||||
if (res->owner == dead_node) {
|
if (res->owner == dead_node) {
|
||||||
if (res->state & DLM_LOCK_RES_DROPPING_REF)
|
if (res->state & DLM_LOCK_RES_DROPPING_REF) {
|
||||||
mlog(0, "%s:%.*s: owned by "
|
mlog(ML_NOTICE, "Ignore %.*s for "
|
||||||
"dead node %u, this node was "
|
"recovery as it is being freed\n",
|
||||||
"dropping its ref when it died. "
|
res->lockname.len,
|
||||||
"continue, dropping the flag.\n",
|
res->lockname.name);
|
||||||
dlm->name, res->lockname.len,
|
} else
|
||||||
res->lockname.name, dead_node);
|
dlm_move_lockres_to_recovery_list(dlm,
|
||||||
|
res);
|
||||||
|
|
||||||
/* the wake_up for this will happen when the
|
|
||||||
* RECOVERING flag is dropped later */
|
|
||||||
res->state &= ~DLM_LOCK_RES_DROPPING_REF;
|
|
||||||
|
|
||||||
dlm_move_lockres_to_recovery_list(dlm, res);
|
|
||||||
} else if (res->owner == dlm->node_num) {
|
} else if (res->owner == dlm->node_num) {
|
||||||
dlm_free_dead_locks(dlm, res, dead_node);
|
dlm_free_dead_locks(dlm, res, dead_node);
|
||||||
__dlm_lockres_calc_usage(dlm, res);
|
__dlm_lockres_calc_usage(dlm, res);
|
||||||
|
@ -92,20 +92,28 @@ int __dlm_lockres_has_locks(struct dlm_lock_resource *res)
|
|||||||
* truly ready to be freed. */
|
* truly ready to be freed. */
|
||||||
int __dlm_lockres_unused(struct dlm_lock_resource *res)
|
int __dlm_lockres_unused(struct dlm_lock_resource *res)
|
||||||
{
|
{
|
||||||
if (!__dlm_lockres_has_locks(res) &&
|
int bit;
|
||||||
(list_empty(&res->dirty) && !(res->state & DLM_LOCK_RES_DIRTY))) {
|
|
||||||
/* try not to scan the bitmap unless the first two
|
if (__dlm_lockres_has_locks(res))
|
||||||
* conditions are already true */
|
return 0;
|
||||||
int bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
|
|
||||||
if (bit >= O2NM_MAX_NODES) {
|
if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY)
|
||||||
/* since the bit for dlm->node_num is not
|
return 0;
|
||||||
* set, inflight_locks better be zero */
|
|
||||||
|
if (res->state & DLM_LOCK_RES_RECOVERING)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
|
||||||
|
if (bit < O2NM_MAX_NODES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* since the bit for dlm->node_num is not set, inflight_locks better
|
||||||
|
* be zero
|
||||||
|
*/
|
||||||
BUG_ON(res->inflight_locks != 0);
|
BUG_ON(res->inflight_locks != 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Call whenever you may have added or deleted something from one of
|
/* Call whenever you may have added or deleted something from one of
|
||||||
@ -152,45 +160,25 @@ void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
|
|||||||
spin_unlock(&dlm->spinlock);
|
spin_unlock(&dlm->spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dlm_purge_lockres(struct dlm_ctxt *dlm,
|
static void dlm_purge_lockres(struct dlm_ctxt *dlm,
|
||||||
struct dlm_lock_resource *res)
|
struct dlm_lock_resource *res)
|
||||||
{
|
{
|
||||||
int master;
|
int master;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
spin_lock(&res->spinlock);
|
assert_spin_locked(&dlm->spinlock);
|
||||||
if (!__dlm_lockres_unused(res)) {
|
assert_spin_locked(&res->spinlock);
|
||||||
mlog(0, "%s:%.*s: tried to purge but not unused\n",
|
|
||||||
dlm->name, res->lockname.len, res->lockname.name);
|
|
||||||
__dlm_print_one_lock_resource(res);
|
|
||||||
spin_unlock(&res->spinlock);
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res->state & DLM_LOCK_RES_MIGRATING) {
|
|
||||||
mlog(0, "%s:%.*s: Delay dropref as this lockres is "
|
|
||||||
"being remastered\n", dlm->name, res->lockname.len,
|
|
||||||
res->lockname.name);
|
|
||||||
/* Re-add the lockres to the end of the purge list */
|
|
||||||
if (!list_empty(&res->purge)) {
|
|
||||||
list_del_init(&res->purge);
|
|
||||||
list_add_tail(&res->purge, &dlm->purge_list);
|
|
||||||
}
|
|
||||||
spin_unlock(&res->spinlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
master = (res->owner == dlm->node_num);
|
master = (res->owner == dlm->node_num);
|
||||||
|
|
||||||
if (!master)
|
|
||||||
res->state |= DLM_LOCK_RES_DROPPING_REF;
|
|
||||||
spin_unlock(&res->spinlock);
|
|
||||||
|
|
||||||
mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len,
|
mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len,
|
||||||
res->lockname.name, master);
|
res->lockname.name, master);
|
||||||
|
|
||||||
if (!master) {
|
if (!master) {
|
||||||
|
res->state |= DLM_LOCK_RES_DROPPING_REF;
|
||||||
/* drop spinlock... retake below */
|
/* drop spinlock... retake below */
|
||||||
|
spin_unlock(&res->spinlock);
|
||||||
spin_unlock(&dlm->spinlock);
|
spin_unlock(&dlm->spinlock);
|
||||||
|
|
||||||
spin_lock(&res->spinlock);
|
spin_lock(&res->spinlock);
|
||||||
@ -208,31 +196,35 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
|
|||||||
mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n",
|
mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n",
|
||||||
dlm->name, res->lockname.len, res->lockname.name, ret);
|
dlm->name, res->lockname.len, res->lockname.name, ret);
|
||||||
spin_lock(&dlm->spinlock);
|
spin_lock(&dlm->spinlock);
|
||||||
|
spin_lock(&res->spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&res->spinlock);
|
|
||||||
if (!list_empty(&res->purge)) {
|
if (!list_empty(&res->purge)) {
|
||||||
mlog(0, "removing lockres %.*s:%p from purgelist, "
|
mlog(0, "removing lockres %.*s:%p from purgelist, "
|
||||||
"master = %d\n", res->lockname.len, res->lockname.name,
|
"master = %d\n", res->lockname.len, res->lockname.name,
|
||||||
res, master);
|
res, master);
|
||||||
list_del_init(&res->purge);
|
list_del_init(&res->purge);
|
||||||
spin_unlock(&res->spinlock);
|
|
||||||
dlm_lockres_put(res);
|
dlm_lockres_put(res);
|
||||||
dlm->purge_count--;
|
dlm->purge_count--;
|
||||||
} else
|
}
|
||||||
spin_unlock(&res->spinlock);
|
|
||||||
|
if (!__dlm_lockres_unused(res)) {
|
||||||
|
mlog(ML_ERROR, "found lockres %s:%.*s: in use after deref\n",
|
||||||
|
dlm->name, res->lockname.len, res->lockname.name);
|
||||||
|
__dlm_print_one_lock_resource(res);
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
__dlm_unhash_lockres(res);
|
__dlm_unhash_lockres(res);
|
||||||
|
|
||||||
/* lockres is not in the hash now. drop the flag and wake up
|
/* lockres is not in the hash now. drop the flag and wake up
|
||||||
* any processes waiting in dlm_get_lock_resource. */
|
* any processes waiting in dlm_get_lock_resource. */
|
||||||
if (!master) {
|
if (!master) {
|
||||||
spin_lock(&res->spinlock);
|
|
||||||
res->state &= ~DLM_LOCK_RES_DROPPING_REF;
|
res->state &= ~DLM_LOCK_RES_DROPPING_REF;
|
||||||
spin_unlock(&res->spinlock);
|
spin_unlock(&res->spinlock);
|
||||||
wake_up(&res->wq);
|
wake_up(&res->wq);
|
||||||
}
|
} else
|
||||||
return 0;
|
spin_unlock(&res->spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dlm_run_purge_list(struct dlm_ctxt *dlm,
|
static void dlm_run_purge_list(struct dlm_ctxt *dlm,
|
||||||
@ -251,17 +243,7 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm,
|
|||||||
lockres = list_entry(dlm->purge_list.next,
|
lockres = list_entry(dlm->purge_list.next,
|
||||||
struct dlm_lock_resource, purge);
|
struct dlm_lock_resource, purge);
|
||||||
|
|
||||||
/* Status of the lockres *might* change so double
|
|
||||||
* check. If the lockres is unused, holding the dlm
|
|
||||||
* spinlock will prevent people from getting and more
|
|
||||||
* refs on it -- there's no need to keep the lockres
|
|
||||||
* spinlock. */
|
|
||||||
spin_lock(&lockres->spinlock);
|
spin_lock(&lockres->spinlock);
|
||||||
unused = __dlm_lockres_unused(lockres);
|
|
||||||
spin_unlock(&lockres->spinlock);
|
|
||||||
|
|
||||||
if (!unused)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
purge_jiffies = lockres->last_used +
|
purge_jiffies = lockres->last_used +
|
||||||
msecs_to_jiffies(DLM_PURGE_INTERVAL_MS);
|
msecs_to_jiffies(DLM_PURGE_INTERVAL_MS);
|
||||||
@ -273,15 +255,29 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm,
|
|||||||
* in tail order, we can stop at the first
|
* in tail order, we can stop at the first
|
||||||
* unpurgable resource -- anyone added after
|
* unpurgable resource -- anyone added after
|
||||||
* him will have a greater last_used value */
|
* him will have a greater last_used value */
|
||||||
|
spin_unlock(&lockres->spinlock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Status of the lockres *might* change so double
|
||||||
|
* check. If the lockres is unused, holding the dlm
|
||||||
|
* spinlock will prevent people from getting and more
|
||||||
|
* refs on it. */
|
||||||
|
unused = __dlm_lockres_unused(lockres);
|
||||||
|
if (!unused ||
|
||||||
|
(lockres->state & DLM_LOCK_RES_MIGRATING)) {
|
||||||
|
mlog(0, "lockres %s:%.*s: is in use or "
|
||||||
|
"being remastered, used %d, state %d\n",
|
||||||
|
dlm->name, lockres->lockname.len,
|
||||||
|
lockres->lockname.name, !unused, lockres->state);
|
||||||
|
list_move_tail(&dlm->purge_list, &lockres->purge);
|
||||||
|
spin_unlock(&lockres->spinlock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
dlm_lockres_get(lockres);
|
dlm_lockres_get(lockres);
|
||||||
|
|
||||||
/* This may drop and reacquire the dlm spinlock if it
|
dlm_purge_lockres(dlm, lockres);
|
||||||
* has to do migration. */
|
|
||||||
if (dlm_purge_lockres(dlm, lockres))
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
dlm_lockres_put(lockres);
|
dlm_lockres_put(lockres);
|
||||||
|
|
||||||
|
@ -2436,16 +2436,26 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
|
|||||||
len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) +
|
len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) +
|
||||||
le32_to_cpu(rec.r_clusters)) - cpos;
|
le32_to_cpu(rec.r_clusters)) - cpos;
|
||||||
/*
|
/*
|
||||||
* If the refcount rec already exist, cool. We just need
|
|
||||||
* to check whether there is a split. Otherwise we just need
|
|
||||||
* to increase the refcount.
|
|
||||||
* If we will insert one, increases recs_add.
|
|
||||||
*
|
|
||||||
* We record all the records which will be inserted to the
|
* We record all the records which will be inserted to the
|
||||||
* same refcount block, so that we can tell exactly whether
|
* same refcount block, so that we can tell exactly whether
|
||||||
* we need a new refcount block or not.
|
* we need a new refcount block or not.
|
||||||
|
*
|
||||||
|
* If we will insert a new one, this is easy and only happens
|
||||||
|
* during adding refcounted flag to the extent, so we don't
|
||||||
|
* have a chance of spliting. We just need one record.
|
||||||
|
*
|
||||||
|
* If the refcount rec already exists, that would be a little
|
||||||
|
* complicated. we may have to:
|
||||||
|
* 1) split at the beginning if the start pos isn't aligned.
|
||||||
|
* we need 1 more record in this case.
|
||||||
|
* 2) split int the end if the end pos isn't aligned.
|
||||||
|
* we need 1 more record in this case.
|
||||||
|
* 3) split in the middle because of file system fragmentation.
|
||||||
|
* we need 2 more records in this case(we can't detect this
|
||||||
|
* beforehand, so always think of the worst case).
|
||||||
*/
|
*/
|
||||||
if (rec.r_refcount) {
|
if (rec.r_refcount) {
|
||||||
|
recs_add += 2;
|
||||||
/* Check whether we need a split at the beginning. */
|
/* Check whether we need a split at the beginning. */
|
||||||
if (cpos == start_cpos &&
|
if (cpos == start_cpos &&
|
||||||
cpos != le64_to_cpu(rec.r_cpos))
|
cpos != le64_to_cpu(rec.r_cpos))
|
||||||
|
Loading…
Reference in New Issue
Block a user