1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* -*- mode: c; c-basic-offset: 8; -*- 3 * vim: noexpandtab sw=8 ts=8 sts=0: 4 * 5 * sysfile.c 6 * 7 * Initialize, read, write, etc. system files. 8 * 9 * Copyright (C) 2002, 2004 Oracle. All rights reserved. 10 */ 11 12 #include <linux/fs.h> 13 #include <linux/types.h> 14 #include <linux/highmem.h> 15 16 #include <cluster/masklog.h> 17 18 #include "ocfs2.h" 19 20 #include "alloc.h" 21 #include "dir.h" 22 #include "inode.h" 23 #include "journal.h" 24 #include "sysfile.h" 25 26 #include "buffer_head_io.h" 27 28 static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb, 29 int type, 30 u32 slot); 31 32 #ifdef CONFIG_DEBUG_LOCK_ALLOC 33 static struct lock_class_key ocfs2_sysfile_cluster_lock_key[NUM_SYSTEM_INODES]; 34 #endif 35 36 static inline int is_global_system_inode(int type) 37 { 38 return type >= OCFS2_FIRST_ONLINE_SYSTEM_INODE && 39 type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; 40 } 41 42 static struct inode **get_local_system_inode(struct ocfs2_super *osb, 43 int type, 44 u32 slot) 45 { 46 int index; 47 struct inode **local_system_inodes, **free = NULL; 48 49 BUG_ON(slot == OCFS2_INVALID_SLOT); 50 BUG_ON(type < OCFS2_FIRST_LOCAL_SYSTEM_INODE || 51 type > OCFS2_LAST_LOCAL_SYSTEM_INODE); 52 53 spin_lock(&osb->osb_lock); 54 local_system_inodes = osb->local_system_inodes; 55 spin_unlock(&osb->osb_lock); 56 57 if (unlikely(!local_system_inodes)) { 58 local_system_inodes = 59 kzalloc(array3_size(sizeof(struct inode *), 60 NUM_LOCAL_SYSTEM_INODES, 61 osb->max_slots), 62 GFP_NOFS); 63 if (!local_system_inodes) { 64 mlog_errno(-ENOMEM); 65 /* 66 * return NULL here so that ocfs2_get_sytem_file_inodes 67 * will try to create an inode and use it. We will try 68 * to initialize local_system_inodes next time. 69 */ 70 return NULL; 71 } 72 73 spin_lock(&osb->osb_lock); 74 if (osb->local_system_inodes) { 75 /* Someone has initialized it for us. */ 76 free = local_system_inodes; 77 local_system_inodes = osb->local_system_inodes; 78 } else 79 osb->local_system_inodes = local_system_inodes; 80 spin_unlock(&osb->osb_lock); 81 kfree(free); 82 } 83 84 index = (slot * NUM_LOCAL_SYSTEM_INODES) + 85 (type - OCFS2_FIRST_LOCAL_SYSTEM_INODE); 86 87 return &local_system_inodes[index]; 88 } 89 90 struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, 91 int type, 92 u32 slot) 93 { 94 struct inode *inode = NULL; 95 struct inode **arr = NULL; 96 97 /* avoid the lookup if cached in local system file array */ 98 if (is_global_system_inode(type)) { 99 arr = &(osb->global_system_inodes[type]); 100 } else 101 arr = get_local_system_inode(osb, type, slot); 102 103 mutex_lock(&osb->system_file_mutex); 104 if (arr && ((inode = *arr) != NULL)) { 105 /* get a ref in addition to the array ref */ 106 inode = igrab(inode); 107 mutex_unlock(&osb->system_file_mutex); 108 BUG_ON(!inode); 109 110 return inode; 111 } 112 113 /* this gets one ref thru iget */ 114 inode = _ocfs2_get_system_file_inode(osb, type, slot); 115 116 /* add one more if putting into array for first time */ 117 if (arr && inode) { 118 *arr = igrab(inode); 119 BUG_ON(!*arr); 120 } 121 mutex_unlock(&osb->system_file_mutex); 122 return inode; 123 } 124 125 static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb, 126 int type, 127 u32 slot) 128 { 129 char namebuf[40]; 130 struct inode *inode = NULL; 131 u64 blkno; 132 int status = 0; 133 134 ocfs2_sprintf_system_inode_name(namebuf, 135 sizeof(namebuf), 136 type, slot); 137 138 status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, namebuf, 139 strlen(namebuf), &blkno); 140 if (status < 0) { 141 goto bail; 142 } 143 144 inode = ocfs2_iget(osb, blkno, OCFS2_FI_FLAG_SYSFILE, type); 145 if (IS_ERR(inode)) { 146 mlog_errno(PTR_ERR(inode)); 147 inode = NULL; 148 goto bail; 149 } 150 #ifdef CONFIG_DEBUG_LOCK_ALLOC 151 if (type == LOCAL_USER_QUOTA_SYSTEM_INODE || 152 type == LOCAL_GROUP_QUOTA_SYSTEM_INODE || 153 type == JOURNAL_SYSTEM_INODE) { 154 /* Ignore inode lock on these inodes as the lock does not 155 * really belong to any process and lockdep cannot handle 156 * that */ 157 OCFS2_I(inode)->ip_inode_lockres.l_lockdep_map.key = NULL; 158 } else { 159 lockdep_init_map(&OCFS2_I(inode)->ip_inode_lockres. 160 l_lockdep_map, 161 ocfs2_system_inodes[type].si_name, 162 &ocfs2_sysfile_cluster_lock_key[type], 0); 163 } 164 #endif 165 bail: 166 167 return inode; 168 } 169 170