aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/shm.c')
-rw-r--r--ipc/shm.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 464694e0aa4a..1a314c89f93c 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -39,7 +39,6 @@
39#include <linux/nsproxy.h> 39#include <linux/nsproxy.h>
40#include <linux/mount.h> 40#include <linux/mount.h>
41#include <linux/ipc_namespace.h> 41#include <linux/ipc_namespace.h>
42#include <linux/ima.h>
43 42
44#include <asm/uaccess.h> 43#include <asm/uaccess.h>
45 44
@@ -101,6 +100,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
101void shm_exit_ns(struct ipc_namespace *ns) 100void shm_exit_ns(struct ipc_namespace *ns)
102{ 101{
103 free_ipcs(ns, &shm_ids(ns), do_shm_rmid); 102 free_ipcs(ns, &shm_ids(ns), do_shm_rmid);
103 idr_destroy(&ns->ids[IPC_SHM_IDS].ipcs_idr);
104} 104}
105#endif 105#endif
106 106
@@ -290,28 +290,31 @@ static unsigned long shm_get_unmapped_area(struct file *file,
290 unsigned long flags) 290 unsigned long flags)
291{ 291{
292 struct shm_file_data *sfd = shm_file_data(file); 292 struct shm_file_data *sfd = shm_file_data(file);
293 return get_unmapped_area(sfd->file, addr, len, pgoff, flags); 293 return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
294} 294 pgoff, flags);
295
296int is_file_shm_hugepages(struct file *file)
297{
298 int ret = 0;
299
300 if (file->f_op == &shm_file_operations) {
301 struct shm_file_data *sfd;
302 sfd = shm_file_data(file);
303 ret = is_file_hugepages(sfd->file);
304 }
305 return ret;
306} 295}
307 296
308static const struct file_operations shm_file_operations = { 297static const struct file_operations shm_file_operations = {
309 .mmap = shm_mmap, 298 .mmap = shm_mmap,
310 .fsync = shm_fsync, 299 .fsync = shm_fsync,
311 .release = shm_release, 300 .release = shm_release,
301#ifndef CONFIG_MMU
302 .get_unmapped_area = shm_get_unmapped_area,
303#endif
304};
305
306static const struct file_operations shm_file_operations_huge = {
307 .mmap = shm_mmap,
308 .fsync = shm_fsync,
309 .release = shm_release,
312 .get_unmapped_area = shm_get_unmapped_area, 310 .get_unmapped_area = shm_get_unmapped_area,
313}; 311};
314 312
313int is_file_shm_hugepages(struct file *file)
314{
315 return file->f_op == &shm_file_operations_huge;
316}
317
315static const struct vm_operations_struct shm_vm_ops = { 318static const struct vm_operations_struct shm_vm_ops = {
316 .open = shm_open, /* callback for a new vm-area open */ 319 .open = shm_open, /* callback for a new vm-area open */
317 .close = shm_close, /* callback for when the vm-area is released */ 320 .close = shm_close, /* callback for when the vm-area is released */
@@ -761,8 +764,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
761 if (euid != shp->shm_perm.uid && 764 if (euid != shp->shm_perm.uid &&
762 euid != shp->shm_perm.cuid) 765 euid != shp->shm_perm.cuid)
763 goto out_unlock; 766 goto out_unlock;
764 if (cmd == SHM_LOCK && 767 if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
765 !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
766 goto out_unlock; 768 goto out_unlock;
767 } 769 }
768 770
@@ -878,8 +880,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
878 if (err) 880 if (err)
879 goto out_unlock; 881 goto out_unlock;
880 882
881 path.dentry = dget(shp->shm_file->f_path.dentry); 883 path = shp->shm_file->f_path;
882 path.mnt = shp->shm_file->f_path.mnt; 884 path_get(&path);
883 shp->shm_nattch++; 885 shp->shm_nattch++;
884 size = i_size_read(path.dentry->d_inode); 886 size = i_size_read(path.dentry->d_inode);
885 shm_unlock(shp); 887 shm_unlock(shp);
@@ -889,10 +891,12 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
889 if (!sfd) 891 if (!sfd)
890 goto out_put_dentry; 892 goto out_put_dentry;
891 893
892 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); 894 file = alloc_file(&path, f_mode,
895 is_file_hugepages(shp->shm_file) ?
896 &shm_file_operations_huge :
897 &shm_file_operations);
893 if (!file) 898 if (!file)
894 goto out_free; 899 goto out_free;
895 ima_counts_get(file);
896 900
897 file->private_data = sfd; 901 file->private_data = sfd;
898 file->f_mapping = shp->shm_file->f_mapping; 902 file->f_mapping = shp->shm_file->f_mapping;
@@ -947,7 +951,7 @@ out_unlock:
947out_free: 951out_free:
948 kfree(sfd); 952 kfree(sfd);
949out_put_dentry: 953out_put_dentry:
950 dput(path.dentry); 954 path_put(&path);
951 goto out_nattch; 955 goto out_nattch;
952} 956}
953 957