ns->shm_ctlall = SHMALL;
ns->shm_ctlmni = SHMMNI;
ns->shm_tot = 0;
- ipc_init_ids(&ns->ids[IPC_SHM_IDS]);
+ ipc_init_ids(&shm_ids(ns));
}
/*
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);
struct file * file;
char name[13];
int id;
+ int acctflag = 0;
if (size < SHMMIN || size > ns->shm_ctlmax)
return -EINVAL;
sprintf (name, "SYSV%08x", key);
if (shmflg & SHM_HUGETLB) {
- /* hugetlb_file_setup takes care of mlock user accounting */
- file = hugetlb_file_setup(name, size);
- shp->mlock_user = current_user();
+ /* hugetlb_file_setup applies strict accounting */
+ if (shmflg & SHM_NORESERVE)
+ acctflag = VM_NORESERVE;
+ file = hugetlb_file_setup(name, size, acctflag,
+ &shp->mlock_user);
} else {
- int acctflag = VM_ACCOUNT;
/*
* Do not allow no accounting for OVERCOMMIT_NEVER, even
* if it's asked for.
*/
if ((shmflg & SHM_NORESERVE) &&
sysctl_overcommit_memory != OVERCOMMIT_NEVER)
- acctflag = 0;
+ acctflag = VM_NORESERVE;
file = shmem_file_setup(name, size, acctflag);
}
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 (shp->mlock_user) /* shmflg & SHM_HUGETLB case */
+ user_shm_unlock(size, shp->mlock_user);
fput(file);
no_file:
security_shm_free(shp);
return 0;
}
-asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg)
{
struct ipc_namespace *ns;
struct ipc_ops shm_ops;
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;
struct hstate *h = hstate_file(shp->shm_file);
*rss += pages_per_huge_page(h) * mapping->nrpages;
} else {
+#ifdef CONFIG_SHMEM
struct shmem_inode_info *info = SHMEM_I(inode);
spin_lock(&info->lock);
*rss += inode->i_mapping->nrpages;
*swp += info->swapped;
spin_unlock(&info->lock);
+#else
+ *rss += inode->i_mapping->nrpages;
+#endif
}
total++;
return err;
}
-asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
struct shmid_kernel *shp;
int err, version;
if (err)
return err;
- memset(&shminfo,0,sizeof(shminfo));
+ memset(&shminfo, 0, sizeof(shminfo));
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
shminfo.shmmax = ns->shm_ctlmax;
shminfo.shmall = ns->shm_ctlall;
if (err)
return err;
- memset(&shm_info,0,sizeof(shm_info));
+ memset(&shm_info, 0, sizeof(shm_info));
down_read(&shm_ids(ns).rw_mutex);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
up_read(&shm_ids(ns).rw_mutex);
- if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
+ if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
}
struct shmid64_ds tbuf;
int result;
- if (!buf) {
- err = -EFAULT;
- goto out;
- }
-
if (cmd == SHM_STAT) {
shp = shm_lock(ns, shmid);
if (IS_ERR(shp)) {
}
result = 0;
}
- err=-EACCES;
+ err = -EACCES;
if (ipcperms (&shp->shm_perm, S_IRUGO))
goto out_unlock;
err = security_shm_shmctl(shp, cmd);
goto out;
}
- err = audit_ipc_obj(&(shp->shm_perm));
- if (err)
- goto out_unlock;
+ audit_ipc_obj(&(shp->shm_perm));
if (!capable(CAP_IPC_LOCK)) {
uid_t euid = current_euid();
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;
goto out_nattch;
}
-asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg)
+SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
{
unsigned long ret;
long err;
* detach and kill segment if marked destroyed.
* The work is done in shm_close.
*/
-asmlinkage long sys_shmdt(char __user *shmaddr)
+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;
*/
vma = find_vma(mm, addr);
+#ifdef CONFIG_MMU
while (vma) {
next = vma->vm_next;
vma = next;
}
+#else /* CONFIG_MMU */
+ /* under NOMMU conditions, the exact address to be destroyed must be
+ * given */
+ retval = -EINVAL;
+ if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
+ do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+ retval = 0;
+ }
+
+#endif
+
up_write(&mm->mmap_sem);
return retval;
}