#define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
static const struct file_operations shm_file_operations;
-static struct vm_operations_struct shm_vm_ops;
+static const struct vm_operations_struct shm_vm_ops;
#define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS])
shm_unlock(shp);
if (!is_file_hugepages(shp->shm_file))
shmem_lock(shp->shm_file, 0, shp->mlock_user);
- else
+ else if (shp->mlock_user)
user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size,
shp->mlock_user);
fput (shp->shm_file);
.get_unmapped_area = shm_get_unmapped_area,
};
-static struct vm_operations_struct shm_vm_ops = {
+static const struct vm_operations_struct shm_vm_ops = {
.open = shm_open, /* callback for a new vm-area open */
.close = shm_close, /* callback for when the vm-area is released */
.fault = shm_fault,
/* hugetlb_file_setup applies strict accounting */
if (shmflg & SHM_NORESERVE)
acctflag = VM_NORESERVE;
- file = hugetlb_file_setup(name, size, acctflag);
- shp->mlock_user = current_user();
+ file = hugetlb_file_setup(name, size, acctflag,
+ &shp->mlock_user, HUGETLB_SHMFS_INODE);
} else {
/*
* Do not allow no accounting for OVERCOMMIT_NEVER, even
error = PTR_ERR(file);
if (IS_ERR(file))
goto no_file;
- ima_shm_check(file);
id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
if (id < 0) {
return error;
no_id:
+ if (is_file_hugepages(file) && shp->mlock_user)
+ user_shm_unlock(size, shp->mlock_user);
fput(file);
no_file:
security_shm_free(shp);
in_use = shm_ids(ns).in_use;
for (total = 0, next_id = 0; total < in_use; next_id++) {
+ struct kern_ipc_perm *ipc;
struct shmid_kernel *shp;
struct inode *inode;
- shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
- if (shp == NULL)
+ ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id);
+ if (ipc == NULL)
continue;
+ shp = container_of(ipc, struct shmid_kernel, shm_perm);
inode = shp->shm_file->f_path.dentry->d_inode;
file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
if (!file)
goto out_free;
- ima_shm_check(file);
+ ima_counts_get(file);
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
{
struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma, *next;
+ struct vm_area_struct *vma;
unsigned long addr = (unsigned long)shmaddr;
- loff_t size = 0;
int retval = -EINVAL;
+#ifdef CONFIG_MMU
+ loff_t size = 0;
+ struct vm_area_struct *next;
+#endif
if (addr & ~PAGE_MASK)
return retval;