Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[linux-2.6.git] / ipc / shm.c
index dca90489e3b0f7b9cfd189b593eeee1d3c0f197e..0b92e874fc068fb1bc34f3e5940cfb45542f29f7 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -34,8 +34,6 @@
 
 #include "util.h"
 
 
 #include "util.h"
 
-#define shm_flags      shm_perm.mode
-
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
@@ -148,7 +146,7 @@ static void shm_close (struct vm_area_struct *shmd)
        shp->shm_dtim = get_seconds();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
        shp->shm_dtim = get_seconds();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
-          shp->shm_flags & SHM_DEST)
+          shp->shm_perm.mode & SHM_DEST)
                shm_destroy (shp);
        else
                shm_unlock(shp);
                shm_destroy (shp);
        else
                shm_unlock(shp);
@@ -157,14 +155,22 @@ static void shm_close (struct vm_area_struct *shmd)
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
-       file_accessed(file);
-       vma->vm_ops = &shm_vm_ops;
-       shm_inc(file->f_dentry->d_inode->i_ino);
-       return 0;
+       int ret;
+
+       ret = shmem_mmap(file, vma);
+       if (ret == 0) {
+               vma->vm_ops = &shm_vm_ops;
+               shm_inc(file->f_dentry->d_inode->i_ino);
+       }
+
+       return ret;
 }
 
 static struct file_operations shm_file_operations = {
 }
 
 static struct file_operations shm_file_operations = {
-       .mmap   = shm_mmap
+       .mmap   = shm_mmap,
+#ifndef CONFIG_MMU
+       .get_unmapped_area = shmem_get_unmapped_area,
+#endif
 };
 
 static struct vm_operations_struct shm_vm_ops = {
 };
 
 static struct vm_operations_struct shm_vm_ops = {
@@ -197,7 +203,7 @@ static int newseg (key_t key, int shmflg, size_t size)
                return -ENOMEM;
 
        shp->shm_perm.key = key;
                return -ENOMEM;
 
        shp->shm_perm.key = key;
-       shp->shm_flags = (shmflg & S_IRWXUGO);
+       shp->shm_perm.mode = (shmflg & S_IRWXUGO);
        shp->mlock_user = NULL;
 
        shp->shm_perm.security = NULL;
        shp->mlock_user = NULL;
 
        shp->shm_perm.security = NULL;
@@ -212,8 +218,16 @@ static int newseg (key_t key, int shmflg, size_t size)
                file = hugetlb_zero_setup(size);
                shp->mlock_user = current->user;
        } else {
                file = hugetlb_zero_setup(size);
                shp->mlock_user = current->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;
                sprintf (name, "SYSV%08x", key);
                sprintf (name, "SYSV%08x", key);
-               file = shmem_file_setup(name, size, VM_ACCOUNT);
+               file = shmem_file_setup(name, size, acctflag);
        }
        error = PTR_ERR(file);
        if (IS_ERR(file))
        }
        error = PTR_ERR(file);
        if (IS_ERR(file))
@@ -233,10 +247,11 @@ static int newseg (key_t key, int shmflg, size_t size)
        shp->id = shm_buildid(id,shp->shm_perm.seq);
        shp->shm_file = file;
        file->f_dentry->d_inode->i_ino = shp->id;
        shp->id = shm_buildid(id,shp->shm_perm.seq);
        shp->shm_file = file;
        file->f_dentry->d_inode->i_ino = shp->id;
-       if (shmflg & SHM_HUGETLB)
-               set_file_hugepages(file);
-       else
+
+       /* Hugetlb ops would have already been assigned. */
+       if (!(shmflg & SHM_HUGETLB))
                file->f_op = &shm_file_operations;
                file->f_op = &shm_file_operations;
+
        shm_tot += numpages;
        shm_unlock(shp);
        return shp->id;
        shm_tot += numpages;
        shm_unlock(shp);
        return shp->id;
