0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/types.h>
0013 #include <linux/buffer_head.h>
0014 #include "nilfs.h"
0015 #include "mdt.h"
0016 #include "alloc.h"
0017 #include "ifile.h"
0018
0019
0020
0021
0022
0023
0024 struct nilfs_ifile_info {
0025 struct nilfs_mdt_info mi;
0026 struct nilfs_palloc_cache palloc_cache;
0027 };
0028
0029 static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
0030 {
0031 return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
0032 }
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
0053 struct buffer_head **out_bh)
0054 {
0055 struct nilfs_palloc_req req;
0056 int ret;
0057
0058 req.pr_entry_nr = 0;
0059
0060
0061
0062 req.pr_entry_bh = NULL;
0063
0064 ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
0065 if (!ret) {
0066 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
0067 &req.pr_entry_bh);
0068 if (ret < 0)
0069 nilfs_palloc_abort_alloc_entry(ifile, &req);
0070 }
0071 if (ret < 0) {
0072 brelse(req.pr_entry_bh);
0073 return ret;
0074 }
0075 nilfs_palloc_commit_alloc_entry(ifile, &req);
0076 mark_buffer_dirty(req.pr_entry_bh);
0077 nilfs_mdt_mark_dirty(ifile);
0078 *out_ino = (ino_t)req.pr_entry_nr;
0079 *out_bh = req.pr_entry_bh;
0080 return 0;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
0098 {
0099 struct nilfs_palloc_req req = {
0100 .pr_entry_nr = ino, .pr_entry_bh = NULL
0101 };
0102 struct nilfs_inode *raw_inode;
0103 void *kaddr;
0104 int ret;
0105
0106 ret = nilfs_palloc_prepare_free_entry(ifile, &req);
0107 if (!ret) {
0108 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
0109 &req.pr_entry_bh);
0110 if (ret < 0)
0111 nilfs_palloc_abort_free_entry(ifile, &req);
0112 }
0113 if (ret < 0) {
0114 brelse(req.pr_entry_bh);
0115 return ret;
0116 }
0117
0118 kaddr = kmap_atomic(req.pr_entry_bh->b_page);
0119 raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
0120 req.pr_entry_bh, kaddr);
0121 raw_inode->i_flags = 0;
0122 kunmap_atomic(kaddr);
0123
0124 mark_buffer_dirty(req.pr_entry_bh);
0125 brelse(req.pr_entry_bh);
0126
0127 nilfs_palloc_commit_free_entry(ifile, &req);
0128
0129 return 0;
0130 }
0131
0132 int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
0133 struct buffer_head **out_bh)
0134 {
0135 struct super_block *sb = ifile->i_sb;
0136 int err;
0137
0138 if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
0139 nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino);
0140 return -EINVAL;
0141 }
0142
0143 err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
0144 if (unlikely(err))
0145 nilfs_warn(sb, "error %d reading inode: ino=%lu",
0146 err, (unsigned long)ino);
0147 return err;
0148 }
0149
0150
0151
0152
0153
0154
0155
0156 int nilfs_ifile_count_free_inodes(struct inode *ifile,
0157 u64 *nmaxinodes, u64 *nfreeinodes)
0158 {
0159 u64 nused;
0160 int err;
0161
0162 *nmaxinodes = 0;
0163 *nfreeinodes = 0;
0164
0165 nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count);
0166 err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes);
0167 if (likely(!err))
0168 *nfreeinodes = *nmaxinodes - nused;
0169 return err;
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
0181 size_t inode_size, struct nilfs_inode *raw_inode,
0182 struct inode **inodep)
0183 {
0184 struct inode *ifile;
0185 int err;
0186
0187 ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
0188 if (unlikely(!ifile))
0189 return -ENOMEM;
0190 if (!(ifile->i_state & I_NEW))
0191 goto out;
0192
0193 err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
0194 sizeof(struct nilfs_ifile_info));
0195 if (err)
0196 goto failed;
0197
0198 err = nilfs_palloc_init_blockgroup(ifile, inode_size);
0199 if (err)
0200 goto failed;
0201
0202 nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
0203
0204 err = nilfs_read_inode_common(ifile, raw_inode);
0205 if (err)
0206 goto failed;
0207
0208 unlock_new_inode(ifile);
0209 out:
0210 *inodep = ifile;
0211 return 0;
0212 failed:
0213 iget_failed(ifile);
0214 return err;
0215 }