Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 01:11:47 +0000 (17:11 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 01:11:47 +0000 (17:11 -0800)
Pull misc vfs updates from Al Viro:
 "All kinds of stuff.  That probably should've been 5 or 6 separate
  branches, but by the time I'd realized how large and mixed that bag
  had become it had been too close to -final to play with rebasing.

  Some fs/namei.c cleanups there, memdup_user_nul() introduction and
  switching open-coded instances, burying long-dead code, whack-a-mole
  of various kinds, several new helpers for ->llseek(), assorted
  cleanups and fixes from various people, etc.

  One piece probably deserves special mention - Neil's
  lookup_one_len_unlocked().  Similar to lookup_one_len(), but gets
  called without ->i_mutex and tries to avoid ever taking it.  That, of
  course, means that it's not useful for any directory modifications,
  but things like getting inode attributes in nfds readdirplus are fine
  with that.  I really should've asked for moratorium on lookup-related
  changes this cycle, but since I hadn't done that early enough...  I
  *am* asking for that for the coming cycle, though - I'm going to try
  and get conversion of i_mutex to rwsem with ->lookup() done under lock
  taken shared.

  There will be a patch closer to the end of the window, along the lines
  of the one Linus had posted last May - mechanical conversion of
  ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/
  inode_is_locked()/inode_lock_nested().  To quote Linus back then:

    -----
    |    This is an automated patch using
    |
    |        sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/'
    |        sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/'
    |        sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[     ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/'
    |        sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/'
    |        sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/'
    |
    |    with a very few manual fixups
    -----

  I'm going to send that once the ->i_mutex-affecting stuff in -next
  gets mostly merged (or when Linus says he's about to stop taking
  merges)"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
  nfsd: don't hold i_mutex over userspace upcalls
  fs:affs:Replace time_t with time64_t
  fs/9p: use fscache mutex rather than spinlock
  proc: add a reschedule point in proc_readfd_common()
  logfs: constify logfs_block_ops structures
  fcntl: allow to set O_DIRECT flag on pipe
  fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE
  fs: xattr: Use kvfree()
  [s390] page_to_phys() always returns a multiple of PAGE_SIZE
  nbd: use ->compat_ioctl()
  fs: use block_device name vsprintf helper
  lib/vsprintf: add %*pg format specifier
  fs: use gendisk->disk_name where possible
  poll: plug an unused argument to do_poll
  amdkfd: don't open-code memdup_user()
  cdrom: don't open-code memdup_user()
  rsxx: don't open-code memdup_user()
  mtip32xx: don't open-code memdup_user()
  [um] mconsole: don't open-code memdup_user_nul()
  [um] hostaudio: don't open-code memdup_user()
  ...

125 files changed:
Documentation/printk-formats.txt
arch/blackfin/include/asm/uaccess.h
arch/m68k/include/asm/uaccess_no.h
arch/mips/lasat/picvue_proc.c
arch/mn10300/include/asm/uaccess.h
arch/powerpc/include/asm/uaccess.h
arch/powerpc/kernel/nvram_64.c
arch/s390/pci/pci_dma.c
arch/sparc/include/asm/uaccess_32.h
arch/sparc/include/asm/uaccess_64.h
arch/sparc/kernel/mdesc.c
arch/um/drivers/hostaudio_kern.c
arch/um/drivers/mconsole_kern.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/msr.c
arch/xtensa/platforms/iss/simdisk.c
drivers/block/cciss.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/nbd.c
drivers/block/rsxx/core.c
drivers/cdrom/cdrom.c
drivers/char/generic_nvram.c
drivers/char/mbcs.c
drivers/char/nvram.c
drivers/char/nwflash.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/vga/vgaarb.c
drivers/md/bcache/util.c
drivers/md/dm-bufio.c
drivers/md/dm-io.c
drivers/mtd/maps/pcmciamtd.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/ti/wlcore/debugfs.c
drivers/s390/char/vmcp.c
drivers/s390/char/vmur.c
drivers/s390/char/zcore.c
drivers/sbus/char/openprom.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/staging/lustre/lustre/llite/namei.c
drivers/staging/lustre/lustre/llite/symlink.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/host/uhci-debug.c
drivers/usb/misc/sisusbvga/sisusb.c
fs/9p/cache.c
fs/9p/v9fs.h
fs/9p/vfs_inode.c
fs/adfs/adfs.h
fs/adfs/dir.c
fs/adfs/dir_f.c
fs/adfs/dir_fplus.c
fs/affs/affs.h
fs/affs/amigaffs.c
fs/affs/super.c
fs/afs/proc.c
fs/bad_inode.c
fs/block_dev.c
fs/btrfs/super.c
fs/buffer.c
fs/cachefiles/daemon.c
fs/compat.c
fs/compat_ioctl.c
fs/coredump.c
fs/dcache.c
fs/dlm/user.c
fs/ecryptfs/inode.c
fs/exec.c
fs/ext2/xattr.c
fs/ext4/page-io.c
fs/ext4/xattr.c
fs/f2fs/debug.c
fs/f2fs/f2fs.h
fs/fcntl.c
fs/file.c
fs/gfs2/ops_fstype.c
fs/hfs/mdb.c
fs/hpfs/map.c
fs/internal.h
fs/jbd2/transaction.c
fs/jfs/jfs_logmgr.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/minix/itree_v1.c
fs/minix/itree_v2.c
fs/namei.c
fs/namespace.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
fs/nilfs2/super.c
fs/open.c
fs/proc/base.c
fs/proc/fd.c
fs/proc_namespace.c
fs/read_write.c
fs/reiserfs/journal.c
fs/reiserfs/prints.c
fs/reiserfs/procfs.c
fs/select.c
fs/splice.c
fs/squashfs/super.c
fs/super.c
fs/xattr.c
fs/xfs/xfs_buf.c
include/linux/fs.h
include/linux/namei.h
include/linux/string.h
kernel/sysctl.c
kernel/trace/blktrace.c
kernel/trace/trace_events.c
kernel/trace/trace_events_trigger.c
kernel/user_namespace.c
lib/dynamic_debug.c
lib/vsprintf.c
mm/util.c
net/9p/trans_virtio.c
net/rxrpc/ar-key.c
security/integrity/iint.c
security/selinux/selinuxfs.c
security/smack/smackfs.c
security/tomoyo/securityfs_if.c

index b784c270105f40e8320cd388cb9a8ef1e2d463f4..6389551bbad6a7971b89e53451428d3b77b4e8d0 100644 (file)
@@ -250,6 +250,12 @@ dentry names:
 
        Passed by reference.
 
+block_device names:
+
+       %pg     sda, sda1 or loop0p1
+
+       For printing name of block_device pointers.
+
 struct va_format:
 
        %pV
index 90612a7f2cf32f0872af2651b608cd56eb0fff26..12f5d6851bbcb3e28c7ba5421a849df3cabbf4fd 100644 (file)
@@ -168,12 +168,6 @@ static inline int bad_user_access_length(void)
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-#define copy_to_user_ret(to, from, n, retval) ({ if (copy_to_user(to, from, n))\
-                                                return retval; })
-
-#define copy_from_user_ret(to, from, n, retval) ({ if (copy_from_user(to, from, n))\
-                                                   return retval; })
-
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
index 68bbe9b312f149e5286068a90bbe59310176747b..1bdf15263754711c63a8007eaf4580c10f3a7741 100644 (file)
@@ -135,10 +135,6 @@ extern int __get_user_bad(void);
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
-
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
-
 /*
  * Copy a null terminated string from userspace.
  */
index 2bcd8391bc93a0e9b0505c9e862038ecfcbb11d8..b420958806678a3b24b7b5b4c8d7dd4d393a7214 100644 (file)
@@ -22,7 +22,6 @@
 static DEFINE_MUTEX(pvc_mutex);
 static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
 static int pvc_linedata[PVC_NLINES];
-static struct proc_dir_entry *pvc_display_dir;
 static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
 #define DISPLAY_DIR_NAME "display"
 static int scroll_dir, scroll_interval;
@@ -169,22 +168,17 @@ void pvc_proc_timerfunc(unsigned long data)
 
 static void pvc_proc_cleanup(void)
 {
-       int i;
-       for (i = 0; i < PVC_NLINES; i++)
-               remove_proc_entry(pvc_linename[i], pvc_display_dir);
-       remove_proc_entry("scroll", pvc_display_dir);
-       remove_proc_entry(DISPLAY_DIR_NAME, NULL);
-
+       remove_proc_subtree(DISPLAY_DIR_NAME, NULL);
        del_timer_sync(&timer);
 }
 
 static int __init pvc_proc_init(void)
 {
-       struct proc_dir_entry *proc_entry;
+       struct proc_dir_entry *dir, *proc_entry;
        int i;
 
-       pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
-       if (pvc_display_dir == NULL)
+       dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
+       if (dir == NULL)
                goto error;
 
        for (i = 0; i < PVC_NLINES; i++) {
@@ -192,12 +186,12 @@ static int __init pvc_proc_init(void)
                pvc_linedata[i] = i;
        }
        for (i = 0; i < PVC_NLINES; i++) {
-               proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir,
+               proc_entry = proc_create_data(pvc_linename[i], 0644, dir,
                                        &pvc_line_proc_fops, &pvc_linedata[i]);
                if (proc_entry == NULL)
                        goto error;
        }
-       proc_entry = proc_create("scroll", 0644, pvc_display_dir,
+       proc_entry = proc_create("scroll", 0644, dir,
                                 &pvc_scroll_proc_fops);
        if (proc_entry == NULL)
                goto error;
index 537278746a1534cead71e487aea7f13533e60b97..20f7bf6de384d06d5beebaeb216d2e6d4f675350 100644 (file)
@@ -110,21 +110,6 @@ extern int fixup_exception(struct pt_regs *regs);
 #define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
 #define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
 
-/*
- * The "xxx_ret" versions return constant specified in third argument, if
- * something bad happens. These macros can be optimized for the
- * case of just returning from the function xxx_ret is used.
- */
-
-#define put_user_ret(x, ptr, ret) \
-       ({ if (put_user((x), (ptr)))    return (ret); })
-#define get_user_ret(x, ptr, ret) \
-       ({ if (get_user((x), (ptr)))    return (ret); })
-#define __put_user_ret(x, ptr, ret) \
-       ({ if (__put_user((x), (ptr)))  return (ret); })
-#define __get_user_ret(x, ptr, ret) \
-       ({ if (__get_user((x), (ptr)))  return (ret); })
-
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
index 2a8ebae0936beb0f6b3ec46eafaf979f0d8ddedd..b7c20f0b8fbeebe03a1c57a4c62f86c0c42e962d 100644 (file)
@@ -274,21 +274,6 @@ do {                                                               \
        __gu_err;                                               \
 })
 
-#ifndef __powerpc64__
-#define __get_user64_nocheck(x, ptr, size)                     \
-({                                                             \
-       long __gu_err;                                          \
-       long long __gu_val;                                     \
-       __typeof__(*(ptr)) __user *__gu_addr = (ptr);   \
-       __chk_user_ptr(ptr);                                    \
-       if (!is_kernel_addr((unsigned long)__gu_addr))          \
-               might_fault();                                  \
-       __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
-       (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
-       __gu_err;                                               \
-})
-#endif /* __powerpc64__ */
-
 #define __get_user_check(x, ptr, size)                                 \
 ({                                                                     \
        long __gu_err = -EFAULT;                                        \
index 32e26526f7e4e0fc5d22adda109bb075a044ae70..0cab9e8c37948685b8128bd156a15b1ef40e6936 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/kmsg_dump.h>
+#include <linux/pagemap.h>
 #include <linux/pstore.h>
 #include <linux/zlib.h>
 #include <asm/uaccess.h>
@@ -733,24 +734,10 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
 
 static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-       int size;
-
        if (ppc_md.nvram_size == NULL)
                return -ENODEV;
-       size = ppc_md.nvram_size();
-
-       switch (origin) {
-       case 1:
-               offset += file->f_pos;
-               break;
-       case 2:
-               offset += size;
-               break;
-       }
-       if (offset < 0)
-               return -EINVAL;
-       file->f_pos = offset;
-       return file->f_pos;
+       return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
+                                       ppc_md.nvram_size());
 }
 
 
index d348f2c09a1eede659378cf4ae2686df008e4bd8..32da0a6ecec26b625463bcfc9207987784ac1322 100644 (file)
@@ -366,8 +366,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
        pa = page_to_phys(page);
        memset((void *) pa, 0, size);
 
-       map = s390_dma_map_pages(dev, page, pa % PAGE_SIZE,
-                                size, DMA_BIDIRECTIONAL, NULL);
+       map = s390_dma_map_pages(dev, page, 0, size, DMA_BIDIRECTIONAL, NULL);
        if (dma_mapping_error(dev, map)) {
                free_pages(pa, get_order(size));
                return NULL;
index 64ee103dc29da142305d93d26fd44cf4a62ae699..57aca2792d29f89203735f892ceab4b73340bd69 100644 (file)
@@ -205,31 +205,6 @@ int __put_user_bad(void);
        __gu_ret; \
 })
 
-#define __get_user_check_ret(x, addr, size, type, retval) ({ \
-       register unsigned long __gu_val __asm__ ("l1"); \
-       if (__access_ok(addr, size)) { \
-               switch (size) { \
-               case 1: \
-                       __get_user_asm_ret(__gu_val, ub, addr, retval); \
-                       break; \
-               case 2: \
-                       __get_user_asm_ret(__gu_val, uh, addr, retval); \
-                       break; \
-               case 4: \
-                       __get_user_asm_ret(__gu_val, , addr, retval); \
-                       break; \
-               case 8: \
-                       __get_user_asm_ret(__gu_val, d, addr, retval); \
-                       break; \
-               default: \
-                       if (__get_user_bad()) \
-                               return retval; \
-               } \
-               x = (__force type) __gu_val; \
-       } else \
-               return retval; \
-})
-
 #define __get_user_nocheck(x, addr, size, type) ({                     \
        register int __gu_ret;                                          \
        register unsigned long __gu_val;                                \
@@ -247,20 +222,6 @@ int __put_user_bad(void);
        __gu_ret;                                                       \
 })
 
-#define __get_user_nocheck_ret(x, addr, size, type, retval) ({         \
-       register unsigned long __gu_val __asm__ ("l1");                 \
-       switch (size) {                                                 \
-       case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break;  \
-       case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break;  \
-       case 4: __get_user_asm_ret(__gu_val, , addr, retval);  break;   \
-       case 8: __get_user_asm_ret(__gu_val, d, addr, retval); break;   \
-       default:                                                        \
-               if (__get_user_bad())                                   \
-                       return retval;                                  \
-       }                                                               \
-       x = (__force type) __gu_val;                                    \
-})
-
 #define __get_user_asm(x, size, addr, ret)                             \
 __asm__ __volatile__(                                                  \
                "/* Get user asm, inline. */\n"                         \
@@ -281,32 +242,6 @@ __asm__ __volatile__(                                                      \
               : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)),             \
                 "i" (-EFAULT))
 
-#define __get_user_asm_ret(x, size, addr, retval)                      \
-if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
-       __asm__ __volatile__(                                           \
-                       "/* Get user asm ret, inline. */\n"             \
-               "1:\t"  "ld"#size " %1, %0\n\n\t"                       \
-                       ".section __ex_table,#alloc\n\t"                \
-                       ".align 4\n\t"                                  \
-                       ".word  1b,__ret_efault\n\n\t"                  \
-                       ".previous\n\t"                                 \
-                      : "=&r" (x) : "m" (*__m(addr)));                 \
-else                                                                   \
-       __asm__ __volatile__(                                           \
-                       "/* Get user asm ret, inline. */\n"             \
-               "1:\t"  "ld"#size " %1, %0\n\n\t"                       \
-                       ".section .fixup,#alloc,#execinstr\n\t"         \
-                       ".align 4\n"                                    \
-               "3:\n\t"                                                \
-                       "ret\n\t"                                       \
-                       " restore %%g0, %2, %%o0\n\n\t"                 \
-                       ".previous\n\t"                                 \
-                       ".section __ex_table,#alloc\n\t"                \
-                       ".align 4\n\t"                                  \
-                       ".word  1b, 3b\n\n\t"                           \
-                       ".previous\n\t"                                 \
-                      : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
-
 int __get_user_bad(void);
 
 unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
index ea6e9a20f3ffb5a80156b1766ac2112c3c0d2bdc..e9a51d64974ddff102017ee8f86be01f7a41361a 100644 (file)
@@ -179,20 +179,6 @@ int __put_user_bad(void);
         __gu_ret;                                                           \
 })
 
