1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/types.h>
22#include <linux/buffer_head.h>
23#include "nilfs.h"
24#include "mdt.h"
25#include "alloc.h"
26#include "ifile.h"
27
28
29
30
31
32
33struct nilfs_ifile_info {
34 struct nilfs_mdt_info mi;
35 struct nilfs_palloc_cache palloc_cache;
36};
37
38static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
39{
40 return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
41}
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
62 struct buffer_head **out_bh)
63{
64 struct nilfs_palloc_req req;
65 int ret;
66
67 req.pr_entry_nr = 0;
68
69
70
71 req.pr_entry_bh = NULL;
72
73 ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
74 if (!ret) {
75 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
76 &req.pr_entry_bh);
77 if (ret < 0)
78 nilfs_palloc_abort_alloc_entry(ifile, &req);
79 }
80 if (ret < 0) {
81 brelse(req.pr_entry_bh);
82 return ret;
83 }
84 nilfs_palloc_commit_alloc_entry(ifile, &req);
85 mark_buffer_dirty(req.pr_entry_bh);
86 nilfs_mdt_mark_dirty(ifile);
87 *out_ino = (ino_t)req.pr_entry_nr;
88 *out_bh = req.pr_entry_bh;
89 return 0;
90}
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
107{
108 struct nilfs_palloc_req req = {
109 .pr_entry_nr = ino, .pr_entry_bh = NULL
110 };
111 struct nilfs_inode *raw_inode;
112 void *kaddr;
113 int ret;
114
115 ret = nilfs_palloc_prepare_free_entry(ifile, &req);
116 if (!ret) {
117 ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
118 &req.pr_entry_bh);
119 if (ret < 0)
120 nilfs_palloc_abort_free_entry(ifile, &req);
121 }
122 if (ret < 0) {
123 brelse(req.pr_entry_bh);
124 return ret;
125 }
126
127 kaddr = kmap_atomic(req.pr_entry_bh->b_page);
128 raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
129 req.pr_entry_bh, kaddr);
130 raw_inode->i_flags = 0;
131 kunmap_atomic(kaddr);
132
133 mark_buffer_dirty(req.pr_entry_bh);
134 brelse(req.pr_entry_bh);
135
136 nilfs_palloc_commit_free_entry(ifile, &req);
137
138 return 0;
139}
140
141int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
142 struct buffer_head **out_bh)
143{
144 struct super_block *sb = ifile->i_sb;
145 int err;
146
147 if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
148 nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino);
149 return -EINVAL;
150 }
151
152 err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
153 if (unlikely(err))
154 nilfs_msg(sb, KERN_WARNING, "error %d reading inode: ino=%lu",
155 err, (unsigned long)ino);
156 return err;
157}
158
159
160
161
162
163
164
165int nilfs_ifile_count_free_inodes(struct inode *ifile,
166 u64 *nmaxinodes, u64 *nfreeinodes)
167{
168 u64 nused;
169 int err;
170
171 *nmaxinodes = 0;
172 *nfreeinodes = 0;
173
174 nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count);
175 err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes);
176 if (likely(!err))
177 *nfreeinodes = *nmaxinodes - nused;
178 return err;
179}
180
181
182
183
184
185
186
187
188
189int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
190 size_t inode_size, struct nilfs_inode *raw_inode,
191 struct inode **inodep)
192{
193 struct inode *ifile;
194 int err;
195
196 ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
197 if (unlikely(!ifile))
198 return -ENOMEM;
199 if (!(ifile->i_state & I_NEW))
200 goto out;
201
202 err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
203 sizeof(struct nilfs_ifile_info));
204 if (err)
205 goto failed;
206
207 err = nilfs_palloc_init_blockgroup(ifile, inode_size);
208 if (err)
209 goto failed;
210
211 nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
212
213 err = nilfs_read_inode_common(ifile, raw_inode);
214 if (err)
215 goto failed;
216
217 unlock_new_inode(ifile);
218 out:
219 *inodep = ifile;
220 return 0;
221 failed:
222 iget_failed(ifile);
223 return err;
224}
225