Merge git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
Linus Torvalds [Fri, 15 Feb 2008 05:23:19 +0000 (21:23 -0800)]
* git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86:
  x86: cpa, fix out of date comment
  KVM is not seen under X86 config with latest git (32 bit compile)
  x86: cpa: ensure page alignment
  x86: include proper prototypes for rodata_test
  x86: fix gart_iommu_init()
  x86: EFI set_memory_x()/set_memory_uc() fixes
  x86: make dump_pagetable() static
  x86: fix "BUG: sleeping function called from invalid context" in print_vma_addr()

140 files changed:
MAINTAINERS
arch/alpha/kernel/osf_sys.c
arch/blackfin/kernel/traps.c
arch/cris/arch-v10/lib/memset.c
arch/cris/arch-v32/lib/memset.c
arch/m68knommu/platform/5206/Makefile
arch/m68knommu/platform/5206e/Makefile
arch/m68knommu/platform/520x/Makefile
arch/m68knommu/platform/523x/Makefile
arch/m68knommu/platform/5249/Makefile
arch/m68knommu/platform/5272/Makefile
arch/m68knommu/platform/527x/Makefile
arch/m68knommu/platform/528x/Makefile
arch/m68knommu/platform/5307/Makefile
arch/m68knommu/platform/532x/Makefile
arch/m68knommu/platform/5407/Makefile
arch/m68knommu/platform/coldfire/Makefile
arch/m68knommu/platform/coldfire/entry.S
arch/m68knommu/platform/coldfire/timers.c
arch/mips/kernel/sysirix.c
arch/parisc/hpux/sys_hpux.c
arch/powerpc/Kconfig
arch/powerpc/boot/Makefile
arch/powerpc/boot/ps3-hvcall.S
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/process.c
arch/powerpc/kernel/vdso.c
arch/powerpc/oprofile/cell/spu_task_sync.c
arch/powerpc/platforms/512x/Kconfig
arch/powerpc/platforms/52xx/Kconfig
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/ras.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/cell/spufs/syscalls.c
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/iseries/vio.c
arch/sparc64/solaris/fs.c
arch/um/drivers/mconsole_kern.c
drivers/block/swim3.c
drivers/char/hvc_rtas.c
drivers/macintosh/mediabay.c
drivers/md/bitmap.c
drivers/md/dm-table.c
drivers/md/md.c
drivers/mtd/mtdsuper.c
drivers/oprofile/buffer_sync.c
drivers/pnp/pnpbios/core.c
drivers/ps3/ps3-lpm.c
drivers/ps3/ps3-sys-manager.c
drivers/usb/gadget/file_storage.c
fs/afs/mntpt.c
fs/autofs4/root.c
fs/binfmt_flat.c
fs/block_dev.c
fs/cifs/cifs_dfs_ref.c
fs/coda/pioctl.c
fs/compat.c
fs/compat_ioctl.c
fs/configfs/symlink.c
fs/dcache.c
fs/dcookies.c
fs/dquot.c
fs/ecryptfs/dentry.c
fs/ecryptfs/inode.c
fs/ecryptfs/main.c
fs/exec.c
fs/ext3/super.c
fs/ext4/super.c
fs/gfs2/ops_fstype.c
fs/inotify_user.c
fs/namei.c
fs/namespace.c
fs/nfs/namespace.c
fs/nfs/nfs4proc.c
fs/nfsctl.c
fs/nfsd/export.c
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsproc.c
fs/nfsd/nfsxdr.c
fs/nfsd/vfs.c
fs/open.c
fs/proc/base.c
fs/proc/internal.h
fs/proc/nommu.c
fs/proc/proc_sysctl.c
fs/proc/task_mmu.c
fs/proc/task_nommu.c
fs/reiserfs/super.c
fs/seq_file.c
fs/stat.c
fs/utimes.c
fs/xattr.c
fs/xfs/linux-2.6/xfs_ioctl.c
include/asm-m68knommu/cacheflush.h
include/asm-m68knommu/system.h
include/asm-powerpc/systbl.h
include/asm-powerpc/unistd.h
include/asm-ppc/page.h
include/linux/audit.h
include/linux/configfs.h
include/linux/dcache.h
include/linux/dcookies.h
include/linux/fs.h
include/linux/fs_struct.h
include/linux/module.h
include/linux/namei.h
include/linux/nfsd/export.h
include/linux/path.h [new file with mode: 0644]
include/linux/proc_fs.h
include/linux/seq_file.h
init/do_mounts.c
kernel/audit.c
kernel/audit_tree.c
kernel/auditfilter.c
kernel/auditsc.c
kernel/exit.c
kernel/fork.c
kernel/kmod.c
mm/memory.c
mm/mempolicy.c
mm/swapfile.c
net/sunrpc/rpc_pipe.c
net/unix/af_unix.c
scripts/kernel-doc
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
security/smack/smack_lsm.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_device.c
sound/core/sound.c
sound/core/timer.c
sound/ppc/daca.c
sound/ppc/tumbler.c

index 6680ec4..1d2edb4 100644 (file)
@@ -1255,8 +1255,8 @@ W:        http://linux-net.osdl.org/index.php/DCCP
 S:     Maintained
 
 DECnet NETWORK LAYER
-P:     Patrick Caulfield
-M:     patrick@tykepenguin.com
+P:     Christine Caulfield
+M:     christine.caulfield@googlemail.com
 W:     http://linux-decnet.sourceforge.net
 L:     linux-decnet-user@lists.sourceforge.net
 S:     Maintained
@@ -1318,8 +1318,8 @@ L:        linux-kernel@vger.kernel.org
 S:     Maintained
 
 DISTRIBUTED LOCK MANAGER
-P:     Patrick Caulfield
-M:     pcaulfie@redhat.com
+P:     Christine Caulfield
+M:     ccaulfie@redhat.com
 P:     David Teigland
 M:     teigland@redhat.com
 L:     cluster-devel@redhat.com
@@ -1616,6 +1616,7 @@ S:        Maintained
 FILESYSTEMS (VFS and infrastructure)
 P:     Alexander Viro
 M:     viro@zeniv.linux.org.uk
+L:     linux-fsdevel@vger.kernel.org
 S:     Maintained
 
 FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
index 973c5c3..8c71daf 100644 (file)
@@ -259,8 +259,8 @@ osf_statfs(char __user *path, struct osf_statfs __user *buffer, unsigned long bu
 
        retval = user_path_walk(path, &nd);
        if (!retval) {
-               retval = do_osf_statfs(nd.dentry, buffer, bufsiz);
-               path_release(&nd);
+               retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz);
+               path_put(&nd.path);
        }
        return retval;
 }
index 58717cb..56a67ab 100644 (file)
@@ -126,15 +126,13 @@ static void decode_address(char *buf, unsigned long address)
                        struct vm_area_struct *vma = vml->vma;
 
                        if (address >= vma->vm_start && address < vma->vm_end) {
+                               char _tmpbuf[256];
                                char *name = p->comm;
                                struct file *file = vma->vm_file;
-                               if (file) {
-                                       char _tmpbuf[256];
-                                       name = d_path(file->f_dentry,
-                                                     file->f_vfsmnt,
-                                                     _tmpbuf,
-                                                     sizeof(_tmpbuf));
-                               }
+
+                               if (file)
+                                       name = d_path(&file->f_path, _tmpbuf,
+                                                     sizeof(_tmpbuf));
 
                                /* FLAT does not have its text aligned to the start of
                                 * the map while FDPIC ELF does ...
index 42c1101..c94ea9b 100644 (file)
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*#                                                                         */
-/*# FUNCTION NAME: memset()                                                 */
-/*#                                                                         */
-/*# PARAMETERS:  void* dst;   Destination address.                          */
-/*#              int     c;   Value of byte to write.                       */
-/*#              int   len;   Number of bytes to write.                     */
-/*#                                                                         */
-/*# RETURNS:     dst.                                                       */
-/*#                                                                         */
-/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */
-/*#              Framework taken from memcpy.  This routine is              */
-/*#              very sensitive to compiler changes in register allocation. */
-/*#              Should really be rewritten to avoid this problem.          */
-/*#                                                                         */
-/*#-------------------------------------------------------------------------*/
-/*#                                                                         */
-/*# HISTORY                                                                 */
-/*#                                                                         */
-/*# DATE      NAME            CHANGES                                       */
-/*# ----      ----            -------                                       */
-/*# 990713    HP              Tired of watching this function (or           */
-/*#                           really, the nonoptimized generic              */
-/*#                           implementation) take up 90% of simulator      */
-/*#                           output.  Measurements needed.                 */
-/*#                                                                         */
-/*#-------------------------------------------------------------------------*/
-
-#include <linux/types.h>
-
-/* No, there's no macro saying 12*4, since it is "hard" to get it into
-   the asm in a good way.  Thus better to expose the problem everywhere.
-   */
-
-/* Assuming 1 cycle per dword written or read (ok, not really true), and
-   one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1)
-   so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */
-
-#define ZERO_BLOCK_SIZE (1*12*4)
-
-void *memset(void *pdst,
-             int c,
-             size_t plen)
+/* A memset for CRIS.
+   Copyright (C) 1999-2005 Axis Communications.
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Neither the name of Axis Communications nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+   COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.  */
+
+/* FIXME: This file should really only be used for reference, as the
+   result is somewhat depending on gcc generating what we expect rather
+   than what we describe.  An assembly file should be used instead.  */
+
+/* Note the multiple occurrence of the expression "12*4", including the
+   asm.  It is hard to get it into the asm in a good way.  Thus better to
+   expose the problem everywhere: no macro.  */
+
+/* Assuming one cycle per dword written or read (ok, not really true; the
+   world is not ideal), and one cycle per instruction, then 43+3*(n/48-1)
+   <= 24+24*(n/48-1) so n >= 45.7; n >= 0.9; we win on the first full
+   48-byte block to set.  */
+
+#define MEMSET_BY_BLOCK_THRESHOLD (1 * 48)
+
+/* No name ambiguities in this file.  */
+__asm__ (".syntax no_register_prefix");
+
+void *memset(void *pdst, int c, unsigned int plen)
 {
-  /* Ok.  Now we want the parameters put in special registers.
-     Make sure the compiler is able to make something useful of this. */
+  /* Now we want the parameters in special registers.  Make sure the
+     compiler does something usable with this.  */
 
   register char *return_dst __asm__ ("r10") = pdst;
   register int n __asm__ ("r12") = plen;
   register int lc __asm__ ("r11") = c;
 
-  /* Most apps use memset sanely.  Only those memsetting about 3..4
-     bytes or less get penalized compared to the generic implementation
-     - and that's not really sane use. */
+  /* Most apps use memset sanely.  Memsetting about 3..4 bytes or less get
+     penalized here compared to the generic implementation.  */
 
-  /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
-     they compile cascaded "x |= x << 8" sanely! */
-  __asm__("movu.b %0,$r13\n\t"
-          "lslq 8,$r13\n\t"
-         "move.b %0,$r13\n\t"
-         "move.d $r13,%0\n\t"
-         "lslq 16,$r13\n\t"
-         "or.d $r13,%0"
-          : "=r" (lc) : "0" (lc) : "r13");
+  /* This is fragile performancewise at best.  Check with newer GCC
+     releases, if they compile cascaded "x |= x << 8" to sane code.  */
+  __asm__("movu.b %0,r13                                               \n\
+          lslq 8,r13                                                   \n\
+          move.b %0,r13                                                \n\
+          move.d r13,%0                                                \n\
+          lslq 16,r13                                                  \n\
+          or.d r13,%0"
+          : "=r" (lc)          /* Inputs.  */
+         : "0" (lc)            /* Outputs.  */
+         : "r13");             /* Trash.  */
 
   {
     register char *dst __asm__ ("r13") = pdst;
 
-  /* This is NONPORTABLE, but since this whole routine is     */
-  /* grossly nonportable that doesn't matter.                 */
+    if (((unsigned long) pdst & 3) != 0
+       /* Oops! n = 0 must be a valid call, regardless of alignment.  */
+       && n >= 3)
+      {
+       if ((unsigned long) dst & 1)
+         {
+           *dst = (char) lc;
+           n--;
+           dst++;
+         }
 
-  if (((unsigned long) pdst & 3) != 0
-     /* Oops! n=0 must be a legal call, regardless of alignment. */
-      && n >= 3)
-  {
-    if ((unsigned long)dst & 1)
-    {
-      *dst = (char) lc;
-      n--;
-      dst++;
-    }
-
-    if ((unsigned long)dst & 2)
-    {
-      *(short *)dst = lc;
-      n -= 2;
-      dst += 2;
-    }
-  }
+       if ((unsigned long) dst & 2)
+         {
+           *(short *) dst = lc;
+           n -= 2;
+           dst += 2;
+         }
+      }
 
-  /* Now the fun part.  For the threshold value of this, check the equation
-     above. */
-  /* Decide which copying method to use. */
-  if (n >= ZERO_BLOCK_SIZE)
-  {
-    /* For large copies we use 'movem' */
-
-  /* It is not optimal to tell the compiler about clobbering any
-     registers; that will move the saving/restoring of those registers
-     to the function prologue/epilogue, and make non-movem sizes
-     suboptimal.
-
-      This method is not foolproof; it assumes that the "asm reg"
-     declarations at the beginning of the function really are used
-     here (beware: they may be moved to temporary registers).
-      This way, we do not have to save/move the registers around into
-     temporaries; we can safely use them straight away.
-
-      If you want to check that the allocation was right; then
-      check the equalities in the first comment.  It should say
-      "r13=r13, r12=r12, r11=r11" */
-    __asm__ volatile ("\n\
-       ;; Check that the following is true (same register names on     \n\
-       ;; both sides of equal sign, as in r8=r8):                      \n\
-       ;; %0=r13, %1=r12, %4=r11                                       \n\
-       ;;                                                              \n\
-       ;; Save the registers we'll clobber in the movem process        \n\
-       ;; on the stack.  Don't mention them to gcc, it will only be    \n\
-       ;; upset.                                                       \n\
-       subq    11*4,$sp                                                \n\
-       movem   $r10,[$sp]                                              \n\
+    /* Decide which setting method to use.  */
+    if (n >= MEMSET_BY_BLOCK_THRESHOLD)
+      {
+       /* It is not optimal to tell the compiler about clobbering any
+          registers; that will move the saving/restoring of those registers
+          to the function prologue/epilogue, and make non-block sizes
+          suboptimal.  */
+       __asm__ volatile
+         ("\
+          ;; GCC does promise correct register allocations, but let's  \n\
+          ;; make sure it keeps its promises.                          \n\
+          .ifnc %0-%1-%4,$r13-$r12-$r11                                \n\
+          .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\"     \n\
+          .endif                                                       \n\
+                                                                       \n\
+          ;; Save the registers we'll clobber in the movem process     \n\
+          ;; on the stack.  Don't mention them to gcc, it will only be \n\
+          ;; upset.                                                    \n\
+          subq    11*4,sp                                              \n\
+          movem   r10,[sp]                                             \n\
                                                                        \n\
-       move.d  $r11,$r0                                                \n\
-       move.d  $r11,$r1                                                \n\
-       move.d  $r11,$r2                                                \n\
-       move.d  $r11,$r3                                                \n\
-       move.d  $r11,$r4                                                \n\
-       move.d  $r11,$r5                                                \n\
-       move.d  $r11,$r6                                                \n\
-       move.d  $r11,$r7                                                \n\
-       move.d  $r11,$r8                                                \n\
-       move.d  $r11,$r9                                                \n\
-       move.d  $r11,$r10                                               \n\
+          move.d  r11,r0                                               \n\
+          move.d  r11,r1                                               \n\
+          move.d  r11,r2                                               \n\
+          move.d  r11,r3                                               \n\
+          move.d  r11,r4                                               \n\
+          move.d  r11,r5                                               \n\
+          move.d  r11,r6                                               \n\
+          move.d  r11,r7                                               \n\
+          move.d  r11,r8                                               \n\
+          move.d  r11,r9                                               \n\
+          move.d  r11,r10                                              \n\
                                                                        \n\
-       ;; Now we've got this:                                          \n\
-       ;; r13 - dst                                                    \n\
-       ;; r12 - n                                                      \n\
+          ;; Now we've got this:                                       \n\
+          ;; r13 - dst                                                 \n\
+          ;; r12 - n                                                   \n\
                                                                        \n\
-       ;; Update n for the first loop                                  \n\
-       subq    12*4,$r12                                               \n\
+          ;; Update n for the first loop                               \n\
+          subq    12*4,r12                                             \n\
 0:                                                                     \n\
-       subq    12*4,$r12                                               \n\
-       bge     0b                                                      \n\
-       movem   $r11,[$r13+]                                            \n\
+"
+#ifdef __arch_common_v10_v32
+          /* Cater to branch offset difference between v32 and v10.  We
+             assume the branch below has an 8-bit offset.  */
+"         setf\n"
+#endif
+"         subq   12*4,r12                                              \n\
+          bge     0b                                                   \n\
+          movem        r11,[r13+]                                      \n\
                                                                        \n\
-       addq    12*4,$r12 ;; compensate for last loop underflowing n    \n\
+          ;; Compensate for last loop underflowing n.                  \n\
+          addq   12*4,r12                                              \n\
                                                                        \n\
-       ;; Restore registers from stack                                 \n\
-       movem   [$sp+],$r10"
+          ;; Restore registers from stack.                             \n\
+          movem [sp+],r10"
 
-     /* Outputs */ : "=r" (dst), "=r" (n)
-     /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
+          /* Outputs.  */
+          : "=r" (dst), "=r" (n)
 
-  }
+          /* Inputs.  */
+          : "0" (dst), "1" (n), "r" (lc));
+      }
+
+    /* An ad-hoc unroll, used for 4*12-1..16 bytes. */
+    while (n >= 16)
+      {
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       n -= 16;
+      }
 
-    /* Either we directly starts copying, using dword copying
-       in a loop, or we copy as much as possible with 'movem'
-       and then the last block (<44 bytes) is copied here.
-       This will work since 'movem' will have updated src,dst,n. */
-
-    while ( n >= 16 )
-    {
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      n -= 16;
-    }
-
-    /* A switch() is definitely the fastest although it takes a LOT of code.
-     * Particularly if you inline code this.
-     */
     switch (n)
-    {
+      {
       case 0:
         break;
+
       case 1:
-        *(char*)dst = (char) lc;
+        *dst = (char) lc;
         break;
+
       case 2:
-        *(short*)dst = (short) lc;
+        *(short *) dst = (short) lc;
         break;
+
       case 3:
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 4:
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc;
         break;
+
       case 5:
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 6:
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 7:
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 8:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc;
         break;
+
       case 9:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 10:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 11:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 12:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc;
         break;
+
       case 13:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 14:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 15:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
-    }
+      }
   }
 
-  return return_dst; /* destination pointer. */
-} /* memset() */
+  return return_dst;
+}
index ffca121..c94ea9b 100644 (file)
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*#                                                                         */
-/*# FUNCTION NAME: memset()                                                 */
-/*#                                                                         */
-/*# PARAMETERS:  void* dst;   Destination address.                          */
-/*#              int     c;   Value of byte to write.                       */
-/*#              int   len;   Number of bytes to write.                     */
-/*#                                                                         */
-/*# RETURNS:     dst.                                                       */
-/*#                                                                         */
-/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */
-/*#              Framework taken from memcpy.  This routine is              */
-/*#              very sensitive to compiler changes in register allocation. */
-/*#              Should really be rewritten to avoid this problem.          */
-/*#                                                                         */
-/*#-------------------------------------------------------------------------*/
-/*#                                                                         */
-/*# HISTORY                                                                 */
-/*#                                                                         */
-/*# DATE      NAME            CHANGES                                       */
-/*# ----      ----            -------                                       */
-/*# 990713    HP              Tired of watching this function (or           */
-/*#                           really, the nonoptimized generic              */
-/*#                           implementation) take up 90% of simulator      */
-/*#                           output.  Measurements needed.                 */
-/*#                                                                         */
-/*#-------------------------------------------------------------------------*/
-
-#include <linux/types.h>
-
-/* No, there's no macro saying 12*4, since it is "hard" to get it into
-   the asm in a good way.  Thus better to expose the problem everywhere.
-   */
-
-/* Assuming 1 cycle per dword written or read (ok, not really true), and
-   one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1)
-   so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */
-
-#define ZERO_BLOCK_SIZE (1*12*4)
-
-void *memset(void *pdst,
-             int c,
-             size_t plen)
+/* A memset for CRIS.
+   Copyright (C) 1999-2005 Axis Communications.
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Neither the name of Axis Communications nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+   COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.  */
+
+/* FIXME: This file should really only be used for reference, as the
+   result is somewhat depending on gcc generating what we expect rather
+   than what we describe.  An assembly file should be used instead.  */
+
+/* Note the multiple occurrence of the expression "12*4", including the
+   asm.  It is hard to get it into the asm in a good way.  Thus better to
+   expose the problem everywhere: no macro.  */
+
+/* Assuming one cycle per dword written or read (ok, not really true; the
+   world is not ideal), and one cycle per instruction, then 43+3*(n/48-1)
+   <= 24+24*(n/48-1) so n >= 45.7; n >= 0.9; we win on the first full
+   48-byte block to set.  */
+
+#define MEMSET_BY_BLOCK_THRESHOLD (1 * 48)
+
+/* No name ambiguities in this file.  */
+__asm__ (".syntax no_register_prefix");
+
+void *memset(void *pdst, int c, unsigned int plen)
 {
-  /* Ok.  Now we want the parameters put in special registers.
-     Make sure the compiler is able to make something useful of this. */
+  /* Now we want the parameters in special registers.  Make sure the
+     compiler does something usable with this.  */
 
   register char *return_dst __asm__ ("r10") = pdst;
   register int n __asm__ ("r12") = plen;
   register int lc __asm__ ("r11") = c;
 
-  /* Most apps use memset sanely.  Only those memsetting about 3..4
-     bytes or less get penalized compared to the generic implementation
-     - and that's not really sane use. */
+  /* Most apps use memset sanely.  Memsetting about 3..4 bytes or less get
+     penalized here compared to the generic implementation.  */
 
-  /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
-     they compile cascaded "x |= x << 8" sanely! */
-  __asm__("movu.b %0,$r13      \n\
-           lslq 8,$r13         \n\
-          move.b %0,$r13       \n\
-          move.d $r13,%0       \n\
-          lslq 16,$r13         \n\
-          or.d $r13,%0"
-          : "=r" (lc) : "0" (lc) : "r13");
+  /* This is fragile performancewise at best.  Check with newer GCC
+     releases, if they compile cascaded "x |= x << 8" to sane code.  */
+  __asm__("movu.b %0,r13                                               \n\
+          lslq 8,r13                                                   \n\
+          move.b %0,r13                                                \n\
+          move.d r13,%0                                                \n\
+          lslq 16,r13                                                  \n\
+          or.d r13,%0"
+          : "=r" (lc)          /* Inputs.  */
+         : "0" (lc)            /* Outputs.  */
+         : "r13");             /* Trash.  */
 
   {
     register char *dst __asm__ ("r13") = pdst;
 
-  /* This is NONPORTABLE, but since this whole routine is     */
-  /* grossly nonportable that doesn't matter.                 */
+    if (((unsigned long) pdst & 3) != 0
+       /* Oops! n = 0 must be a valid call, regardless of alignment.  */
+       && n >= 3)
+      {
+       if ((unsigned long) dst & 1)
+         {
+           *dst = (char) lc;
+           n--;
+           dst++;
+         }
 
-  if (((unsigned long) pdst & 3) != 0
-     /* Oops! n=0 must be a legal call, regardless of alignment. */
-      && n >= 3)
-  {
-    if ((unsigned long)dst & 1)
-    {
-      *dst = (char) lc;
-      n--;
-      dst++;
-    }
-
-    if ((unsigned long)dst & 2)
-    {
-      *(short *)dst = lc;
-      n -= 2;
-      dst += 2;
-    }
-  }
+       if ((unsigned long) dst & 2)
+         {
+           *(short *) dst = lc;
+           n -= 2;
+           dst += 2;
+         }
+      }
 
-  /* Now the fun part.  For the threshold value of this, check the equation
-     above. */
-  /* Decide which copying method to use. */
-  if (n >= ZERO_BLOCK_SIZE)
-  {
-    /* For large copies we use 'movem' */
-
-  /* It is not optimal to tell the compiler about clobbering any
-     registers; that will move the saving/restoring of those registers
-     to the function prologue/epilogue, and make non-movem sizes
-     suboptimal.
-
-      This method is not foolproof; it assumes that the "asm reg"
-     declarations at the beginning of the function really are used
-     here (beware: they may be moved to temporary registers).
-      This way, we do not have to save/move the registers around into
-     temporaries; we can safely use them straight away.
-
-      If you want to check that the allocation was right; then
-      check the equalities in the first comment.  It should say
-      "r13=r13, r12=r12, r11=r11" */
-    __asm__ volatile ("                                                        \n\
-        ;; Check that the register asm declaration got right.          \n\
-        ;; The GCC manual says it will work, but there *has* been bugs.        \n\
-       .ifnc %0-%1-%4,$r13-$r12-$r11                                   \n\
-       .err                                                            \n\
-       .endif                                                          \n\
+    /* Decide which setting method to use.  */
+    if (n >= MEMSET_BY_BLOCK_THRESHOLD)
+      {
+       /* It is not optimal to tell the compiler about clobbering any
+          registers; that will move the saving/restoring of those registers
+          to the function prologue/epilogue, and make non-block sizes
+          suboptimal.  */
+       __asm__ volatile
+         ("\
+          ;; GCC does promise correct register allocations, but let's  \n\
+          ;; make sure it keeps its promises.                          \n\
+          .ifnc %0-%1-%4,$r13-$r12-$r11                                \n\
+          .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\"     \n\
+          .endif                                                       \n\
                                                                        \n\
-       ;; Save the registers we'll clobber in the movem process        \n\
-       ;; on the stack.  Don't mention them to gcc, it will only be    \n\
-       ;; upset.                                                       \n\
-       subq    11*4,$sp                                                \n\
-        movem   $r10,[$sp]                                             \n\
+          ;; Save the registers we'll clobber in the movem process     \n\
+          ;; on the stack.  Don't mention them to gcc, it will only be \n\
+          ;; upset.                                                    \n\
+          subq    11*4,sp                                              \n\
+          movem   r10,[sp]                                             \n\
                                                                        \n\
-        move.d  $r11,$r0                                               \n\
-        move.d  $r11,$r1                                               \n\
-        move.d  $r11,$r2                                               \n\
-        move.d  $r11,$r3                                               \n\
-        move.d  $r11,$r4                                               \n\
-        move.d  $r11,$r5                                               \n\
-        move.d  $r11,$r6                                               \n\
-        move.d  $r11,$r7                                               \n\
-        move.d  $r11,$r8                                               \n\
-        move.d  $r11,$r9                                               \n\
-        move.d  $r11,$r10                                              \n\
+          move.d  r11,r0                                               \n\
+          move.d  r11,r1                                               \n\
+          move.d  r11,r2                                               \n\
+          move.d  r11,r3                                               \n\
+          move.d  r11,r4                                               \n\
+          move.d  r11,r5                                               \n\
+          move.d  r11,r6                                               \n\
+          move.d  r11,r7                                               \n\
+          move.d  r11,r8                                               \n\
+          move.d  r11,r9                                               \n\
+          move.d  r11,r10                                              \n\
                                                                        \n\
-        ;; Now we've got this:                                         \n\
-       ;; r13 - dst                                                    \n\
-       ;; r12 - n                                                      \n\
+          ;; Now we've got this:                                       \n\
+          ;; r13 - dst                                                 \n\
+          ;; r12 - n                                                   \n\
                                                                        \n\
-        ;; Update n for the first loop                                 \n\
-        subq    12*4,$r12                                              \n\
+          ;; Update n for the first loop                               \n\
+          subq    12*4,r12                                             \n\
 0:                                                                     \n\
-        subq   12*4,$r12                                               \n\
-        bge     0b                                                     \n\
-       movem   $r11,[$r13+]                                            \n\
+"
+#ifdef __arch_common_v10_v32
+          /* Cater to branch offset difference between v32 and v10.  We
+             assume the branch below has an 8-bit offset.  */
+"         setf\n"
+#endif
+"         subq   12*4,r12                                              \n\
+          bge     0b                                                   \n\
+          movem        r11,[r13+]                                      \n\
                                                                        \n\
-        addq   12*4,$r12  ;; compensate for last loop underflowing n   \n\
+          ;; Compensate for last loop underflowing n.                  \n\
+          addq   12*4,r12                                              \n\
                                                                        \n\
-       ;; Restore registers from stack                                 \n\
-        movem [$sp+],$r10"
+          ;; Restore registers from stack.                             \n\
+          movem [sp+],r10"
 
-     /* Outputs */ : "=r" (dst), "=r" (n)
-     /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
-  }
+          /* Outputs.  */
+          : "=r" (dst), "=r" (n)
+
+          /* Inputs.  */
+          : "0" (dst), "1" (n), "r" (lc));
+      }
+
+    /* An ad-hoc unroll, used for 4*12-1..16 bytes. */
+    while (n >= 16)
+      {
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       *(long *) dst = lc; dst += 4;
+       n -= 16;
+      }
 
-    /* Either we directly starts copying, using dword copying
-       in a loop, or we copy as much as possible with 'movem'
-       and then the last block (<44 bytes) is copied here.
-       This will work since 'movem' will have updated src,dst,n. */
-
-    while ( n >= 16 )
-    {
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      *((long*)dst)++ = lc;
-      n -= 16;
-    }
-
-    /* A switch() is definitely the fastest although it takes a LOT of code.
-     * Particularly if you inline code this.
-     */
     switch (n)
-    {
+      {
       case 0:
         break;
+
       case 1:
-        *(char*)dst = (char) lc;
+        *dst = (char) lc;
         break;
+
       case 2:
-        *(short*)dst = (short) lc;
+        *(short *) dst = (short) lc;
         break;
+
       case 3:
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 4:
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc;
         break;
+
       case 5:
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 6:
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 7:
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 8:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc;
         break;
+
       case 9:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 10:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 11:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
+
       case 12:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc;
         break;
+
       case 13:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *dst = (char) lc;
         break;
+
       case 14:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *(short*)dst = (short) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc;
         break;
+
       case 15:
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((long*)dst)++ = lc;
-        *((short*)dst)++ = (short) lc;
-        *(char*)dst = (char) lc;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(long *) dst = lc; dst += 4;
+        *(short *) dst = (short) lc; dst += 2;
+        *dst = (char) lc;
         break;
-    }
+      }
   }
 
-  return return_dst; /* destination pointer. */
-} /* memset() */
+  return return_dst;
+}
index c7bb0ce..a439d9a 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index c7bb0ce..a439d9a 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index 31b4eb5..a50e76a 100644 (file)
@@ -12,8 +12,6 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
index ac9fbec..5694d59 100644 (file)
@@ -12,8 +12,6 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
index c7bb0ce..a439d9a 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index 7475c38..26135d9 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index 7475c38..26135d9 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index 7475c38..26135d9 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index 580fd66..cfd5868 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y  += config.o
 
index 475b928..e431912 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 #obj-y := config.o usb-mcf532x.o spi-mcf532x.o
 obj-y := config.o
index 68633b2..e6035e7 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-y := config.o
 
index e5fff29..40cf20b 100644 (file)
@@ -12,9 +12,7 @@
 # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
 #
 
-ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
-endif
+asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o
 obj-$(CONFIG_M5206)    += timers.o
index b333731..111b66d 100644 (file)
@@ -197,14 +197,13 @@ ENTRY(fasthandler)
        RESTORE_LOCAL
 
 ENTRY(ret_from_interrupt)
-       jeq     2f
-1:
-       RESTORE_ALL
-2:
        moveb   %sp@(PT_SR),%d0
        andl    #0x7,%d0
-       jhi     1b
+       jeq     1f
 
+       RESTORE_ALL
+
+1:
        /* check if we need to do software interrupts */
        movel   irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
        jeq     ret_from_exception
index a60213e..ba5a9f3 100644 (file)
@@ -148,25 +148,32 @@ irqreturn_t coldfire_profile_tick(int irq, void *dummy)
        /* Reset ColdFire timer2 */
        __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
        if (current->pid)
-               profile_tick(CPU_PROFILING, regs);
+               profile_tick(CPU_PROFILING);
        return IRQ_HANDLED;
 }
 
 /***************************************************************************/
 
