get rid of BKL in fs/efs
[safe/jmp/linux-2.6] / fs / hugetlbfs / inode.c
index 7d479ce..941c842 100644 (file)
 #include <linux/pagevec.h>
 #include <linux/parser.h>
 #include <linux/mman.h>
-#include <linux/quotaops.h>
 #include <linux/slab.h>
 #include <linux/dnotify.h>
 #include <linux/statfs.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 
 #include <asm/uaccess.h>
 
@@ -108,7 +108,8 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 
        if (hugetlb_reserve_pages(inode,
                                vma->vm_pgoff >> huge_page_order(h),
-                               len >> huge_page_shift(h), vma))
+                               len >> huge_page_shift(h), vma,
+                               vma->vm_flags))
                goto out;
 
        ret = 0;
@@ -252,6 +253,7 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
        for (;;) {
                struct page *page;
                unsigned long nr, ret;
+               int ra;
 
                /* nr is the maximum number of bytes to copy from this page */
                nr = huge_page_size(h);
@@ -274,16 +276,19 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
                         */
                        ret = len < nr ? len : nr;
                        if (clear_user(buf, ret))
-                               ret = -EFAULT;
+                               ra = -EFAULT;
+                       else
+                               ra = 0;
                } else {
                        /*
                         * We have the page, copy it to user space buffer.
                         */
-                       ret = hugetlbfs_read_actor(page, offset, buf, len, nr);
+                       ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
+                       ret = ra;
                }
-               if (ret < 0) {
+               if (ra < 0) {
                        if (retval == 0)
-                               retval = ret;
+                               retval = ra;
                        if (page)
                                page_cache_release(page);
                        goto out;
@@ -308,16 +313,6 @@ out:
        return retval;
 }
 
-/*
- * Read a page. Again trivial. If it didn't already exist
- * in the page cache, it is zero-filled.
- */
-static int hugetlbfs_readpage(struct file *file, struct page * page)
-{
-       unlock_page(page);
-       return -EINVAL;
-}
-
 static int hugetlbfs_write_begin(struct file *file,
                        struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
@@ -506,7 +501,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
                inode->i_mode = mode;
                inode->i_uid = uid;
                inode->i_gid = gid;
-               inode->i_blocks = 0;
                inode->i_mapping->a_ops = &hugetlbfs_aops;
                inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@ -698,7 +692,6 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
 }
 
 static const struct address_space_operations hugetlbfs_aops = {
-       .readpage       = hugetlbfs_readpage,
        .write_begin    = hugetlbfs_write_begin,
        .write_end      = hugetlbfs_write_end,
        .set_page_dirty = hugetlbfs_set_page_dirty,
@@ -838,7 +831,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
 bad_val:
        printk(KERN_ERR "hugetlbfs: Bad value '%s' for mount option '%s'\n",
               args[0].from, p);
-       return 1;
+       return -EINVAL;
 }
 
 static int
@@ -939,14 +932,13 @@ static struct vfsmount *hugetlbfs_vfsmount;
 
 static int can_do_hugetlb_shm(void)
 {
-       return likely(capable(CAP_IPC_LOCK) ||
-                       in_group_p(sysctl_hugetlb_shm_group) ||
-                       can_do_mlock());
+       return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
 }
 
-struct file *hugetlb_file_setup(const char *name, size_t size)
+struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
 {
        int error = -ENOMEM;
+       int unlock_shm = 0;
        struct file *file;
        struct inode *inode;
        struct dentry *dentry, *root;
@@ -956,11 +948,14 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
        if (!hugetlbfs_vfsmount)
                return ERR_PTR(-ENOENT);
 
-       if (!can_do_hugetlb_shm())
-               return ERR_PTR(-EPERM);
-
-       if (!user_shm_lock(size, user))
-               return ERR_PTR(-ENOMEM);
+       if (!can_do_hugetlb_shm()) {
+               if (user_shm_lock(size, user)) {
+                       unlock_shm = 1;
+                       WARN_ONCE(1,
+                         "Using mlock ulimits for SHM_HUGETLB deprecated\n");
+               } else
+                       return ERR_PTR(-EPERM);
+       }
 
        root = hugetlbfs_vfsmount->mnt_root;
        quick_string.name = name;
@@ -978,7 +973,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
 
        error = -ENOMEM;
        if (hugetlb_reserve_pages(inode, 0,
-                       size >> huge_page_shift(hstate_inode(inode)), NULL))
+                       size >> huge_page_shift(hstate_inode(inode)), NULL,
+                       acctflag))
                goto out_inode;
 
        d_instantiate(dentry, inode);
@@ -991,6 +987,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
                        &hugetlbfs_file_operations);
        if (!file)
                goto out_dentry; /* inode is already attached */
+       ima_counts_get(file);
 
        return file;
 
@@ -999,7 +996,8 @@ out_inode:
 out_dentry:
        dput(dentry);
 out_shm_unlock:
-       user_shm_unlock(size, user);
+       if (unlock_shm)
+               user_shm_unlock(size, user);
        return ERR_PTR(error);
 }