]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/util.c
fs/ncpfs/dir.c: remove unnecessary new_valid_dev() check
[karo-tx-linux.git] / mm / util.c
index 68ff8a5361e79a30233fe9ecc4b26b09e614e1b8..55012d786a3545bc415d30b4774bf9b62dbf27ac 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <linux/export.h>
+#include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/security.h>
@@ -99,6 +100,35 @@ char *kstrndup(const char *s, size_t max, gfp_t gfp)
 }
 EXPORT_SYMBOL(kstrndup);
 
+/**
+ * kstrimdup - Trim and copy a %NUL terminated string.
+ * @s: the string to trim and duplicate
+ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ *
+ * Returns an address, which the caller must kfree, containing
+ * a duplicate of the passed string with leading and/or trailing
+ * whitespace (as defined by isspace) removed.
+ */
+char *kstrimdup(const char *s, gfp_t gfp)
+{
+       char *buf;
+       char *begin = skip_spaces(s);
+       size_t len = strlen(begin);
+
+       while (len && isspace(begin[len - 1]))
+               len--;
+
+       buf = kmalloc_track_caller(len + 1, gfp);
+       if (!buf)
+               return NULL;
+
+       memcpy(buf, begin, len);
+       buf[len] = '\0';
+
+       return buf;
+}
+EXPORT_SYMBOL(kstrimdup);
+
 /**
  * kmemdup - duplicate region of memory
  *
@@ -309,7 +339,7 @@ unsigned long vm_mmap(struct file *file, unsigned long addr,
 {
        if (unlikely(offset + PAGE_ALIGN(len) < offset))
                return -EINVAL;
-       if (unlikely(offset & ~PAGE_MASK))
+       if (unlikely(offset_in_page(offset)))
                return -EINVAL;
 
        return vm_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
@@ -355,7 +385,9 @@ struct anon_vma *page_anon_vma(struct page *page)
 
 struct address_space *page_mapping(struct page *page)
 {
-       unsigned long mapping;
+       struct address_space *mapping;
+
+       page = compound_head(page);
 
        /* This happens if someone calls flush_dcache_page on slab page */
        if (unlikely(PageSlab(page)))
@@ -368,10 +400,10 @@ struct address_space *page_mapping(struct page *page)
                return swap_address_space(entry);
        }
 
-       mapping = (unsigned long)page->mapping;
-       if (mapping & PAGE_MAPPING_FLAGS)
+       mapping = page->mapping;
+       if ((unsigned long)mapping & PAGE_MAPPING_FLAGS)
                return NULL;
-       return page->mapping;
+       return mapping;
 }
 
 int overcommit_ratio_handler(struct ctl_table *table, int write,