Merge to Fedora kernel-2.6.6-1.422
[linux-2.6.git] / mm / shmem.c
index 21d58bd..ada4f73 100644 (file)
@@ -1161,17 +1161,36 @@ shmem_get_policy(struct vm_area_struct *vma, unsigned long addr)
 }
 #endif
 
-void shmem_lock(struct file *file, int lock)
+int shmem_lock(struct file *file, int lock)
 {
        struct inode *inode = file->f_dentry->d_inode;
        struct shmem_inode_info *info = SHMEM_I(inode);
+       struct mm_struct *mm = current->mm;
+       unsigned long lock_limit, locked;
+       int retval = -ENOMEM;
 
        spin_lock(&info->lock);
+       if (lock && !(info->flags & VM_LOCKED)) {
+               locked = inode->i_size >> PAGE_SHIFT;
+               locked += mm->locked_vm;
+               lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+               lock_limit >>= PAGE_SHIFT;
+               if ((locked > lock_limit) && !capable(CAP_IPC_LOCK))
+                       goto out_nomem;
+               mm->locked_vm = locked;
+       }
+       if (!lock && (info->flags & VM_LOCKED) && mm) {
+               locked = inode->i_size >> PAGE_SHIFT;
+               mm->locked_vm -= locked;
+       }
        if (lock)
                info->flags |= VM_LOCKED;
        else
                info->flags &= ~VM_LOCKED;
+       retval = 0;
+out_nomem:
        spin_unlock(&info->lock);
+       return retval;
 }
 
 static int shmem_mmap(struct file *file, struct vm_area_struct *vma)