/* * get a superblock on an MTD-backed filesystem */ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct mtd_info *mtd, int (*fill_super)(struct super_block *, void *, int), struct vfsmount *mnt) { struct super_block *sb; int ret; sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, mtd); if (IS_ERR(sb)) goto out_error; if (sb->s_root) goto already_mounted; /* fresh new superblock */ DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n", mtd->index, mtd->name); sb->s_flags = flags; ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (ret < 0) { deactivate_locked_super(sb); return ret; } /* go */ sb->s_flags |= MS_ACTIVE; simple_set_mnt(mnt, sb); return 0; /* new mountpoint for an already mounted superblock */ already_mounted: DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", mtd->index, mtd->name); simple_set_mnt(mnt, sb); ret = 0; goto out_put; out_error: ret = PTR_ERR(sb); out_put: put_mtd_device(mtd); return ret; }
/* A feature which supports mount_nodev() with options */ static struct dentry *mount_nodev_with_options(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, int (*fill_super)(struct super_block *, const char *, void *, int)) { int error; struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); if (IS_ERR(s)) return ERR_CAST(s); s->s_flags = flags; error = fill_super(s, dev_name, data, flags & MS_SILENT ? 1 : 0); if (error) { deactivate_locked_super(s); return ERR_PTR(error); } s->s_flags |= MS_ACTIVE; return dget(s->s_root); }