diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-04-06 22:01:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 11:31:14 -0400 |
commit | 43bfb45ed4feace26157778889be55e4046b7a4b (patch) | |
tree | 248958c79a8ed0ff5057c8aeffb1ebd39a6abbcf | |
parent | a17564f58b11476c011d623fa1f268602a81c27c (diff) |
nilfs2: inode map file
This adds a meta data file which stores on-disk inodes in its data blocks.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Yoshiji Amagai <amagai.yoshiji@lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/nilfs2/ifile.c | 150 | ||||
-rw-r--r-- | fs/nilfs2/ifile.h | 53 |
2 files changed, 203 insertions, 0 deletions
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c new file mode 100644 index 000000000000..de86401f209f --- /dev/null +++ b/fs/nilfs2/ifile.c | |||
@@ -0,0 +1,150 @@ | |||
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 | * nilfs_ifile_create_inode - create a new disk inode | ||
34 | * @ifile: ifile inode | ||
35 | * @out_ino: pointer to a variable to store inode number | ||
36 | * @out_bh: buffer_head contains newly allocated disk inode | ||
37 | * | ||
38 | * Return Value: On success, 0 is returned and the newly allocated inode | ||
39 | * number is stored in the place pointed by @ino, and buffer_head pointer | ||
40 | * that contains newly allocated disk inode structure is stored in the | ||
41 | * place pointed by @out_bh | ||
42 | * On error, one of the following negative error codes is returned. | ||
43 | * | ||
44 | * %-EIO - I/O error. | ||
45 | * | ||
46 | * %-ENOMEM - Insufficient amount of memory available. | ||
47 | * | ||
48 | * %-ENOSPC - No inode left. | ||
49 | */ | ||
50 | int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, | ||
51 | struct buffer_head **out_bh) | ||
52 | { | ||
53 | struct nilfs_palloc_req req; | ||
54 | int ret; | ||
55 | |||
56 | req.pr_entry_nr = 0; /* 0 says find free inode from beginning of | ||
57 | a group. dull code!! */ | ||
58 | req.pr_entry_bh = NULL; | ||
59 | |||
60 | ret = nilfs_palloc_prepare_alloc_entry(ifile, &req); | ||
61 | if (!ret) { | ||
62 | ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1, | ||
63 | &req.pr_entry_bh); | ||
64 | if (ret < 0) | ||
65 | nilfs_palloc_abort_alloc_entry(ifile, &req); | ||
66 | } | ||
67 | if (ret < 0) { | ||
68 | brelse(req.pr_entry_bh); | ||
69 | return ret; | ||
70 | } | ||
71 | nilfs_palloc_commit_alloc_entry(ifile, &req); | ||
72 | nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh); | ||
73 | nilfs_mdt_mark_dirty(ifile); | ||
74 | *out_ino = (ino_t)req.pr_entry_nr; | ||
75 | *out_bh = req.pr_entry_bh; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * nilfs_ifile_delete_inode - delete a disk inode | ||
81 | * @ifile: ifile inode | ||
82 | * @ino: inode number | ||
83 | * | ||
84 | * Return Value: On success, 0 is returned. On error, one of the following | ||
85 | * negative error codes is returned. | ||
86 | * | ||
87 | * %-EIO - I/O error. | ||
88 | * | ||
89 | * %-ENOMEM - Insufficient amount of memory available. | ||
90 | * | ||
91 | * %-ENOENT - The inode number @ino have not been allocated. | ||
92 | */ | ||
93 | int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino) | ||
94 | { | ||
95 | struct nilfs_palloc_req req = { | ||
96 | .pr_entry_nr = ino, .pr_entry_bh = NULL | ||
97 | }; | ||
98 | struct nilfs_inode *raw_inode; | ||
99 | void *kaddr; | ||
100 | int ret; | ||
101 | |||
102 | ret = nilfs_palloc_prepare_free_entry(ifile, &req); | ||
103 | if (!ret) { | ||
104 | ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0, | ||
105 | &req.pr_entry_bh); | ||
106 | if (ret < 0) | ||
107 | nilfs_palloc_abort_free_entry(ifile, &req); | ||
108 | } | ||
109 | if (ret < 0) { | ||
110 | brelse(req.pr_entry_bh); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | kaddr = kmap_atomic(req.pr_entry_bh->b_page, KM_USER0); | ||
115 | raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr, | ||
116 | req.pr_entry_bh, kaddr); | ||
117 | raw_inode->i_flags = 0; | ||
118 | kunmap_atomic(kaddr, KM_USER0); | ||
119 | |||
120 | nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh); | ||
121 | brelse(req.pr_entry_bh); | ||
122 | |||
123 | nilfs_palloc_commit_free_entry(ifile, &req); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino, | ||
129 | struct buffer_head **out_bh) | ||
130 | { | ||
131 | struct super_block *sb = ifile->i_sb; | ||
132 | int err; | ||
133 | |||
134 | if (unlikely(!NILFS_VALID_INODE(sb, ino))) { | ||
135 | nilfs_error(sb, __func__, "bad inode number: %lu", | ||
136 | (unsigned long) ino); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh); | ||
141 | if (unlikely(err)) { | ||
142 | if (err == -EINVAL) | ||
143 | nilfs_error(sb, __func__, "ifile is broken"); | ||
144 | else | ||
145 | nilfs_warning(sb, __func__, | ||
146 | "unable to read inode: %lu", | ||
147 | (unsigned long) ino); | ||
148 | } | ||
149 | return err; | ||
150 | } | ||
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h new file mode 100644 index 000000000000..5d30a35679b5 --- /dev/null +++ b/fs/nilfs2/ifile.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * ifile.h - 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 | #ifndef _NILFS_IFILE_H | ||
26 | #define _NILFS_IFILE_H | ||
27 | |||
28 | #include <linux/fs.h> | ||
29 | #include <linux/buffer_head.h> | ||
30 | #include <linux/nilfs2_fs.h> | ||
31 | #include "mdt.h" | ||
32 | #include "alloc.h" | ||
33 | |||
34 | #define NILFS_IFILE_GFP NILFS_MDT_GFP | ||
35 | |||
36 | static inline struct nilfs_inode * | ||
37 | nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh) | ||
38 | { | ||
39 | void *kaddr = kmap(ibh->b_page); | ||
40 | return nilfs_palloc_block_get_entry(ifile, ino, ibh, kaddr); | ||
41 | } | ||
42 | |||
43 | static inline void nilfs_ifile_unmap_inode(struct inode *ifile, ino_t ino, | ||
44 | struct buffer_head *ibh) | ||
45 | { | ||
46 | kunmap(ibh->b_page); | ||
47 | } | ||
48 | |||
49 | int nilfs_ifile_create_inode(struct inode *, ino_t *, struct buffer_head **); | ||
50 | int nilfs_ifile_delete_inode(struct inode *, ino_t); | ||
51 | int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **); | ||
52 | |||
53 | #endif /* _NILFS_IFILE_H */ | ||