+static struct irqaction coldfire_profile_irq = {
+       .name    = "profile timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER,
+       .handler = coldfire_profile_tick,
+};
+
 void coldfire_profile_init(void)
 {
-       printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
+       printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
+              PROFILEHZ);
+
+       setup_irq(mcf_profilevector, &coldfire_profile_irq);
 
        /* Set up TIMER 2 as high speed profile clock */
        __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
 
-       __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
+       __raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
        __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
                MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
 
-       request_irq(mcf_profilevector, coldfire_profile_tick,
-               (IRQF_DISABLED | IRQ_FLG_FAST), "profile timer", NULL);
        mcf_settimericr(2, 7);
 }
 
index d70c4e0..672fba8 100644 (file)
@@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __user *path,
        if (error)
                goto out;
 
-       error = vfs_statfs(nd.dentry, &kbuf);
+       error = vfs_statfs(nd.path.dentry, &kbuf);
        if (error)
                goto dput_and_out;
 
@@ -711,7 +711,7 @@ asmlinkage int irix_statfs(const char __user *path,
        }
 
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
        error = user_path_walk(fname, &nd);
        if (error)
                goto out;
-       error = vfs_statfs(nd.dentry, &kbuf);
+       error = vfs_statfs(nd.path.dentry, &kbuf);
        if (error)
                goto dput_and_out;
 
@@ -1385,7 +1385,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf)
                error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *
        error = user_path_walk(fname, &nd);
        if (error)
                goto out;
-       error = vfs_statfs(nd.dentry, &kbuf);
+       error = vfs_statfs(nd.path.dentry, &kbuf);
        if (error)
                goto dput_and_out;
 
@@ -1636,7 +1636,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *
                error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
index 3e025df..0c5b9da 100644 (file)
@@ -219,10 +219,10 @@ asmlinkage long hpux_statfs(const char __user *path,
        error = user_path_walk(path, &nd);
        if (!error) {
                struct hpux_statfs tmp;
-               error = vfs_statfs_hpux(nd.dentry, &tmp);
+               error = vfs_statfs_hpux(nd.path.dentry, &tmp);
                if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                        error = -EFAULT;
-               path_release(&nd);
+               path_put(&nd.path);
        }
        return error;
 }
index 485513c..5b8d838 100644 (file)
@@ -442,10 +442,6 @@ config SECCOMP
 
          If unsure, say Y. Only embedded should say N here.
 
-config WANT_DEVICE_TREE
-       bool
-       default n
-
 endmenu
 
 config ISA_DMA_API
index 49797a4..63d07cc 100644 (file)
@@ -147,6 +147,8 @@ HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
 targets += dtc-src/dtc-parser.tab.c
 targets += dtc-src/dtc-lexer.lex.c
 
+clean-files += dtc-src/dtc-parser.tab.h
+
 ifdef DTC_GENPARSER
 BISON = bison
 FLEX = flex
index 585965f..d6068f1 100644 (file)
 .macro STORE_REGS_5_2
        lwz r11, 16(r1)
        std r4, 0(r11)
-       lwz r11, 24(r1)
+       lwz r11, 20(r1)
        std r5, 0(r11)
 .endm
 
index 0662ae4..c1baf9d 100644 (file)
@@ -104,3 +104,5 @@ quiet_cmd_systbl_chk = CALL    $<
 PHONY += systbl_chk
 systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
        $(call cmd,systbl_chk)
+
+clean-files := vmlinux.lds
index b9d8837..4846bf5 100644 (file)
@@ -462,7 +462,7 @@ void show_regs(struct pt_regs * regs)
               current, task_pid_nr(current), current->comm, task_thread_info(current));
 
 #ifdef CONFIG_SMP
-       printk(" CPU: %d", smp_processor_id());
+       printk(" CPU: %d", raw_smp_processor_id());
 #endif /* CONFIG_SMP */
 
        for (i = 0;  i < 32;  i++) {
index 3702df7..d3437c4 100644 (file)
@@ -336,9 +336,9 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib,
        return sym->st_value - VDSO32_LBASE;
 }
 
-static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
-                               struct lib64_elfinfo *v64,
-                               const char *orig, const char *fix)
+static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,
+                                      struct lib64_elfinfo *v64,
+                                      const char *orig, const char *fix)
 {
        Elf32_Sym *sym32_gen, *sym32_fix;
 
@@ -433,9 +433,9 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib,
 #endif
 }
 
-static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
-                               struct lib64_elfinfo *v64,
-                               const char *orig, const char *fix)
+static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32,
+                                      struct lib64_elfinfo *v64,
+                                      const char *orig, const char *fix)
 {
        Elf64_Sym *sym64_gen, *sym64_fix;
 
index 4a890cb..257b13c 100644 (file)
@@ -198,14 +198,13 @@ out:
  * dcookie user still being registered (namely, the reader
  * of the event buffer).
  */
-static inline unsigned long fast_get_dcookie(struct dentry *dentry,
-                                            struct vfsmount *vfsmnt)
+static inline unsigned long fast_get_dcookie(struct path *path)
 {
        unsigned long cookie;
 
-       if (dentry->d_cookie)
-               return (unsigned long)dentry;
-       get_dcookie(dentry, vfsmnt, &cookie);
+       if (path->dentry->d_cookie)
+               return (unsigned long)path->dentry;
+       get_dcookie(path, &cookie);
        return cookie;
 }
 
@@ -240,8 +239,7 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
                        continue;
                if (!(vma->vm_flags & VM_EXECUTABLE))
                        continue;
-               app_cookie = fast_get_dcookie(vma->vm_file->f_dentry,
-                                         vma->vm_file->f_vfsmnt);
+               app_cookie = fast_get_dcookie(&vma->vm_file->f_path);
                pr_debug("got dcookie for %s\n",
                         vma->vm_file->f_dentry->d_name.name);
                app = vma->vm_file;
@@ -262,8 +260,7 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
                break;
        }
 
-       *spu_bin_dcookie = fast_get_dcookie(vma->vm_file->f_dentry,
-                                                vma->vm_file->f_vfsmnt);
+       *spu_bin_dcookie = fast_get_dcookie(&vma->vm_file->f_path);
        pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name);
 
        up_read(&mm->mmap_sem);
index c6fa49e..4c0da0c 100644 (file)
@@ -13,7 +13,6 @@ config MPC5121_ADS
        bool "Freescale MPC5121E ADS"
        depends on PPC_MULTIPLATFORM && PPC32
        select DEFAULT_UIMAGE
-       select WANT_DEVICE_TREE
        select PPC_MPC5121
        help
          This option enables support for the MPC5121E ADS board.
index 515f244..cf945d5 100644 (file)
@@ -8,7 +8,6 @@ config PPC_MPC5200_SIMPLE
        bool "Generic support for simple MPC5200 based boards"
        depends on PPC_MPC52xx
        select DEFAULT_UIMAGE
-       select WANT_DEVICE_TREE
        help
          This option enables support for a simple MPC52xx based boards which
          do not need a custom platform specific setup. Such boards are
@@ -35,7 +34,6 @@ config PPC_LITE5200
        bool "Freescale Lite5200 Eval Board"
        depends on PPC_MPC52xx
        select DEFAULT_UIMAGE
-       select WANT_DEVICE_TREE
 
 config PPC_MPC5200_BUGFIX
        bool "MPC5200 (L25R) bugfix support"
index fcedbec..0afd225 100644 (file)
@@ -15,7 +15,6 @@ config PPC_MULTIPLATFORM
 config PPC_82xx
        bool "Freescale 82xx"
        depends on 6xx
-       select WANT_DEVICE_TREE
 
 config PPC_83xx
        bool "Freescale 83xx"
@@ -23,7 +22,6 @@ config PPC_83xx
        select FSL_SOC
        select MPC83xx
        select IPIC
-       select WANT_DEVICE_TREE
        select FSL_EMB_PERFMON
 
 config PPC_86xx
index 69941ba..73d81ce 100644 (file)
@@ -29,26 +29,22 @@ config PPC_85xx
        bool "Freescale 85xx"
        select E500
        select FSL_SOC
-       select WANT_DEVICE_TREE
        select MPC85xx
 
 config PPC_8xx
        bool "Freescale 8xx"
        select FSL_SOC
        select 8xx
-       select WANT_DEVICE_TREE
        select PPC_LIB_RHEAP
 
 config 40x
        bool "AMCC 40x"
        select PPC_DCR_NATIVE
-       select WANT_DEVICE_TREE
        select PPC_UDBG_16550
 
 config 44x
        bool "AMCC 44x"
        select PPC_DCR_NATIVE
-       select WANT_DEVICE_TREE
        select PPC_UDBG_16550
 
 config E200
index b2494eb..e43024c 100644 (file)
@@ -1,4 +1,13 @@
-#define DEBUG
+/*
+ * Copyright 2006-2008, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
 
 #include <linux/types.h>
 #include <linux/kernel.h>
index e6e6559..6d1228c 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * SPU file system
  *
@@ -592,7 +593,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
 
        ret = -EINVAL;
        /* check if we are on spufs */
-       if (nd->dentry->d_sb->s_type != &spufs_type)
+       if (nd->path.dentry->d_sb->s_type != &spufs_type)
                goto out;
 
        /* don't accept undefined flags */
@@ -600,9 +601,9 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
                goto out;
 
        /* only threads can be underneath a gang */
-       if (nd->dentry != nd->dentry->d_sb->s_root) {
+       if (nd->path.dentry != nd->path.dentry->d_sb->s_root) {
                if ((flags & SPU_CREATE_GANG) ||
-                   !SPUFS_I(nd->dentry->d_inode)->i_gang)
+                   !SPUFS_I(nd->path.dentry->d_inode)->i_gang)
                        goto out;
        }
 
@@ -618,16 +619,17 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
        mode &= ~current->fs->umask;
 
        if (flags & SPU_CREATE_GANG)
-               return spufs_create_gang(nd->dentry->d_inode,
-                                       dentry, nd->mnt, mode);
+               return spufs_create_gang(nd->path.dentry->d_inode,
+                                        dentry, nd->path.mnt, mode);
        else
-               return spufs_create_context(nd->dentry->d_inode,
-                                       dentry, nd->mnt, flags, mode, filp);
+               return spufs_create_context(nd->path.dentry->d_inode,
+                                           dentry, nd->path.mnt, flags, mode,
+                                           filp);
 
 out_dput:
        dput(dentry);
 out_dir:
