summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdsuper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdsuper.c')
-rw-r--r--drivers/mtd/mtdsuper.c189
1 files changed, 0 insertions, 189 deletions
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 3f9a3b7b12c5..c3e2098372f2 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -194,195 +194,6 @@ int get_tree_mtd(struct fs_context *fc,
194EXPORT_SYMBOL_GPL(get_tree_mtd); 194EXPORT_SYMBOL_GPL(get_tree_mtd);
195 195
196/* 196/*
197 * compare superblocks to see if they're equivalent
198 * - they are if the underlying MTD device is the same
199 */
200static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
201{
202 struct mtd_info *mtd = _mtd;
203
204 if (sb->s_mtd == mtd) {
205 pr_debug("MTDSB: Match on device %d (\"%s\")\n",
206 mtd->index, mtd->name);
207 return 1;
208 }
209
210 pr_debug("MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
211 sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
212 return 0;
213}
214
215/*
216 * mark the superblock by the MTD device it is using
217 * - set the device number to be the correct MTD block device for pesuperstence
218 * of NFS exports
219 */
220static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
221{
222 struct mtd_info *mtd = _mtd;
223
224 sb->s_mtd = mtd;
225 sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
226 sb->s_bdi = bdi_get(mtd_bdi);
227
228 return 0;
229}
230
231/*
232 * get a superblock on an MTD-backed filesystem
233 */
234static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
235 const char *dev_name, void *data,
236 struct mtd_info *mtd,
237 int (*fill_super)(struct super_block *, void *, int))
238{
239 struct super_block *sb;
240 int ret;
241
242 sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, flags, mtd);
243 if (IS_ERR(sb))
244 goto out_error;
245
246 if (sb->s_root)
247 goto already_mounted;
248
249 /* fresh new superblock */
250 pr_debug("MTDSB: New superblock for device %d (\"%s\")\n",
251 mtd->index, mtd->name);
252
253 ret = fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
254 if (ret < 0) {
255 deactivate_locked_super(sb);
256 return ERR_PTR(ret);
257 }
258
259 /* go */
260 sb->s_flags |= SB_ACTIVE;
261 return dget(sb->s_root);
262
263 /* new mountpoint for an already mounted superblock */
264already_mounted:
265 pr_debug("MTDSB: Device %d (\"%s\") is already mounted\n",
266 mtd->index, mtd->name);
267 put_mtd_device(mtd);
268 return dget(sb->s_root);
269
270out_error:
271 put_mtd_device(mtd);
272 return ERR_CAST(sb);
273}
274
275/*
276 * get a superblock on an MTD-backed filesystem by MTD device number
277 */
278static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags,
279 const char *dev_name, void *data, int mtdnr,
280 int (*fill_super)(struct super_block *, void *, int))
281{
282 struct mtd_info *mtd;
283
284 mtd = get_mtd_device(NULL, mtdnr);
285 if (IS_ERR(mtd)) {
286 pr_debug("MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
287 return ERR_CAST(mtd);
288 }
289
290 return mount_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super);
291}
292
293/*
294 * set up an MTD-based superblock
295 */
296struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
297 const char *dev_name, void *data,
298 int (*fill_super)(struct super_block *, void *, int))
299{
300#ifdef CONFIG_BLOCK
301 struct block_device *bdev;
302 int ret, major;
303#endif
304 int mtdnr;
305
306 if (!dev_name)
307 return ERR_PTR(-EINVAL);
308
309 pr_debug("MTDSB: dev_name \"%s\"\n", dev_name);
310
311 /* the preferred way of mounting in future; especially when
312 * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
313 * by name, so that we don't require block device support to be present
314 * in the kernel. */
315 if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
316 if (dev_name[3] == ':') {
317 struct mtd_info *mtd;
318
319 /* mount by MTD device name */
320 pr_debug("MTDSB: mtd:%%s, name \"%s\"\n",
321 dev_name + 4);
322
323 mtd = get_mtd_device_nm(dev_name + 4);
324 if (!IS_ERR(mtd))
325 return mount_mtd_aux(
326 fs_type, flags,
327 dev_name, data, mtd,
328 fill_super);
329
330 printk(KERN_NOTICE "MTD:"
331 " MTD device with name \"%s\" not found.\n",
332 dev_name + 4);
333
334 } else if (isdigit(dev_name[3])) {
335 /* mount by MTD device number name */
336 char *endptr;
337
338 mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
339 if (!*endptr) {
340 /* It was a valid number */
341 pr_debug("MTDSB: mtd%%d, mtdnr %d\n",
342 mtdnr);
343 return mount_mtd_nr(fs_type, flags,
344 dev_name, data,
345 mtdnr, fill_super);
346 }
347 }
348 }
349
350#ifdef CONFIG_BLOCK
351 /* try the old way - the hack where we allowed users to mount
352 * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
353 */
354 bdev = lookup_bdev(dev_name);
355 if (IS_ERR(bdev)) {
356 ret = PTR_ERR(bdev);
357 pr_debug("MTDSB: lookup_bdev() returned %d\n", ret);
358 return ERR_PTR(ret);
359 }
360 pr_debug("MTDSB: lookup_bdev() returned 0\n");
361
362 ret = -EINVAL;
363
364 major = MAJOR(bdev->bd_dev);
365 mtdnr = MINOR(bdev->bd_dev);
366 bdput(bdev);
367
368 if (major != MTD_BLOCK_MAJOR)
369 goto not_an_MTD_device;
370
371 return mount_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super);
372
373not_an_MTD_device:
374#endif /* CONFIG_BLOCK */
375
376 if (!(flags & SB_SILENT))
377 printk(KERN_NOTICE
378 "MTD: Attempt to mount non-MTD device \"%s\"\n",
379 dev_name);
380 return ERR_PTR(-EINVAL);
381}
382
383EXPORT_SYMBOL_GPL(mount_mtd);
384
385/*
386 * destroy an MTD-based superblock 197 * destroy an MTD-based superblock
387 */ 198 */
388void kill_mtd_super(struct super_block *sb) 199void kill_mtd_super(struct super_block *sb)