static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif
-static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
+static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
{
ns->ids[IPC_SHM_IDS] = ids;
ns->shm_ctlmax = SHMMAX;
shm_destroy(ns, shp);
}
-#ifdef CONFIG_IPC_NS
int shm_init_ns(struct ipc_namespace *ns)
{
struct ipc_ids *ids;
kfree(ns->ids[IPC_SHM_IDS]);
ns->ids[IPC_SHM_IDS] = NULL;
}
-#endif
void __init shm_init (void)
{
mutex_unlock(&shm_ids(ns).mutex);
}
-struct page *shm_nopage(struct vm_area_struct *vma, unsigned long address,
- int *type)
+static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct file *file = vma->vm_file;
struct shm_file_data *sfd = shm_file_data(file);
- return sfd->vm_ops->nopage(vma, address, type);
+ return sfd->vm_ops->fault(vma, vmf);
}
#ifdef CONFIG_NUMA
if (sfd->vm_ops->get_policy)
pol = sfd->vm_ops->get_policy(vma, addr);
- else
+ else if (vma->vm_policy)
pol = vma->vm_policy;
+ else
+ pol = current->mempolicy;
return pol;
}
#endif
if (ret != 0)
return ret;
sfd->vm_ops = vma->vm_ops;
+ BUG_ON(!sfd->vm_ops->fault);
vma->vm_ops = &shm_vm_ops;
shm_open(vma);
return 0;
}
-#ifndef CONFIG_MMU
+static int shm_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ int (*fsync) (struct file *, struct dentry *, int datasync);
+ struct shm_file_data *sfd = shm_file_data(file);
+ int ret = -EINVAL;
+
+ fsync = sfd->file->f_op->fsync;
+ if (fsync)
+ ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync);
+ return ret;
+}
+
static unsigned long shm_get_unmapped_area(struct file *file,
unsigned long addr, unsigned long len, unsigned long pgoff,
unsigned long flags)
{
struct shm_file_data *sfd = shm_file_data(file);
- return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, pgoff,
- flags);
+ return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
+}
+
+int is_file_shm_hugepages(struct file *file)
+{
+ int ret = 0;
+
+ if (file->f_op == &shm_file_operations) {
+ struct shm_file_data *sfd;
+ sfd = shm_file_data(file);
+ ret = is_file_hugepages(sfd->file);
+ }
+ return ret;
}
-#else
-#define shm_get_unmapped_area NULL
-#endif
static const struct file_operations shm_file_operations = {
.mmap = shm_mmap,
+ .fsync = shm_fsync,
.release = shm_release,
.get_unmapped_area = shm_get_unmapped_area,
};
static 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 */
- .nopage = shm_nopage,
+ .fault = shm_fault,
#if defined(CONFIG_NUMA)
.set_policy = shm_set_policy,
.get_policy = shm_get_policy,
return error;
}
+ sprintf (name, "SYSV%08x", key);
if (shmflg & SHM_HUGETLB) {
- /* hugetlb_zero_setup takes care of mlock user accounting */
- file = hugetlb_zero_setup(size);
+ /* hugetlb_file_setup takes care of mlock user accounting */
+ file = hugetlb_file_setup(name, size);
shp->mlock_user = current->user;
} else {
int acctflag = VM_ACCOUNT;
if ((shmflg & SHM_NORESERVE) &&
sysctl_overcommit_memory != OVERCOMMIT_NEVER)
acctflag = 0;
- sprintf (name, "SYSV%08x", key);
file = shmem_file_setup(name, size, acctflag);
}
error = PTR_ERR(file);
shp->shm_nattch = 0;
shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
shp->shm_file = file;
+ /*
+ * 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->id;
ns->shm_tot += numpages;
shm_unlock(shp);