]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/shmem.c
Merge tag 's390-5.6-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux.git] / mm / shmem.c
index 165fa633299348412084a81fb546bd74f1425436..c8f7540ef048ebc5b425ed640999acf361819cd7 100644 (file)
@@ -2107,9 +2107,10 @@ unsigned long shmem_get_unmapped_area(struct file *file,
        /*
         * Our priority is to support MAP_SHARED mapped hugely;
         * and support MAP_PRIVATE mapped hugely too, until it is COWed.
-        * But if caller specified an address hint, respect that as before.
+        * But if caller specified an address hint and we allocated area there
+        * successfully, respect that as before.
         */
-       if (uaddr)
+       if (uaddr == addr)
                return addr;
 
        if (shmem_huge != SHMEM_HUGE_FORCE) {
@@ -2143,7 +2144,7 @@ unsigned long shmem_get_unmapped_area(struct file *file,
        if (inflated_len < len)
                return addr;
 
-       inflated_addr = get_area(NULL, 0, inflated_len, 0, flags);
+       inflated_addr = get_area(NULL, uaddr, inflated_len, 0, flags);
        if (IS_ERR_VALUE(inflated_addr))
                return addr;
        if (inflated_addr & ~PAGE_MASK)
@@ -3380,9 +3381,19 @@ enum shmem_param {
        Opt_uid,
 };
 
-static const struct fs_parameter_spec shmem_param_specs[] = {
+static const struct constant_table shmem_param_enums_huge[] = {
+       {"never",       SHMEM_HUGE_NEVER },
+       {"always",      SHMEM_HUGE_ALWAYS },
+       {"within_size", SHMEM_HUGE_WITHIN_SIZE },
+       {"advise",      SHMEM_HUGE_ADVISE },
+       {"deny",        SHMEM_HUGE_DENY },
+       {"force",       SHMEM_HUGE_FORCE },
+       {}
+};
+
+const struct fs_parameter_spec shmem_fs_parameters[] = {
        fsparam_u32   ("gid",           Opt_gid),
-       fsparam_enum  ("huge",          Opt_huge),
+       fsparam_enum  ("huge",          Opt_huge,  shmem_param_enums_huge),
        fsparam_u32oct("mode",          Opt_mode),
        fsparam_string("mpol",          Opt_mpol),
        fsparam_string("nr_blocks",     Opt_nr_blocks),
@@ -3392,20 +3403,6 @@ static const struct fs_parameter_spec shmem_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_enum shmem_param_enums[] = {
-       { Opt_huge,     "never",        SHMEM_HUGE_NEVER },
-       { Opt_huge,     "always",       SHMEM_HUGE_ALWAYS },
-       { Opt_huge,     "within_size",  SHMEM_HUGE_WITHIN_SIZE },
-       { Opt_huge,     "advise",       SHMEM_HUGE_ADVISE },
-       {}
-};
-
-const struct fs_parameter_description shmem_fs_parameters = {
-       .name           = "tmpfs",
-       .specs          = shmem_param_specs,
-       .enums          = shmem_param_enums,
-};
-
 static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
 {
        struct shmem_options *ctx = fc->fs_private;
@@ -3414,7 +3411,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
        char *rest;
        int opt;
 
-       opt = fs_parse(fc, &shmem_fs_parameters, param, &result);
+       opt = fs_parse(fc, shmem_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -3478,9 +3475,9 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
        return 0;
 
 unsupported_parameter:
-       return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key);
+       return invalfc(fc, "Unsupported parameter '%s'", param->key);
 bad_value:
-       return invalf(fc, "tmpfs: Bad value for '%s'", param->key);
+       return invalfc(fc, "Bad value for '%s'", param->key);
 }
 
 static int shmem_parse_options(struct fs_context *fc, void *data)
@@ -3586,7 +3583,7 @@ static int shmem_reconfigure(struct fs_context *fc)
        return 0;
 out:
        spin_unlock(&sbinfo->stat_lock);
-       return invalf(fc, "tmpfs: %s", err);
+       return invalfc(fc, "%s", err);
 }
 
 static int shmem_show_options(struct seq_file *seq, struct dentry *root)
@@ -3888,7 +3885,7 @@ static struct file_system_type shmem_fs_type = {
        .name           = "tmpfs",
        .init_fs_context = shmem_init_fs_context,
 #ifdef CONFIG_TMPFS
-       .parameters     = &shmem_fs_parameters,
+       .parameters     = shmem_fs_parameters,
 #endif
        .kill_sb        = kill_litter_super,
        .fs_flags       = FS_USERNS_MOUNT,
@@ -4034,7 +4031,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma)
 static struct file_system_type shmem_fs_type = {
        .name           = "tmpfs",
        .init_fs_context = ramfs_init_fs_context,
-       .parameters     = &ramfs_fs_parameters,
+       .parameters     = ramfs_fs_parameters,
        .kill_sb        = kill_litter_super,
        .fs_flags       = FS_USERNS_MOUNT,
 };