1ccd979bdSMark Fasheh /* -*- mode: c; c-basic-offset: 8; -*- 2ccd979bdSMark Fasheh * vim: noexpandtab sw=8 ts=8 sts=0: 3ccd979bdSMark Fasheh * 4ccd979bdSMark Fasheh * slot_map.c 5ccd979bdSMark Fasheh * 6ccd979bdSMark Fasheh * 7ccd979bdSMark Fasheh * 8ccd979bdSMark Fasheh * Copyright (C) 2002, 2004 Oracle. All rights reserved. 9ccd979bdSMark Fasheh * 10ccd979bdSMark Fasheh * This program is free software; you can redistribute it and/or 11ccd979bdSMark Fasheh * modify it under the terms of the GNU General Public 12ccd979bdSMark Fasheh * License as published by the Free Software Foundation; either 13ccd979bdSMark Fasheh * version 2 of the License, or (at your option) any later version. 14ccd979bdSMark Fasheh * 15ccd979bdSMark Fasheh * This program is distributed in the hope that it will be useful, 16ccd979bdSMark Fasheh * but WITHOUT ANY WARRANTY; without even the implied warranty of 17ccd979bdSMark Fasheh * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18ccd979bdSMark Fasheh * General Public License for more details. 19ccd979bdSMark Fasheh * 20ccd979bdSMark Fasheh * You should have received a copy of the GNU General Public 21ccd979bdSMark Fasheh * License along with this program; if not, write to the 22ccd979bdSMark Fasheh * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23ccd979bdSMark Fasheh * Boston, MA 021110-1307, USA. 24ccd979bdSMark Fasheh */ 25ccd979bdSMark Fasheh 26ccd979bdSMark Fasheh #include <linux/types.h> 27ccd979bdSMark Fasheh #include <linux/slab.h> 28ccd979bdSMark Fasheh #include <linux/highmem.h> 29ccd979bdSMark Fasheh 30ccd979bdSMark Fasheh #define MLOG_MASK_PREFIX ML_SUPER 31ccd979bdSMark Fasheh #include <cluster/masklog.h> 32ccd979bdSMark Fasheh 33ccd979bdSMark Fasheh #include "ocfs2.h" 34ccd979bdSMark Fasheh 35ccd979bdSMark Fasheh #include "dlmglue.h" 36ccd979bdSMark Fasheh #include "extent_map.h" 37ccd979bdSMark Fasheh #include "heartbeat.h" 38ccd979bdSMark Fasheh #include "inode.h" 39ccd979bdSMark Fasheh #include "slot_map.h" 40ccd979bdSMark Fasheh #include "super.h" 41ccd979bdSMark Fasheh #include "sysfile.h" 42ccd979bdSMark Fasheh 43ccd979bdSMark Fasheh #include "buffer_head_io.h" 44ccd979bdSMark Fasheh 45*fc881fa0SJoel Becker 46*fc881fa0SJoel Becker struct ocfs2_slot { 47*fc881fa0SJoel Becker int sl_valid; 48*fc881fa0SJoel Becker unsigned int sl_node_num; 49*fc881fa0SJoel Becker }; 50*fc881fa0SJoel Becker 51d85b20e4SJoel Becker struct ocfs2_slot_info { 52d85b20e4SJoel Becker struct inode *si_inode; 531c8d9a6aSJoel Becker unsigned int si_blocks; 541c8d9a6aSJoel Becker struct buffer_head **si_bh; 55d85b20e4SJoel Becker unsigned int si_num_slots; 56*fc881fa0SJoel Becker struct ocfs2_slot *si_slots; 57d85b20e4SJoel Becker }; 58d85b20e4SJoel Becker 59d85b20e4SJoel Becker 60*fc881fa0SJoel Becker static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 61*fc881fa0SJoel Becker unsigned int node_num); 62*fc881fa0SJoel Becker 63*fc881fa0SJoel Becker static void ocfs2_invalidate_slot(struct ocfs2_slot_info *si, 64*fc881fa0SJoel Becker int slot_num) 65*fc881fa0SJoel Becker { 66*fc881fa0SJoel Becker BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots)); 67*fc881fa0SJoel Becker si->si_slots[slot_num].sl_valid = 0; 68*fc881fa0SJoel Becker } 69*fc881fa0SJoel Becker 70*fc881fa0SJoel Becker static void ocfs2_set_slot(struct ocfs2_slot_info *si, 71*fc881fa0SJoel Becker int slot_num, unsigned int node_num) 72*fc881fa0SJoel Becker { 73*fc881fa0SJoel Becker BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots)); 74*fc881fa0SJoel Becker BUG_ON((node_num == O2NM_INVALID_NODE_NUM) || 75*fc881fa0SJoel Becker (node_num >= O2NM_MAX_NODES)); 76*fc881fa0SJoel Becker 77*fc881fa0SJoel Becker si->si_slots[slot_num].sl_valid = 1; 78*fc881fa0SJoel Becker si->si_slots[slot_num].sl_node_num = node_num; 79*fc881fa0SJoel Becker } 80ccd979bdSMark Fasheh 81d85b20e4SJoel Becker /* 82d85b20e4SJoel Becker * Post the slot information on disk into our slot_info struct. 83d85b20e4SJoel Becker * Must be protected by osb_lock. 84d85b20e4SJoel Becker */ 858e8a4603SMark Fasheh static void ocfs2_update_slot_info(struct ocfs2_slot_info *si) 86ccd979bdSMark Fasheh { 87ccd979bdSMark Fasheh int i; 88ccd979bdSMark Fasheh __le16 *disk_info; 89ccd979bdSMark Fasheh 90ccd979bdSMark Fasheh /* we don't read the slot block here as ocfs2_super_lock 91ccd979bdSMark Fasheh * should've made sure we have the most recent copy. */ 921c8d9a6aSJoel Becker disk_info = (__le16 *) si->si_bh[0]->b_data; 93ccd979bdSMark Fasheh 94*fc881fa0SJoel Becker for (i = 0; i < si->si_num_slots; i++) { 95*fc881fa0SJoel Becker if (le16_to_cpu(disk_info[i]) == (u16)OCFS2_INVALID_SLOT) 96*fc881fa0SJoel Becker ocfs2_invalidate_slot(si, i); 97*fc881fa0SJoel Becker else 98*fc881fa0SJoel Becker ocfs2_set_slot(si, i, le16_to_cpu(disk_info[i])); 99*fc881fa0SJoel Becker } 100ccd979bdSMark Fasheh } 101ccd979bdSMark Fasheh 1028e8a4603SMark Fasheh int ocfs2_refresh_slot_info(struct ocfs2_super *osb) 1038e8a4603SMark Fasheh { 1048e8a4603SMark Fasheh int ret; 1058e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 1068e8a4603SMark Fasheh 1078e8a4603SMark Fasheh if (si == NULL) 1088e8a4603SMark Fasheh return 0; 1098e8a4603SMark Fasheh 1101c8d9a6aSJoel Becker BUG_ON(si->si_blocks == 0); 1111c8d9a6aSJoel Becker BUG_ON(si->si_bh == NULL); 1121c8d9a6aSJoel Becker 1131c8d9a6aSJoel Becker mlog(0, "Refreshing slot map, reading %u block(s)\n", 1141c8d9a6aSJoel Becker si->si_blocks); 1151c8d9a6aSJoel Becker 1161c8d9a6aSJoel Becker /* 1171c8d9a6aSJoel Becker * We pass -1 as blocknr because we expect all of si->si_bh to 1181c8d9a6aSJoel Becker * be !NULL. Thus, ocfs2_read_blocks() will ignore blocknr. If 1191c8d9a6aSJoel Becker * this is not true, the read of -1 (UINT64_MAX) will fail. 1201c8d9a6aSJoel Becker */ 1211c8d9a6aSJoel Becker ret = ocfs2_read_blocks(osb, -1, si->si_blocks, si->si_bh, 0, 1221c8d9a6aSJoel Becker si->si_inode); 123d85b20e4SJoel Becker if (ret == 0) { 124d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 1258e8a4603SMark Fasheh ocfs2_update_slot_info(si); 126d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 127d85b20e4SJoel Becker } 1288e8a4603SMark Fasheh 1298e8a4603SMark Fasheh return ret; 1308e8a4603SMark Fasheh } 1318e8a4603SMark Fasheh 132ccd979bdSMark Fasheh /* post the our slot info stuff into it's destination bh and write it 133ccd979bdSMark Fasheh * out. */ 1348e8a4603SMark Fasheh static int ocfs2_update_disk_slots(struct ocfs2_super *osb, 135ccd979bdSMark Fasheh struct ocfs2_slot_info *si) 136ccd979bdSMark Fasheh { 137ccd979bdSMark Fasheh int status, i; 1381c8d9a6aSJoel Becker __le16 *disk_info = (__le16 *) si->si_bh[0]->b_data; 139ccd979bdSMark Fasheh 140d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 141*fc881fa0SJoel Becker for (i = 0; i < si->si_num_slots; i++) { 142*fc881fa0SJoel Becker if (si->si_slots[i].sl_valid) 143*fc881fa0SJoel Becker disk_info[i] = 144*fc881fa0SJoel Becker cpu_to_le16(si->si_slots[i].sl_node_num); 145*fc881fa0SJoel Becker else 146*fc881fa0SJoel Becker disk_info[i] = cpu_to_le16(OCFS2_INVALID_SLOT); 147*fc881fa0SJoel Becker } 148d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 149ccd979bdSMark Fasheh 1501c8d9a6aSJoel Becker status = ocfs2_write_block(osb, si->si_bh[0], si->si_inode); 151ccd979bdSMark Fasheh if (status < 0) 152ccd979bdSMark Fasheh mlog_errno(status); 153ccd979bdSMark Fasheh 154ccd979bdSMark Fasheh return status; 155ccd979bdSMark Fasheh } 156ccd979bdSMark Fasheh 1571c8d9a6aSJoel Becker /* 1581c8d9a6aSJoel Becker * Calculate how many bytes are needed by the slot map. Returns 1591c8d9a6aSJoel Becker * an error if the slot map file is too small. 1601c8d9a6aSJoel Becker */ 1611c8d9a6aSJoel Becker static int ocfs2_slot_map_physical_size(struct ocfs2_super *osb, 1621c8d9a6aSJoel Becker struct inode *inode, 1631c8d9a6aSJoel Becker unsigned long long *bytes) 1641c8d9a6aSJoel Becker { 1651c8d9a6aSJoel Becker unsigned long long bytes_needed; 1661c8d9a6aSJoel Becker 1671c8d9a6aSJoel Becker bytes_needed = osb->max_slots * sizeof(__le16); 1681c8d9a6aSJoel Becker if (bytes_needed > i_size_read(inode)) { 1691c8d9a6aSJoel Becker mlog(ML_ERROR, 1701c8d9a6aSJoel Becker "Slot map file is too small! (size %llu, needed %llu)\n", 1711c8d9a6aSJoel Becker i_size_read(inode), bytes_needed); 1721c8d9a6aSJoel Becker return -ENOSPC; 1731c8d9a6aSJoel Becker } 1741c8d9a6aSJoel Becker 1751c8d9a6aSJoel Becker *bytes = bytes_needed; 1761c8d9a6aSJoel Becker return 0; 1771c8d9a6aSJoel Becker } 1781c8d9a6aSJoel Becker 179*fc881fa0SJoel Becker /* try to find global node in the slot info. Returns -ENOENT 180*fc881fa0SJoel Becker * if nothing is found. */ 181*fc881fa0SJoel Becker static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 182*fc881fa0SJoel Becker unsigned int node_num) 183ccd979bdSMark Fasheh { 184*fc881fa0SJoel Becker int i, ret = -ENOENT; 185ccd979bdSMark Fasheh 186ccd979bdSMark Fasheh for(i = 0; i < si->si_num_slots; i++) { 187*fc881fa0SJoel Becker if (si->si_slots[i].sl_valid && 188*fc881fa0SJoel Becker (node_num == si->si_slots[i].sl_node_num)) { 189*fc881fa0SJoel Becker ret = i; 190ccd979bdSMark Fasheh break; 191ccd979bdSMark Fasheh } 192ccd979bdSMark Fasheh } 193*fc881fa0SJoel Becker 194ccd979bdSMark Fasheh return ret; 195ccd979bdSMark Fasheh } 196ccd979bdSMark Fasheh 197*fc881fa0SJoel Becker static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, 198*fc881fa0SJoel Becker int preferred) 199ccd979bdSMark Fasheh { 200*fc881fa0SJoel Becker int i, ret = -ENOSPC; 201ccd979bdSMark Fasheh 202*fc881fa0SJoel Becker if ((preferred >= 0) && (preferred < si->si_num_slots)) { 203*fc881fa0SJoel Becker if (!si->si_slots[preferred].sl_valid) { 204baf4661aSSunil Mushran ret = preferred; 205baf4661aSSunil Mushran goto out; 206baf4661aSSunil Mushran } 207baf4661aSSunil Mushran } 208baf4661aSSunil Mushran 209ccd979bdSMark Fasheh for(i = 0; i < si->si_num_slots; i++) { 210*fc881fa0SJoel Becker if (!si->si_slots[i].sl_valid) { 211*fc881fa0SJoel Becker ret = i; 212ccd979bdSMark Fasheh break; 213ccd979bdSMark Fasheh } 214ccd979bdSMark Fasheh } 215baf4661aSSunil Mushran out: 216ccd979bdSMark Fasheh return ret; 217ccd979bdSMark Fasheh } 218ccd979bdSMark Fasheh 219d85b20e4SJoel Becker int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) 220ccd979bdSMark Fasheh { 221*fc881fa0SJoel Becker int slot; 222d85b20e4SJoel Becker struct ocfs2_slot_info *si = osb->slot_info; 223ccd979bdSMark Fasheh 224d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 225d85b20e4SJoel Becker slot = __ocfs2_node_num_to_slot(si, node_num); 226d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 227d85b20e4SJoel Becker 228d85b20e4SJoel Becker return slot; 229d85b20e4SJoel Becker } 230d85b20e4SJoel Becker 231d85b20e4SJoel Becker int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num, 232d85b20e4SJoel Becker unsigned int *node_num) 233d85b20e4SJoel Becker { 234d85b20e4SJoel Becker struct ocfs2_slot_info *si = osb->slot_info; 235d85b20e4SJoel Becker 236d85b20e4SJoel Becker assert_spin_locked(&osb->osb_lock); 237d85b20e4SJoel Becker 238d85b20e4SJoel Becker BUG_ON(slot_num < 0); 239d85b20e4SJoel Becker BUG_ON(slot_num > osb->max_slots); 240d85b20e4SJoel Becker 241*fc881fa0SJoel Becker if (!si->si_slots[slot_num].sl_valid) 242d85b20e4SJoel Becker return -ENOENT; 243d85b20e4SJoel Becker 244*fc881fa0SJoel Becker *node_num = si->si_slots[slot_num].sl_node_num; 245d85b20e4SJoel Becker return 0; 246ccd979bdSMark Fasheh } 247ccd979bdSMark Fasheh 2488e8a4603SMark Fasheh static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) 2498e8a4603SMark Fasheh { 2501c8d9a6aSJoel Becker unsigned int i; 2511c8d9a6aSJoel Becker 2528e8a4603SMark Fasheh if (si == NULL) 2538e8a4603SMark Fasheh return; 2548e8a4603SMark Fasheh 2558e8a4603SMark Fasheh if (si->si_inode) 2568e8a4603SMark Fasheh iput(si->si_inode); 2571c8d9a6aSJoel Becker if (si->si_bh) { 2581c8d9a6aSJoel Becker for (i = 0; i < si->si_blocks; i++) { 2591c8d9a6aSJoel Becker if (si->si_bh[i]) { 2601c8d9a6aSJoel Becker brelse(si->si_bh[i]); 2611c8d9a6aSJoel Becker si->si_bh[i] = NULL; 2621c8d9a6aSJoel Becker } 2631c8d9a6aSJoel Becker } 2641c8d9a6aSJoel Becker kfree(si->si_bh); 2651c8d9a6aSJoel Becker } 2668e8a4603SMark Fasheh 2678e8a4603SMark Fasheh kfree(si); 2688e8a4603SMark Fasheh } 2698e8a4603SMark Fasheh 270*fc881fa0SJoel Becker int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num) 271ccd979bdSMark Fasheh { 2728e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 2738e8a4603SMark Fasheh 2748e8a4603SMark Fasheh if (si == NULL) 2758e8a4603SMark Fasheh return 0; 2768e8a4603SMark Fasheh 277d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 278*fc881fa0SJoel Becker ocfs2_invalidate_slot(si, slot_num); 279d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 2808e8a4603SMark Fasheh 2818e8a4603SMark Fasheh return ocfs2_update_disk_slots(osb, osb->slot_info); 282ccd979bdSMark Fasheh } 283ccd979bdSMark Fasheh 2841c8d9a6aSJoel Becker static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, 2851c8d9a6aSJoel Becker struct ocfs2_slot_info *si) 2861c8d9a6aSJoel Becker { 2871c8d9a6aSJoel Becker int status = 0; 2881c8d9a6aSJoel Becker u64 blkno; 2891c8d9a6aSJoel Becker unsigned long long blocks, bytes; 2901c8d9a6aSJoel Becker unsigned int i; 2911c8d9a6aSJoel Becker struct buffer_head *bh; 2921c8d9a6aSJoel Becker 2931c8d9a6aSJoel Becker status = ocfs2_slot_map_physical_size(osb, si->si_inode, &bytes); 2941c8d9a6aSJoel Becker if (status) 2951c8d9a6aSJoel Becker goto bail; 2961c8d9a6aSJoel Becker 2971c8d9a6aSJoel Becker blocks = ocfs2_blocks_for_bytes(si->si_inode->i_sb, bytes); 2981c8d9a6aSJoel Becker BUG_ON(blocks > UINT_MAX); 2991c8d9a6aSJoel Becker si->si_blocks = blocks; 3001c8d9a6aSJoel Becker if (!si->si_blocks) 3011c8d9a6aSJoel Becker goto bail; 3021c8d9a6aSJoel Becker 3031c8d9a6aSJoel Becker mlog(0, "Slot map needs %u buffers for %llu bytes\n", 3041c8d9a6aSJoel Becker si->si_blocks, bytes); 3051c8d9a6aSJoel Becker 3061c8d9a6aSJoel Becker si->si_bh = kzalloc(sizeof(struct buffer_head *) * si->si_blocks, 3071c8d9a6aSJoel Becker GFP_KERNEL); 3081c8d9a6aSJoel Becker if (!si->si_bh) { 3091c8d9a6aSJoel Becker status = -ENOMEM; 3101c8d9a6aSJoel Becker mlog_errno(status); 3111c8d9a6aSJoel Becker goto bail; 3121c8d9a6aSJoel Becker } 3131c8d9a6aSJoel Becker 3141c8d9a6aSJoel Becker for (i = 0; i < si->si_blocks; i++) { 3151c8d9a6aSJoel Becker status = ocfs2_extent_map_get_blocks(si->si_inode, i, 3161c8d9a6aSJoel Becker &blkno, NULL, NULL); 3171c8d9a6aSJoel Becker if (status < 0) { 3181c8d9a6aSJoel Becker mlog_errno(status); 3191c8d9a6aSJoel Becker goto bail; 3201c8d9a6aSJoel Becker } 3211c8d9a6aSJoel Becker 3221c8d9a6aSJoel Becker mlog(0, "Reading slot map block %u at %llu\n", i, 3231c8d9a6aSJoel Becker (unsigned long long)blkno); 3241c8d9a6aSJoel Becker 3251c8d9a6aSJoel Becker bh = NULL; /* Acquire a fresh bh */ 3261c8d9a6aSJoel Becker status = ocfs2_read_block(osb, blkno, &bh, 0, si->si_inode); 3271c8d9a6aSJoel Becker if (status < 0) { 3281c8d9a6aSJoel Becker mlog_errno(status); 3291c8d9a6aSJoel Becker goto bail; 3301c8d9a6aSJoel Becker } 3311c8d9a6aSJoel Becker 3321c8d9a6aSJoel Becker si->si_bh[i] = bh; 3331c8d9a6aSJoel Becker } 3341c8d9a6aSJoel Becker 3351c8d9a6aSJoel Becker bail: 3361c8d9a6aSJoel Becker return status; 3371c8d9a6aSJoel Becker } 3381c8d9a6aSJoel Becker 339ccd979bdSMark Fasheh int ocfs2_init_slot_info(struct ocfs2_super *osb) 340ccd979bdSMark Fasheh { 341*fc881fa0SJoel Becker int status; 342ccd979bdSMark Fasheh struct inode *inode = NULL; 343ccd979bdSMark Fasheh struct ocfs2_slot_info *si; 344ccd979bdSMark Fasheh 345*fc881fa0SJoel Becker si = kzalloc(sizeof(struct ocfs2_slot_info) + 346*fc881fa0SJoel Becker (sizeof(struct ocfs2_slot) * osb->max_slots), 347*fc881fa0SJoel Becker GFP_KERNEL); 348ccd979bdSMark Fasheh if (!si) { 349ccd979bdSMark Fasheh status = -ENOMEM; 350ccd979bdSMark Fasheh mlog_errno(status); 351ccd979bdSMark Fasheh goto bail; 352ccd979bdSMark Fasheh } 353ccd979bdSMark Fasheh 354ccd979bdSMark Fasheh si->si_num_slots = osb->max_slots; 355*fc881fa0SJoel Becker si->si_slots = (struct ocfs2_slot *)((char *)si + 356*fc881fa0SJoel Becker sizeof(struct ocfs2_slot_info)); 357ccd979bdSMark Fasheh 358ccd979bdSMark Fasheh inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, 359ccd979bdSMark Fasheh OCFS2_INVALID_SLOT); 360ccd979bdSMark Fasheh if (!inode) { 361ccd979bdSMark Fasheh status = -EINVAL; 362ccd979bdSMark Fasheh mlog_errno(status); 363ccd979bdSMark Fasheh goto bail; 364ccd979bdSMark Fasheh } 365ccd979bdSMark Fasheh 366ccd979bdSMark Fasheh si->si_inode = inode; 3671c8d9a6aSJoel Becker status = ocfs2_map_slot_buffers(osb, si); 3681c8d9a6aSJoel Becker if (status < 0) { 3691c8d9a6aSJoel Becker mlog_errno(status); 3701c8d9a6aSJoel Becker goto bail; 3711c8d9a6aSJoel Becker } 3721c8d9a6aSJoel Becker 373d85b20e4SJoel Becker osb->slot_info = (struct ocfs2_slot_info *)si; 374ccd979bdSMark Fasheh bail: 375ccd979bdSMark Fasheh if (status < 0 && si) 3768e8a4603SMark Fasheh __ocfs2_free_slot_info(si); 377ccd979bdSMark Fasheh 378ccd979bdSMark Fasheh return status; 379ccd979bdSMark Fasheh } 380ccd979bdSMark Fasheh 3818e8a4603SMark Fasheh void ocfs2_free_slot_info(struct ocfs2_super *osb) 382ccd979bdSMark Fasheh { 3838e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 3848e8a4603SMark Fasheh 3858e8a4603SMark Fasheh osb->slot_info = NULL; 3868e8a4603SMark Fasheh __ocfs2_free_slot_info(si); 387ccd979bdSMark Fasheh } 388ccd979bdSMark Fasheh 389ccd979bdSMark Fasheh int ocfs2_find_slot(struct ocfs2_super *osb) 390ccd979bdSMark Fasheh { 391ccd979bdSMark Fasheh int status; 392*fc881fa0SJoel Becker int slot; 393ccd979bdSMark Fasheh struct ocfs2_slot_info *si; 394ccd979bdSMark Fasheh 395ccd979bdSMark Fasheh mlog_entry_void(); 396ccd979bdSMark Fasheh 397ccd979bdSMark Fasheh si = osb->slot_info; 398ccd979bdSMark Fasheh 399d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 400ccd979bdSMark Fasheh ocfs2_update_slot_info(si); 401ccd979bdSMark Fasheh 402ccd979bdSMark Fasheh /* search for ourselves first and take the slot if it already 403ccd979bdSMark Fasheh * exists. Perhaps we need to mark this in a variable for our 404ccd979bdSMark Fasheh * own journal recovery? Possibly not, though we certainly 405ccd979bdSMark Fasheh * need to warn to the user */ 406ccd979bdSMark Fasheh slot = __ocfs2_node_num_to_slot(si, osb->node_num); 407*fc881fa0SJoel Becker if (slot < 0) { 408ccd979bdSMark Fasheh /* if no slot yet, then just take 1st available 409ccd979bdSMark Fasheh * one. */ 410baf4661aSSunil Mushran slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); 411*fc881fa0SJoel Becker if (slot < 0) { 412d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 413ccd979bdSMark Fasheh mlog(ML_ERROR, "no free slots available!\n"); 414ccd979bdSMark Fasheh status = -EINVAL; 415ccd979bdSMark Fasheh goto bail; 416ccd979bdSMark Fasheh } 417ccd979bdSMark Fasheh } else 418ccd979bdSMark Fasheh mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", 419ccd979bdSMark Fasheh slot); 420ccd979bdSMark Fasheh 421*fc881fa0SJoel Becker ocfs2_set_slot(si, slot, osb->node_num); 422ccd979bdSMark Fasheh osb->slot_num = slot; 423d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 424ccd979bdSMark Fasheh 425e7607ab3SMark Fasheh mlog(0, "taking node slot %d\n", osb->slot_num); 426ccd979bdSMark Fasheh 427ccd979bdSMark Fasheh status = ocfs2_update_disk_slots(osb, si); 428ccd979bdSMark Fasheh if (status < 0) 429ccd979bdSMark Fasheh mlog_errno(status); 430ccd979bdSMark Fasheh 431ccd979bdSMark Fasheh bail: 432ccd979bdSMark Fasheh mlog_exit(status); 433ccd979bdSMark Fasheh return status; 434ccd979bdSMark Fasheh } 435ccd979bdSMark Fasheh 436ccd979bdSMark Fasheh void ocfs2_put_slot(struct ocfs2_super *osb) 437ccd979bdSMark Fasheh { 438ccd979bdSMark Fasheh int status; 439ccd979bdSMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 440ccd979bdSMark Fasheh 441ccd979bdSMark Fasheh if (!si) 442ccd979bdSMark Fasheh return; 443ccd979bdSMark Fasheh 444d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 445ccd979bdSMark Fasheh ocfs2_update_slot_info(si); 446ccd979bdSMark Fasheh 447*fc881fa0SJoel Becker ocfs2_invalidate_slot(si, osb->slot_num); 448ccd979bdSMark Fasheh osb->slot_num = OCFS2_INVALID_SLOT; 449d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 450ccd979bdSMark Fasheh 451ccd979bdSMark Fasheh status = ocfs2_update_disk_slots(osb, si); 452ccd979bdSMark Fasheh if (status < 0) { 453ccd979bdSMark Fasheh mlog_errno(status); 454ccd979bdSMark Fasheh goto bail; 455ccd979bdSMark Fasheh } 456ccd979bdSMark Fasheh 457ccd979bdSMark Fasheh bail: 4588e8a4603SMark Fasheh ocfs2_free_slot_info(osb); 459ccd979bdSMark Fasheh } 460ccd979bdSMark Fasheh 461