-#define __get_user_nocheck_ret(data, addr, size, type, retval) ({      \
-       register unsigned long __gu_val __asm__ ("l1");                 \
-       switch (size) {                                                 \
-       case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break;  \
-       case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break;  \
-       case 4: __get_user_asm_ret(__gu_val, uw, addr, retval); break;  \
-       case 8: __get_user_asm_ret(__gu_val, x, addr, retval); break;   \
-       default:                                                        \
-               if (__get_user_bad())                                   \
-                       return retval;                                  \
-       }                                                               \
-       data = (__force type) __gu_val;                                 \
-})
-
 #define __get_user_asm(x, size, addr, ret)                             \
 __asm__ __volatile__(                                                  \
                "/* Get user asm, inline. */\n"                         \
@@ -214,32 +200,6 @@ __asm__ __volatile__(                                                      \
               : "=r" (ret), "=r" (x) : "r" (__m(addr)),                \
                 "i" (-EFAULT))
 
-#define __get_user_asm_ret(x, size, addr, retval)                      \
-if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
-       __asm__ __volatile__(                                           \
-               "/* Get user asm ret, inline. */\n"                     \
-       "1:\t"  "ld"#size "a [%1] %%asi, %0\n\n\t"                      \
-               ".section __ex_table,\"a\"\n\t"                         \
-               ".align 4\n\t"                                          \
-               ".word  1b,__ret_efault\n\n\t"                          \
-               ".previous\n\t"                                         \
-              : "=r" (x) : "r" (__m(addr)));                           \
-else                                                                   \
-       __asm__ __volatile__(                                           \
-               "/* Get user asm ret, inline. */\n"                     \
-       "1:\t"  "ld"#size "a [%1] %%asi, %0\n\n\t"                      \
-               ".section .fixup,#alloc,#execinstr\n\t"                 \
-               ".align 4\n"                                            \
-       "3:\n\t"                                                        \
-               "ret\n\t"                                               \
-               " restore %%g0, %2, %%o0\n\n\t"                         \
-               ".previous\n\t"                                         \
-               ".section __ex_table,\"a\"\n\t"                         \
-               ".align 4\n\t"                                          \
-               ".word  1b, 3b\n\n\t"                                   \
-               ".previous\n\t"                                         \
-              : "=r" (x) : "r" (__m(addr)), "i" (retval))
-
 int __get_user_bad(void);
 
 unsigned long __must_check ___copy_from_user(void *to,
index 6f80936e0eea4d0dab82966b8f69cd7e6127b1dd..11228861d9b4716dde53881c4b2184538dec6197 100644 (file)
@@ -1033,25 +1033,9 @@ static ssize_t mdesc_read(struct file *file, char __user *buf,
 
 static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
 {
-       struct mdesc_handle *hp;
-
-       switch (whence) {
-       case SEEK_CUR:
-               offset += file->f_pos;
-               break;
-       case SEEK_SET:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       hp = file->private_data;
-       if (offset > hp->handle_size)
-               return -EINVAL;
-       else
-               file->f_pos = offset;
+       struct mdesc_handle *hp = file->private_data;
 
-       return offset;
+       return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
 }
 
 /* mdesc_close() - /dev/mdesc is being closed, release the reference to
index f6b911cc3923a1958f9c393a94799a879c4aa8d9..3a4b58730f5fbcf45e8a586b2005e3b4b9688eda 100644 (file)
@@ -105,13 +105,9 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
        printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count);
 #endif
 
-       kbuf = kmalloc(count, GFP_KERNEL);
-       if (kbuf == NULL)
-               return -ENOMEM;
-
-       err = -EFAULT;
-       if (copy_from_user(kbuf, buffer, count))
-               goto out;
+       kbuf = memdup_user(buffer, count);
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        err = os_write_file(state->fd, kbuf, count);
        if (err < 0)
index 29880c9b324ed33601c8af02340a4765d9d75b3b..b821b13d343a7bb37e1c260aa59ab5387cba195d 100644 (file)
@@ -748,19 +748,11 @@ static ssize_t mconsole_proc_write(struct file *file,
 {
        char *buf;
 
-       buf = kmalloc(count + 1, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(buf, buffer, count)) {
-               count = -EFAULT;
-               goto out;
-       }
-
-       buf[count] = '\0';
+       buf = memdup_user_nul(buffer, count);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
- out:
        kfree(buf);
        return count;
 }
index bd3507da39f01678257e3d8a65a3009ad1d1f6f1..2836de390f95cdad34ff11331d9f0afd8df08998 100644 (file)
@@ -58,28 +58,6 @@ static void cpuid_smp_cpuid(void *cmd_block)
                    &cmd->eax, &cmd->ebx, &cmd->ecx, &cmd->edx);
 }
 
-static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
-{
-       loff_t ret;
-       struct inode *inode = file->f_mapping->host;
-
-       mutex_lock(&inode->i_mutex);
-       switch (orig) {
-       case 0:
-               file->f_pos = offset;
-               ret = file->f_pos;
-               break;
-       case 1:
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       mutex_unlock(&inode->i_mutex);
-       return ret;
-}
-
 static ssize_t cpuid_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos)
 {
@@ -132,7 +110,7 @@ static int cpuid_open(struct inode *inode, struct file *file)
  */
 static const struct file_operations cpuid_fops = {
        .owner = THIS_MODULE,
-       .llseek = cpuid_seek,
+       .llseek = no_seek_end_llseek,
        .read = cpuid_read,
        .open = cpuid_open,
 };
index 113e70784854fb55bdc0eb08fe5e38bee4946126..64f9616f93f1ec39a85494857d2d07728a7ec5d2 100644 (file)
 
 static struct class *msr_class;
 
-static loff_t msr_seek(struct file *file, loff_t offset, int orig)
-{
-       loff_t ret;
-       struct inode *inode = file_inode(file);
-
-       mutex_lock(&inode->i_mutex);
-       switch (orig) {
-       case SEEK_SET:
-               file->f_pos = offset;
-               ret = file->f_pos;
-               break;
-       case SEEK_CUR:
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       mutex_unlock(&inode->i_mutex);
-       return ret;
-}
-
 static ssize_t msr_read(struct file *file, char __user *buf,
                        size_t count, loff_t *ppos)
 {
@@ -194,7 +172,7 @@ static int msr_open(struct inode *inode, struct file *file)
  */
 static const struct file_operations msr_fops = {
        .owner = THIS_MODULE,
-       .llseek = msr_seek,
+       .llseek = no_seek_end_llseek,
        .read = msr_read,
        .write = msr_write,
        .open = msr_open,
index 3c3ace2c46b613522ddccbd6ee7c357507b65ea4..f58a4e6472cbc5fd9988d8bfb73d3a80e4806bfd 100644 (file)
@@ -227,16 +227,12 @@ static ssize_t proc_read_simdisk(struct file *file, char __user *buf,
 static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
                        size_t count, loff_t *ppos)
 {
-       char *tmp = kmalloc(count + 1, GFP_KERNEL);
+       char *tmp = memdup_user_nul(buf, count);
        struct simdisk *dev = PDE_DATA(file_inode(file));
        int err;
 
-       if (tmp == NULL)
-               return -ENOMEM;
-       if (copy_from_user(tmp, buf, count)) {
-               err = -EFAULT;
-               goto out_free;
-       }
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
 
        err = simdisk_detach(dev);
        if (err != 0)
@@ -244,8 +240,6 @@ static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
 
        if (count > 0 && tmp[count - 1] == '\n')
                tmp[count - 1] = 0;
-       else
-               tmp[count] = 0;
 
        if (tmp[0])
                err = simdisk_attach(dev, tmp);
index 0422c47261c3a06ad7bc6796d09ae5a84603a514..b38bd06d564c8d94fd79bfccc9dbb51b7c2d4552 100644 (file)
@@ -514,14 +514,9 @@ cciss_proc_write(struct file *file, const char __user *buf,
        if (!buf || length > PAGE_SIZE - 1)
                return -EINVAL;
 
-       buffer = (char *)__get_free_page(GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
-       err = -EFAULT;
-       if (copy_from_user(buffer, buf, length))
-               goto out;
-       buffer[length] = '\0';
+       buffer = memdup_user_nul(buf, length);
+       if (IS_ERR(buffer))
+               return PTR_ERR(buffer);
 
 #ifdef CONFIG_CISS_SCSI_TAPE
        if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) {
@@ -537,8 +532,7 @@ cciss_proc_write(struct file *file, const char __user *buf,
        /* might be nice to have "disengage" too, but it's not
           safely possible. (only 1 module use count, lock issues.) */
 
-out:
-       free_page((unsigned long)buffer);
+       kfree(buffer);
        return err;
 }
 
index 3457ac8c03e2f3cfe10c8a2ccc26f9a706039831..34997d8ecd64b40d30db036a05dfc476e356111e 100644 (file)
@@ -2029,13 +2029,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
        }
 
        if (taskout) {
-               outbuf = kzalloc(taskout, GFP_KERNEL);
-               if (outbuf == NULL) {
-                       err = -ENOMEM;
-                       goto abort;
-               }
-               if (copy_from_user(outbuf, buf + outtotal, taskout)) {
-                       err = -EFAULT;
+               outbuf = memdup_user(buf + outtotal, taskout);
+               if (IS_ERR(outbuf)) {
+                       err = PTR_ERR(outbuf);
+                       outbuf = NULL;
                        goto abort;
                }
                outbuf_dma = pci_map_single(dd->pdev,
@@ -2050,14 +2047,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
        }
 
        if (taskin) {
-               inbuf = kzalloc(taskin, GFP_KERNEL);
-               if (inbuf == NULL) {
-                       err = -ENOMEM;
-                       goto abort;
-               }
-
-               if (copy_from_user(inbuf, buf + intotal, taskin)) {
-                       err = -EFAULT;
+               inbuf = memdup_user(buf + intotal, taskin);
+               if (IS_ERR(inbuf)) {
+                       err = PTR_ERR(inbuf);
+                       inbuf = NULL;
                        goto abort;
                }
                inbuf_dma = pci_map_single(dd->pdev,
index 93b3f99b6865fe721f7124412553cadf3c328e7a..e4c5cc1079344110298f0becd938d91b27685924 100644 (file)
@@ -827,6 +827,7 @@ static const struct block_device_operations nbd_fops =
 {
        .owner =        THIS_MODULE,
        .ioctl =        nbd_ioctl,
+       .compat_ioctl = nbd_ioctl,
 };
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
index d8b2488aaade109847a3b9156e1279b112907c14..34997df132e240be4bcebedcf0df6c6baaf39907 100644 (file)
@@ -203,14 +203,11 @@ static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf,
        char *buf;
        ssize_t st;
 
-       buf = kzalloc(cnt, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       buf = memdup_user(ubuf, cnt);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       st = copy_from_user(buf, ubuf, cnt);
-       if (!st)
-               st = rsxx_creg_write(card, CREG_ADD_CRAM + (u32)*ppos, cnt,
-                                    buf, 1);
+       st = rsxx_creg_write(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1);
        kfree(buf);
        if (st)
                return st;
index c206ccda899b388fe7856424078c505f99c87830..1b257ea9776ae596ed3164bc11a37d325c47d989 100644 (file)
@@ -3186,15 +3186,11 @@ static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
        if (!CDROM_CAN(CDC_DVD))
                return -ENOSYS;
 
-       s = kmalloc(size, GFP_KERNEL);
-       if (!s)
-               return -ENOMEM;
+       s = memdup_user(arg, size);
+       if (IS_ERR(s))
+               return PTR_ERR(s);
 
        cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
-       if (copy_from_user(s, arg, size)) {
-               kfree(s);
-               return -EFAULT;
-       }
 
        ret = dvd_read_struct(cdi, s, cgc);
        if (ret)
index 6c4f4b5a9dd3aebb80920b2cae781c4a858fccac..073db9558379366dcde41921c059bbf5287b4341 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/pagemap.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 #ifdef CONFIG_PPC_PMAC
@@ -33,24 +34,8 @@ static ssize_t nvram_len;
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-       switch (origin) {
-       case 0:
-               break;
-       case 1:
-               offset += file->f_pos;
-               break;
-       case 2:
-               offset += nvram_len;
-               break;
-       default:
-               offset = -1;
-       }
-       if (offset < 0)
-               return -EINVAL;
-
-       file->f_pos = offset;
-
-       return file->f_pos;
+       return generic_file_llseek_size(file, offset, origin,
+                                       MAX_LFS_FILESIZE, nvram_len);
 }
 
 static ssize_t read_nvram(struct file *file, char __user *buf,
index e5d3e3f7a49bcdbbb31d8e05045b8125d561b210..67d426470e5341df2c88afe1b509742b9923603a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/uio.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -451,31 +452,8 @@ mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * o
 
 static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
 {
-       loff_t newpos;
-
-       switch (whence) {
-       case SEEK_SET:
-               newpos = off;
-               break;
-
-       case SEEK_CUR:
-               newpos = filp->f_pos + off;
-               break;
-
-       case SEEK_END:
-               newpos = MBCS_SRAM_SIZE + off;
-               break;
-
-       default:                /* can't happen */
-               return -EINVAL;
-       }
-
-       if (newpos < 0)
-               return -EINVAL;
-
-       filp->f_pos = newpos;
-
-       return newpos;
+       return generic_file_llseek_size(filp, off, whence, MAX_LFS_FILESIZE,
+                                       MBCS_SRAM_SIZE);
 }
 
 static uint64_t mbcs_pioaddr(struct mbcs_soft *soft, uint64_t offset)
index 97c2d8d433d6227f82f8524da27ecbd8929d9cd8..01292328a45677d7da51e662c3c94dec2c5e970c 100644 (file)
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/mutex.h>
+#include <linux/pagemap.h>
 
 
 static DEFINE_MUTEX(nvram_mutex);
@@ -213,21 +214,8 @@ void nvram_set_checksum(void)
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
-       switch (origin) {
-       case 0:
-               /* nothing to do */
-               break;
-       case 1:
-               offset += file->f_pos;
-               break;
-       case 2:
-               offset += NVRAM_BYTES;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
+       return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
+                                       NVRAM_BYTES);
 }
 
 static ssize_t nvram_read(struct file *file, char __user *buf,
index e371480d36394974cc5e27787c6a243e2c075dcf..dbe598de9b74ff4392384f8327715dc3136aa499 100644 (file)
@@ -277,36 +277,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
                printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
                       (unsigned int) offset, orig);
 
-       switch (orig) {
-       case 0:
-               if (offset < 0) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               if ((unsigned int) offset > gbFlashSize) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               file->f_pos = (unsigned int) offset;
-               ret = file->f_pos;
-               break;
-       case 1:
-               if ((file->f_pos + offset) > gbFlashSize) {
-                       ret = -EINVAL;
-                       break;
-               }
-               if ((file->f_pos + offset) < 0) {
-                       ret = -EINVAL;
-                       break;
-               }
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       default:
-               ret = -EINVAL;
-       }
+       ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
        mutex_unlock(&flash_mutex);
        return ret;
 }
index c6a1b4cc64581733a9a8218299571576e3e6957a..d321222fd92ef0a1cbc0fda0110da1f8230d9d39 100644 (file)
@@ -559,19 +559,10 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
 
        /* this is the actual buffer to work with */
 
-       args_buff = kmalloc(args->buf_size_in_bytes -
-                                       sizeof(*args), GFP_KERNEL);
-       if (args_buff == NULL)
-               return -ENOMEM;
-
-       status = copy_from_user(args_buff, cmd_from_user,
+       args_buff = memdup_user(args_buff,
                                args->buf_size_in_bytes - sizeof(*args));
-
-       if (status != 0) {
-               pr_debug("Failed to copy address watch user data\n");
-               kfree(args_buff);
-               return -EINVAL;
-       }
+       if (IS_ERR(args_buff))
+               return PTR_ERR(args_buff);
 
        aw_info.process = p;
 
@@ -677,22 +668,12 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep,
        if (cmd_from_user == NULL)
                return -EINVAL;
 
-       /* this is the actual buffer to work with */
+       /* copy the entire buffer from user */
 
-       args_buff = kmalloc(args->buf_size_in_bytes - sizeof(*args),
-                       GFP_KERNEL);
-
-       if (args_buff == NULL)
-               return -ENOMEM;
-
-       /* Now copy the entire buffer from user */
-       status = copy_from_user(args_buff, cmd_from_user,
+       args_buff = memdup_user(cmd_from_user,
                                args->buf_size_in_bytes - sizeof(*args));
-       if (status != 0) {
-               pr_debug("Failed to copy wave control user data\n");
-               kfree(args_buff);
-               return -EINVAL;
-       }
+       if (IS_ERR(args_buff))
+               return PTR_ERR(args_buff);
 
        /* move ptr to the start of the "pay-load" area */
        wac_info.process = p;
index 9abcaa53bd25a4149e850562628bdc17e81161ed..f17cb04318337688b0d5223dd60ad4f687b0cfc5 100644 (file)
@@ -1163,12 +1163,8 @@ done:
 
 static unsigned int vga_arb_fpoll(struct file *file, poll_table *wait)
 {
-       struct vga_arb_private *priv = file->private_data;
-
        pr_debug("%s\n", __func__);
 
-       if (priv == NULL)
-               return -ENODEV;
        poll_wait(file, &vga_wait_queue, wait);
        return POLLIN;
 }
@@ -1209,9 +1205,6 @@ static int vga_arb_release(struct inode *inode, struct file *file)
 
        pr_debug("%s\n", __func__);
 
-       if (priv == NULL)
-               return -ENODEV;
-
        spin_lock_irqsave(&vga_user_lock, flags);
        list_del(&priv->list);
        for (i = 0; i < MAX_USER_CARDS; i++) {
index db3ae4c2b2233a4026ebe8a183042eb84d53cdc4..dde6172f3f105dde590744b52fd9116db10f825d 100644 (file)
@@ -230,7 +230,7 @@ void bch_bio_map(struct bio *bio, void *base)
        BUG_ON(!bio->bi_iter.bi_size);
        BUG_ON(bio->bi_vcnt);
 
-       bv->bv_offset = base ? ((unsigned long) base) % PAGE_SIZE : 0;
+       bv->bv_offset = base ? offset_in_page(base) : 0;
        goto start;
 
        for (; size; bio->bi_vcnt++, bv++) {
index 6b832e06580dd6527bbf6e1a92e36c044db62f4a..cd77216beff166651c67b0881b747dcdd720c9e7 100644 (file)
@@ -650,7 +650,7 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,
        do {
                if (!bio_add_page(&b->bio, virt_to_page(ptr),
                                  len < PAGE_SIZE ? len : PAGE_SIZE,
-                                 virt_to_phys(ptr) & (PAGE_SIZE - 1))) {
+                                 offset_in_page(ptr))) {
                        BUG_ON(b->c->block_size <= PAGE_SIZE);
                        use_dmio(b, rw, block, end_io);
                        return;
index 81c5e1a1f36389e0d743eedfb6ae895de88340be..06d426eb5a306b79c1ef9bbac00c9a36578226fb 100644 (file)
@@ -246,7 +246,7 @@ static void vm_dp_init(struct dpages *dp, void *data)
 {
        dp->get_page = vm_get_page;
        dp->next_page = vm_next_page;
-       dp->context_u = ((unsigned long) data) & (PAGE_SIZE - 1);
+       dp->context_u = offset_in_page(data);
        dp->context_ptr = data;
 }
 
@@ -271,7 +271,7 @@ static void km_dp_init(struct dpages *dp, void *data)
 {
        dp->get_page = km_get_page;
        dp->next_page = km_next_page;
-       dp->context_u = ((unsigned long) data) & (PAGE_SIZE - 1);
+       dp->context_u = offset_in_page(data);
        dp->context_ptr = data;
 }
 
index 3dad2111b7e331ee1d97f89530f57f8732a5d0b9..70bb403f69f72cc02198fe6946cfaf1bbb418134 100644 (file)
@@ -30,7 +30,7 @@
 
 struct pcmciamtd_dev {
        struct pcmcia_device    *p_dev;
-       caddr_t         win_base;       /* ioremapped address of PCMCIA window */
+       void __iomem    *win_base;      /* ioremapped address of PCMCIA window */
        unsigned int    win_size;       /* size of window */
        unsigned int    offset;         /* offset into card the window currently points at */
        struct map_info pcmcia_map;
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)")
 /* read/write{8,16} copy_{from,to} routines with window remapping
  * to access whole card
  */
-static caddr_t remap_window(struct map_info *map, unsigned long to)
+static void __iomem *remap_window(struct map_info *map, unsigned long to)
 {
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        struct resource *win = (struct resource *) map->map_priv_2;
@@ -107,7 +107,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
 
 static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
 {
-       caddr_t addr;
+       void __iomem *addr;
        map_word d = {{0}};
 
        addr = remap_window(map, ofs);
@@ -122,7 +122,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
 
 static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
 {
-       caddr_t addr;
+       void __iomem *addr;
        map_word d = {{0}};
 
        addr = remap_window(map, ofs);
@@ -143,7 +143,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
        pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
        while(len) {
                int toread = win_size - (from & (win_size-1));
-               caddr_t addr;
+               void __iomem *addr;
 
                if(toread > len)
                        toread = len;
@@ -163,7 +163,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
 
 static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long adr)
 {
-       caddr_t addr = remap_window(map, adr);
+       void __iomem *addr = remap_window(map, adr);
 
        if(!addr)
                return;
@@ -175,7 +175,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long
 
 static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long adr)
 {
-       caddr_t addr = remap_window(map, adr);
+       void __iomem *addr = remap_window(map, adr);
        if(!addr)
                return;
 
@@ -192,7 +192,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
        pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
        while(len) {
                int towrite = win_size - (to & (win_size-1));
-               caddr_t addr;
+               void __iomem *addr;
 
                if(towrite > len)
                        towrite = len;
@@ -216,7 +216,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
 
 static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
        map_word d = {{0}};
 
        if(DEV_REMOVED(map))
@@ -231,7 +231,7 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
 
 static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
        map_word d = {{0}};
 
        if(DEV_REMOVED(map))
@@ -246,7 +246,7 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
 
 static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
@@ -258,7 +258,7 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from,
 
 static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
@@ -271,7 +271,7 @@ static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
 
 static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
@@ -284,7 +284,7 @@ static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
 
 static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 {
-       caddr_t win_base = (caddr_t)map->map_priv_2;
+       void __iomem *win_base = (void __iomem *)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
index 97bc186f9728247a0048476065d17fe0021a3573..a1d10b85989f7bfec11be8a7352b5a58247daacb 100644 (file)
@@ -580,16 +580,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
        long channel;
        bool on;
 
-       char *kbuf = kmalloc(len + 1, GFP_KERNEL);
-
-       if (!kbuf)
-               return -ENOMEM;
-       if (copy_from_user(kbuf, buf, len)) {
-               kfree(kbuf);
-               return -EIO;
-       }
+       char *kbuf = memdup_user_nul(buf, len);
 
-       kbuf[len] = '\0';
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
        rc = kstrtol(kbuf, 0, &channel);
        kfree(kbuf);
        if (rc)
index 26cbf1dcc6620f0502314daf8cac579794c8f6e4..faed1823c58ec2dfe0125038ff694bbb18842e5c 100644 (file)
@@ -56,19 +56,15 @@ static ssize_t lbs_sleepparams_write(struct file *file,
                                loff_t *ppos)
 {
        struct lbs_private *priv = file->private_data;
-       ssize_t buf_size, ret;
+       ssize_t ret;
        struct sleep_params sp;
        int p1, p2, p3, p4, p5, p6;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(user_buf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, user_buf, buf_size)) {
-               ret = -EFAULT;
-               goto out_unlock;
-       }
        ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
        if (ret != 6) {
                ret = -EINVAL;
@@ -88,7 +84,7 @@ static ssize_t lbs_sleepparams_write(struct file *file,
                ret = -EINVAL;
 
 out_unlock:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -125,18 +121,14 @@ static ssize_t lbs_host_sleep_write(struct file *file,
                                loff_t *ppos)
 {
        struct lbs_private *priv = file->private_data;
-       ssize_t buf_size, ret;
+       ssize_t ret;
        int host_sleep;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(user_buf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, user_buf, buf_size)) {
-               ret = -EFAULT;
-               goto out_unlock;
-       }
        ret = sscanf(buf, "%d", &host_sleep);
        if (ret != 1) {
                ret = -EINVAL;
@@ -162,7 +154,7 @@ static ssize_t lbs_host_sleep_write(struct file *file,
                ret = count;
 
 out_unlock:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -281,21 +273,15 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
        struct cmd_ds_802_11_subscribe_event *events;
        struct mrvl_ie_thresholds *tlv;
        struct lbs_private *priv = file->private_data;
-       ssize_t buf_size;
        int value, freq, new_mask;
        uint16_t curr_mask;
        char *buf;
        int ret;
 
-       buf = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               ret = -EFAULT;
-               goto out_page;
-       }
        ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
        if (ret != 3) {
                ret = -EINVAL;
@@ -343,7 +329,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
  out_events:
        kfree(events);
  out_page:
-       free_page((unsigned long)buf);
+       kfree(buf);
        return ret;
 }
 
@@ -472,22 +458,15 @@ static ssize_t lbs_rdmac_write(struct file *file,
                                    size_t count, loff_t *ppos)
 {
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        priv->mac_offset = simple_strtoul(buf, NULL, 16);
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
+       kfree(buf);
+       return count;
 }
 
 static ssize_t lbs_wrmac_write(struct file *file,
@@ -496,18 +475,14 @@ static ssize_t lbs_wrmac_write(struct file *file,
 {
 
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
+       ssize_t res;
        u32 offset, value;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        res = sscanf(buf, "%x %x", &offset, &value);
        if (res != 2) {
                res = -EFAULT;
@@ -520,7 +495,7 @@ static ssize_t lbs_wrmac_write(struct file *file,
        if (!res)
                res = count;
 out_unlock:
-       free_page(addr);
+       kfree(buf);
        return res;
 }
 
@@ -554,22 +529,16 @@ static ssize_t lbs_rdbbp_write(struct file *file,
                                    size_t count, loff_t *ppos)
 {
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        priv->bbp_offset = simple_strtoul(buf, NULL, 16);
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
+       kfree(buf);
+
+       return count;
 }
 
 static ssize_t lbs_wrbbp_write(struct file *file,
@@ -578,18 +547,14 @@ static ssize_t lbs_wrbbp_write(struct file *file,
 {
 
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
+       ssize_t res;
        u32 offset, value;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        res = sscanf(buf, "%x %x", &offset, &value);
        if (res != 2) {
                res = -EFAULT;
@@ -602,7 +567,7 @@ static ssize_t lbs_wrbbp_write(struct file *file,
        if (!res)
                res = count;
 out_unlock:
-       free_page(addr);
+       kfree(buf);
        return res;
 }
 
@@ -636,22 +601,15 @@ static ssize_t lbs_rdrf_write(struct file *file,
                                    size_t count, loff_t *ppos)
 {
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        priv->rf_offset = simple_strtoul(buf, NULL, 16);
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
+       kfree(buf);
+       return count;
 }
 
 static ssize_t lbs_wrrf_write(struct file *file,
@@ -660,18 +618,14 @@ static ssize_t lbs_wrrf_write(struct file *file,
 {
 
        struct lbs_private *priv = file->private_data;
-       ssize_t res, buf_size;
+       ssize_t res;
        u32 offset, value;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
+
+       buf = memdup_user_nul(userbuf, min(count, len - 1));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
        res = sscanf(buf, "%x %x", &offset, &value);
        if (res != 2) {
                res = -EFAULT;
@@ -684,7 +638,7 @@ static ssize_t lbs_wrrf_write(struct file *file,
        if (!res)
                res = count;
 out_unlock:
-       free_page(addr);
+       kfree(buf);
        return res;
 }
 
@@ -915,16 +869,9 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
        if (cnt == 0)
                return 0;
 
-       pdata = kmalloc(cnt + 1, GFP_KERNEL);
-       if (pdata == NULL)
-               return 0;
-
-       if (copy_from_user(pdata, buf, cnt)) {
-               lbs_deb_debugfs("Copy from user failed\n");
-               kfree(pdata);
-               return 0;
-       }
-       pdata[cnt] = '\0';
+       pdata = memdup_user_nul(buf, cnt);
+       if (IS_ERR(pdata))
+               return PTR_ERR(pdata);
 
        p0 = pdata;
        for (i = 0; i < num_of_items; i++) {
index 9824d8dd2b4447f11304557a44f3c7ea2d629d76..241e1c3fbf08593d09981d98d258d3b6cac0cc99 100644 (file)
@@ -447,20 +447,13 @@ static ssize_t
 mwifiex_regrdwr_write(struct file *file,
                      const char __user *ubuf, size_t count, loff_t *ppos)
 {
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *) addr;
-       size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
+       char *buf;
        int ret;
        u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
 
-       if (!buf)
-               return -ENOMEM;
-
-
-       if (copy_from_user(buf, ubuf, buf_size)) {
-               ret = -EFAULT;
-               goto done;
-       }
+       buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
 
@@ -474,7 +467,7 @@ mwifiex_regrdwr_write(struct file *file,
                ret = count;
        }
 done:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -572,17 +565,11 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
        int ret;
        unsigned long debug_mask;
        struct mwifiex_private *priv = (void *)file->private_data;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (void *)addr;
-       size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1));
+       char *buf;
 
-       if (!buf)
-               return -ENOMEM;
-
-       if (copy_from_user(buf, ubuf, buf_size)) {
-               ret = -EFAULT;
-               goto done;
-       }
+       buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        if (kstrtoul(buf, 0, &debug_mask)) {
                ret = -EINVAL;
@@ -592,7 +579,7 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
        priv->adapter->debug_mask = debug_mask;
        ret = count;
 done:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -609,17 +596,11 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
        struct mwifiex_ds_mem_rw mem_rw;
        u16 cmd_action;
        struct mwifiex_private *priv = (void *)file->private_data;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (void *)addr;
-       size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1));
-
-       if (!buf)
-               return -ENOMEM;
+       char *buf;
 
-       if (copy_from_user(buf, ubuf, buf_size)) {
-               ret = -EFAULT;
-               goto done;
-       }
+       buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
        if (ret != 3) {
@@ -645,7 +626,7 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
                ret = count;
 
 done:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -686,20 +667,13 @@ static ssize_t
 mwifiex_rdeeprom_write(struct file *file,
                       const char __user *ubuf, size_t count, loff_t *ppos)
 {
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *) addr;
-       size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
+       char *buf;
        int ret = 0;
        int offset = -1, bytes = -1;
 
-       if (!buf)
-               return -ENOMEM;
-
-
-       if (copy_from_user(buf, ubuf, buf_size)) {
-               ret = -EFAULT;
-               goto done;
-       }
+       buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        sscanf(buf, "%d %d", &offset, &bytes);
 
@@ -712,7 +686,7 @@ mwifiex_rdeeprom_write(struct file *file,
                ret = count;
        }
 done:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
@@ -771,21 +745,15 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
                    size_t count, loff_t *ppos)
 {
        struct mwifiex_private *priv = (void *)file->private_data;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-       size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
+       char *buf;
        int ret, arg_num;
        struct mwifiex_ds_hs_cfg hscfg;
        int conditions = HS_CFG_COND_DEF;
        u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
 
-       if (!buf)
-               return -ENOMEM;
-
-       if (copy_from_user(buf, ubuf, buf_size)) {
-               ret = -EFAULT;
-               goto done;
-       }
+       buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
 
@@ -823,7 +791,7 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
        priv->adapter->hs_enabling = false;
        ret = count;
 done:
-       free_page(addr);
+       kfree(buf);
        return ret;
 }
 
index eb43f94a15973fec04cba41af965fac4e9065715..be72306f8c695b653e3a0574a410648633559381 100644 (file)
@@ -1205,26 +1205,11 @@ err_out:
 
 static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig)
 {
-       loff_t ret;
-
        /* only requests of dword-aligned size and offset are supported */
        if (offset % 4)
                return -EINVAL;
 
-       switch (orig) {
-       case SEEK_SET:
-               file->f_pos = offset;
-               ret = file->f_pos;
-               break;
-       case SEEK_CUR:
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
+       return no_seek_end_llseek(file, offset, orig);
 }
 
 static const struct file_operations dev_mem_ops = {
index 0fdedadff7bc845f7700c43b1e830542f7948fcf..2a67b496a9e28869dd9443aa5b823be6003b900f 100644 (file)
@@ -88,14 +88,9 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
 
        if (count > 240)
                return -EINVAL;
-       cmd = kmalloc(count + 1, GFP_KERNEL);
-       if (!cmd)
-               return -ENOMEM;
-       if (copy_from_user(cmd, buff, count)) {
-               kfree(cmd);
-               return -EFAULT;
-       }
-       cmd[count] = '\0';
+       cmd = memdup_user_nul(buff, count);
+       if (IS_ERR(cmd))
+               return PTR_ERR(cmd);
        session = file->private_data;
        if (mutex_lock_interruptible(&session->mutex)) {
                kfree(cmd);
index 0efb27f6f1999f4c85af4587c491b926fc30b251..6c30e93ab8fa2533b3f3ccd942e3a1884cf39939 100644 (file)
@@ -782,24 +782,11 @@ static int ur_release(struct inode *inode, struct file *file)
 
 static loff_t ur_llseek(struct file *file, loff_t offset, int whence)
 {
-       loff_t newpos;
-
        if ((file->f_flags & O_ACCMODE) != O_RDONLY)
                return -ESPIPE; /* seek allowed only for reader */
        if (offset % PAGE_SIZE)
                return -ESPIPE; /* only multiples of 4K allowed */
-       switch (whence) {
-       case 0: /* SEEK_SET */
-               newpos = offset;
-               break;
-       case 1: /* SEEK_CUR */
-               newpos = file->f_pos + offset;
-               break;
-       default:
-               return -EINVAL;
-       }
-       file->f_pos = newpos;
-       return newpos;
+       return no_seek_end_llseek(file, offset, whence);
 }
 
 static const struct file_operations ur_fops = {
index 823f41fc4bbd6762184737b73d55452967ca3e44..3339b862ec1701b8b1bab8aa97de73e464685422 100644 (file)
@@ -385,18 +385,7 @@ static loff_t zcore_lseek(struct file *file, loff_t offset, int orig)
        loff_t rc;
 
        mutex_lock(&zcore_mutex);
-       switch (orig) {
-       case 0:
-               file->f_pos = offset;
-               rc = file->f_pos;
-               break;
-       case 1:
-               file->f_pos += offset;
-               rc = file->f_pos;
-               break;
-       default:
-               rc = -EINVAL;
-       }
+       rc = no_seek_end_llseek(file, offset, orig);
        mutex_unlock(&zcore_mutex);
        return rc;
 }
index 5843288f64bc00c8e5666a499767aee995795820..e077ebd8931985a7cb6ef6b440a654a635085e7d 100644 (file)
@@ -390,16 +390,9 @@ static int copyin_string(char __user *user, size_t len, char **ptr)
        if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
                return -EINVAL;
 
-       tmp = kmalloc(len + 1, GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       if (copy_from_user(tmp, user, len)) {
-               kfree(tmp);
-               return -EFAULT;
-       }
-
-       tmp[len] = '\0';
+       tmp = memdup_user_nul(user, len);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
 
        *ptr = tmp;
 
index 02f27593013e3650e16bd22b511084755b2dc519..31cd6b323a39f4c6cbb28b6a421628758b3a6a11 100644 (file)
@@ -3139,7 +3139,7 @@ struct file_operations ll_file_operations_noflock = {
        .lock      = ll_file_noflock
 };
 
-struct inode_operations ll_file_inode_operations = {
+const struct inode_operations ll_file_inode_operations = {
        .setattr        = ll_setattr,
        .getattr        = ll_getattr,
        .permission     = ll_inode_permission,
index 9096d311e45d76baa411fb53b0d331685f304972..6102b29dbf30763d52b6613dabf23ca533b99663 100644 (file)
@@ -705,7 +705,7 @@ extern const struct address_space_operations ll_aops;
 extern struct file_operations ll_file_operations;
 extern struct file_operations ll_file_operations_flock;
 extern struct file_operations ll_file_operations_noflock;
-extern struct inode_operations ll_file_inode_operations;
+extern const struct inode_operations ll_file_inode_operations;
 int ll_have_md_lock(struct inode *inode, __u64 *bits,
                    ldlm_mode_t l_req_mode);
 ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
@@ -805,7 +805,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb,
                                      const struct lu_fid *fid);
 
 /* llite/symlink.c */
-extern struct inode_operations ll_fast_symlink_inode_operations;
+extern const struct inode_operations ll_fast_symlink_inode_operations;
 
 /* llite/llite_close.c */
 struct ll_close_queue {
index 2ca22001a534d87759e644151da517368338ad4a..64db5e86672fa3710cd8f2864f9fd661741a8f3b 100644 (file)
@@ -126,9 +126,7 @@ struct inode *ll_iget(struct super_block *sb, ino_t hash,
                                rc = cl_file_inode_init(inode, md);
                        }
                        if (rc != 0) {
-                               make_bad_inode(inode);
-                               unlock_new_inode(inode);
-                               iput(inode);
+                               iget_failed(inode);
                                inode = ERR_PTR(rc);
                        } else
                                unlock_new_inode(inode);
index e489a3271f0697fe8a9f35708434412072a3f2a1..2610348f6c7268eb3cc7195137c57a82206f65ee 100644 (file)
@@ -149,7 +149,7 @@ static const char *ll_get_link(struct dentry *dentry,
        return symname;
 }
 
-struct inode_operations ll_fast_symlink_inode_operations = {
+const struct inode_operations ll_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .setattr        = ll_setattr,
        .get_link       = ll_get_link,
index 2a3bbdf7eb9407568c71c0896615d30fb48ea9cb..cffa0a0d7de282de402f3576dd3669df9aa33eb2 100644 (file)
@@ -661,32 +661,8 @@ static unsigned int usb_device_poll(struct file *file,
        return 0;
 }
 
-static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)
-{
-       loff_t ret;
-
-       mutex_lock(&file_inode(file)->i_mutex);
-
-       switch (orig) {
-       case 0:
-               file->f_pos = offset;
-               ret = file->f_pos;
-               break;
-       case 1:
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       case 2:
-       default:
-               ret = -EINVAL;
-       }
-
-       mutex_unlock(&file_inode(file)->i_mutex);
-       return ret;
-}
-
 const struct file_operations usbfs_devices_fops = {
-       .llseek =       usb_device_lseek,
+       .llseek =       no_seek_end_llseek,
        .read =         usb_device_read,
        .poll =         usb_device_poll,
 };
index 38ae877c46e3124eb07c2a46ddd33bc66ac54d93..dbc3e143453a01c20dcdc44529afa51fed5f079f 100644 (file)
@@ -157,30 +157,6 @@ static int connected(struct usb_dev_state *ps)
                        ps->dev->state != USB_STATE_NOTATTACHED);
 }
 
-static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
-{
-       loff_t ret;
-
-       mutex_lock(&file_inode(file)->i_mutex);
-
-       switch (orig) {
-       case 0:
-               file->f_pos = offset;
-               ret = file->f_pos;
-               break;
-       case 1:
-               file->f_pos += offset;
-               ret = file->f_pos;
-               break;
-       case 2:
-       default:
-               ret = -EINVAL;
-       }
-
-       mutex_unlock(&file_inode(file)->i_mutex);
-       return ret;
-}
-
 static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes,
                           loff_t *ppos)
 {
@@ -2366,7 +2342,7 @@ static unsigned int usbdev_poll(struct file *file,
 
 const struct file_operations usbdev_file_operations = {
        .owner =          THIS_MODULE,
-       .llseek =         usbdev_lseek,
+       .llseek =         no_seek_end_llseek,
        .read =           usbdev_read,
        .poll =           usbdev_poll,
        .unlocked_ioctl = usbdev_ioctl,
index 1b28a000d5c62c53c1d7d9cc026bfedb921cc296..9c6635d43db0d88a48f2d54ca8ed9ab776d2ad5f 100644 (file)
@@ -584,27 +584,8 @@ static int uhci_debug_open(struct inode *inode, struct file *file)
 
 static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
 {
-       struct uhci_debug *up;
-       loff_t new = -1;
-
-       up = file->private_data;
-
-       /*
-        * XXX: atomic 64bit seek access, but that needs to be fixed in the VFS
-        */
-       switch (whence) {
-       case 0:
-               new = off;
-               break;
-       case 1:
-               new = file->f_pos + off;
-               break;
-       }
-
-       if (new < 0 || new > up->size)
-               return -EINVAL;
-
-       return (file->f_pos = new);
+       struct uhci_debug *up = file->private_data;
+       return no_seek_end_llseek_size(file, off, whence, up->size);
 }
 
 static ssize_t uhci_debug_read(struct file *file, char __user *buf,
index 306d6852ebc726b0f365633c4ca452164071597a..8efbabacc84e6b3179f43165b1f90920e99b2a5d 100644 (file)
@@ -2825,21 +2825,7 @@ sisusb_lseek(struct file *file, loff_t offset, int orig)
                return -ENODEV;
        }
 
-       switch (orig) {
-               case 0:
-                       file->f_pos = offset;
-                       ret = file->f_pos;
-                       /* never negative, no force_successful_syscall needed */
-                       break;
-               case 1:
-                       file->f_pos += offset;
-                       ret = file->f_pos;
-                       /* never negative, no force_successful_syscall needed */
-                       break;
-               default:
-                       /* seeking relative to "end of file" is not supported */
-                       ret = -EINVAL;
-       }
+       ret = no_seek_end_llseek(file, offset, orig);
 
        mutex_unlock(&sisusb->lock);
        return ret;
index a69260f27555df85894618dc1647422971914dc4..103ca5e1267beb2229999e0711e50ba83f4c0abb 100644 (file)
@@ -243,14 +243,14 @@ void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
        if (!v9inode->fscache)
                return;
 
-       spin_lock(&v9inode->fscache_lock);
+       mutex_lock(&v9inode->fscache_lock);
 
        if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
                v9fs_cache_inode_flush_cookie(inode);
        else
                v9fs_cache_inode_get_cookie(inode);
 
-       spin_unlock(&v9inode->fscache_lock);
+       mutex_unlock(&v9inode->fscache_lock);
 }
 
 void v9fs_cache_inode_reset_cookie(struct inode *inode)
@@ -264,7 +264,7 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
 
        old = v9inode->fscache;
 
-       spin_lock(&v9inode->fscache_lock);
+       mutex_lock(&v9inode->fscache_lock);
        fscache_relinquish_cookie(v9inode->fscache, 1);
 
        v9ses = v9fs_inode2v9ses(inode);
@@ -274,7 +274,7 @@ void v9fs_cache_inode_reset_cookie(struct inode *inode)
        p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
                 inode, old, v9inode->fscache);
 
-       spin_unlock(&v9inode->fscache_lock);
+       mutex_unlock(&v9inode->fscache_lock);
 }
 
 int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
index 0923f2cf3c80aa2fb95a7385276de6f497ea46fe..6877050384a1407d438576bd24a642dc7baf842d 100644 (file)
@@ -123,7 +123,7 @@ struct v9fs_session_info {
 
 struct v9fs_inode {
 #ifdef CONFIG_9P_FSCACHE
-       spinlock_t fscache_lock;
+       struct mutex fscache_lock;
        struct fscache_cookie *fscache;
 #endif
        struct p9_qid qid;
index c7cc7c30f0c8b9aab15816584763f9d32fec37f0..3a08b3e6ff1d7a31a6b1ce6358b17e9350544da5 100644 (file)
@@ -244,7 +244,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
                return NULL;
 #ifdef CONFIG_9P_FSCACHE
        v9inode->fscache = NULL;
-       spin_lock_init(&v9inode->fscache_lock);
+       mutex_init(&v9inode->fscache_lock);
 #endif
        v9inode->writeback_fid = NULL;
        v9inode->cache_validity = 0;
index 24575d9d882d99e790f97d351ddfac369c616603..ea4aba56f29d69dc26192a2b76e14e1d03747e2d 100644 (file)
@@ -45,7 +45,7 @@ struct adfs_dir_ops;
 struct adfs_sb_info {
        union { struct {
                struct adfs_discmap *s_map;     /* bh list containing map        */
-               struct adfs_dir_ops *s_dir;     /* directory operations          */
+               const struct adfs_dir_ops *s_dir; /* directory operations        */
                };
                struct rcu_head rcu;            /* used only at shutdown time    */
        };
@@ -168,8 +168,8 @@ void __adfs_error(struct super_block *sb, const char *function,
 extern const struct inode_operations adfs_dir_inode_operations;
 extern const struct file_operations adfs_dir_operations;
 extern const struct dentry_operations adfs_dentry_operations;
-extern struct adfs_dir_ops adfs_f_dir_ops;
-extern struct adfs_dir_ops adfs_fplus_dir_ops;
+extern const struct adfs_dir_ops adfs_f_dir_ops;
+extern const struct adfs_dir_ops adfs_fplus_dir_ops;
 
 extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
                           int wait);
index 51c279a29845e6870125469b18fd06ccdd99f64f..fd4cf2c48e48e3d16b3fc525373a65ecb5cad6cc 100644 (file)
@@ -21,7 +21,7 @@ adfs_readdir(struct file *file, struct dir_context *ctx)
 {
        struct inode *inode = file_inode(file);
        struct super_block *sb = inode->i_sb;
-       struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+       const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
        struct object_info obj;
        struct adfs_dir dir;
        int ret = 0;
@@ -69,7 +69,7 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
 {
        int ret = -EINVAL;
 #ifdef CONFIG_ADFS_FS_RW
-       struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+       const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
        struct adfs_dir dir;
 
        printk(KERN_INFO "adfs_dir_update: object %06X in dir %06X\n",
@@ -129,7 +129,7 @@ static int
 adfs_dir_lookup_byname(struct inode *inode, struct qstr *name, struct object_info *obj)
 {
        struct super_block *sb = inode->i_sb;
-       struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
+       const struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir;
        struct adfs_dir dir;
        int ret;
 
index 4bbe853ee50a1ee8931470802a6581139f16257f..0fbfd0b04ae09abca52a420f8d6754ce83f1781e 100644 (file)
@@ -476,7 +476,7 @@ adfs_f_free(struct adfs_dir *dir)
        dir->sb = NULL;
 }
 
-struct adfs_dir_ops adfs_f_dir_ops = {
+const struct adfs_dir_ops adfs_f_dir_ops = {
        .read           = adfs_f_read,
        .setpos         = adfs_f_setpos,
        .getnext        = adfs_f_getnext,
index 82d14cdf70f9d02448944a456cba29a01c785105..c92cfb638c18324a5c2e7af17cafb7b3db6982a7 100644 (file)
@@ -256,7 +256,7 @@ adfs_fplus_free(struct adfs_dir *dir)
        dir->sb = NULL;
 }
 
-struct adfs_dir_ops adfs_fplus_dir_ops = {
+const struct adfs_dir_ops adfs_fplus_dir_ops = {
        .read           = adfs_fplus_read,
        .setpos         = adfs_fplus_setpos,
        .getnext        = adfs_fplus_getnext,
index c69a87eaf57d147bfae947335e95fa5ae2be4452..cc2b2efc92116c819839affb7632350f4b31c8de 100644 (file)
@@ -138,7 +138,7 @@ extern int  affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh);
 extern int     affs_remove_header(struct dentry *dentry);
 extern u32     affs_checksum_block(struct super_block *sb, struct buffer_head *bh);
 extern void    affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
-extern void    secs_to_datestamp(time_t secs, struct affs_date *ds);
+extern void    secs_to_datestamp(time64_t secs, struct affs_date *ds);
 extern umode_t prot_to_mode(u32 prot);
 extern void    mode_to_prot(struct inode *inode);
 __printf(3, 4)
index 5fa92bc790ef7e960b5f3b1fc1501eb1842e5b5e..d6c7a51c93e4cc3419094027578bc68bd17b4a69 100644 (file)
@@ -8,6 +8,7 @@
  *  Please send bug reports to: hjw@zvw.de
  */
 
+#include <linux/math64.h>
 #include "affs.h"
 
 /*
@@ -366,22 +367,22 @@ affs_fix_checksum(struct super_block *sb, struct buffer_head *bh)
 }
 
 void
-secs_to_datestamp(time_t secs, struct affs_date *ds)
+secs_to_datestamp(time64_t secs, struct affs_date *ds)
 {
        u32      days;
        u32      minute;
+       s32      rem;
 
        secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60);
        if (secs < 0)
                secs = 0;
-       days    = secs / 86400;
-       secs   -= days * 86400;
-       minute  = secs / 60;
-       secs   -= minute * 60;
+       days    = div_s64_rem(secs, 86400, &rem);
+       minute  = rem / 60;
+       rem    -= minute * 60;
 
        ds->days = cpu_to_be32(days);
        ds->mins = cpu_to_be32(minute);
-       ds->ticks = cpu_to_be32(secs * 50);
+       ds->ticks = cpu_to_be32(rem * 50);
 }
 
 umode_t
index 5b50c4ca43a7dde6ce48049f365a9988da23449b..8836df5f1e11181e9fae8db39b5bd91eac1e59e0 100644 (file)
@@ -32,7 +32,7 @@ affs_commit_super(struct super_block *sb, int wait)
        struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh);
 
        lock_buffer(bh);
-       secs_to_datestamp(get_seconds(), &tail->disk_change);
+       secs_to_datestamp(ktime_get_real_seconds(), &tail->disk_change);
        affs_fix_checksum(sb, bh);
        unlock_buffer(bh);
 
index 24a905b076fd77268c74978053afef93ba4ef5d9..2853b40953442c44be94c3795caea497606872e4 100644 (file)
@@ -230,14 +230,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
        if (size <= 1 || size >= PAGE_SIZE)
                return -EINVAL;
 
-       kbuf = kmalloc(size + 1, GFP_KERNEL);
-       if (!kbuf)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       if (copy_from_user(kbuf, buf, size) != 0)
-               goto done;
-       kbuf[size] = 0;
+       kbuf = memdup_user_nul(buf, size);
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        /* trim to first NL */
        name = memchr(kbuf, '\n', size);
@@ -315,15 +310,9 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
        if (size <= 1 || size >= PAGE_SIZE)
                return -EINVAL;
 
-       ret = -ENOMEM;
-       kbuf = kmalloc(size + 1, GFP_KERNEL);
-       if (!kbuf)
-               goto nomem;
-
-       ret = -EFAULT;
-       if (copy_from_user(kbuf, buf, size) != 0)
-               goto infault;
-       kbuf[size] = 0;
+       kbuf = memdup_user_nul(buf, size);
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        /* trim to first NL */
        s = memchr(kbuf, '\n', size);
@@ -337,9 +326,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
        if (ret >= 0)
                ret = size;     /* consume everything, always */
 
-infault:
        kfree(kbuf);
-nomem:
        _leave(" = %d", ret);
        return ret;
 }
index 861b1e1c477710faced77767a0327c1d6e6b79c5..103f5d7c30838b98dd87b01828e536b667882798 100644 (file)
@@ -192,7 +192,7 @@ EXPORT_SYMBOL(make_bad_inode);
  *     Returns true if the inode in question has been marked as bad.
  */
  
-int is_bad_inode(struct inode *inode)
+bool is_bad_inode(struct inode *inode)
 {
        return (inode->i_op == &bad_inode_ops); 
 }
index 44d4a1e9244e74e923d7b26018d4b420aa2e1323..01b8e0d4b4ff0aec98725485463f5c8b2a362102 100644 (file)
@@ -1042,12 +1042,9 @@ EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
 static void flush_disk(struct block_device *bdev, bool kill_dirty)
 {
        if (__invalidate_device(bdev, kill_dirty)) {
-               char name[BDEVNAME_SIZE] = "";
-
-               if (bdev->bd_disk)
-                       disk_name(bdev->bd_disk, 0, name);
                printk(KERN_WARNING "VFS: busy inodes on changed media or "
-                      "resized disk %s\n", name);
+                      "resized disk %s\n",
+                      bdev->bd_disk ? bdev->bd_disk->disk_name : "");
        }
 
        if (!bdev->bd_disk)
@@ -1071,12 +1068,9 @@ void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
        disk_size = (loff_t)get_capacity(disk) << 9;
        bdev_size = i_size_read(bdev->bd_inode);
        if (disk_size != bdev_size) {
-               char name[BDEVNAME_SIZE];
-
-               disk_name(disk, 0, name);
                printk(KERN_INFO
                       "%s: detected capacity change from %lld to %lld\n",
-                      name, bdev_size, disk_size);
+                      disk->disk_name, bdev_size, disk_size);
                i_size_write(bdev->bd_inode, disk_size);
                flush_disk(bdev, false);
        }
index 24154e422945167f474557887c62acaf6ed0779c..a0434c179ea96b9f1308e7034066202b30cb4267 100644 (file)
@@ -1514,9 +1514,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                if ((flags ^ s->s_flags) & MS_RDONLY)
                        error = -EBUSY;
        } else {
-               char b[BDEVNAME_SIZE];
-
-               strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
                btrfs_sb(s)->bdev_holder = fs_type;
                error = btrfs_fill_super(s, fs_devices, data,
                                         flags & MS_SILENT ? 1 : 0);
index 4f4cd959da7c8fdfef9fcf49fd90e73c24c6d230..e1632abb4ca9fa6a00444f09b30eb9a90ede43fc 100644 (file)
@@ -134,13 +134,10 @@ __clear_page_buffers(struct page *page)
 
 static void buffer_io_error(struct buffer_head *bh, char *msg)
 {
-       char b[BDEVNAME_SIZE];
-
        if (!test_bit(BH_Quiet, &bh->b_state))
                printk_ratelimited(KERN_ERR
-                       "Buffer I/O error on dev %s, logical block %llu%s\n",
-                       bdevname(bh->b_bdev, b),
-                       (unsigned long long)bh->b_blocknr, msg);
+                       "Buffer I/O error on dev %pg, logical block %llu%s\n",
+                       bh->b_bdev, (unsigned long long)bh->b_blocknr, msg);
 }
 
 /*
@@ -237,15 +234,13 @@ __find_get_block_slow(struct block_device *bdev, sector_t block)
         * elsewhere, don't buffer_error if we had some unmapped buffers
         */
        if (all_mapped) {
-               char b[BDEVNAME_SIZE];
-
                printk("__find_get_block_slow() failed. "
                        "block=%llu, b_blocknr=%llu\n",
                        (unsigned long long)block,
                        (unsigned long long)bh->b_blocknr);
                printk("b_state=0x%08lx, b_size=%zu\n",
                        bh->b_state, bh->b_size);
-               printk("device %s blocksize: %d\n", bdevname(bdev, b),
+               printk("device %pg blocksize: %d\n", bdev,
                        1 << bd_inode->i_blkbits);
        }
 out_unlock:
@@ -531,10 +526,8 @@ repeat:
 
 static void do_thaw_one(struct super_block *sb, void *unused)
 {
-       char b[BDEVNAME_SIZE];
        while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
-               printk(KERN_WARNING "Emergency Thaw on %s\n",
-                      bdevname(sb->s_bdev, b));
+               printk(KERN_WARNING "Emergency Thaw on %pg\n", sb->s_bdev);
 }
 
 static void do_thaw_all(struct work_struct *work)
@@ -1074,12 +1067,10 @@ grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp)
         * pagecache index.  (this comparison is done using sector_t types).
         */
        if (unlikely(index != block >> sizebits)) {
-               char b[BDEVNAME_SIZE];
-
                printk(KERN_ERR "%s: requested out-of-range block %llu for "
-                       "device %s\n",
+                       "device %pg\n",
                        __func__, (unsigned long long)block,
-                       bdevname(bdev, b));
+                       bdev);
                return -EIO;
        }
 
index f601def05bdf00663f5b1666514e1810068e1b19..452e98dd756053363a092a456ede5de373d9361f 100644 (file)
@@ -226,15 +226,9 @@ static ssize_t cachefiles_daemon_write(struct file *file,
                return -EOPNOTSUPP;
 
        /* drag the command string into the kernel so we can parse it */
-       data = kmalloc(datalen + 1, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       if (copy_from_user(data, _data, datalen) != 0)
-               goto error;
-
-       data[datalen] = '\0';
+       data = memdup_user_nul(_data, datalen);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        ret = -EINVAL;
        if (memchr(data, '\0', datalen))
index 6fd272d455e4deb1112c277fc564324fd9d7b3ba..a71936a3f4cb39e7022d98363a0df70d69c8c3d0 100644 (file)
@@ -792,7 +792,7 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
                       const void __user *, data)
 {
        char *kernel_type;
-       unsigned long data_page;
+       void *options;
        char *kernel_dev;
        int retval;
 
@@ -806,26 +806,25 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
        if (IS_ERR(kernel_dev))
                goto out1;
 
-       retval = copy_mount_options(data, &data_page);
-       if (retval < 0)
+       options = copy_mount_options(data);
+       retval = PTR_ERR(options);
+       if (IS_ERR(options))
                goto out2;
 
-       retval = -EINVAL;
-
-       if (kernel_type && data_page) {
+       if (kernel_type && options) {
                if (!strcmp(kernel_type, NCPFS_NAME)) {
-                       do_ncp_super_data_conv((void *)data_page);
+                       do_ncp_super_data_conv(options);
                } else if (!strcmp(kernel_type, NFS4_NAME)) {
-                       if (do_nfs4_super_data_conv((void *) data_page))
+                       retval = -EINVAL;
+                       if (do_nfs4_super_data_conv(options))
                                goto out3;
                }
        }
 
-       retval = do_mount(kernel_dev, dir_name, kernel_type,
-                       flags, (void*)data_page);
+       retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
 
  out3:
-       free_page(data_page);
+       kfree(options);
  out2:
        kfree(kernel_dev);
  out1:
index 647ee0b03dc0082f9cc5ff162f307a6b82c78844..a5b8eb69a8f42526d4fb4d46d1cc26d33e78e6b2 100644 (file)
@@ -1305,12 +1305,6 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
 COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* NBD */
-COMPATIBLE_IOCTL(NBD_DO_IT)
-COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
-COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
-COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
-COMPATIBLE_IOCTL(NBD_DISCONNECT)
 /* i2c */
 COMPATIBLE_IOCTL(I2C_SLAVE)
 COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
@@ -1529,11 +1523,6 @@ static long do_ioctl_trans(unsigned int cmd,
        case KDSKBMETA:
        case KDSKBLED:
        case KDSETLED:
-       /* NBD */
-       case NBD_SET_SOCK:
-       case NBD_SET_BLKSIZE:
-       case NBD_SET_SIZE:
-       case NBD_SET_SIZE_BLOCKS:
                return vfs_ioctl(file, cmd, arg);
        }
 
index 1777331eee767fa323cb864fb95131983eaad588..b3c153ca435d24fdbdfcb909228b6b4787bb63f2 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/oom.h>
 #include <linux/compat.h>
+#include <linux/timekeeping.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -232,9 +233,10 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
                                break;
                        /* UNIX time of coredump */
                        case 't': {
-                               struct timeval tv;
-                               do_gettimeofday(&tv);
-                               err = cn_printf(cn, "%lu", tv.tv_sec);
+                               time64_t time;
+
+                               time = ktime_get_real_seconds();
+                               err = cn_printf(cn, "%lld", time);
                                break;
                        }
                        /* hostname */
index d27f0909d9f61141b6f6073996ed56858f2249c7..8d38cd07b207b9234d0f571bb4a945e05a395c7b 100644 (file)
@@ -3303,18 +3303,18 @@ out:
  * @new_dentry: new dentry
  * @old_dentry: old dentry
  *
- * Returns 1 if new_dentry is a subdirectory of the parent (at any depth).
- * Returns 0 otherwise.
+ * Returns true if new_dentry is a subdirectory of the parent (at any depth).
+ * Returns false otherwise.
  * Caller must ensure that "new_dentry" is pinned before calling is_subdir()
  */
   
-int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
+bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
 {
-       int result;
+       bool result;
        unsigned seq;
 
        if (new_dentry == old_dentry)
-               return 1;
+               return true;
 
        do {
                /* for restarting inner loop in case of seq retry */
@@ -3325,9 +3325,9 @@ int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
                 */
                rcu_read_lock();
                if (d_ancestor(old_dentry, new_dentry))
-                       result = 1;
+                       result = true;
                else
-                       result = 0;
+                       result = false;
                rcu_read_unlock();
        } while (read_seqretry(&rename_lock, seq));
 
index 173b3873a4f4ee94a42c9ffa821e6d64ce902d07..1925d6d222b87f635b9925e05003a3c7c41d7580 100644 (file)
@@ -515,14 +515,9 @@ static ssize_t device_write(struct file *file, const char __user *buf,
        if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
                return -EINVAL;
 
-       kbuf = kzalloc(count + 1, GFP_NOFS);
-       if (!kbuf)
-               return -ENOMEM;
-
-       if (copy_from_user(kbuf, buf, count)) {
-               error = -EFAULT;
-               goto out_free;
-       }
+       kbuf = memdup_user_nul(buf, count);
+       if (!IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        if (check_version(kbuf)) {
                error = -EBADE;
index a4dddc61594cbdb7797b1a75cd50fae0ec3a6e77..040aa879d634fe15d38f0ce9bf103c7b514122b4 100644 (file)
@@ -282,9 +282,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
        if (rc) {
                ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
                                   ecryptfs_inode);
-               make_bad_inode(ecryptfs_inode);
-               unlock_new_inode(ecryptfs_inode);
-               iput(ecryptfs_inode);
+               iget_failed(ecryptfs_inode);
                goto out;
        }
        unlock_new_inode(ecryptfs_inode);
index b06623a9347f4f206fb466c80574ec4bdd7d13fa..828ec5f07de00b7a21d016c022afc68ee0962331 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -119,7 +119,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
        int error = PTR_ERR(tmp);
        static const struct open_flags uselib_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
-               .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN,
+               .acc_mode = MAY_READ | MAY_EXEC,
                .intent = LOOKUP_OPEN,
                .lookup_flags = LOOKUP_FOLLOW,
        };
@@ -763,7 +763,7 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
        int err;
        struct open_flags open_exec_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
-               .acc_mode = MAY_EXEC | MAY_OPEN,
+               .acc_mode = MAY_EXEC,
                .intent = LOOKUP_OPEN,
                .lookup_flags = LOOKUP_FOLLOW,
        };
index cd95d14f9cc262503479c606401ce32e4f495e7b..f57a7aba32ebbd01aac9dde8783e5476b95a4c1d 100644 (file)
                printk("\n"); \
        } while (0)
 # define ea_bdebug(bh, f...) do { \
-               char b[BDEVNAME_SIZE]; \
-               printk(KERN_DEBUG "block %s:%lu: ", \
-                       bdevname(bh->b_bdev, b), \
-                       (unsigned long) bh->b_blocknr); \
+               printk(KERN_DEBUG "block %pg:%lu: ", \
+                       bh->b_bdev, (unsigned long) bh->b_blocknr); \
                printk(f); \
                printk("\n"); \
        } while (0)
index 17fbe3882b8eb70e3ecc0445a950d25b42423beb..090b3498638e7a7282e2c9f1ff7426bc01153e21 100644 (file)
@@ -52,9 +52,8 @@ void ext4_exit_pageio(void)
  */
 static void buffer_io_error(struct buffer_head *bh)
 {
-       char b[BDEVNAME_SIZE];
-       printk_ratelimited(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
-                       bdevname(bh->b_bdev, b),
+       printk_ratelimited(KERN_ERR "Buffer I/O error on device %pg, logical block %llu\n",
+                      bh->b_bdev,
                        (unsigned long long)bh->b_blocknr);
 }
 
index e9b9afdd1d964ab3bfca8dcc55e26976c5f8b45e..a95151e875bdcb384d3f5e46d6532828820fb086 100644 (file)
                printk("\n"); \
        } while (0)
 # define ea_bdebug(bh, f...) do { \
-               char b[BDEVNAME_SIZE]; \
-               printk(KERN_DEBUG "block %s:%lu: ", \
-                       bdevname(bh->b_bdev, b), \
-                       (unsigned long) bh->b_blocknr); \
+               printk(KERN_DEBUG "block %pg:%lu: ",               \
+                      bh->b_bdev, (unsigned long) bh->b_blocknr); \
                printk(f); \
                printk("\n"); \
        } while (0)
index 478e5d54154f5b8e1faed3f5b2414c43475b06d5..ad1b18a7705bcdb6b815207882a0b28e798ef729 100644 (file)
@@ -211,12 +211,10 @@ static int stat_show(struct seq_file *s, void *v)
 
        mutex_lock(&f2fs_stat_mutex);
        list_for_each_entry(si, &f2fs_stat_list, stat_list) {
-               char devname[BDEVNAME_SIZE];
-
                update_general_status(si->sbi);
 
-               seq_printf(s, "\n=====[ partition info(%s). #%d ]=====\n",
-                       bdevname(si->sbi->sb->s_bdev, devname), i++);
+               seq_printf(s, "\n=====[ partition info(%pg). #%d ]=====\n",
+                       si->sbi->sb->s_bdev, i++);
                seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
                           si->sit_area_segs, si->nat_area_segs);
                seq_printf(s, "[SSA: %d] [MAIN: %d",
index 9db5500d63d9805437a028fcedd0820a1ebf5135..ec6067c33a3fa02472a9631b01bf4cc8a5643814 100644 (file)
@@ -1602,13 +1602,11 @@ static inline bool is_dot_dotdot(const struct qstr *str)
 
 static inline bool f2fs_may_extent_tree(struct inode *inode)
 {
-       mode_t mode = inode->i_mode;
-
        if (!test_opt(F2FS_I_SB(inode), EXTENT_CACHE) ||
                        is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
                return false;
 
-       return S_ISREG(mode);
+       return S_ISREG(inode->i_mode);
 }
 
 static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
@@ -2121,7 +2119,7 @@ static inline int f2fs_sb_has_crypto(struct super_block *sb)
 static inline bool f2fs_may_encrypt(struct inode *inode)
 {
 #ifdef CONFIG_F2FS_FS_ENCRYPTION
-       mode_t mode = inode->i_mode;
+       umode_t mode = inode->i_mode;
 
        return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
 #else
index ee85cd4e136abbff33409fb018343028d21578e2..350a2c8cfd28f3f1339613b31564da1c2422e917 100644 (file)
@@ -51,7 +51,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
               if (arg & O_NDELAY)
                   arg |= O_NONBLOCK;
 
-       if (arg & O_DIRECT) {
+       /* Pipe packetized mode is controlled by O_DIRECT flag */
+       if (!S_ISFIFO(filp->f_inode->i_mode) && (arg & O_DIRECT)) {
                if (!filp->f_mapping || !filp->f_mapping->a_ops ||
                        !filp->f_mapping->a_ops->direct_IO)
                                return -EINVAL;
index 39f8f15921da7973a2300ce4978f37937a1af288..1aed0add16a2c05d88249472744e6048232aea88 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -25,9 +25,9 @@
 
 int sysctl_nr_open __read_mostly = 1024*1024;
 int sysctl_nr_open_min = BITS_PER_LONG;
-/* our max() is unusable in constant expressions ;-/ */
-#define __const_max(x, y) ((x) < (y) ? (x) : (y))
-int sysctl_nr_open_max = __const_max(INT_MAX, ~(size_t)0/sizeof(void *)) &
+/* our min() is unusable in constant expressions ;-/ */
+#define __const_min(x, y) ((x) < (y) ? (x) : (y))
+int sysctl_nr_open_max = __const_min(INT_MAX, ~(size_t)0/sizeof(void *)) &
                         -BITS_PER_LONG;
 
 static void *alloc_fdmem(size_t size)
index baab99b69d8ae3b56e7c74646d9c3783c1d3e3e7..001c6664124302189a0a6a10eddfd3fc4102ff05 100644 (file)
@@ -1315,9 +1315,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
                if ((flags ^ s->s_flags) & MS_RDONLY)
                        goto error_super;
        } else {
-               char b[BDEVNAME_SIZE];
-
-               strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
                sb_set_blocksize(s, block_size(bdev));
                error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
                if (error)
index aa3f0d6d043c32f7b52293640daa3ad6c875821b..a3ec3ae7d34796877c2cfc7d08c631128569ca93 100644 (file)
@@ -166,7 +166,7 @@ int hfs_mdb_get(struct super_block *sb)
                pr_warn("continuing without an alternate MDB\n");
        }
 
-       HFS_SB(sb)->bitmap = (__be32 *)__get_free_pages(GFP_KERNEL, PAGE_SIZE < 8192 ? 1 : 0);
+       HFS_SB(sb)->bitmap = kmalloc(8192, GFP_KERNEL);
        if (!HFS_SB(sb)->bitmap)
                goto out;
 
@@ -360,7 +360,7 @@ void hfs_mdb_put(struct super_block *sb)
        unload_nls(HFS_SB(sb)->nls_io);
        unload_nls(HFS_SB(sb)->nls_disk);
 
-       free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0);
+       kfree(HFS_SB(sb)->bitmap);
        kfree(HFS_SB(sb));
        sb->s_fs_info = NULL;
 }
index a69bbc1e87f868738b0d0578cd61ac8f9a2e3f5d..a136929189f01435533ec5fbb0d0bae7a37b6908 100644 (file)
@@ -133,7 +133,7 @@ __le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
 void hpfs_load_hotfix_map(struct super_block *s, struct hpfs_spare_block *spareblock)
 {
        struct quad_buffer_head qbh;
-       u32 *directory;
+       __le32 *directory;
        u32 n_hotfixes, n_used_hotfixes;
        unsigned i;
 
index e38c08ca437dcdeed706b1cb0d043fd99d53600c..b71deeecea17939d85bce1c54f30da77f1c4d8a1 100644 (file)
@@ -55,7 +55,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 /*
  * namespace.c
  */
-extern int copy_mount_options(const void __user *, unsigned long *);
+extern void *copy_mount_options(const void __user *);
 extern char *copy_mount_string(const void __user *);
 
 extern struct vfsmount *lookup_mnt(struct path *);
index ca181e81c765518d4a599025c914adbac626e739..081dff087fc07c171f6ef052b860029c6a7fe2f4 100644 (file)
@@ -764,13 +764,11 @@ void jbd2_journal_unlock_updates (journal_t *journal)
 
 static void warn_dirty_buffer(struct buffer_head *bh)
 {
-       char b[BDEVNAME_SIZE];
-
        printk(KERN_WARNING
-              "JBD2: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). "
+              "JBD2: Spotted dirty metadata buffer (dev = %pg, blocknr = %llu). "
               "There's a risk of filesystem corruption in case of system "
               "crash.\n",
-              bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr);
+              bh->b_bdev, (unsigned long long)bh->b_blocknr);
 }
 
 /* Call t_frozen trigger and copy buffer data into jh->b_frozen_data. */
index a69bdf2a108500ceddee89b80bfd7e34dcddf8e8..a270cb7ff4e030c8031f2c48114e6771c4d796b1 100644 (file)
@@ -1835,17 +1835,16 @@ static int lbmLogInit(struct jfs_log * log)
        for (i = 0; i < LOGPAGES;) {
                char *buffer;
                uint offset;
-               struct page *page;
+               struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 
-               buffer = (char *) get_zeroed_page(GFP_KERNEL);
-               if (buffer == NULL)
+               if (!page)
                        goto error;
-               page = virt_to_page(buffer);
+               buffer = page_address(page);
                for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) {
                        lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL);
                        if (lbuf == NULL) {
                                if (offset == 0)
-                                       free_page((unsigned long) buffer);
+                                       __free_page(page);
                                goto error;
                        }
                        if (offset) /* we already have one reference */
index 209a26d84c3835eda1ae30638e5edc2d3896cc49..39d91f86cd357ea12f38c4406d6bb12a4a5de8c5 100644 (file)
@@ -302,7 +302,7 @@ struct logfs_block {
        struct inode *inode;
        struct logfs_transaction *ta;
        unsigned long alias_map[LOGFS_BLOCK_FACTOR / BITS_PER_LONG];
-       struct logfs_block_ops *ops;
+       const struct logfs_block_ops *ops;
        int full;
        int partial;
        int reserved_bytes;
@@ -578,7 +578,7 @@ int logfs_exist_block(struct inode *inode, u64 bix);
 int get_page_reserve(struct inode *inode, struct page *page);
 void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock);
 void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock);
-extern struct logfs_block_ops indirect_block_ops;
+extern const struct logfs_block_ops indirect_block_ops;
 
 /* segment.c */
 int logfs_erase_segment(struct super_block *sb, u32 ofs, int ensure_erase);
index 380d86e1ab450b2ed02c9011ec9843ba0e2d2f6c..20973c9e52f807cf462766e6299e4c32177f1e3d 100644 (file)
@@ -569,13 +569,13 @@ static void indirect_free_block(struct super_block *sb,
 }
 
 
-static struct logfs_block_ops inode_block_ops = {
+static const struct logfs_block_ops inode_block_ops = {
        .write_block = inode_write_block,
        .free_block = inode_free_block,
        .write_alias = inode_write_alias,
 };
 
-struct logfs_block_ops indirect_block_ops = {
+const struct logfs_block_ops indirect_block_ops = {
        .write_block = indirect_write_block,
        .free_block = indirect_free_block,
        .write_alias = indirect_write_alias,
index 6de0fbfc6c00a237b90c0d5bc6b4dc67659a1507..d270e4b2ab6b0f9ae448ef15985c8ce459c3b2d6 100644 (file)
@@ -197,7 +197,7 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
        return 0;
 }
 
-static struct logfs_block_ops btree_block_ops = {
+static const struct logfs_block_ops btree_block_ops = {
        .write_block    = btree_write_block,
        .free_block     = __free_block,
        .write_alias    = btree_write_alias,
index 282e15ad8cd8c8ce24da286263acbd284985ed17..46ca39d6c73586fea640e60cfdee9905ad19970c 100644 (file)
@@ -24,16 +24,15 @@ static inline block_t *i_data(struct inode *inode)
 static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
 {
        int n = 0;
-       char b[BDEVNAME_SIZE];
 
        if (block < 0) {
-               printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
-                       block, bdevname(inode->i_sb->s_bdev, b));
+               printk("MINIX-fs: block_to_path: block %ld < 0 on dev %pg\n",
+                       block, inode->i_sb->s_bdev);
        } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
                if (printk_ratelimit())
                        printk("MINIX-fs: block_to_path: "
-                              "block %ld too big on dev %s\n",
-                               block, bdevname(inode->i_sb->s_bdev, b));
+                              "block %ld too big on dev %pg\n",
+                               block, inode->i_sb->s_bdev);
        } else if (block < 7) {
                offsets[n++] = block;
        } else if ((block -= 7) < 512) {
index 78e2d93e5c830f33cc370d8ca98262fcfe27e883..1ee101352586465cada91c2674a41b8a7c79ad38 100644 (file)
@@ -26,18 +26,17 @@ static inline block_t *i_data(struct inode *inode)
 static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
 {
        int n = 0;
-       char b[BDEVNAME_SIZE];
        struct super_block *sb = inode->i_sb;
 
        if (block < 0) {
-               printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
-                       block, bdevname(sb->s_bdev, b));
+               printk("MINIX-fs: block_to_path: block %ld < 0 on dev %pg\n",
+                       block, sb->s_bdev);
        } else if ((u64)block * (u64)sb->s_blocksize >=
                        minix_sb(sb)->s_max_size) {
                if (printk_ratelimit())
                        printk("MINIX-fs: block_to_path: "
-                              "block %ld too big on dev %s\n",
-                               block, bdevname(sb->s_bdev, b));
+                              "block %ld too big on dev %pg\n",
+                               block, sb->s_bdev);
        } else if (block < DIRCOUNT) {
                offsets[n++] = block;
        } else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
index 3c909aebef70f8a8a091960bd3ba434a15e2f829..bceefd5588a2bf908626a0a6282a5f810ecfc5c1 100644 (file)
@@ -534,10 +534,8 @@ static void restore_nameidata(void)
        current->nameidata = old;
        if (old)
                old->total_link_count = now->total_link_count;
-       if (now->stack != now->internal) {
+       if (now->stack != now->internal)
                kfree(now->stack);
-               now->stack = now->internal;
-       }
 }
 
 static int __nd_alloc_stack(struct nameidata *nd)
@@ -654,7 +652,7 @@ static bool legitimize_links(struct nameidata *nd)
  * Path walking has 2 modes, rcu-walk and ref-walk (see
  * Documentation/filesystems/path-lookup.txt).  In situations when we can't
  * continue in RCU mode, we attempt to drop out of rcu-walk mode and grab
- * normal reference counts on dentries and vfsmounts to transition to rcu-walk
+ * normal reference counts on dentries and vfsmounts to transition to ref-walk
  * mode.  Refcounts are grabbed at the last known good point before rcu-walk
  * got stuck, so ref-walk may continue from there. If this is not successful
  * (eg. a seqcount has changed), then failure is returned and it's up to caller
@@ -803,20 +801,20 @@ static int complete_walk(struct nameidata *nd)
 }
 
 static void set_root(struct nameidata *nd)
-{
-       get_fs_root(current->fs, &nd->root);
-}
-
-static void set_root_rcu(struct nameidata *nd)
 {
        struct fs_struct *fs = current->fs;
-       unsigned seq;
 
-       do {
-               seq = read_seqcount_begin(&fs->seq);
-               nd->root = fs->root;
-               nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
-       } while (read_seqcount_retry(&fs->seq, seq));
+       if (nd->flags & LOOKUP_RCU) {
+               unsigned seq;
+
+               do {
+                       seq = read_seqcount_begin(&fs->seq);
+                       nd->root = fs->root;
+                       nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
+               } while (read_seqcount_retry(&fs->seq, seq));
+       } else {
+               get_fs_root(fs, &nd->root);
+       }
 }
 
 static void path_put_conditional(struct path *path, struct nameidata *nd)
@@ -838,6 +836,26 @@ static inline void path_to_nameidata(const struct path *path,
        nd->path.dentry = path->dentry;
 }
 
+static int nd_jump_root(struct nameidata *nd)
+{
+       if (nd->flags & LOOKUP_RCU) {
+               struct dentry *d;
+               nd->path = nd->root;
+               d = nd->path.dentry;
+               nd->inode = d->d_inode;
+               nd->seq = nd->root_seq;
+               if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
+                       return -ECHILD;
+       } else {
+               path_put(&nd->path);
+               nd->path = nd->root;
+               path_get(&nd->path);
+               nd->inode = nd->path.dentry->d_inode;
+       }
+       nd->flags |= LOOKUP_JUMPED;
+       return 0;
+}
+
 /*
  * Helper to directly jump to a known parsed path from ->get_link,
  * caller must have taken a reference to path beforehand.
@@ -1016,25 +1034,10 @@ const char *get_link(struct nameidata *nd)
                        return res;
        }
        if (*res == '/') {
-               if (nd->flags & LOOKUP_RCU) {
-                       struct dentry *d;
-                       if (!nd->root.mnt)
-                               set_root_rcu(nd);
-                       nd->path = nd->root;
-                       d = nd->path.dentry;
-                       nd->inode = d->d_inode;
-                       nd->seq = nd->root_seq;
-                       if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
-                               return ERR_PTR(-ECHILD);
-               } else {
-                       if (!nd->root.mnt)
-                               set_root(nd);
-                       path_put(&nd->path);
-                       nd->path = nd->root;
-                       path_get(&nd->root);
-                       nd->inode = nd->path.dentry->d_inode;
-               }
-               nd->flags |= LOOKUP_JUMPED;
+               if (!nd->root.mnt)
+                       set_root(nd);
+               if (unlikely(nd_jump_root(nd)))
+                       return ERR_PTR(-ECHILD);
                while (unlikely(*++res == '/'))
                        ;
        }
@@ -1295,8 +1298,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
 static int follow_dotdot_rcu(struct nameidata *nd)
 {
        struct inode *inode = nd->inode;
-       if (!nd->root.mnt)
-               set_root_rcu(nd);
 
        while (1) {
                if (path_equal(&nd->path, &nd->root))
@@ -1416,9 +1417,6 @@ static void follow_mount(struct path *path)
 
 static int follow_dotdot(struct nameidata *nd)
 {
-       if (!nd->root.mnt)
-               set_root(nd);
-
        while(1) {
                struct dentry *old = nd->path.dentry;
 
@@ -1656,6 +1654,8 @@ static inline int may_lookup(struct nameidata *nd)
 static inline int handle_dots(struct nameidata *nd, int type)
 {
        if (type == LAST_DOTDOT) {
+               if (!nd->root.mnt)
+                       set_root(nd);
                if (nd->flags & LOOKUP_RCU) {
                        return follow_dotdot_rcu(nd);
                } else
@@ -2021,18 +2021,19 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
        }
 
        nd->root.mnt = NULL;
+       nd->path.mnt = NULL;
+       nd->path.dentry = NULL;
 
        nd->m_seq = read_seqbegin(&mount_lock);
        if (*s == '/') {
-               if (flags & LOOKUP_RCU) {
+               if (flags & LOOKUP_RCU)
                        rcu_read_lock();
-                       set_root_rcu(nd);
-                       nd->seq = nd->root_seq;
-               } else {
-                       set_root(nd);
-                       path_get(&nd->root);
-               }
-               nd->path = nd->root;
+               set_root(nd);
+               if (likely(!nd_jump_root(nd)))
+                       return s;
+               nd->root.mnt = NULL;
+               rcu_read_unlock();
+               return ERR_PTR(-ECHILD);
        } else if (nd->dfd == AT_FDCWD) {
                if (flags & LOOKUP_RCU) {
                        struct fs_struct *fs = current->fs;
@@ -2043,11 +2044,14 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
                        do {
                                seq = read_seqcount_begin(&fs->seq);
                                nd->path = fs->pwd;
+                               nd->inode = nd->path.dentry->d_inode;
                                nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
                        } while (read_seqcount_retry(&fs->seq, seq));
                } else {
                        get_fs_pwd(current->fs, &nd->path);
+                       nd->inode = nd->path.dentry->d_inode;
                }
+               return s;
        } else {
                /* Caller must check execute permissions on the starting path component */
                struct fd f = fdget_raw(nd->dfd);
@@ -2077,16 +2081,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
                fdput(f);
                return s;
        }
-
-       nd->inode = nd->path.dentry->d_inode;
-       if (!(flags & LOOKUP_RCU))
-               return s;
-       if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
-               return s;
-       if (!(nd->flags & LOOKUP_ROOT))
-               nd->root.mnt = NULL;
-       rcu_read_unlock();
-       return ERR_PTR(-ECHILD);
 }
 
 static const char *trailing_symlink(struct nameidata *nd)
@@ -2279,6 +2273,8 @@ EXPORT_SYMBOL(vfs_path_lookup);
  *
  * Note that this routine is purely a helper for filesystem usage and should
  * not be called by generic code.
+ *
+ * The caller must hold base->i_mutex.
  */
 struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 {
@@ -2322,6 +2318,75 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 }
 EXPORT_SYMBOL(lookup_one_len);
 
+/**
+ * lookup_one_len_unlocked - filesystem helper to lookup single pathname component
+ * @name:      pathname component to lookup
+ * @base:      base directory to lookup from
+ * @len:       maximum length @len should be interpreted to
+ *
+ * Note that this routine is purely a helper for filesystem usage and should
+ * not be called by generic code.
+ *
+ * Unlike lookup_one_len, it should be called without the parent
+ * i_mutex held, and will take the i_mutex itself if necessary.
+ */
+struct dentry *lookup_one_len_unlocked(const char *name,
+                                      struct dentry *base, int len)
+{
+       struct qstr this;
+       unsigned int c;
+       int err;
+       struct dentry *ret;
+
+       this.name = name;
+       this.len = len;
+       this.hash = full_name_hash(name, len);
+       if (!len)
+               return ERR_PTR(-EACCES);
+
+       if (unlikely(name[0] == '.')) {
+               if (len < 2 || (len == 2 && name[1] == '.'))
+                       return ERR_PTR(-EACCES);
+       }
+
+       while (len--) {
+               c = *(const unsigned char *)name++;
+               if (c == '/' || c == '\0')
+                       return ERR_PTR(-EACCES);
+       }
+       /*
+        * See if the low-level filesystem might want
+        * to use its own hash..
+        */
+       if (base->d_flags & DCACHE_OP_HASH) {
+               int err = base->d_op->d_hash(base, &this);
+               if (err < 0)
+                       return ERR_PTR(err);
+       }
+
+       err = inode_permission(base->d_inode, MAY_EXEC);
+       if (err)
+               return ERR_PTR(err);
+
+       /*
+        * __d_lookup() is used to try to get a quick answer and avoid the
+        * mutex.  A false-negative does no harm.
+        */
+       ret = __d_lookup(base, &this);
+       if (ret && unlikely(ret->d_flags & DCACHE_OP_REVALIDATE)) {
+               dput(ret);
+               ret = NULL;
+       }
+       if (ret)
+               return ret;
+
+       mutex_lock(&base->d_inode->i_mutex);
+       ret =  __lookup_hash(&this, base, 0);
+       mutex_unlock(&base->d_inode->i_mutex);
+       return ret;
+}
+EXPORT_SYMBOL(lookup_one_len_unlocked);
+
 int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
                 struct path *path, int *empty)
 {
@@ -2670,10 +2735,6 @@ static int may_open(struct path *path, int acc_mode, int flag)
        struct inode *inode = dentry->d_inode;
        int error;
 
-       /* O_PATH? */
-       if (!acc_mode)
-               return 0;
-
        if (!inode)
                return -ENOENT;
 
@@ -2695,7 +2756,7 @@ static int may_open(struct path *path, int acc_mode, int flag)
                break;
        }
 
-       error = inode_permission(inode, acc_mode);
+       error = inode_permission(inode, MAY_OPEN | acc_mode);
        if (error)
                return error;
 
@@ -2887,7 +2948,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
        if (*opened & FILE_CREATED) {
                WARN_ON(!(open_flag & O_CREAT));
                fsnotify_create(dir, dentry);
-               acc_mode = MAY_OPEN;
+               acc_mode = 0;
        }
        error = may_open(&file->f_path, acc_mode, open_flag);
        if (error)
@@ -3100,7 +3161,7 @@ retry_lookup:
                /* Don't check for write permission, don't truncate */
                open_flag &= ~O_TRUNC;
                will_truncate = false;
-               acc_mode = MAY_OPEN;
+               acc_mode = 0;
                path_to_nameidata(&path, nd);
                goto finish_open_created;
        }
@@ -3184,10 +3245,11 @@ finish_open:
                got_write = true;
        }
 finish_open_created:
-       error = may_open(&nd->path, acc_mode, open_flag);
-       if (error)
-               goto out;
-
+       if (likely(!(open_flag & O_PATH))) {
+               error = may_open(&nd->path, acc_mode, open_flag);
+               if (error)
+                       goto out;
+       }
        BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
        error = vfs_open(&nd->path, file, current_cred());
        if (!error) {
@@ -3274,7 +3336,7 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
                goto out2;
        audit_inode(nd->name, child, 0);
        /* Don't check for other permissions, the inode was just created */
-       error = may_open(&path, MAY_OPEN, op->open_flag);
+       error = may_open(&path, 0, op->open_flag);
        if (error)
                goto out2;
        file->f_path.mnt = path.mnt;
index 4d2c8f64b7bf03e4ca0817bcfa1c51a11c8891cb..a830e1463704b590b72947d313cd50b454555668 100644 (file)
@@ -2609,18 +2609,18 @@ static long exact_copy_from_user(void *to, const void __user * from,
        return n;
 }
 
-int copy_mount_options(const void __user * data, unsigned long *where)
+void *copy_mount_options(const void __user * data)
 {
        int i;
-       unsigned long page;
        unsigned long size;
+       char *copy;
 
-       *where = 0;
        if (!data)
-               return 0;
+               return NULL;
 
-       if (!(page = __get_free_page(GFP_KERNEL)))
-               return -ENOMEM;
+       copy = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!copy)
+               return ERR_PTR(-ENOMEM);
 
        /* We only care that *some* data at the address the user
         * gave us is valid.  Just in case, we'll zero
@@ -2631,15 +2631,14 @@ int copy_mount_options(const void __user * data, unsigned long *where)
        if (size > PAGE_SIZE)
                size = PAGE_SIZE;
 
-       i = size - exact_copy_from_user((void *)page, data, size);
+       i = size - exact_copy_from_user(copy, data, size);
        if (!i) {
-               free_page(page);
-               return -EFAULT;
+               kfree(copy);
+               return ERR_PTR(-EFAULT);
        }
        if (i != PAGE_SIZE)
-               memset((char *)page + i, 0, PAGE_SIZE - i);
-       *where = page;
-       return 0;
+               memset(copy + i, 0, PAGE_SIZE - i);
+       return copy;
 }
 
 char *copy_mount_string(const void __user *data)
@@ -2906,7 +2905,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
        int ret;
        char *kernel_type;
        char *kernel_dev;
-       unsigned long data_page;
+       void *options;
 
        kernel_type = copy_mount_string(type);
        ret = PTR_ERR(kernel_type);
@@ -2918,14 +2917,14 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
        if (IS_ERR(kernel_dev))
                goto out_dev;
 
-       ret = copy_mount_options(data, &data_page);
-       if (ret < 0)
+       options = copy_mount_options(data);
+       ret = PTR_ERR(options);
+       if (IS_ERR(options))
                goto out_data;
 
-       ret = do_mount(kernel_dev, dir_name, kernel_type, flags,
-               (void *) data_page);
+       ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
 
-       free_page(data_page);
+       kfree(options);
 out_data:
        kfree(kernel_dev);
 out_dev:
@@ -2949,9 +2948,9 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
        return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
 }
 
-int path_is_under(struct path *path1, struct path *path2)
+bool path_is_under(struct path *path1, struct path *path2)
 {
-       int res;
+       bool res;
        read_seqlock_excl(&mount_lock);
        res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);
        read_sequnlock_excl(&mount_lock);
index 00575d776d91f58576523d1fc30e558585a91ace..2246454dec7654b3570f3c52bb5264567e32064c 100644 (file)
@@ -823,7 +823,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
                } else
                        dchild = dget(dparent);
        } else
-               dchild = lookup_one_len(name, dparent, namlen);
+               dchild = lookup_one_len_unlocked(name, dparent, namlen);
        if (IS_ERR(dchild))
                return rv;
        if (d_mountpoint(dchild))
index 924416f91fdd95c5d7e80e1302a27fce57920084..d6ef0955a979ca0eb3a581d09a33d8fcc7a48fd1 100644 (file)
@@ -2858,14 +2858,14 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
        __be32 nfserr;
        int ignore_crossmnt = 0;
 
-       dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
+       dentry = lookup_one_len_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
        if (IS_ERR(dentry))
                return nfserrno(PTR_ERR(dentry));
        if (d_really_is_negative(dentry)) {
                /*
-                * nfsd_buffered_readdir drops the i_mutex between
-                * readdir and calling this callback, leaving a window
-                * where this directory entry could have gone away.
+                * we're not holding the i_mutex here, so there's
+                * a window where this directory entry could have gone
+                * away.
                 */
                dput(dentry);
                return nfserr_noent;
index 5411bf09b810b25e6ae7aae0f14406a0da6a7758..d41c149fae75e8c6b88c1295cfdb61c7f10950fe 100644 (file)
@@ -218,10 +218,16 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
                host_err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
                        goto out_nfserr;
-               /*
-                * check if we have crossed a mount point ...
-                */
                if (nfsd_mountpoint(dentry, exp)) {
+                       /*
+                        * We don't need the i_mutex after all.  It's
+                        * still possible we could open this (regular
+                        * files can be mountpoints too), but the
+                        * i_mutex is just there to prevent renames of
+                        * something that we might be about to delegate,
+                        * and a mountpoint won't be renamed:
+                        */
+                       fh_unlock(fhp);
                        if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
                                dput(dentry);
                                goto out_nfserr;
@@ -1817,7 +1823,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
        offset = *offsetp;
 
        while (1) {
-               struct inode *dir_inode = file_inode(file);
                unsigned int reclen;
 
                cdp->err = nfserr_eof; /* will be cleared on successful read */
@@ -1836,15 +1841,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
                if (!size)
                        break;
 
-               /*
-                * Various filldir functions may end up calling back into
-                * lookup_one_len() and the file system's ->lookup() method.
-                * These expect i_mutex to be held, as it would within readdir.
-                */
-               host_err = mutex_lock_killable(&dir_inode->i_mutex);
-               if (host_err)
-                       break;
-
                de = (struct buffered_dirent *)buf.dirent;
                while (size > 0) {
                        offset = de->offset;
@@ -1861,7 +1857,6 @@ static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func,
                        size -= reclen;
                        de = (struct buffered_dirent *)((char *)de + reclen);
                }
-               mutex_unlock(&dir_inode->i_mutex);
                if (size > 0) /* We bailed out early */
                        break;
 
index 354013ea22ec212001ef2c300fdf282ad39c611d..c7343844e6b62a7ca3c78f9f4fa12e59f97dfdbf 100644 (file)
@@ -1316,13 +1316,11 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
        }
 
        if (!s->s_root) {
-               char b[BDEVNAME_SIZE];
-
-               s_new = true;
+               s_new = true;
 
                /* New superblock instance created */
                s->s_mode = mode;
-               strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
+               snprintf(s->s_id, sizeof(s->s_id), "%pg", sd.bdev);
                sb_set_blocksize(s, block_size(sd.bdev));
 
                err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
index b6f1e96a7c0b331b3e5a5d9bb4c014c5c9edc54b..b25b1542c5304a74999db5ad52af57e89133a68e 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -887,7 +887,7 @@ EXPORT_SYMBOL(dentry_open);
 static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
 {
        int lookup_flags = 0;
-       int acc_mode;
+       int acc_mode = ACC_MODE(flags);
 
        if (flags & (O_CREAT | __O_TMPFILE))
                op->mode = (mode & S_IALLUGO) | S_IFREG;
@@ -909,7 +909,6 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
        if (flags & __O_TMPFILE) {
                if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
                        return -EINVAL;
-               acc_mode = MAY_OPEN | ACC_MODE(flags);
                if (!(acc_mode & MAY_WRITE))
                        return -EINVAL;
        } else if (flags & O_PATH) {
@@ -919,8 +918,6 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
                 */
                flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH;
                acc_mode = 0;
-       } else {
-               acc_mode = MAY_OPEN | ACC_MODE(flags);
        }
 
        op->open_flag = flags;
index 55e01f88eac9d1156e240700598fd9688c6c503e..2cf5d7e373757d631de6f9d8a174287d46058219 100644 (file)
@@ -2365,7 +2365,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
 {
        struct inode * inode = file_inode(file);
-       char *page;
+       void *page;
        ssize_t length;
        struct task_struct *task = get_proc_task(inode);
 
@@ -2380,14 +2380,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
        if (*ppos != 0)
                goto out;
 
-       length = -ENOMEM;
-       page = (char*)__get_free_page(GFP_TEMPORARY);
-       if (!page)
+       page = memdup_user(buf, count);
+       if (IS_ERR(page)) {
+               length = PTR_ERR(page);
                goto out;
-
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out_free;
+       }
 
        /* Guard against adverse ptrace interaction */
        length = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
@@ -2396,10 +2393,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 
        length = security_setprocattr(task,
                                      (char*)file->f_path.dentry->d_name.name,
-                                     (void*)page, count);
+                                     page, count);
        mutex_unlock(&task->signal->cred_guard_mutex);
 out_free:
-       free_page((unsigned long) page);
+       kfree(page);
 out:
        put_task_struct(task);
 out_no_task:
index 3c2a915c695a319708c2939c9bb8923b73508112..56afa5ef08f2dbca5f36f5feafa2a257bf525ab3 100644 (file)
@@ -258,6 +258,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
                                     name, len, instantiate, p,
                                     (void *)(unsigned long)fd))
                        goto out_fd_loop;
+               cond_resched();
                rcu_read_lock();
        }
        rcu_read_unlock();
index 8ebd9a3340852823b17f61af59f4dd6a65f1b35f..2256e7e23e678a11d2ab3fbaf1226a508f0ef1c8 100644 (file)
@@ -95,9 +95,9 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
 {
        struct proc_mounts *p = m->private;
        struct mount *r = real_mount(mnt);
-       int err = 0;
        struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
        struct super_block *sb = mnt_path.dentry->d_sb;
+       int err;
 
        if (sb->s_op->show_devname) {
                err = sb->s_op->show_devname(m, mnt_path.dentry);
@@ -131,16 +131,17 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
        struct mount *r = real_mount(mnt);
        struct super_block *sb = mnt->mnt_sb;
        struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
-       int err = 0;
+       int err;
 
        seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
                   MAJOR(sb->s_dev), MINOR(sb->s_dev));
-       if (sb->s_op->show_path)
+       if (sb->s_op->show_path) {
                err = sb->s_op->show_path(m, mnt->mnt_root);
-       else
+               if (err)
+                       goto out;
+       } else {
                seq_dentry(m, mnt->mnt_root, " \t\n\\");
-       if (err)
-               goto out;
+       }
        seq_putc(m, ' ');
 
        /* mountpoints outside of chroot jail will give SEQ_SKIP on this */
@@ -168,12 +169,13 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
        seq_puts(m, " - ");
        show_type(m, sb);
        seq_putc(m, ' ');
-       if (sb->s_op->show_devname)
+       if (sb->s_op->show_devname) {
                err = sb->s_op->show_devname(m, mnt->mnt_root);
-       else
+               if (err)
+                       goto out;
+       } else {
                mangle(m, r->mnt_devname ? r->mnt_devname : "none");
-       if (err)
-               goto out;
+       }
        seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw");
        err = show_sb_opts(m, sb);
        if (err)
@@ -191,7 +193,7 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
        struct mount *r = real_mount(mnt);
        struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
        struct super_block *sb = mnt_path.dentry->d_sb;
-       int err = 0;
+       int err;
 
        /* device */
        if (sb->s_op->show_devname) {
@@ -220,8 +222,7 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
        /* optional statistics */
        if (sb->s_op->show_stats) {
                seq_putc(m, ' ');
-               if (!err)
-                       err = sb->s_op->show_stats(m, mnt_path.dentry);
+               err = sb->s_op->show_stats(m, mnt_path.dentry);
        }
 
        seq_putc(m, '\n');
index 2116e74a83d3f34e94335e0ab2530c27ef9b972d..06b07d5a08fec4be6d83e9c92192963da6c8bc5c 100644 (file)
@@ -171,6 +171,45 @@ loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t si
 }
 EXPORT_SYMBOL(fixed_size_llseek);
 
+/**
+ * no_seek_end_llseek - llseek implementation for fixed-sized devices
+ * @file:      file structure to seek on
+ * @offset:    file offset to seek to
+ * @whence:    type of seek
+ *
+ */
+loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
+{
+       switch (whence) {
+       case SEEK_SET: case SEEK_CUR:
+               return generic_file_llseek_size(file, offset, whence,
+                                               ~0ULL, 0);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL(no_seek_end_llseek);
+
+/**
+ * no_seek_end_llseek_size - llseek implementation for fixed-sized devices
+ * @file:      file structure to seek on
+ * @offset:    file offset to seek to
+ * @whence:    type of seek
+ * @size:      maximal offset allowed
+ *
+ */
+loff_t no_seek_end_llseek_size(struct file *file, loff_t offset, int whence, loff_t size)
+{
+       switch (whence) {
+       case SEEK_SET: case SEEK_CUR:
+               return generic_file_llseek_size(file, offset, whence,
+                                               size, 0);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL(no_seek_end_llseek_size);
+
 /**
  * noop_llseek - No Operation Performed llseek implementation
  * @file:      file structure to seek on
index 9d6486d416a33308047e1f21a92cd9cf21f7c144..44c2bdced1c87fda2f0592d9939ba5d626dc4460 100644 (file)
@@ -618,12 +618,10 @@ static void release_buffer_page(struct buffer_head *bh)
 
 static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
 {
-       char b[BDEVNAME_SIZE];
-
        if (buffer_journaled(bh)) {
                reiserfs_warning(NULL, "clm-2084",
-                                "pinned buffer %lu:%s sent to disk",
-                                bh->b_blocknr, bdevname(bh->b_bdev, b));
+                                "pinned buffer %lu:%pg sent to disk",
+                                bh->b_blocknr, bh->b_bdev);
        }
        if (uptodate)
                set_buffer_uptodate(bh);
@@ -2387,11 +2385,10 @@ static int journal_read(struct super_block *sb)
        int replay_count = 0;
        int continue_replay = 1;
        int ret;
-       char b[BDEVNAME_SIZE];
 
        cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(sb);
-       reiserfs_info(sb, "checking transaction log (%s)\n",
-                     bdevname(journal->j_dev_bd, b));
+       reiserfs_info(sb, "checking transaction log (%pg)\n",
+                     journal->j_dev_bd);
        start = get_seconds();
 
        /*
@@ -2651,8 +2648,8 @@ static int journal_init_dev(struct super_block *super,
 
        set_blocksize(journal->j_dev_bd, super->s_blocksize);
        reiserfs_info(super,
-                     "journal_init_dev: journal device: %s\n",
-                     bdevname(journal->j_dev_bd, b));
+                     "journal_init_dev: journal device: %pg\n",
+                     journal->j_dev_bd);
        return 0;
 }
 
@@ -2724,7 +2721,6 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
        struct reiserfs_journal_header *jh;
        struct reiserfs_journal *journal;
        struct reiserfs_journal_list *jl;
-       char b[BDEVNAME_SIZE];
        int ret;
 
        journal = SB_JOURNAL(sb) = vzalloc(sizeof(struct reiserfs_journal));
@@ -2794,10 +2790,10 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
            && (le32_to_cpu(jh->jh_journal.jp_journal_magic) !=
                sb_jp_journal_magic(rs))) {
                reiserfs_warning(sb, "sh-460",
-                                "journal header magic %x (device %s) does "
+                                "journal header magic %x (device %pg) does "
                                 "not match to magic found in super block %x",
                                 jh->jh_journal.jp_journal_magic,
-                                bdevname(journal->j_dev_bd, b),
+                                journal->j_dev_bd,
                                 sb_jp_journal_magic(rs));
                brelse(bhjh);
                goto free_and_return;
@@ -2818,10 +2814,10 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
                journal->j_max_trans_age = commit_max_age;
        }
 
-       reiserfs_info(sb, "journal params: device %s, size %u, "
+       reiserfs_info(sb, "journal params: device %pg, size %u, "
                      "journal first block %u, max trans len %u, max batch %u, "
                      "max commit age %u, max trans age %u\n",
-                     bdevname(journal->j_dev_bd, b),
+                     journal->j_dev_bd,
                      SB_ONDISK_JOURNAL_SIZE(sb),
                      SB_ONDISK_JOURNAL_1st_BLOCK(sb),
                      journal->j_trans_max,
index ae1dc841db3af85bfef8391449cbea7ef2a13428..4f3f928076f3c237c3c582e5f764b8a6ca3d1aea 100644 (file)
@@ -139,11 +139,9 @@ static void sprintf_block_head(char *buf, struct buffer_head *bh)
 
 static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
 {
-       char b[BDEVNAME_SIZE];
-
        sprintf(buf,
-               "dev %s, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
-               bdevname(bh->b_bdev, b), bh->b_size,
+               "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
+               bh->b_bdev, bh->b_size,
                (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
                bh->b_state, bh->b_page,
                buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
@@ -530,7 +528,6 @@ static int print_super_block(struct buffer_head *bh)
            (struct reiserfs_super_block *)(bh->b_data);
        int skipped, data_blocks;
        char *version;
-       char b[BDEVNAME_SIZE];
 
        if (is_reiserfs_3_5(rs)) {
                version = "3.5";
@@ -543,7 +540,7 @@ static int print_super_block(struct buffer_head *bh)
                return 1;
        }
 
-       printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
+       printk("%pg\'s super block is in block %llu\n", bh->b_bdev,
               (unsigned long long)bh->b_blocknr);
        printk("Reiserfs version %s\n", version);
        printk("Block count %u\n", sb_block_count(rs));
index 621b9f381fe1faed2925d1117e13ee4452129730..fe999157dd97e6fc5c9b361d90db1d6fea8baa0e 100644 (file)
@@ -303,11 +303,10 @@ static int show_journal(struct seq_file *m, void *unused)
        struct reiserfs_sb_info *r = REISERFS_SB(sb);
        struct reiserfs_super_block *rs = r->s_rs;
        struct journal_params *jp = &rs->s_v1.s_journal;
-       char b[BDEVNAME_SIZE];
 
        seq_printf(m,           /* on-disk fields */
                   "jp_journal_1st_block: \t%i\n"
-                  "jp_journal_dev: \t%s[%x]\n"
+                  "jp_journal_dev: \t%pg[%x]\n"
                   "jp_journal_size: \t%i\n"
                   "jp_journal_trans_max: \t%i\n"
                   "jp_journal_magic: \t%i\n"
@@ -348,7 +347,7 @@ static int show_journal(struct seq_file *m, void *unused)
                   "prepare: \t%12lu\n"
                   "prepare_retry: \t%12lu\n",
                   DJP(jp_journal_1st_block),
-                  bdevname(SB_JOURNAL(sb)->j_dev_bd, b),
+                  SB_JOURNAL(sb)->j_dev_bd,
                   DJP(jp_journal_dev),
                   DJP(jp_journal_size),
                   DJP(jp_journal_trans_max),
index 015547330e88699dccb37fe1d4509e1dc07394f7..79d0d4953cada643890cb6fd62323fa07a9dede5 100644 (file)
@@ -778,8 +778,8 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait,
        return mask;
 }
 
-static int do_poll(unsigned int nfds,  struct poll_list *list,
-                  struct poll_wqueues *wait, struct timespec *end_time)
+static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
+                  struct timespec *end_time)
 {
        poll_table* pt = &wait->pt;
        ktime_t expire, *to = NULL;
@@ -908,7 +908,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
        }
 
        poll_initwait(&table);
-       fdcount = do_poll(nfds, head, &table, end_time);
+       fdcount = do_poll(head, &table, end_time);
        poll_freewait(&table);
 
        for (walk = head; walk; walk = walk->next) {
index 4cf700d50b4037e6c334b0647cdb81b816f9ef65..82bc0d64fc38d538b6482adf7d5d279318405069 100644 (file)
@@ -415,6 +415,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                         */
                        if (!page->mapping) {
                                unlock_page(page);
+retry_lookup:
                                page = find_or_create_page(mapping, index,
                                                mapping_gfp_mask(mapping));
 
@@ -439,13 +440,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                        error = mapping->a_ops->readpage(in, page);
                        if (unlikely(error)) {
                                /*
-                                * We really should re-lookup the page here,
-                                * but it complicates things a lot. Instead
-                                * lets just do what we already stored, and
-                                * we'll get it the next time we are called.
+                                * Re-lookup the page
                                 */
                                if (error == AOP_TRUNCATED_PAGE)
-                                       error = 0;
+                                       goto retry_lookup;
 
                                break;
                        }
index 5056babe00df93249465c22b8b6dc6d0ebc1723d..dded920cbc8f14da85efdefaeca147079aae59ac 100644 (file)
@@ -80,7 +80,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct squashfs_sb_info *msblk;
        struct squashfs_super_block *sblk = NULL;
-       char b[BDEVNAME_SIZE];
        struct inode *root;
        long long root_inode;
        unsigned short flags;
@@ -124,8 +123,8 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_magic = le32_to_cpu(sblk->s_magic);
        if (sb->s_magic != SQUASHFS_MAGIC) {
                if (!silent)
-                       ERROR("Can't find a SQUASHFS superblock on %s\n",
-                                               bdevname(sb->s_bdev, b));
+                       ERROR("Can't find a SQUASHFS superblock on %pg\n",
+                                               sb->s_bdev);
                goto failed_mount;
        }
 
@@ -178,7 +177,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
        msblk->inodes = le32_to_cpu(sblk->inodes);
        flags = le16_to_cpu(sblk->flags);
 
-       TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
+       TRACE("Found valid superblock on %pg\n", sb->s_bdev);
        TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
                                ? "un" : "");
        TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
index 954aeb80e202be0a40fc42eeca465c033ab1fc9a..cc658a20a29e10dc829ed4bdfe648a7acf1d7331 100644 (file)
@@ -1012,10 +1012,8 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
                blkdev_put(bdev, mode);
                down_write(&s->s_umount);
        } else {
-               char b[BDEVNAME_SIZE];
-
                s->s_mode = mode;
-               strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
                sb_set_blocksize(s, block_size(bdev));
                error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
                if (error) {
index d7f5037a17b5585676e8594498f59da94a087650..d5dd6c8b82a712085c105ec1c30f827c639ff614 100644 (file)
@@ -305,7 +305,6 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
 {
        int error;
        void *kvalue = NULL;
-       void *vvalue = NULL;    /* If non-NULL, we used vmalloc() */
        char kname[XATTR_NAME_MAX + 1];
 
        if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
@@ -322,10 +321,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
                        return -E2BIG;
                kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
                if (!kvalue) {
-                       vvalue = vmalloc(size);
-                       if (!vvalue)
+                       kvalue = vmalloc(size);
+                       if (!kvalue)
                                return -ENOMEM;
-                       kvalue = vvalue;
                }
                if (copy_from_user(kvalue, value, size)) {
                        error = -EFAULT;
@@ -338,10 +336,8 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
 
        error = vfs_setxattr(d, kname, kvalue, size, flags);
 out:
-       if (vvalue)
-               vfree(vvalue);
-       else
-               kfree(kvalue);
+       kvfree(kvalue);
+
        return error;
 }
 
@@ -409,7 +405,6 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
 {
        ssize_t error;
        void *kvalue = NULL;
-       void *vvalue = NULL;
        char kname[XATTR_NAME_MAX + 1];
 
        error = strncpy_from_user(kname, name, sizeof(kname));
@@ -423,10 +418,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
                        size = XATTR_SIZE_MAX;
                kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
                if (!kvalue) {
-                       vvalue = vmalloc(size);
-                       if (!vvalue)
+                       kvalue = vmalloc(size);
+                       if (!kvalue)
                                return -ENOMEM;
-                       kvalue = vvalue;
                }
        }
 
@@ -442,10 +436,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
                   than XATTR_SIZE_MAX bytes. Not possible. */
                error = -E2BIG;
        }
-       if (vvalue)
-               vfree(vvalue);
-       else
-               kfree(kvalue);
+
+       kvfree(kvalue);
+
        return error;
 }
 
@@ -502,17 +495,15 @@ listxattr(struct dentry *d, char __user *list, size_t size)
 {
        ssize_t error;
        char *klist = NULL;
-       char *vlist = NULL;     /* If non-NULL, we used vmalloc() */
 
        if (size) {
                if (size > XATTR_LIST_MAX)
                        size = XATTR_LIST_MAX;
                klist = kmalloc(size, __GFP_NOWARN | GFP_KERNEL);
                if (!klist) {
-                       vlist = vmalloc(size);
-                       if (!vlist)
+                       klist = vmalloc(size);
+                       if (!klist)
                                return -ENOMEM;
-                       klist = vlist;
                }
        }
 
@@ -525,10 +516,9 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                   than XATTR_LIST_MAX bytes. Not possible. */
                error = -E2BIG;
        }
-       if (vlist)
-               vfree(vlist);
-       else
-               kfree(klist);
+
+       kvfree(klist);
+
        return error;
 }
 
index 3243cdf97f33f2998de6d8207d1128093a0ec587..ace91e7c713e39f5b9e132d6e897aace0a1992c1 100644 (file)
@@ -1632,13 +1632,9 @@ xfs_setsize_buftarg(
        btp->bt_meta_sectormask = sectorsize - 1;
 
        if (set_blocksize(btp->bt_bdev, sectorsize)) {
-               char name[BDEVNAME_SIZE];
-
-               bdevname(btp->bt_bdev, name);
-
                xfs_warn(btp->bt_mount,
-                       "Cannot set_blocksize to %u on device %s",
-                       sectorsize, name);
+                       "Cannot set_blocksize to %u on device %pg",
+                       sectorsize, btp->bt_bdev);
                return -EINVAL;
        }
 
index ec43a24bf63d3937edb2e93603852757ded8c18c..731262c3fbb7b12952811981580961284500e7a3 100644 (file)
@@ -2307,9 +2307,9 @@ static inline void iterate_bdevs(void (*f)(struct block_device *, void *), void
 {
 }
 
-static inline int sb_is_blkdev_sb(struct super_block *sb)
+static inline bool sb_is_blkdev_sb(struct super_block *sb)
 {
-       return 0;
+       return false;
 }
 #endif
 extern int sync_filesystem(struct super_block *);
@@ -2387,7 +2387,7 @@ extern void init_special_inode(struct inode *, umode_t, dev_t);
 
 /* Invalid inode operations -- fs/bad_inode.c */
 extern void make_bad_inode(struct inode *);
-extern int is_bad_inode(struct inode *);
+extern bool is_bad_inode(struct inode *);
 
 #ifdef CONFIG_BLOCK
 /*
@@ -2548,8 +2548,8 @@ extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
  
 /* fs/dcache.c -- generic fs support functions */
-extern int is_subdir(struct dentry *, struct dentry *);
-extern int path_is_under(struct path *, struct path *);
+extern bool is_subdir(struct dentry *, struct dentry *);
+extern bool path_is_under(struct path *, struct path *);
 
 extern char *file_path(struct file *, char *, int);
 
@@ -2676,6 +2676,8 @@ extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
                int whence, loff_t maxsize, loff_t eof);
 extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
                int whence, loff_t size);
+extern loff_t no_seek_end_llseek_size(struct file *, loff_t, int, loff_t);
+extern loff_t no_seek_end_llseek(struct file *, loff_t, int);
 extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);
 
@@ -2978,7 +2980,7 @@ int __init get_filesystem_list(char *buf);
 #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \
                                            (flag & __FMODE_NONOTIFY)))
 
-static inline int is_sxid(umode_t mode)
+static inline bool is_sxid(umode_t mode)
 {
        return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP));
 }
index d8c6334cd15005c16162f57959e20b2e09f99d03..d0f25d81b46a6c2f488c34e2cd14e91c49fb8145 100644 (file)
@@ -77,6 +77,7 @@ extern struct dentry *kern_path_locked(const char *, struct path *);
 extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int);
 
 extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
+extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int);
 
 extern int follow_down_one(struct path *);
 extern int follow_down(struct path *);
index 9ef7795e65e40c5dfbee53726909fbcb2ce341b0..9eebc66d957a7f74cffd602372cff71d31473abc 100644 (file)
@@ -10,6 +10,7 @@
 
 extern char *strndup_user(const char __user *, long);
 extern void *memdup_user(const void __user *, size_t);
+extern void *memdup_user_nul(const void __user *, size_t);
 
 /*
  * Include machine specific inline routines
index dc6858d6639ed022d65129bdbb869ff7bcc05789..5faf89ac9ec0894a45eb2e35d9642d0affc5d16a 100644 (file)
@@ -2047,9 +2047,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
                  void *data)
 {
        int *i, vleft, first = 1, err = 0;
-       unsigned long page = 0;
        size_t left;
-       char *kbuf;
+       char *kbuf = NULL, *p;
        
        if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
                *lenp = 0;
@@ -2078,15 +2077,9 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
 
                if (left > PAGE_SIZE - 1)
                        left = PAGE_SIZE - 1;
-               page = __get_free_page(GFP_TEMPORARY);
-               kbuf = (char *) page;
-               if (!kbuf)
-                       return -ENOMEM;
-               if (copy_from_user(kbuf, buffer, left)) {
-                       err = -EFAULT;
-                       goto free;
-               }
-               kbuf[left] = 0;
+               p = kbuf = memdup_user_nul(buffer, left);
+               if (IS_ERR(kbuf))
+                       return PTR_ERR(kbuf);
        }
 
        for (; left && vleft--; i++, first=0) {
@@ -2094,11 +2087,11 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
                bool neg;
 
                if (write) {
-                       left -= proc_skip_spaces(&kbuf);
+                       left -= proc_skip_spaces(&p);
 
                        if (!left)
                                break;
-                       err = proc_get_long(&kbuf, &left, &lval, &neg,
+                       err = proc_get_long(&p, &left, &lval, &neg,
                                             proc_wspace_sep,
                                             sizeof(proc_wspace_sep), NULL);
                        if (err)
@@ -2125,10 +2118,9 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
        if (!write && !first && left && !err)
                err = proc_put_char(&buffer, &left, '\n');
        if (write && !err && left)
-               left -= proc_skip_spaces(&kbuf);
-free:
+               left -= proc_skip_spaces(&p);
        if (write) {
-               free_page(page);
+               kfree(kbuf);
                if (first)
                        return err ? : -EINVAL;
        }
@@ -2310,9 +2302,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
 {
        unsigned long *i, *min, *max;
        int vleft, first = 1, err = 0;
-       unsigned long page = 0;
        size_t left;
-       char *kbuf;
+       char *kbuf = NULL, *p;
 
        if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
                *lenp = 0;
@@ -2340,15 +2331,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
 
                if (left > PAGE_SIZE - 1)
                        left = PAGE_SIZE - 1;
-               page = __get_free_page(GFP_TEMPORARY);
-               kbuf = (char *) page;
-               if (!kbuf)
-                       return -ENOMEM;
-               if (copy_from_user(kbuf, buffer, left)) {
-                       err = -EFAULT;
-                       goto free;
-               }
-               kbuf[left] = 0;
+               p = kbuf = memdup_user_nul(buffer, left);
+               if (IS_ERR(kbuf))
+                       return PTR_ERR(kbuf);
        }
 
        for (; left && vleft--; i++, first = 0) {
@@ -2357,9 +2342,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
                if (write) {
                        bool neg;
 
-                       left -= proc_skip_spaces(&kbuf);
+                       left -= proc_skip_spaces(&p);
 
-                       err = proc_get_long(&kbuf, &left, &val, &neg,
+                       err = proc_get_long(&p, &left, &val, &neg,
                                             proc_wspace_sep,
                                             sizeof(proc_wspace_sep), NULL);
                        if (err)
@@ -2385,10 +2370,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
        if (!write && !first && left && !err)
                err = proc_put_char(&buffer, &left, '\n');
        if (write && !err)
-               left -= proc_skip_spaces(&kbuf);
-free:
+               left -= proc_skip_spaces(&p);
        if (write) {
-               free_page(page);
+               kfree(kbuf);
                if (first)
                        return err ? : -EINVAL;
        }
@@ -2650,34 +2634,27 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
        }
 
        if (write) {
-               unsigned long page = 0;
-               char *kbuf;
+               char *kbuf, *p;
 
                if (left > PAGE_SIZE - 1)
                        left = PAGE_SIZE - 1;
 
-               page = __get_free_page(GFP_TEMPORARY);
-               kbuf = (char *) page;
-               if (!kbuf)
-                       return -ENOMEM;
-               if (copy_from_user(kbuf, buffer, left)) {
-                       free_page(page);
-                       return -EFAULT;
-                }
-               kbuf[left] = 0;
+               p = kbuf = memdup_user_nul(buffer, left);
+               if (IS_ERR(kbuf))
+                       return PTR_ERR(kbuf);
 
                tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
                                     GFP_KERNEL);
                if (!tmp_bitmap) {
-                       free_page(page);
+                       kfree(kbuf);
                        return -ENOMEM;
                }
-               proc_skip_char(&kbuf, &left, '\n');
+               proc_skip_char(&p, &left, '\n');
                while (!err && left) {
                        unsigned long val_a, val_b;
                        bool neg;
 
-                       err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
+                       err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
                                             sizeof(tr_a), &c);
                        if (err)
                                break;
@@ -2688,12 +2665,12 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 
                        val_b = val_a;
                        if (left) {
-                               kbuf++;
+                               p++;
                                left--;
                        }
 
                        if (c == '-') {
-                               err = proc_get_long(&kbuf, &left, &val_b,
+                               err = proc_get_long(&p, &left, &val_b,
                                                     &neg, tr_b, sizeof(tr_b),
                                                     &c);
                                if (err)
@@ -2704,16 +2681,16 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
                                        break;
                                }
                                if (left) {
-                                       kbuf++;
+                                       p++;
                                        left--;
                                }
                        }
 
                        bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
                        first = 0;
-                       proc_skip_char(&kbuf, &left, '\n');
+                       proc_skip_char(&p, &left, '\n');
                }
-               free_page(page);
+               kfree(kbuf);
        } else {
                unsigned long bit_a, bit_b = 0;
 
index a990824c86044779c089156daea170412cc84e8e..2aeb6ffc0a1e8799570723d2619b49da084b2b17 100644 (file)
@@ -349,16 +349,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
        if (count >= BLK_TN_MAX_MSG)
                return -EINVAL;
 
-       msg = kmalloc(count + 1, GFP_KERNEL);
-       if (msg == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(msg, buffer, count)) {
-               kfree(msg);
-               return -EFAULT;
-       }
+       msg = memdup_user_nul(buffer, count);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
 
-       msg[count] = '\0';
        bt = filp->private_data;
        __trace_note_message(bt, "%s", msg);
        kfree(msg);
index 4f6ef6912e00173040867f6a68c52f010bbfd21d..f333e57c4614a2a6aaac04061003f73cd3a6d844 100644 (file)
@@ -1340,15 +1340,9 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
        if (cnt >= PAGE_SIZE)
                return -EINVAL;
 
-       buf = (char *)__get_free_page(GFP_TEMPORARY);
-       if (!buf)
-               return -ENOMEM;
-
-       if (copy_from_user(buf, ubuf, cnt)) {
-               free_page((unsigned long) buf);
-               return -EFAULT;
-       }
-       buf[cnt] = '\0';
+       buf = memdup_user_nul(ubuf, cnt);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        mutex_lock(&event_mutex);
        file = event_file_data(filp);
@@ -1356,7 +1350,7 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
                err = apply_event_filter(file, buf);
        mutex_unlock(&event_mutex);
 
-       free_page((unsigned long) buf);
+       kfree(buf);
        if (err < 0)
                return err;
 
@@ -1507,18 +1501,12 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
        if (cnt >= PAGE_SIZE)
                return -EINVAL;
 
-       buf = (char *)__get_free_page(GFP_TEMPORARY);
-       if (!buf)
-               return -ENOMEM;
-
-       if (copy_from_user(buf, ubuf, cnt)) {
-               free_page((unsigned long) buf);
-               return -EFAULT;
-       }
-       buf[cnt] = '\0';
+       buf = memdup_user_nul(ubuf, cnt);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
        err = apply_subsystem_event_filter(dir, buf);
-       free_page((unsigned long) buf);
+       kfree(buf);
        if (err < 0)
                return err;
 
index 42a4009fd75adadb4c110cfb0ef3824f9f935248..4b5e8ed68d77a9b711fefae80b6999b9d6eaf579 100644 (file)
@@ -237,28 +237,23 @@ static ssize_t event_trigger_regex_write(struct file *file,
        if (cnt >= PAGE_SIZE)
                return -EINVAL;
 
-       buf = (char *)__get_free_page(GFP_TEMPORARY);
-       if (!buf)
-               return -ENOMEM;
+       buf = memdup_user_nul(ubuf, cnt);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
 
-       if (copy_from_user(buf, ubuf, cnt)) {
-               free_page((unsigned long)buf);
-               return -EFAULT;
-       }
-       buf[cnt] = '\0';
        strim(buf);
 
        mutex_lock(&event_mutex);
        event_file = event_file_data(file);
        if (unlikely(!event_file)) {
                mutex_unlock(&event_mutex);
-               free_page((unsigned long)buf);
+               kfree(buf);
                return -ENODEV;
        }
        ret = trigger_process_regex(event_file, buf);
        mutex_unlock(&event_mutex);
 
-       free_page((unsigned long)buf);
+       kfree(buf);
        if (ret < 0)
                goto out;
 
index 88fefa68c5164c88e5ec2487c942b15e3914666b..9bafc211930c79fac444a77f6f075a04ccc7f980 100644 (file)
@@ -602,8 +602,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        struct uid_gid_map new_map;
        unsigned idx;
        struct uid_gid_extent *extent = NULL;
-       unsigned long page = 0;
-       char *kbuf, *pos, *next_line;
+       char *kbuf = NULL, *pos, *next_line;
        ssize_t ret = -EINVAL;
 
        /*
@@ -638,23 +637,18 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
                goto out;
 
-       /* Get a buffer */
-       ret = -ENOMEM;
-       page = __get_free_page(GFP_TEMPORARY);
-       kbuf = (char *) page;
-       if (!page)
-               goto out;
-
        /* Only allow < page size writes at the beginning of the file */
        ret = -EINVAL;
        if ((*ppos != 0) || (count >= PAGE_SIZE))
                goto out;
 
        /* Slurp in the user data */
-       ret = -EFAULT;
-       if (copy_from_user(kbuf, buf, count))
+       kbuf = memdup_user_nul(buf, count);
+       if (IS_ERR(kbuf)) {
+               ret = PTR_ERR(kbuf);
+               kbuf = NULL;
                goto out;
-       kbuf[count] = '\0';
+       }
 
        /* Parse the user data */
        ret = -EINVAL;
@@ -756,8 +750,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        ret = count;
 out:
        mutex_unlock(&userns_state_mutex);
-       if (page)
-               free_page(page);
+       kfree(kbuf);
        return ret;
 }
 
index e3952e9c8ec04256e656ada5ca39ccdd62843093..fe42b6ec3f0ce4913d70e298e624caa89fbf1903 100644 (file)
@@ -657,14 +657,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
                pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
                return -E2BIG;
        }
-       tmpbuf = kmalloc(len + 1, GFP_KERNEL);
-       if (!tmpbuf)
-               return -ENOMEM;
-       if (copy_from_user(tmpbuf, ubuf, len)) {
-               kfree(tmpbuf);
-               return -EFAULT;
-       }
-       tmpbuf[len] = '\0';
+       tmpbuf = memdup_user_nul(ubuf, len);
+       if (IS_ERR(tmpbuf))
+               return PTR_ERR(tmpbuf);
        vpr_info("read %d bytes from userspace\n", (int)len);
 
        ret = ddebug_exec_queries(tmpbuf, NULL);
index f9cee8e1233c0fe0f626fe2680ca4b9ff9d3153e..ac3f9476b7765bc23ddcaf3db2166d11cd85d24c 100644 (file)
@@ -31,6 +31,9 @@
 #include <linux/dcache.h>
 #include <linux/cred.h>
 #include <net/addrconf.h>
+#ifdef CONFIG_BLOCK
+#include <linux/blkdev.h>
+#endif
 
 #include <asm/page.h>          /* for PAGE_SIZE */
 #include <asm/sections.h>      /* for dereference_function_descriptor() */
@@ -613,6 +616,26 @@ char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_sp
        return buf;
 }
 
+#ifdef CONFIG_BLOCK
+static noinline_for_stack
+char *bdev_name(char *buf, char *end, struct block_device *bdev,
+               struct printf_spec spec, const char *fmt)
+{
+       struct gendisk *hd = bdev->bd_disk;
+       
+       buf = string(buf, end, hd->disk_name, spec);
+       if (bdev->bd_part->partno) {
+               if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) {
+                       if (buf < end)
+                               *buf = 'p';
+                       buf++;
+               }
+               buf = number(buf, end, bdev->bd_part->partno, spec);
+       }
+       return buf;
+}
+#endif
+
 static noinline_for_stack
 char *symbol_string(char *buf, char *end, void *ptr,
                    struct printf_spec spec, const char *fmt)
@@ -1443,6 +1466,7 @@ int kptr_restrict __read_mostly;
  *           (default assumed to be phys_addr_t, passed by reference)
  * - 'd[234]' For a dentry name (optionally 2-4 last components)
  * - 'D[234]' Same as 'd' but for a struct file
+ * - 'g' For block_device name (gendisk + partition number)
  * - 'C' For a clock, it prints the name (Common Clock Framework) or address
  *       (legacy clock framework) of the clock
  * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
@@ -1600,6 +1624,11 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
                return dentry_name(buf, end,
                                   ((const struct file *)ptr)->f_path.dentry,
                                   spec, fmt);
+#ifdef CONFIG_BLOCK
+       case 'g':
+               return bdev_name(buf, end, ptr, spec, fmt);
+#endif
+
        }
        spec.flags |= SMALL;
        if (spec.field_width == -1) {
index 9af1c12b310c7f092f030fc1a4303c287724b0a6..2d28f79300431422397f0c3d82f637bc9f8d5a87 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -176,6 +176,37 @@ char *strndup_user(const char __user *s, long n)
 }
 EXPORT_SYMBOL(strndup_user);
 
+/**
+ * memdup_user_nul - duplicate memory region from user space and NUL-terminate
+ *
+ * @src: source address in user space
+ * @len: number of bytes to copy
+ *
+ * Returns an ERR_PTR() on failure.
+ */
+void *memdup_user_nul(const void __user *src, size_t len)
+{
+       char *p;
+
+       /*
+        * Always use GFP_KERNEL, since copy_from_user() can sleep and
+        * cause pagefault, which makes it pointless to use GFP_NOFS
+        * or GFP_ATOMIC.
+        */
+       p = kmalloc_track_caller(len + 1, GFP_KERNEL);
+       if (!p)
+               return ERR_PTR(-ENOMEM);
+
+       if (copy_from_user(p, src, len)) {
+               kfree(p);
+               return ERR_PTR(-EFAULT);
+       }
+       p[len] = '\0';
+
+       return p;
+}
+EXPORT_SYMBOL(memdup_user_nul);
+
 void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
                struct vm_area_struct *prev, struct rb_node *rb_parent)
 {
index 6e70ddb158b4bc121a0f32e7a53fecf8125e8354..199bc76202d2552d23fe964f377bbf69eaf518b9 100644 (file)
@@ -105,7 +105,7 @@ static struct list_head virtio_chan_list;
 /* How many bytes left in this page. */
 static unsigned int rest_of_page(void *data)
 {
-       return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
+       return PAGE_SIZE - offset_in_page(data);
 }
 
 /**
@@ -143,7 +143,6 @@ static void p9_virtio_close(struct p9_client *client)
 static void req_done(struct virtqueue *vq)
 {
        struct virtio_chan *chan = vq->vdev->priv;
-       struct p9_fcall *rc;
        unsigned int len;
        struct p9_req_t *req;
        unsigned long flags;
@@ -152,8 +151,8 @@ static void req_done(struct virtqueue *vq)
 
        while (1) {
                spin_lock_irqsave(&chan->lock, flags);
-               rc = virtqueue_get_buf(chan->vq, &len);
-               if (rc == NULL) {
+               req = virtqueue_get_buf(chan->vq, &len);
+               if (req == NULL) {
                        spin_unlock_irqrestore(&chan->lock, flags);
                        break;
                }
@@ -161,9 +160,6 @@ static void req_done(struct virtqueue *vq)
                spin_unlock_irqrestore(&chan->lock, flags);
                /* Wakeup if anyone waiting for VirtIO ring space. */
                wake_up(chan->vc_wq);
-               p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc);
-               p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
-               req = p9_tag_lookup(chan->client, rc->tag);
                p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
        }
 }
@@ -284,7 +280,7 @@ req_retry:
        if (in)
                sgs[out_sgs + in_sgs++] = chan->sg + out;
 
-       err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
+       err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
                                GFP_ATOMIC);
        if (err < 0) {
                if (err == -ENOSPC) {
@@ -369,7 +365,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
                        return -ENOMEM;
 
                *need_drop = 0;
-               p -= (*offs = (unsigned long)p % PAGE_SIZE);
+               p -= (*offs = offset_in_page(p));
                for (index = 0; index < nr_pages; index++) {
                        if (is_vmalloc_addr(p))
                                (*pages)[index] = vmalloc_to_page(p);
@@ -469,7 +465,7 @@ req_retry_pinned:
        }
 
        BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
-       err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
+       err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
                                GFP_ATOMIC);
        if (err < 0) {
                if (err == -ENOSPC) {
index da3cc09f683e982a43269d166acfad0e05575020..3f6571651d32ebf9890ec0e6d28228e62655b71e 100644 (file)
@@ -896,15 +896,9 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
        if (optlen <= 0 || optlen > PAGE_SIZE - 1)
                return -EINVAL;
 
-       description = kmalloc(optlen + 1, GFP_KERNEL);
-       if (!description)
-               return -ENOMEM;
-
-       if (copy_from_user(description, optval, optlen)) {
-               kfree(description);
-               return -EFAULT;
-       }
-       description[optlen] = 0;
+       description = memdup_user_nul(optval, optlen);
+       if (IS_ERR(description))
+               return PTR_ERR(description);
 
        key = request_key(&key_type_rxrpc, description, NULL);
        if (IS_ERR(key)) {
@@ -933,15 +927,9 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
        if (optlen <= 0 || optlen > PAGE_SIZE - 1)
                return -EINVAL;
 
-       description = kmalloc(optlen + 1, GFP_KERNEL);
-       if (!description)
-               return -ENOMEM;
-
-       if (copy_from_user(description, optval, optlen)) {
-               kfree(description);
-               return -EFAULT;
-       }
-       description[optlen] = 0;
+       description = memdup_user_nul(optval, optlen);
+       if (IS_ERR(description))
+               return PTR_ERR(description);
 
        key = request_key(&key_type_keyring, description, NULL);
        if (IS_ERR(key)) {
index 3d2f5b45c8cbeb0b376749adab00985b7a636f6f..c2e3ccd4b51044ae368271f0b4bce9b6630271f5 100644 (file)
@@ -234,12 +234,13 @@ int __init integrity_read_file(const char *path, char **data)
        }
 
        rc = integrity_kernel_read(file, 0, buf, size);
-       if (rc < 0)
-               kfree(buf);
-       else if (rc != size)
-               rc = -EIO;
-       else
+       if (rc == size) {
                *data = buf;
+       } else {
+               kfree(buf);
+               if (rc >= 0)
+                       rc = -EIO;
+       }
 out:
        fput(file);
        return rc;
index c02da25d7b631992aa7841ca98250b08b48d8477..73c60baa90a4736de9b4598946b4407ef1e05d16 100644 (file)
@@ -147,23 +147,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
        ssize_t length;
        int new_value;
 
-       length = -ENOMEM;
        if (count >= PAGE_SIZE)
-               goto out;
+               return -ENOMEM;
 
        /* No partial writes. */
-       length = -EINVAL;
        if (*ppos != 0)
-               goto out;
-
-       length = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
+               return -EINVAL;
 
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out;
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
 
        length = -EINVAL;
        if (sscanf(page, "%d", &new_value) != 1)
@@ -186,7 +179,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
        }
        length = count;
 out:
-       free_page((unsigned long) page);
+       kfree(page);
        return length;
 }
 #else
@@ -275,27 +268,20 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
                                 size_t count, loff_t *ppos)
 
 {
-       char *page = NULL;
+       char *page;
        ssize_t length;
        int new_value;
 
-       length = -ENOMEM;
        if (count >= PAGE_SIZE)
-               goto out;
+               return -ENOMEM;
 
        /* No partial writes. */
-       length = -EINVAL;
        if (*ppos != 0)
-               goto out;
-
-       length = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
+               return -EINVAL;
 
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out;
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
 
        length = -EINVAL;
        if (sscanf(page, "%d", &new_value) != 1)
@@ -313,7 +299,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
 
        length = count;
 out:
-       free_page((unsigned long) page);
+       kfree(page);
        return length;
 }
 #else
@@ -611,31 +597,24 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
 static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
                                      size_t count, loff_t *ppos)
 {
-       char *page = NULL;
+       char *page;
        ssize_t length;
        unsigned int new_value;
 
        length = task_has_security(current, SECURITY__SETCHECKREQPROT);
        if (length)
-               goto out;
+               return length;
 
-       length = -ENOMEM;
        if (count >= PAGE_SIZE)
-               goto out;
+               return -ENOMEM;
 
        /* No partial writes. */
-       length = -EINVAL;
        if (*ppos != 0)
-               goto out;
-
-       length = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
+               return -EINVAL;
 
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out;
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
 
        length = -EINVAL;
        if (sscanf(page, "%u", &new_value) != 1)
@@ -644,7 +623,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
        selinux_checkreqprot = new_value ? 1 : 0;
        length = count;
 out:
-       free_page((unsigned long) page);
+       kfree(page);
        return length;
 }
 static const struct file_operations sel_checkreqprot_ops = {
@@ -1100,14 +1079,12 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
        if (*ppos != 0)
                goto out;
 
-       length = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
-
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page)) {
+               length = PTR_ERR(page);
+               page = NULL;
                goto out;
+       }
 
        length = -EINVAL;
        if (sscanf(page, "%d", &new_value) != 1)
@@ -1121,7 +1098,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
 
 out:
        mutex_unlock(&sel_mutex);
-       free_page((unsigned long) page);
+       kfree(page);
        return length;
 }
 
@@ -1154,14 +1131,12 @@ static ssize_t sel_commit_bools_write(struct file *filep,
        if (*ppos != 0)
                goto out;
 
-       length = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
-
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page)) {
+               length = PTR_ERR(page);
+               page = NULL;
                goto out;
+       }
 
        length = -EINVAL;
        if (sscanf(page, "%d", &new_value) != 1)
@@ -1176,7 +1151,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
 
 out:
        mutex_unlock(&sel_mutex);
-       free_page((unsigned long) page);
+       kfree(page);
        return length;
 }
 
@@ -1292,31 +1267,24 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
                                             size_t count, loff_t *ppos)
 
 {
-       char *page = NULL;
+       char *page;
        ssize_t ret;
        int new_value;
 
        ret = task_has_security(current, SECURITY__SETSECPARAM);
        if (ret)
-               goto out;
+               return ret;
 
-       ret = -ENOMEM;
        if (count >= PAGE_SIZE)
-               goto out;
+               return -ENOMEM;
 
        /* No partial writes. */
-       ret = -EINVAL;
        if (*ppos != 0)
-               goto out;
-
-       ret = -ENOMEM;
-       page = (char *)get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               goto out;
+               return -EINVAL;
 
-       ret = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out;
+       page = memdup_user_nul(buf, count);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
 
        ret = -EINVAL;
        if (sscanf(page, "%u", &new_value) != 1)
@@ -1326,7 +1294,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
 
        ret = count;
 out:
-       free_page((unsigned long)page);
+       kfree(page);
        return ret;
 }
 
index 94bd9e41c9ecb39ce3d432f9c3734a5db7e1b353..e249a66db53393ccf9e1e0c34bd27b4f529b800b 100644 (file)
@@ -497,14 +497,9 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
                }
        }
 
-       data = kmalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto out;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        /*
         * In case of parsing only part of user buf,
@@ -884,16 +879,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
            (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
                return -EINVAL;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto unlockedout;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
-       data[count] = '\0';
        rule = data;
        /*
         * Only allow one writer at a time. Writes should be
@@ -946,7 +935,6 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
 
 out:
        mutex_unlock(&smack_cipso_lock);
-unlockedout:
        kfree(data);
        return rc;
 }
@@ -1187,14 +1175,9 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
        if (count < SMK_NETLBLADDRMIN)
                return -EINVAL;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto free_data_out;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        smack = kzalloc(count + 1, GFP_KERNEL);
        if (smack == NULL) {
@@ -1202,8 +1185,6 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
                goto free_data_out;
        }
 
-       data[count] = '\0';
-
        rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
                &host[0], &host[1], &host[2], &host[3], &masks, smack);
        if (rc != 6) {
@@ -1454,14 +1435,9 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
        if (count < SMK_NETLBLADDRMIN)
                return -EINVAL;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto free_data_out;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        smack = kzalloc(count + 1, GFP_KERNEL);
        if (smack == NULL) {
@@ -1469,8 +1445,6 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
                goto free_data_out;
        }
 
-       data[count] = '\0';
-
        i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
                        &scanned[0], &scanned[1], &scanned[2], &scanned[3],
                        &scanned[4], &scanned[5], &scanned[6], &scanned[7],
@@ -1865,14 +1839,9 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
        if (!smack_privileged(CAP_MAC_ADMIN))
                return -EPERM;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto out;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        skp = smk_import_entry(data, count);
        if (IS_ERR(skp)) {
@@ -2041,14 +2010,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
        if (!smack_privileged(CAP_MAC_ADMIN))
                return -EPERM;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               kfree(data);
-               return -EFAULT;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        rc = smk_parse_label_list(data, &list_tmp);
        kfree(data);
@@ -2133,14 +2097,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
        if (!smack_privileged(CAP_MAC_ADMIN))
                return -EPERM;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               rc = -EFAULT;
-               goto freeout;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        /*
         * Clear the smack_unconfined on invalid label errors. This means
@@ -2696,19 +2655,15 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
        if (!smack_privileged(CAP_MAC_ADMIN))
                return -EPERM;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
-       if (copy_from_user(data, buf, count) != 0)
-               rc = -EFAULT;
-       else {
-               skp = smk_import_entry(data, count);
-               if (IS_ERR(skp))
-                       rc = PTR_ERR(skp);
-               else
-                       smack_syslog_label = skp;
-       }
+       skp = smk_import_entry(data, count);
+       if (IS_ERR(skp))
+               rc = PTR_ERR(skp);
+       else
+               smack_syslog_label = skp;
 
        kfree(data);
        return rc;
@@ -2798,14 +2753,9 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf,
        if (*ppos != 0)
                return -EINVAL;
 
-       data = kzalloc(count + 1, GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
-       if (copy_from_user(data, buf, count) != 0) {
-               kfree(data);
-               return -EFAULT;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
 
        rc = smk_parse_label_list(data, &list_tmp);
        kfree(data);
index 179a955b319df9f3952ee6d5e4ff22af13b7d76d..06ab41b1ff286ad4de93e996d15d1b180c48c830 100644 (file)
@@ -43,13 +43,9 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
        int error;
        if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
                return -ENOMEM;
-       data = kzalloc(count + 1, GFP_NOFS);
-       if (!data)
-               return -ENOMEM;
-       if (copy_from_user(data, buf, count)) {
-               error = -EFAULT;
-               goto out;
-       }
+       data = memdup_user_nul(buf, count);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
        tomoyo_normalize_line(data);
        if (tomoyo_correct_domain(data)) {
                const int idx = tomoyo_read_lock();
@@ -87,7 +83,6 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
                tomoyo_read_unlock(idx);
        } else
                error = -EINVAL;
-out:
        kfree(data);
        return error ? error : count;
 }