1/* 2 * ifile.c - NILFS inode file 3 * 4 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 * Written by Amagai Yoshiji <amagai@osrg.net>. 21 * Revised by Ryusuke Konishi <ryusuke@osrg.net>. 22 * 23 */ 24 25#include <linux/types.h> 26#include <linux/buffer_head.h> 27#include "nilfs.h" 28#include "mdt.h" 29#include "alloc.h" 30#include "ifile.h" 31 32/** 33 * struct nilfs_ifile_info - on-memory private data of ifile 34 * @mi: on-memory private data of metadata file 35 * @palloc_cache: persistent object allocator cache of ifile 36 */ 37struct nilfs_ifile_info { 38 struct nilfs_mdt_info mi; 39 struct nilfs_palloc_cache palloc_cache; 40}; 41 42static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile) 43{ 44 return (struct nilfs_ifile_info *)NILFS_MDT(ifile); 45} 46 47/** 48 * nilfs_ifile_create_inode - create a new disk inode 49 * @ifile: ifile inode 50 * @out_ino: pointer to a variable to store inode number 51 * @out_bh: buffer_head contains newly allocated disk inode 52 * 53 * Return Value: On success, 0 is returned and the newly allocated inode 54 * number is stored in the place pointed by @ino, and buffer_head pointer 55 * that contains newly allocated disk inode structure is stored in the 56 * place pointed by @out_bh 57 * On error, one of the following negative error codes is returned. 58 * 59 * %-EIO - I/O error. 60 * 61 * %-ENOMEM - Insufficient amount of memory available. 62 * 63 * %-ENOSPC - No inode left. 64 */ 65int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, 66 struct buffer_head **out_bh) 67{ 68 struct nilfs_palloc_req req; 69 int ret; 70 71 req.pr_entry_nr = 0; /* 0 says find free inode from beginning of 72 a group. dull code!! */ 73 req.pr_entry_bh = NULL; 74 75 ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); 76 if (!ret) { 77 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1, 78 &req.pr_entry_bh); 79 if (ret < 0) 80 nilfs_palloc_abort_alloc_entry(ifile, &req); 81 } 82 if (ret < 0) { 83 brelse(req.pr_entry_bh); 84 return ret; 85 } 86 nilfs_palloc_commit_alloc_entry(ifile, &req); 87 mark_buffer_dirty(req.pr_entry_bh); 88 nilfs_mdt_mark_dirty(ifile); 89 *out_ino = (ino_t)req.pr_entry_nr; 90 *out_bh = req.pr_entry_bh; 91 return 0; 92} 93 94/** 95 * nilfs_ifile_delete_inode - delete a disk inode 96 * @ifile: ifile inode 97 * @ino: inode number 98 * 99 * Return Value: On success, 0 is returned. On error, one of the following 100 * negative error codes is returned. 101 * 102 * %-EIO - I/O error. 103 * 104 * %-ENOMEM - Insufficient amount of memory available. 105 * 106 * %-ENOENT - The inode number @ino have not been allocated. 107 */ 108int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino) 109{ 110 struct nilfs_palloc_req req = { 111 .pr_entry_nr = ino, .pr_entry_bh = NULL 112 }; 113 struct nilfs_inode *raw_inode; 114 void *kaddr; 115 int ret; 116 117 ret = nilfs_palloc_prepare_free_entry(ifile, &req); 118 if (!ret) { 119 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0, 120 &req.pr_entry_bh); 121 if (ret < 0) 122 nilfs_palloc_abort_free_entry(ifile, &req); 123 } 124 if (ret < 0) { 125 brelse(req.pr_entry_bh); 126 return ret; 127 } 128 129 kaddr = kmap_atomic(req.pr_entry_bh->b_page); 130 raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr, 131 req.pr_entry_bh, kaddr); 132 raw_inode->i_flags = 0; 133 kunmap_atomic(kaddr); 134 135 mark_buffer_dirty(req.pr_entry_bh); 136 brelse(req.pr_entry_bh); 137 138 nilfs_palloc_commit_free_entry(ifile, &req); 139 140 return 0; 141} 142 143int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino, 144 struct buffer_head **out_bh) 145{ 146 struct super_block *sb = ifile->i_sb; 147 int err; 148 149 if (unlikely(!NILFS_VALID_INODE(sb, ino))) { 150 nilfs_error(sb, __func__, "bad inode number: %lu", 151 (unsigned long) ino); 152 return -EINVAL; 153 } 154 155 err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh); 156 if (unlikely(err)) 157 nilfs_warning(sb, __func__, "unable to read inode: %lu", 158 (unsigned long) ino); 159 return err; 160} 161 162/** 163 * nilfs_ifile_count_free_inodes - calculate free inodes count 164 * @ifile: ifile inode 165 * @nmaxinodes: current maximum of available inodes count [out] 166 * @nfreeinodes: free inodes count [out] 167 */ 168int nilfs_ifile_count_free_inodes(struct inode *ifile, 169 u64 *nmaxinodes, u64 *nfreeinodes) 170{ 171 u64 nused; 172 int err; 173 174 *nmaxinodes = 0; 175 *nfreeinodes = 0; 176 177 nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count); 178 err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes); 179 if (likely(!err)) 180 *nfreeinodes = *nmaxinodes - nused; 181 return err; 182} 183 184/** 185 * nilfs_ifile_read - read or get ifile inode 186 * @sb: super block instance 187 * @root: root object 188 * @inode_size: size of an inode 189 * @raw_inode: on-disk ifile inode 190 * @inodep: buffer to store the inode 191 */ 192int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root, 193 size_t inode_size, struct nilfs_inode *raw_inode, 194 struct inode **inodep) 195{ 196 struct inode *ifile; 197 int err; 198 199 ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO); 200 if (unlikely(!ifile)) 201 return -ENOMEM; 202 if (!(ifile->i_state & I_NEW)) 203 goto out; 204 205 err = nilfs_mdt_init(ifile, NILFS_MDT_GFP, 206 sizeof(struct nilfs_ifile_info)); 207 if (err) 208 goto failed; 209 210 err = nilfs_palloc_init_blockgroup(ifile, inode_size); 211 if (err) 212 goto failed; 213 214 nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache); 215 216 err = nilfs_read_inode_common(ifile, raw_inode); 217 if (err) 218 goto failed; 219 220 unlock_new_inode(ifile); 221 out: 222 *inodep = ifile; 223 return 0; 224 failed: 225 iget_failed(ifile); 226 return err; 227} 228