diff options
Diffstat (limited to 'fs/logfs/dev_mtd.c')
-rw-r--r-- | fs/logfs/dev_mtd.c | 78 |
1 files changed, 40 insertions, 38 deletions
diff --git a/fs/logfs/dev_mtd.c b/fs/logfs/dev_mtd.c index 339e17e9133d..e97404d611e0 100644 --- a/fs/logfs/dev_mtd.c +++ b/fs/logfs/dev_mtd.c | |||
@@ -13,13 +13,14 @@ | |||
13 | 13 | ||
14 | #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) | 14 | #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) |
15 | 15 | ||
16 | static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf) | 16 | static int logfs_mtd_read(struct super_block *sb, loff_t ofs, size_t len, |
17 | void *buf) | ||
17 | { | 18 | { |
18 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; | 19 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; |
19 | size_t retlen; | 20 | size_t retlen; |
20 | int ret; | 21 | int ret; |
21 | 22 | ||
22 | ret = mtd->read(mtd, ofs, len, &retlen, buf); | 23 | ret = mtd_read(mtd, ofs, len, &retlen, buf); |
23 | BUG_ON(ret == -EINVAL); | 24 | BUG_ON(ret == -EINVAL); |
24 | if (ret) | 25 | if (ret) |
25 | return ret; | 26 | return ret; |
@@ -31,7 +32,8 @@ static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf) | |||
31 | return 0; | 32 | return 0; |
32 | } | 33 | } |
33 | 34 | ||
34 | static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf) | 35 | static int loffs_mtd_write(struct super_block *sb, loff_t ofs, size_t len, |
36 | void *buf) | ||
35 | { | 37 | { |
36 | struct logfs_super *super = logfs_super(sb); | 38 | struct logfs_super *super = logfs_super(sb); |
37 | struct mtd_info *mtd = super->s_mtd; | 39 | struct mtd_info *mtd = super->s_mtd; |
@@ -47,7 +49,7 @@ static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf) | |||
47 | BUG_ON(len > PAGE_CACHE_SIZE); | 49 | BUG_ON(len > PAGE_CACHE_SIZE); |
48 | page_start = ofs & PAGE_CACHE_MASK; | 50 | page_start = ofs & PAGE_CACHE_MASK; |
49 | page_end = PAGE_CACHE_ALIGN(ofs + len) - 1; | 51 | page_end = PAGE_CACHE_ALIGN(ofs + len) - 1; |
50 | ret = mtd->write(mtd, ofs, len, &retlen, buf); | 52 | ret = mtd_write(mtd, ofs, len, &retlen, buf); |
51 | if (ret || (retlen != len)) | 53 | if (ret || (retlen != len)) |
52 | return -EIO; | 54 | return -EIO; |
53 | 55 | ||
@@ -60,14 +62,15 @@ static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf) | |||
60 | * asynchronous properties. So just to prevent the first implementor of such | 62 | * asynchronous properties. So just to prevent the first implementor of such |
61 | * a thing from breaking logfs in 2350, we do the usual pointless dance to | 63 | * a thing from breaking logfs in 2350, we do the usual pointless dance to |
62 | * declare a completion variable and wait for completion before returning | 64 | * declare a completion variable and wait for completion before returning |
63 | * from mtd_erase(). What an exercise in futility! | 65 | * from logfs_mtd_erase(). What an exercise in futility! |
64 | */ | 66 | */ |
65 | static void logfs_erase_callback(struct erase_info *ei) | 67 | static void logfs_erase_callback(struct erase_info *ei) |
66 | { | 68 | { |
67 | complete((struct completion *)ei->priv); | 69 | complete((struct completion *)ei->priv); |
68 | } | 70 | } |
69 | 71 | ||
70 | static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len) | 72 | static int logfs_mtd_erase_mapping(struct super_block *sb, loff_t ofs, |
73 | size_t len) | ||
71 | { | 74 | { |
72 | struct logfs_super *super = logfs_super(sb); | 75 | struct logfs_super *super = logfs_super(sb); |
73 | struct address_space *mapping = super->s_mapping_inode->i_mapping; | 76 | struct address_space *mapping = super->s_mapping_inode->i_mapping; |
@@ -84,7 +87,7 @@ static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len) | |||
84 | return 0; | 87 | return 0; |
85 | } | 88 | } |
86 | 89 | ||
87 | static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len, | 90 | static int logfs_mtd_erase(struct super_block *sb, loff_t ofs, size_t len, |
88 | int ensure_write) | 91 | int ensure_write) |
89 | { | 92 | { |
90 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; | 93 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; |
@@ -102,30 +105,29 @@ static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len, | |||
102 | ei.len = len; | 105 | ei.len = len; |
103 | ei.callback = logfs_erase_callback; | 106 | ei.callback = logfs_erase_callback; |
104 | ei.priv = (long)&complete; | 107 | ei.priv = (long)&complete; |
105 | ret = mtd->erase(mtd, &ei); | 108 | ret = mtd_erase(mtd, &ei); |
106 | if (ret) | 109 | if (ret) |
107 | return -EIO; | 110 | return -EIO; |
108 | 111 | ||
109 | wait_for_completion(&complete); | 112 | wait_for_completion(&complete); |
110 | if (ei.state != MTD_ERASE_DONE) | 113 | if (ei.state != MTD_ERASE_DONE) |
111 | return -EIO; | 114 | return -EIO; |
112 | return mtd_erase_mapping(sb, ofs, len); | 115 | return logfs_mtd_erase_mapping(sb, ofs, len); |
113 | } | 116 | } |
114 | 117 | ||
115 | static void mtd_sync(struct super_block *sb) | 118 | static void logfs_mtd_sync(struct super_block *sb) |
116 | { | 119 | { |
117 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; | 120 | struct mtd_info *mtd = logfs_super(sb)->s_mtd; |
118 | 121 | ||
119 | if (mtd->sync) | 122 | mtd_sync(mtd); |
120 | mtd->sync(mtd); | ||
121 | } | 123 | } |
122 | 124 | ||
123 | static int mtd_readpage(void *_sb, struct page *page) | 125 | static int logfs_mtd_readpage(void *_sb, struct page *page) |
124 | { | 126 | { |
125 | struct super_block *sb = _sb; | 127 | struct super_block *sb = _sb; |
126 | int err; | 128 | int err; |
127 | 129 | ||
128 | err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE, | 130 | err = logfs_mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE, |
129 | page_address(page)); | 131 | page_address(page)); |
130 | if (err == -EUCLEAN || err == -EBADMSG) { | 132 | if (err == -EUCLEAN || err == -EBADMSG) { |
131 | /* -EBADMSG happens regularly on power failures */ | 133 | /* -EBADMSG happens regularly on power failures */ |
@@ -143,18 +145,18 @@ static int mtd_readpage(void *_sb, struct page *page) | |||
143 | return err; | 145 | return err; |
144 | } | 146 | } |
145 | 147 | ||
146 | static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs) | 148 | static struct page *logfs_mtd_find_first_sb(struct super_block *sb, u64 *ofs) |
147 | { | 149 | { |
148 | struct logfs_super *super = logfs_super(sb); | 150 | struct logfs_super *super = logfs_super(sb); |
149 | struct address_space *mapping = super->s_mapping_inode->i_mapping; | 151 | struct address_space *mapping = super->s_mapping_inode->i_mapping; |
150 | filler_t *filler = mtd_readpage; | 152 | filler_t *filler = logfs_mtd_readpage; |
151 | struct mtd_info *mtd = super->s_mtd; | 153 | struct mtd_info *mtd = super->s_mtd; |
152 | 154 | ||
153 | if (!mtd->block_isbad) | 155 | if (!mtd_can_have_bb(mtd)) |
154 | return NULL; | 156 | return NULL; |
155 | 157 | ||
156 | *ofs = 0; | 158 | *ofs = 0; |
157 | while (mtd->block_isbad(mtd, *ofs)) { | 159 | while (mtd_block_isbad(mtd, *ofs)) { |
158 | *ofs += mtd->erasesize; | 160 | *ofs += mtd->erasesize; |
159 | if (*ofs >= mtd->size) | 161 | if (*ofs >= mtd->size) |
160 | return NULL; | 162 | return NULL; |
@@ -163,18 +165,18 @@ static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs) | |||
163 | return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); | 165 | return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); |
164 | } | 166 | } |
165 | 167 | ||
166 | static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs) | 168 | static struct page *logfs_mtd_find_last_sb(struct super_block *sb, u64 *ofs) |
167 | { | 169 | { |
168 | struct logfs_super *super = logfs_super(sb); | 170 | struct logfs_super *super = logfs_super(sb); |
169 | struct address_space *mapping = super->s_mapping_inode->i_mapping; | 171 | struct address_space *mapping = super->s_mapping_inode->i_mapping; |
170 | filler_t *filler = mtd_readpage; | 172 | filler_t *filler = logfs_mtd_readpage; |
171 | struct mtd_info *mtd = super->s_mtd; | 173 | struct mtd_info *mtd = super->s_mtd; |
172 | 174 | ||
173 | if (!mtd->block_isbad) | 175 | if (!mtd_can_have_bb(mtd)) |
174 | return NULL; | 176 | return NULL; |
175 | 177 | ||
176 | *ofs = mtd->size - mtd->erasesize; | 178 | *ofs = mtd->size - mtd->erasesize; |
177 | while (mtd->block_isbad(mtd, *ofs)) { | 179 | while (mtd_block_isbad(mtd, *ofs)) { |
178 | *ofs -= mtd->erasesize; | 180 | *ofs -= mtd->erasesize; |
179 | if (*ofs <= 0) | 181 | if (*ofs <= 0) |
180 | return NULL; | 182 | return NULL; |
@@ -184,7 +186,7 @@ static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs) | |||
184 | return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); | 186 | return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb); |
185 | } | 187 | } |
186 | 188 | ||
187 | static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, | 189 | static int __logfs_mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, |
188 | size_t nr_pages) | 190 | size_t nr_pages) |
189 | { | 191 | { |
190 | struct logfs_super *super = logfs_super(sb); | 192 | struct logfs_super *super = logfs_super(sb); |
@@ -196,8 +198,8 @@ static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, | |||
196 | page = find_lock_page(mapping, index + i); | 198 | page = find_lock_page(mapping, index + i); |
197 | BUG_ON(!page); | 199 | BUG_ON(!page); |
198 | 200 | ||
199 | err = mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE, | 201 | err = loffs_mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE, |
200 | page_address(page)); | 202 | page_address(page)); |
201 | unlock_page(page); | 203 | unlock_page(page); |
202 | page_cache_release(page); | 204 | page_cache_release(page); |
203 | if (err) | 205 | if (err) |
@@ -206,7 +208,7 @@ static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, | |||
206 | return 0; | 208 | return 0; |
207 | } | 209 | } |
208 | 210 | ||
209 | static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len) | 211 | static void logfs_mtd_writeseg(struct super_block *sb, u64 ofs, size_t len) |
210 | { | 212 | { |
211 | struct logfs_super *super = logfs_super(sb); | 213 | struct logfs_super *super = logfs_super(sb); |
212 | int head; | 214 | int head; |
@@ -227,15 +229,15 @@ static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len) | |||
227 | len += head; | 229 | len += head; |
228 | } | 230 | } |
229 | len = PAGE_ALIGN(len); | 231 | len = PAGE_ALIGN(len); |
230 | __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT); | 232 | __logfs_mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT); |
231 | } | 233 | } |
232 | 234 | ||
233 | static void mtd_put_device(struct logfs_super *s) | 235 | static void logfs_mtd_put_device(struct logfs_super *s) |
234 | { | 236 | { |
235 | put_mtd_device(s->s_mtd); | 237 | put_mtd_device(s->s_mtd); |
236 | } | 238 | } |
237 | 239 | ||
238 | static int mtd_can_write_buf(struct super_block *sb, u64 ofs) | 240 | static int logfs_mtd_can_write_buf(struct super_block *sb, u64 ofs) |
239 | { | 241 | { |
240 | struct logfs_super *super = logfs_super(sb); | 242 | struct logfs_super *super = logfs_super(sb); |
241 | void *buf; | 243 | void *buf; |
@@ -244,7 +246,7 @@ static int mtd_can_write_buf(struct super_block *sb, u64 ofs) | |||
244 | buf = kmalloc(super->s_writesize, GFP_KERNEL); | 246 | buf = kmalloc(super->s_writesize, GFP_KERNEL); |
245 | if (!buf) | 247 | if (!buf) |
246 | return -ENOMEM; | 248 | return -ENOMEM; |
247 | err = mtd_read(sb, ofs, super->s_writesize, buf); | 249 | err = logfs_mtd_read(sb, ofs, super->s_writesize, buf); |
248 | if (err) | 250 | if (err) |
249 | goto out; | 251 | goto out; |
250 | if (memchr_inv(buf, 0xff, super->s_writesize)) | 252 | if (memchr_inv(buf, 0xff, super->s_writesize)) |
@@ -255,14 +257,14 @@ out: | |||
255 | } | 257 | } |
256 | 258 | ||
257 | static const struct logfs_device_ops mtd_devops = { | 259 | static const struct logfs_device_ops mtd_devops = { |
258 | .find_first_sb = mtd_find_first_sb, | 260 | .find_first_sb = logfs_mtd_find_first_sb, |
259 | .find_last_sb = mtd_find_last_sb, | 261 | .find_last_sb = logfs_mtd_find_last_sb, |
260 | .readpage = mtd_readpage, | 262 | .readpage = logfs_mtd_readpage, |
261 | .writeseg = mtd_writeseg, | 263 | .writeseg = logfs_mtd_writeseg, |
262 | .erase = mtd_erase, | 264 | .erase = logfs_mtd_erase, |
263 | .can_write_buf = mtd_can_write_buf, | 265 | .can_write_buf = logfs_mtd_can_write_buf, |
264 | .sync = mtd_sync, | 266 | .sync = logfs_mtd_sync, |
265 | .put_device = mtd_put_device, | 267 | .put_device = logfs_mtd_put_device, |
266 | }; | 268 | }; |
267 | 269 | ||
268 | int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) | 270 | int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) |