diff options
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r-- | ipc/mqueue.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index b3b69fd51330..96fb36cd9874 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -207,7 +207,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type, | |||
207 | return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); | 207 | return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); |
208 | } | 208 | } |
209 | 209 | ||
210 | static void init_once(struct kmem_cache *cachep, void *foo) | 210 | static void init_once(void *foo) |
211 | { | 211 | { |
212 | struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; | 212 | struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; |
213 | 213 | ||
@@ -314,15 +314,11 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry) | |||
314 | * through std routines) | 314 | * through std routines) |
315 | */ | 315 | */ |
316 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | 316 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, |
317 | size_t count, loff_t * off) | 317 | size_t count, loff_t *off) |
318 | { | 318 | { |
319 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); | 319 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); |
320 | char buffer[FILENT_SIZE]; | 320 | char buffer[FILENT_SIZE]; |
321 | size_t slen; | 321 | ssize_t ret; |
322 | loff_t o; | ||
323 | |||
324 | if (!count) | ||
325 | return 0; | ||
326 | 322 | ||
327 | spin_lock(&info->lock); | 323 | spin_lock(&info->lock); |
328 | snprintf(buffer, sizeof(buffer), | 324 | snprintf(buffer, sizeof(buffer), |
@@ -335,21 +331,14 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | |||
335 | pid_vnr(info->notify_owner)); | 331 | pid_vnr(info->notify_owner)); |
336 | spin_unlock(&info->lock); | 332 | spin_unlock(&info->lock); |
337 | buffer[sizeof(buffer)-1] = '\0'; | 333 | buffer[sizeof(buffer)-1] = '\0'; |
338 | slen = strlen(buffer)+1; | ||
339 | |||
340 | o = *off; | ||
341 | if (o > slen) | ||
342 | return 0; | ||
343 | |||
344 | if (o + count > slen) | ||
345 | count = slen - o; | ||
346 | 334 | ||
347 | if (copy_to_user(u_data, buffer + o, count)) | 335 | ret = simple_read_from_buffer(u_data, count, off, buffer, |
348 | return -EFAULT; | 336 | strlen(buffer)); |
337 | if (ret <= 0) | ||
338 | return ret; | ||
349 | 339 | ||
350 | *off = o + count; | ||
351 | filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; | 340 | filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; |
352 | return count; | 341 | return ret; |
353 | } | 342 | } |
354 | 343 | ||
355 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) | 344 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) |
@@ -649,7 +638,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | |||
649 | return ERR_PTR(-EINVAL); | 638 | return ERR_PTR(-EINVAL); |
650 | } | 639 | } |
651 | 640 | ||
652 | if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) { | 641 | if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { |
653 | dput(dentry); | 642 | dput(dentry); |
654 | mntput(mqueue_mnt); | 643 | mntput(mqueue_mnt); |
655 | return ERR_PTR(-EACCES); | 644 | return ERR_PTR(-EACCES); |
@@ -1054,7 +1043,7 @@ retry: | |||
1054 | } | 1043 | } |
1055 | 1044 | ||
1056 | timeo = MAX_SCHEDULE_TIMEOUT; | 1045 | timeo = MAX_SCHEDULE_TIMEOUT; |
1057 | ret = netlink_attachskb(sock, nc, 0, &timeo, NULL); | 1046 | ret = netlink_attachskb(sock, nc, &timeo, NULL); |
1058 | if (ret == 1) | 1047 | if (ret == 1) |
1059 | goto retry; | 1048 | goto retry; |
1060 | if (ret) { | 1049 | if (ret) { |