@@ -328,7 +343,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
 
                out->uid        = tbuf.shm_perm.uid;
                out->gid        = tbuf.shm_perm.gid;
 
                out->uid        = tbuf.shm_perm.uid;
                out->gid        = tbuf.shm_perm.gid;
-               out->mode       = tbuf.shm_flags;
+               out->mode       = tbuf.shm_perm.mode;
 
                return 0;
            }
 
                return 0;
            }
@@ -341,7 +356,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
 
                out->uid        = tbuf_old.shm_perm.uid;
                out->gid        = tbuf_old.shm_perm.gid;
 
                out->uid        = tbuf_old.shm_perm.uid;
                out->gid        = tbuf_old.shm_perm.gid;
-               out->mode       = tbuf_old.shm_flags;
+               out->mode       = tbuf_old.shm_perm.mode;
 
                return 0;
            }
 
                return 0;
            }
@@ -543,13 +558,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        if (!is_file_hugepages(shp->shm_file)) {
                                err = shmem_lock(shp->shm_file, 1, user);
                                if (!err) {
                        if (!is_file_hugepages(shp->shm_file)) {
                                err = shmem_lock(shp->shm_file, 1, user);
                                if (!err) {
-                                       shp->shm_flags |= SHM_LOCKED;
+                                       shp->shm_perm.mode |= SHM_LOCKED;
                                        shp->mlock_user = user;
                                }
                        }
                } else if (!is_file_hugepages(shp->shm_file)) {
                        shmem_lock(shp->shm_file, 0, shp->mlock_user);
                                        shp->mlock_user = user;
                                }
                        }
                } else if (!is_file_hugepages(shp->shm_file)) {
                        shmem_lock(shp->shm_file, 0, shp->mlock_user);
-                       shp->shm_flags &= ~SHM_LOCKED;
+                       shp->shm_perm.mode &= ~SHM_LOCKED;
                        shp->mlock_user = NULL;
                }
                shm_unlock(shp);
                        shp->mlock_user = NULL;
                }
                shm_unlock(shp);
@@ -588,7 +603,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                        goto out_unlock_up;
 
                if (shp->shm_nattch){
                        goto out_unlock_up;
 
                if (shp->shm_nattch){
-                       shp->shm_flags |= SHM_DEST;
+                       shp->shm_perm.mode |= SHM_DEST;
                        /* Do not find it any more */
                        shp->shm_perm.key = IPC_PRIVATE;
                        shm_unlock(shp);
                        /* Do not find it any more */
                        shp->shm_perm.key = IPC_PRIVATE;
                        shm_unlock(shp);
@@ -627,7 +642,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
                
                shp->shm_perm.uid = setbuf.uid;
                shp->shm_perm.gid = setbuf.gid;
                
                shp->shm_perm.uid = setbuf.uid;
                shp->shm_perm.gid = setbuf.gid;
-               shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO)
+               shp->shm_perm.mode = (shp->shm_perm.mode & ~S_IRWXUGO)
                        | (setbuf.mode & S_IRWXUGO);
                shp->shm_ctim = get_seconds();
                break;
                        | (setbuf.mode & S_IRWXUGO);
                shp->shm_ctim = get_seconds();
                break;
@@ -760,7 +775,7 @@ invalid:
                BUG();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
                BUG();
        shp->shm_nattch--;
        if(shp->shm_nattch == 0 &&
-          shp->shm_flags & SHM_DEST)
+          shp->shm_perm.mode & SHM_DEST)
                shm_destroy (shp);
        else
                shm_unlock(shp);
                shm_destroy (shp);
        else
                shm_unlock(shp);
@@ -885,7 +900,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
        return seq_printf(s, format,
                          shp->shm_perm.key,
                          shp->id,
        return seq_printf(s, format,
                          shp->shm_perm.key,
                          shp->id,
-                         shp->shm_flags,
+                         shp->shm_perm.mode,
                          shp->shm_segsz,
                          shp->shm_cprid,
                          shp->shm_lprid,
                          shp->shm_segsz,
                          shp->shm_cprid,
                          shp->shm_lprid,