-       mutex_unlock(&nd->dentry->d_inode->i_mutex);
+       mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
        return ret;
 }
index 4304044..49c8776 100644 (file)
@@ -73,7 +73,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
                                LOOKUP_OPEN|LOOKUP_CREATE, &nd);
                if (!ret) {
                        ret = spufs_create(&nd, flags, mode, neighbor);
-                       path_release(&nd);
+                       path_put(&nd.path);
                }
                putname(tmp);
        }
index 6c80837..4290889 100644 (file)
@@ -24,7 +24,6 @@ config STORCENTER
        select MPIC
        select FSL_SOC
        select PPC_UDBG_16550 if SERIAL_8250
-       select WANT_DEVICE_TREE
        select MPC10X_OPENPIC
        select MPC10X_BRIDGE
        help
@@ -37,7 +36,6 @@ config MPC7448HPC2
        select TSI108_BRIDGE
        select DEFAULT_UIMAGE
        select PPC_UDBG_16550
-       select WANT_DEVICE_TREE
        select TSI108_BRIDGE
        help
          Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
@@ -48,7 +46,6 @@ config PPC_HOLLY
        depends on EMBEDDED6xx
        select TSI108_BRIDGE
        select PPC_UDBG_16550
-       select WANT_DEVICE_TREE
        select TSI108_BRIDGE
        help
          Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
@@ -59,7 +56,6 @@ config PPC_PRPMC2800
        depends on EMBEDDED6xx
        select MV64X60
        select NOT_COHERENT_CACHE
-       select WANT_DEVICE_TREE
        help
          This option enables support for the Motorola PrPMC2800 board
 
index be06cfd..657b72f 100644 (file)
@@ -75,7 +75,7 @@ static struct property *new_property(const char *name, int length,
        return np;
 }
 
-static void __init free_property(struct property *np)
+static void free_property(struct property *np)
 {
        kfree(np);
 }
index 9311bfe..7d035f0 100644 (file)
@@ -434,9 +434,9 @@ asmlinkage int solaris_statvfs(u32 path, u32 buf)
 
        error = user_path_walk(A(path),&nd);
        if (!error) {
-               struct inode * inode = nd.dentry->d_inode;
-               error = report_statvfs(nd.mnt, inode, buf);
-               path_release(&nd);
+               struct inode *inode = nd.path.dentry->d_inode;
+               error = report_statvfs(nd.path.mnt, inode, buf);
+               path_put(&nd.path);
        }
        return error;
 }
@@ -464,9 +464,9 @@ asmlinkage int solaris_statvfs64(u32 path, u32 buf)
        lock_kernel();
        error = user_path_walk(A(path), &nd);
        if (!error) {
-               struct inode * inode = nd.dentry->d_inode;
-               error = report_statvfs64(nd.mnt, inode, buf);
-               path_release(&nd);
+               struct inode *inode = nd.path.dentry->d_inode;
+               error = report_statvfs64(nd.path.mnt, inode, buf);
+               path_put(&nd.path);
        }
        unlock_kernel();
        return error;
index ebb265c..19d579d 100644 (file)
@@ -145,8 +145,8 @@ void mconsole_proc(struct mc_request *req)
        }
        up_write(&super->s_umount);
 
-       nd.dentry = super->s_root;
-       nd.mnt = NULL;
+       nd.path.dentry = super->s_root;
+       nd.path.mnt = NULL;
        nd.flags = O_RDONLY + 1;
        nd.last_type = LAST_ROOT;
 
@@ -159,7 +159,7 @@ void mconsole_proc(struct mc_request *req)
                goto out_kill;
        }
 
-       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
+       file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
        if (IS_ERR(file)) {
                mconsole_reply(req, "Failed to open file", 1, 0);
                goto out_kill;
index b4e462f..730ccea 100644 (file)
@@ -251,10 +251,6 @@ static int floppy_release(struct inode *inode, struct file *filp);
 static int floppy_check_change(struct gendisk *disk);
 static int floppy_revalidate(struct gendisk *disk);
 
-#ifndef CONFIG_PMAC_MEDIABAY
-#define check_media_bay(which, what)   1
-#endif
-
 static void swim3_select(struct floppy_state *fs, int sel)
 {
        struct swim3 __iomem *sw = fs->swim3;
index bb09413..88590d0 100644 (file)
@@ -76,7 +76,7 @@ static struct hv_ops hvc_rtas_get_put_ops = {
        .put_chars = hvc_rtas_write_console,
 };
 
-static int hvc_rtas_init(void)
+static int __init hvc_rtas_init(void)
 {
        struct hvc_struct *hp;
 
index 9367882..51a1128 100644 (file)
@@ -416,7 +416,6 @@ static void poll_media_bay(struct media_bay_info* bay)
        }
 }
 
-#ifdef CONFIG_MAC_FLOPPY
 int check_media_bay(struct device_node *which_bay, int what)
 {
        int     i;
@@ -431,7 +430,6 @@ int check_media_bay(struct device_node *which_bay, int what)
        return -ENODEV;
 }
 EXPORT_SYMBOL(check_media_bay);
-#endif /* CONFIG_MAC_FLOPPY */
 
 #ifdef CONFIG_BLK_DEV_IDE_PMAC
 int check_media_bay_by_base(unsigned long base, int what)
index a0585fb..7aeceed 100644 (file)
@@ -206,16 +206,10 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
 /* copy the pathname of a file to a buffer */
 char *file_path(struct file *file, char *buf, int count)
 {
-       struct dentry *d;
-       struct vfsmount *v;
-
        if (!buf)
                return NULL;
 
-       d = file->f_path.dentry;
-       v = file->f_path.mnt;
-
-       buf = d_path(d, v, buf, count);
+       buf = d_path(&file->f_path, buf, count);
 
        return IS_ERR(buf) ? NULL : buf;
 }
index f160629..e75b143 100644 (file)
@@ -361,7 +361,7 @@ static int lookup_device(const char *path, dev_t *dev)
        if ((r = path_lookup(path, LOOKUP_FOLLOW, &nd)))
                return r;
 
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
        if (!inode) {
                r = -ENOENT;
                goto out;
@@ -375,7 +375,7 @@ static int lookup_device(const char *path, dev_t *dev)
        *dev = inode->i_rdev;
 
  out:
-       path_release(&nd);
+       path_put(&nd.path);
        return r;
 }
 
index 5fc326d..7da6ec2 100644 (file)
@@ -5197,8 +5197,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
                                chunk_kb ? "KB" : "B");
                        if (bitmap->file) {
                                seq_printf(seq, ", file: ");
-                               seq_path(seq, bitmap->file->f_path.mnt,
-                                        bitmap->file->f_path.dentry," \t\n");
+                               seq_path(seq, &bitmap->file->f_path, " \t\n");
                        }
 
                        seq_printf(seq, "\n");
index 9b430f2..28cc678 100644 (file)
@@ -184,26 +184,26 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
        ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
 
        DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
-             ret, nd.dentry ? nd.dentry->d_inode : NULL);
+             ret, nd.path.dentry ? nd.path.dentry->d_inode : NULL);
 
        if (ret)
                return ret;
 
        ret = -EINVAL;
 
-       if (!S_ISBLK(nd.dentry->d_inode->i_mode))
+       if (!S_ISBLK(nd.path.dentry->d_inode->i_mode))
                goto out;
 
-       if (nd.mnt->mnt_flags & MNT_NODEV) {
+       if (nd.path.mnt->mnt_flags & MNT_NODEV) {
                ret = -EACCES;
                goto out;
        }
 
-       if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
+       if (imajor(nd.path.dentry->d_inode) != MTD_BLOCK_MAJOR)
                goto not_an_MTD_device;
 
-       mtdnr = iminor(nd.dentry->d_inode);
-       path_release(&nd);
+       mtdnr = iminor(nd.path.dentry->d_inode);
+       path_put(&nd.path);
 
        return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
                             mnt);
@@ -214,7 +214,7 @@ not_an_MTD_device:
                       "MTD: Attempt to mount non-MTD device \"%s\"\n",
                       dev_name);
 out:
-       path_release(&nd);
+       path_put(&nd.path);
        return ret;
 
 }
index 8134c7e..b07ba2a 100644 (file)
@@ -187,23 +187,22 @@ void sync_stop(void)
        end_sync();
 }
 
+
 /* Optimisation. We can manage without taking the dcookie sem
  * because we cannot reach this code without at least one
  * dcookie user still being registered (namely, the reader
  * of the event buffer). */
-static inline unsigned long fast_get_dcookie(struct dentry * dentry,
-       struct vfsmount * vfsmnt)
+static inline unsigned long fast_get_dcookie(struct path *path)
 {
        unsigned long cookie;
-       if (dentry->d_cookie)
-               return (unsigned long)dentry;
-       get_dcookie(dentry, vfsmnt, &cookie);
+
+       if (path->dentry->d_cookie)
+               return (unsigned long)path->dentry;
+       get_dcookie(path, &cookie);
        return cookie;
 }
 
+
 /* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
  * which corresponds loosely to "application name". This is
  * not strictly necessary but allows oprofile to associate
@@ -222,8 +221,7 @@ static unsigned long get_exec_dcookie(struct mm_struct * mm)
                        continue;
                if (!(vma->vm_flags & VM_EXECUTABLE))
                        continue;
-               cookie = fast_get_dcookie(vma->vm_file->f_path.dentry,
-                       vma->vm_file->f_path.mnt);
+               cookie = fast_get_dcookie(&vma->vm_file->f_path);
                break;
        }
 
@@ -248,8 +246,7 @@ static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, o
                        continue;
 
                if (vma->vm_file) {
-                       cookie = fast_get_dcookie(vma->vm_file->f_path.dentry,
-                               vma->vm_file->f_path.mnt);
+                       cookie = fast_get_dcookie(&vma->vm_file->f_path);
                        *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr -
                                vma->vm_start;
                } else {
index f7e6719..a8a5150 100644 (file)
@@ -105,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
        char *argv[3], **envp, *buf, *scratch;
        int i = 0, value;
 
-       if (!current->fs->root)
-               return -EAGAIN;
        if (!(envp = kcalloc(20, sizeof(char *), GFP_KERNEL)))
                return -ENOMEM;
        if (!(buf = kzalloc(256, GFP_KERNEL))) {
index 4c06654..6c9592c 100644 (file)
@@ -76,7 +76,6 @@
  *
  * @pm_control: Shadow of the processor's pm_control register.
  * @pm_start_stop: Shadow of the processor's pm_start_stop register.
- * @pm_interval: Shadow of the processor's pm_interval register.
  * @group_control: Shadow of the processor's group_control register.
  * @debug_bus_control: Shadow of the processor's debug_bus_control register.
  *
@@ -91,7 +90,6 @@
 struct ps3_lpm_shadow_regs {
        u64 pm_control;
        u64 pm_start_stop;
-       u64 pm_interval;
        u64 group_control;
        u64 debug_bus_control;
 };
@@ -181,9 +179,9 @@ void ps3_set_bookmark(u64 bookmark)
         * includes cycles before the call.
         */
 
-       asm volatile("or 29, 29, 29;"); /* db10cyc */
+       asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
        mtspr(SPRN_BKMK, bookmark);
-       asm volatile("or 29, 29, 29;"); /* db10cyc */
+       asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
 }
 EXPORT_SYMBOL_GPL(ps3_set_bookmark);
 
@@ -408,7 +406,14 @@ u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
        case pm_start_stop:
                return lpm_priv->shadow.pm_start_stop;
        case pm_interval:
-               return lpm_priv->shadow.pm_interval;
+               result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val);
+               if (result) {
+                       val = 0;
+                       dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: "
+                               "reg %u, %s\n", __func__, __LINE__, reg,
+                               ps3_result(result));
+               }
+               return (u32)val;
        case group_control:
                return lpm_priv->shadow.group_control;
        case debug_bus_control:
@@ -475,10 +480,8 @@ void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
                lpm_priv->shadow.pm_control = val;
                break;
        case pm_interval:
-               if (val != lpm_priv->shadow.pm_interval)
-                       result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
-                                                  PS3_WRITE_PM_MASK, &dummy);
-               lpm_priv->shadow.pm_interval = val;
+               result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
+                                             PS3_WRITE_PM_MASK, &dummy);
                break;
        case pm_start_stop:
                if (val != lpm_priv->shadow.pm_start_stop)
@@ -1140,7 +1143,6 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
 
        lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
        lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
-       lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT;
        lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
        lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
 
index c3c3aba..d4f6f96 100644 (file)
 
 #include "vuart.h"
 
-MODULE_AUTHOR("Sony Corporation");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PS3 System Manager");
-
 /**
  * ps3_sys_manager - PS3 system manager driver.
  *
@@ -142,9 +138,11 @@ enum ps3_sys_manager_attr {
 
 /**
  * enum ps3_sys_manager_event - External event type, reported by system manager.
- * @PS3_SM_EVENT_POWER_PRESSED: payload.value not used.
+ * @PS3_SM_EVENT_POWER_PRESSED: payload.value =
+ *  enum ps3_sys_manager_button_event.
  * @PS3_SM_EVENT_POWER_RELEASED: payload.value = time pressed in millisec.
- * @PS3_SM_EVENT_RESET_PRESSED: payload.value not used.
+ * @PS3_SM_EVENT_RESET_PRESSED: payload.value =
+ *  enum ps3_sys_manager_button_event.
  * @PS3_SM_EVENT_RESET_RELEASED: payload.value = time pressed in millisec.
  * @PS3_SM_EVENT_THERMAL_ALERT: payload.value = thermal zone id.
  * @PS3_SM_EVENT_THERMAL_CLEARED: payload.value = thermal zone id.
@@ -162,6 +160,17 @@ enum ps3_sys_manager_event {
 };
 
 /**
+ * enum ps3_sys_manager_button_event - Button event payload values.
+ * @PS3_SM_BUTTON_EVENT_HARD: Hardware generated event.
+ * @PS3_SM_BUTTON_EVENT_SOFT: Software generated event.
+ */
+
+enum ps3_sys_manager_button_event {
+       PS3_SM_BUTTON_EVENT_HARD = 0,
+       PS3_SM_BUTTON_EVENT_SOFT = 1,
+};
+
+/**
  * enum ps3_sys_manager_next_op - Operation to perform after lpar is destroyed.
  */
 
