/* This version is for the extended slot map */ staticvoid ocfs2_update_slot_info_extended(struct ocfs2_slot_info *si)
{ int b, i, slotno; struct ocfs2_slot_map_extended *se;
slotno = 0; for (b = 0; b < si->si_blocks; b++) {
se = (struct ocfs2_slot_map_extended *)si->si_bh[b]->b_data; for (i = 0;
(i < si->si_slots_per_block) &&
(slotno < si->si_num_slots);
i++, slotno++) { if (se->se_slots[i].es_valid)
ocfs2_set_slot(si, slotno,
le32_to_cpu(se->se_slots[i].es_node_num)); else
ocfs2_invalidate_slot(si, slotno);
}
}
}
sm = (struct ocfs2_slot_map *)si->si_bh[0]->b_data;
for (i = 0; i < si->si_num_slots; i++) { if (le16_to_cpu(sm->sm_slots[i]) == (u16)OCFS2_INVALID_SLOT)
ocfs2_invalidate_slot(si, i); else
ocfs2_set_slot(si, i, le16_to_cpu(sm->sm_slots[i]));
}
}
/* post the our slot info stuff into it's destination bh and write it
* out. */ staticvoid ocfs2_update_disk_slot_extended(struct ocfs2_slot_info *si, int slot_num, struct buffer_head **bh)
{ int blkind = slot_num / si->si_slots_per_block; int slotno = slot_num % si->si_slots_per_block; struct ocfs2_slot_map_extended *se;
BUG_ON(blkind >= si->si_blocks);
se = (struct ocfs2_slot_map_extended *)si->si_bh[blkind]->b_data;
se->se_slots[slotno].es_valid = si->si_slots[slot_num].sl_valid; if (si->si_slots[slot_num].sl_valid)
se->se_slots[slotno].es_node_num =
cpu_to_le32(si->si_slots[slot_num].sl_node_num);
*bh = si->si_bh[blkind];
}
staticvoid ocfs2_update_disk_slot_old(struct ocfs2_slot_info *si, int slot_num, struct buffer_head **bh)
{ int i; struct ocfs2_slot_map *sm;
sm = (struct ocfs2_slot_map *)si->si_bh[0]->b_data; for (i = 0; i < si->si_num_slots; i++) { if (si->si_slots[i].sl_valid)
sm->sm_slots[i] =
cpu_to_le16(si->si_slots[i].sl_node_num); else
sm->sm_slots[i] = cpu_to_le16(OCFS2_INVALID_SLOT);
}
*bh = si->si_bh[0];
}
staticint ocfs2_update_disk_slot(struct ocfs2_super *osb, struct ocfs2_slot_info *si, int slot_num)
{ int status; struct buffer_head *bh;
if (ocfs2_uses_extended_slot_map(osb)) {
bytes_needed = osb->max_slots * sizeof(struct ocfs2_extended_slot);
} else {
bytes_needed = osb->max_slots * sizeof(__le16);
} if (bytes_needed > i_size_read(inode)) {
mlog(ML_ERROR, "Slot map file is too small! (size %llu, needed %llu)\n",
i_size_read(inode), bytes_needed); return -ENOSPC;
}
*bytes = bytes_needed; return0;
}
/* try to find global node in the slot info. Returns -ENOENT
* if nothing is found. */ staticint __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, unsignedint node_num)
{ int i, ret = -ENOENT;
for(i = 0; i < si->si_num_slots; i++) { if (si->si_slots[i].sl_valid &&
(node_num == si->si_slots[i].sl_node_num)) {
ret = i; break;
}
}
return ret;
}
staticint __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, int preferred)
{ int i, ret = -ENOSPC;
if ((preferred >= 0) && (preferred < si->si_num_slots)) { if (!si->si_slots[preferred].sl_valid) {
ret = preferred; goto out;
}
}
for(i = 0; i < si->si_num_slots; i++) { if (!si->si_slots[i].sl_valid) {
ret = i; break;
}
}
out: return ret;
}
int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsignedint node_num)
{ int slot; struct ocfs2_slot_info *si = osb->slot_info;
iput(si->si_inode); if (si->si_bh) { for (i = 0; i < si->si_blocks; i++) { if (si->si_bh[i]) {
brelse(si->si_bh[i]);
si->si_bh[i] = NULL;
}
}
kfree(si->si_bh);
}
kfree(si);
}
int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num)
{ struct ocfs2_slot_info *si = osb->slot_info;
si->si_bh = kcalloc(si->si_blocks, sizeof(struct buffer_head *),
GFP_KERNEL); if (!si->si_bh) {
status = -ENOMEM;
mlog_errno(status); goto bail;
}
for (i = 0; i < si->si_blocks; i++) {
status = ocfs2_extent_map_get_blocks(si->si_inode, i,
&blkno, NULL, NULL); if (status < 0) {
mlog_errno(status); goto bail;
}
/* search for ourselves first and take the slot if it already *exists.Perhapsweneedtomarkthisinavariableforour *ownjournalrecovery?Possiblynot,thoughwecertainly
* need to warn to the user */
slot = __ocfs2_node_num_to_slot(si, osb->node_num); if (slot < 0) { /* if no slot yet, then just take 1st available
* one. */
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); if (slot < 0) {
spin_unlock(&osb->osb_lock);
mlog(ML_ERROR, "no free slots available!\n");
status = -EINVAL; goto bail;
}
} else
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already " "allocated to this node!\n", slot, osb->dev_str);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.