1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * NILFS inode file 4 * 5 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation. 6 * 7 * Written by Amagai Yoshiji. 8 * Revised by Ryusuke Konishi. 9 * 10 */ 11 12 #include <linux/types.h> 13 #include <linux/buffer_head.h> 14 #include "nilfs.h" 15 #include "mdt.h" 16 #include "alloc.h" 17 #include "ifile.h" 18 #include "cpfile.h" 19 20 /** 21 * struct nilfs_ifile_info - on-memory private data of ifile 22 * @mi: on-memory private data of metadata file 23 * @palloc_cache: persistent object allocator cache of ifile 24 */ 25 struct nilfs_ifile_info { 26 struct nilfs_mdt_info mi; 27 struct nilfs_palloc_cache palloc_cache; 28 }; 29 30 static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile) 31 { 32 return (struct nilfs_ifile_info *)NILFS_MDT(ifile); 33 } 34 35 /** 36 * nilfs_ifile_create_inode - create a new disk inode 37 * @ifile: ifile inode 38 * @out_ino: pointer to a variable to store inode number 39 * @out_bh: buffer_head contains newly allocated disk inode 40 * 41 * Return Value: On success, 0 is returned and the newly allocated inode 42 * number is stored in the place pointed by @ino, and buffer_head pointer 43 * that contains newly allocated disk inode structure is stored in the 44 * place pointed by @out_bh 45 * On error, one of the following negative error codes is returned. 46 * 47 * %-EIO - I/O error. 48 * 49 * %-ENOMEM - Insufficient amount of memory available. 50 * 51 * %-ENOSPC - No inode left. 52 */ 53 int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, 54 struct buffer_head **out_bh) 55 { 56 struct nilfs_palloc_req req; 57 int ret; 58 59 req.pr_entry_nr = NILFS_FIRST_INO(ifile->i_sb); 60 req.pr_entry_bh = NULL; 61 62 ret = nilfs_palloc_prepare_alloc_entry(ifile, &req, false); 63 if (!ret) { 64 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1, 65 &req.pr_entry_bh); 66 if (ret < 0) 67 nilfs_palloc_abort_alloc_entry(ifile, &req); 68 } 69 if (ret < 0) { 70 brelse(req.pr_entry_bh); 71 return ret; 72 } 73 nilfs_palloc_commit_alloc_entry(ifile, &req); 74 mark_buffer_dirty(req.pr_entry_bh); 75 nilfs_mdt_mark_dirty(ifile); 76 *out_ino = (ino_t)req.pr_entry_nr; 77 *out_bh = req.pr_entry_bh; 78 return 0; 79 } 80 81 /** 82 * nilfs_ifile_delete_inode - delete a disk inode 83 * @ifile: ifile inode 84 * @ino: inode number 85 * 86 * Return Value: On success, 0 is returned. On error, one of the following 87 * negative error codes is returned. 88 * 89 * %-EIO - I/O error. 90 * 91 * %-ENOMEM - Insufficient amount of memory available. 92 * 93 * %-ENOENT - The inode number @ino have not been allocated. 94 */ 95 int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino) 96 { 97 struct nilfs_palloc_req req = { 98 .pr_entry_nr = ino, .pr_entry_bh = NULL 99 }; 100 struct nilfs_inode *raw_inode; 101 void *kaddr; 102 int ret; 103 104 ret = nilfs_palloc_prepare_free_entry(ifile, &req); 105 if (!ret) { 106 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0, 107 &req.pr_entry_bh); 108 if (ret < 0) 109 nilfs_palloc_abort_free_entry(ifile, &req); 110 } 111 if (ret < 0) { 112 brelse(req.pr_entry_bh); 113 return ret; 114 } 115 116 kaddr = kmap_local_page(req.pr_entry_bh->b_page); 117 raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr, 118 req.pr_entry_bh, kaddr); 119 raw_inode->i_flags = 0; 120 kunmap_local(kaddr); 121 122 mark_buffer_dirty(req.pr_entry_bh); 123 brelse(req.pr_entry_bh); 124 125 nilfs_palloc_commit_free_entry(ifile, &req); 126 127 return 0; 128 } 129 130 int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino, 131 struct buffer_head **out_bh) 132 { 133 struct super_block *sb = ifile->i_sb; 134 int err; 135 136 if (unlikely(!NILFS_VALID_INODE(sb, ino))) { 137 nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino); 138 return -EINVAL; 139 } 140 141 err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh); 142 if (unlikely(err)) 143 nilfs_warn(sb, "error %d reading inode: ino=%lu", 144 err, (unsigned long)ino); 145 return err; 146 } 147 148 /** 149 * nilfs_ifile_count_free_inodes - calculate free inodes count 150 * @ifile: ifile inode 151 * @nmaxinodes: current maximum of available inodes count [out] 152 * @nfreeinodes: free inodes count [out] 153 */ 154 int nilfs_ifile_count_free_inodes(struct inode *ifile, 155 u64 *nmaxinodes, u64 *nfreeinodes) 156 { 157 u64 nused; 158 int err; 159 160 *nmaxinodes = 0; 161 *nfreeinodes = 0; 162 163 nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count); 164 err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes); 165 if (likely(!err)) 166 *nfreeinodes = *nmaxinodes - nused; 167 return err; 168 } 169 170 /** 171 * nilfs_ifile_read - read or get ifile inode 172 * @sb: super block instance 173 * @root: root object 174 * @cno: number of checkpoint entry to read 175 * @inode_size: size of an inode 176 * 177 * Return: 0 on success, or the following negative error code on failure. 178 * * %-EINVAL - Invalid checkpoint. 179 * * %-ENOMEM - Insufficient memory available. 180 * * %-EIO - I/O error (including metadata corruption). 181 */ 182 int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root, 183 __u64 cno, size_t inode_size) 184 { 185 struct the_nilfs *nilfs; 186 struct inode *ifile; 187 int err; 188 189 ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO); 190 if (unlikely(!ifile)) 191 return -ENOMEM; 192 if (!(ifile->i_state & I_NEW)) 193 goto out; 194 195 err = nilfs_mdt_init(ifile, NILFS_MDT_GFP, 196 sizeof(struct nilfs_ifile_info)); 197 if (err) 198 goto failed; 199 200 err = nilfs_palloc_init_blockgroup(ifile, inode_size); 201 if (err) 202 goto failed; 203 204 nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache); 205 206 nilfs = sb->s_fs_info; 207 err = nilfs_cpfile_read_checkpoint(nilfs->ns_cpfile, cno, root, ifile); 208 if (err) 209 goto failed; 210 211 unlock_new_inode(ifile); 212 out: 213 return 0; 214 failed: 215 iget_failed(ifile); 216 return err; 217 } 218
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.