diff options
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r-- | ipc/mqueue.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c60e519e2917..14fb6d67e6a3 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -116,6 +116,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, | |||
116 | 116 | ||
117 | inode = new_inode(sb); | 117 | inode = new_inode(sb); |
118 | if (inode) { | 118 | if (inode) { |
119 | inode->i_ino = get_next_ino(); | ||
119 | inode->i_mode = mode; | 120 | inode->i_mode = mode; |
120 | inode->i_uid = current_fsuid(); | 121 | inode->i_uid = current_fsuid(); |
121 | inode->i_gid = current_fsgid(); | 122 | inode->i_gid = current_fsgid(); |
@@ -210,13 +211,13 @@ out: | |||
210 | return error; | 211 | return error; |
211 | } | 212 | } |
212 | 213 | ||
213 | static int mqueue_get_sb(struct file_system_type *fs_type, | 214 | static struct dentry *mqueue_mount(struct file_system_type *fs_type, |
214 | int flags, const char *dev_name, | 215 | int flags, const char *dev_name, |
215 | void *data, struct vfsmount *mnt) | 216 | void *data) |
216 | { | 217 | { |
217 | if (!(flags & MS_KERNMOUNT)) | 218 | if (!(flags & MS_KERNMOUNT)) |
218 | data = current->nsproxy->ipc_ns; | 219 | data = current->nsproxy->ipc_ns; |
219 | return get_sb_ns(fs_type, flags, data, mqueue_fill_super, mnt); | 220 | return mount_ns(fs_type, flags, data, mqueue_fill_super); |
220 | } | 221 | } |
221 | 222 | ||
222 | static void init_once(void *foo) | 223 | static void init_once(void *foo) |
@@ -236,11 +237,18 @@ static struct inode *mqueue_alloc_inode(struct super_block *sb) | |||
236 | return &ei->vfs_inode; | 237 | return &ei->vfs_inode; |
237 | } | 238 | } |
238 | 239 | ||
239 | static void mqueue_destroy_inode(struct inode *inode) | 240 | static void mqueue_i_callback(struct rcu_head *head) |
240 | { | 241 | { |
242 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
243 | INIT_LIST_HEAD(&inode->i_dentry); | ||
241 | kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode)); | 244 | kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode)); |
242 | } | 245 | } |
243 | 246 | ||
247 | static void mqueue_destroy_inode(struct inode *inode) | ||
248 | { | ||
249 | call_rcu(&inode->i_rcu, mqueue_i_callback); | ||
250 | } | ||
251 | |||
244 | static void mqueue_evict_inode(struct inode *inode) | 252 | static void mqueue_evict_inode(struct inode *inode) |
245 | { | 253 | { |
246 | struct mqueue_inode_info *info; | 254 | struct mqueue_inode_info *info; |
@@ -769,7 +777,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) | |||
769 | 777 | ||
770 | inode = dentry->d_inode; | 778 | inode = dentry->d_inode; |
771 | if (inode) | 779 | if (inode) |
772 | atomic_inc(&inode->i_count); | 780 | ihold(inode); |
773 | err = mnt_want_write(ipc_ns->mq_mnt); | 781 | err = mnt_want_write(ipc_ns->mq_mnt); |
774 | if (err) | 782 | if (err) |
775 | goto out_err; | 783 | goto out_err; |
@@ -1219,6 +1227,7 @@ static const struct file_operations mqueue_file_operations = { | |||
1219 | .flush = mqueue_flush_file, | 1227 | .flush = mqueue_flush_file, |
1220 | .poll = mqueue_poll_file, | 1228 | .poll = mqueue_poll_file, |
1221 | .read = mqueue_read_file, | 1229 | .read = mqueue_read_file, |
1230 | .llseek = default_llseek, | ||
1222 | }; | 1231 | }; |
1223 | 1232 | ||
1224 | static const struct super_operations mqueue_super_ops = { | 1233 | static const struct super_operations mqueue_super_ops = { |
@@ -1230,7 +1239,7 @@ static const struct super_operations mqueue_super_ops = { | |||
1230 | 1239 | ||
1231 | static struct file_system_type mqueue_fs_type = { | 1240 | static struct file_system_type mqueue_fs_type = { |
1232 | .name = "mqueue", | 1241 | .name = "mqueue", |
1233 | .get_sb = mqueue_get_sb, | 1242 | .mount = mqueue_mount, |
1234 | .kill_sb = kill_litter_super, | 1243 | .kill_sb = kill_litter_super, |
1235 | }; | 1244 | }; |
1236 | 1245 | ||