@@ -181,7 +190,9 @@ enum ps3_sys_manager_next_op {
  * @PS3_SM_WAKE_P_O_R: Power on reset.
  *
  * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN.
- * System will always wake from the PS3_SM_WAKE_DEFAULT sources.
+ * The system will always wake from the PS3_SM_WAKE_DEFAULT sources.
+ * Sources listed here are the only ones available to guests in the
+ * other-os lpar.
  */
 
 enum ps3_sys_manager_wake_source {
@@ -189,7 +200,7 @@ enum ps3_sys_manager_wake_source {
        PS3_SM_WAKE_DEFAULT   = 0,
        PS3_SM_WAKE_RTC       = 0x00000040,
        PS3_SM_WAKE_RTC_ERROR = 0x00000080,
-       PS3_SM_WAKE_P_O_R     = 0x10000000,
+       PS3_SM_WAKE_P_O_R     = 0x80000000,
 };
 
 /**
@@ -418,8 +429,10 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev)
 
        switch (event.type) {
        case PS3_SM_EVENT_POWER_PRESSED:
-               dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n",
-                       __func__, __LINE__);
+               dev_dbg(&dev->core, "%s:%d: POWER_PRESSED (%s)\n",
+                       __func__, __LINE__,
+                       (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft"
+                       : "hard"));
                ps3_sm_force_power_off = 1;
                /*
                 * A memory barrier is use here to sync memory since
@@ -434,8 +447,10 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev)
                        __func__, __LINE__, event.value);
                break;
        case PS3_SM_EVENT_RESET_PRESSED:
-               dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n",
-                       __func__, __LINE__);
+               dev_dbg(&dev->core, "%s:%d: RESET_PRESSED (%s)\n",
+                       __func__, __LINE__,
+                       (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft"
+                       : "hard"));
                ps3_sm_force_power_off = 0;
                /*
                 * A memory barrier is use here to sync memory since
@@ -622,7 +637,7 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev)
        ps3_vuart_cancel_async(dev);
 
        ps3_sys_manager_send_attr(dev, 0);
-       ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,
+       ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT,
                PS3_SM_WAKE_DEFAULT);
        ps3_sys_manager_send_request_shutdown(dev);
 
@@ -699,4 +714,7 @@ static int __init ps3_sys_manager_init(void)
 module_init(ps3_sys_manager_init);
 /* Module remove not supported. */
 
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PS3 System Manager");
 MODULE_ALIAS(PS3_MODULE_ALIAS_SYSTEM_MANAGER);
index 3301167..017a196 100644 (file)
@@ -3563,8 +3563,7 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr,
 
        down_read(&fsg->filesem);
        if (backing_file_is_open(curlun)) {     // Get the complete pathname
-               p = d_path(curlun->filp->f_path.dentry,
-                               curlun->filp->f_path.mnt, buf, PAGE_SIZE - 1);
+               p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
                if (IS_ERR(p))
                        rc = PTR_ERR(p);
                else {
@@ -3981,9 +3980,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                if (backing_file_is_open(curlun)) {
                        p = NULL;
                        if (pathbuf) {
-                               p = d_path(curlun->filp->f_path.dentry,
-                                       curlun->filp->f_path.mnt,
-                                       pathbuf, PATH_MAX);
+                               p = d_path(&curlun->filp->f_path,
+                                          pathbuf, PATH_MAX);
                                if (IS_ERR(p))
                                        p = NULL;
                        }
index 5ce43b6..a3510b8 100644 (file)
@@ -218,16 +218,16 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
        _enter("%p{%s},{%s:%p{%s},}",
               dentry,
               dentry->d_name.name,
-              nd->mnt->mnt_devname,
+              nd->path.mnt->mnt_devname,
               dentry,
-              nd->dentry->d_name.name);
+              nd->path.dentry->d_name.name);
 
-       dput(nd->dentry);
-       nd->dentry = dget(dentry);
+       dput(nd->path.dentry);
+       nd->path.dentry = dget(dentry);
 
-       newmnt = afs_mntpt_do_automount(nd->dentry);
+       newmnt = afs_mntpt_do_automount(nd->path.dentry);
        if (IS_ERR(newmnt)) {
-               path_release(nd);
+               path_put(&nd->path);
                return (void *)newmnt;
        }
 
@@ -235,17 +235,16 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
        err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
        switch (err) {
        case 0:
-               dput(nd->dentry);
-               mntput(nd->mnt);
-               nd->mnt = newmnt;
-               nd->dentry = dget(newmnt->mnt_root);
+               path_put(&nd->path);
+               nd->path.mnt = newmnt;
+               nd->path.dentry = dget(newmnt->mnt_root);
                schedule_delayed_work(&afs_mntpt_expiry_timer,
                                      afs_mntpt_expiry_timeout * HZ);
                break;
        case -EBUSY:
                /* someone else made a mount here whilst we were busy */
-               while (d_mountpoint(nd->dentry) &&
-                      follow_down(&nd->mnt, &nd->dentry))
+               while (d_mountpoint(nd->path.dentry) &&
+                      follow_down(&nd->path.mnt, &nd->path.dentry))
                        ;
                err = 0;
        default:
index 2bbcc81..a54a946 100644 (file)
@@ -368,7 +368,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
                 * so we don't need to follow the mount.
                 */
                if (d_mountpoint(dentry)) {
-                       if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) {
+                       if (!autofs4_follow_mount(&nd->path.mnt,
+                                                 &nd->path.dentry)) {
                                status = -ENOENT;
                                goto out_error;
                        }
@@ -382,7 +383,7 @@ done:
        return NULL;
 
 out_error:
-       path_release(nd);
+       path_put(&nd->path);
        return ERR_PTR(status);
 }
 
index d8a02f1..0498b18 100644 (file)
@@ -443,12 +443,12 @@ static int load_flat_file(struct linux_binprm * bprm,
 
        if (strncmp(hdr->magic, "bFLT", 4)) {
                /*
+                * Previously, here was a printk to tell people
+                *   "BINFMT_FLAT: bad header magic".
+                * But for the kernel which also use ELF FD-PIC format, this
+                * error message is confusing.
                 * because a lot of people do not manage to produce good
-                * flat binaries,  we leave this printk to help them realise
-                * the problem.  We only print the error if its not a script file
                 */
-               if (strncmp(hdr->magic, "#!", 2))
-                       printk("BINFMT_FLAT: bad header magic\n");
                ret = -ENOEXEC;
                goto err;
        }
index e63067d..67fe72c 100644 (file)
@@ -1397,19 +1397,19 @@ struct block_device *lookup_bdev(const char *path)
        if (error)
                return ERR_PTR(error);
 
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
        error = -ENOTBLK;
        if (!S_ISBLK(inode->i_mode))
                goto fail;
        error = -EACCES;
-       if (nd.mnt->mnt_flags & MNT_NODEV)
+       if (nd.path.mnt->mnt_flags & MNT_NODEV)
                goto fail;
        error = -ENOMEM;
        bdev = bd_acquire(inode);
        if (!bdev)
                goto fail;
 out:
-       path_release(&nd);
+       path_put(&nd.path);
        return bdev;
 fail:
        bdev = ERR_PTR(error);
index 413ee23..6ad4475 100644 (file)
@@ -259,18 +259,18 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
        int err;
 
        mntget(newmnt);
-       err = do_add_mount(newmnt, nd, nd->mnt->mnt_flags, mntlist);
+       err = do_add_mount(newmnt, nd, nd->path.mnt->mnt_flags, mntlist);
        switch (err) {
        case 0:
-               dput(nd->dentry);
-               mntput(nd->mnt);
-               nd->mnt = newmnt;
-               nd->dentry = dget(newmnt->mnt_root);
+               dput(nd->path.dentry);
+               mntput(nd->path.mnt);
+               nd->path.mnt = newmnt;
+               nd->path.dentry = dget(newmnt->mnt_root);
                break;
        case -EBUSY:
                /* someone else made a mount here whilst we were busy */
-               while (d_mountpoint(nd->dentry) &&
-                      follow_down(&nd->mnt, &nd->dentry))
+               while (d_mountpoint(nd->path.dentry) &&
+                      follow_down(&nd->path.mnt, &nd->path.dentry))
                        ;
                err = 0;
        default:
@@ -307,8 +307,8 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 
        xid = GetXid();
 
-       dput(nd->dentry);
-       nd->dentry = dget(dentry);
+       dput(nd->path.dentry);
+       nd->path.dentry = dget(dentry);
 
        cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
        ses = cifs_sb->tcon->ses;
@@ -340,7 +340,8 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
                                rc = -EINVAL;
                                goto out_err;
                        }
-                       mnt = cifs_dfs_do_refmount(nd->mnt, nd->dentry,
+                       mnt = cifs_dfs_do_refmount(nd->path.mnt,
+                                               nd->path.dentry,
                                                referrals[i].node_name);
                        cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p",
                                         __FUNCTION__,
@@ -357,7 +358,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        if (IS_ERR(mnt))
                goto out_err;
 
-       nd->mnt->mnt_flags |= MNT_SHRINKABLE;
+       nd->path.mnt->mnt_flags |= MNT_SHRINKABLE;
        rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list);
 
 out:
@@ -367,7 +368,7 @@ out:
        cFYI(1, ("leaving %s" , __FUNCTION__));
        return ERR_PTR(rc);
 out_err:
-       path_release(nd);
+       path_put(&nd->path);
        goto out;
 }
 
index 2bf3026..c21a1f5 100644 (file)
@@ -75,12 +75,12 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
        if ( error ) {
                return error;
         } else {
-               target_inode = nd.dentry->d_inode;
+               target_inode = nd.path.dentry->d_inode;
        }
        
        /* return if it is not a Coda inode */
        if ( target_inode->i_sb != inode->i_sb ) {
-               path_release(&nd);
+               path_put(&nd.path);
                return  -EINVAL;
        }
 
@@ -89,7 +89,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
 
        error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
 
-       path_release(&nd);
+       path_put(&nd.path);
         return error;
 }
 
index ee80ff3..43ca016 100644 (file)
@@ -241,10 +241,10 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs
        error = user_path_walk(path, &nd);
        if (!error) {
                struct kstatfs tmp;
-               error = vfs_statfs(nd.dentry, &tmp);
+               error = vfs_statfs(nd.path.dentry, &tmp);
                if (!error)
                        error = put_compat_statfs(buf, &tmp);
-               path_release(&nd);
+               path_put(&nd.path);
        }
        return error;
 }
@@ -309,10 +309,10 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s
        error = user_path_walk(path, &nd);
        if (!error) {
                struct kstatfs tmp;
-               error = vfs_statfs(nd.dentry, &tmp);
+               error = vfs_statfs(nd.path.dentry, &tmp);
                if (!error)
                        error = put_compat_statfs64(buf, &tmp);
-               path_release(&nd);
+               path_put(&nd.path);
        }
        return error;
 }
index ee32c0e..c6e72ae 100644 (file)
@@ -2853,7 +2853,7 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd,
        /* find the name of the device. */
        path = (char *)__get_free_page(GFP_KERNEL);
        if (path) {
-               fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE);
+               fn = d_path(&filp->f_path, path, PAGE_SIZE);
                if (IS_ERR(fn))
                        fn = "?";
        }
index 22700d2..78929ea 100644 (file)
@@ -99,11 +99,11 @@ static int get_target(const char *symname, struct nameidata *nd,
 
        ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
        if (!ret) {
-               if (nd->dentry->d_sb == configfs_sb) {
-                       *target = configfs_get_config_item(nd->dentry);
+               if (nd->path.dentry->d_sb == configfs_sb) {
+                       *target = configfs_get_config_item(nd->path.dentry);
                        if (!*target) {
                                ret = -ENOENT;
-                               path_release(nd);
+                               path_put(&nd->path);
                        }
                } else
                        ret = -EPERM;
@@ -141,7 +141,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
                ret = create_link(parent_item, target_item, dentry);
 
        config_item_put(target_item);
-       path_release(&nd);
+       path_put(&nd.path);
 
 out_put:
        config_item_put(parent_item);
index 44f6cf2..4345577 100644 (file)
@@ -95,6 +95,14 @@ static void d_free(struct dentry *dentry)
                call_rcu(&dentry->d_u.d_rcu, d_callback);
 }
 
+static void dentry_lru_remove(struct dentry *dentry)
+{
+       if (!list_empty(&dentry->d_lru)) {
+               list_del_init(&dentry->d_lru);
+               dentry_stat.nr_unused--;
+       }
+}
+
 /*
  * Release the dentry's inode, using the filesystem
  * d_iput() operation if defined.
@@ -211,13 +219,7 @@ repeat:
 unhash_it:
        __d_drop(dentry);
 kill_it:
-       /* If dentry was on d_lru list
-        * delete it from there
-        */
-       if (!list_empty(&dentry->d_lru)) {
-               list_del(&dentry->d_lru);
-               dentry_stat.nr_unused--;
-       }
+       dentry_lru_remove(dentry);
        dentry = d_kill(dentry);
        if (dentry)
                goto repeat;
@@ -285,10 +287,7 @@ int d_invalidate(struct dentry * dentry)
 static inline struct dentry * __dget_locked(struct dentry *dentry)
 {
        atomic_inc(&dentry->d_count);
-       if (!list_empty(&dentry->d_lru)) {
-               dentry_stat.nr_unused--;
-               list_del_init(&dentry->d_lru);
-       }
+       dentry_lru_remove(dentry);
        return dentry;
 }
 
@@ -404,10 +403,7 @@ static void prune_one_dentry(struct dentry * dentry)
 
                if (dentry->d_op && dentry->d_op->d_delete)
                        dentry->d_op->d_delete(dentry);
-               if (!list_empty(&dentry->d_lru)) {
-                       list_del(&dentry->d_lru);
-                       dentry_stat.nr_unused--;
-               }
+               dentry_lru_remove(dentry);
                __d_drop(dentry);
                dentry = d_kill(dentry);
                spin_lock(&dcache_lock);
@@ -596,10 +592,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 
        /* detach this root from the system */
        spin_lock(&dcache_lock);
-       if (!list_empty(&dentry->d_lru)) {
-               dentry_stat.nr_unused--;
-               list_del_init(&dentry->d_lru);
-       }
+       dentry_lru_remove(dentry);
        __d_drop(dentry);
        spin_unlock(&dcache_lock);
 
@@ -613,11 +606,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                        spin_lock(&dcache_lock);
                        list_for_each_entry(loop, &dentry->d_subdirs,
                                            d_u.d_child) {
-                               if (!list_empty(&loop->d_lru)) {
-                                       dentry_stat.nr_unused--;
-                                       list_del_init(&loop->d_lru);
-                               }
-
+                               dentry_lru_remove(loop);
                                __d_drop(loop);
                                cond_resched_lock(&dcache_lock);
                        }
@@ -799,10 +788,7 @@ resume:
                struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
                next = tmp->next;
 
-               if (!list_empty(&dentry->d_lru)) {
-                       dentry_stat.nr_unused--;
-                       list_del_init(&dentry->d_lru);
-               }
+               dentry_lru_remove(dentry);
                /* 
                 * move only zero ref count dentries to the end 
                 * of the unused list for prune_dcache
@@ -1776,9 +1762,8 @@ shouldnt_be_hashed:
  *
  * "buflen" should be positive. Caller holds the dcache_lock.
  */
-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
-                       struct dentry *root, struct vfsmount *rootmnt,
-                       char *buffer, int buflen)
+static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+                      struct path *root, char *buffer, int buflen)
 {
        char * end = buffer+buflen;
        char * retval;
@@ -1803,7 +1788,7 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
        for (;;) {
                struct dentry * parent;
 
-               if (dentry == root && vfsmnt == rootmnt)
+               if (dentry == root->dentry && vfsmnt == root->mnt)
                        break;
                if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
                        /* Global root? */
@@ -1844,13 +1829,23 @@ Elong:
        return ERR_PTR(-ENAMETOOLONG);
 }
 
-/* write full pathname into buffer and return start of pathname */
-char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
-                               char *buf, int buflen)
+/**
+ * d_path - return the path of a dentry
+ * @path: path to report
+ * @buf: buffer to return value in
+ * @buflen: buffer length
+ *
+ * Convert a dentry into an ASCII path name. If the entry has been deleted
+ * the string " (deleted)" is appended. Note that this is ambiguous.
+ *
+ * Returns the buffer or an error code if the path was too long.
+ *
+ * "buflen" should be positive. Caller holds the dcache_lock.
+ */
+char *d_path(struct path *path, char *buf, int buflen)
 {
        char *res;
-       struct vfsmount *rootmnt;
-       struct dentry *root;
+       struct path root;
 
        /*
         * We have various synthetic filesystems that never get mounted.  On
@@ -1859,18 +1854,17 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
         * user wants to identify the object in /proc/pid/fd/.  The little hack
         * below allows us to generate a name for these objects on demand:
         */
-       if (dentry->d_op && dentry->d_op->d_dname)
-               return dentry->d_op->d_dname(dentry, buf, buflen);
+       if (path->dentry->d_op && path->dentry->d_op->d_dname)
+               return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        read_lock(&current->fs->lock);
-       rootmnt = mntget(current->fs->rootmnt);
-       root = dget(current->fs->root);
+       root = current->fs->root;
+       path_get(&current->fs->root);
        read_unlock(&current->fs->lock);
        spin_lock(&dcache_lock);
-       res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+       res = __d_path(path->dentry, path->mnt, &root, buf, buflen);
        spin_unlock(&dcache_lock);
-       dput(root);
-       mntput(rootmnt);
+       path_put(&root);
        return res;
 }
 
@@ -1916,28 +1910,27 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
 asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
 {
        int error;
-       struct vfsmount *pwdmnt, *rootmnt;
-       struct dentry *pwd, *root;
+       struct path pwd, root;
        char *page = (char *) __get_free_page(GFP_USER);
 
        if (!page)
                return -ENOMEM;
 
        read_lock(&current->fs->lock);
-       pwdmnt = mntget(current->fs->pwdmnt);
-       pwd = dget(current->fs->pwd);
-       rootmnt = mntget(current->fs->rootmnt);
-       root = dget(current->fs->root);
+       pwd = current->fs->pwd;
+       path_get(&current->fs->pwd);
+       root = current->fs->root;
+       path_get(&current->fs->root);
        read_unlock(&current->fs->lock);
 
        error = -ENOENT;
        /* Has the current directory has been unlinked? */
        spin_lock(&dcache_lock);
-       if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
+       if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
                unsigned long len;
                char * cwd;
 
-               cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+               cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE);
                spin_unlock(&dcache_lock);
 
                error = PTR_ERR(cwd);
@@ -1955,10 +1948,8 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
                spin_unlock(&dcache_lock);
 
 out:
-       dput(pwd);
-       mntput(pwdmnt);
-       dput(root);
-       mntput(rootmnt);
+       path_put(&pwd);
+       path_put(&root);
        free_page((unsigned long) page);
        return error;
 }
index 792cbf5..855d4b1 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/errno.h>
 #include <linux/dcookies.h>
 #include <linux/mutex.h>
+#include <linux/path.h>
 #include <asm/uaccess.h>
 
 /* The dcookies are allocated from a kmem_cache and
@@ -31,8 +32,7 @@
  * code here is particularly performance critical
  */
 struct dcookie_struct {
-       struct dentry * dentry;
-       struct vfsmount * vfsmnt;
+       struct path path;
        struct list_head hash_list;
 };
 
@@ -51,7 +51,7 @@ static inline int is_live(void)
 /* The dentry is locked, its address will do for the cookie */
 static inline unsigned long dcookie_value(struct dcookie_struct * dcs)
 {
-       return (unsigned long)dcs->dentry;
+       return (unsigned long)dcs->path.dentry;
 }
 
 
@@ -89,19 +89,17 @@ static void hash_dcookie(struct dcookie_struct * dcs)
 }
 
 
-static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
-       struct vfsmount * vfsmnt)
+static struct dcookie_struct *alloc_dcookie(struct path *path)
 {
-       struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL);
+       struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache,
+                                                       GFP_KERNEL);
        if (!dcs)
                return NULL;
 
-       dentry->d_cookie = dcs;
-
-       dcs->dentry = dget(dentry);
-       dcs->vfsmnt = mntget(vfsmnt);
+       path->dentry->d_cookie = dcs;
+       dcs->path = *path;
+       path_get(path);
        hash_dcookie(dcs);
-
        return dcs;
 }
 
@@ -109,8 +107,7 @@ static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
 /* This is the main kernel-side routine that retrieves the cookie
  * value for a dentry/vfsmnt pair.
  */
-int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
-       unsigned long * cookie)
+int get_dcookie(struct path *path, unsigned long *cookie)
 {
        int err = 0;
        struct dcookie_struct * dcs;
@@ -122,10 +119,10 @@ int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt,
                goto out;
        }
 
-       dcs = dentry->d_cookie;
+       dcs = path->dentry->d_cookie;
 
        if (!dcs)
-               dcs = alloc_dcookie(dentry, vfsmnt);
+               dcs = alloc_dcookie(path);
 
        if (!dcs) {
                err = -ENOMEM;
@@ -174,7 +171,7 @@ asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len)
                goto out;
 
        /* FIXME: (deleted) ? */
-       path = d_path(dcs->dentry, dcs->vfsmnt, kbuf, PAGE_SIZE);
+       path = d_path(&dcs->path, kbuf, PAGE_SIZE);
 
        if (IS_ERR(path)) {
                err = PTR_ERR(path);
@@ -254,9 +251,8 @@ out_kmem:
 
 static void free_dcookie(struct dcookie_struct * dcs)
 {
-       dcs->dentry->d_cookie = NULL;
-       dput(dcs->dentry);
-       mntput(dcs->vfsmnt);
+       dcs->path.dentry->d_cookie = NULL;
+       path_put(&dcs->path);
        kmem_cache_free(dcookie_cache, dcs);
 }
 
index def4e96..9c7feb6 100644 (file)
@@ -1633,16 +1633,17 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
        error = path_lookup(path, LOOKUP_FOLLOW, &nd);
        if (error < 0)
                return error;
-       error = security_quota_on(nd.dentry);
+       error = security_quota_on(nd.path.dentry);
        if (error)
                goto out_path;
        /* Quota file not on the same filesystem? */
-       if (nd.mnt->mnt_sb != sb)
+       if (nd.path.mnt->mnt_sb != sb)
                error = -EXDEV;
        else
-               error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
+               error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
+                                          format_id);
 out_path:
-       path_release(&nd);
+       path_put(&nd.path);
        return error;
 }
 
index cb20b96..841a032 100644 (file)
@@ -51,13 +51,13 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 
        if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
                goto out;
-       dentry_save = nd->dentry;
-       vfsmount_save = nd->mnt;
-       nd->dentry = lower_dentry;
-       nd->mnt = lower_mnt;
+       dentry_save = nd->path.dentry;
+       vfsmount_save = nd->path.mnt;
+       nd->path.dentry = lower_dentry;
+       nd->path.mnt = lower_mnt;
        rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
-       nd->dentry = dentry_save;
-       nd->mnt = vfsmount_save;
+       nd->path.dentry = dentry_save;
+       nd->path.mnt = vfsmount_save;
        if (dentry->d_inode) {
                struct inode *lower_inode =
                        ecryptfs_inode_to_lower(dentry->d_inode);
index edd1e44..e238611 100644 (file)
@@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
        struct vfsmount *vfsmount_save;
        int rc;
 
-       dentry_save = nd->dentry;
-       vfsmount_save = nd->mnt;
-       nd->dentry = lower_dentry;
-       nd->mnt = lower_mnt;
+       dentry_save = nd->path.dentry;
+       vfsmount_save = nd->path.mnt;
+       nd->path.dentry = lower_dentry;
+       nd->path.mnt = lower_mnt;
        rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
-       nd->dentry = dentry_save;
-       nd->mnt = vfsmount_save;
+       nd->path.dentry = dentry_save;
+       nd->path.mnt = vfsmount_save;
        return rc;
 }
 
@@ -819,14 +819,14 @@ ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
        int rc;
 
         if (nd) {
-               struct vfsmount *vfsmnt_save = nd->mnt;
-               struct dentry *dentry_save = nd->dentry;
+               struct vfsmount *vfsmnt_save = nd->path.mnt;
+               struct dentry *dentry_save = nd->path.dentry;
 
-               nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
-               nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
+               nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry);
+               nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry);
                rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
-               nd->mnt = vfsmnt_save;
-               nd->dentry = dentry_save;
+               nd->path.mnt = vfsmnt_save;
+               nd->path.dentry = dentry_save;
         } else
                rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
         return rc;
index 778c420..d25ac95 100644 (file)
@@ -513,8 +513,8 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
                ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
                goto out;
        }
-       lower_root = nd.dentry;
-       lower_mnt = nd.mnt;
+       lower_root = nd.path.dentry;
+       lower_mnt = nd.path.mnt;
        ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
        sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
        sb->s_blocksize = lower_root->d_sb->s_blocksize;
@@ -526,7 +526,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
        rc = 0;
        goto out;
 out_free:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return rc;
 }
index 9ff6069..a44b142 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -112,7 +112,7 @@ asmlinkage long sys_uselib(const char __user * library)
                goto out;
 
        error = -EINVAL;
-       if (!S_ISREG(nd.dentry->d_inode->i_mode))
+       if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
                goto exit;
 
        error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
@@ -148,7 +148,7 @@ out:
        return error;
 exit:
        release_open_intent(&nd);
-       path_release(&nd);
+       path_put(&nd.path);
        goto out;
 }
 
@@ -652,7 +652,7 @@ struct file *open_exec(const char *name)
        file = ERR_PTR(err);
 
        if (!err) {
-               struct inode *inode = nd.dentry->d_inode;
+               struct inode *inode = nd.path.dentry->d_inode;
                file = ERR_PTR(-EACCES);
                if (S_ISREG(inode->i_mode)) {
                        int err = vfs_permission(&nd, MAY_EXEC);
@@ -672,7 +672,7 @@ out:
                        }
                }
                release_open_intent(&nd);
-               path_release(&nd);
+               path_put(&nd.path);
        }
        goto out;
 }
index 8e02cbf..18769cc 100644 (file)
@@ -2758,16 +2758,16 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
        if (err)
                return err;
        /* Quotafile not on the same filesystem? */
-       if (nd.mnt->mnt_sb != sb) {
-               path_release(&nd);
+       if (nd.path.mnt->mnt_sb != sb) {
+               path_put(&nd.path);
                return -EXDEV;
        }
        /* Quotafile not of fs root? */
-       if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+       if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
                printk(KERN_WARNING
                        "EXT3-fs: Quota file not on filesystem root. "
                        "Journalled quota will not work.\n");
-       path_release(&nd);
+       path_put(&nd.path);
        return vfs_quota_on(sb, type, format_id, path);
 }
 
index 0072da7..13383ba 100644 (file)
@@ -3158,16 +3158,16 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
        if (err)
                return err;
        /* Quotafile not on the same filesystem? */
-       if (nd.mnt->mnt_sb != sb) {
-               path_release(&nd);
+       if (nd.path.mnt->mnt_sb != sb) {
+               path_put(&nd.path);
                return -EXDEV;
        }
        /* Quotafile not of fs root? */
-       if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+       if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
                printk(KERN_WARNING
                        "EXT4-fs: Quota file not on filesystem root. "
                        "Journalled quota will not work.\n");
-       path_release(&nd);
+       path_put(&nd.path);
        return vfs_quota_on(sb, type, format_id, path);
 }
 
index 43d511b..4bee6aa 100644 (file)
@@ -884,12 +884,13 @@ static struct super_block* get_gfs2_sb(const char *dev_name)
                       dev_name);
                goto out;
        }
-       error = vfs_getattr(nd.mnt, nd.dentry, &stat);
+       error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat);
 
        fstype = get_fs_type("gfs2");
        list_for_each_entry(s, &fstype->fs_supers, s_instances) {
                if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
-                   (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) {
+                   (S_ISDIR(stat.mode) &&
+                    s == nd.path.dentry->d_inode->i_sb)) {
                        sb = s;
                        goto free_nd;
                }
@@ -899,7 +900,7 @@ static struct super_block* get_gfs2_sb(const char *dev_name)
               "mount point %s\n", dev_name);
 
 free_nd:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return sb;
 }
index 3ab09a6..7b94a1e 100644 (file)
@@ -41,9 +41,9 @@ static struct kmem_cache *event_cachep __read_mostly;
 static struct vfsmount *inotify_mnt __read_mostly;
 
 /* these are configurable via /proc/sys/fs/inotify/ */
