From 3c09f4cb0b17b5bb282b6dc19d1f3435661dc119 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 10 Feb 2008 11:21:54 +0100 Subject: [PATCH] --- yaml --- r: 85507 b: refs/heads/master c: e51bfd0ad10600a9fe4c8ede5ac2272e80075008 h: refs/heads/master i: 85505: 03700c6dafecf27567bff33a6ad5352f84fa54c5 85503: a370114482318109345f25553babf64e5b7d5a31 v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 9 +- trunk/arch/alpha/kernel/osf_sys.c | 4 +- trunk/arch/blackfin/kernel/traps.c | 12 +- trunk/arch/cris/arch-v10/lib/memset.c | 397 +++++++++-------- trunk/arch/cris/arch-v32/lib/memset.c | 398 +++++++++--------- trunk/arch/m68knommu/platform/5206/Makefile | 4 +- trunk/arch/m68knommu/platform/5206e/Makefile | 4 +- trunk/arch/m68knommu/platform/520x/Makefile | 4 +- trunk/arch/m68knommu/platform/523x/Makefile | 4 +- trunk/arch/m68knommu/platform/5249/Makefile | 4 +- trunk/arch/m68knommu/platform/5272/Makefile | 4 +- trunk/arch/m68knommu/platform/527x/Makefile | 4 +- trunk/arch/m68knommu/platform/528x/Makefile | 4 +- trunk/arch/m68knommu/platform/5307/Makefile | 4 +- trunk/arch/m68knommu/platform/532x/Makefile | 4 +- trunk/arch/m68knommu/platform/5407/Makefile | 4 +- .../arch/m68knommu/platform/coldfire/Makefile | 4 +- .../arch/m68knommu/platform/coldfire/entry.S | 9 +- .../arch/m68knommu/platform/coldfire/timers.c | 17 +- trunk/arch/mips/kernel/sysirix.c | 12 +- trunk/arch/parisc/hpux/sys_hpux.c | 4 +- trunk/arch/powerpc/Kconfig | 4 + trunk/arch/powerpc/boot/Makefile | 2 - trunk/arch/powerpc/boot/ps3-hvcall.S | 2 +- trunk/arch/powerpc/kernel/Makefile | 2 - trunk/arch/powerpc/kernel/process.c | 2 +- trunk/arch/powerpc/kernel/vdso.c | 12 +- .../powerpc/oprofile/cell/spu_task_sync.c | 15 +- trunk/arch/powerpc/platforms/512x/Kconfig | 1 + trunk/arch/powerpc/platforms/52xx/Kconfig | 2 + trunk/arch/powerpc/platforms/Kconfig | 2 + trunk/arch/powerpc/platforms/Kconfig.cputype | 4 + trunk/arch/powerpc/platforms/cell/ras.c | 11 +- .../arch/powerpc/platforms/cell/spufs/inode.c | 18 +- .../powerpc/platforms/cell/spufs/syscalls.c | 2 +- .../powerpc/platforms/embedded6xx/Kconfig | 4 + trunk/arch/powerpc/platforms/iseries/vio.c | 2 +- trunk/arch/sparc64/solaris/fs.c | 12 +- trunk/arch/um/drivers/mconsole_kern.c | 6 +- trunk/arch/x86/Kconfig | 4 +- trunk/arch/x86/kernel/efi.c | 4 +- trunk/arch/x86/kernel/pci-gart_64.c | 9 - trunk/arch/x86/kernel/test_rodata.c | 2 +- trunk/arch/x86/kernel/traps_64.c | 4 +- trunk/arch/x86/mm/fault.c | 2 +- trunk/arch/x86/mm/init_32.c | 1 - trunk/arch/x86/mm/init_64.c | 1 - trunk/arch/x86/mm/pageattr.c | 17 +- trunk/drivers/block/swim3.c | 4 + trunk/drivers/char/hvc_rtas.c | 2 +- trunk/drivers/infiniband/core/cm.c | 26 +- trunk/drivers/infiniband/core/cma.c | 10 +- trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c | 17 - trunk/drivers/infiniband/hw/mlx4/mr.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_cq.c | 2 +- .../infiniband/hw/mthca/mthca_memfree.c | 1 - trunk/drivers/infiniband/ulp/ipoib/ipoib.h | 1 + trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c | 1 - trunk/drivers/macintosh/mediabay.c | 2 + trunk/drivers/md/bitmap.c | 8 +- trunk/drivers/md/dm-table.c | 4 +- trunk/drivers/md/md.c | 3 +- trunk/drivers/mtd/mtdsuper.c | 14 +- trunk/drivers/net/mlx4/mr.c | 21 +- trunk/drivers/oprofile/buffer_sync.c | 21 +- trunk/drivers/pnp/pnpbios/core.c | 2 + trunk/drivers/ps3/ps3-lpm.c | 22 +- trunk/drivers/ps3/ps3-sys-manager.c | 44 +- trunk/drivers/usb/gadget/file_storage.c | 8 +- trunk/fs/afs/mntpt.c | 23 +- trunk/fs/autofs4/root.c | 5 +- trunk/fs/binfmt_flat.c | 8 +- trunk/fs/block_dev.c | 6 +- trunk/fs/cifs/cifs_dfs_ref.c | 25 +- trunk/fs/coda/pioctl.c | 6 +- trunk/fs/compat.c | 8 +- trunk/fs/compat_ioctl.c | 2 +- trunk/fs/configfs/symlink.c | 8 +- trunk/fs/dcache.c | 103 ++--- trunk/fs/dcookies.c | 34 +- trunk/fs/dquot.c | 9 +- trunk/fs/ecryptfs/dentry.c | 12 +- trunk/fs/ecryptfs/inode.c | 24 +- trunk/fs/ecryptfs/main.c | 6 +- trunk/fs/exec.c | 8 +- trunk/fs/ext3/super.c | 8 +- trunk/fs/ext4/super.c | 8 +- trunk/fs/gfs2/ops_fstype.c | 7 +- trunk/fs/inotify_user.c | 12 +- trunk/fs/namei.c | 311 +++++++------- trunk/fs/namespace.c | 268 ++++++------ trunk/fs/nfs/namespace.c | 29 +- trunk/fs/nfs/nfs4proc.c | 8 +- trunk/fs/nfsctl.c | 4 +- trunk/fs/nfsd/export.c | 122 +++--- trunk/fs/nfsd/nfs3proc.c | 2 +- trunk/fs/nfsd/nfs3xdr.c | 4 +- trunk/fs/nfsd/nfs4recover.c | 34 +- trunk/fs/nfsd/nfs4state.c | 4 +- trunk/fs/nfsd/nfs4xdr.c | 12 +- trunk/fs/nfsd/nfsfh.c | 26 +- trunk/fs/nfsd/nfsproc.c | 6 +- trunk/fs/nfsd/nfsxdr.c | 2 +- trunk/fs/nfsd/vfs.c | 13 +- trunk/fs/open.c | 61 +-- trunk/fs/proc/base.c | 61 +-- trunk/fs/proc/internal.h | 2 +- trunk/fs/proc/nommu.c | 2 +- trunk/fs/proc/proc_sysctl.c | 2 +- trunk/fs/proc/task_mmu.c | 8 +- trunk/fs/proc/task_nommu.c | 6 +- trunk/fs/reiserfs/super.c | 14 +- trunk/fs/seq_file.c | 6 +- trunk/fs/stat.c | 19 +- trunk/fs/utimes.c | 4 +- trunk/fs/xattr.c | 32 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 8 +- trunk/include/asm-m68knommu/cacheflush.h | 14 +- trunk/include/asm-m68knommu/system.h | 2 +- trunk/include/asm-powerpc/systbl.h | 4 +- trunk/include/asm-powerpc/unistd.h | 6 +- trunk/include/asm-ppc/page.h | 2 - trunk/include/asm-x86/cacheflush.h | 7 +- trunk/include/asm-x86/kdebug.h | 1 + trunk/include/linux/audit.h | 5 +- trunk/include/linux/configfs.h | 1 - trunk/include/linux/dcache.h | 5 +- trunk/include/linux/dcookies.h | 15 +- trunk/include/linux/fs.h | 6 +- trunk/include/linux/fs_struct.h | 10 +- trunk/include/linux/module.h | 3 +- trunk/include/linux/namei.h | 11 +- trunk/include/linux/nfsd/export.h | 8 +- trunk/include/linux/path.h | 15 - trunk/include/linux/proc_fs.h | 2 +- trunk/include/linux/seq_file.h | 5 +- trunk/init/do_mounts.c | 6 +- trunk/kernel/audit.c | 12 +- trunk/kernel/audit_tree.c | 28 +- trunk/kernel/auditfilter.c | 15 +- trunk/kernel/auditsc.c | 28 +- trunk/kernel/exit.c | 12 +- trunk/kernel/fork.c | 18 +- trunk/kernel/kmod.c | 5 +- trunk/mm/memory.c | 9 +- trunk/mm/mempolicy.c | 2 +- trunk/mm/slab.c | 3 +- trunk/mm/swapfile.c | 2 +- trunk/net/sunrpc/rpc_pipe.c | 7 +- trunk/net/unix/af_unix.c | 26 +- trunk/scripts/kernel-doc | 1 + trunk/security/selinux/avc.c | 15 +- trunk/security/selinux/hooks.c | 32 +- trunk/security/selinux/include/avc.h | 6 +- trunk/security/smack/smack_lsm.c | 2 +- trunk/sound/core/seq/seq_clientmgr.c | 4 +- trunk/sound/core/seq/seq_device.c | 3 + trunk/sound/core/sound.c | 4 + trunk/sound/core/timer.c | 2 + trunk/sound/ppc/daca.c | 5 +- trunk/sound/ppc/tumbler.c | 5 +- 162 files changed, 1512 insertions(+), 1528 deletions(-) delete mode 100644 trunk/include/linux/path.h diff --git a/[refs] b/[refs] index 0624cd819992..ad01890d5a01 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cead99dcf48eeaaac0a1ececff9c979756b79294 +refs/heads/master: e51bfd0ad10600a9fe4c8ede5ac2272e80075008 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 1d2edb491b34..6680ec44779e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1255,8 +1255,8 @@ W: http://linux-net.osdl.org/index.php/DCCP S: Maintained DECnet NETWORK LAYER -P: Christine Caulfield -M: christine.caulfield@googlemail.com +P: Patrick Caulfield +M: patrick@tykepenguin.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: Christine Caulfield -M: ccaulfie@redhat.com +P: Patrick Caulfield +M: pcaulfie@redhat.com P: David Teigland M: teigland@redhat.com L: cluster-devel@redhat.com @@ -1616,7 +1616,6 @@ 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, ) diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 8c71daf94a59..973c5c3705e3 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -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.path.dentry, buffer, bufsiz); - path_put(&nd.path); + retval = do_osf_statfs(nd.dentry, buffer, bufsiz); + path_release(&nd); } return retval; } diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index 56a67ab698c7..58717cb19707 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -126,13 +126,15 @@ 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) - name = d_path(&file->f_path, _tmpbuf, - sizeof(_tmpbuf)); + if (file) { + char _tmpbuf[256]; + name = d_path(file->f_dentry, + file->f_vfsmnt, + _tmpbuf, + sizeof(_tmpbuf)); + } /* FLAT does not have its text aligned to the start of * the map while FDPIC ELF does ... diff --git a/trunk/arch/cris/arch-v10/lib/memset.c b/trunk/arch/cris/arch-v10/lib/memset.c index c94ea9b3ec29..42c1101043a3 100644 --- a/trunk/arch/cris/arch-v10/lib/memset.c +++ b/trunk/arch/cris/arch-v10/lib/memset.c @@ -1,259 +1,252 @@ -/* 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) +/*#************************************************************************#*/ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# 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 + +/* 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) { - /* Now we want the parameters in special registers. Make sure the - compiler does something usable with this. */ + /* Ok. Now we want the parameters put in special registers. + Make sure the compiler is able to make something useful of 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. Memsetting about 3..4 bytes or less get - penalized here compared to the generic implementation. */ + /* 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. */ - /* 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. */ + /* 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"); { register char *dst __asm__ ("r13") = pdst; - 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++; - } + /* This is NONPORTABLE, but since this whole routine is */ + /* grossly nonportable that doesn't matter. */ - if ((unsigned long) dst & 2) - { - *(short *) dst = lc; - n -= 2; - dst += 2; - } - } + 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; + } + } - /* 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\ + /* 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\ \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\ -" -#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\ + subq 12*4,$r12 \n\ + bge 0b \n\ + movem $r11,[$r13+] \n\ \n\ - ;; Compensate for last loop underflowing n. \n\ - addq 12*4,r12 \n\ + addq 12*4,$r12 ;; compensate for last loop underflowing n \n\ \n\ - ;; Restore registers from stack. \n\ - movem [sp+],r10" + ;; Restore registers from stack \n\ + movem [$sp+],$r10" - /* Outputs. */ - : "=r" (dst), "=r" (n) + /* Outputs */ : "=r" (dst), "=r" (n) + /* Inputs */ : "0" (dst), "1" (n), "r" (lc)); - /* 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: - *dst = (char) lc; + *(char*)dst = (char) lc; break; - case 2: - *(short *) dst = (short) lc; + *(short*)dst = (short) lc; break; - case 3: - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 4: - *(long *) dst = lc; + *((long*)dst)++ = lc; break; - case 5: - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 6: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 7: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 8: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 9: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 10: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 11: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 12: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 13: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 14: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 15: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - } + } } - return return_dst; -} + return return_dst; /* destination pointer. */ +} /* memset() */ diff --git a/trunk/arch/cris/arch-v32/lib/memset.c b/trunk/arch/cris/arch-v32/lib/memset.c index c94ea9b3ec29..ffca1214674e 100644 --- a/trunk/arch/cris/arch-v32/lib/memset.c +++ b/trunk/arch/cris/arch-v32/lib/memset.c @@ -1,259 +1,253 @@ -/* 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) +/*#************************************************************************#*/ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# 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 + +/* 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) { - /* Now we want the parameters in special registers. Make sure the - compiler does something usable with this. */ + /* Ok. Now we want the parameters put in special registers. + Make sure the compiler is able to make something useful of 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. Memsetting about 3..4 bytes or less get - penalized here compared to the generic implementation. */ + /* 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. */ - /* 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. */ + /* 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"); { register char *dst __asm__ ("r13") = pdst; - 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++; - } + /* This is NONPORTABLE, but since this whole routine is */ + /* grossly nonportable that doesn't matter. */ - if ((unsigned long) dst & 2) - { - *(short *) dst = lc; - n -= 2; - dst += 2; - } - } + 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; + } + } - /* 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\ + /* 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\ \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\ -" -#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\ + subq 12*4,$r12 \n\ + bge 0b \n\ + movem $r11,[$r13+] \n\ \n\ - ;; Compensate for last loop underflowing n. \n\ - addq 12*4,r12 \n\ + addq 12*4,$r12 ;; compensate for last loop underflowing n \n\ \n\ - ;; Restore registers from stack. \n\ - movem [sp+],r10" - - /* Outputs. */ - : "=r" (dst), "=r" (n) + ;; Restore registers from stack \n\ + movem [$sp+],$r10" - /* 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; - } + /* Outputs */ : "=r" (dst), "=r" (n) + /* Inputs */ : "0" (dst), "1" (n), "r" (lc)); + } + /* 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: - *dst = (char) lc; + *(char*)dst = (char) lc; break; - case 2: - *(short *) dst = (short) lc; + *(short*)dst = (short) lc; break; - case 3: - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 4: - *(long *) dst = lc; + *((long*)dst)++ = lc; break; - case 5: - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 6: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 7: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 8: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 9: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 10: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 11: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 12: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 13: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 14: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 15: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - } + } } - return return_dst; -} + return return_dst; /* destination pointer. */ +} /* memset() */ diff --git a/trunk/arch/m68knommu/platform/5206/Makefile b/trunk/arch/m68knommu/platform/5206/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5206/Makefile +++ b/trunk/arch/m68knommu/platform/5206/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5206e/Makefile b/trunk/arch/m68knommu/platform/5206e/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5206e/Makefile +++ b/trunk/arch/m68knommu/platform/5206e/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/520x/Makefile b/trunk/arch/m68knommu/platform/520x/Makefile index a50e76acc8fd..31b4eb51739d 100644 --- a/trunk/arch/m68knommu/platform/520x/Makefile +++ b/trunk/arch/m68knommu/platform/520x/Makefile @@ -12,6 +12,8 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/523x/Makefile b/trunk/arch/m68knommu/platform/523x/Makefile index 5694d593f029..ac9fbece8a4f 100644 --- a/trunk/arch/m68knommu/platform/523x/Makefile +++ b/trunk/arch/m68knommu/platform/523x/Makefile @@ -12,6 +12,8 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5249/Makefile b/trunk/arch/m68knommu/platform/5249/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5249/Makefile +++ b/trunk/arch/m68knommu/platform/5249/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5272/Makefile b/trunk/arch/m68knommu/platform/5272/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/5272/Makefile +++ b/trunk/arch/m68knommu/platform/5272/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/527x/Makefile b/trunk/arch/m68knommu/platform/527x/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/527x/Makefile +++ b/trunk/arch/m68knommu/platform/527x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/528x/Makefile b/trunk/arch/m68knommu/platform/528x/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/528x/Makefile +++ b/trunk/arch/m68knommu/platform/528x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5307/Makefile b/trunk/arch/m68knommu/platform/5307/Makefile index cfd586860fd8..580fd6658d7c 100644 --- a/trunk/arch/m68knommu/platform/5307/Makefile +++ b/trunk/arch/m68knommu/platform/5307/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y += config.o diff --git a/trunk/arch/m68knommu/platform/532x/Makefile b/trunk/arch/m68knommu/platform/532x/Makefile index e431912f5628..475b92866a9b 100644 --- a/trunk/arch/m68knommu/platform/532x/Makefile +++ b/trunk/arch/m68knommu/platform/532x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif #obj-y := config.o usb-mcf532x.o spi-mcf532x.o obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5407/Makefile b/trunk/arch/m68knommu/platform/5407/Makefile index e6035e7a2d3f..68633b27df51 100644 --- a/trunk/arch/m68knommu/platform/5407/Makefile +++ b/trunk/arch/m68knommu/platform/5407/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/coldfire/Makefile b/trunk/arch/m68knommu/platform/coldfire/Makefile index 40cf20be1b90..e5fff297ae01 100644 --- a/trunk/arch/m68knommu/platform/coldfire/Makefile +++ b/trunk/arch/m68knommu/platform/coldfire/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o obj-$(CONFIG_M5206) += timers.o diff --git a/trunk/arch/m68knommu/platform/coldfire/entry.S b/trunk/arch/m68knommu/platform/coldfire/entry.S index 111b66dc737b..b333731b875a 100644 --- a/trunk/arch/m68knommu/platform/coldfire/entry.S +++ b/trunk/arch/m68knommu/platform/coldfire/entry.S @@ -197,13 +197,14 @@ ENTRY(fasthandler) RESTORE_LOCAL ENTRY(ret_from_interrupt) + jeq 2f +1: + RESTORE_ALL +2: moveb %sp@(PT_SR),%d0 andl #0x7,%d0 - jeq 1f + jhi 1b - RESTORE_ALL - -1: /* check if we need to do software interrupts */ movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0 jeq ret_from_exception diff --git a/trunk/arch/m68knommu/platform/coldfire/timers.c b/trunk/arch/m68knommu/platform/coldfire/timers.c index ba5a9f32ebd4..a60213e877ef 100644 --- a/trunk/arch/m68knommu/platform/coldfire/timers.c +++ b/trunk/arch/m68knommu/platform/coldfire/timers.c @@ -148,32 +148,25 @@ 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); + profile_tick(CPU_PROFILING, regs); 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); - - setup_irq(mcf_profilevector, &coldfire_profile_irq); + printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); - __raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); + __raw_writetrr(((MCF_CLK / 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); } diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 672fba84b2cc..d70c4e0e85fb 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __user *path, if (error) goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); + error = vfs_statfs(nd.dentry, &kbuf); if (error) goto dput_and_out; @@ -711,7 +711,7 @@ asmlinkage int irix_statfs(const char __user *path, } dput_and_out: - path_put(&nd.path); + path_release(&nd); 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.path.dentry, &kbuf); + error = vfs_statfs(nd.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_put(&nd.path); + path_release(&nd); 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.path.dentry, &kbuf); + error = vfs_statfs(nd.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_put(&nd.path); + path_release(&nd); out: return error; } diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index 0c5b9dabb475..3e025df2dc86 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -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.path.dentry, &tmp); + error = vfs_statfs_hpux(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } return error; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 5b8d8382b762..485513c9f1af 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -442,6 +442,10 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config WANT_DEVICE_TREE + bool + default n + endmenu config ISA_DMA_API diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 63d07ccbb9db..49797a45416c 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -147,8 +147,6 @@ 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 diff --git a/trunk/arch/powerpc/boot/ps3-hvcall.S b/trunk/arch/powerpc/boot/ps3-hvcall.S index d6068f1829ca..585965f7e6a8 100644 --- a/trunk/arch/powerpc/boot/ps3-hvcall.S +++ b/trunk/arch/powerpc/boot/ps3-hvcall.S @@ -145,7 +145,7 @@ .macro STORE_REGS_5_2 lwz r11, 16(r1) std r4, 0(r11) - lwz r11, 20(r1) + lwz r11, 24(r1) std r5, 0(r11) .endm diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index c1baf9d5903f..0662ae46f724 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -104,5 +104,3 @@ 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 diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 4846bf543a8c..b9d88374f14f 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -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", raw_smp_processor_id()); + printk(" CPU: %d", smp_processor_id()); #endif /* CONFIG_SMP */ for (i = 0; i < 32; i++) { diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index d3437c4c4a6f..3702df7dc567 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -336,9 +336,9 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib, return sym->st_value - VDSO32_LBASE; } -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) +static int 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 __init vdso_do_func_patch64(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) +static int vdso_do_func_patch64(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64, + const char *orig, const char *fix) { Elf64_Sym *sym64_gen, *sym64_fix; diff --git a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c b/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c index 257b13cb18af..4a890cb42b98 100644 --- a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -198,13 +198,14 @@ static int release_cached_info(int spu_index) * dcookie user still being registered (namely, the reader * of the event buffer). */ -static inline unsigned long fast_get_dcookie(struct path *path) +static inline unsigned long fast_get_dcookie(struct dentry *dentry, + struct vfsmount *vfsmnt) { unsigned long cookie; - if (path->dentry->d_cookie) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); + if (dentry->d_cookie) + return (unsigned long)dentry; + get_dcookie(dentry, vfsmnt, &cookie); return cookie; } @@ -239,7 +240,8 @@ 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_path); + app_cookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); app = vma->vm_file; @@ -260,7 +262,8 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, break; } - *spu_bin_dcookie = fast_get_dcookie(&vma->vm_file->f_path); + *spu_bin_dcookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); up_read(&mm->mmap_sem); diff --git a/trunk/arch/powerpc/platforms/512x/Kconfig b/trunk/arch/powerpc/platforms/512x/Kconfig index 4c0da0c079e9..c6fa49e23dc0 100644 --- a/trunk/arch/powerpc/platforms/512x/Kconfig +++ b/trunk/arch/powerpc/platforms/512x/Kconfig @@ -13,6 +13,7 @@ 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. diff --git a/trunk/arch/powerpc/platforms/52xx/Kconfig b/trunk/arch/powerpc/platforms/52xx/Kconfig index cf945d55c276..515f244c90bb 100644 --- a/trunk/arch/powerpc/platforms/52xx/Kconfig +++ b/trunk/arch/powerpc/platforms/52xx/Kconfig @@ -8,6 +8,7 @@ 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 @@ -34,6 +35,7 @@ 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" diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index 0afd22595546..fcedbec07f94 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -15,6 +15,7 @@ config PPC_MULTIPLATFORM config PPC_82xx bool "Freescale 82xx" depends on 6xx + select WANT_DEVICE_TREE config PPC_83xx bool "Freescale 83xx" @@ -22,6 +23,7 @@ config PPC_83xx select FSL_SOC select MPC83xx select IPIC + select WANT_DEVICE_TREE select FSL_EMB_PERFMON config PPC_86xx diff --git a/trunk/arch/powerpc/platforms/Kconfig.cputype b/trunk/arch/powerpc/platforms/Kconfig.cputype index 73d81ce14b67..69941ba70975 100644 --- a/trunk/arch/powerpc/platforms/Kconfig.cputype +++ b/trunk/arch/powerpc/platforms/Kconfig.cputype @@ -29,22 +29,26 @@ 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 diff --git a/trunk/arch/powerpc/platforms/cell/ras.c b/trunk/arch/powerpc/platforms/cell/ras.c index e43024c0392e..b2494ebcdbe9 100644 --- a/trunk/arch/powerpc/platforms/cell/ras.c +++ b/trunk/arch/powerpc/platforms/cell/ras.c @@ -1,13 +1,4 @@ -/* - * 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 +#define DEBUG #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 6d1228c66c5e..e6e6559c55ed 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -1,4 +1,3 @@ - /* * SPU file system * @@ -593,7 +592,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, ret = -EINVAL; /* check if we are on spufs */ - if (nd->path.dentry->d_sb->s_type != &spufs_type) + if (nd->dentry->d_sb->s_type != &spufs_type) goto out; /* don't accept undefined flags */ @@ -601,9 +600,9 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, goto out; /* only threads can be underneath a gang */ - if (nd->path.dentry != nd->path.dentry->d_sb->s_root) { + if (nd->dentry != nd->dentry->d_sb->s_root) { if ((flags & SPU_CREATE_GANG) || - !SPUFS_I(nd->path.dentry->d_inode)->i_gang) + !SPUFS_I(nd->dentry->d_inode)->i_gang) goto out; } @@ -619,17 +618,16 @@ 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->path.dentry->d_inode, - dentry, nd->path.mnt, mode); + return spufs_create_gang(nd->dentry->d_inode, + dentry, nd->mnt, mode); else - return spufs_create_context(nd->path.dentry->d_inode, - dentry, nd->path.mnt, flags, mode, - filp); + return spufs_create_context(nd->dentry->d_inode, + dentry, nd->mnt, flags, mode, filp); out_dput: dput(dentry); out_dir: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); out: return ret; } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index 49c87769b1f8..430404413178 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -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_put(&nd.path); + path_release(&nd); } putname(tmp); } diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 429088967813..6c8083757938 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -24,6 +24,7 @@ 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 @@ -36,6 +37,7 @@ 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) @@ -46,6 +48,7 @@ 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 @@ -56,6 +59,7 @@ 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 diff --git a/trunk/arch/powerpc/platforms/iseries/vio.c b/trunk/arch/powerpc/platforms/iseries/vio.c index 657b72f68493..be06cfd9fa3d 100644 --- a/trunk/arch/powerpc/platforms/iseries/vio.c +++ b/trunk/arch/powerpc/platforms/iseries/vio.c @@ -75,7 +75,7 @@ static struct property *new_property(const char *name, int length, return np; } -static void free_property(struct property *np) +static void __init free_property(struct property *np) { kfree(np); } diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c index 7d035f0d3ae1..9311bfe4f2f7 100644 --- a/trunk/arch/sparc64/solaris/fs.c +++ b/trunk/arch/sparc64/solaris/fs.c @@ -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.path.dentry->d_inode; - error = report_statvfs(nd.path.mnt, inode, buf); - path_put(&nd.path); + struct inode * inode = nd.dentry->d_inode; + error = report_statvfs(nd.mnt, inode, buf); + path_release(&nd); } 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.path.dentry->d_inode; - error = report_statvfs64(nd.path.mnt, inode, buf); - path_put(&nd.path); + struct inode * inode = nd.dentry->d_inode; + error = report_statvfs64(nd.mnt, inode, buf); + path_release(&nd); } unlock_kernel(); return error; diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 19d579d74d27..ebb265c07e4d 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -145,8 +145,8 @@ void mconsole_proc(struct mc_request *req) } up_write(&super->s_umount); - nd.path.dentry = super->s_root; - nd.path.mnt = NULL; + nd.dentry = super->s_root; + nd.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.path.dentry, nd.path.mnt, O_RDONLY); + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); if (IS_ERR(file)) { mconsole_reply(req, "Failed to open file", 1, 0); goto out_kill; diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 3be2305709b7..aaed1a3b92d6 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -21,8 +21,6 @@ config X86 select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES - select HAVE_KVM - config GENERIC_LOCKBREAK def_bool n @@ -121,6 +119,8 @@ config ARCH_HAS_CPU_RELAX config HAVE_SETUP_PER_CPU_AREA def_bool X86_64 +select HAVE_KVM + config ARCH_HIBERNATION_POSSIBLE def_bool y depends on !SMP || !X86_VOYAGER diff --git a/trunk/arch/x86/kernel/efi.c b/trunk/arch/x86/kernel/efi.c index 0c0eeb163d90..cbdf9bacc575 100644 --- a/trunk/arch/x86/kernel/efi.c +++ b/trunk/arch/x86/kernel/efi.c @@ -391,7 +391,7 @@ static void __init runtime_code_page_mkexec(void) if (md->type != EFI_RUNTIME_SERVICES_CODE) continue; - set_memory_x(md->virt_addr, md->num_pages); + set_memory_x(md->virt_addr, md->num_pages << EFI_PAGE_SHIFT); } } @@ -434,7 +434,7 @@ void __init efi_enter_virtual_mode(void) } if (!(md->attribute & EFI_MEMORY_WB)) - set_memory_uc(md->virt_addr, md->num_pages); + set_memory_uc(md->virt_addr, size); systab = (u64) (unsigned long) efi_phys.systab; if (md->phys_addr <= systab && systab < end) { diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index faf3229f8fb3..65f6acb025c8 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -749,15 +749,6 @@ void __init gart_iommu_init(void) */ set_memory_np((unsigned long)__va(iommu_bus_base), iommu_size >> PAGE_SHIFT); - /* - * Tricky. The GART table remaps the physical memory range, - * so the CPU wont notice potential aliases and if the memory - * is remapped to UC later on, we might surprise the PCI devices - * with a stray writeout of a cacheline. So play it sure and - * do an explicit, full-scale wbinvd() _after_ having marked all - * the pages as Not-Present: - */ - wbinvd(); /* * Try to workaround a bug (thanks to BenH) diff --git a/trunk/arch/x86/kernel/test_rodata.c b/trunk/arch/x86/kernel/test_rodata.c index c29e235792af..4c163772000e 100644 --- a/trunk/arch/x86/kernel/test_rodata.c +++ b/trunk/arch/x86/kernel/test_rodata.c @@ -10,8 +10,8 @@ * of the License. */ #include -#include #include +extern int rodata_test_data; int rodata_test(void) { diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c index 045466681911..efc66df728b6 100644 --- a/trunk/arch/x86/kernel/traps_64.c +++ b/trunk/arch/x86/kernel/traps_64.c @@ -84,7 +84,7 @@ static inline void conditional_sti(struct pt_regs *regs) static inline void preempt_conditional_sti(struct pt_regs *regs) { - inc_preempt_count(); + preempt_disable(); if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } @@ -95,7 +95,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) local_irq_disable(); /* Make sure to not schedule here because we could be running on an exception stack. */ - dec_preempt_count(); + preempt_enable_no_resched(); } int kstack_depth_to_print = 12; diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index fdc667422df9..621afb6343dc 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -186,7 +186,7 @@ static int bad_address(void *p) } #endif -static void dump_pagetable(unsigned long address) +void dump_pagetable(unsigned long address) { #ifdef CONFIG_X86_32 __typeof__(pte_val(__pte(0))) page; diff --git a/trunk/arch/x86/mm/init_32.c b/trunk/arch/x86/mm/init_32.c index ee1091a46964..8106bba41ecb 100644 --- a/trunk/arch/x86/mm/init_32.c +++ b/trunk/arch/x86/mm/init_32.c @@ -47,7 +47,6 @@ #include #include #include -#include unsigned int __VMALLOC_RESERVE = 128 << 20; diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index a4a9cccdd4f2..b59fc238151f 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -45,7 +45,6 @@ #include #include #include -#include const struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 4119379f80ff..bd61ed13f9cf 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -688,15 +688,6 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, if (!pgprot_val(mask_set) && !pgprot_val(mask_clr)) return 0; - /* Ensure we are PAGE_SIZE aligned */ - if (addr & ~PAGE_MASK) { - addr &= PAGE_MASK; - /* - * People should not be passing in unaligned addresses: - */ - WARN_ON_ONCE(1); - } - cpa.vaddr = addr; cpa.numpages = numpages; cpa.mask_set = mask_set; @@ -870,12 +861,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) return; /* - * The return value is ignored as the calls cannot fail. - * Large pages are kept enabled at boot time, and are - * split up quickly with DEBUG_PAGEALLOC. If a splitup - * fails here (due to temporary memory shortage) no damage - * is done because we just keep the largepage intact up - * to the next attempt when it will likely be split up: + * The return value is ignored - the calls cannot fail, + * large pages are disabled at boot time: */ if (enable) __set_pages_p(page, numpages); diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index 730ccea78e45..b4e462f154ea 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -251,6 +251,10 @@ 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; diff --git a/trunk/drivers/char/hvc_rtas.c b/trunk/drivers/char/hvc_rtas.c index 88590d040046..bb09413d5a21 100644 --- a/trunk/drivers/char/hvc_rtas.c +++ b/trunk/drivers/char/hvc_rtas.c @@ -76,7 +76,7 @@ static struct hv_ops hvc_rtas_get_put_ops = { .put_chars = hvc_rtas_write_console, }; -static int __init hvc_rtas_init(void) +static int hvc_rtas_init(void) { struct hvc_struct *hp; diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index b10ade92efed..638b727d42e0 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -3587,6 +3587,8 @@ static void cm_release_port_obj(struct kobject *obj) { struct cm_port *cm_port; + printk(KERN_ERR "free cm port\n"); + cm_port = container_of(obj, struct cm_port, port_obj); kfree(cm_port); } @@ -3599,6 +3601,8 @@ static void cm_release_dev_obj(struct kobject *obj) { struct cm_device *cm_dev; + printk(KERN_ERR "free cm dev\n"); + cm_dev = container_of(obj, struct cm_device, dev_obj); kfree(cm_dev); } @@ -3612,12 +3616,18 @@ struct class cm_class = { }; EXPORT_SYMBOL(cm_class); +static void cm_remove_fs_obj(struct kobject *obj) +{ + kobject_put(obj->parent); + kobject_put(obj); +} + static int cm_create_port_fs(struct cm_port *port) { int i, ret; ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type, - &port->cm_dev->dev_obj, + kobject_get(&port->cm_dev->dev_obj), "%d", port->port_num); if (ret) { kfree(port); @@ -3627,7 +3637,7 @@ static int cm_create_port_fs(struct cm_port *port) for (i = 0; i < CM_COUNTER_GROUPS; i++) { ret = kobject_init_and_add(&port->counter_group[i].obj, &cm_counter_obj_type, - &port->port_obj, + kobject_get(&port->port_obj), "%s", counter_group_names[i]); if (ret) goto error; @@ -3637,8 +3647,8 @@ static int cm_create_port_fs(struct cm_port *port) error: while (i--) - kobject_put(&port->counter_group[i].obj); - kobject_put(&port->port_obj); + cm_remove_fs_obj(&port->counter_group[i].obj); + cm_remove_fs_obj(&port->port_obj); return ret; } @@ -3648,9 +3658,9 @@ static void cm_remove_port_fs(struct cm_port *port) int i; for (i = 0; i < CM_COUNTER_GROUPS; i++) - kobject_put(&port->counter_group[i].obj); + cm_remove_fs_obj(&port->counter_group[i].obj); - kobject_put(&port->port_obj); + cm_remove_fs_obj(&port->port_obj); } static void cm_add_one(struct ib_device *device) @@ -3734,7 +3744,7 @@ static void cm_add_one(struct ib_device *device) ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - kobject_put(&cm_dev->dev_obj); + cm_remove_fs_obj(&cm_dev->dev_obj); } static void cm_remove_one(struct ib_device *device) @@ -3761,7 +3771,7 @@ static void cm_remove_one(struct ib_device *device) ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - kobject_put(&cm_dev->dev_obj); + cm_remove_fs_obj(&cm_dev->dev_obj); } static int __init ib_cm_init(void) diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 34507daaf9b6..1eff1b2c0e08 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -1107,6 +1107,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) event.param.ud.private_data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE - offset; } else { + ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); conn_id = cma_new_conn_id(&listen_id->id, ib_event); cma_set_req_event_data(&event, &ib_event->param.req_rcvd, ib_event->private_data, offset); @@ -1129,15 +1130,6 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) ret = conn_id->id.event_handler(&conn_id->id, &event); if (!ret) { - /* - * Acquire mutex to prevent user executing rdma_destroy_id() - * while we're accessing the cm_id. - */ - mutex_lock(&lock); - if (cma_comp(conn_id, CMA_CONNECT) && - !cma_is_ud_ps(conn_id->id.ps)) - ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); - mutex_unlock(&lock); cma_enable_remove(conn_id); goto out; } diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c index 320f2b6ddee6..e9a08fa3dffe 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -1785,17 +1784,6 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) return err; } -static int is_loopback_dst(struct iw_cm_id *cm_id) -{ - struct net_device *dev; - - dev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr); - if (!dev) - return 0; - dev_put(dev); - return 1; -} - int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { int err = 0; @@ -1803,11 +1791,6 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct iwch_ep *ep; struct rtable *rt; - if (is_loopback_dst(cm_id)) { - err = -ENOSYS; - goto out; - } - ep = alloc_ep(sizeof(*ep), GFP_KERNEL); if (!ep) { printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __FUNCTION__); diff --git a/trunk/drivers/infiniband/hw/mlx4/mr.c b/trunk/drivers/infiniband/hw/mlx4/mr.c index fe2c2e94a5f8..7dc91a3e712d 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mr.c +++ b/trunk/drivers/infiniband/hw/mlx4/mr.c @@ -199,7 +199,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, if (err) goto err_free; - err = mlx4_fmr_enable(to_mdev(pd->device)->dev, &fmr->mfmr); + err = mlx4_mr_enable(to_mdev(pd->device)->dev, &fmr->mfmr.mr); if (err) goto err_mr; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 1e1e336d3ef9..6bd9f1393349 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -473,7 +473,7 @@ static void handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd)) return; - be16_add_cpu(&cqe->db_cnt, -dbd); + cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd); cqe->wqe = new_wqe; cqe->syndrome = SYNDROME_WR_FLUSH_ERR; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c index 252db0822f6c..1f4d27d7c16d 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -542,7 +542,6 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) for (i = 0; i < npages; ++i) { db_tab->page[i].refcount = 0; db_tab->page[i].uvirt = 0; - sg_init_table(&db_tab->page[i].mem, 1); } return db_tab; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index 054fab8e27a0..f9b7caa54143 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -209,6 +209,7 @@ struct ipoib_cm_tx { unsigned tx_tail; unsigned long flags; u32 mtu; + struct ib_wc ibwc[IPOIB_NUM_WC]; }; struct ipoib_cm_rx_buf { diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 08c4396cf418..9d3e778dc56d 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -780,7 +780,6 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); ipoib_ib_dev_down(dev, 0); - ipoib_ib_dev_stop(dev, 0); ipoib_pkey_dev_delay_open(dev); return; } diff --git a/trunk/drivers/macintosh/mediabay.c b/trunk/drivers/macintosh/mediabay.c index 51a112815f46..936788272a5f 100644 --- a/trunk/drivers/macintosh/mediabay.c +++ b/trunk/drivers/macintosh/mediabay.c @@ -416,6 +416,7 @@ 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; @@ -430,6 +431,7 @@ 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) diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 7aeceedcf7d4..a0585fb6da94 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -206,10 +206,16 @@ 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; - buf = d_path(&file->f_path, buf, count); + d = file->f_path.dentry; + v = file->f_path.mnt; + + buf = d_path(d, v, buf, count); return IS_ERR(buf) ? NULL : buf; } diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index e75b1437b58b..f16062982383 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -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.path.dentry->d_inode; + inode = nd.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_put(&nd.path); + path_release(&nd); return r; } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 7da6ec244e15..5fc326d3970e 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -5197,7 +5197,8 @@ 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, " \t\n"); + seq_path(seq, bitmap->file->f_path.mnt, + bitmap->file->f_path.dentry," \t\n"); } seq_printf(seq, "\n"); diff --git a/trunk/drivers/mtd/mtdsuper.c b/trunk/drivers/mtd/mtdsuper.c index 28cc6787a800..9b430f20b640 100644 --- a/trunk/drivers/mtd/mtdsuper.c +++ b/trunk/drivers/mtd/mtdsuper.c @@ -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.path.dentry ? nd.path.dentry->d_inode : NULL); + ret, nd.dentry ? nd.dentry->d_inode : NULL); if (ret) return ret; ret = -EINVAL; - if (!S_ISBLK(nd.path.dentry->d_inode->i_mode)) + if (!S_ISBLK(nd.dentry->d_inode->i_mode)) goto out; - if (nd.path.mnt->mnt_flags & MNT_NODEV) { + if (nd.mnt->mnt_flags & MNT_NODEV) { ret = -EACCES; goto out; } - if (imajor(nd.path.dentry->d_inode) != MTD_BLOCK_MAJOR) + if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) goto not_an_MTD_device; - mtdnr = iminor(nd.path.dentry->d_inode); - path_put(&nd.path); + mtdnr = iminor(nd.dentry->d_inode); + path_release(&nd); return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super, mnt); @@ -214,7 +214,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, "MTD: Attempt to mount non-MTD device \"%s\"\n", dev_name); out: - path_put(&nd.path); + path_release(&nd); return ret; } diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index 79b317b88c86..679dfdb6807f 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -578,6 +578,13 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, goto err_free; } + fmr->mpt = mlx4_table_find(&priv->mr_table.dmpt_table, + key_to_hw_index(fmr->mr.key), NULL); + if (!fmr->mpt) { + err = -ENOMEM; + goto err_free; + } + return 0; err_free: @@ -588,19 +595,7 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_alloc); int mlx4_fmr_enable(struct mlx4_dev *dev, struct mlx4_fmr *fmr) { - struct mlx4_priv *priv = mlx4_priv(dev); - int err; - - err = mlx4_mr_enable(dev, &fmr->mr); - if (err) - return err; - - fmr->mpt = mlx4_table_find(&priv->mr_table.dmpt_table, - key_to_hw_index(fmr->mr.key), NULL); - if (!fmr->mpt) - return -ENOMEM; - - return 0; + return mlx4_mr_enable(dev, &fmr->mr); } EXPORT_SYMBOL_GPL(mlx4_fmr_enable); diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index b07ba2a14119..8134c7e198a5 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -187,22 +187,23 @@ 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 path *path) +static inline unsigned long fast_get_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt) { unsigned long cookie; - - if (path->dentry->d_cookie) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); + + if (dentry->d_cookie) + return (unsigned long)dentry; + get_dcookie(dentry, vfsmnt, &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 @@ -221,7 +222,8 @@ 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); + cookie = fast_get_dcookie(vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); break; } @@ -246,7 +248,8 @@ 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); + cookie = fast_get_dcookie(vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; } else { diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index a8a51500e1e9..f7e67197a568 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -105,6 +105,8 @@ 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))) { diff --git a/trunk/drivers/ps3/ps3-lpm.c b/trunk/drivers/ps3/ps3-lpm.c index 6c9592ce4996..4c066545d176 100644 --- a/trunk/drivers/ps3/ps3-lpm.c +++ b/trunk/drivers/ps3/ps3-lpm.c @@ -76,6 +76,7 @@ * * @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. * @@ -90,6 +91,7 @@ struct ps3_lpm_shadow_regs { u64 pm_control; u64 pm_start_stop; + u64 pm_interval; u64 group_control; u64 debug_bus_control; }; @@ -179,9 +181,9 @@ void ps3_set_bookmark(u64 bookmark) * includes cycles before the call. */ - asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;"); + asm volatile("or 29, 29, 29;"); /* db10cyc */ mtspr(SPRN_BKMK, bookmark); - asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;"); + asm volatile("or 29, 29, 29;"); /* db10cyc */ } EXPORT_SYMBOL_GPL(ps3_set_bookmark); @@ -406,14 +408,7 @@ 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: - 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; + return lpm_priv->shadow.pm_interval; case group_control: return lpm_priv->shadow.group_control; case debug_bus_control: @@ -480,8 +475,10 @@ void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) lpm_priv->shadow.pm_control = val; break; case pm_interval: - result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, - PS3_WRITE_PM_MASK, &dummy); + 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; break; case pm_start_stop: if (val != lpm_priv->shadow.pm_start_stop) @@ -1143,6 +1140,7 @@ 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; diff --git a/trunk/drivers/ps3/ps3-sys-manager.c b/trunk/drivers/ps3/ps3-sys-manager.c index d4f6f960dd18..c3c3aba3ffce 100644 --- a/trunk/drivers/ps3/ps3-sys-manager.c +++ b/trunk/drivers/ps3/ps3-sys-manager.c @@ -28,6 +28,10 @@ #include "vuart.h" +MODULE_AUTHOR("Sony Corporation"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PS3 System Manager"); + /** * ps3_sys_manager - PS3 system manager driver. * @@ -138,11 +142,9 @@ enum ps3_sys_manager_attr { /** * enum ps3_sys_manager_event - External event type, reported by system manager. - * @PS3_SM_EVENT_POWER_PRESSED: payload.value = - * enum ps3_sys_manager_button_event. + * @PS3_SM_EVENT_POWER_PRESSED: payload.value not used. * @PS3_SM_EVENT_POWER_RELEASED: payload.value = time pressed in millisec. - * @PS3_SM_EVENT_RESET_PRESSED: payload.value = - * enum ps3_sys_manager_button_event. + * @PS3_SM_EVENT_RESET_PRESSED: payload.value not used. * @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. @@ -159,17 +161,6 @@ enum ps3_sys_manager_event { /* no info on controller events */ }; -/** - * 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. */ @@ -190,9 +181,7 @@ 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. - * 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. + * System will always wake from the PS3_SM_WAKE_DEFAULT sources. */ enum ps3_sys_manager_wake_source { @@ -200,7 +189,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 = 0x80000000, + PS3_SM_WAKE_P_O_R = 0x10000000, }; /** @@ -429,10 +418,8 @@ 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 (%s)\n", - __func__, __LINE__, - (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft" - : "hard")); + dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n", + __func__, __LINE__); ps3_sm_force_power_off = 1; /* * A memory barrier is use here to sync memory since @@ -447,10 +434,8 @@ 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 (%s)\n", - __func__, __LINE__, - (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft" - : "hard")); + dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n", + __func__, __LINE__); ps3_sm_force_power_off = 0; /* * A memory barrier is use here to sync memory since @@ -637,7 +622,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_SYS_REBOOT, + ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT, PS3_SM_WAKE_DEFAULT); ps3_sys_manager_send_request_shutdown(dev); @@ -714,7 +699,4 @@ 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); diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 017a196d041f..3301167d4f2a 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -3563,7 +3563,8 @@ 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, buf, PAGE_SIZE - 1); + p = d_path(curlun->filp->f_path.dentry, + curlun->filp->f_path.mnt, buf, PAGE_SIZE - 1); if (IS_ERR(p)) rc = PTR_ERR(p); else { @@ -3980,8 +3981,9 @@ 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, - pathbuf, PATH_MAX); + p = d_path(curlun->filp->f_path.dentry, + curlun->filp->f_path.mnt, + pathbuf, PATH_MAX); if (IS_ERR(p)) p = NULL; } diff --git a/trunk/fs/afs/mntpt.c b/trunk/fs/afs/mntpt.c index a3510b8ba3e7..5ce43b63c60e 100644 --- a/trunk/fs/afs/mntpt.c +++ b/trunk/fs/afs/mntpt.c @@ -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->path.mnt->mnt_devname, + nd->mnt->mnt_devname, dentry, - nd->path.dentry->d_name.name); + nd->dentry->d_name.name); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); - newmnt = afs_mntpt_do_automount(nd->path.dentry); + newmnt = afs_mntpt_do_automount(nd->dentry); if (IS_ERR(newmnt)) { - path_put(&nd->path); + path_release(nd); return (void *)newmnt; } @@ -235,16 +235,17 @@ 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: - path_put(&nd->path); - nd->path.mnt = newmnt; - nd->path.dentry = dget(newmnt->mnt_root); + dput(nd->dentry); + mntput(nd->mnt); + nd->mnt = newmnt; + nd->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->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && + follow_down(&nd->mnt, &nd->dentry)) ; err = 0; default: diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index a54a946a50ae..2bbcc8151dc3 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -368,8 +368,7 @@ 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->path.mnt, - &nd->path.dentry)) { + if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) { status = -ENOENT; goto out_error; } @@ -383,7 +382,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) return NULL; out_error: - path_put(&nd->path); + path_release(nd); return ERR_PTR(status); } diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 0498b181dd52..d8a02f1e08cc 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -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; } diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 67fe72ce6ac7..e63067d25cdb 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1397,19 +1397,19 @@ struct block_device *lookup_bdev(const char *path) if (error) return ERR_PTR(error); - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; error = -ENOTBLK; if (!S_ISBLK(inode->i_mode)) goto fail; error = -EACCES; - if (nd.path.mnt->mnt_flags & MNT_NODEV) + if (nd.mnt->mnt_flags & MNT_NODEV) goto fail; error = -ENOMEM; bdev = bd_acquire(inode); if (!bdev) goto fail; out: - path_put(&nd.path); + path_release(&nd); return bdev; fail: bdev = ERR_PTR(error); diff --git a/trunk/fs/cifs/cifs_dfs_ref.c b/trunk/fs/cifs/cifs_dfs_ref.c index 6ad447529961..413ee2349d1a 100644 --- a/trunk/fs/cifs/cifs_dfs_ref.c +++ b/trunk/fs/cifs/cifs_dfs_ref.c @@ -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->path.mnt->mnt_flags, mntlist); + err = do_add_mount(newmnt, nd, nd->mnt->mnt_flags, mntlist); switch (err) { case 0: - dput(nd->path.dentry); - mntput(nd->path.mnt); - nd->path.mnt = newmnt; - nd->path.dentry = dget(newmnt->mnt_root); + dput(nd->dentry); + mntput(nd->mnt); + nd->mnt = newmnt; + nd->dentry = dget(newmnt->mnt_root); break; case -EBUSY: /* someone else made a mount here whilst we were busy */ - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && + follow_down(&nd->mnt, &nd->dentry)) ; err = 0; default: @@ -307,8 +307,8 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) xid = GetXid(); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); cifs_sb = CIFS_SB(dentry->d_inode->i_sb); ses = cifs_sb->tcon->ses; @@ -340,8 +340,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) rc = -EINVAL; goto out_err; } - mnt = cifs_dfs_do_refmount(nd->path.mnt, - nd->path.dentry, + mnt = cifs_dfs_do_refmount(nd->mnt, nd->dentry, referrals[i].node_name); cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __FUNCTION__, @@ -358,7 +357,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) if (IS_ERR(mnt)) goto out_err; - nd->path.mnt->mnt_flags |= MNT_SHRINKABLE; + nd->mnt->mnt_flags |= MNT_SHRINKABLE; rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list); out: @@ -368,7 +367,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) cFYI(1, ("leaving %s" , __FUNCTION__)); return ERR_PTR(rc); out_err: - path_put(&nd->path); + path_release(nd); goto out; } diff --git a/trunk/fs/coda/pioctl.c b/trunk/fs/coda/pioctl.c index c21a1f552a63..2bf3026adc80 100644 --- a/trunk/fs/coda/pioctl.c +++ b/trunk/fs/coda/pioctl.c @@ -75,12 +75,12 @@ static int coda_pioctl(struct inode * inode, struct file * filp, if ( error ) { return error; } else { - target_inode = nd.path.dentry->d_inode; + target_inode = nd.dentry->d_inode; } /* return if it is not a Coda inode */ if ( target_inode->i_sb != inode->i_sb ) { - path_put(&nd.path); + path_release(&nd); 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_put(&nd.path); + path_release(&nd); return error; } diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 43ca0165740c..ee80ff341d37 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -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.path.dentry, &tmp); + error = vfs_statfs(nd.dentry, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); - path_put(&nd.path); + path_release(&nd); } 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.path.dentry, &tmp); + error = vfs_statfs(nd.dentry, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); - path_put(&nd.path); + path_release(&nd); } return error; } diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index c6e72aebd16b..ee32c0eac7c1 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -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, path, PAGE_SIZE); + fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); if (IS_ERR(fn)) fn = "?"; } diff --git a/trunk/fs/configfs/symlink.c b/trunk/fs/configfs/symlink.c index 78929ea84ff2..22700d2857da 100644 --- a/trunk/fs/configfs/symlink.c +++ b/trunk/fs/configfs/symlink.c @@ -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->path.dentry->d_sb == configfs_sb) { - *target = configfs_get_config_item(nd->path.dentry); + if (nd->dentry->d_sb == configfs_sb) { + *target = configfs_get_config_item(nd->dentry); if (!*target) { ret = -ENOENT; - path_put(&nd->path); + path_release(nd); } } 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_put(&nd.path); + path_release(&nd); out_put: config_item_put(parent_item); diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 43455776711e..44f6cf23b70e 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -95,14 +95,6 @@ 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. @@ -219,7 +211,13 @@ void dput(struct dentry *dentry) unhash_it: __d_drop(dentry); kill_it: - dentry_lru_remove(dentry); + /* 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 = d_kill(dentry); if (dentry) goto repeat; @@ -287,7 +285,10 @@ int d_invalidate(struct dentry * dentry) static inline struct dentry * __dget_locked(struct dentry *dentry) { atomic_inc(&dentry->d_count); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } return dentry; } @@ -403,7 +404,10 @@ static void prune_one_dentry(struct dentry * dentry) if (dentry->d_op && dentry->d_op->d_delete) dentry->d_op->d_delete(dentry); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + list_del(&dentry->d_lru); + dentry_stat.nr_unused--; + } __d_drop(dentry); dentry = d_kill(dentry); spin_lock(&dcache_lock); @@ -592,7 +596,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) /* detach this root from the system */ spin_lock(&dcache_lock); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } __d_drop(dentry); spin_unlock(&dcache_lock); @@ -606,7 +613,11 @@ 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) { - dentry_lru_remove(loop); + if (!list_empty(&loop->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&loop->d_lru); + } + __d_drop(loop); cond_resched_lock(&dcache_lock); } @@ -788,7 +799,10 @@ static int select_parent(struct dentry * parent) struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); next = tmp->next; - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } /* * move only zero ref count dentries to the end * of the unused list for prune_dcache @@ -1762,8 +1776,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) * * "buflen" should be positive. Caller holds the dcache_lock. */ -static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, - struct path *root, char *buffer, int buflen) +static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, + struct dentry *root, struct vfsmount *rootmnt, + char *buffer, int buflen) { char * end = buffer+buflen; char * retval; @@ -1788,7 +1803,7 @@ static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, for (;;) { struct dentry * parent; - if (dentry == root->dentry && vfsmnt == root->mnt) + if (dentry == root && vfsmnt == rootmnt) break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { /* Global root? */ @@ -1829,23 +1844,13 @@ static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, return ERR_PTR(-ENAMETOOLONG); } -/** - * 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) +/* write full pathname into buffer and return start of pathname */ +char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) { char *res; - struct path root; + struct vfsmount *rootmnt; + struct dentry *root; /* * We have various synthetic filesystems that never get mounted. On @@ -1854,17 +1859,18 @@ char *d_path(struct path *path, char *buf, int buflen) * 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 (path->dentry->d_op && path->dentry->d_op->d_dname) - return path->dentry->d_op->d_dname(path->dentry, buf, buflen); + if (dentry->d_op && dentry->d_op->d_dname) + return dentry->d_op->d_dname(dentry, buf, buflen); read_lock(¤t->fs->lock); - root = current->fs->root; - path_get(¤t->fs->root); + rootmnt = mntget(current->fs->rootmnt); + root = dget(current->fs->root); read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); - res = __d_path(path->dentry, path->mnt, &root, buf, buflen); + res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); spin_unlock(&dcache_lock); - path_put(&root); + dput(root); + mntput(rootmnt); return res; } @@ -1910,27 +1916,28 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, asmlinkage long sys_getcwd(char __user *buf, unsigned long size) { int error; - struct path pwd, root; + struct vfsmount *pwdmnt, *rootmnt; + struct dentry *pwd, *root; char *page = (char *) __get_free_page(GFP_USER); if (!page) return -ENOMEM; read_lock(¤t->fs->lock); - pwd = current->fs->pwd; - path_get(¤t->fs->pwd); - root = current->fs->root; - path_get(¤t->fs->root); + pwdmnt = mntget(current->fs->pwdmnt); + pwd = dget(current->fs->pwd); + rootmnt = mntget(current->fs->rootmnt); + root = dget(current->fs->root); read_unlock(¤t->fs->lock); error = -ENOENT; /* Has the current directory has been unlinked? */ spin_lock(&dcache_lock); - if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { + if (pwd->d_parent == pwd || !d_unhashed(pwd)) { unsigned long len; char * cwd; - cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE); + cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); spin_unlock(&dcache_lock); error = PTR_ERR(cwd); @@ -1948,8 +1955,10 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) spin_unlock(&dcache_lock); out: - path_put(&pwd); - path_put(&root); + dput(pwd); + mntput(pwdmnt); + dput(root); + mntput(rootmnt); free_page((unsigned long) page); return error; } diff --git a/trunk/fs/dcookies.c b/trunk/fs/dcookies.c index 855d4b1d619a..792cbf55fa95 100644 --- a/trunk/fs/dcookies.c +++ b/trunk/fs/dcookies.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /* The dcookies are allocated from a kmem_cache and @@ -32,7 +31,8 @@ * code here is particularly performance critical */ struct dcookie_struct { - struct path path; + struct dentry * dentry; + struct vfsmount * vfsmnt; 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->path.dentry; + return (unsigned long)dcs->dentry; } @@ -89,17 +89,19 @@ static void hash_dcookie(struct dcookie_struct * dcs) } -static struct dcookie_struct *alloc_dcookie(struct path *path) +static struct dcookie_struct * alloc_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt) { - 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; - path->dentry->d_cookie = dcs; - dcs->path = *path; - path_get(path); + dentry->d_cookie = dcs; + + dcs->dentry = dget(dentry); + dcs->vfsmnt = mntget(vfsmnt); hash_dcookie(dcs); + return dcs; } @@ -107,7 +109,8 @@ static struct dcookie_struct *alloc_dcookie(struct path *path) /* This is the main kernel-side routine that retrieves the cookie * value for a dentry/vfsmnt pair. */ -int get_dcookie(struct path *path, unsigned long *cookie) +int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt, + unsigned long * cookie) { int err = 0; struct dcookie_struct * dcs; @@ -119,10 +122,10 @@ int get_dcookie(struct path *path, unsigned long *cookie) goto out; } - dcs = path->dentry->d_cookie; + dcs = dentry->d_cookie; if (!dcs) - dcs = alloc_dcookie(path); + dcs = alloc_dcookie(dentry, vfsmnt); if (!dcs) { err = -ENOMEM; @@ -171,7 +174,7 @@ asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) goto out; /* FIXME: (deleted) ? */ - path = d_path(&dcs->path, kbuf, PAGE_SIZE); + path = d_path(dcs->dentry, dcs->vfsmnt, kbuf, PAGE_SIZE); if (IS_ERR(path)) { err = PTR_ERR(path); @@ -251,8 +254,9 @@ static int dcookie_init(void) static void free_dcookie(struct dcookie_struct * dcs) { - dcs->path.dentry->d_cookie = NULL; - path_put(&dcs->path); + dcs->dentry->d_cookie = NULL; + dput(dcs->dentry); + mntput(dcs->vfsmnt); kmem_cache_free(dcookie_cache, dcs); } diff --git a/trunk/fs/dquot.c b/trunk/fs/dquot.c index 9c7feb62eed1..def4e969df77 100644 --- a/trunk/fs/dquot.c +++ b/trunk/fs/dquot.c @@ -1633,17 +1633,16 @@ 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.path.dentry); + error = security_quota_on(nd.dentry); if (error) goto out_path; /* Quota file not on the same filesystem? */ - if (nd.path.mnt->mnt_sb != sb) + if (nd.mnt->mnt_sb != sb) error = -EXDEV; else - error = vfs_quota_on_inode(nd.path.dentry->d_inode, type, - format_id); + error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id); out_path: - path_put(&nd.path); + path_release(&nd); return error; } diff --git a/trunk/fs/ecryptfs/dentry.c b/trunk/fs/ecryptfs/dentry.c index 841a032050a7..cb20b964419f 100644 --- a/trunk/fs/ecryptfs/dentry.c +++ b/trunk/fs/ecryptfs/dentry.c @@ -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->path.dentry; - vfsmount_save = nd->path.mnt; - nd->path.dentry = lower_dentry; - nd->path.mnt = lower_mnt; + dentry_save = nd->dentry; + vfsmount_save = nd->mnt; + nd->dentry = lower_dentry; + nd->mnt = lower_mnt; rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); - nd->path.dentry = dentry_save; - nd->path.mnt = vfsmount_save; + nd->dentry = dentry_save; + nd->mnt = vfsmount_save; if (dentry->d_inode) { struct inode *lower_inode = ecryptfs_inode_to_lower(dentry->d_inode); diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index e23861152101..edd1e44e9d47 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, struct vfsmount *vfsmount_save; int rc; - dentry_save = nd->path.dentry; - vfsmount_save = nd->path.mnt; - nd->path.dentry = lower_dentry; - nd->path.mnt = lower_mnt; + dentry_save = nd->dentry; + vfsmount_save = nd->mnt; + nd->dentry = lower_dentry; + nd->mnt = lower_mnt; rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); - nd->path.dentry = dentry_save; - nd->path.mnt = vfsmount_save; + nd->dentry = dentry_save; + nd->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->path.mnt; - struct dentry *dentry_save = nd->path.dentry; + struct vfsmount *vfsmnt_save = nd->mnt; + struct dentry *dentry_save = nd->dentry; - nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); - nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); + nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry); + nd->dentry = ecryptfs_dentry_to_lower(nd->dentry); rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); - nd->path.mnt = vfsmnt_save; - nd->path.dentry = dentry_save; + nd->mnt = vfsmnt_save; + nd->dentry = dentry_save; } else rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); return rc; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index d25ac9500a92..778c420e4cac 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -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.path.dentry; - lower_mnt = nd.path.mnt; + lower_root = nd.dentry; + lower_mnt = nd.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_put(&nd.path); + path_release(&nd); out: return rc; } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index a44b142fb460..9ff6069094d8 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -112,7 +112,7 @@ asmlinkage long sys_uselib(const char __user * library) goto out; error = -EINVAL; - if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) + if (!S_ISREG(nd.dentry->d_inode->i_mode)) goto exit; error = vfs_permission(&nd, MAY_READ | MAY_EXEC); @@ -148,7 +148,7 @@ asmlinkage long sys_uselib(const char __user * library) return error; exit: release_open_intent(&nd); - path_put(&nd.path); + path_release(&nd); goto out; } @@ -652,7 +652,7 @@ struct file *open_exec(const char *name) file = ERR_PTR(err); if (!err) { - struct inode *inode = nd.path.dentry->d_inode; + struct inode *inode = nd.dentry->d_inode; file = ERR_PTR(-EACCES); if (S_ISREG(inode->i_mode)) { int err = vfs_permission(&nd, MAY_EXEC); @@ -672,7 +672,7 @@ struct file *open_exec(const char *name) } } release_open_intent(&nd); - path_put(&nd.path); + path_release(&nd); } goto out; } diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 18769cc32377..8e02cbfb1123 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -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.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.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_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 13383ba18f1d..0072da75221f 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -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.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.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_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/gfs2/ops_fstype.c b/trunk/fs/gfs2/ops_fstype.c index 4bee6aa845e4..43d511bba52d 100644 --- a/trunk/fs/gfs2/ops_fstype.c +++ b/trunk/fs/gfs2/ops_fstype.c @@ -884,13 +884,12 @@ static struct super_block* get_gfs2_sb(const char *dev_name) dev_name); goto out; } - error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat); + error = vfs_getattr(nd.mnt, nd.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.path.dentry->d_inode->i_sb)) { + (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) { sb = s; goto free_nd; } @@ -900,7 +899,7 @@ static struct super_block* get_gfs2_sb(const char *dev_name) "mount point %s\n", dev_name); free_nd: - path_put(&nd.path); + path_release(&nd); out: return sb; } diff --git a/trunk/fs/inotify_user.c b/trunk/fs/inotify_user.c index 7b94a1e3c015..3ab09a65c456 100644 --- a/trunk/fs/inotify_user.c +++ b/trunk/fs/inotify_user.c @@ -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/ */ -static int inotify_max_user_instances __read_mostly; -static int inotify_max_user_watches __read_mostly; -static int inotify_max_queued_events __read_mostly; +int inotify_max_user_instances __read_mostly; +int inotify_max_user_watches __read_mostly; +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_put(&nd->path); + path_release(nd); 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.path.dentry->d_inode; + inode = nd.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_put(&nd.path); + path_release(&nd); fput_and_out: fput_light(filp, fput_needed); return ret; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 941c8e8228c0..52703986323a 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -231,7 +231,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) struct vfsmount *mnt = NULL; if (nd) - mnt = nd->path.mnt; + mnt = nd->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->path.dentry->d_inode, mask, nd); + return permission(nd->dentry->d_inode, mask, nd); } /** @@ -362,31 +362,21 @@ int deny_write_access(struct file * file) return 0; } -/** - * 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) +void path_release(struct nameidata *nd) { - mntget(path->mnt); - dget(path->dentry); + dput(nd->dentry); + mntput(nd->mnt); } -EXPORT_SYMBOL(path_get); -/** - * 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. +/* + * umount() mustn't call path_release()/mntput() as that would clear + * mnt_expiry_mark */ -void path_put(struct path *path) +void path_release_on_umount(struct nameidata *nd) { - dput(path->dentry); - mntput(path->mnt); + dput(nd->dentry); + mntput_no_expire(nd->mnt); } -EXPORT_SYMBOL(path_put); /** * release_open_intent - free up open intent resources @@ -549,16 +539,16 @@ walk_init_root(const char *name, struct nameidata *nd) struct fs_struct *fs = current->fs; read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) return 0; read_lock(&fs->lock); } - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); return 1; } @@ -571,7 +561,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l goto fail; if (*link == '/') { - path_put(&nd->path); + path_release(nd); if (!walk_init_root(link, nd)) /* weird __emul_prefix() stuff did it */ goto out; @@ -587,31 +577,31 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l */ name = __getname(); if (unlikely(!name)) { - path_put(&nd->path); + path_release(nd); return -ENOMEM; } strcpy(name, nd->last.name); nd->last.name = name; return 0; fail: - path_put(&nd->path); + path_release(nd); return PTR_ERR(link); } -static void path_put_conditional(struct path *path, struct nameidata *nd) +static inline void dput_path(struct path *path, struct nameidata *nd) { dput(path->dentry); - if (path->mnt != nd->path.mnt) + if (path->mnt != nd->mnt) mntput(path->mnt); } static inline void path_to_nameidata(struct path *path, struct nameidata *nd) { - dput(nd->path.dentry); - if (nd->path.mnt != path->mnt) - mntput(nd->path.mnt); - nd->path.mnt = path->mnt; - nd->path.dentry = path->dentry; + dput(nd->dentry); + if (nd->mnt != path->mnt) + mntput(nd->mnt); + nd->mnt = path->mnt; + nd->dentry = path->dentry; } static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) @@ -623,7 +613,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->path.mnt) { + if (path->mnt != nd->mnt) { path_to_nameidata(path, nd); dget(dentry); } @@ -638,7 +628,8 @@ 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); } - path_put(path); + dput(dentry); + mntput(path->mnt); return error; } @@ -670,8 +661,8 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) nd->depth--; return err; loop: - path_put_conditional(path, nd); - path_put(&nd->path); + dput_path(path, nd); + path_release(nd); return err; } @@ -752,37 +743,37 @@ static __always_inline void follow_dotdot(struct nameidata *nd) while(1) { struct vfsmount *parent; - struct dentry *old = nd->path.dentry; + struct dentry *old = nd->dentry; read_lock(&fs->lock); - if (nd->path.dentry == fs->root.dentry && - nd->path.mnt == fs->root.mnt) { + if (nd->dentry == fs->root && + nd->mnt == fs->rootmnt) { read_unlock(&fs->lock); break; } read_unlock(&fs->lock); spin_lock(&dcache_lock); - if (nd->path.dentry != nd->path.mnt->mnt_root) { - nd->path.dentry = dget(nd->path.dentry->d_parent); + if (nd->dentry != nd->mnt->mnt_root) { + nd->dentry = dget(nd->dentry->d_parent); spin_unlock(&dcache_lock); dput(old); break; } spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); - parent = nd->path.mnt->mnt_parent; - if (parent == nd->path.mnt) { + parent = nd->mnt->mnt_parent; + if (parent == nd->mnt) { spin_unlock(&vfsmount_lock); break; } mntget(parent); - nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint); + nd->dentry = dget(nd->mnt->mnt_mountpoint); spin_unlock(&vfsmount_lock); dput(old); - mntput(nd->path.mnt); - nd->path.mnt = parent; + mntput(nd->mnt); + nd->mnt = parent; } - follow_mount(&nd->path.mnt, &nd->path.dentry); + follow_mount(&nd->mnt, &nd->dentry); } /* @@ -793,8 +784,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->path.mnt; - struct dentry *dentry = __d_lookup(nd->path.dentry, name); + struct vfsmount *mnt = nd->mnt; + struct dentry *dentry = __d_lookup(nd->dentry, name); if (!dentry) goto need_lookup; @@ -807,7 +798,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, return 0; need_lookup: - dentry = real_lookup(nd->path.dentry, name, nd); + dentry = real_lookup(nd->dentry, name, nd); if (IS_ERR(dentry)) goto fail; goto done; @@ -844,7 +835,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (!*name) goto return_reval; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; if (nd->depth) lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); @@ -892,7 +883,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (this.name[1] != '.') break; follow_dotdot(nd); - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; /* fallthrough */ case 1: continue; @@ -901,9 +892,8 @@ 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->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { - err = nd->path.dentry->d_op->d_hash(nd->path.dentry, - &this); + if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { + err = nd->dentry->d_op->d_hash(nd->dentry, &this); if (err < 0) break; } @@ -925,7 +915,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (err) goto return_err; err = -ENOENT; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; if (!inode) break; err = -ENOTDIR; @@ -953,14 +943,13 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (this.name[1] != '.') break; follow_dotdot(nd); - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; /* fallthrough */ case 1: goto return_reval; } - 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 (nd->dentry->d_op && nd->dentry->d_op->d_hash) { + err = nd->dentry->d_op->d_hash(nd->dentry, &this); if (err < 0) break; } @@ -973,7 +962,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) err = do_follow_link(&next, nd); if (err) goto return_err; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; } else path_to_nameidata(&next, nd); err = -ENOENT; @@ -1001,21 +990,20 @@ static int __link_path_walk(const char *name, struct nameidata *nd) * We bypassed the ordinary revalidation routines. * We may need to check the cached dentry for staleness. */ - if (nd->path.dentry && nd->path.dentry->d_sb && - (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { + if (nd->dentry && nd->dentry->d_sb && + (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { err = -ESTALE; /* Note: we do not d_invalidate() */ - if (!nd->path.dentry->d_op->d_revalidate( - nd->path.dentry, nd)) + if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) break; } return_base: return 0; out_dput: - path_put_conditional(&next, nd); + dput_path(&next, nd); break; } - path_put(&nd->path); + path_release(nd); return_err: return err; } @@ -1033,19 +1021,20 @@ 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.path.dentry); - mntget(save.path.mnt); + dget(save.dentry); + mntget(save.mnt); result = __link_path_walk(name, nd); if (result == -ESTALE) { *nd = save; - dget(nd->path.dentry); - mntget(nd->path.mnt); + dget(nd->dentry); + mntget(nd->mnt); nd->flags |= LOOKUP_REVAL; result = __link_path_walk(name, nd); } - path_put(&save.path); + dput(save.dentry); + mntput(save.mnt); return result; } @@ -1065,9 +1054,9 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) if (path_walk(name, nd)) return 0; /* something went wrong... */ - if (!nd->path.dentry->d_inode || - S_ISDIR(nd->path.dentry->d_inode->i_mode)) { - struct path old_path = nd->path; + 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; struct qstr last = nd->last; int last_type = nd->last_type; struct fs_struct *fs = current->fs; @@ -1078,17 +1067,19 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) */ nd->last_type = LAST_ROOT; read_lock(&fs->lock); - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); if (path_walk(name, nd) == 0) { - if (nd->path.dentry->d_inode) { - path_put(&old_path); + if (nd->dentry->d_inode) { + dput(old_dentry); + mntput(old_mnt); return 1; } - path_put(&nd->path); + path_release(nd); } - nd->path = old_path; + nd->dentry = old_dentry; + nd->mnt = old_mnt; nd->last = last; nd->last_type = last_type; } @@ -1099,22 +1090,29 @@ void set_fs_altroot(void) { char *emul = __emul_prefix(); struct nameidata nd; - struct path path = {}, old_path; + struct vfsmount *mnt = NULL, *oldmnt; + struct dentry *dentry = NULL, *olddentry; 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) - path = nd.path; + if (!err) { + mnt = nd.mnt; + dentry = nd.dentry; + } set_it: write_lock(&fs->lock); - old_path = fs->altroot; - fs->altroot = path; + oldmnt = fs->altrootmnt; + olddentry = fs->altroot; + fs->altrootmnt = mnt; + fs->altroot = dentry; write_unlock(&fs->lock); - if (old_path.dentry) - path_put(&old_path); + if (olddentry) { + dput(olddentry); + mntput(oldmnt); + } } /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ @@ -1132,21 +1130,21 @@ static int do_path_lookup(int dfd, const char *name, if (*name=='/') { read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) goto out; /* found in altroot */ read_lock(&fs->lock); } - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); } else if (dfd == AT_FDCWD) { read_lock(&fs->lock); - nd->path = fs->pwd; - path_get(&fs->pwd); + nd->mnt = mntget(fs->pwdmnt); + nd->dentry = dget(fs->pwd); read_unlock(&fs->lock); } else { struct dentry *dentry; @@ -1166,17 +1164,17 @@ static int do_path_lookup(int dfd, const char *name, if (retval) goto fput_fail; - nd->path = file->f_path; - path_get(&file->f_path); + nd->mnt = mntget(file->f_path.mnt); + nd->dentry = dget(dentry); fput_light(file, fput_needed); } retval = path_walk(name, nd); out: - if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && - nd->path.dentry->d_inode)) - audit_inode(name, nd->path.dentry); + if (unlikely(!retval && !audit_dummy_context() && nd->dentry && + nd->dentry->d_inode)) + audit_inode(name, nd->dentry); out_fail: return retval; @@ -1210,13 +1208,13 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, nd->flags = flags; nd->depth = 0; - nd->path.mnt = mntget(mnt); - nd->path.dentry = dget(dentry); + nd->mnt = mntget(mnt); + nd->dentry = dget(dentry); retval = path_walk(name, nd); - if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && - nd->path.dentry->d_inode)) - audit_inode(name, nd->path.dentry); + if (unlikely(!retval && !audit_dummy_context() && nd->dentry && + nd->dentry->d_inode)) + audit_inode(name, nd->dentry); return retval; @@ -1238,7 +1236,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_put(&nd->path); + path_release(nd); } } else if (err != 0) release_open_intent(nd); @@ -1335,10 +1333,10 @@ static struct dentry *lookup_hash(struct nameidata *nd) { int err; - err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); + err = permission(nd->dentry->d_inode, MAY_EXEC, nd); if (err) return ERR_PTR(err); - return __lookup_hash(&nd->last, nd->path.dentry, nd); + return __lookup_hash(&nd->last, nd->dentry, nd); } static int __lookup_one_len(const char *name, struct qstr *this, @@ -1597,7 +1595,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->path.dentry; + struct dentry *dentry = nd->dentry; struct inode *inode = dentry->d_inode; int error; @@ -1618,7 +1616,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->path.mnt->mnt_flags & MNT_NODEV) + if (nd->mnt->mnt_flags & MNT_NODEV) return -EACCES; flag &= ~O_TRUNC; @@ -1680,14 +1678,14 @@ static int open_namei_create(struct nameidata *nd, struct path *path, int flag, int mode) { int error; - struct dentry *dir = nd->path.dentry; + struct dentry *dir = nd->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->path.dentry); - nd->path.dentry = path->dentry; + dput(nd->dentry); + nd->dentry = path->dentry; if (error) return error; /* Don't check for write permission, don't truncate */ @@ -1754,11 +1752,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->path.dentry; + dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; mutex_lock(&dir->d_inode->i_mutex); path.dentry = lookup_hash(nd); - path.mnt = nd->path.mnt; + path.mnt = nd->mnt; do_last: error = PTR_ERR(path.dentry); @@ -1814,11 +1812,11 @@ int open_namei(int dfd, const char *pathname, int flag, return 0; exit_dput: - path_put_conditional(&path, nd); + dput_path(&path, nd); exit: if (!IS_ERR(nd->intent.open.file)) release_open_intent(nd); - path_put(&nd->path); + path_release(nd); return error; do_link: @@ -1863,10 +1861,10 @@ int open_namei(int dfd, const char *pathname, int flag, __putname(nd->last.name); goto exit; } - dir = nd->path.dentry; + dir = nd->dentry; mutex_lock(&dir->d_inode->i_mutex); path.dentry = lookup_hash(nd); - path.mnt = nd->path.mnt; + path.mnt = nd->mnt; __putname(nd->last.name); goto do_last; } @@ -1879,13 +1877,13 @@ int open_namei(int dfd, const char *pathname, int flag, * Simple function to lookup and return a dentry and create it * if it doesn't exist. Is SMP-safe. * - * Returns with nd->path.dentry->d_inode->i_mutex locked. + * Returns with nd->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->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT); /* * Yucky last component or no last component at all? * (foo/., foo/.., /////) @@ -1964,19 +1962,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.path.dentry->d_inode)) + if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; if (!IS_ERR(dentry)) { switch (mode & S_IFMT) { case 0: case S_IFREG: - error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, + error = vfs_mknod(nd.dentry->d_inode,dentry,mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); break; case S_IFDIR: error = -EPERM; @@ -1986,8 +1984,8 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, } dput(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(tmp); @@ -2041,13 +2039,13 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) if (IS_ERR(dentry)) goto out_unlock; - if (!IS_POSIXACL(nd.path.dentry->d_inode)) + if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); dput(dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(tmp); out_err: @@ -2145,17 +2143,17 @@ static long do_rmdir(int dfd, const char __user *pathname) error = -EBUSY; goto exit1; } - mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd.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.path.dentry->d_inode, dentry); + error = vfs_rmdir(nd.dentry->d_inode, dentry); dput(dentry); exit2: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); exit1: - path_put(&nd.path); + path_release(&nd); exit: putname(name); return error; @@ -2221,7 +2219,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.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_hash(&nd); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { @@ -2231,15 +2229,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.path.dentry->d_inode, dentry); + error = vfs_unlink(nd.dentry->d_inode, dentry); exit2: dput(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); if (inode) iput(inode); /* truncate the inode here */ exit1: - path_put(&nd.path); + path_release(&nd); exit: putname(name); return error; @@ -2312,11 +2310,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname, if (IS_ERR(dentry)) goto out_unlock; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); dput(dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(to); out_putname: @@ -2401,20 +2399,20 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, if (error) goto out; error = -EXDEV; - if (old_nd.path.mnt != nd.path.mnt) + if (old_nd.mnt != nd.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.path.dentry, nd.path.dentry->d_inode, new_dentry); + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); dput(new_dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); out_release: - path_put(&nd.path); + path_release(&nd); out: - path_put(&old_nd.path); + path_release(&old_nd); exit: putname(to); @@ -2590,15 +2588,15 @@ static int do_rename(int olddfd, const char *oldname, goto exit1; error = -EXDEV; - if (oldnd.path.mnt != newnd.path.mnt) + if (oldnd.mnt != newnd.mnt) goto exit2; - old_dir = oldnd.path.dentry; + old_dir = oldnd.dentry; error = -EBUSY; if (oldnd.last_type != LAST_NORM) goto exit2; - new_dir = newnd.path.dentry; + new_dir = newnd.dentry; if (newnd.last_type != LAST_NORM) goto exit2; @@ -2642,9 +2640,9 @@ static int do_rename(int olddfd, const char *oldname, exit3: unlock_rename(new_dir, old_dir); exit2: - path_put(&newnd.path); + path_release(&newnd); exit1: - path_put(&oldnd.path); + path_release(&oldnd); exit: return error; } @@ -2818,6 +2816,7 @@ 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); diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 7953c96a2071..63ced21c12dc 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -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->path.dentry = mnt->mnt_mountpoint; - old_nd->path.mnt = mnt->mnt_parent; + old_nd->dentry = mnt->mnt_mountpoint; + old_nd->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->path.dentry->d_mounted--; + old_nd->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->path.mnt, nd->path.dentry, mnt); + mnt_set_mountpoint(nd->mnt, nd->dentry, mnt); list_add_tail(&mnt->mnt_hash, mount_hashtable + - hash(nd->path.mnt, nd->path.dentry)); - list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); + hash(nd->mnt, nd->dentry)); + list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts); } /* @@ -408,11 +408,10 @@ 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_path, " \t\n\\"); + seq_path(m, mnt, mnt->mnt_root, " \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]) { @@ -444,7 +443,6 @@ 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 */ @@ -456,7 +454,7 @@ static int show_vfsstat(struct seq_file *m, void *v) /* mount point */ seq_puts(m, " mounted on "); - seq_path(m, &mnt_path, " \t\n\\"); + seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); seq_putc(m, ' '); /* file system type */ @@ -595,7 +593,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->root.mnt || + if (mnt == current->fs->rootmnt || flags & (MNT_FORCE | MNT_DETACH)) return -EINVAL; @@ -630,7 +628,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->root.mnt && !(flags & MNT_DETACH)) { + if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) { /* * Special case for "unmounting" root ... * we just try to remount it readonly. @@ -681,20 +679,18 @@ asmlinkage long sys_umount(char __user * name, int flags) if (retval) goto out; retval = -EINVAL; - if (nd.path.dentry != nd.path.mnt->mnt_root) + if (nd.dentry != nd.mnt->mnt_root) goto dput_and_out; - if (!check_mnt(nd.path.mnt)) + if (!check_mnt(nd.mnt)) goto dput_and_out; retval = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto dput_and_out; - retval = do_umount(nd.path.mnt, flags); + retval = do_umount(nd.mnt, flags); dput_and_out: - /* we mustn't call path_put() as that would clear mnt_expiry_mark */ - dput(nd.path.dentry); - mntput_no_expire(nd.path.mnt); + path_release_on_umount(&nd); out: return retval; } @@ -717,10 +713,10 @@ static int mount_is_safe(struct nameidata *nd) return 0; return -EPERM; #ifdef notyet - if (S_ISLNK(nd->path.dentry->d_inode->i_mode)) + if (S_ISLNK(nd->dentry->d_inode->i_mode)) return -EPERM; - if (nd->path.dentry->d_inode->i_mode & S_ISVTX) { - if (current->uid != nd->path.dentry->d_inode->i_uid) + if (nd->dentry->d_inode->i_mode & S_ISVTX) { + if (current->uid != nd->dentry->d_inode->i_uid) return -EPERM; } if (vfs_permission(nd, MAY_WRITE)) @@ -769,8 +765,8 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, q = q->mnt_parent; } p = s; - nd.path.mnt = q; - nd.path.dentry = p->mnt_mountpoint; + nd.mnt = q; + nd.dentry = p->mnt_mountpoint; q = clone_mnt(p, p->mnt_root, flag); if (!q) goto Enomem; @@ -879,8 +875,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->path.mnt; - struct dentry *dest_dentry = nd->path.dentry; + struct vfsmount *dest_mnt = nd->mnt; + struct dentry *dest_dentry = nd->dentry; struct vfsmount *child, *p; if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) @@ -915,13 +911,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->path.dentry->d_inode->i_mode) != + if (S_ISDIR(nd->dentry->d_inode->i_mode) != S_ISDIR(mnt->mnt_root->d_inode->i_mode)) return -ENOTDIR; err = -ENOENT; - mutex_lock(&nd->path.dentry->d_inode->i_mutex); - if (IS_DEADDIR(nd->path.dentry->d_inode)) + mutex_lock(&nd->dentry->d_inode->i_mutex); + if (IS_DEADDIR(nd->dentry->d_inode)) goto out_unlock; err = security_sb_check_sb(mnt, nd); @@ -929,10 +925,10 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) goto out_unlock; err = -ENOENT; - if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) + if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) err = attach_recursive_mnt(mnt, nd, NULL); out_unlock: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); if (!err) security_sb_post_addmount(mnt, nd); return err; @@ -944,14 +940,14 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) */ static noinline int do_change_type(struct nameidata *nd, int flag) { - struct vfsmount *m, *mnt = nd->path.mnt; + struct vfsmount *m, *mnt = nd->mnt; int recurse = flag & MS_REC; int type = flag & ~MS_REC; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (nd->path.dentry != nd->path.mnt->mnt_root) + if (nd->dentry != nd->mnt->mnt_root) return -EINVAL; down_write(&namespace_sem); @@ -983,17 +979,17 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, down_write(&namespace_sem); err = -EINVAL; - if (IS_MNT_UNBINDABLE(old_nd.path.mnt)) - goto out; + if (IS_MNT_UNBINDABLE(old_nd.mnt)) + goto out; - if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) + if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) goto out; err = -ENOMEM; if (recurse) - mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0); + mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0); else - mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0); + mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0); if (!mnt) goto out; @@ -1009,7 +1005,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, out: up_write(&namespace_sem); - path_put(&old_nd.path); + path_release(&old_nd); return err; } @@ -1023,24 +1019,24 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, void *data) { int err; - struct super_block *sb = nd->path.mnt->mnt_sb; + struct super_block *sb = nd->mnt->mnt_sb; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!check_mnt(nd->path.mnt)) + if (!check_mnt(nd->mnt)) return -EINVAL; - if (nd->path.dentry != nd->path.mnt->mnt_root) + if (nd->dentry != nd->mnt->mnt_root) return -EINVAL; down_write(&sb->s_umount); err = do_remount_sb(sb, flags, data, 0); if (!err) - nd->path.mnt->mnt_flags = mnt_flags; + nd->mnt->mnt_flags = mnt_flags; up_write(&sb->s_umount); if (!err) - security_sb_post_remount(nd->path.mnt, flags, data); + security_sb_post_remount(nd->mnt, flags, data); return err; } @@ -1071,65 +1067,61 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name) return err; down_write(&namespace_sem); - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = -EINVAL; - if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) + if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) goto out; err = -ENOENT; - mutex_lock(&nd->path.dentry->d_inode->i_mutex); - if (IS_DEADDIR(nd->path.dentry->d_inode)) + mutex_lock(&nd->dentry->d_inode->i_mutex); + if (IS_DEADDIR(nd->dentry->d_inode)) goto out1; - if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry)) + if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry)) goto out1; err = -EINVAL; - if (old_nd.path.dentry != old_nd.path.mnt->mnt_root) + if (old_nd.dentry != old_nd.mnt->mnt_root) goto out1; - if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent) + if (old_nd.mnt == old_nd.mnt->mnt_parent) goto out1; - if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != - S_ISDIR(old_nd.path.dentry->d_inode->i_mode)) + if (S_ISDIR(nd->dentry->d_inode->i_mode) != + S_ISDIR(old_nd.dentry->d_inode->i_mode)) goto out1; /* * Don't move a mount residing in a shared parent. */ - if (old_nd.path.mnt->mnt_parent && - IS_MNT_SHARED(old_nd.path.mnt->mnt_parent)) + if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.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->path.mnt) && - tree_contains_unbindable(old_nd.path.mnt)) + if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt)) goto out1; err = -ELOOP; - for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent) - if (p == old_nd.path.mnt) + for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent) + if (p == old_nd.mnt) goto out1; - err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd); - if (err) + if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd))) goto out1; spin_lock(&vfsmount_lock); /* if the mount is moved, it should no longer be expire * automatically */ - list_del_init(&old_nd.path.mnt->mnt_expire); + list_del_init(&old_nd.mnt->mnt_expire); spin_unlock(&vfsmount_lock); out1: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); out: up_write(&namespace_sem); if (!err) - path_put(&parent_nd.path); - path_put(&old_nd.path); + path_release(&parent_nd); + path_release(&old_nd); return err; } @@ -1168,17 +1160,16 @@ 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->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = -EINVAL; - if (!check_mnt(nd->path.mnt)) + if (!check_mnt(nd->mnt)) goto unlock; /* Refuse the same filesystem on the same mount point */ err = -EBUSY; - if (nd->path.mnt->mnt_sb == newmnt->mnt_sb && - nd->path.mnt->mnt_root == nd->path.dentry) + if (nd->mnt->mnt_sb == newmnt->mnt_sb && + nd->mnt->mnt_root == nd->dentry) goto unlock; err = -EINVAL; @@ -1514,7 +1505,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_put(&nd.path); + path_release(&nd); return retval; } @@ -1561,17 +1552,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->root.mnt) { + if (p == fs->rootmnt) { rootmnt = p; - fs->root.mnt = mntget(q); + fs->rootmnt = mntget(q); } - if (p == fs->pwd.mnt) { + if (p == fs->pwdmnt) { pwdmnt = p; - fs->pwd.mnt = mntget(q); + fs->pwdmnt = mntget(q); } - if (p == fs->altroot.mnt) { + if (p == fs->altrootmnt) { altrootmnt = p; - fs->altroot.mnt = mntget(q); + fs->altrootmnt = mntget(q); } } p = next_mnt(p, mnt_ns->root); @@ -1652,35 +1643,44 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, * 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 path *path) +void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, + struct dentry *dentry) { - struct path old_root; - + struct dentry *old_root; + struct vfsmount *old_rootmnt; write_lock(&fs->lock); old_root = fs->root; - fs->root = *path; - path_get(path); + old_rootmnt = fs->rootmnt; + fs->rootmnt = mntget(mnt); + fs->root = dget(dentry); write_unlock(&fs->lock); - if (old_root.dentry) - path_put(&old_root); + if (old_root) { + dput(old_root); + mntput(old_rootmnt); + } } /* * 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 path *path) +void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, + struct dentry *dentry) { - struct path old_pwd; + struct dentry *old_pwd; + struct vfsmount *old_pwdmnt; write_lock(&fs->lock); old_pwd = fs->pwd; - fs->pwd = *path; - path_get(path); + old_pwdmnt = fs->pwdmnt; + fs->pwdmnt = mntget(mnt); + fs->pwd = dget(dentry); write_unlock(&fs->lock); - if (old_pwd.dentry) - path_put(&old_pwd); + if (old_pwd) { + dput(old_pwd); + mntput(old_pwdmnt); + } } 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.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); + 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); 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.path.mnt)) + if (!check_mnt(new_nd.mnt)) goto out1; error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); @@ -1759,78 +1759,74 @@ asmlinkage long sys_pivot_root(const char __user * new_root, error = security_sb_pivotroot(&old_nd, &new_nd); if (error) { - path_put(&old_nd.path); + path_release(&old_nd); goto out1; } read_lock(¤t->fs->lock); - user_nd.path = current->fs->root; - path_get(¤t->fs->root); + user_nd.mnt = mntget(current->fs->rootmnt); + user_nd.dentry = dget(current->fs->root); read_unlock(¤t->fs->lock); down_write(&namespace_sem); - mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); + mutex_lock(&old_nd.dentry->d_inode->i_mutex); error = -EINVAL; - 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)) + if (IS_MNT_SHARED(old_nd.mnt) || + IS_MNT_SHARED(new_nd.mnt->mnt_parent) || + IS_MNT_SHARED(user_nd.mnt->mnt_parent)) goto out2; - if (!check_mnt(user_nd.path.mnt)) + if (!check_mnt(user_nd.mnt)) goto out2; error = -ENOENT; - if (IS_DEADDIR(new_nd.path.dentry->d_inode)) + if (IS_DEADDIR(new_nd.dentry->d_inode)) goto out2; - if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) + if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry)) goto out2; - if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) + if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry)) goto out2; error = -EBUSY; - if (new_nd.path.mnt == user_nd.path.mnt || - old_nd.path.mnt == user_nd.path.mnt) + if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt) goto out2; /* loop, on the same file system */ error = -EINVAL; - if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) + if (user_nd.mnt->mnt_root != user_nd.dentry) goto out2; /* not a mountpoint */ - if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) + if (user_nd.mnt->mnt_parent == user_nd.mnt) goto out2; /* not attached */ - if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) + if (new_nd.mnt->mnt_root != new_nd.dentry) goto out2; /* not a mountpoint */ - if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) + if (new_nd.mnt->mnt_parent == new_nd.mnt) goto out2; /* not attached */ - /* make sure we can reach put_old from new_root */ - tmp = old_nd.path.mnt; + tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */ spin_lock(&vfsmount_lock); - if (tmp != new_nd.path.mnt) { + if (tmp != new_nd.mnt) { for (;;) { if (tmp->mnt_parent == tmp) goto out3; /* already mounted on put_old */ - if (tmp->mnt_parent == new_nd.path.mnt) + if (tmp->mnt_parent == new_nd.mnt) break; tmp = tmp->mnt_parent; } - if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) + if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry)) goto out3; - } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) + } else if (!is_subdir(old_nd.dentry, new_nd.dentry)) goto out3; - 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); + 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 / */ 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_put(&root_parent.path); - path_put(&parent_nd.path); + path_release(&root_parent); + path_release(&parent_nd); out2: - mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&old_nd.dentry->d_inode->i_mutex); up_write(&namespace_sem); - path_put(&user_nd.path); - path_put(&old_nd.path); + path_release(&user_nd); + path_release(&old_nd); out1: - path_put(&new_nd.path); + path_release(&new_nd); out0: unlock_kernel(); return error; @@ -1843,7 +1839,6 @@ 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)) @@ -1862,11 +1857,8 @@ static void __init init_mount_tree(void) init_task.nsproxy->mnt_ns = ns; get_mnt_ns(ns); - root.mnt = ns->root; - root.dentry = ns->root->mnt_root; - - set_fs_pwd(current->fs, &root); - set_fs_root(current->fs, &root); + set_fs_pwd(current->fs, ns->root, ns->root->mnt_root); + set_fs_root(current->fs, ns->root, ns->root->mnt_root); } void __init mnt_init(void) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 607f6eb9cdb5..be4ce1c3a3d8 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -107,40 +107,38 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) BUG_ON(IS_ROOT(dentry)); dprintk("%s: enter\n", __FUNCTION__); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); /* Look it up again */ - parent = dget_parent(nd->path.dentry); + parent = dget_parent(nd->dentry); err = server->nfs_client->rpc_ops->lookup(parent->d_inode, - &nd->path.dentry->d_name, + &nd->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->path.mnt, nd->path.dentry); + mnt = nfs_do_refmount(nd->mnt, nd->dentry); else - mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh, - &fattr); + mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr); err = PTR_ERR(mnt); if (IS_ERR(mnt)) goto out_err; mntget(mnt); - err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, - &nfs_automount_list); + err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); if (err < 0) { mntput(mnt); if (err == -EBUSY) goto out_follow; goto out_err; } - mntput(nd->path.mnt); - dput(nd->path.dentry); - nd->path.mnt = mnt; - nd->path.dentry = dget(mnt->mnt_root); + mntput(nd->mnt); + dput(nd->dentry); + nd->mnt = mnt; + nd->dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: dprintk("%s: done, returned %d\n", __FUNCTION__, err); @@ -148,11 +146,10 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) dprintk("<-- nfs_follow_mountpoint() = %d\n", err); return ERR_PTR(err); out_err: - path_put(&nd->path); + path_release(nd); goto out; out_follow: - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = 0; goto out; diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 7ce07862c2fb..027e1095256e 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -1384,11 +1384,11 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct struct dentry * nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { + struct dentry *parent; struct path path = { - .mnt = nd->path.mnt, + .mnt = nd->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->path.mnt, + .mnt = nd->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->path.mnt, + .mnt = nd->mnt, .dentry = dentry, }; struct nfs4_state *state; diff --git a/trunk/fs/nfsctl.c b/trunk/fs/nfsctl.c index aed8145d9087..51f1b31acbf6 100644 --- a/trunk/fs/nfsctl.c +++ b/trunk/fs/nfsctl.c @@ -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.path.dentry, nd.path.mnt, flags); + return dentry_open(nd.dentry, nd.mnt, flags); - path_put(&nd.path); + path_release(&nd); return ERR_PTR(error); } diff --git a/trunk/fs/nfsd/export.c b/trunk/fs/nfsd/export.c index 8a6f7c924c75..346570f6d848 100644 --- a/trunk/fs/nfsd/export.c +++ b/trunk/fs/nfsd/export.c @@ -63,8 +63,10 @@ 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)) - path_put(&key->ek_path); + !test_bit(CACHE_NEGATIVE, &key->h.flags)) { + dput(key->ek_dentry); + mntput(key->ek_mnt); + } auth_domain_put(key->ek_client); kfree(key); } @@ -167,14 +169,15 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) goto out; dprintk("Found the path %s\n", buf); - key.ek_path = nd.path; - + key.ek_mnt = nd.mnt; + key.ek_dentry = nd.dentry; + ek = svc_expkey_update(&key, ek); if (ek) cache_put(&ek->h, &svc_expkey_cache); else err = -ENOMEM; - path_put(&nd.path); + path_release(&nd); } cache_flush(); out: @@ -203,7 +206,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_path, "\\ \t\n"); + seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n"); } seq_printf(m, "\n"); return 0; @@ -240,8 +243,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_path = item->ek_path; - path_get(&item->ek_path); + new->ek_mnt = mntget(item->ek_mnt); + new->ek_dentry = dget(item->ek_dentry); } static struct cache_head *expkey_alloc(void) @@ -329,9 +332,10 @@ 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); - path_put(&exp->ex_path); + dput(exp->ex_dentry); + mntput(exp->ex_mnt); auth_domain_put(exp->ex_client); - kfree(exp->ex_pathname); + kfree(exp->ex_path); nfsd4_fslocs_free(&exp->ex_fslocs); kfree(exp); } @@ -345,7 +349,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_path, *bpp, *blen); + pth = d_path(exp->ex_dentry, exp->ex_mnt, *bpp, *blen); if (IS_ERR(pth)) { /* is this correct? */ (*bpp)[0] = '\n'; @@ -503,8 +507,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) struct svc_export exp, *expp; int an_int; - nd.path.dentry = NULL; - exp.ex_pathname = NULL; + nd.dentry = NULL; + exp.ex_path = NULL; /* fs locations */ exp.ex_fslocs.locations = NULL; @@ -543,11 +547,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) exp.h.flags = 0; exp.ex_client = dom; - exp.ex_path.mnt = nd.path.mnt; - exp.ex_path.dentry = nd.path.dentry; - exp.ex_pathname = kstrdup(buf, GFP_KERNEL); + exp.ex_mnt = nd.mnt; + exp.ex_dentry = nd.dentry; + exp.ex_path = kstrdup(buf, GFP_KERNEL); err = -ENOMEM; - if (!exp.ex_pathname) + if (!exp.ex_path) goto out; /* expiry */ @@ -606,7 +610,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) goto out; } - err = check_export(nd.path.dentry->d_inode, exp.ex_flags, + err = check_export(nd.dentry->d_inode, exp.ex_flags, exp.ex_uuid); if (err) goto out; } @@ -624,9 +628,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_pathname); - if (nd.path.dentry) - path_put(&nd.path); + kfree(exp.ex_path); + if (nd.dentry) + path_release(&nd); out_no_path: if (dom) auth_domain_put(dom); @@ -649,7 +653,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_path, " \t\n\\"); + seq_path(m, exp->ex_mnt, exp->ex_dentry, " \t\n\\"); seq_putc(m, '\t'); seq_escape(m, exp->ex_client->name, " \t\n\\"); seq_putc(m, '('); @@ -676,8 +680,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_path.dentry == new->ex_path.dentry && - orig->ex_path.mnt == new->ex_path.mnt; + orig->ex_dentry == new->ex_dentry && + orig->ex_mnt == new->ex_mnt; } static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) @@ -687,9 +691,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_path.dentry = dget(item->ex_path.dentry); - new->ex_path.mnt = mntget(item->ex_path.mnt); - new->ex_pathname = NULL; + new->ex_dentry = dget(item->ex_dentry); + new->ex_mnt = mntget(item->ex_mnt); + new->ex_path = NULL; new->ex_fslocs.locations = NULL; new->ex_fslocs.locations_count = 0; new->ex_fslocs.migrated = 0; @@ -707,8 +711,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_pathname = item->ex_pathname; - item->ex_pathname = NULL; + new->ex_path = item->ex_path; + item->ex_path = NULL; new->ex_fslocs.locations = item->ex_fslocs.locations; item->ex_fslocs.locations = NULL; new->ex_fslocs.locations_count = item->ex_fslocs.locations_count; @@ -751,8 +755,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_path.dentry, EXPORT_HASHBITS); - hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS); + hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS); + hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS); ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h, hash); @@ -768,8 +772,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_path.dentry, EXPORT_HASHBITS); - hash ^= hash_ptr(old->ex_path.mnt, EXPORT_HASHBITS); + hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS); + hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS); ch = sunrpc_cache_update(&svc_export_cache, &new->h, &old->h, @@ -811,7 +815,8 @@ 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_path = exp->ex_path; + key.ek_mnt = exp->ex_mnt; + key.ek_dentry = exp->ex_dentry; key.h.expiry_time = NEVER; key.h.flags = 0; @@ -860,13 +865,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_path.mnt = mnt; - key.ex_path.dentry = dentry; + key.ex_mnt = mnt; + key.ex_dentry = dentry; exp = svc_export_lookup(&key); if (exp == NULL) @@ -963,7 +968,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_path.dentry->d_inode; + struct inode *inode = exp->ex_dentry->d_inode; dev_t dev = inode->i_sb->s_dev; if (old_valid_dev(dev)) { @@ -977,7 +982,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_path.dentry->d_inode; + struct inode *inode = exp->ex_dentry->d_inode; ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); if (!IS_ERR(ek)) { @@ -1025,16 +1030,15 @@ exp_export(struct nfsctl_export *nxp) goto out_unlock; err = -EINVAL; - exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL); + exp = exp_get_by_name(clp, nd.mnt, nd.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_path.mnt && - (fsid_key->ek_path.mnt != nd.path.mnt || - fsid_key->ek_path.dentry != nd.path.dentry)) + fsid_key->ek_mnt && + (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) ) goto finish; if (!IS_ERR(exp)) { @@ -1050,7 +1054,7 @@ exp_export(struct nfsctl_export *nxp) goto finish; } - err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL); + err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL); if (err) goto finish; err = -ENOMEM; @@ -1059,11 +1063,12 @@ exp_export(struct nfsctl_export *nxp) new.h.expiry_time = NEVER; new.h.flags = 0; - new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL); - if (!new.ex_pathname) + new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); + if (!new.ex_path) goto finish; new.ex_client = clp; - new.ex_path = nd.path; + new.ex_mnt = nd.mnt; + new.ex_dentry = nd.dentry; new.ex_flags = nxp->ex_flags; new.ex_anon_uid = nxp->ex_anon_uid; new.ex_anon_gid = nxp->ex_anon_gid; @@ -1084,14 +1089,15 @@ exp_export(struct nfsctl_export *nxp) } else err = 0; finish: - kfree(new.ex_pathname); + if (new.ex_path) + kfree(new.ex_path); 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_put(&nd.path); + path_release(&nd); out_unlock: exp_writeunlock(); out: @@ -1142,8 +1148,8 @@ exp_unexport(struct nfsctl_export *nxp) goto out_domain; err = -EINVAL; - exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL); - path_put(&nd.path); + exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); + path_release(&nd); if (IS_ERR(exp)) goto out_domain; @@ -1179,12 +1185,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.path.dentry->d_inode; + inode = nd.dentry->d_inode; dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", - path, nd.path.dentry, clp->name, + path, nd.dentry, clp->name, inode->i_sb->s_id, inode->i_ino); - exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL); + exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); if (IS_ERR(exp)) { err = PTR_ERR(exp); goto out; @@ -1194,7 +1200,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.path.dentry, NULL)) + if (fh_compose(&fh, exp, nd.dentry, NULL)) err = -EINVAL; else err = 0; @@ -1202,7 +1208,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) fh_put(&fh); exp_put(exp); out: - path_put(&nd.path); + path_release(&nd); return err; } @@ -1214,7 +1220,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_path.mnt, ek->ek_path.dentry, reqp); + exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp); cache_put(&ek->h, &svc_expkey_cache); if (IS_ERR(exp)) @@ -1353,7 +1359,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_path.dentry, NULL); + rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); if (rv) goto out; rv = check_nfsd_access(exp, rqstp); diff --git a/trunk/fs/nfsd/nfs3proc.c b/trunk/fs/nfsd/nfs3proc.c index c721a1e6e9dd..eac82830bfd7 100644 --- a/trunk/fs/nfsd/nfs3proc.c +++ b/trunk/fs/nfsd/nfs3proc.c @@ -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_path.mnt, + err = vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat); nfserr = nfserrno(err); diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 17d0dd997204..d7647f70e02b 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -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_path.mnt, dentry, &stat); + err = vfs_getattr(fhp->fh_export->ex_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_path.mnt, fhp->fh_dentry, + err = vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &fhp->fh_post_attr); if (err) fhp->fh_post_saved = 0; diff --git a/trunk/fs/nfsd/nfs4recover.c b/trunk/fs/nfsd/nfs4recover.c index 1ff90625860f..1602cd00dd45 100644 --- a/trunk/fs/nfsd/nfs4recover.c +++ b/trunk/fs/nfsd/nfs4recover.c @@ -120,9 +120,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) static void nfsd4_sync_rec_dir(void) { - 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); + mutex_lock(&rec_dir.dentry->d_inode->i_mutex); + nfsd_sync_dir(rec_dir.dentry); + mutex_unlock(&rec_dir.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.path.dentry->d_inode->i_mutex); + mutex_lock(&rec_dir.dentry->d_inode->i_mutex); - dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1); + dentry = lookup_one_len(dname, rec_dir.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.path.dentry->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); out_put: dput(dentry); out_unlock: - mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); + mutex_unlock(&rec_dir.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.path.mnt), O_RDONLY); + filp = dentry_open(dget(dir), mntget(rec_dir.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.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); + 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); 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.path.dentry, dentry); + status = nfsd4_clear_clid_dir(rec_dir.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.path.dentry, purge_old); + status = nfsd4_list_rec_dir(rec_dir.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.path.dentry->d_name.name); + " directory %s\n", rec_dir.dentry->d_name.name); return; } @@ -373,10 +373,10 @@ int nfsd4_recdir_load(void) { int status; - status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir); + status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir); if (status) printk("nfsd4: failed loading clients from recovery" - " directory %s\n", rec_dir.path.dentry->d_name.name); + " directory %s\n", rec_dir.dentry->d_name.name); return status; } @@ -415,5 +415,5 @@ nfsd4_shutdown_recdir(void) if (!rec_dir_init) return; rec_dir_init = 0; - path_put(&rec_dir.path); + path_release(&rec_dir); } diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index bcb97d8e8b8b..f6744bc03dae 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -3261,11 +3261,11 @@ nfs4_reset_recoverydir(char *recdir) if (status) return status; status = -ENOTDIR; - if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) { + if (S_ISDIR(nd.dentry->d_inode->i_mode)) { nfs4_set_recdir(recdir); status = 0; } - path_put(&nd.path); + path_release(&nd); return status; } diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 0e6a179eccaf..b0592e7c378d 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -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_pathname; + rootpath = tmp_fh.fh_export->ex_path; - path = exp->ex_pathname; + path = exp->ex_path; 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_path.mnt, dentry, &stat); + err = vfs_getattr(exp->ex_mnt, dentry, &stat); if (err) goto out_nfserr; if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | @@ -1838,9 +1838,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, * and this is the root of a cross-mounted filesystem. */ if (ignore_crossmnt == 0 && - 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); + exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { + err = vfs_getattr(exp->ex_mnt->mnt_parent, + exp->ex_mnt->mnt_mountpoint, &stat); if (err) goto out_nfserr; } diff --git a/trunk/fs/nfsd/nfsfh.c b/trunk/fs/nfsd/nfsfh.c index 0130b345234d..8fbd2dc08a92 100644 --- a/trunk/fs/nfsd/nfsfh.c +++ b/trunk/fs/nfsd/nfsfh.c @@ -47,7 +47,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) return 1; tdentry = dget(dentry); - while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) { + while (tdentry != exp->ex_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_path.dentry) + if (tdentry != exp->ex_dentry) dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name); - rv = (tdentry == exp->ex_path.dentry); + rv = (tdentry == exp->ex_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_path.dentry); + dentry = dget(exp->ex_dentry); else { - dentry = exportfs_decode_fh(exp->ex_path.mnt, fid, + dentry = exportfs_decode_fh(exp->ex_mnt, fid, data_left, fileid_type, nfsd_acceptable, exp); } @@ -299,7 +299,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry) { - if (dentry != exp->ex_path.dentry) { + if (dentry != exp->ex_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_path.dentry->d_inode->i_sb->s_dev; - int root_export = (exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root); + 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); dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", MAJOR(ex_dev), MINOR(ex_dev), - (long) exp->ex_path.dentry->d_inode->i_ino, + (long) exp->ex_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_path.dentry->d_inode->i_sb->s_type->fs_flags + if (!(exp->ex_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_path.dentry->d_inode->i_ino); + ino_t_to_u32(exp->ex_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_path.dentry->d_inode->i_ino, + exp->ex_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_path.dentry->d_inode->i_sb->s_type->fs_flags + if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) return FSIDSOURCE_DEV; break; diff --git a/trunk/fs/nfsd/nfsproc.c b/trunk/fs/nfsd/nfsproc.c index 6cfc96a12483..977a71f64e19 100644 --- a/trunk/fs/nfsd/nfsproc.c +++ b/trunk/fs/nfsd/nfsproc.c @@ -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_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_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_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_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_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat)); } diff --git a/trunk/fs/nfsd/nfsxdr.c b/trunk/fs/nfsd/nfsxdr.c index afd08e2c90a5..61ad61743d94 100644 --- a/trunk/fs/nfsd/nfsxdr.c +++ b/trunk/fs/nfsd/nfsxdr.c @@ -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_path.mnt, fhp->fh_dentry, &stat); + vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); return encode_fattr(rqstp, p, fhp, &stat); } diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 46f59d5365a0..cc75e4fcd02b 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -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_path.mnt); + struct vfsmount *mnt = mntget(exp->ex_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_path.dentry) + else if (dparent != exp->ex_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_path.mnt); + struct vfsmount *mnt = mntget(exp->ex_mnt); dentry = dget(dparent); while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) ; @@ -721,8 +721,7 @@ 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_path.mnt), - flags); + *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags); if (IS_ERR(*filp)) host_err = PTR_ERR(*filp); out_nfserr: @@ -1463,7 +1462,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_path.mnt, dentry); + touch_atime(fhp->fh_export->ex_mnt, dentry); /* N.B. Why does this call need a get_fs()?? * Remove the set_fs and watch the fireworks:-) --okir */ diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 54198538b67e..43fcd6031969 100644 --- a/trunk/fs/open.c +++ b/trunk/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.path.dentry, &tmp); + error = vfs_statfs_native(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } 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.path.dentry, &tmp); + error = vfs_statfs64(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } 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.path.dentry->d_inode; + inode = nd.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.path.dentry, length, 0, NULL); + error = do_truncate(nd.dentry, length, 0, NULL); } put_write_and_out: put_write_access(inode); dput_and_out: - path_put(&nd.path); + path_release(&nd); 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.path.dentry->d_inode->i_mode)) + special_file(nd.dentry->d_inode->i_mode)) goto out_path_release; - if(IS_RDONLY(nd.path.dentry->d_inode)) + if(IS_RDONLY(nd.dentry->d_inode)) res = -EROFS; out_path_release: - path_put(&nd.path); + path_release(&nd); 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.path); + set_fs_pwd(current->fs, nd.mnt, nd.dentry); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -501,7 +501,9 @@ asmlinkage long sys_chdir(const char __user * filename) asmlinkage long sys_fchdir(unsigned int fd) { struct file *file; + struct dentry *dentry; struct inode *inode; + struct vfsmount *mnt; int error; error = -EBADF; @@ -509,7 +511,9 @@ asmlinkage long sys_fchdir(unsigned int fd) if (!file) goto out; - inode = file->f_path.dentry->d_inode; + dentry = file->f_path.dentry; + mnt = file->f_path.mnt; + inode = dentry->d_inode; error = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) @@ -517,7 +521,7 @@ asmlinkage long sys_fchdir(unsigned int fd) error = file_permission(file, MAY_EXEC); if (!error) - set_fs_pwd(current->fs, &file->f_path); + set_fs_pwd(current->fs, mnt, dentry); out_putf: fput(file); out: @@ -541,11 +545,11 @@ asmlinkage long sys_chroot(const char __user * filename) if (!capable(CAP_SYS_CHROOT)) goto dput_and_out; - set_fs_root(current->fs, &nd.path); + set_fs_root(current->fs, nd.mnt, nd.dentry); set_fs_altroot(); error = 0; dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -598,7 +602,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.path.dentry->d_inode; + inode = nd.dentry->d_inode; error = -EROFS; if (IS_RDONLY(inode)) @@ -613,11 +617,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.path.dentry, &newattrs); + error = notify_change(nd.dentry, &newattrs); mutex_unlock(&inode->i_mutex); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -671,8 +675,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.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -691,8 +695,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.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -705,8 +709,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.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -859,7 +863,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->path.mnt), + nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt), nd->intent.open.flags - 1, nd->intent.open.file, open); @@ -887,10 +891,9 @@ 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->path.dentry, nd->path.mnt, flags, filp, - NULL); + filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL); else - path_put(&nd->path); + path_release(nd); return filp; } diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 88f8edf18258..7c6b4ec83cb7 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk) return count; } -static int proc_cwd_link(struct inode *inode, struct path *path) +static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { 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 path *path) } if (fs) { read_lock(&fs->lock); - *path = fs->pwd; - path_get(&fs->pwd); + *mnt = mntget(fs->pwdmnt); + *dentry = dget(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 path *path) return result; } -static int proc_root_link(struct inode *inode, struct path *path) +static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { 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 path *path) } if (fs) { read_lock(&fs->lock); - *path = fs->root; - path_get(&fs->root); + *mnt = mntget(fs->rootmnt); + *dentry = dget(fs->root); read_unlock(&fs->lock); result = 0; put_fs_struct(fs); @@ -1164,36 +1164,39 @@ 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_put(&nd->path); + path_release(nd); /* 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->path); + error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); nd->last_type = LAST_BIND; out: return ERR_PTR(error); } -static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) +static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, + char __user *buffer, int buflen) { + struct inode * inode; char *tmp = (char*)__get_free_page(GFP_TEMPORARY); - char *pathname; + char *path; int len; if (!tmp) return -ENOMEM; - pathname = d_path(path, tmp, PAGE_SIZE); - len = PTR_ERR(pathname); - if (IS_ERR(pathname)) + inode = dentry->d_inode; + path = d_path(dentry, mnt, tmp, PAGE_SIZE); + len = PTR_ERR(path); + if (IS_ERR(path)) goto out; - len = tmp + PAGE_SIZE - 1 - pathname; + len = tmp + PAGE_SIZE - 1 - path; if (len > buflen) len = buflen; - if (copy_to_user(buffer, pathname, len)) + if (copy_to_user(buffer, path, len)) len = -EFAULT; out: free_page((unsigned long)tmp); @@ -1204,18 +1207,20 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b { int error = -EACCES; struct inode *inode = dentry->d_inode; - struct path path; + struct dentry *de; + struct vfsmount *mnt = NULL; /* 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, &path); + error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); if (error) goto out; - error = do_proc_readlink(&path, buffer, buflen); - path_put(&path); + error = do_proc_readlink(de, mnt, buffer, buflen); + dput(de); + mntput(mnt); out: return error; } @@ -1442,7 +1447,8 @@ static unsigned name_to_int(struct dentry *dentry) #define PROC_FDINFO_MAX 64 -static int proc_fd_info(struct inode *inode, struct path *path, char *info) +static int proc_fd_info(struct inode *inode, struct dentry **dentry, + struct vfsmount **mnt, char *info) { struct task_struct *task = get_proc_task(inode); struct files_struct *files = NULL; @@ -1461,10 +1467,10 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { - if (path) { - *path = file->f_path; - path_get(&file->f_path); - } + if (mnt) + *mnt = mntget(file->f_path.mnt); + if (dentry) + *dentry = dget(file->f_path.dentry); if (info) snprintf(info, PROC_FDINFO_MAX, "pos:\t%lli\n" @@ -1481,9 +1487,10 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) return -ENOENT; } -static int proc_fd_link(struct inode *inode, struct path *path) +static int proc_fd_link(struct inode *inode, struct dentry **dentry, + struct vfsmount **mnt) { - return proc_fd_info(inode, path, NULL); + return proc_fd_info(inode, dentry, mnt, NULL); } static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) @@ -1677,7 +1684,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, tmp); + int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); if (!err) err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); return err; diff --git a/trunk/fs/proc/internal.h b/trunk/fs/proc/internal.h index 1c81c8f1aeed..ea496ffeabe7 100644 --- a/trunk/fs/proc/internal.h +++ b/trunk/fs/proc/internal.h @@ -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 path *); +extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); 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, diff --git a/trunk/fs/proc/nommu.c b/trunk/fs/proc/nommu.c index 941e95114b5a..5d9147b9d738 100644 --- a/trunk/fs/proc/nommu.c +++ b/trunk/fs/proc/nommu.c @@ -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, ""); + seq_path(m, file->f_path.mnt, file->f_path.dentry, ""); } seq_putc(m, '\n'); diff --git a/trunk/fs/proc/proc_sysctl.c b/trunk/fs/proc/proc_sysctl.c index 614c34b6d1c2..b9cb23c08f63 100644 --- a/trunk/fs/proc/proc_sysctl.c +++ b/trunk/fs/proc/proc_sysctl.c @@ -407,7 +407,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * if (!nd || !depth) goto out; - dentry = nd->path.dentry; + dentry = nd->dentry; table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); /* If the entry does not exist deny permission */ diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 49958cffbd8d..ae4d3f2c8cb2 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -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 path *path) +int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct vm_area_struct * vma; int result = -ENOENT; @@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct path *path) } if (vma) { - *path = vma->vm_file->f_path; - path_get(&vma->vm_file->f_path); + *mnt = mntget(vma->vm_file->f_path.mnt); + *dentry = dget(vma->vm_file->f_path.dentry); 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, "\n"); + seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n"); } else { const char *name = arch_vma_name(vma); if (!name) { diff --git a/trunk/fs/proc/task_nommu.c b/trunk/fs/proc/task_nommu.c index 8011528518bd..abfc6f5e56ca 100644 --- a/trunk/fs/proc/task_nommu.c +++ b/trunk/fs/proc/task_nommu.c @@ -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 path *path) +int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct vm_list_struct *vml; struct vm_area_struct *vma; @@ -126,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct path *path) } if (vma) { - *path = vma->vm_file->f_path; - path_get(&vma->vm_file->f_path); + *mnt = mntget(vma->vm_file->f_path.mnt); + *dentry = dget(vma->vm_file->f_path.dentry); result = 0; } diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 6841452e0dea..6033f0c3bd0b 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -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.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* We must not pack tails for quota files on reiserfs for quota IO to work */ - if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { + if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) { reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled."); - path_put(&nd.path); + path_release(&nd); 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_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.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_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index 853770274f20..ca71c115bdaa 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -342,11 +342,13 @@ int seq_printf(struct seq_file *m, const char *f, ...) } EXPORT_SYMBOL(seq_printf); -int seq_path(struct seq_file *m, struct path *path, char *esc) +int seq_path(struct seq_file *m, + struct vfsmount *mnt, struct dentry *dentry, + char *esc) { if (m->count < m->size) { char *s = m->buf + m->count; - char *p = d_path(path, s, m->size - m->count); + char *p = d_path(dentry, mnt, s, m->size - m->count); if (!IS_ERR(p)) { while (s <= p) { char c = *p++; diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index 9cf41f719d50..68510068a641 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -62,8 +62,8 @@ int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); if (!error) { - error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_put(&nd.path); + error = vfs_getattr(nd.mnt, nd.dentry, stat); + path_release(&nd); } return error; } @@ -82,8 +82,8 @@ int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) error = __user_walk_fd(dfd, name, 0, &nd); if (!error) { - error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_put(&nd.path); + error = vfs_getattr(nd.mnt, nd.dentry, stat); + path_release(&nd); } return error; } @@ -302,18 +302,17 @@ asmlinkage long sys_readlinkat(int dfd, const char __user *path, error = __user_walk_fd(dfd, path, 0, &nd); if (!error) { - struct inode *inode = nd.path.dentry->d_inode; + struct inode * inode = nd.dentry->d_inode; error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(nd.path.dentry); + error = security_inode_readlink(nd.dentry); if (!error) { - touch_atime(nd.path.mnt, nd.path.dentry); - error = inode->i_op->readlink(nd.path.dentry, - buf, bufsiz); + touch_atime(nd.mnt, nd.dentry); + error = inode->i_op->readlink(nd.dentry, buf, bufsiz); } } - path_put(&nd.path); + path_release(&nd); } return error; } diff --git a/trunk/fs/utimes.c b/trunk/fs/utimes.c index b18da9c0b97f..e5588cd8530e 100644 --- a/trunk/fs/utimes.c +++ b/trunk/fs/utimes.c @@ -84,7 +84,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (error) goto out; - dentry = nd.path.dentry; + dentry = nd.dentry; } inode = dentry->d_inode; @@ -138,7 +138,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (f) fput(f); else - path_put(&nd.path); + path_release(&nd); out: return error; } diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 3acab1615460..f7c8f87bb390 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -262,8 +262,8 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk(path, &nd); if (error) return error; - error = setxattr(nd.path.dentry, name, value, size, flags); - path_put(&nd.path); + error = setxattr(nd.dentry, name, value, size, flags); + path_release(&nd); return error; } @@ -277,8 +277,8 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk_link(path, &nd); if (error) return error; - error = setxattr(nd.path.dentry, name, value, size, flags); - path_put(&nd.path); + error = setxattr(nd.dentry, name, value, size, flags); + path_release(&nd); return error; } @@ -347,8 +347,8 @@ sys_getxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk(path, &nd); if (error) return error; - error = getxattr(nd.path.dentry, name, value, size); - path_put(&nd.path); + error = getxattr(nd.dentry, name, value, size); + path_release(&nd); return error; } @@ -362,8 +362,8 @@ sys_lgetxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk_link(path, &nd); if (error) return error; - error = getxattr(nd.path.dentry, name, value, size); - path_put(&nd.path); + error = getxattr(nd.dentry, name, value, size); + path_release(&nd); return error; } @@ -421,8 +421,8 @@ sys_listxattr(char __user *path, char __user *list, size_t size) error = user_path_walk(path, &nd); if (error) return error; - error = listxattr(nd.path.dentry, list, size); - path_put(&nd.path); + error = listxattr(nd.dentry, list, size); + path_release(&nd); return error; } @@ -435,8 +435,8 @@ sys_llistxattr(char __user *path, char __user *list, size_t size) error = user_path_walk_link(path, &nd); if (error) return error; - error = listxattr(nd.path.dentry, list, size); - path_put(&nd.path); + error = listxattr(nd.dentry, list, size); + path_release(&nd); return error; } @@ -482,8 +482,8 @@ sys_removexattr(char __user *path, char __user *name) error = user_path_walk(path, &nd); if (error) return error; - error = removexattr(nd.path.dentry, name); - path_put(&nd.path); + error = removexattr(nd.dentry, name); + path_release(&nd); return error; } @@ -496,8 +496,8 @@ sys_lremovexattr(char __user *path, char __user *name) error = user_path_walk_link(path, &nd); if (error) return error; - error = removexattr(nd.path.dentry, name); - path_put(&nd.path); + error = removexattr(nd.dentry, name); + path_release(&nd); return error; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index a9952e490ac9..4c82a050a3a8 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -91,10 +91,10 @@ xfs_find_handle( if (error) return error; - ASSERT(nd.path.dentry); - ASSERT(nd.path.dentry->d_inode); - inode = igrab(nd.path.dentry->d_inode); - path_put(&nd.path); + ASSERT(nd.dentry); + ASSERT(nd.dentry->d_inode); + inode = igrab(nd.dentry->d_inode); + path_release(&nd); break; } diff --git a/trunk/include/asm-m68knommu/cacheflush.h b/trunk/include/asm-m68knommu/cacheflush.h index 87e5dc0413b4..29bc0aad2ebc 100644 --- a/trunk/include/asm-m68knommu/cacheflush.h +++ b/trunk/include/asm-m68knommu/cacheflush.h @@ -54,28 +54,28 @@ static inline void __flush_cache_all(void) #if defined(CONFIG_M527x) || defined(CONFIG_M528x) __asm__ __volatile__ ( "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M527x || CONFIG_M528x */ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) __asm__ __volatile__ ( - "movel #0x81000100, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0x81000100, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ #ifdef CONFIG_M5249 __asm__ __volatile__ ( - "movel #0xa1000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0xa1000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M5249 */ #ifdef CONFIG_M532x __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0x81000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M532x */ diff --git a/trunk/include/asm-m68knommu/system.h b/trunk/include/asm-m68knommu/system.h index 64c64432bbb8..039ab3f81732 100644 --- a/trunk/include/asm-m68knommu/system.h +++ b/trunk/include/asm-m68knommu/system.h @@ -104,7 +104,7 @@ asmlinkage void resume(void); #define mb() asm volatile ("" : : :"memory") #define rmb() asm volatile ("" : : :"memory") #define wmb() asm volatile ("" : : :"memory") -#define set_mb(var, value) ({ (var) = (value); wmb(); }) +#define set_mb(var, value) do { xchg(&var, value); } while (0) #ifdef CONFIG_SMP #define smp_mb() mb() diff --git a/trunk/include/asm-powerpc/systbl.h b/trunk/include/asm-powerpc/systbl.h index ae7085c65692..e996521fb3a6 100644 --- a/trunk/include/asm-powerpc/systbl.h +++ b/trunk/include/asm-powerpc/systbl.h @@ -309,10 +309,8 @@ SYSCALL_SPU(getcpu) COMPAT_SYS(epoll_pwait) COMPAT_SYS_SPU(utimensat) COMPAT_SYS_SPU(signalfd) -SYSCALL_SPU(timerfd_create) +SYSCALL(ni_syscall) SYSCALL_SPU(eventfd) COMPAT_SYS_SPU(sync_file_range2) COMPAT_SYS(fallocate) SYSCALL(subpage_prot) -COMPAT_SYS_SPU(timerfd_settime) -COMPAT_SYS_SPU(timerfd_gettime) diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index ce91bb662063..fedc4b8e49e2 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -328,17 +328,15 @@ #define __NR_epoll_pwait 303 #define __NR_utimensat 304 #define __NR_signalfd 305 -#define __NR_timerfd_create 306 +#define __NR_timerfd 306 #define __NR_eventfd 307 #define __NR_sync_file_range2 308 #define __NR_fallocate 309 #define __NR_subpage_prot 310 -#define __NR_timerfd_settime 311 -#define __NR_timerfd_gettime 312 #ifdef __KERNEL__ -#define __NR_syscalls 313 +#define __NR_syscalls 311 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/trunk/include/asm-ppc/page.h b/trunk/include/asm-ppc/page.h index 37e4756b6b2d..ad4c5a1bc9d6 100644 --- a/trunk/include/asm-ppc/page.h +++ b/trunk/include/asm-ppc/page.h @@ -125,8 +125,6 @@ extern __inline__ int get_order(unsigned long size) return 32 - lz; } -typedef struct page *pgtable_t; - #endif /* __ASSEMBLY__ */ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ diff --git a/trunk/include/asm-x86/cacheflush.h b/trunk/include/asm-x86/cacheflush.h index 5396c212d8c0..6a22212b4b20 100644 --- a/trunk/include/asm-x86/cacheflush.h +++ b/trunk/include/asm-x86/cacheflush.h @@ -48,15 +48,12 @@ void cpa_init(void); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); -extern const int rodata_test_data; #endif - #ifdef CONFIG_DEBUG_RODATA_TEST -int rodata_test(void); +void rodata_test(void); #else -static inline int rodata_test(void) +static inline void rodata_test(void) { - return 0; } #endif diff --git a/trunk/include/asm-x86/kdebug.h b/trunk/include/asm-x86/kdebug.h index 99dcbafa1511..dd442a1632c0 100644 --- a/trunk/include/asm-x86/kdebug.h +++ b/trunk/include/asm-x86/kdebug.h @@ -31,6 +31,7 @@ extern void show_trace(struct task_struct *t, struct pt_regs *regs, unsigned long *sp, unsigned long bp); extern void __show_regs(struct pt_regs *regs); extern void show_regs(struct pt_regs *regs); +extern void dump_pagetable(unsigned long); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 2af9ec025015..97153027207a 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -534,7 +534,8 @@ extern void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string); extern void audit_log_d_path(struct audit_buffer *ab, const char *prefix, - struct path *path); + struct dentry *dentry, + struct vfsmount *vfsmnt); extern void audit_log_lost(const char *message); /* Private API (for audit.c only) */ extern int audit_filter_user(struct netlink_skb_parms *cb, int type); @@ -551,7 +552,7 @@ extern int audit_enabled; #define audit_log_hex(a,b,l) do { ; } while (0) #define audit_log_untrustedstring(a,s) do { ; } while (0) #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) -#define audit_log_d_path(b, p, d) do { ; } while (0) +#define audit_log_d_path(b,p,d,v) do { ; } while (0) #define audit_enabled 0 #endif #endif diff --git a/trunk/include/linux/configfs.h b/trunk/include/linux/configfs.h index 4b287ad9371a..8c6967f3fb11 100644 --- a/trunk/include/linux/configfs.h +++ b/trunk/include/linux/configfs.h @@ -37,7 +37,6 @@ #ifdef __KERNEL__ -#include #include #include #include diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 6bd646096fa6..c2c153f97e8f 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -10,7 +10,6 @@ #include struct nameidata; -struct path; struct vfsmount; /* @@ -301,8 +300,8 @@ extern int d_validate(struct dentry *, struct dentry *); */ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *d_path(struct path *, char *, int); - +extern char * d_path(struct dentry *, struct vfsmount *, char *, int); + /* Allocation counts.. */ /** diff --git a/trunk/include/linux/dcookies.h b/trunk/include/linux/dcookies.h index 24c806f12a6c..98c69ab80c84 100644 --- a/trunk/include/linux/dcookies.h +++ b/trunk/include/linux/dcookies.h @@ -13,7 +13,6 @@ #ifdef CONFIG_PROFILING #include -#include #include struct dcookie_user; @@ -44,7 +43,8 @@ void dcookie_unregister(struct dcookie_user * user); * * Returns 0 on success, with *cookie filled in */ -int get_dcookie(struct path *path, unsigned long *cookie); +int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt, + unsigned long * cookie); #else @@ -57,12 +57,13 @@ static inline void dcookie_unregister(struct dcookie_user * user) { return; } - -static inline int get_dcookie(struct path *path, unsigned long *cookie) + +static inline int get_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt, unsigned long * cookie) { return -ENOSYS; -} - +} + #endif /* CONFIG_PROFILING */ - + #endif /* DCOOKIES_H */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 98ffb6ead434..18cfbf76ec5b 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1284,10 +1284,8 @@ struct super_operations { * * I_DIRTY_SYNC Inode is dirty, but doesn't have to be written on * fdatasync(). i_atime is the usual cause. - * I_DIRTY_DATASYNC Data-related inode changes pending. We keep track of - * these changes separately from I_DIRTY_SYNC so that we - * don't have to write inode on fdatasync() when only - * mtime has changed in it. + * I_DIRTY_DATASYNC Inode is dirty and must be written on fdatasync(), f.e. + * because i_size changed. * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both * are cleared by unlock_new_inode(), called from iget(). diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h index 282f54219129..11a36ceddf73 100644 --- a/trunk/include/linux/fs_struct.h +++ b/trunk/include/linux/fs_struct.h @@ -1,13 +1,15 @@ #ifndef _LINUX_FS_STRUCT_H #define _LINUX_FS_STRUCT_H -#include +struct dentry; +struct vfsmount; struct fs_struct { atomic_t count; rwlock_t lock; int umask; - struct path root, pwd, altroot; + struct dentry * root, * pwd, * altroot; + struct vfsmount * rootmnt, * pwdmnt, * altrootmnt; }; #define INIT_FS { \ @@ -20,8 +22,8 @@ extern struct kmem_cache *fs_cachep; extern void exit_fs(struct task_struct *); extern void set_fs_altroot(void); -extern void set_fs_root(struct fs_struct *, struct path *); -extern void set_fs_pwd(struct fs_struct *, struct path *); +extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *); +extern void set_fs_pwd(struct fs_struct *, struct vfsmount *, struct dentry *); extern struct fs_struct *copy_fs_struct(struct fs_struct *); extern void put_fs_struct(struct fs_struct *); diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 819c4e889bf1..330bec08c2c4 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -567,7 +567,8 @@ static inline void print_modules(void) { } -static inline void module_update_markers(void) +static inline void module_update_markers(struct module *probe_module, + int *refcount) { } diff --git a/trunk/include/linux/namei.h b/trunk/include/linux/namei.h index 24d88e98a626..c13e411491f4 100644 --- a/trunk/include/linux/namei.h +++ b/trunk/include/linux/namei.h @@ -3,7 +3,6 @@ #include #include -#include struct vfsmount; @@ -16,7 +15,8 @@ struct open_intent { enum { MAX_NESTED_LINKS = 8 }; struct nameidata { - struct path path; + struct dentry *dentry; + struct vfsmount *mnt; struct qstr last; unsigned int flags; int last_type; @@ -29,6 +29,11 @@ struct nameidata { } intent; }; +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + /* * Type of the last component on LOOKUP_PARENT */ @@ -66,6 +71,8 @@ extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameida extern int path_lookup(const char *, unsigned, struct nameidata *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct nameidata *); +extern void path_release(struct nameidata *); +extern void path_release_on_umount(struct nameidata *); extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags); extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); diff --git a/trunk/include/linux/nfsd/export.h b/trunk/include/linux/nfsd/export.h index 5431512b2757..3a1687251367 100644 --- a/trunk/include/linux/nfsd/export.h +++ b/trunk/include/linux/nfsd/export.h @@ -84,8 +84,9 @@ struct svc_export { struct cache_head h; struct auth_domain * ex_client; int ex_flags; - struct path ex_path; - char *ex_pathname; + struct vfsmount * ex_mnt; + struct dentry * ex_dentry; + char * ex_path; uid_t ex_anon_uid; gid_t ex_anon_gid; int ex_fsid; @@ -106,7 +107,8 @@ struct svc_expkey { int ek_fsidtype; u32 ek_fsid[6]; - struct path ek_path; + struct vfsmount * ek_mnt; + struct dentry * ek_dentry; }; #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) diff --git a/trunk/include/linux/path.h b/trunk/include/linux/path.h deleted file mode 100644 index 915e0c382a51..000000000000 --- a/trunk/include/linux/path.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _LINUX_PATH_H -#define _LINUX_PATH_H - -struct dentry; -struct vfsmount; - -struct path { - struct vfsmount *mnt; - struct dentry *dentry; -}; - -extern void path_get(struct path *); -extern void path_put(struct path *); - -#endif /* _LINUX_PATH_H */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index d9a9e718ad19..d6a4f69bdc92 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -269,7 +269,7 @@ extern void kclist_add(struct kcore_list *, void *, size_t); #endif union proc_op { - int (*proc_get_link)(struct inode *, struct path *); + int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); int (*proc_read)(struct task_struct *task, char *page); int (*proc_show)(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, diff --git a/trunk/include/linux/seq_file.h b/trunk/include/linux/seq_file.h index 67c2563961f3..648dfeb444db 100644 --- a/trunk/include/linux/seq_file.h +++ b/trunk/include/linux/seq_file.h @@ -8,7 +8,8 @@ struct seq_operations; struct file; -struct path; +struct vfsmount; +struct dentry; struct inode; struct seq_file { @@ -41,7 +42,7 @@ int seq_puts(struct seq_file *m, const char *s); int seq_printf(struct seq_file *, const char *, ...) __attribute__ ((format (printf,2,3))); -int seq_path(struct seq_file *, struct path *, char *); +int seq_path(struct seq_file *, struct vfsmount *, struct dentry *, char *); int single_open(struct file *, int (*)(struct seq_file *, void *), void *); int single_release(struct inode *, struct file *); diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 3885e70e7759..f86573126f83 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -193,10 +193,10 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) return err; sys_chdir("/root"); - ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev; + ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; printk("VFS: Mounted root (%s filesystem)%s.\n", - current->fs->pwd.mnt->mnt_sb->s_type->name, - current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ? + current->fs->pwdmnt->mnt_sb->s_type->name, + current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? " readonly" : ""); return 0; } diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 2eeea9a14240..c8555b180213 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -1312,26 +1312,26 @@ void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) /* This is a helper-function to print the escaped d_path */ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, - struct path *path) + struct dentry *dentry, struct vfsmount *vfsmnt) { - char *p, *pathname; + char *p, *path; if (prefix) audit_log_format(ab, " %s", prefix); /* We will allow 11 spaces for ' (deleted)' to be appended */ - pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); - if (!pathname) { + path = kmalloc(PATH_MAX+11, ab->gfp_mask); + if (!path) { audit_log_format(ab, ""); return; } - p = d_path(path, pathname, PATH_MAX+11); + p = d_path(dentry, vfsmnt, path, PATH_MAX+11); if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ /* FIXME: can we save some information here? */ audit_log_format(ab, ""); } else audit_log_untrustedstring(ab, p); - kfree(pathname); + kfree(path); } /** diff --git a/trunk/kernel/audit_tree.c b/trunk/kernel/audit_tree.c index 9ef5e0aacc3c..f4fcf58f20f8 100644 --- a/trunk/kernel/audit_tree.c +++ b/trunk/kernel/audit_tree.c @@ -549,8 +549,8 @@ void audit_trim_trees(void) if (err) goto skip_it; - root_mnt = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + root_mnt = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!root_mnt) goto skip_it; @@ -583,17 +583,17 @@ void audit_trim_trees(void) static int is_under(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { - if (mnt != nd->path.mnt) { + if (mnt != nd->mnt) { for (;;) { if (mnt->mnt_parent == mnt) return 0; - if (mnt->mnt_parent == nd->path.mnt) + if (mnt->mnt_parent == nd->mnt) break; mnt = mnt->mnt_parent; } dentry = mnt->mnt_mountpoint; } - return is_subdir(dentry, nd->path.dentry); + return is_subdir(dentry, nd->dentry); } int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op) @@ -641,8 +641,8 @@ int audit_add_tree_rule(struct audit_krule *rule) err = path_lookup(tree->pathname, 0, &nd); if (err) goto Err; - mnt = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + mnt = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!mnt) { err = -ENOMEM; goto Err; @@ -701,8 +701,8 @@ int audit_tag_tree(char *old, char *new) err = path_lookup(new, 0, &nd); if (err) return err; - tagged = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + tagged = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!tagged) return -ENOMEM; @@ -711,9 +711,9 @@ int audit_tag_tree(char *old, char *new) drop_collected_mounts(tagged); return err; } - mnt = mntget(nd.path.mnt); - dentry = dget(nd.path.dentry); - path_put(&nd.path); + mnt = mntget(nd.mnt); + dentry = dget(nd.dentry); + path_release(&nd); if (dentry == tagged->mnt_root && dentry == mnt->mnt_root) follow_up(&mnt, &dentry); @@ -744,13 +744,13 @@ int audit_tag_tree(char *old, char *new) spin_lock(&vfsmount_lock); if (!is_under(mnt, dentry, &nd)) { spin_unlock(&vfsmount_lock); - path_put(&nd.path); + path_release(&nd); put_tree(tree); mutex_lock(&audit_filter_mutex); continue; } spin_unlock(&vfsmount_lock); - path_put(&nd.path); + path_release(&nd); list_for_each_entry(p, &list, mnt_list) { failed = tag_chunk(p->mnt_root->d_inode, tree); diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 2f2914b7cc30..6f19fd477aac 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -169,8 +169,8 @@ static struct audit_parent *audit_init_parent(struct nameidata *ndp) inotify_init_watch(&parent->wdata); /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ get_inotify_watch(&parent->wdata); - wd = inotify_add_watch(audit_ih, &parent->wdata, - ndp->path.dentry->d_inode, AUDIT_IN_WATCH); + wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode, + AUDIT_IN_WATCH); if (wd < 0) { audit_free_parent(&parent->wdata); return ERR_PTR(wd); @@ -1161,11 +1161,11 @@ static int audit_get_nd(char *path, struct nameidata **ndp, static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) { if (ndp) { - path_put(&ndp->path); + path_release(ndp); kfree(ndp); } if (ndw) { - path_put(&ndw->path); + path_release(ndw); kfree(ndw); } } @@ -1214,8 +1214,8 @@ static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, /* update watch filter fields */ if (ndw) { - watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; - watch->ino = ndw->path.dentry->d_inode->i_ino; + watch->dev = ndw->dentry->d_inode->i_sb->s_dev; + watch->ino = ndw->dentry->d_inode->i_ino; } /* The audit_filter_mutex must not be held during inotify calls because @@ -1225,8 +1225,7 @@ static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, */ mutex_unlock(&audit_filter_mutex); - if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, - &i_watch) < 0) { + if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) { parent = audit_init_parent(ndp); if (IS_ERR(parent)) { /* caller expects mutex locked */ diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index ac6d9b23b018..1c06ecf38d7b 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -208,7 +208,8 @@ struct audit_context { int name_count; struct audit_names names[AUDIT_NAMES]; char * filterkey; /* key for rule that triggered record */ - struct path pwd; + struct dentry * pwd; + struct vfsmount * pwdmnt; struct audit_context *previous; /* For nested syscalls */ struct audit_aux_data *aux; struct audit_aux_data *aux_pids; @@ -785,9 +786,12 @@ static inline void audit_free_names(struct audit_context *context) __putname(context->names[i].name); } context->name_count = 0; - path_put(&context->pwd); - context->pwd.dentry = NULL; - context->pwd.mnt = NULL; + if (context->pwd) + dput(context->pwd); + if (context->pwdmnt) + mntput(context->pwdmnt); + context->pwd = NULL; + context->pwdmnt = NULL; } static inline void audit_free_aux(struct audit_context *context) @@ -926,7 +930,8 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { audit_log_d_path(ab, "exe=", - &vma->vm_file->f_path); + vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); break; } vma = vma->vm_next; @@ -1336,10 +1341,10 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts context->target_sid, context->target_comm)) call_panic = 1; - if (context->pwd.dentry && context->pwd.mnt) { + if (context->pwd && context->pwdmnt) { ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); if (ab) { - audit_log_d_path(ab, "cwd=", &context->pwd); + audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); audit_log_end(ab); } } @@ -1362,7 +1367,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts case 0: /* name was specified as a relative path and the * directory component is the cwd */ - audit_log_d_path(ab, " name=", &context->pwd); + audit_log_d_path(ab, " name=", context->pwd, + context->pwdmnt); break; default: /* log the name's directory component */ @@ -1689,10 +1695,10 @@ void __audit_getname(const char *name) context->names[context->name_count].ino = (unsigned long)-1; context->names[context->name_count].osid = 0; ++context->name_count; - if (!context->pwd.dentry) { + if (!context->pwd) { read_lock(¤t->fs->lock); - context->pwd = current->fs->pwd; - path_get(¤t->fs->pwd); + context->pwd = dget(current->fs->pwd); + context->pwdmnt = mntget(current->fs->pwdmnt); read_unlock(¤t->fs->lock); } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 506a957b665a..3b893e78ce61 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -512,10 +512,14 @@ static void __put_fs_struct(struct fs_struct *fs) { /* No need to hold fs->lock if we are killing it */ if (atomic_dec_and_test(&fs->count)) { - path_put(&fs->root); - path_put(&fs->pwd); - if (fs->altroot.dentry) - path_put(&fs->altroot); + dput(fs->root); + mntput(fs->rootmnt); + dput(fs->pwd); + mntput(fs->pwdmnt); + if (fs->altroot) { + dput(fs->altroot); + mntput(fs->altrootmnt); + } kmem_cache_free(fs_cachep, fs); } } diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index dd249c37b3a3..4363a4eb84e3 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -600,16 +600,16 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old) rwlock_init(&fs->lock); fs->umask = old->umask; read_lock(&old->lock); - fs->root = old->root; - path_get(&old->root); - fs->pwd = old->pwd; - path_get(&old->pwd); - if (old->altroot.dentry) { - fs->altroot = old->altroot; - path_get(&old->altroot); + fs->rootmnt = mntget(old->rootmnt); + fs->root = dget(old->root); + fs->pwdmnt = mntget(old->pwdmnt); + fs->pwd = dget(old->pwd); + if (old->altroot) { + fs->altrootmnt = mntget(old->altrootmnt); + fs->altroot = dget(old->altroot); } else { - fs->altroot.mnt = NULL; - fs->altroot.dentry = NULL; + fs->altrootmnt = NULL; + fs->altroot = NULL; } read_unlock(&old->lock); } diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 22be3ff3f363..bb7df2a28bd7 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -173,7 +173,10 @@ static int ____call_usermodehelper(void *data) */ set_user_nice(current, 0); - retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); + retval = -EPERM; + if (current->fs->root) + retval = kernel_execve(sub_info->path, + sub_info->argv, sub_info->envp); /* Exec failed? */ sub_info->retval = retval; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index ce3c9e4492d8..717aa0e3be2d 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -2711,13 +2711,6 @@ void print_vma_addr(char *prefix, unsigned long ip) struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - /* - * Do not print if we are in atomic - * contexts (in exception stacks, etc.): - */ - if (preempt_count()) - return; - down_read(&mm->mmap_sem); vma = find_vma(mm, ip); if (vma && vma->vm_file) { @@ -2726,7 +2719,7 @@ void print_vma_addr(char *prefix, unsigned long ip) if (buf) { char *p, *s; - p = d_path(&f->f_path, buf, PAGE_SIZE); + p = d_path(f->f_dentry, f->f_vfsmnt, buf, PAGE_SIZE); if (IS_ERR(p)) p = "?"; s = strrchr(p, '/'); diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 6c7ba1a63d23..8d246c3b340f 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -1996,7 +1996,7 @@ int show_numa_map(struct seq_file *m, void *v) if (file) { seq_printf(m, " file="); - seq_path(m, &file->f_path, "\n\t= "); + seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n\t= "); } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { seq_printf(m, " heap"); } else if (vma->vm_start <= mm->start_stack && diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 40c00dacbe4b..473e6c2eaefb 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -2630,6 +2630,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, slabp->colouroff = colour_off; slabp->s_mem = objp + colour_off; slabp->nodeid = nodeid; + slabp->free = 0; return slabp; } @@ -2683,7 +2684,6 @@ static void cache_init_objs(struct kmem_cache *cachep, slab_bufctl(slabp)[i] = i + 1; } slab_bufctl(slabp)[i - 1] = BUFCTL_END; - slabp->free = 0; } static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags) @@ -2816,7 +2816,6 @@ static int cache_grow(struct kmem_cache *cachep, if (!slabp) goto opps1; - slabp->nodeid = nodeid; slab_map_pages(cachep, slabp, objp); cache_init_objs(cachep, slabp); diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 2da149cfc9ac..02ccab5ad9d9 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1394,7 +1394,7 @@ static int swap_show(struct seq_file *swap, void *v) } file = ptr->swap_file; - len = seq_path(swap, &file->f_path, " \t\n\\"); + len = seq_path(swap, file->f_path.mnt, file->f_path.dentry, " \t\n\\"); seq_printf(swap, "%*s%s\t%u\t%u\t%d\n", len < 40 ? 40 - len : 1, " ", S_ISBLK(file->f_path.dentry->d_inode->i_mode) ? diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 1b395a41a8b2..0e3ead7e11b9 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -495,7 +495,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd) static void rpc_release_path(struct nameidata *nd) { - path_put(&nd->path); + path_release(nd); rpc_put_mount(); } @@ -668,8 +668,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) if ((error = rpc_lookup_parent(path, nd)) != 0) return ERR_PTR(error); - dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len, - 1); + dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1); if (IS_ERR(dentry)) rpc_release_path(nd); return dentry; @@ -696,7 +695,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) dentry = rpc_lookup_negative(path, &nd); if (IS_ERR(dentry)) return dentry; - dir = nd.path.dentry->d_inode; + dir = nd.dentry->d_inode; if ((error = __rpc_mkdir(dir, dentry)) != 0) goto err_dput; RPC_I(dentry->d_inode)->private = rpc_client; diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index b8788fd5e3c6..eea75888805e 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -718,16 +718,16 @@ static struct sock *unix_find_other(struct net *net, goto put_fail; err = -ECONNREFUSED; - if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode)) + if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) goto put_fail; - u = unix_find_socket_byinode(net, nd.path.dentry->d_inode); + u=unix_find_socket_byinode(net, nd.dentry->d_inode); if (!u) goto put_fail; if (u->sk_type == type) - touch_atime(nd.path.mnt, nd.path.dentry); + touch_atime(nd.mnt, nd.dentry); - path_put(&nd.path); + path_release(&nd); err=-EPROTOTYPE; if (u->sk_type != type) { @@ -748,7 +748,7 @@ static struct sock *unix_find_other(struct net *net, return u; put_fail: - path_put(&nd.path); + path_release(&nd); fail: *error=err; return NULL; @@ -819,12 +819,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) */ mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); if (err) goto out_mknod_dput; - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - dput(nd.path.dentry); - nd.path.dentry = dentry; + mutex_unlock(&nd.dentry->d_inode->i_mutex); + dput(nd.dentry); + nd.dentry = dentry; addr->hash = UNIX_HASH_SIZE; } @@ -842,8 +842,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) list = &unix_socket_table[addr->hash]; } else { list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; - u->dentry = nd.path.dentry; - u->mnt = nd.path.mnt; + u->dentry = nd.dentry; + u->mnt = nd.mnt; } err = 0; @@ -861,8 +861,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out_mknod_dput: dput(dentry); out_mknod_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out_mknod_parent: if (err==-EEXIST) err=-EADDRINUSE; diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index 26146cbaa504..6c18a14386a4 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1624,6 +1624,7 @@ sub dump_function($$) { $prototype =~ s/^static +//; $prototype =~ s/^extern +//; + $prototype =~ s/^fastcall +//; $prototype =~ s/^asmlinkage +//; $prototype =~ s/^inline +//; $prototype =~ s/^__inline__ +//; diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 187964e88af1..e8529e2f51e5 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -568,11 +568,10 @@ void avc_audit(u32 ssid, u32 tsid, audit_log_format(ab, " capability=%d", a->u.cap); break; case AVC_AUDIT_DATA_FS: - if (a->u.fs.path.dentry) { - struct dentry *dentry = a->u.fs.path.dentry; - if (a->u.fs.path.mnt) { - audit_log_d_path(ab, "path=", - &a->u.fs.path); + if (a->u.fs.dentry) { + struct dentry *dentry = a->u.fs.dentry; + if (a->u.fs.mnt) { + audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt); } else { audit_log_format(ab, " name="); audit_log_untrustedstring(ab, dentry->d_name.name); @@ -627,12 +626,8 @@ void avc_audit(u32 ssid, u32 tsid, case AF_UNIX: u = unix_sk(sk); if (u->dentry) { - struct path path = { - .dentry = u->dentry, - .mnt = u->mnt - }; audit_log_d_path(ab, "path=", - &path); + u->dentry, u->mnt); break; } if (!u->addr) diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 75c2e99bfb81..44f16d9041e3 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1356,8 +1356,8 @@ static inline int dentry_has_perm(struct task_struct *tsk, struct inode *inode = dentry->d_inode; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.mnt = mnt; - ad.u.fs.path.dentry = dentry; + ad.u.fs.mnt = mnt; + ad.u.fs.dentry = dentry; return inode_has_perm(tsk, inode, av, &ad); } @@ -1375,12 +1375,15 @@ static int file_has_perm(struct task_struct *tsk, { struct task_security_struct *tsec = tsk->security; struct file_security_struct *fsec = file->f_security; - struct inode *inode = file->f_path.dentry->d_inode; + struct vfsmount *mnt = file->f_path.mnt; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = dentry->d_inode; struct avc_audit_data ad; int rc; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = file->f_path; + ad.u.fs.mnt = mnt; + ad.u.fs.dentry = dentry; if (tsec->sid != fsec->sid) { rc = avc_has_perm(tsec->sid, fsec->sid, @@ -1415,7 +1418,7 @@ static int may_create(struct inode *dir, sbsec = dir->i_sb->s_security; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1473,7 +1476,7 @@ static int may_link(struct inode *dir, isec = dentry->d_inode->i_security; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1520,7 +1523,7 @@ static inline int may_rename(struct inode *old_dir, AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = old_dentry; + ad.u.fs.dentry = old_dentry; rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR, DIR__REMOVE_NAME | DIR__SEARCH, &ad); if (rc) @@ -1536,7 +1539,7 @@ static inline int may_rename(struct inode *old_dir, return rc; } - ad.u.fs.path.dentry = new_dentry; + ad.u.fs.dentry = new_dentry; av = DIR__ADD_NAME | DIR__SEARCH; if (new_dentry->d_inode) av |= DIR__REMOVE_NAME; @@ -1915,7 +1918,8 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) } AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = bprm->file->f_path; + ad.u.fs.mnt = bprm->file->f_path.mnt; + ad.u.fs.dentry = bprm->file->f_path.dentry; if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) newsid = tsec->sid; @@ -2311,7 +2315,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) return rc; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = sb->s_root; + ad.u.fs.dentry = sb->s_root; return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); } @@ -2320,7 +2324,7 @@ static int selinux_sb_statfs(struct dentry *dentry) struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = dentry->d_sb->s_root; + ad.u.fs.dentry = dentry->d_sb->s_root; return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2337,10 +2341,10 @@ static int selinux_mount(char * dev_name, return rc; if (flags & MS_REMOUNT) - return superblock_has_perm(current, nd->path.mnt->mnt_sb, + return superblock_has_perm(current, nd->mnt->mnt_sb, FILESYSTEM__REMOUNT, NULL); else - return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, + return dentry_has_perm(current, nd->mnt, nd->dentry, FILE__MOUNTON); } @@ -2583,7 +2587,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value return -EPERM; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, FILE__RELABELFROM, &ad); diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index 8e23d7a873a4..80c28fa6621c 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "flask.h" #include "av_permissions.h" @@ -31,6 +30,8 @@ extern int selinux_enforcing; struct avc_entry; struct task_struct; +struct vfsmount; +struct dentry; struct inode; struct sock; struct sk_buff; @@ -45,7 +46,8 @@ struct avc_audit_data { struct task_struct *tsk; union { struct { - struct path path; + struct vfsmount *mnt; + struct dentry *dentry; struct inode *inode; } fs; struct { diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 2b5d6f72f678..5b690482f8cb 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -325,7 +325,7 @@ static int smack_sb_statfs(struct dentry *dentry) static int smack_sb_mount(char *dev_name, struct nameidata *nd, char *type, unsigned long flags, void *data) { - struct superblock_smack *sbp = nd->path.mnt->mnt_sb->s_security; + struct superblock_smack *sbp = nd->mnt->mnt_sb->s_security; return smk_curacc(sbp->smk_floor, MAY_WRITE); } diff --git a/trunk/sound/core/seq/seq_clientmgr.c b/trunk/sound/core/seq/seq_clientmgr.c index 47cfa5186e34..f97c1ba43a28 100644 --- a/trunk/sound/core/seq/seq_clientmgr.c +++ b/trunk/sound/core/seq/seq_clientmgr.c @@ -149,13 +149,13 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid) } spin_unlock_irqrestore(&clients_lock, flags); #ifdef CONFIG_KMOD - if (!in_interrupt()) { + if (!in_interrupt() && current->fs->root) { static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS]; static char card_requested[SNDRV_CARDS]; if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) { int idx; - if (!client_requested[clientid]) { + if (! client_requested[clientid] && current->fs->root) { client_requested[clientid] = 1; for (idx = 0; idx < 15; idx++) { if (seq_client_load[idx] < 0) diff --git a/trunk/sound/core/seq/seq_device.c b/trunk/sound/core/seq/seq_device.c index 2f00ad28a2b7..155dc7da4722 100644 --- a/trunk/sound/core/seq/seq_device.c +++ b/trunk/sound/core/seq/seq_device.c @@ -149,6 +149,9 @@ void snd_seq_device_load_drivers(void) if (snd_seq_in_init) return; + if (! current->fs->root) + return; + mutex_lock(&ops_mutex); list_for_each_entry(ops, &opslist, list) { if (! (ops->driver & DRIVER_LOADED) && diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 812f91b3de5b..00cca4d6e562 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -71,6 +71,8 @@ static DEFINE_MUTEX(sound_mutex); */ void snd_request_card(int card) { + if (! current->fs->root) + return; if (snd_card_locked(card)) return; if (card < 0 || card >= cards_limit) @@ -84,6 +86,8 @@ static void snd_request_other(int minor) { char *str; + if (! current->fs->root) + return; switch (minor) { case SNDRV_MINOR_SEQUENCER: str = "snd-seq"; break; case SNDRV_MINOR_TIMER: str = "snd-timer"; break; diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index 9d8184a2c2d0..aece465934b8 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -150,6 +150,8 @@ static struct snd_timer *snd_timer_find(struct snd_timer_id *tid) static void snd_timer_request(struct snd_timer_id *tid) { + if (! current->fs->root) + return; switch (tid->dev_class) { case SNDRV_TIMER_CLASS_GLOBAL: if (tid->device < timer_limit) diff --git a/trunk/sound/ppc/daca.c b/trunk/sound/ppc/daca.c index ca9452901a50..8432c16cd6ff 100644 --- a/trunk/sound/ppc/daca.c +++ b/trunk/sound/ppc/daca.c @@ -250,8 +250,9 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip) struct pmac_daca *mix; #ifdef CONFIG_KMOD - request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ + if (current->fs->root) + request_module("i2c-powermac"); +#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix) diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 3f8d7164cef9..71a7a9765429 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -1351,8 +1351,9 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) char *chipname; #ifdef CONFIG_KMOD - request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ + if (current->fs->root) + request_module("i2c-powermac"); +#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix)