diff options
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/mqueue.c | 17 | ||||
| -rw-r--r-- | ipc/shm.c | 23 | ||||
| -rw-r--r-- | ipc/util.c | 30 |
3 files changed, 31 insertions, 39 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 71a3ca18c873..e5c4f609f22c 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -477,7 +477,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry) | |||
| 477 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | 477 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, |
| 478 | size_t count, loff_t *off) | 478 | size_t count, loff_t *off) |
| 479 | { | 479 | { |
| 480 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); | 480 | struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); |
| 481 | char buffer[FILENT_SIZE]; | 481 | char buffer[FILENT_SIZE]; |
| 482 | ssize_t ret; | 482 | ssize_t ret; |
| 483 | 483 | ||
| @@ -498,13 +498,13 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | |||
| 498 | if (ret <= 0) | 498 | if (ret <= 0) |
| 499 | return ret; | 499 | return ret; |
| 500 | 500 | ||
| 501 | filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; | 501 | file_inode(filp)->i_atime = file_inode(filp)->i_ctime = CURRENT_TIME; |
| 502 | return ret; | 502 | return ret; |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) | 505 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) |
| 506 | { | 506 | { |
| 507 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); | 507 | struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); |
| 508 | 508 | ||
| 509 | spin_lock(&info->lock); | 509 | spin_lock(&info->lock); |
| 510 | if (task_tgid(current) == info->notify_owner) | 510 | if (task_tgid(current) == info->notify_owner) |
| @@ -516,7 +516,7 @@ static int mqueue_flush_file(struct file *filp, fl_owner_t id) | |||
| 516 | 516 | ||
| 517 | static unsigned int mqueue_poll_file(struct file *filp, struct poll_table_struct *poll_tab) | 517 | static unsigned int mqueue_poll_file(struct file *filp, struct poll_table_struct *poll_tab) |
| 518 | { | 518 | { |
| 519 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); | 519 | struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); |
| 520 | int retval = 0; | 520 | int retval = 0; |
| 521 | 521 | ||
| 522 | poll_wait(filp, &info->wait_q, poll_tab); | 522 | poll_wait(filp, &info->wait_q, poll_tab); |
| @@ -973,7 +973,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, | |||
| 973 | goto out; | 973 | goto out; |
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | inode = f.file->f_path.dentry->d_inode; | 976 | inode = file_inode(f.file); |
| 977 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { | 977 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
| 978 | ret = -EBADF; | 978 | ret = -EBADF; |
| 979 | goto out_fput; | 979 | goto out_fput; |
| @@ -1089,7 +1089,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, | |||
| 1089 | goto out; | 1089 | goto out; |
| 1090 | } | 1090 | } |
| 1091 | 1091 | ||
| 1092 | inode = f.file->f_path.dentry->d_inode; | 1092 | inode = file_inode(f.file); |
| 1093 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { | 1093 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
| 1094 | ret = -EBADF; | 1094 | ret = -EBADF; |
| 1095 | goto out_fput; | 1095 | goto out_fput; |
| @@ -1249,7 +1249,7 @@ retry: | |||
| 1249 | goto out; | 1249 | goto out; |
| 1250 | } | 1250 | } |
| 1251 | 1251 | ||
| 1252 | inode = f.file->f_path.dentry->d_inode; | 1252 | inode = file_inode(f.file); |
| 1253 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { | 1253 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
| 1254 | ret = -EBADF; | 1254 | ret = -EBADF; |
| 1255 | goto out_fput; | 1255 | goto out_fput; |
| @@ -1323,7 +1323,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, | |||
| 1323 | goto out; | 1323 | goto out; |
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | inode = f.file->f_path.dentry->d_inode; | 1326 | inode = file_inode(f.file); |
| 1327 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { | 1327 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
| 1328 | ret = -EBADF; | 1328 | ret = -EBADF; |
| 1329 | goto out_fput; | 1329 | goto out_fput; |
| @@ -1383,6 +1383,7 @@ static struct file_system_type mqueue_fs_type = { | |||
| 1383 | .name = "mqueue", | 1383 | .name = "mqueue", |
| 1384 | .mount = mqueue_mount, | 1384 | .mount = mqueue_mount, |
| 1385 | .kill_sb = kill_litter_super, | 1385 | .kill_sb = kill_litter_super, |
| 1386 | .fs_flags = FS_USERNS_MOUNT, | ||
| 1386 | }; | 1387 | }; |
| 1387 | 1388 | ||
| 1388 | int mq_init_ns(struct ipc_namespace *ns) | 1389 | int mq_init_ns(struct ipc_namespace *ns) |
| @@ -193,7 +193,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
| 193 | if (!is_file_hugepages(shp->shm_file)) | 193 | if (!is_file_hugepages(shp->shm_file)) |
| 194 | shmem_lock(shp->shm_file, 0, shp->mlock_user); | 194 | shmem_lock(shp->shm_file, 0, shp->mlock_user); |
| 195 | else if (shp->mlock_user) | 195 | else if (shp->mlock_user) |
| 196 | user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size, | 196 | user_shm_unlock(file_inode(shp->shm_file)->i_size, |
| 197 | shp->mlock_user); | 197 | shp->mlock_user); |
| 198 | fput (shp->shm_file); | 198 | fput (shp->shm_file); |
| 199 | security_shm_free(shp); | 199 | security_shm_free(shp); |
| @@ -529,7 +529,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
| 529 | * shmid gets reported as "inode#" in /proc/pid/maps. | 529 | * shmid gets reported as "inode#" in /proc/pid/maps. |
| 530 | * proc-ps tools use this. Changing this will break them. | 530 | * proc-ps tools use this. Changing this will break them. |
| 531 | */ | 531 | */ |
| 532 | file->f_dentry->d_inode->i_ino = shp->shm_perm.id; | 532 | file_inode(file)->i_ino = shp->shm_perm.id; |
| 533 | 533 | ||
| 534 | ns->shm_tot += numpages; | 534 | ns->shm_tot += numpages; |
| 535 | error = shp->shm_perm.id; | 535 | error = shp->shm_perm.id; |
| @@ -678,7 +678,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp, | |||
| 678 | { | 678 | { |
| 679 | struct inode *inode; | 679 | struct inode *inode; |
| 680 | 680 | ||
| 681 | inode = shp->shm_file->f_path.dentry->d_inode; | 681 | inode = file_inode(shp->shm_file); |
| 682 | 682 | ||
| 683 | if (is_file_hugepages(shp->shm_file)) { | 683 | if (is_file_hugepages(shp->shm_file)) { |
| 684 | struct address_space *mapping = inode->i_mapping; | 684 | struct address_space *mapping = inode->i_mapping; |
| @@ -967,11 +967,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
| 967 | unsigned long flags; | 967 | unsigned long flags; |
| 968 | unsigned long prot; | 968 | unsigned long prot; |
| 969 | int acc_mode; | 969 | int acc_mode; |
| 970 | unsigned long user_addr; | ||
| 971 | struct ipc_namespace *ns; | 970 | struct ipc_namespace *ns; |
| 972 | struct shm_file_data *sfd; | 971 | struct shm_file_data *sfd; |
| 973 | struct path path; | 972 | struct path path; |
| 974 | fmode_t f_mode; | 973 | fmode_t f_mode; |
| 974 | unsigned long populate = 0; | ||
| 975 | 975 | ||
| 976 | err = -EINVAL; | 976 | err = -EINVAL; |
| 977 | if (shmid < 0) | 977 | if (shmid < 0) |
| @@ -1042,7 +1042,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
| 1042 | is_file_hugepages(shp->shm_file) ? | 1042 | is_file_hugepages(shp->shm_file) ? |
| 1043 | &shm_file_operations_huge : | 1043 | &shm_file_operations_huge : |
| 1044 | &shm_file_operations); | 1044 | &shm_file_operations); |
| 1045 | if (!file) | 1045 | err = PTR_ERR(file); |
| 1046 | if (IS_ERR(file)) | ||
| 1046 | goto out_free; | 1047 | goto out_free; |
| 1047 | 1048 | ||
| 1048 | file->private_data = sfd; | 1049 | file->private_data = sfd; |
| @@ -1070,13 +1071,15 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
| 1070 | goto invalid; | 1071 | goto invalid; |
| 1071 | } | 1072 | } |
| 1072 | 1073 | ||
| 1073 | user_addr = do_mmap_pgoff(file, addr, size, prot, flags, 0); | 1074 | addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); |
| 1074 | *raddr = user_addr; | 1075 | *raddr = addr; |
| 1075 | err = 0; | 1076 | err = 0; |
| 1076 | if (IS_ERR_VALUE(user_addr)) | 1077 | if (IS_ERR_VALUE(addr)) |
| 1077 | err = (long)user_addr; | 1078 | err = (long)addr; |
| 1078 | invalid: | 1079 | invalid: |
| 1079 | up_write(¤t->mm->mmap_sem); | 1080 | up_write(¤t->mm->mmap_sem); |
| 1081 | if (populate) | ||
| 1082 | mm_populate(addr, populate); | ||
| 1080 | 1083 | ||
| 1081 | out_fput: | 1084 | out_fput: |
| 1082 | fput(file); | 1085 | fput(file); |
| @@ -1173,7 +1176,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) | |||
| 1173 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { | 1176 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { |
| 1174 | 1177 | ||
| 1175 | 1178 | ||
| 1176 | size = vma->vm_file->f_path.dentry->d_inode->i_size; | 1179 | size = file_inode(vma->vm_file)->i_size; |
| 1177 | do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); | 1180 | do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); |
| 1178 | /* | 1181 | /* |
| 1179 | * We discovered the size of the shm segment, so | 1182 | * We discovered the size of the shm segment, so |
diff --git a/ipc/util.c b/ipc/util.c index 74e1d9c7a98a..464a8abd779f 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -252,7 +252,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
| 252 | { | 252 | { |
| 253 | kuid_t euid; | 253 | kuid_t euid; |
| 254 | kgid_t egid; | 254 | kgid_t egid; |
| 255 | int id, err; | 255 | int id; |
| 256 | int next_id = ids->next_id; | 256 | int next_id = ids->next_id; |
| 257 | 257 | ||
| 258 | if (size > IPCMNI) | 258 | if (size > IPCMNI) |
| @@ -261,17 +261,21 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
| 261 | if (ids->in_use >= size) | 261 | if (ids->in_use >= size) |
| 262 | return -ENOSPC; | 262 | return -ENOSPC; |
| 263 | 263 | ||
| 264 | idr_preload(GFP_KERNEL); | ||
| 265 | |||
| 264 | spin_lock_init(&new->lock); | 266 | spin_lock_init(&new->lock); |
| 265 | new->deleted = 0; | 267 | new->deleted = 0; |
| 266 | rcu_read_lock(); | 268 | rcu_read_lock(); |
| 267 | spin_lock(&new->lock); | 269 | spin_lock(&new->lock); |
| 268 | 270 | ||
| 269 | err = idr_get_new_above(&ids->ipcs_idr, new, | 271 | id = idr_alloc(&ids->ipcs_idr, new, |
| 270 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), &id); | 272 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, |
| 271 | if (err) { | 273 | GFP_NOWAIT); |
| 274 | idr_preload_end(); | ||
| 275 | if (id < 0) { | ||
| 272 | spin_unlock(&new->lock); | 276 | spin_unlock(&new->lock); |
| 273 | rcu_read_unlock(); | 277 | rcu_read_unlock(); |
| 274 | return err; | 278 | return id; |
| 275 | } | 279 | } |
| 276 | 280 | ||
| 277 | ids->in_use++; | 281 | ids->in_use++; |
| @@ -307,19 +311,10 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
| 307 | struct ipc_ops *ops, struct ipc_params *params) | 311 | struct ipc_ops *ops, struct ipc_params *params) |
| 308 | { | 312 | { |
| 309 | int err; | 313 | int err; |
| 310 | retry: | ||
| 311 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); | ||
| 312 | |||
| 313 | if (!err) | ||
| 314 | return -ENOMEM; | ||
| 315 | 314 | ||
| 316 | down_write(&ids->rw_mutex); | 315 | down_write(&ids->rw_mutex); |
| 317 | err = ops->getnew(ns, params); | 316 | err = ops->getnew(ns, params); |
| 318 | up_write(&ids->rw_mutex); | 317 | up_write(&ids->rw_mutex); |
| 319 | |||
| 320 | if (err == -EAGAIN) | ||
| 321 | goto retry; | ||
| 322 | |||
| 323 | return err; | 318 | return err; |
| 324 | } | 319 | } |
| 325 | 320 | ||
| @@ -376,8 +371,6 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
| 376 | struct kern_ipc_perm *ipcp; | 371 | struct kern_ipc_perm *ipcp; |
| 377 | int flg = params->flg; | 372 | int flg = params->flg; |
| 378 | int err; | 373 | int err; |
| 379 | retry: | ||
| 380 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); | ||
| 381 | 374 | ||
| 382 | /* | 375 | /* |
| 383 | * Take the lock as a writer since we are potentially going to add | 376 | * Take the lock as a writer since we are potentially going to add |
| @@ -389,8 +382,6 @@ retry: | |||
| 389 | /* key not used */ | 382 | /* key not used */ |
| 390 | if (!(flg & IPC_CREAT)) | 383 | if (!(flg & IPC_CREAT)) |
| 391 | err = -ENOENT; | 384 | err = -ENOENT; |
| 392 | else if (!err) | ||
| 393 | err = -ENOMEM; | ||
| 394 | else | 385 | else |
| 395 | err = ops->getnew(ns, params); | 386 | err = ops->getnew(ns, params); |
| 396 | } else { | 387 | } else { |
| @@ -413,9 +404,6 @@ retry: | |||
| 413 | } | 404 | } |
| 414 | up_write(&ids->rw_mutex); | 405 | up_write(&ids->rw_mutex); |
| 415 | 406 | ||
| 416 | if (err == -EAGAIN) | ||
| 417 | goto retry; | ||
| 418 | |||
| 419 | return err; | 407 | return err; |
| 420 | } | 408 | } |
| 421 | 409 | ||