-int inotify_max_user_instances __read_mostly;
-int inotify_max_user_watches __read_mostly;
-int inotify_max_queued_events __read_mostly;
+static int inotify_max_user_instances __read_mostly;
+static int inotify_max_user_watches __read_mostly;
+static int inotify_max_queued_events __read_mostly;
 
 /*
  * Lock ordering:
@@ -367,7 +367,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd,
        /* you can only watch an inode if you have read permissions on it */
        error = vfs_permission(nd, MAY_READ);
        if (error)
-               path_release(nd);
+               path_put(&nd->path);
        return error;
 }
 
@@ -667,7 +667,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
                goto fput_and_out;
 
        /* inode held in place by reference to nd; dev by fget on fd */
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
        dev = filp->private_data;
 
        mutex_lock(&dev->up_mutex);
@@ -676,7 +676,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
                ret = create_watch(dev, inode, mask);
        mutex_unlock(&dev->up_mutex);
 
-       path_release(&nd);
+       path_put(&nd.path);
 fput_and_out:
        fput_light(filp, fput_needed);
        return ret;
index 5270398..941c8e8 100644 (file)
@@ -231,7 +231,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
        struct vfsmount *mnt = NULL;
 
        if (nd)
-               mnt = nd->mnt;
+               mnt = nd->path.mnt;
 
        if (mask & MAY_WRITE) {
                umode_t mode = inode->i_mode;
@@ -296,7 +296,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
  */
 int vfs_permission(struct nameidata *nd, int mask)
 {
-       return permission(nd->dentry->d_inode, mask, nd);
+       return permission(nd->path.dentry->d_inode, mask, nd);
 }
 
 /**
@@ -362,21 +362,31 @@ int deny_write_access(struct file * file)
        return 0;
 }
 
-void path_release(struct nameidata *nd)
+/**
+ * path_get - get a reference to a path
+ * @path: path to get the reference to
+ *
+ * Given a path increment the reference count to the dentry and the vfsmount.
+ */
+void path_get(struct path *path)
 {
-       dput(nd->dentry);
-       mntput(nd->mnt);
+       mntget(path->mnt);
+       dget(path->dentry);
 }
+EXPORT_SYMBOL(path_get);
 
-/*
- * umount() mustn't call path_release()/mntput() as that would clear
- * mnt_expiry_mark
+/**
+ * path_put - put a reference to a path
+ * @path: path to put the reference to
+ *
+ * Given a path decrement the reference count to the dentry and the vfsmount.
  */
-void path_release_on_umount(struct nameidata *nd)
+void path_put(struct path *path)
 {
-       dput(nd->dentry);
-       mntput_no_expire(nd->mnt);
+       dput(path->dentry);
+       mntput(path->mnt);
 }
+EXPORT_SYMBOL(path_put);
 
 /**
  * release_open_intent - free up open intent resources
@@ -539,16 +549,16 @@ walk_init_root(const char *name, struct nameidata *nd)
        struct fs_struct *fs = current->fs;
 
        read_lock(&fs->lock);
-       if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-               nd->mnt = mntget(fs->altrootmnt);
-               nd->dentry = dget(fs->altroot);
+       if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
+               nd->path = fs->altroot;
+               path_get(&fs->altroot);
                read_unlock(&fs->lock);
                if (__emul_lookup_dentry(name,nd))
                        return 0;
                read_lock(&fs->lock);
        }
-       nd->mnt = mntget(fs->rootmnt);
-       nd->dentry = dget(fs->root);
+       nd->path = fs->root;
+       path_get(&fs->root);
        read_unlock(&fs->lock);
        return 1;
 }
@@ -561,7 +571,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
                goto fail;
 
        if (*link == '/') {
-               path_release(nd);
+               path_put(&nd->path);
                if (!walk_init_root(link, nd))
                        /* weird __emul_prefix() stuff did it */
                        goto out;
@@ -577,31 +587,31 @@ out:
         */
        name = __getname();
        if (unlikely(!name)) {
-               path_release(nd);
+               path_put(&nd->path);
                return -ENOMEM;
        }
        strcpy(name, nd->last.name);
        nd->last.name = name;
        return 0;
 fail:
-       path_release(nd);
+       path_put(&nd->path);
        return PTR_ERR(link);
 }
 
-static inline void dput_path(struct path *path, struct nameidata *nd)
+static void path_put_conditional(struct path *path, struct nameidata *nd)
 {
        dput(path->dentry);
-       if (path->mnt != nd->mnt)
+       if (path->mnt != nd->path.mnt)
                mntput(path->mnt);
 }
 
 static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
 {
-       dput(nd->dentry);
-       if (nd->mnt != path->mnt)
-               mntput(nd->mnt);
-       nd->mnt = path->mnt;
-       nd->dentry = path->dentry;
+       dput(nd->path.dentry);
+       if (nd->path.mnt != path->mnt)
+               mntput(nd->path.mnt);
+       nd->path.mnt = path->mnt;
+       nd->path.dentry = path->dentry;
 }
 
 static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
@@ -613,7 +623,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
        touch_atime(path->mnt, dentry);
        nd_set_link(nd, NULL);
 
-       if (path->mnt != nd->mnt) {
+       if (path->mnt != nd->path.mnt) {
                path_to_nameidata(path, nd);
                dget(dentry);
        }
@@ -628,8 +638,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
                if (dentry->d_inode->i_op->put_link)
                        dentry->d_inode->i_op->put_link(dentry, nd, cookie);
        }
-       dput(dentry);
-       mntput(path->mnt);
+       path_put(path);
 
        return error;
 }
@@ -661,8 +670,8 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
        nd->depth--;
        return err;
 loop:
-       dput_path(path, nd);
-       path_release(nd);
+       path_put_conditional(path, nd);
+       path_put(&nd->path);
        return err;
 }
 
@@ -743,37 +752,37 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
 
        while(1) {
                struct vfsmount *parent;
-               struct dentry *old = nd->dentry;
+               struct dentry *old = nd->path.dentry;
 
                 read_lock(&fs->lock);
-               if (nd->dentry == fs->root &&
-                   nd->mnt == fs->rootmnt) {
+               if (nd->path.dentry == fs->root.dentry &&
+                   nd->path.mnt == fs->root.mnt) {
                         read_unlock(&fs->lock);
                        break;
                }
                 read_unlock(&fs->lock);
                spin_lock(&dcache_lock);
-               if (nd->dentry != nd->mnt->mnt_root) {
-                       nd->dentry = dget(nd->dentry->d_parent);
+               if (nd->path.dentry != nd->path.mnt->mnt_root) {
+                       nd->path.dentry = dget(nd->path.dentry->d_parent);
                        spin_unlock(&dcache_lock);
                        dput(old);
                        break;
                }
                spin_unlock(&dcache_lock);
                spin_lock(&vfsmount_lock);
-               parent = nd->mnt->mnt_parent;
-               if (parent == nd->mnt) {
+               parent = nd->path.mnt->mnt_parent;
+               if (parent == nd->path.mnt) {
                        spin_unlock(&vfsmount_lock);
                        break;
                }
                mntget(parent);
-               nd->dentry = dget(nd->mnt->mnt_mountpoint);
+               nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint);
                spin_unlock(&vfsmount_lock);
                dput(old);
-               mntput(nd->mnt);
-               nd->mnt = parent;
+               mntput(nd->path.mnt);
+               nd->path.mnt = parent;
        }
-       follow_mount(&nd->mnt, &nd->dentry);
+       follow_mount(&nd->path.mnt, &nd->path.dentry);
 }
 
 /*
@@ -784,8 +793,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
 static int do_lookup(struct nameidata *nd, struct qstr *name,
                     struct path *path)
 {
-       struct vfsmount *mnt = nd->mnt;
-       struct dentry *dentry = __d_lookup(nd->dentry, name);
+       struct vfsmount *mnt = nd->path.mnt;
+       struct dentry *dentry = __d_lookup(nd->path.dentry, name);
 
        if (!dentry)
                goto need_lookup;
@@ -798,7 +807,7 @@ done:
        return 0;
 
 need_lookup:
-       dentry = real_lookup(nd->dentry, name, nd);
+       dentry = real_lookup(nd->path.dentry, name, nd);
        if (IS_ERR(dentry))
                goto fail;
        goto done;
@@ -835,7 +844,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
        if (!*name)
                goto return_reval;
 
-       inode = nd->dentry->d_inode;
+       inode = nd->path.dentry->d_inode;
        if (nd->depth)
                lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
 
@@ -883,7 +892,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
                                if (this.name[1] != '.')
                                        break;
                                follow_dotdot(nd);
-                               inode = nd->dentry->d_inode;
+                               inode = nd->path.dentry->d_inode;
                                /* fallthrough */
                        case 1:
                                continue;
@@ -892,8 +901,9 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
                 * See if the low-level filesystem might want
                 * to use its own hash..
                 */
-               if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-                       err = nd->dentry->d_op->d_hash(nd->dentry, &this);
+               if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
+                       err = nd->path.dentry->d_op->d_hash(nd->path.dentry,
+                                                           &this);
                        if (err < 0)
                                break;
                }
@@ -915,7 +925,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
                        if (err)
                                goto return_err;
                        err = -ENOENT;
-                       inode = nd->dentry->d_inode;
+                       inode = nd->path.dentry->d_inode;
                        if (!inode)
                                break;
                        err = -ENOTDIR; 
@@ -943,13 +953,14 @@ last_component:
                                if (this.name[1] != '.')
                                        break;
                                follow_dotdot(nd);
-                               inode = nd->dentry->d_inode;
+                               inode = nd->path.dentry->d_inode;
                                /* fallthrough */
                        case 1:
                                goto return_reval;
                }
-               if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-                       err = nd->dentry->d_op->d_hash(nd->dentry, &this);
+               if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
+                       err = nd->path.dentry->d_op->d_hash(nd->path.dentry,
+                                                           &this);
                        if (err < 0)
                                break;
                }
@@ -962,7 +973,7 @@ last_component:
                        err = do_follow_link(&next, nd);
                        if (err)
                                goto return_err;
-                       inode = nd->dentry->d_inode;
+                       inode = nd->path.dentry->d_inode;
                } else
                        path_to_nameidata(&next, nd);
                err = -ENOENT;
@@ -990,20 +1001,21 @@ return_reval:
                 * We bypassed the ordinary revalidation routines.
                 * We may need to check the cached dentry for staleness.
                 */
-               if (nd->dentry && nd->dentry->d_sb &&
-                   (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
+               if (nd->path.dentry && nd->path.dentry->d_sb &&
+                   (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
                        err = -ESTALE;
                        /* Note: we do not d_invalidate() */
-                       if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd))
+                       if (!nd->path.dentry->d_op->d_revalidate(
+                                       nd->path.dentry, nd))
                                break;
                }
 return_base:
                return 0;
 out_dput:
-               dput_path(&next, nd);
+               path_put_conditional(&next, nd);
                break;
        }
-       path_release(nd);
+       path_put(&nd->path);
 return_err:
        return err;
 }
@@ -1021,20 +1033,19 @@ static int link_path_walk(const char *name, struct nameidata *nd)
        int result;
 
        /* make sure the stuff we saved doesn't go away */
-       dget(save.dentry);
-       mntget(save.mnt);
+       dget(save.path.dentry);
+       mntget(save.path.mnt);
 
        result = __link_path_walk(name, nd);
        if (result == -ESTALE) {
                *nd = save;
-               dget(nd->dentry);
-               mntget(nd->mnt);
+               dget(nd->path.dentry);
+               mntget(nd->path.mnt);
                nd->flags |= LOOKUP_REVAL;
                result = __link_path_walk(name, nd);
        }
 
-       dput(save.dentry);
-       mntput(save.mnt);
+       path_put(&save.path);
 
        return result;
 }
@@ -1054,9 +1065,9 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
        if (path_walk(name, nd))
                return 0;               /* something went wrong... */
 
-       if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
-               struct dentry *old_dentry = nd->dentry;
-               struct vfsmount *old_mnt = nd->mnt;
+       if (!nd->path.dentry->d_inode ||
+           S_ISDIR(nd->path.dentry->d_inode->i_mode)) {
+               struct path old_path = nd->path;
                struct qstr last = nd->last;
                int last_type = nd->last_type;
                struct fs_struct *fs = current->fs;
@@ -1067,19 +1078,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
                 */
                nd->last_type = LAST_ROOT;
                read_lock(&fs->lock);
-               nd->mnt = mntget(fs->rootmnt);
-               nd->dentry = dget(fs->root);
+               nd->path = fs->root;
+               path_get(&fs->root);
                read_unlock(&fs->lock);
                if (path_walk(name, nd) == 0) {
-                       if (nd->dentry->d_inode) {
-                               dput(old_dentry);
-                               mntput(old_mnt);
+                       if (nd->path.dentry->d_inode) {
+                               path_put(&old_path);
                                return 1;
                        }
-                       path_release(nd);
+                       path_put(&nd->path);
                }
-               nd->dentry = old_dentry;
-               nd->mnt = old_mnt;
+               nd->path = old_path;
                nd->last = last;
                nd->last_type = last_type;
        }
@@ -1090,29 +1099,22 @@ void set_fs_altroot(void)
 {
        char *emul = __emul_prefix();
        struct nameidata nd;
-       struct vfsmount *mnt = NULL, *oldmnt;
-       struct dentry *dentry = NULL, *olddentry;
+       struct path path = {}, old_path;
        int err;
        struct fs_struct *fs = current->fs;
 
        if (!emul)
                goto set_it;
        err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
-       if (!err) {
-               mnt = nd.mnt;
-               dentry = nd.dentry;
-       }
+       if (!err)
+               path = nd.path;
 set_it:
        write_lock(&fs->lock);
-       oldmnt = fs->altrootmnt;
-       olddentry = fs->altroot;
-       fs->altrootmnt = mnt;
-       fs->altroot = dentry;
+       old_path = fs->altroot;
+       fs->altroot = path;
        write_unlock(&fs->lock);
-       if (olddentry) {
-               dput(olddentry);
-               mntput(oldmnt);
-       }
+       if (old_path.dentry)
+               path_put(&old_path);
 }
 
 /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
@@ -1130,21 +1132,21 @@ static int do_path_lookup(int dfd, const char *name,
 
        if (*name=='/') {
                read_lock(&fs->lock);
-               if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-                       nd->mnt = mntget(fs->altrootmnt);
-                       nd->dentry = dget(fs->altroot);
+               if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
+                       nd->path = fs->altroot;
+                       path_get(&fs->altroot);
                        read_unlock(&fs->lock);
                        if (__emul_lookup_dentry(name,nd))
                                goto out; /* found in altroot */
                        read_lock(&fs->lock);
                }
-               nd->mnt = mntget(fs->rootmnt);
-               nd->dentry = dget(fs->root);
+               nd->path = fs->root;
+               path_get(&fs->root);
                read_unlock(&fs->lock);
        } else if (dfd == AT_FDCWD) {
                read_lock(&fs->lock);
-               nd->mnt = mntget(fs->pwdmnt);
-               nd->dentry = dget(fs->pwd);
+               nd->path = fs->pwd;
+               path_get(&fs->pwd);
                read_unlock(&fs->lock);
        } else {
                struct dentry *dentry;
@@ -1164,17 +1166,17 @@ static int do_path_lookup(int dfd, const char *name,
                if (retval)
                        goto fput_fail;
 
-               nd->mnt = mntget(file->f_path.mnt);
-               nd->dentry = dget(dentry);
+               nd->path = file->f_path;
+               path_get(&file->f_path);
 
                fput_light(file, fput_needed);
        }
 
        retval = path_walk(name, nd);
 out:
-       if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
-                               nd->dentry->d_inode))
-               audit_inode(name, nd->dentry);
+       if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
+                               nd->path.dentry->d_inode))
+               audit_inode(name, nd->path.dentry);
 out_fail:
        return retval;
 
@@ -1208,13 +1210,13 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
        nd->flags = flags;
        nd->depth = 0;
 
-       nd->mnt = mntget(mnt);
-       nd->dentry = dget(dentry);
+       nd->path.mnt = mntget(mnt);
+       nd->path.dentry = dget(dentry);
 
        retval = path_walk(name, nd);
-       if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
-                               nd->dentry->d_inode))
-               audit_inode(name, nd->dentry);
+       if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
+                               nd->path.dentry->d_inode))
+               audit_inode(name, nd->path.dentry);
 
        return retval;
 
@@ -1236,7 +1238,7 @@ static int __path_lookup_intent_open(int dfd, const char *name,
        if (IS_ERR(nd->intent.open.file)) {
                if (err == 0) {
                        err = PTR_ERR(nd->intent.open.file);
-                       path_release(nd);
+                       path_put(&nd->path);
                }
        } else if (err != 0)
                release_open_intent(nd);
@@ -1333,10 +1335,10 @@ static struct dentry *lookup_hash(struct nameidata *nd)
 {
        int err;
 
-       err = permission(nd->dentry->d_inode, MAY_EXEC, nd);
+       err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd);
        if (err)
                return ERR_PTR(err);
-       return __lookup_hash(&nd->last, nd->dentry, nd);
+       return __lookup_hash(&nd->last, nd->path.dentry, nd);
 }
 
 static int __lookup_one_len(const char *name, struct qstr *this,
@@ -1595,7 +1597,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
 
 int may_open(struct nameidata *nd, int acc_mode, int flag)
 {
-       struct dentry *dentry = nd->dentry;
+       struct dentry *dentry = nd->path.dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -1616,7 +1618,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
        if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
                flag &= ~O_TRUNC;
        } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-               if (nd->mnt->mnt_flags & MNT_NODEV)
+               if (nd->path.mnt->mnt_flags & MNT_NODEV)
                        return -EACCES;
 
                flag &= ~O_TRUNC;
@@ -1678,14 +1680,14 @@ static int open_namei_create(struct nameidata *nd, struct path *path,
                                int flag, int mode)
 {
        int error;
-       struct dentry *dir = nd->dentry;
+       struct dentry *dir = nd->path.dentry;
 
        if (!IS_POSIXACL(dir->d_inode))
                mode &= ~current->fs->umask;
        error = vfs_create(dir->d_inode, path->dentry, mode, nd);
        mutex_unlock(&dir->d_inode->i_mutex);
-       dput(nd->dentry);
-       nd->dentry = path->dentry;
+       dput(nd->path.dentry);
+       nd->path.dentry = path->dentry;
        if (error)
                return error;
        /* Don't check for write permission, don't truncate */
@@ -1752,11 +1754,11 @@ int open_namei(int dfd, const char *pathname, int flag,
        if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len])
                goto exit;
 
-       dir = nd->dentry;
+       dir = nd->path.dentry;
        nd->flags &= ~LOOKUP_PARENT;
        mutex_lock(&dir->d_inode->i_mutex);
        path.dentry = lookup_hash(nd);
-       path.mnt = nd->mnt;
+       path.mnt = nd->path.mnt;
 
 do_last:
        error = PTR_ERR(path.dentry);
@@ -1812,11 +1814,11 @@ ok:
        return 0;
 
 exit_dput:
-       dput_path(&path, nd);
+       path_put_conditional(&path, nd);
 exit:
        if (!IS_ERR(nd->intent.open.file))
                release_open_intent(nd);
-       path_release(nd);
+       path_put(&nd->path);
        return error;
 
 do_link:
@@ -1861,10 +1863,10 @@ do_link:
                __putname(nd->last.name);
                goto exit;
        }
-       dir = nd->dentry;
+       dir = nd->path.dentry;
        mutex_lock(&dir->d_inode->i_mutex);
        path.dentry = lookup_hash(nd);
-       path.mnt = nd->mnt;
+       path.mnt = nd->path.mnt;
        __putname(nd->last.name);
        goto do_last;
 }
@@ -1877,13 +1879,13 @@ do_link:
  * Simple function to lookup and return a dentry and create it
  * if it doesn't exist.  Is SMP-safe.
  *
- * Returns with nd->dentry->d_inode->i_mutex locked.
+ * Returns with nd->path.dentry->d_inode->i_mutex locked.
  */
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
        struct dentry *dentry = ERR_PTR(-EEXIST);
 
-       mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        /*
         * Yucky last component or no last component at all?
         * (foo/., foo/.., /////)
@@ -1962,19 +1964,19 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
        dentry = lookup_create(&nd, 0);
        error = PTR_ERR(dentry);
 
-       if (!IS_POSIXACL(nd.dentry->d_inode))
+       if (!IS_POSIXACL(nd.path.dentry->d_inode))
                mode &= ~current->fs->umask;
        if (!IS_ERR(dentry)) {
                switch (mode & S_IFMT) {
                case 0: case S_IFREG:
-                       error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
+                       error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
                        break;
                case S_IFCHR: case S_IFBLK:
-                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
+                       error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
                                        new_decode_dev(dev));
                        break;
                case S_IFIFO: case S_IFSOCK:
-                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+                       error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
                        break;
                case S_IFDIR:
                        error = -EPERM;
@@ -1984,8 +1986,8 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
                }
                dput(dentry);
        }
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
-       path_release(&nd);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+       path_put(&nd.path);
 out:
        putname(tmp);
 
@@ -2039,13 +2041,13 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
        if (IS_ERR(dentry))
                goto out_unlock;
 
-       if (!IS_POSIXACL(nd.dentry->d_inode))
+       if (!IS_POSIXACL(nd.path.dentry->d_inode))
                mode &= ~current->fs->umask;
-       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+       error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
        dput(dentry);
 out_unlock:
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
-       path_release(&nd);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+       path_put(&nd.path);
 out:
        putname(tmp);
 out_err:
@@ -2143,17 +2145,17 @@ static long do_rmdir(int dfd, const char __user *pathname)
                        error = -EBUSY;
                        goto exit1;
        }
-       mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        dentry = lookup_hash(&nd);
        error = PTR_ERR(dentry);
        if (IS_ERR(dentry))
                goto exit2;
-       error = vfs_rmdir(nd.dentry->d_inode, dentry);
+       error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
        dput(dentry);
 exit2:
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 exit1:
-       path_release(&nd);
+       path_put(&nd.path);
 exit:
        putname(name);
        return error;
@@ -2219,7 +2221,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
        error = -EISDIR;
        if (nd.last_type != LAST_NORM)
                goto exit1;
-       mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+       mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        dentry = lookup_hash(&nd);
        error = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
@@ -2229,15 +2231,15 @@ static long do_unlinkat(int dfd, const char __user *pathname)
                inode = dentry->d_inode;
                if (inode)
                        atomic_inc(&inode->i_count);
-               error = vfs_unlink(nd.dentry->d_inode, dentry);
+               error = vfs_unlink(nd.path.dentry->d_inode, dentry);
        exit2:
                dput(dentry);
        }
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
        if (inode)
                iput(inode);    /* truncate the inode here */
 exit1:
