aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdchar.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-31 16:42:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-31 16:42:57 -0400
commit8bb1f229527dee95644e0f8496980bb767c6f620 (patch)
tree511551e9772f11f855bd5b759b6d449da47e8820 /drivers/mtd/mtdchar.c
parentf22e08a79f3765fecf060b225a46931c94fb0a92 (diff)
parentc0d0259481cc6ec2a38cad810055e455de35c733 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second try at vfs part d#2 from Al Viro: "Miklos' first series (with do_lookup() rewrite split into edible chunks) + assorted bits and pieces. The 'untangling of do_lookup()' series is is a splitup of what used to be a monolithic patch from Miklos, so this series is basically "how do I convince myself that his patch is correct (or find a hole in it)". No holes found and I like the resulting cleanup, so in it went..." Changes from try 1: Fix a boot problem with selinux, and commit messages prettied up a bit. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (24 commits) vfs: fix out-of-date dentry_unhash() comment vfs: split __lookup_hash untangling do_lookup() - take __lookup_hash()-calling case out of line. untangling do_lookup() - switch to calling __lookup_hash() untangling do_lookup() - merge d_alloc_and_lookup() callers untangling do_lookup() - merge failure exits in !dentry case untangling do_lookup() - massage !dentry case towards __lookup_hash() untangling do_lookup() - get rid of need_reval in !dentry case untangling do_lookup() - eliminate a loop. untangling do_lookup() - expand the area under ->i_mutex untangling do_lookup() - isolate !dentry stuff from the rest of it. vfs: move MAY_EXEC check from __lookup_hash() vfs: don't revalidate just looked up dentry vfs: fix d_need_lookup/d_revalidate order in do_lookup ext3: move headers to fs/ext3/ migrate ext2_fs.h guts to fs/ext2/ext2.h new helper: ext2_image_size() get rid of pointless includes of ext2_fs.h ext2: No longer export ext2_fs.h to user space mtdchar: kill persistently held vfsmount ...
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r--drivers/mtd/mtdchar.c53
1 files changed, 16 insertions, 37 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 55d82321d307..94eb05b1afdf 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -39,7 +39,6 @@
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40 40
41static DEFINE_MUTEX(mtd_mutex); 41static DEFINE_MUTEX(mtd_mutex);
42static struct vfsmount *mtd_inode_mnt __read_mostly;
43 42
44/* 43/*
45 * Data structure to hold the pointer to the mtd device as well 44 * Data structure to hold the pointer to the mtd device as well
@@ -75,7 +74,9 @@ static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
75 return -EINVAL; 74 return -EINVAL;
76} 75}
77 76
78 77static int count;
78static struct vfsmount *mnt;
79static struct file_system_type mtd_inodefs_type;
79 80
80static int mtdchar_open(struct inode *inode, struct file *file) 81static int mtdchar_open(struct inode *inode, struct file *file)
81{ 82{
@@ -92,6 +93,10 @@ static int mtdchar_open(struct inode *inode, struct file *file)
92 if ((file->f_mode & FMODE_WRITE) && (minor & 1)) 93 if ((file->f_mode & FMODE_WRITE) && (minor & 1))
93 return -EACCES; 94 return -EACCES;
94 95
96 ret = simple_pin_fs(&mtd_inodefs_type, &mnt, &count);
97 if (ret)
98 return ret;
99
95 mutex_lock(&mtd_mutex); 100 mutex_lock(&mtd_mutex);
96 mtd = get_mtd_device(NULL, devnum); 101 mtd = get_mtd_device(NULL, devnum);
97 102
@@ -106,7 +111,7 @@ static int mtdchar_open(struct inode *inode, struct file *file)
106 goto out; 111 goto out;
107 } 112 }
108 113
109 mtd_ino = iget_locked(mtd_inode_mnt->mnt_sb, devnum); 114 mtd_ino = iget_locked(mnt->mnt_sb, devnum);
110 if (!mtd_ino) { 115 if (!mtd_ino) {
111 put_mtd_device(mtd); 116 put_mtd_device(mtd);
112 ret = -ENOMEM; 117 ret = -ENOMEM;
@@ -141,6 +146,7 @@ static int mtdchar_open(struct inode *inode, struct file *file)
141 146
142out: 147out:
143 mutex_unlock(&mtd_mutex); 148 mutex_unlock(&mtd_mutex);
149 simple_release_fs(&mnt, &count);
144 return ret; 150 return ret;
145} /* mtdchar_open */ 151} /* mtdchar_open */
146 152
@@ -162,6 +168,7 @@ static int mtdchar_close(struct inode *inode, struct file *file)
162 put_mtd_device(mtd); 168 put_mtd_device(mtd);
163 file->private_data = NULL; 169 file->private_data = NULL;
164 kfree(mfi); 170 kfree(mfi);
171 simple_release_fs(&mnt, &count);
165 172
166 return 0; 173 return 0;
167} /* mtdchar_close */ 174} /* mtdchar_close */
@@ -1175,10 +1182,15 @@ static const struct file_operations mtd_fops = {
1175#endif 1182#endif
1176}; 1183};
1177 1184
1185static const struct super_operations mtd_ops = {
1186 .drop_inode = generic_delete_inode,
1187 .statfs = simple_statfs,
1188};
1189
1178static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type, 1190static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type,
1179 int flags, const char *dev_name, void *data) 1191 int flags, const char *dev_name, void *data)
1180{ 1192{
1181 return mount_pseudo(fs_type, "mtd_inode:", NULL, NULL, MTD_INODE_FS_MAGIC); 1193 return mount_pseudo(fs_type, "mtd_inode:", &mtd_ops, NULL, MTD_INODE_FS_MAGIC);
1182} 1194}
1183 1195
1184static struct file_system_type mtd_inodefs_type = { 1196static struct file_system_type mtd_inodefs_type = {
@@ -1187,26 +1199,6 @@ static struct file_system_type mtd_inodefs_type = {
1187 .kill_sb = kill_anon_super, 1199 .kill_sb = kill_anon_super,
1188}; 1200};
1189 1201
1190static void mtdchar_notify_add(struct mtd_info *mtd)
1191{
1192}
1193
1194static void mtdchar_notify_remove(struct mtd_info *mtd)
1195{
1196 struct inode *mtd_ino = ilookup(mtd_inode_mnt->mnt_sb, mtd->index);
1197
1198 if (mtd_ino) {
1199 /* Destroy the inode if it exists */
1200 clear_nlink(mtd_ino);
1201 iput(mtd_ino);
1202 }
1203}
1204
1205static struct mtd_notifier mtdchar_notifier = {
1206 .add = mtdchar_notify_add,
1207 .remove = mtdchar_notify_remove,
1208};
1209
1210static int __init init_mtdchar(void) 1202static int __init init_mtdchar(void)
1211{ 1203{
1212 int ret; 1204 int ret;
@@ -1224,19 +1216,8 @@ static int __init init_mtdchar(void)
1224 pr_notice("Can't register mtd_inodefs filesystem: %d\n", ret); 1216 pr_notice("Can't register mtd_inodefs filesystem: %d\n", ret);
1225 goto err_unregister_chdev; 1217 goto err_unregister_chdev;
1226 } 1218 }
1227
1228 mtd_inode_mnt = kern_mount(&mtd_inodefs_type);
1229 if (IS_ERR(mtd_inode_mnt)) {
1230 ret = PTR_ERR(mtd_inode_mnt);
1231 pr_notice("Error mounting mtd_inodefs filesystem: %d\n", ret);
1232 goto err_unregister_filesystem;
1233 }
1234 register_mtd_user(&mtdchar_notifier);
1235
1236 return ret; 1219 return ret;
1237 1220
1238err_unregister_filesystem:
1239 unregister_filesystem(&mtd_inodefs_type);
1240err_unregister_chdev: 1221err_unregister_chdev:
1241 __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd"); 1222 __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
1242 return ret; 1223 return ret;
@@ -1244,8 +1225,6 @@ err_unregister_chdev:
1244 1225
1245static void __exit cleanup_mtdchar(void) 1226static void __exit cleanup_mtdchar(void)
1246{ 1227{
1247 unregister_mtd_user(&mtdchar_notifier);
1248 kern_unmount(mtd_inode_mnt);
1249 unregister_filesystem(&mtd_inodefs_type); 1228 unregister_filesystem(&mtd_inodefs_type);
1250 __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd"); 1229 __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
1251} 1230}