diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mqueue.c | 17 | ||||
-rw-r--r-- | ipc/shm.c | 11 | ||||
-rw-r--r-- | ipc/util.c | 30 |
3 files changed, 24 insertions, 34 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 71a3ca1..e5c4f60 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -477,7 +477,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry) static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, size_t count, loff_t *off) { - struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); + struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); char buffer[FILENT_SIZE]; ssize_t ret; @@ -498,13 +498,13 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, if (ret <= 0) return ret; - filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; + file_inode(filp)->i_atime = file_inode(filp)->i_ctime = CURRENT_TIME; return ret; } static int mqueue_flush_file(struct file *filp, fl_owner_t id) { - struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); + struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); spin_lock(&info->lock); if (task_tgid(current) == info->notify_owner) @@ -516,7 +516,7 @@ static int mqueue_flush_file(struct file *filp, fl_owner_t id) static unsigned int mqueue_poll_file(struct file *filp, struct poll_table_struct *poll_tab) { - struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); + struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp)); int retval = 0; 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, goto out; } - inode = f.file->f_path.dentry->d_inode; + inode = file_inode(f.file); if (unlikely(f.file->f_op != &mqueue_file_operations)) { ret = -EBADF; goto out_fput; @@ -1089,7 +1089,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, goto out; } - inode = f.file->f_path.dentry->d_inode; + inode = file_inode(f.file); if (unlikely(f.file->f_op != &mqueue_file_operations)) { ret = -EBADF; goto out_fput; @@ -1249,7 +1249,7 @@ retry: goto out; } - inode = f.file->f_path.dentry->d_inode; + inode = file_inode(f.file); if (unlikely(f.file->f_op != &mqueue_file_operations)) { ret = -EBADF; goto out_fput; @@ -1323,7 +1323,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, goto out; } - inode = f.file->f_path.dentry->d_inode; + inode = file_inode(f.file); if (unlikely(f.file->f_op != &mqueue_file_operations)) { ret = -EBADF; goto out_fput; @@ -1383,6 +1383,7 @@ static struct file_system_type mqueue_fs_type = { .name = "mqueue", .mount = mqueue_mount, .kill_sb = kill_litter_super, + .fs_flags = FS_USERNS_MOUNT, }; int mq_init_ns(struct ipc_namespace *ns) @@ -193,7 +193,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) if (!is_file_hugepages(shp->shm_file)) shmem_lock(shp->shm_file, 0, shp->mlock_user); else if (shp->mlock_user) - user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size, + user_shm_unlock(file_inode(shp->shm_file)->i_size, shp->mlock_user); fput (shp->shm_file); security_shm_free(shp); @@ -529,7 +529,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) * shmid gets reported as "inode#" in /proc/pid/maps. * proc-ps tools use this. Changing this will break them. */ - file->f_dentry->d_inode->i_ino = shp->shm_perm.id; + file_inode(file)->i_ino = shp->shm_perm.id; ns->shm_tot += numpages; error = shp->shm_perm.id; @@ -678,7 +678,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp, { struct inode *inode; - inode = shp->shm_file->f_path.dentry->d_inode; + inode = file_inode(shp->shm_file); if (is_file_hugepages(shp->shm_file)) { struct address_space *mapping = inode->i_mapping; @@ -1042,7 +1042,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, is_file_hugepages(shp->shm_file) ? &shm_file_operations_huge : &shm_file_operations); - if (!file) + err = PTR_ERR(file); + if (IS_ERR(file)) goto out_free; file->private_data = sfd; @@ -1175,7 +1176,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { - size = vma->vm_file->f_path.dentry->d_inode->i_size; + size = file_inode(vma->vm_file)->i_size; do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); /* * We discovered the size of the shm segment, so @@ -252,7 +252,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) { kuid_t euid; kgid_t egid; - int id, err; + int id; int next_id = ids->next_id; if (size > IPCMNI) @@ -261,17 +261,21 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) if (ids->in_use >= size) return -ENOSPC; + idr_preload(GFP_KERNEL); + spin_lock_init(&new->lock); new->deleted = 0; rcu_read_lock(); spin_lock(&new->lock); - err = idr_get_new_above(&ids->ipcs_idr, new, - (next_id < 0) ? 0 : ipcid_to_idx(next_id), &id); - if (err) { + id = idr_alloc(&ids->ipcs_idr, new, + (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, + GFP_NOWAIT); + idr_preload_end(); + if (id < 0) { spin_unlock(&new->lock); rcu_read_unlock(); - return err; + return id; } ids->in_use++; @@ -307,19 +311,10 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, struct ipc_ops *ops, struct ipc_params *params) { int err; -retry: - err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); - - if (!err) - return -ENOMEM; down_write(&ids->rw_mutex); err = ops->getnew(ns, params); up_write(&ids->rw_mutex); - - if (err == -EAGAIN) - goto retry; - return err; } @@ -376,8 +371,6 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, struct kern_ipc_perm *ipcp; int flg = params->flg; int err; -retry: - err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); /* * Take the lock as a writer since we are potentially going to add @@ -389,8 +382,6 @@ retry: /* key not used */ if (!(flg & IPC_CREAT)) err = -ENOENT; - else if (!err) - err = -ENOMEM; else err = ops->getnew(ns, params); } else { @@ -413,9 +404,6 @@ retry: } up_write(&ids->rw_mutex); - if (err == -EAGAIN) - goto retry; - return err; } |