-       path_release(&nd);
+       path_put(&nd.path);
 exit:
        putname(name);
        return error;
@@ -2310,11 +2312,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
        if (IS_ERR(dentry))
                goto out_unlock;
 
-       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+       error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
        dput(dentry);
 out_unlock:
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
-       path_release(&nd);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+       path_put(&nd.path);
 out:
        putname(to);
 out_putname:
@@ -2399,20 +2401,20 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
        if (error)
                goto out;
        error = -EXDEV;
-       if (old_nd.mnt != nd.mnt)
+       if (old_nd.path.mnt != nd.path.mnt)
                goto out_release;
        new_dentry = lookup_create(&nd, 0);
        error = PTR_ERR(new_dentry);
        if (IS_ERR(new_dentry))
                goto out_unlock;
-       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+       error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
        dput(new_dentry);
 out_unlock:
-       mutex_unlock(&nd.dentry->d_inode->i_mutex);
+       mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
 out_release:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
-       path_release(&old_nd);
+       path_put(&old_nd.path);
 exit:
        putname(to);
 
@@ -2588,15 +2590,15 @@ static int do_rename(int olddfd, const char *oldname,
                goto exit1;
 
        error = -EXDEV;
-       if (oldnd.mnt != newnd.mnt)
+       if (oldnd.path.mnt != newnd.path.mnt)
                goto exit2;
 
-       old_dir = oldnd.dentry;
+       old_dir = oldnd.path.dentry;
        error = -EBUSY;
        if (oldnd.last_type != LAST_NORM)
                goto exit2;
 
-       new_dir = newnd.dentry;
+       new_dir = newnd.path.dentry;
        if (newnd.last_type != LAST_NORM)
                goto exit2;
 
@@ -2640,9 +2642,9 @@ exit4:
 exit3:
        unlock_rename(new_dir, old_dir);
 exit2:
-       path_release(&newnd);
+       path_put(&newnd.path);
 exit1:
-       path_release(&oldnd);
+       path_put(&oldnd.path);
 exit:
        return error;
 }
@@ -2816,7 +2818,6 @@ EXPORT_SYMBOL(page_symlink);
 EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
 EXPORT_SYMBOL(vfs_path_lookup);
-EXPORT_SYMBOL(path_release);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(file_permission);
index 63ced21..7953c96 100644 (file)
@@ -157,13 +157,13 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
 
 static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
 {
-       old_nd->dentry = mnt->mnt_mountpoint;
-       old_nd->mnt = mnt->mnt_parent;
+       old_nd->path.dentry = mnt->mnt_mountpoint;
+       old_nd->path.mnt = mnt->mnt_parent;
        mnt->mnt_parent = mnt;
        mnt->mnt_mountpoint = mnt->mnt_root;
        list_del_init(&mnt->mnt_child);
        list_del_init(&mnt->mnt_hash);
-       old_nd->dentry->d_mounted--;
+       old_nd->path.dentry->d_mounted--;
 }
 
 void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
@@ -176,10 +176,10 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
 
 static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
 {
-       mnt_set_mountpoint(nd->mnt, nd->dentry, mnt);
+       mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt);
        list_add_tail(&mnt->mnt_hash, mount_hashtable +
-                       hash(nd->mnt, nd->dentry));
-       list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+                       hash(nd->path.mnt, nd->path.dentry));
+       list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts);
 }
 
 /*
@@ -408,10 +408,11 @@ static int show_vfsmnt(struct seq_file *m, void *v)
                { 0, NULL }
        };
        struct proc_fs_info *fs_infop;
+       struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
 
        mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
        seq_putc(m, ' ');
-       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_path(m, &mnt_path, " \t\n\\");
        seq_putc(m, ' ');
        mangle(m, mnt->mnt_sb->s_type->name);
        if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
@@ -443,6 +444,7 @@ struct seq_operations mounts_op = {
 static int show_vfsstat(struct seq_file *m, void *v)
 {
        struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list);
+       struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
        int err = 0;
 
        /* device */
@@ -454,7 +456,7 @@ static int show_vfsstat(struct seq_file *m, void *v)
 
        /* mount point */
        seq_puts(m, " mounted on ");
-       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_path(m, &mnt_path, " \t\n\\");
        seq_putc(m, ' ');
 
        /* file system type */
@@ -593,7 +595,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
         *  (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
         */
        if (flags & MNT_EXPIRE) {
-               if (mnt == current->fs->rootmnt ||
+               if (mnt == current->fs->root.mnt ||
                    flags & (MNT_FORCE | MNT_DETACH))
                        return -EINVAL;
 
@@ -628,7 +630,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
         * /reboot - static binary that would close all descriptors and
         * call reboot(9). Then init(8) could umount root and exec /reboot.
         */
-       if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
+       if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
                /*
                 * Special case for "unmounting" root ...
                 * we just try to remount it readonly.
@@ -679,18 +681,20 @@ asmlinkage long sys_umount(char __user * name, int flags)
        if (retval)
                goto out;
        retval = -EINVAL;
-       if (nd.dentry != nd.mnt->mnt_root)
+       if (nd.path.dentry != nd.path.mnt->mnt_root)
                goto dput_and_out;
-       if (!check_mnt(nd.mnt))
+       if (!check_mnt(nd.path.mnt))
                goto dput_and_out;
 
        retval = -EPERM;
        if (!capable(CAP_SYS_ADMIN))
                goto dput_and_out;
 
-       retval = do_umount(nd.mnt, flags);
+       retval = do_umount(nd.path.mnt, flags);
 dput_and_out:
-       path_release_on_umount(&nd);
+       /* we mustn't call path_put() as that would clear mnt_expiry_mark */
+       dput(nd.path.dentry);
+       mntput_no_expire(nd.path.mnt);
 out:
        return retval;
 }
@@ -713,10 +717,10 @@ static int mount_is_safe(struct nameidata *nd)
                return 0;
        return -EPERM;
 #ifdef notyet
-       if (S_ISLNK(nd->dentry->d_inode->i_mode))
+       if (S_ISLNK(nd->path.dentry->d_inode->i_mode))
                return -EPERM;
-       if (nd->dentry->d_inode->i_mode & S_ISVTX) {
-               if (current->uid != nd->dentry->d_inode->i_uid)
+       if (nd->path.dentry->d_inode->i_mode & S_ISVTX) {
+               if (current->uid != nd->path.dentry->d_inode->i_uid)
                        return -EPERM;
        }
        if (vfs_permission(nd, MAY_WRITE))
@@ -765,8 +769,8 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
                                q = q->mnt_parent;
                        }
                        p = s;
-                       nd.mnt = q;
-                       nd.dentry = p->mnt_mountpoint;
+                       nd.path.mnt = q;
+                       nd.path.dentry = p->mnt_mountpoint;
                        q = clone_mnt(p, p->mnt_root, flag);
                        if (!q)
                                goto Enomem;
@@ -875,8 +879,8 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
                        struct nameidata *nd, struct nameidata *parent_nd)
 {
        LIST_HEAD(tree_list);
-       struct vfsmount *dest_mnt = nd->mnt;
-       struct dentry *dest_dentry = nd->dentry;
+       struct vfsmount *dest_mnt = nd->path.mnt;
+       struct dentry *dest_dentry = nd->path.dentry;
        struct vfsmount *child, *p;
 
        if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
@@ -911,13 +915,13 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
        if (mnt->mnt_sb->s_flags & MS_NOUSER)
                return -EINVAL;
 
-       if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+       if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
              S_ISDIR(mnt->mnt_root->d_inode->i_mode))
                return -ENOTDIR;
 
        err = -ENOENT;
-       mutex_lock(&nd->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(nd->dentry->d_inode))
+       mutex_lock(&nd->path.dentry->d_inode->i_mutex);
+       if (IS_DEADDIR(nd->path.dentry->d_inode))
                goto out_unlock;
 
        err = security_sb_check_sb(mnt, nd);
@@ -925,10 +929,10 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
                goto out_unlock;
 
        err = -ENOENT;
-       if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
+       if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
                err = attach_recursive_mnt(mnt, nd, NULL);
 out_unlock:
-       mutex_unlock(&nd->dentry->d_inode->i_mutex);
+       mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
        if (!err)
                security_sb_post_addmount(mnt, nd);
        return err;
@@ -940,14 +944,14 @@ out_unlock:
  */
 static noinline int do_change_type(struct nameidata *nd, int flag)
 {
-       struct vfsmount *m, *mnt = nd->mnt;
+       struct vfsmount *m, *mnt = nd->path.mnt;
        int recurse = flag & MS_REC;
        int type = flag & ~MS_REC;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (nd->dentry != nd->mnt->mnt_root)
+       if (nd->path.dentry != nd->path.mnt->mnt_root)
                return -EINVAL;
 
        down_write(&namespace_sem);
@@ -979,17 +983,17 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
 
        down_write(&namespace_sem);
        err = -EINVAL;
-       if (IS_MNT_UNBINDABLE(old_nd.mnt))
-               goto out;
+       if (IS_MNT_UNBINDABLE(old_nd.path.mnt))
+               goto out;
 
-       if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+       if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
                goto out;
 
        err = -ENOMEM;
        if (recurse)
-               mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0);
+               mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0);
        else
-               mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0);
+               mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0);
 
        if (!mnt)
                goto out;
@@ -1005,7 +1009,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
 
 out:
        up_write(&namespace_sem);
-       path_release(&old_nd);
+       path_put(&old_nd.path);
        return err;
 }
 
@@ -1019,24 +1023,24 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
                      void *data)
 {
        int err;
-       struct super_block *sb = nd->mnt->mnt_sb;
+       struct super_block *sb = nd->path.mnt->mnt_sb;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (!check_mnt(nd->mnt))
+       if (!check_mnt(nd->path.mnt))
                return -EINVAL;
 
-       if (nd->dentry != nd->mnt->mnt_root)
+       if (nd->path.dentry != nd->path.mnt->mnt_root)
                return -EINVAL;
 
        down_write(&sb->s_umount);
        err = do_remount_sb(sb, flags, data, 0);
        if (!err)
-               nd->mnt->mnt_flags = mnt_flags;
+               nd->path.mnt->mnt_flags = mnt_flags;
        up_write(&sb->s_umount);
        if (!err)
-               security_sb_post_remount(nd->mnt, flags, data);
+               security_sb_post_remount(nd->path.mnt, flags, data);
        return err;
 }
 
@@ -1067,61 +1071,65 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
                return err;
 
        down_write(&namespace_sem);
-       while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+       while (d_mountpoint(nd->path.dentry) &&
+              follow_down(&nd->path.mnt, &nd->path.dentry))
                ;
        err = -EINVAL;
-       if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+       if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
                goto out;
 
        err = -ENOENT;
-       mutex_lock(&nd->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(nd->dentry->d_inode))
+       mutex_lock(&nd->path.dentry->d_inode->i_mutex);
+       if (IS_DEADDIR(nd->path.dentry->d_inode))
                goto out1;
 
-       if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
+       if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry))
                goto out1;
 
        err = -EINVAL;
-       if (old_nd.dentry != old_nd.mnt->mnt_root)
+       if (old_nd.path.dentry != old_nd.path.mnt->mnt_root)
                goto out1;
 
-       if (old_nd.mnt == old_nd.mnt->mnt_parent)
+       if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent)
                goto out1;
 
-       if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
-             S_ISDIR(old_nd.dentry->d_inode->i_mode))
+       if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
+             S_ISDIR(old_nd.path.dentry->d_inode->i_mode))
                goto out1;
        /*
         * Don't move a mount residing in a shared parent.
         */
-       if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent))
+       if (old_nd.path.mnt->mnt_parent &&
+           IS_MNT_SHARED(old_nd.path.mnt->mnt_parent))
                goto out1;
        /*
         * Don't move a mount tree containing unbindable mounts to a destination
         * mount which is shared.
         */
-       if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt))
+       if (IS_MNT_SHARED(nd->path.mnt) &&
+           tree_contains_unbindable(old_nd.path.mnt))
                goto out1;
        err = -ELOOP;
-       for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent)
-               if (p == old_nd.mnt)
+       for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent)
+               if (p == old_nd.path.mnt)
                        goto out1;
 
-       if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd)))
+       err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd);
+       if (err)
                goto out1;
 
        spin_lock(&vfsmount_lock);
        /* if the mount is moved, it should no longer be expire
         * automatically */
-       list_del_init(&old_nd.mnt->mnt_expire);
+       list_del_init(&old_nd.path.mnt->mnt_expire);
        spin_unlock(&vfsmount_lock);
 out1:
-       mutex_unlock(&nd->dentry->d_inode->i_mutex);
+       mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
        up_write(&namespace_sem);
        if (!err)
-               path_release(&parent_nd);
-       path_release(&old_nd);
+               path_put(&parent_nd.path);
+       path_put(&old_nd.path);
        return err;
 }
 
@@ -1160,16 +1168,17 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
 
        down_write(&namespace_sem);
        /* Something was mounted here while we slept */
-       while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+       while (d_mountpoint(nd->path.dentry) &&
+              follow_down(&nd->path.mnt, &nd->path.dentry))
                ;
        err = -EINVAL;
-       if (!check_mnt(nd->mnt))
+       if (!check_mnt(nd->path.mnt))
                goto unlock;
 
        /* Refuse the same filesystem on the same mount point */
        err = -EBUSY;
-       if (nd->mnt->mnt_sb == newmnt->mnt_sb &&
-           nd->mnt->mnt_root == nd->dentry)
+       if (nd->path.mnt->mnt_sb == newmnt->mnt_sb &&
+           nd->path.mnt->mnt_root == nd->path.dentry)
                goto unlock;
 
        err = -EINVAL;
@@ -1505,7 +1514,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                retval = do_new_mount(&nd, type_page, flags, mnt_flags,
                                      dev_name, data_page);
 dput_out:
-       path_release(&nd);
+       path_put(&nd.path);
        return retval;
 }
 
@@ -1552,17 +1561,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        while (p) {
                q->mnt_ns = new_ns;
                if (fs) {
-                       if (p == fs->rootmnt) {
+                       if (p == fs->root.mnt) {
                                rootmnt = p;
-                               fs->rootmnt = mntget(q);
+                               fs->root.mnt = mntget(q);
                        }
-                       if (p == fs->pwdmnt) {
+                       if (p == fs->pwd.mnt) {
                                pwdmnt = p;
-                               fs->pwdmnt = mntget(q);
+                               fs->pwd.mnt = mntget(q);
                        }
-                       if (p == fs->altrootmnt) {
+                       if (p == fs->altroot.mnt) {
                                altrootmnt = p;
-                               fs->altrootmnt = mntget(q);
+                               fs->altroot.mnt = mntget(q);
                        }
                }
                p = next_mnt(p, mnt_ns->root);
@@ -1643,44 +1652,35 @@ out1:
  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
-void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
-                struct dentry *dentry)
+void set_fs_root(struct fs_struct *fs, struct path *path)
 {
-       struct dentry *old_root;
-       struct vfsmount *old_rootmnt;
+       struct path old_root;
+
        write_lock(&fs->lock);
        old_root = fs->root;
-       old_rootmnt = fs->rootmnt;
-       fs->rootmnt = mntget(mnt);
-       fs->root = dget(dentry);
+       fs->root = *path;
+       path_get(path);
        write_unlock(&fs->lock);
-       if (old_root) {
-               dput(old_root);
-               mntput(old_rootmnt);
-       }
+       if (old_root.dentry)
+               path_put(&old_root);
 }
 
 /*
  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
-void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
-               struct dentry *dentry)
+void set_fs_pwd(struct fs_struct *fs, struct path *path)
 {
-       struct dentry *old_pwd;
-       struct vfsmount *old_pwdmnt;
+       struct path old_pwd;
 
        write_lock(&fs->lock);
        old_pwd = fs->pwd;
-       old_pwdmnt = fs->pwdmnt;
-       fs->pwdmnt = mntget(mnt);
-       fs->pwd = dget(dentry);
+       fs->pwd = *path;
+       path_get(path);
        write_unlock(&fs->lock);
 
-       if (old_pwd) {
-               dput(old_pwd);
-               mntput(old_pwdmnt);
-       }
+       if (old_pwd.dentry)
+               path_put(&old_pwd);
 }
 
 static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
@@ -1695,12 +1695,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
                if (fs) {
                        atomic_inc(&fs->count);
                        task_unlock(p);
-                       if (fs->root == old_nd->dentry
-                           && fs->rootmnt == old_nd->mnt)
-                               set_fs_root(fs, new_nd->mnt, new_nd->dentry);
-                       if (fs->pwd == old_nd->dentry
-                           && fs->pwdmnt == old_nd->mnt)
-                               set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
+                       if (fs->root.dentry == old_nd->path.dentry
+                           && fs->root.mnt == old_nd->path.mnt)
+                               set_fs_root(fs, &new_nd->path);
+                       if (fs->pwd.dentry == old_nd->path.dentry
+                           && fs->pwd.mnt == old_nd->path.mnt)
+                               set_fs_pwd(fs, &new_nd->path);
                        put_fs_struct(fs);
                } else
                        task_unlock(p);
@@ -1750,7 +1750,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
        if (error)
                goto out0;
        error = -EINVAL;
-       if (!check_mnt(new_nd.mnt))
+       if (!check_mnt(new_nd.path.mnt))
                goto out1;
 
        error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd);
@@ -1759,74 +1759,78 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
 
        error = security_sb_pivotroot(&old_nd, &new_nd);
        if (error) {
-               path_release(&old_nd);
+               path_put(&old_nd.path);
                goto out1;
        }
 
        read_lock(&current->fs->lock);
-       user_nd.mnt = mntget(current->fs->rootmnt);
-       user_nd.dentry = dget(current->fs->root);
+       user_nd.path = current->fs->root;
+       path_get(&current->fs->root);
        read_unlock(&current->fs->lock);
        down_write(&namespace_sem);
-       mutex_lock(&old_nd.dentry->d_inode->i_mutex);
+       mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
        error = -EINVAL;
-       if (IS_MNT_SHARED(old_nd.mnt) ||
-               IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
-               IS_MNT_SHARED(user_nd.mnt->mnt_parent))
+       if (IS_MNT_SHARED(old_nd.path.mnt) ||
+               IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
+               IS_MNT_SHARED(user_nd.path.mnt->mnt_parent))
                goto out2;
-       if (!check_mnt(user_nd.mnt))
+       if (!check_mnt(user_nd.path.mnt))
                goto out2;
        error = -ENOENT;
-       if (IS_DEADDIR(new_nd.dentry->d_inode))
+       if (IS_DEADDIR(new_nd.path.dentry->d_inode))
                goto out2;
-       if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
+       if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry))
                goto out2;
-       if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
+       if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
                goto out2;
        error = -EBUSY;
-       if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
+       if (new_nd.path.mnt == user_nd.path.mnt ||
+           old_nd.path.mnt == user_nd.path.mnt)
                goto out2; /* loop, on the same file system  */
        error = -EINVAL;
-       if (user_nd.mnt->mnt_root != user_nd.dentry)
+       if (user_nd.path.mnt->mnt_root != user_nd.path.dentry)
                goto out2; /* not a mountpoint */
-       if (user_nd.mnt->mnt_parent == user_nd.mnt)
+       if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt)
                goto out2; /* not attached */
-       if (new_nd.mnt->mnt_root != new_nd.dentry)
+       if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
                goto out2; /* not a mountpoint */
-       if (new_nd.mnt->mnt_parent == new_nd.mnt)
+       if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt)
                goto out2; /* not attached */
-       tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
+       /* make sure we can reach put_old from new_root */
+       tmp = old_nd.path.mnt;
        spin_lock(&vfsmount_lock);
-       if (tmp != new_nd.mnt) {
+       if (tmp != new_nd.path.mnt) {
                for (;;) {
                        if (tmp->mnt_parent == tmp)
                                goto out3; /* already mounted on put_old */
-                       if (tmp->mnt_parent == new_nd.mnt)
+                       if (tmp->mnt_parent == new_nd.path.mnt)
                                break;
                        tmp = tmp->mnt_parent;
                }
-               if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
+               if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry))
                        goto out3;
-       } else if (!is_subdir(old_nd.dentry, new_nd.dentry))
+       } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
                goto out3;
