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 45d85b20e4SJoel Becker struct ocfs2_slot_info { 46d85b20e4SJoel Becker struct inode *si_inode; 47*1c8d9a6aSJoel Becker unsigned int si_blocks; 48*1c8d9a6aSJoel Becker struct buffer_head **si_bh; 49d85b20e4SJoel Becker unsigned int si_num_slots; 50d85b20e4SJoel Becker unsigned int si_size; 51d85b20e4SJoel Becker s16 si_global_node_nums[OCFS2_MAX_SLOTS]; 52d85b20e4SJoel Becker }; 53d85b20e4SJoel Becker 54d85b20e4SJoel Becker 55ccd979bdSMark Fasheh static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 56ccd979bdSMark Fasheh s16 global); 57ccd979bdSMark Fasheh static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 58ccd979bdSMark Fasheh s16 slot_num, 59ccd979bdSMark Fasheh s16 node_num); 60ccd979bdSMark Fasheh 61d85b20e4SJoel Becker /* 62d85b20e4SJoel Becker * Post the slot information on disk into our slot_info struct. 63d85b20e4SJoel Becker * Must be protected by osb_lock. 64d85b20e4SJoel Becker */ 658e8a4603SMark Fasheh static void ocfs2_update_slot_info(struct ocfs2_slot_info *si) 66ccd979bdSMark Fasheh { 67ccd979bdSMark Fasheh int i; 68ccd979bdSMark Fasheh __le16 *disk_info; 69ccd979bdSMark Fasheh 70ccd979bdSMark Fasheh /* we don't read the slot block here as ocfs2_super_lock 71ccd979bdSMark Fasheh * should've made sure we have the most recent copy. */ 72*1c8d9a6aSJoel Becker disk_info = (__le16 *) si->si_bh[0]->b_data; 73ccd979bdSMark Fasheh 74ccd979bdSMark Fasheh for (i = 0; i < si->si_size; i++) 75ccd979bdSMark Fasheh si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]); 76ccd979bdSMark Fasheh } 77ccd979bdSMark Fasheh 788e8a4603SMark Fasheh int ocfs2_refresh_slot_info(struct ocfs2_super *osb) 798e8a4603SMark Fasheh { 808e8a4603SMark Fasheh int ret; 818e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 828e8a4603SMark Fasheh 838e8a4603SMark Fasheh if (si == NULL) 848e8a4603SMark Fasheh return 0; 858e8a4603SMark Fasheh 86*1c8d9a6aSJoel Becker BUG_ON(si->si_blocks == 0); 87*1c8d9a6aSJoel Becker BUG_ON(si->si_bh == NULL); 88*1c8d9a6aSJoel Becker 89*1c8d9a6aSJoel Becker mlog(0, "Refreshing slot map, reading %u block(s)\n", 90*1c8d9a6aSJoel Becker si->si_blocks); 91*1c8d9a6aSJoel Becker 92*1c8d9a6aSJoel Becker /* 93*1c8d9a6aSJoel Becker * We pass -1 as blocknr because we expect all of si->si_bh to 94*1c8d9a6aSJoel Becker * be !NULL. Thus, ocfs2_read_blocks() will ignore blocknr. If 95*1c8d9a6aSJoel Becker * this is not true, the read of -1 (UINT64_MAX) will fail. 96*1c8d9a6aSJoel Becker */ 97*1c8d9a6aSJoel Becker ret = ocfs2_read_blocks(osb, -1, si->si_blocks, si->si_bh, 0, 98*1c8d9a6aSJoel Becker si->si_inode); 99d85b20e4SJoel Becker if (ret == 0) { 100d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 1018e8a4603SMark Fasheh ocfs2_update_slot_info(si); 102d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 103d85b20e4SJoel Becker } 1048e8a4603SMark Fasheh 1058e8a4603SMark Fasheh return ret; 1068e8a4603SMark Fasheh } 1078e8a4603SMark Fasheh 108ccd979bdSMark Fasheh /* post the our slot info stuff into it's destination bh and write it 109ccd979bdSMark Fasheh * out. */ 1108e8a4603SMark Fasheh static int ocfs2_update_disk_slots(struct ocfs2_super *osb, 111ccd979bdSMark Fasheh struct ocfs2_slot_info *si) 112ccd979bdSMark Fasheh { 113ccd979bdSMark Fasheh int status, i; 114*1c8d9a6aSJoel Becker __le16 *disk_info = (__le16 *) si->si_bh[0]->b_data; 115ccd979bdSMark Fasheh 116d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 117ccd979bdSMark Fasheh for (i = 0; i < si->si_size; i++) 118ccd979bdSMark Fasheh disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]); 119d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 120ccd979bdSMark Fasheh 121*1c8d9a6aSJoel Becker status = ocfs2_write_block(osb, si->si_bh[0], si->si_inode); 122ccd979bdSMark Fasheh if (status < 0) 123ccd979bdSMark Fasheh mlog_errno(status); 124ccd979bdSMark Fasheh 125ccd979bdSMark Fasheh return status; 126ccd979bdSMark Fasheh } 127ccd979bdSMark Fasheh 128*1c8d9a6aSJoel Becker /* 129*1c8d9a6aSJoel Becker * Calculate how many bytes are needed by the slot map. Returns 130*1c8d9a6aSJoel Becker * an error if the slot map file is too small. 131*1c8d9a6aSJoel Becker */ 132*1c8d9a6aSJoel Becker static int ocfs2_slot_map_physical_size(struct ocfs2_super *osb, 133*1c8d9a6aSJoel Becker struct inode *inode, 134*1c8d9a6aSJoel Becker unsigned long long *bytes) 135*1c8d9a6aSJoel Becker { 136*1c8d9a6aSJoel Becker unsigned long long bytes_needed; 137*1c8d9a6aSJoel Becker 138*1c8d9a6aSJoel Becker bytes_needed = osb->max_slots * sizeof(__le16); 139*1c8d9a6aSJoel Becker if (bytes_needed > i_size_read(inode)) { 140*1c8d9a6aSJoel Becker mlog(ML_ERROR, 141*1c8d9a6aSJoel Becker "Slot map file is too small! (size %llu, needed %llu)\n", 142*1c8d9a6aSJoel Becker i_size_read(inode), bytes_needed); 143*1c8d9a6aSJoel Becker return -ENOSPC; 144*1c8d9a6aSJoel Becker } 145*1c8d9a6aSJoel Becker 146*1c8d9a6aSJoel Becker *bytes = bytes_needed; 147*1c8d9a6aSJoel Becker return 0; 148*1c8d9a6aSJoel Becker } 149*1c8d9a6aSJoel Becker 150ccd979bdSMark Fasheh /* try to find global node in the slot info. Returns 151ccd979bdSMark Fasheh * OCFS2_INVALID_SLOT if nothing is found. */ 152ccd979bdSMark Fasheh static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, 153ccd979bdSMark Fasheh s16 global) 154ccd979bdSMark Fasheh { 155ccd979bdSMark Fasheh int i; 156ccd979bdSMark Fasheh s16 ret = OCFS2_INVALID_SLOT; 157ccd979bdSMark Fasheh 158ccd979bdSMark Fasheh for(i = 0; i < si->si_num_slots; i++) { 159ccd979bdSMark Fasheh if (global == si->si_global_node_nums[i]) { 160ccd979bdSMark Fasheh ret = (s16) i; 161ccd979bdSMark Fasheh break; 162ccd979bdSMark Fasheh } 163ccd979bdSMark Fasheh } 164ccd979bdSMark Fasheh return ret; 165ccd979bdSMark Fasheh } 166ccd979bdSMark Fasheh 167d85b20e4SJoel Becker static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, 168d85b20e4SJoel Becker s16 preferred) 169ccd979bdSMark Fasheh { 170ccd979bdSMark Fasheh int i; 171ccd979bdSMark Fasheh s16 ret = OCFS2_INVALID_SLOT; 172ccd979bdSMark Fasheh 173baf4661aSSunil Mushran if (preferred >= 0 && preferred < si->si_num_slots) { 174baf4661aSSunil Mushran if (OCFS2_INVALID_SLOT == si->si_global_node_nums[preferred]) { 175baf4661aSSunil Mushran ret = preferred; 176baf4661aSSunil Mushran goto out; 177baf4661aSSunil Mushran } 178baf4661aSSunil Mushran } 179baf4661aSSunil Mushran 180ccd979bdSMark Fasheh for(i = 0; i < si->si_num_slots; i++) { 181ccd979bdSMark Fasheh if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) { 182ccd979bdSMark Fasheh ret = (s16) i; 183ccd979bdSMark Fasheh break; 184ccd979bdSMark Fasheh } 185ccd979bdSMark Fasheh } 186baf4661aSSunil Mushran out: 187ccd979bdSMark Fasheh return ret; 188ccd979bdSMark Fasheh } 189ccd979bdSMark Fasheh 190d85b20e4SJoel Becker int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num) 191ccd979bdSMark Fasheh { 192d85b20e4SJoel Becker s16 slot; 193d85b20e4SJoel Becker struct ocfs2_slot_info *si = osb->slot_info; 194ccd979bdSMark Fasheh 195d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 196d85b20e4SJoel Becker slot = __ocfs2_node_num_to_slot(si, node_num); 197d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 198d85b20e4SJoel Becker 199d85b20e4SJoel Becker if (slot == OCFS2_INVALID_SLOT) 200d85b20e4SJoel Becker return -ENOENT; 201d85b20e4SJoel Becker 202d85b20e4SJoel Becker return slot; 203d85b20e4SJoel Becker } 204d85b20e4SJoel Becker 205d85b20e4SJoel Becker int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num, 206d85b20e4SJoel Becker unsigned int *node_num) 207d85b20e4SJoel Becker { 208d85b20e4SJoel Becker struct ocfs2_slot_info *si = osb->slot_info; 209d85b20e4SJoel Becker 210d85b20e4SJoel Becker assert_spin_locked(&osb->osb_lock); 211d85b20e4SJoel Becker 212d85b20e4SJoel Becker BUG_ON(slot_num < 0); 213d85b20e4SJoel Becker BUG_ON(slot_num > osb->max_slots); 214d85b20e4SJoel Becker 215d85b20e4SJoel Becker if (si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT) 216d85b20e4SJoel Becker return -ENOENT; 217d85b20e4SJoel Becker 218d85b20e4SJoel Becker *node_num = si->si_global_node_nums[slot_num]; 219d85b20e4SJoel Becker return 0; 220ccd979bdSMark Fasheh } 221ccd979bdSMark Fasheh 2228e8a4603SMark Fasheh static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si) 2238e8a4603SMark Fasheh { 224*1c8d9a6aSJoel Becker unsigned int i; 225*1c8d9a6aSJoel Becker 2268e8a4603SMark Fasheh if (si == NULL) 2278e8a4603SMark Fasheh return; 2288e8a4603SMark Fasheh 2298e8a4603SMark Fasheh if (si->si_inode) 2308e8a4603SMark Fasheh iput(si->si_inode); 231*1c8d9a6aSJoel Becker if (si->si_bh) { 232*1c8d9a6aSJoel Becker for (i = 0; i < si->si_blocks; i++) { 233*1c8d9a6aSJoel Becker if (si->si_bh[i]) { 234*1c8d9a6aSJoel Becker brelse(si->si_bh[i]); 235*1c8d9a6aSJoel Becker si->si_bh[i] = NULL; 236*1c8d9a6aSJoel Becker } 237*1c8d9a6aSJoel Becker } 238*1c8d9a6aSJoel Becker kfree(si->si_bh); 239*1c8d9a6aSJoel Becker } 2408e8a4603SMark Fasheh 2418e8a4603SMark Fasheh kfree(si); 2428e8a4603SMark Fasheh } 2438e8a4603SMark Fasheh 244ccd979bdSMark Fasheh static void __ocfs2_fill_slot(struct ocfs2_slot_info *si, 245ccd979bdSMark Fasheh s16 slot_num, 246ccd979bdSMark Fasheh s16 node_num) 247ccd979bdSMark Fasheh { 248ccd979bdSMark Fasheh BUG_ON(slot_num == OCFS2_INVALID_SLOT); 249ccd979bdSMark Fasheh BUG_ON(slot_num >= si->si_num_slots); 250ccd979bdSMark Fasheh BUG_ON((node_num != O2NM_INVALID_NODE_NUM) && 251ccd979bdSMark Fasheh (node_num >= O2NM_MAX_NODES)); 252ccd979bdSMark Fasheh 253ccd979bdSMark Fasheh si->si_global_node_nums[slot_num] = node_num; 254ccd979bdSMark Fasheh } 255ccd979bdSMark Fasheh 2568e8a4603SMark Fasheh int ocfs2_clear_slot(struct ocfs2_super *osb, s16 slot_num) 257ccd979bdSMark Fasheh { 2588e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 2598e8a4603SMark Fasheh 2608e8a4603SMark Fasheh if (si == NULL) 2618e8a4603SMark Fasheh return 0; 2628e8a4603SMark Fasheh 263d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 264ccd979bdSMark Fasheh __ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT); 265d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 2668e8a4603SMark Fasheh 2678e8a4603SMark Fasheh return ocfs2_update_disk_slots(osb, osb->slot_info); 268ccd979bdSMark Fasheh } 269ccd979bdSMark Fasheh 270*1c8d9a6aSJoel Becker static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, 271*1c8d9a6aSJoel Becker struct ocfs2_slot_info *si) 272*1c8d9a6aSJoel Becker { 273*1c8d9a6aSJoel Becker int status = 0; 274*1c8d9a6aSJoel Becker u64 blkno; 275*1c8d9a6aSJoel Becker unsigned long long blocks, bytes; 276*1c8d9a6aSJoel Becker unsigned int i; 277*1c8d9a6aSJoel Becker struct buffer_head *bh; 278*1c8d9a6aSJoel Becker 279*1c8d9a6aSJoel Becker status = ocfs2_slot_map_physical_size(osb, si->si_inode, &bytes); 280*1c8d9a6aSJoel Becker if (status) 281*1c8d9a6aSJoel Becker goto bail; 282*1c8d9a6aSJoel Becker 283*1c8d9a6aSJoel Becker blocks = ocfs2_blocks_for_bytes(si->si_inode->i_sb, bytes); 284*1c8d9a6aSJoel Becker BUG_ON(blocks > UINT_MAX); 285*1c8d9a6aSJoel Becker si->si_blocks = blocks; 286*1c8d9a6aSJoel Becker if (!si->si_blocks) 287*1c8d9a6aSJoel Becker goto bail; 288*1c8d9a6aSJoel Becker 289*1c8d9a6aSJoel Becker mlog(0, "Slot map needs %u buffers for %llu bytes\n", 290*1c8d9a6aSJoel Becker si->si_blocks, bytes); 291*1c8d9a6aSJoel Becker 292*1c8d9a6aSJoel Becker si->si_bh = kzalloc(sizeof(struct buffer_head *) * si->si_blocks, 293*1c8d9a6aSJoel Becker GFP_KERNEL); 294*1c8d9a6aSJoel Becker if (!si->si_bh) { 295*1c8d9a6aSJoel Becker status = -ENOMEM; 296*1c8d9a6aSJoel Becker mlog_errno(status); 297*1c8d9a6aSJoel Becker goto bail; 298*1c8d9a6aSJoel Becker } 299*1c8d9a6aSJoel Becker 300*1c8d9a6aSJoel Becker for (i = 0; i < si->si_blocks; i++) { 301*1c8d9a6aSJoel Becker status = ocfs2_extent_map_get_blocks(si->si_inode, i, 302*1c8d9a6aSJoel Becker &blkno, NULL, NULL); 303*1c8d9a6aSJoel Becker if (status < 0) { 304*1c8d9a6aSJoel Becker mlog_errno(status); 305*1c8d9a6aSJoel Becker goto bail; 306*1c8d9a6aSJoel Becker } 307*1c8d9a6aSJoel Becker 308*1c8d9a6aSJoel Becker mlog(0, "Reading slot map block %u at %llu\n", i, 309*1c8d9a6aSJoel Becker (unsigned long long)blkno); 310*1c8d9a6aSJoel Becker 311*1c8d9a6aSJoel Becker bh = NULL; /* Acquire a fresh bh */ 312*1c8d9a6aSJoel Becker status = ocfs2_read_block(osb, blkno, &bh, 0, si->si_inode); 313*1c8d9a6aSJoel Becker if (status < 0) { 314*1c8d9a6aSJoel Becker mlog_errno(status); 315*1c8d9a6aSJoel Becker goto bail; 316*1c8d9a6aSJoel Becker } 317*1c8d9a6aSJoel Becker 318*1c8d9a6aSJoel Becker si->si_bh[i] = bh; 319*1c8d9a6aSJoel Becker } 320*1c8d9a6aSJoel Becker 321*1c8d9a6aSJoel Becker bail: 322*1c8d9a6aSJoel Becker return status; 323*1c8d9a6aSJoel Becker } 324*1c8d9a6aSJoel Becker 325ccd979bdSMark Fasheh int ocfs2_init_slot_info(struct ocfs2_super *osb) 326ccd979bdSMark Fasheh { 327ccd979bdSMark Fasheh int status, i; 328ccd979bdSMark Fasheh struct inode *inode = NULL; 329ccd979bdSMark Fasheh struct ocfs2_slot_info *si; 330ccd979bdSMark Fasheh 331cd861280SRobert P. J. Day si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL); 332ccd979bdSMark Fasheh if (!si) { 333ccd979bdSMark Fasheh status = -ENOMEM; 334ccd979bdSMark Fasheh mlog_errno(status); 335ccd979bdSMark Fasheh goto bail; 336ccd979bdSMark Fasheh } 337ccd979bdSMark Fasheh 338ccd979bdSMark Fasheh si->si_num_slots = osb->max_slots; 339ccd979bdSMark Fasheh si->si_size = OCFS2_MAX_SLOTS; 340ccd979bdSMark Fasheh 341ccd979bdSMark Fasheh for(i = 0; i < si->si_num_slots; i++) 342ccd979bdSMark Fasheh si->si_global_node_nums[i] = OCFS2_INVALID_SLOT; 343ccd979bdSMark Fasheh 344ccd979bdSMark Fasheh inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE, 345ccd979bdSMark Fasheh OCFS2_INVALID_SLOT); 346ccd979bdSMark Fasheh if (!inode) { 347ccd979bdSMark Fasheh status = -EINVAL; 348ccd979bdSMark Fasheh mlog_errno(status); 349ccd979bdSMark Fasheh goto bail; 350ccd979bdSMark Fasheh } 351ccd979bdSMark Fasheh 352ccd979bdSMark Fasheh si->si_inode = inode; 353*1c8d9a6aSJoel Becker status = ocfs2_map_slot_buffers(osb, si); 354*1c8d9a6aSJoel Becker if (status < 0) { 355*1c8d9a6aSJoel Becker mlog_errno(status); 356*1c8d9a6aSJoel Becker goto bail; 357*1c8d9a6aSJoel Becker } 358*1c8d9a6aSJoel Becker 359d85b20e4SJoel Becker osb->slot_info = (struct ocfs2_slot_info *)si; 360ccd979bdSMark Fasheh bail: 361ccd979bdSMark Fasheh if (status < 0 && si) 3628e8a4603SMark Fasheh __ocfs2_free_slot_info(si); 363ccd979bdSMark Fasheh 364ccd979bdSMark Fasheh return status; 365ccd979bdSMark Fasheh } 366ccd979bdSMark Fasheh 3678e8a4603SMark Fasheh void ocfs2_free_slot_info(struct ocfs2_super *osb) 368ccd979bdSMark Fasheh { 3698e8a4603SMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 3708e8a4603SMark Fasheh 3718e8a4603SMark Fasheh osb->slot_info = NULL; 3728e8a4603SMark Fasheh __ocfs2_free_slot_info(si); 373ccd979bdSMark Fasheh } 374ccd979bdSMark Fasheh 375ccd979bdSMark Fasheh int ocfs2_find_slot(struct ocfs2_super *osb) 376ccd979bdSMark Fasheh { 377ccd979bdSMark Fasheh int status; 378ccd979bdSMark Fasheh s16 slot; 379ccd979bdSMark Fasheh struct ocfs2_slot_info *si; 380ccd979bdSMark Fasheh 381ccd979bdSMark Fasheh mlog_entry_void(); 382ccd979bdSMark Fasheh 383ccd979bdSMark Fasheh si = osb->slot_info; 384ccd979bdSMark Fasheh 385d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 386ccd979bdSMark Fasheh ocfs2_update_slot_info(si); 387ccd979bdSMark Fasheh 388ccd979bdSMark Fasheh /* search for ourselves first and take the slot if it already 389ccd979bdSMark Fasheh * exists. Perhaps we need to mark this in a variable for our 390ccd979bdSMark Fasheh * own journal recovery? Possibly not, though we certainly 391ccd979bdSMark Fasheh * need to warn to the user */ 392ccd979bdSMark Fasheh slot = __ocfs2_node_num_to_slot(si, osb->node_num); 393ccd979bdSMark Fasheh if (slot == OCFS2_INVALID_SLOT) { 394ccd979bdSMark Fasheh /* if no slot yet, then just take 1st available 395ccd979bdSMark Fasheh * one. */ 396baf4661aSSunil Mushran slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); 397ccd979bdSMark Fasheh if (slot == OCFS2_INVALID_SLOT) { 398d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 399ccd979bdSMark Fasheh mlog(ML_ERROR, "no free slots available!\n"); 400ccd979bdSMark Fasheh status = -EINVAL; 401ccd979bdSMark Fasheh goto bail; 402ccd979bdSMark Fasheh } 403ccd979bdSMark Fasheh } else 404ccd979bdSMark Fasheh mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", 405ccd979bdSMark Fasheh slot); 406ccd979bdSMark Fasheh 407ccd979bdSMark Fasheh __ocfs2_fill_slot(si, slot, osb->node_num); 408ccd979bdSMark Fasheh osb->slot_num = slot; 409d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 410ccd979bdSMark Fasheh 411e7607ab3SMark Fasheh mlog(0, "taking node slot %d\n", osb->slot_num); 412ccd979bdSMark Fasheh 413ccd979bdSMark Fasheh status = ocfs2_update_disk_slots(osb, si); 414ccd979bdSMark Fasheh if (status < 0) 415ccd979bdSMark Fasheh mlog_errno(status); 416ccd979bdSMark Fasheh 417ccd979bdSMark Fasheh bail: 418ccd979bdSMark Fasheh mlog_exit(status); 419ccd979bdSMark Fasheh return status; 420ccd979bdSMark Fasheh } 421ccd979bdSMark Fasheh 422ccd979bdSMark Fasheh void ocfs2_put_slot(struct ocfs2_super *osb) 423ccd979bdSMark Fasheh { 424ccd979bdSMark Fasheh int status; 425ccd979bdSMark Fasheh struct ocfs2_slot_info *si = osb->slot_info; 426ccd979bdSMark Fasheh 427ccd979bdSMark Fasheh if (!si) 428ccd979bdSMark Fasheh return; 429ccd979bdSMark Fasheh 430d85b20e4SJoel Becker spin_lock(&osb->osb_lock); 431ccd979bdSMark Fasheh ocfs2_update_slot_info(si); 432ccd979bdSMark Fasheh 433ccd979bdSMark Fasheh __ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT); 434ccd979bdSMark Fasheh osb->slot_num = OCFS2_INVALID_SLOT; 435d85b20e4SJoel Becker spin_unlock(&osb->osb_lock); 436ccd979bdSMark Fasheh 437ccd979bdSMark Fasheh status = ocfs2_update_disk_slots(osb, si); 438ccd979bdSMark Fasheh if (status < 0) { 439ccd979bdSMark Fasheh mlog_errno(status); 440ccd979bdSMark Fasheh goto bail; 441ccd979bdSMark Fasheh } 442ccd979bdSMark Fasheh 443ccd979bdSMark Fasheh bail: 4448e8a4603SMark Fasheh ocfs2_free_slot_info(osb); 445ccd979bdSMark Fasheh } 446ccd979bdSMark Fasheh 447