-       detach_mnt(new_nd.mnt, &parent_nd);
-       detach_mnt(user_nd.mnt, &root_parent);
-       attach_mnt(user_nd.mnt, &old_nd);     /* mount old root on put_old */
-       attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
+       detach_mnt(new_nd.path.mnt, &parent_nd);
+       detach_mnt(user_nd.path.mnt, &root_parent);
+       /* mount old root on put_old */
+       attach_mnt(user_nd.path.mnt, &old_nd);
+       /* mount new_root on / */
+       attach_mnt(new_nd.path.mnt, &root_parent);
        touch_mnt_namespace(current->nsproxy->mnt_ns);
        spin_unlock(&vfsmount_lock);
        chroot_fs_refs(&user_nd, &new_nd);
        security_sb_post_pivotroot(&user_nd, &new_nd);
        error = 0;
-       path_release(&root_parent);
-       path_release(&parent_nd);
+       path_put(&root_parent.path);
+       path_put(&parent_nd.path);
 out2:
-       mutex_unlock(&old_nd.dentry->d_inode->i_mutex);
+       mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
        up_write(&namespace_sem);
-       path_release(&user_nd);
-       path_release(&old_nd);
+       path_put(&user_nd.path);
+       path_put(&old_nd.path);
 out1:
-       path_release(&new_nd);
+       path_put(&new_nd.path);
 out0:
        unlock_kernel();
        return error;
@@ -1839,6 +1843,7 @@ static void __init init_mount_tree(void)
 {
        struct vfsmount *mnt;
        struct mnt_namespace *ns;
+       struct path root;
 
        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
        if (IS_ERR(mnt))
@@ -1857,8 +1862,11 @@ static void __init init_mount_tree(void)
        init_task.nsproxy->mnt_ns = ns;
        get_mnt_ns(ns);
 
-       set_fs_pwd(current->fs, ns->root, ns->root->mnt_root);
-       set_fs_root(current->fs, ns->root, ns->root->mnt_root);
+       root.mnt = ns->root;
+       root.dentry = ns->root->mnt_root;
+
+       set_fs_pwd(current->fs, &root);
+       set_fs_root(current->fs, &root);
 }
 
 void __init mnt_init(void)
index be4ce1c..607f6eb 100644 (file)
@@ -107,38 +107,40 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
 
        BUG_ON(IS_ROOT(dentry));
        dprintk("%s: enter\n", __FUNCTION__);
-       dput(nd->dentry);
-       nd->dentry = dget(dentry);
+       dput(nd->path.dentry);
+       nd->path.dentry = dget(dentry);
 
        /* Look it up again */
-       parent = dget_parent(nd->dentry);
+       parent = dget_parent(nd->path.dentry);
        err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
-                                                 &nd->dentry->d_name,
+                                                 &nd->path.dentry->d_name,
                                                  &fh, &fattr);
        dput(parent);
        if (err != 0)
                goto out_err;
 
        if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
-               mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+               mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
        else
-               mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr);
+               mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
+                                     &fattr);
        err = PTR_ERR(mnt);
        if (IS_ERR(mnt))
                goto out_err;
 
        mntget(mnt);
-       err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list);
+       err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
+                          &nfs_automount_list);
        if (err < 0) {
                mntput(mnt);
                if (err == -EBUSY)
                        goto out_follow;
                goto out_err;
        }
-       mntput(nd->mnt);
-       dput(nd->dentry);
-       nd->mnt = mnt;
-       nd->dentry = dget(mnt->mnt_root);
+       mntput(nd->path.mnt);
+       dput(nd->path.dentry);
+       nd->path.mnt = mnt;
+       nd->path.dentry = dget(mnt->mnt_root);
        schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
 out:
        dprintk("%s: done, returned %d\n", __FUNCTION__, err);
@@ -146,10 +148,11 @@ out:
        dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
        return ERR_PTR(err);
 out_err:
-       path_release(nd);
+       path_put(&nd->path);
        goto out;
 out_follow:
-       while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+       while (d_mountpoint(nd->path.dentry) &&
+              follow_down(&nd->path.mnt, &nd->path.dentry))
                ;
        err = 0;
        goto out;
index 027e109..7ce0786 100644 (file)
@@ -1384,11 +1384,11 @@ out_close:
 struct dentry *
 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
-       struct dentry *parent;
        struct path path = {
-               .mnt = nd->mnt,
+               .mnt = nd->path.mnt,
                .dentry = dentry,
        };
+       struct dentry *parent;
        struct iattr attr;
        struct rpc_cred *cred;
        struct nfs4_state *state;
@@ -1433,7 +1433,7 @@ int
 nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
 {
        struct path path = {
-               .mnt = nd->mnt,
+               .mnt = nd->path.mnt,
                .dentry = dentry,
        };
        struct rpc_cred *cred;
@@ -1885,7 +1885,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                  int flags, struct nameidata *nd)
 {
        struct path path = {
-               .mnt = nd->mnt,
+               .mnt = nd->path.mnt,
                .dentry = dentry,
        };
        struct nfs4_state *state;
index 51f1b31..aed8145 100644 (file)
@@ -41,9 +41,9 @@ static struct file *do_open(char *name, int flags)
                error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
 
        if (!error)
-               return dentry_open(nd.dentry, nd.mnt, flags);
+               return dentry_open(nd.path.dentry, nd.path.mnt, flags);
 
-       path_release(&nd);
+       path_put(&nd.path);
        return ERR_PTR(error);
 }
 
index 346570f..8a6f7c9 100644 (file)
@@ -63,10 +63,8 @@ static void expkey_put(struct kref *ref)
        struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
 
        if (test_bit(CACHE_VALID, &key->h.flags) &&
-           !test_bit(CACHE_NEGATIVE, &key->h.flags)) {
-               dput(key->ek_dentry);
-               mntput(key->ek_mnt);
-       }
+           !test_bit(CACHE_NEGATIVE, &key->h.flags))
+               path_put(&key->ek_path);
        auth_domain_put(key->ek_client);
        kfree(key);
 }
@@ -169,15 +167,14 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
                        goto out;
 
                dprintk("Found the path %s\n", buf);
-               key.ek_mnt = nd.mnt;
-               key.ek_dentry = nd.dentry;
-               
+               key.ek_path = nd.path;
+
                ek = svc_expkey_update(&key, ek);
                if (ek)
                        cache_put(&ek->h, &svc_expkey_cache);
                else
                        err = -ENOMEM;
-               path_release(&nd);
+               path_put(&nd.path);
        }
        cache_flush();
  out:
@@ -206,7 +203,7 @@ static int expkey_show(struct seq_file *m,
        if (test_bit(CACHE_VALID, &h->flags) && 
            !test_bit(CACHE_NEGATIVE, &h->flags)) {
                seq_printf(m, " ");
-               seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n");
+               seq_path(m, &ek->ek_path, "\\ \t\n");
        }
        seq_printf(m, "\n");
        return 0;
@@ -243,8 +240,8 @@ static inline void expkey_update(struct cache_head *cnew,
        struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
        struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
 
-       new->ek_mnt = mntget(item->ek_mnt);
-       new->ek_dentry = dget(item->ek_dentry);
+       new->ek_path = item->ek_path;
+       path_get(&item->ek_path);
 }
 
 static struct cache_head *expkey_alloc(void)
@@ -332,10 +329,9 @@ static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
 static void svc_export_put(struct kref *ref)
 {
        struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
-       dput(exp->ex_dentry);
-       mntput(exp->ex_mnt);
+       path_put(&exp->ex_path);
        auth_domain_put(exp->ex_client);
-       kfree(exp->ex_path);
+       kfree(exp->ex_pathname);
        nfsd4_fslocs_free(&exp->ex_fslocs);
        kfree(exp);
 }
@@ -349,7 +345,7 @@ static void svc_export_request(struct cache_detail *cd,
        char *pth;
 
        qword_add(bpp, blen, exp->ex_client->name);
-       pth = d_path(exp->ex_dentry, exp->ex_mnt, *bpp, *blen);
+       pth = d_path(&exp->ex_path, *bpp, *blen);
        if (IS_ERR(pth)) {
                /* is this correct? */
                (*bpp)[0] = '\n';
@@ -507,8 +503,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        struct svc_export exp, *expp;
        int an_int;
 
-       nd.dentry = NULL;
-       exp.ex_path = NULL;
+       nd.path.dentry = NULL;
+       exp.ex_pathname = NULL;
 
        /* fs locations */
        exp.ex_fslocs.locations = NULL;
@@ -547,11 +543,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 
        exp.h.flags = 0;
        exp.ex_client = dom;
-       exp.ex_mnt = nd.mnt;
-       exp.ex_dentry = nd.dentry;
-       exp.ex_path = kstrdup(buf, GFP_KERNEL);
+       exp.ex_path.mnt = nd.path.mnt;
+       exp.ex_path.dentry = nd.path.dentry;
+       exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
        err = -ENOMEM;
-       if (!exp.ex_path)
+       if (!exp.ex_pathname)
                goto out;
 
        /* expiry */
@@ -610,7 +606,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                                goto out;
                }
 
-               err = check_export(nd.dentry->d_inode, exp.ex_flags,
+               err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
                                   exp.ex_uuid);
                if (err) goto out;
        }
@@ -628,9 +624,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
  out:
        nfsd4_fslocs_free(&exp.ex_fslocs);
        kfree(exp.ex_uuid);
-       kfree(exp.ex_path);
-       if (nd.dentry)
-               path_release(&nd);
+       kfree(exp.ex_pathname);
+       if (nd.path.dentry)
+               path_put(&nd.path);
  out_no_path:
        if (dom)
                auth_domain_put(dom);
@@ -653,7 +649,7 @@ static int svc_export_show(struct seq_file *m,
                return 0;
        }
        exp = container_of(h, struct svc_export, h);
-       seq_path(m, exp->ex_mnt, exp->ex_dentry, " \t\n\\");
+       seq_path(m, &exp->ex_path, " \t\n\\");
        seq_putc(m, '\t');
        seq_escape(m, exp->ex_client->name, " \t\n\\");
        seq_putc(m, '(');
@@ -680,8 +676,8 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b)
        struct svc_export *orig = container_of(a, struct svc_export, h);
        struct svc_export *new = container_of(b, struct svc_export, h);
        return orig->ex_client == new->ex_client &&
-               orig->ex_dentry == new->ex_dentry &&
-               orig->ex_mnt == new->ex_mnt;
+               orig->ex_path.dentry == new->ex_path.dentry &&
+               orig->ex_path.mnt == new->ex_path.mnt;
 }
 
 static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
@@ -691,9 +687,9 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
 
        kref_get(&item->ex_client->ref);
        new->ex_client = item->ex_client;
-       new->ex_dentry = dget(item->ex_dentry);
-       new->ex_mnt = mntget(item->ex_mnt);
-       new->ex_path = NULL;
+       new->ex_path.dentry = dget(item->ex_path.dentry);
+       new->ex_path.mnt = mntget(item->ex_path.mnt);
+       new->ex_pathname = NULL;
        new->ex_fslocs.locations = NULL;
        new->ex_fslocs.locations_count = 0;
        new->ex_fslocs.migrated = 0;
@@ -711,8 +707,8 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
        new->ex_fsid = item->ex_fsid;
        new->ex_uuid = item->ex_uuid;
        item->ex_uuid = NULL;
-       new->ex_path = item->ex_path;
-       item->ex_path = NULL;
+       new->ex_pathname = item->ex_pathname;
+       item->ex_pathname = NULL;
        new->ex_fslocs.locations = item->ex_fslocs.locations;
        item->ex_fslocs.locations = NULL;
        new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
@@ -755,8 +751,8 @@ svc_export_lookup(struct svc_export *exp)
        struct cache_head *ch;
        int hash;
        hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
-       hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS);
-       hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS);
+       hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS);
+       hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS);
 
        ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h,
                                 hash);
@@ -772,8 +768,8 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
        struct cache_head *ch;
        int hash;
        hash = hash_ptr(old->ex_client, EXPORT_HASHBITS);
-       hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS);
-       hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS);
+       hash ^= hash_ptr(old->ex_path.dentry, EXPORT_HASHBITS);
+       hash ^= hash_ptr(old->ex_path.mnt, EXPORT_HASHBITS);
 
        ch = sunrpc_cache_update(&svc_export_cache, &new->h,
                                 &old->h,
@@ -815,8 +811,7 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv,
        key.ek_client = clp;
        key.ek_fsidtype = fsid_type;
        memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
-       key.ek_mnt = exp->ex_mnt;
-       key.ek_dentry = exp->ex_dentry;
+       key.ek_path = exp->ex_path;
        key.h.expiry_time = NEVER;
        key.h.flags = 0;
 
@@ -865,13 +860,13 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
 {
        struct svc_export *exp, key;
        int err;
-       
+
        if (!clp)
                return ERR_PTR(-ENOENT);
 
        key.ex_client = clp;
-       key.ex_mnt = mnt;
-       key.ex_dentry = dentry;
+       key.ex_path.mnt = mnt;
+       key.ex_path.dentry = dentry;
 
        exp = svc_export_lookup(&key);
        if (exp == NULL)
@@ -968,7 +963,7 @@ static int exp_fsid_hash(svc_client *clp, struct svc_export *exp)
 static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
 {
        u32 fsid[2];
-       struct inode *inode = exp->ex_dentry->d_inode;
+       struct inode *inode = exp->ex_path.dentry->d_inode;
        dev_t dev = inode->i_sb->s_dev;
 
        if (old_valid_dev(dev)) {
@@ -982,7 +977,7 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
 static void exp_unhash(struct svc_export *exp)
 {
        struct svc_expkey *ek;
-       struct inode *inode = exp->ex_dentry->d_inode;
+       struct inode *inode = exp->ex_path.dentry->d_inode;
 
        ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino);
        if (!IS_ERR(ek)) {
@@ -1030,15 +1025,16 @@ exp_export(struct nfsctl_export *nxp)
                goto out_unlock;
        err = -EINVAL;
 
-       exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
+       exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
 
        memset(&new, 0, sizeof(new));
 
        /* must make sure there won't be an ex_fsid clash */
        if ((nxp->ex_flags & NFSEXP_FSID) &&
            (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
-           fsid_key->ek_mnt &&
-           (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) )
+           fsid_key->ek_path.mnt &&
+           (fsid_key->ek_path.mnt != nd.path.mnt ||
+            fsid_key->ek_path.dentry != nd.path.dentry))
                goto finish;
 
        if (!IS_ERR(exp)) {
@@ -1054,7 +1050,7 @@ exp_export(struct nfsctl_export *nxp)
                goto finish;
        }
 
-       err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
+       err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
        if (err) goto finish;
 
        err = -ENOMEM;
@@ -1063,12 +1059,11 @@ exp_export(struct nfsctl_export *nxp)
 
        new.h.expiry_time = NEVER;
        new.h.flags = 0;
-       new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL);
-       if (!new.ex_path)
+       new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL);
+       if (!new.ex_pathname)
                goto finish;
        new.ex_client = clp;
-       new.ex_mnt = nd.mnt;
-       new.ex_dentry = nd.dentry;
+       new.ex_path = nd.path;
        new.ex_flags = nxp->ex_flags;
        new.ex_anon_uid = nxp->ex_anon_uid;
        new.ex_anon_gid = nxp->ex_anon_gid;
@@ -1089,15 +1084,14 @@ exp_export(struct nfsctl_export *nxp)
        } else
                err = 0;
 finish:
-       if (new.ex_path)
-               kfree(new.ex_path);
+       kfree(new.ex_pathname);
        if (exp)
                exp_put(exp);
        if (fsid_key && !IS_ERR(fsid_key))
                cache_put(&fsid_key->h, &svc_expkey_cache);
        if (clp)
                auth_domain_put(clp);
-       path_release(&nd);
+       path_put(&nd.path);
 out_unlock:
        exp_writeunlock();
 out:
@@ -1148,8 +1142,8 @@ exp_unexport(struct nfsctl_export *nxp)
                goto out_domain;
 
        err = -EINVAL;
-       exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
-       path_release(&nd);
+       exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
+       path_put(&nd.path);
        if (IS_ERR(exp))
                goto out_domain;
 
@@ -1185,12 +1179,12 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
                printk("nfsd: exp_rootfh path not found %s", path);
                return err;
        }
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
 
        dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
-                path, nd.dentry, clp->name,
+                path, nd.path.dentry, clp->name,
                 inode->i_sb->s_id, inode->i_ino);
-       exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
+       exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
        if (IS_ERR(exp)) {
                err = PTR_ERR(exp);
                goto out;
@@ -1200,7 +1194,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
         * fh must be initialized before calling fh_compose
         */
        fh_init(&fh, maxsize);
-       if (fh_compose(&fh, exp, nd.dentry, NULL))
+       if (fh_compose(&fh, exp, nd.path.dentry, NULL))
                err = -EINVAL;
        else
                err = 0;
@@ -1208,7 +1202,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
        fh_put(&fh);
        exp_put(exp);
 out:
-       path_release(&nd);
+       path_put(&nd.path);
        return err;
 }
 
@@ -1220,7 +1214,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
        if (IS_ERR(ek))
                return ERR_CAST(ek);
 
-       exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp);
+       exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp);
        cache_put(&ek->h, &svc_expkey_cache);
 
        if (IS_ERR(exp))
@@ -1359,7 +1353,7 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
        exp = rqst_exp_find(rqstp, FSID_NUM, fsidv);
        if (IS_ERR(exp))
                return nfserrno(PTR_ERR(exp));
-       rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
+       rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
        if (rv)
                goto out;
        rv = check_nfsd_access(exp, rqstp);
index eac8283..c721a1e 100644 (file)
@@ -67,7 +67,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
        if (nfserr)
                RETURN_STATUS(nfserr);
 
-       err = vfs_getattr(resp->fh.fh_export->ex_mnt,
+       err = vfs_getattr(resp->fh.fh_export->ex_path.mnt,
                          resp->fh.fh_dentry, &resp->stat);
        nfserr = nfserrno(err);
 
index d7647f7..17d0dd9 100644 (file)
@@ -218,7 +218,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
                int err;
                struct kstat stat;
 
-               err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat);
+               err = vfs_getattr(fhp->fh_export->ex_path.mnt, dentry, &stat);
                if (!err) {
                        *p++ = xdr_one;         /* attributes follow */
                        lease_get_mtime(dentry->d_inode, &stat.mtime);
@@ -270,7 +270,7 @@ void fill_post_wcc(struct svc_fh *fhp)
        if (fhp->fh_post_saved)
                printk("nfsd: inode locked twice during operation.\n");
 
-       err = vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry,
+       err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
                        &fhp->fh_post_attr);
        if (err)
                fhp->fh_post_saved = 0;
index 1602cd0..1ff9062 100644 (file)
@@ -120,9 +120,9 @@ out_no_tfm:
 static void
 nfsd4_sync_rec_dir(void)
 {
-       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-       nfsd_sync_dir(rec_dir.dentry);
-       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
+       nfsd_sync_dir(rec_dir.path.dentry);
+       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
 }
 
 int
@@ -142,9 +142,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
        nfs4_save_user(&uid, &gid);
 
        /* lock the parent */
-       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
 
-       dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
+       dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                goto out_unlock;
@@ -154,11 +154,11 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
                dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
                goto out_put;
        }
-       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+       status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
 out_put:
        dput(dentry);
 out_unlock:
-       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
        if (status == 0) {
                clp->cl_firststate = 1;
                nfsd4_sync_rec_dir();
@@ -221,7 +221,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
 
        nfs4_save_user(&uid, &gid);
 
-       filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
+       filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
        status = PTR_ERR(filp);
        if (IS_ERR(filp))
                goto out;
@@ -286,9 +286,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
 
        dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
 
-       mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-       dentry = lookup_one_len(name, rec_dir.dentry, namlen);
-       mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+       mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
+       dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
+       mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
        if (IS_ERR(dentry)) {
                status = PTR_ERR(dentry);
                return status;
@@ -297,7 +297,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
        if (!dentry->d_inode)
                goto out;
 
-       status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
+       status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
 out:
        dput(dentry);
        return status;
@@ -347,12 +347,12 @@ nfsd4_recdir_purge_old(void) {
 
        if (!rec_dir_init)
                return;
-       status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
+       status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
        if (status == 0)
                nfsd4_sync_rec_dir();
        if (status)
                printk("nfsd4: failed to purge old clients from recovery"
-                       " directory %s\n", rec_dir.dentry->d_name.name);
+                       " directory %s\n", rec_dir.path.dentry->d_name.name);
        return;
 }
 
@@ -373,10 +373,10 @@ int
 nfsd4_recdir_load(void) {
        int status;
 
-       status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
+       status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
        if (status)
                printk("nfsd4: failed loading clients from recovery"
-                       " directory %s\n", rec_dir.dentry->d_name.name);
+                       " directory %s\n", rec_dir.path.dentry->d_name.name);
        return status;
 }
 
@@ -415,5 +415,5 @@ nfsd4_shutdown_recdir(void)
        if (!rec_dir_init)
                return;
        rec_dir_init = 0;
-       path_release(&rec_dir);
+       path_put(&rec_dir.path);
 }
index f6744bc..bcb97d8 100644 (file)
@@ -3261,11 +3261,11 @@ nfs4_reset_recoverydir(char *recdir)
        if (status)
                return status;
        status = -ENOTDIR;
-       if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
+       if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
                nfs4_set_recdir(recdir);
                status = 0;
        }
-       path_release(&nd);
+       path_put(&nd.path);
        return status;
 }
 
index b0592e7..0e6a179 100644 (file)
@@ -1330,9 +1330,9 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *
        *stat = exp_pseudoroot(rqstp, &tmp_fh);
        if (*stat)
                return NULL;
-       rootpath = tmp_fh.fh_export->ex_path;
+       rootpath = tmp_fh.fh_export->ex_pathname;
 
-       path = exp->ex_path;
+       path = exp->ex_pathname;
 
        if (strncmp(path, rootpath, strlen(rootpath))) {
                dprintk("nfsd: fs_locations failed;"
@@ -1481,7 +1481,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                        goto out;
        }
 
-       err = vfs_getattr(exp->ex_mnt, dentry, &stat);
+       err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
        if (err)
                goto out_nfserr;
        if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
@@ -1838,9 +1838,9 @@ out_acl:
                 * and this is the root of a cross-mounted filesystem.
                 */
                if (ignore_crossmnt == 0 &&
-                   exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) {
-                       err = vfs_getattr(exp->ex_mnt->mnt_parent,
-                               exp->ex_mnt->mnt_mountpoint, &stat);
+                   exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) {
+                       err = vfs_getattr(exp->ex_path.mnt->mnt_parent,
+                               exp->ex_path.mnt->mnt_mountpoint, &stat);
                        if (err)
                                goto out_nfserr;
                }
index 8fbd2dc..0130b34 100644 (file)
@@ -47,7 +47,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
                return 1;
 
        tdentry = dget(dentry);
-       while (tdentry != exp->ex_dentry && ! IS_ROOT(tdentry)) {
+       while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) {
                /* make sure parents give x permission to user */
                int err;
                parent = dget_parent(tdentry);
@@ -59,9 +59,9 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
                dput(tdentry);
                tdentry = parent;
        }
-       if (tdentry != exp->ex_dentry)
+       if (tdentry != exp->ex_path.dentry)
                dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name);
-       rv = (tdentry == exp->ex_dentry);
+       rv = (tdentry == exp->ex_path.dentry);
        dput(tdentry);
        return rv;
 }
@@ -209,9 +209,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                        fileid_type = fh->fh_fileid_type;
 
                if (fileid_type == FILEID_ROOT)
-                       dentry = dget(exp->ex_dentry);
+                       dentry = dget(exp->ex_path.dentry);
                else {
-                       dentry = exportfs_decode_fh(exp->ex_mnt, fid,
+                       dentry = exportfs_decode_fh(exp->ex_path.mnt, fid,
                                        data_left, fileid_type,
                                        nfsd_acceptable, exp);
                }
@@ -299,7 +299,7 @@ out:
 static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
                struct dentry *dentry)
 {
-       if (dentry != exp->ex_dentry) {
+       if (dentry != exp->ex_path.dentry) {
                struct fid *fid = (struct fid *)
                        (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
                int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
@@ -344,12 +344,12 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
        struct inode * inode = dentry->d_inode;
        struct dentry *parent = dentry->d_parent;
        __u32 *datap;
-       dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev;
-       int root_export = (exp->ex_dentry == exp->ex_dentry->d_sb->s_root);
+       dev_t ex_dev = exp->ex_path.dentry->d_inode->i_sb->s_dev;
+       int root_export = (exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root);
 
        dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
                MAJOR(ex_dev), MINOR(ex_dev),
-               (long) exp->ex_dentry->d_inode->i_ino,
+               (long) exp->ex_path.dentry->d_inode->i_ino,
                parent->d_name.name, dentry->d_name.name,
                (inode ? inode->i_ino : 0));
 
@@ -391,7 +391,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
                        /* FALL THROUGH */
                case FSID_MAJOR_MINOR:
                case FSID_ENCODE_DEV:
-                       if (!(exp->ex_dentry->d_inode->i_sb->s_type->fs_flags
+                       if (!(exp->ex_path.dentry->d_inode->i_sb->s_type->fs_flags
                              & FS_REQUIRES_DEV))
                                goto retry;
                        break;
@@ -454,7 +454,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
                fhp->fh_handle.ofh_dev =  old_encode_dev(ex_dev);
                fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
                fhp->fh_handle.ofh_xino =
-                       ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
+                       ino_t_to_u32(exp->ex_path.dentry->d_inode->i_ino);
                fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
                if (inode)
                        _fh_update_old(dentry, exp, &fhp->fh_handle);
@@ -465,7 +465,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
                datap = fhp->fh_handle.fh_auth+0;
                fhp->fh_handle.fh_fsid_type = fsid_type;
                mk_fsid(fsid_type, datap, ex_dev,
-                       exp->ex_dentry->d_inode->i_ino,
+                       exp->ex_path.dentry->d_inode->i_ino,
                        exp->ex_fsid, exp->ex_uuid);
 
                len = key_len(fsid_type);
@@ -571,7 +571,7 @@ enum fsid_source fsid_source(struct svc_fh *fhp)
        case FSID_DEV:
        case FSID_ENCODE_DEV:
        case FSID_MAJOR_MINOR:
-               if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags
+               if (fhp->fh_export->ex_path.dentry->d_inode->i_sb->s_type->fs_flags
                    & FS_REQUIRES_DEV)
                        return FSIDSOURCE_DEV;
                break;
index 977a71f..6cfc96a 100644 (file)
@@ -41,7 +41,7 @@ static __be32
 nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp)
 {
        if (err) return err;
-       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
                                    resp->fh.fh_dentry,
                                    &resp->stat));
 }
@@ -49,7 +49,7 @@ static __be32
 nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
 {
        if (err) return err;
-       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
                                    resp->fh.fh_dentry,
                                    &resp->stat));
 }
@@ -164,7 +164,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
                                  &resp->count);
 
        if (nfserr) return nfserr;
-       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+       return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt,
                                    resp->fh.fh_dentry,
                                    &resp->stat));
 }
index 61ad617..afd08e2 100644 (file)
@@ -207,7 +207,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        struct kstat stat;
-       vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat);
+       vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, &stat);
        return encode_fattr(rqstp, p, fhp, &stat);
 }
 
index cc75e4f..46f59d5 100644 (file)
@@ -101,7 +101,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
 {
        struct svc_export *exp = *expp, *exp2 = NULL;
        struct dentry *dentry = *dpp;
-       struct vfsmount *mnt = mntget(exp->ex_mnt);
+       struct vfsmount *mnt = mntget(exp->ex_path.mnt);
        struct dentry *mounts = dget(dentry);
        int err = 0;
 
@@ -156,15 +156,15 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
        if (isdotent(name, len)) {
                if (len==1)
                        dentry = dget(dparent);
-               else if (dparent != exp->ex_dentry) {
+               else if (dparent != exp->ex_path.dentry)
                        dentry = dget_parent(dparent);
-               } else  if (!EX_NOHIDE(exp))
+               else if (!EX_NOHIDE(exp))
                        dentry = dget(dparent); /* .. == . just like at / */
                else {
                        /* checking mountpoint crossing is very different when stepping up */
                        struct svc_export *exp2 = NULL;
                        struct dentry *dp;
-                       struct vfsmount *mnt = mntget(exp->ex_mnt);
+                       struct vfsmount *mnt = mntget(exp->ex_path.mnt);
                        dentry = dget(dparent);
                        while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry))
                                ;
@@ -721,7 +721,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 
                DQUOT_INIT(inode);
        }
-       *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags);
+       *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
+                               flags);
        if (IS_ERR(*filp))
                host_err = PTR_ERR(*filp);
 out_nfserr:
@@ -1462,7 +1463,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
        if (!inode->i_op || !inode->i_op->readlink)
                goto out;
 
-       touch_atime(fhp->fh_export->ex_mnt, dentry);
+       touch_atime(fhp->fh_export->ex_path.mnt, dentry);
        /* N.B. Why does this call need a get_fs()??
         * Remove the set_fs and watch the fireworks:-) --okir
         */
index 43fcd60..5419853 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -127,10 +127,10 @@ asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
        error = user_path_walk(path, &nd);
        if (!error) {
                struct statfs tmp;
-               error = vfs_statfs_native(nd.dentry, &tmp);
+               error = vfs_statfs_native(nd.path.dentry, &tmp);
                if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                        error = -EFAULT;
-               path_release(&nd);
+               path_put(&nd.path);
        }
        return error;
 }
@@ -146,10 +146,10 @@ asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64
        error = user_path_walk(path, &nd);
        if (!error) {
                struct statfs64 tmp;
-               error = vfs_statfs64(nd.dentry, &tmp);
+               error = vfs_statfs64(nd.path.dentry, &tmp);
                if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
                        error = -EFAULT;
-               path_release(&nd);
+               path_put(&nd.path);
        }
        return error;
 }
@@ -233,7 +233,7 @@ static long do_sys_truncate(const char __user * path, loff_t length)
        error = user_path_walk(path, &nd);
        if (error)
                goto out;
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
 
        /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
        error = -EISDIR;
@@ -271,13 +271,13 @@ static long do_sys_truncate(const char __user * path, loff_t length)
        error = locks_verify_truncate(inode, NULL, length);
        if (!error) {
                DQUOT_INIT(inode);
-               error = do_truncate(nd.dentry, length, 0, NULL);
+               error = do_truncate(nd.path.dentry, length, 0, NULL);
        }
 
 put_write_and_out:
        put_write_access(inode);
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -455,14 +455,14 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
        res = vfs_permission(&nd, mode);
        /* SuS v2 requires we report a read only fs too */
        if(res || !(mode & S_IWOTH) ||
-          special_file(nd.dentry->d_inode->i_mode))
+          special_file(nd.path.dentry->d_inode->i_mode))
                goto out_path_release;
 
-       if(IS_RDONLY(nd.dentry->d_inode))
+       if(IS_RDONLY(nd.path.dentry->d_inode))
                res = -EROFS;
 
 out_path_release:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        current->fsuid = old_fsuid;
        current->fsgid = old_fsgid;
@@ -490,10 +490,10 @@ asmlinkage long sys_chdir(const char __user * filename)
        if (error)
                goto dput_and_out;
 
-       set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+       set_fs_pwd(current->fs, &nd.path);
 
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -501,9 +501,7 @@ out:
 asmlinkage long sys_fchdir(unsigned int fd)
 {
        struct file *file;
-       struct dentry *dentry;
        struct inode *inode;
-       struct vfsmount *mnt;
        int error;
 
        error = -EBADF;
@@ -511,9 +509,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
        if (!file)
                goto out;
 
-       dentry = file->f_path.dentry;
-       mnt = file->f_path.mnt;
-       inode = dentry->d_inode;
+       inode = file->f_path.dentry->d_inode;
 
        error = -ENOTDIR;
        if (!S_ISDIR(inode->i_mode))
@@ -521,7 +517,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
 
        error = file_permission(file, MAY_EXEC);
        if (!error)
-               set_fs_pwd(current->fs, mnt, dentry);
+               set_fs_pwd(current->fs, &file->f_path);
 out_putf:
        fput(file);
 out:
@@ -545,11 +541,11 @@ asmlinkage long sys_chroot(const char __user * filename)
        if (!capable(CAP_SYS_CHROOT))
                goto dput_and_out;
 
-       set_fs_root(current->fs, nd.mnt, nd.dentry);
+       set_fs_root(current->fs, &nd.path);
        set_fs_altroot();
        error = 0;
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -602,7 +598,7 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
        error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
        if (error)
                goto out;
-       inode = nd.dentry->d_inode;
+       inode = nd.path.dentry->d_inode;
 
        error = -EROFS;
        if (IS_RDONLY(inode))
@@ -617,11 +613,11 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
                mode = inode->i_mode;
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-       error = notify_change(nd.dentry, &newattrs);
+       error = notify_change(nd.path.dentry, &newattrs);
        mutex_unlock(&inode->i_mutex);
 
 dput_and_out:
-       path_release(&nd);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -675,8 +671,8 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group)
        error = user_path_walk(filename, &nd);
        if (error)
                goto out;
-       error = chown_common(nd.dentry, user, group);
-       path_release(&nd);
+       error = chown_common(nd.path.dentry, user, group);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -695,8 +691,8 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
        error = __user_walk_fd(dfd, filename, follow, &nd);
        if (error)
                goto out;
-       error = chown_common(nd.dentry, user, group);
-       path_release(&nd);
+       error = chown_common(nd.path.dentry, user, group);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -709,8 +705,8 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group
        error = user_path_walk_link(filename, &nd);
        if (error)
                goto out;
-       error = chown_common(nd.dentry, user, group);
-       path_release(&nd);
+       error = chown_common(nd.path.dentry, user, group);
+       path_put(&nd.path);
 out:
        return error;
 }
@@ -863,7 +859,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
                goto out;
        if (IS_ERR(dentry))
                goto out_err;
-       nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
+       nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
                                             nd->intent.open.flags - 1,
                                             nd->intent.open.file,
                                             open);
@@ -891,9 +887,10 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
        filp = nd->intent.open.file;
        /* Has the filesystem initialised the file for us? */
        if (filp->f_path.dentry == NULL)
-               filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
+               filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
+                                    NULL);
        else
-               path_release(nd);
+               path_put(&nd->path);
        return filp;
 }
 
index 7c6b4ec..88f8edf 100644 (file)
@@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk)
        return count;
 }
 
-static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+static int proc_cwd_link(struct inode *inode, struct path *path)
 {
        struct task_struct *task = get_proc_task(inode);
        struct fs_struct *fs = NULL;
@@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
        }
        if (fs) {
                read_lock(&fs->lock);
-               *mnt = mntget(fs->pwdmnt);
-               *dentry = dget(fs->pwd);
+               *path = fs->pwd;
+               path_get(&fs->pwd);
                read_unlock(&fs->lock);
                result = 0;
                put_fs_struct(fs);
@@ -174,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
        return result;
 }
 
-static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+static int proc_root_link(struct inode *inode, struct path *path)
 {
        struct task_struct *task = get_proc_task(inode);
        struct fs_struct *fs = NULL;
@@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
        }
        if (fs) {
                read_lock(&fs->lock);
-               *mnt = mntget(fs->rootmnt);
-               *dentry = dget(fs->root);
+               *path = fs->root;
+               path_get(&fs->root);
                read_unlock(&fs->lock);
                result = 0;
                put_fs_struct(fs);
@@ -1164,39 +1164,36 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
        int error = -EACCES;
 
        /* We don't need a base pointer in the /proc filesystem */
-       path_release(nd);
+       path_put(&nd->path);
 
        /* Are we allowed to snoop on the tasks file descriptors? */
        if (!proc_fd_access_allowed(inode))
                goto out;
 
-       error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
+       error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
        nd->last_type = LAST_BIND;
 out:
        return ERR_PTR(error);
 }
 
-static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
-                           char __user *buffer, int buflen)
+static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
 {
-       struct inode * inode;
        char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
-       char *path;
+       char *pathname;
        int len;
 
        if (!tmp)
                return -ENOMEM;
 
-       inode = dentry->d_inode;
-       path = d_path(dentry, mnt, tmp, PAGE_SIZE);
-       len = PTR_ERR(path);
-       if (IS_ERR(path))
+       pathname = d_path(path, tmp, PAGE_SIZE);
+       len = PTR_ERR(pathname);
+       if (IS_ERR(pathname))
                goto out;
-       len = tmp + PAGE_SIZE - 1 - path;
+       len = tmp + PAGE_SIZE - 1 - pathname;
 
        if (len > buflen)
                len = buflen;
-       if (copy_to_user(buffer, path, len))
+       if (copy_to_user(buffer, pathname, len))
                len = -EFAULT;
  out:
        free_page((unsigned long)tmp);
@@ -1207,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
 {
        int error = -EACCES;
        struct inode *inode = dentry->d_inode;
-       struct dentry *de;
-       struct vfsmount *mnt = NULL;
+       struct path path;
 
        /* Are we allowed to snoop on the tasks file descriptors? */
        if (!proc_fd_access_allowed(inode))
                goto out;
 
-       error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
+       error = PROC_I(inode)->op.proc_get_link(inode, &path);
        if (error)
                goto out;
 
-       error = do_proc_readlink(de, mnt, buffer, buflen);
-       dput(de);
-       mntput(mnt);
+       error = do_proc_readlink(&path, buffer, buflen);
+       path_put(&path);
 out:
        return error;
 }
@@ -1447,8 +1442,7 @@ out:
 
 #define PROC_FDINFO_MAX 64
 
-static int proc_fd_info(struct inode *inode, struct dentry **dentry,
-                       struct vfsmount **mnt, char *info)
+static int proc_fd_info(struct inode *inode, struct path *path, char *info)
 {
        struct task_struct *task = get_proc_task(inode);
        struct files_struct *files = NULL;
@@ -1467,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
                spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                if (file) {
-                       if (mnt)
-                               *mnt = mntget(file->f_path.mnt);
-                       if (dentry)
-                               *dentry = dget(file->f_path.dentry);
+                       if (path) {
+                               *path = file->f_path;
+                               path_get(&file->f_path);
+                       }
                        if (info)
                                snprintf(info, PROC_FDINFO_MAX,
                                         "pos:\t%lli\n"
@@ -1487,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
        return -ENOENT;
 }
 
-static int proc_fd_link(struct inode *inode, struct dentry **dentry,
-                       struct vfsmount **mnt)
+static int proc_fd_link(struct inode *inode, struct path *path)
 {
-       return proc_fd_info(inode, dentry, mnt, NULL);
+       return proc_fd_info(inode, path, NULL);
 }
 
 static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1684,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
                                      size_t len, loff_t *ppos)
 {
        char tmp[PROC_FDINFO_MAX];
-       int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
+       int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
        if (!err)
                err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
        return err;
index ea496ff..1c81c8f 100644 (file)
@@ -48,7 +48,7 @@ extern int maps_protect;
 
 extern void create_seq_entry(char *name, mode_t mode,
                                const struct file_operations *f);
-extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **);
+extern int proc_exe_link(struct inode *, struct path *);
 extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
                                struct pid *pid, struct task_struct *task);
 extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
index 5d9147b..941e951 100644 (file)
@@ -67,7 +67,7 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
                if (len < 1)
                        len = 1;
                seq_printf(m, "%*c", len, ' ');
-               seq_path(m, file->f_path.mnt, file->f_path.dentry, "");
+               seq_path(m, &file->f_path, "");
        }
 
        seq_putc(m, '\n');
index b9cb23c..614c34b 100644 (file)
@@ -407,7 +407,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *
        if (!nd || !depth)
                goto out;
 
-       dentry = nd->dentry;
+       dentry = nd->path.dentry;
        table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
 
        /* If the entry does not exist deny permission */
index ae4d3f2..49958cf 100644 (file)
@@ -75,7 +75,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
        return mm->total_vm;
 }
 
-int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+int proc_exe_link(struct inode *inode, struct path *path)
 {
        struct vm_area_struct * vma;
        int result = -ENOENT;
@@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
        }
 
        if (vma) {
-               *mnt = mntget(vma->vm_file->f_path.mnt);
-               *dentry = dget(vma->vm_file->f_path.dentry);
+               *path = vma->vm_file->f_path;
+               path_get(&vma->vm_file->f_path);
                result = 0;
        }
 
@@ -271,7 +271,7 @@ static int show_map(struct seq_file *m, void *v)
         */
        if (file) {
                pad_len_spaces(m, len);
-               seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n");
+               seq_path(m, &file->f_path, "\n");
        } else {
                const char *name = arch_vma_name(vma);
                if (!name) {
index abfc6f5..8011528 100644 (file)
@@ -103,7 +103,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
        return size;
 }
 
-int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+int proc_exe_link(struct inode *inode, struct path *path)
 {
        struct vm_list_struct *vml;
        struct vm_area_struct *vma;
@@ -126,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
        }
 
        if (vma) {
-               *mnt = mntget(vma->vm_file->f_path.mnt);
-               *dentry = dget(vma->vm_file->f_path.dentry);
+               *path = vma->vm_file->f_path;
+               path_get(&vma->vm_file->f_path);
                result = 0;
        }
 
index 6033f0c..6841452 100644 (file)
@@ -2026,29 +2026,29 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
        if (err)
                return err;
        /* Quotafile not on the same filesystem? */
-       if (nd.mnt->mnt_sb != sb) {
-               path_release(&nd);
+       if (nd.path.mnt->mnt_sb != sb) {
+               path_put(&nd.path);
                return -EXDEV;
        }
        /* We must not pack tails for quota files on reiserfs for quota IO to work */
-       if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
+       if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) {
                reiserfs_warning(sb,
                                 "reiserfs: Quota file must have tail packing disabled.");
-               path_release(&nd);
+               path_put(&nd.path);
                return -EINVAL;
        }
        /* Not journalling quota? No more tests needed... */
        if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
            !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
-               path_release(&nd);
+               path_put(&nd.path);
                return vfs_quota_on(sb, type, format_id, path);
        }
        /* Quotafile not of fs root? */
-       if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+       if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
                reiserfs_warning(sb,
                                 "reiserfs: Quota file not on filesystem root. "
                                 "Journalled quota will not work.");
-       path_release(&nd);
+       path_put(&nd.path);
        return vfs_quota_on(sb, type, format_id, path);
 }
 
index ca71c11..8537702 100644 (file)
@@ -342,13 +342,11 @@ int seq_printf(struct seq_file *m, const char *f, ...)
 }