Commit b446946d authored by Jeff Garzik's avatar Jeff Garzik

Merge mandrakesoft.com:/home/jgarzik/vanilla/linus-2.5

into mandrakesoft.com:/home/jgarzik/repo/net-drivers-2.5
parents feeb46df fa44005c
...@@ -146,3 +146,9 @@ support for this helper, particularly get_parent. ...@@ -146,3 +146,9 @@ support for this helper, particularly get_parent.
It is planned that this will be required for exporting once the code It is planned that this will be required for exporting once the code
settles down a bit. settles down a bit.
[mandatory]
s_export_op is now required for exporting a filesystem.
isofs, ext2, ext3, resierfs, fat
can be used as examples of very different filesystems.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
OUTPUT_FORMAT("elf64-alpha") OUTPUT_FORMAT("elf64-alpha")
ENTRY(__start) ENTRY(__start)
PHDRS { kernel PT_LOAD ; } PHDRS { kernel PT_LOAD ; }
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
OUTPUT_ARCH(arm) OUTPUT_ARCH(arm)
ENTRY(stext) ENTRY(stext)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = TEXTADDR; . = TEXTADDR;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
OUTPUT_ARCH(arm) OUTPUT_ARCH(arm)
ENTRY(stext) ENTRY(stext)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = TEXTADDR; . = TEXTADDR;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* the kernel has booted. * the kernel has booted.
*/ */
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
. = @CONFIG_ETRAX_DRAM_VIRTUAL_BASE@; . = @CONFIG_ETRAX_DRAM_VIRTUAL_BASE@;
......
...@@ -24,6 +24,4 @@ endif # CONFIG_MULTIQUAD ...@@ -24,6 +24,4 @@ endif # CONFIG_MULTIQUAD
obj-y += irq.o common.o obj-y += irq.o common.o
endif # CONFIG_VISWS endif # CONFIG_VISWS
export-objs += $(obj-y)
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386) OUTPUT_ARCH(i386)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
. = 0xC0000000 + 0x100000; . = 0xC0000000 + 0x100000;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_FORMAT("elf64-ia64-little")
OUTPUT_ARCH(ia64) OUTPUT_ARCH(ia64)
ENTRY(phys_start) ENTRY(phys_start)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
/* Sections to be discarded */ /* Sections to be discarded */
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k) OUTPUT_ARCH(m68k)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = 0xE004000; . = 0xE004000;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k) OUTPUT_ARCH(m68k)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = 0x1000; . = 0x1000;
......
OUTPUT_ARCH(mips) OUTPUT_ARCH(mips)
ENTRY(kernel_entry) ENTRY(kernel_entry)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
/* Read-only sections, merged into text segment: */ /* Read-only sections, merged into text segment: */
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
OUTPUT_FORMAT("elf32-hppa") OUTPUT_FORMAT("elf32-hppa")
OUTPUT_ARCH(hppa) OUTPUT_ARCH(hppa)
ENTRY(_stext) ENTRY(_stext)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
......
...@@ -2,6 +2,7 @@ OUTPUT_ARCH(powerpc) ...@@ -2,6 +2,7 @@ OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf? /* Do we need any of these for elf?
__DYNAMIC = 0; */ __DYNAMIC = 0; */
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
/* Read-only sections, merged into text segment: */ /* Read-only sections, merged into text segment: */
......
...@@ -2,6 +2,7 @@ OUTPUT_ARCH(powerpc) ...@@ -2,6 +2,7 @@ OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf? /* Do we need any of these for elf?
__DYNAMIC = 0; */ __DYNAMIC = 0; */
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
/* Read-only sections, merged into text segment: */ /* Read-only sections, merged into text segment: */
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390) OUTPUT_ARCH(s390)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = 0x00000000; . = 0x00000000;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390) OUTPUT_ARCH(s390)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = 0x00000000; . = 0x00000000;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390) OUTPUT_ARCH(s390)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
. = 0x00000000; . = 0x00000000;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390) OUTPUT_ARCH(s390)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
. = 0x00000000; . = 0x00000000;
......
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
#include <linux/config.h> #include <linux/config.h>
#ifdef CONFIG_CPU_LITTLE_ENDIAN #ifdef CONFIG_CPU_LITTLE_ENDIAN
OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
jiffies = jiffies_64;
#else #else
OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
jiffies = jiffies_64 + 4;
#endif #endif
OUTPUT_ARCH(sh) OUTPUT_ARCH(sh)
ENTRY(_start) ENTRY(_start)
......
...@@ -234,29 +234,13 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, ...@@ -234,29 +234,13 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
#ifdef DEBUG_PTRACE #ifdef DEBUG_PTRACE
char *pt_rq [] = { char *pt_rq [] = {
"TRACEME", /* 0 */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
"PEEKTEXT", /* 4 */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
"PEEKDATA", /* 8 */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
"PEEKUSR", /* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
"POKETEXT", /* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
"POKEDATA", /* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
"POKEUSR", /* 24 */ "SYSCALL", ""
"CONT",
"KILL",
"SINGLESTEP",
"SUNATTACH",
"SUNDETACH",
"GETREGS",
"SETREGS",
"GETFPREGS",
"SETFPREGS",
"READDATA",
"WRITEDATA",
"READTEXT",
"WRITETEXT",
"GETFPAREGS",
"SETFPAREGS",
""
}; };
#endif #endif
...@@ -285,7 +269,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -285,7 +269,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
{ {
char *s; char *s;
if ((request > 0) && (request < 21)) if ((request >= 0) && (request <= 24))
s = pt_rq [request]; s = pt_rq [request];
else else
s = "unknown"; s = "unknown";
......
...@@ -1048,8 +1048,8 @@ static inline int check_nonblock(int ret, int fd) ...@@ -1048,8 +1048,8 @@ static inline int check_nonblock(int ret, int fd)
return ret; return ret;
} }
extern asmlinkage int sys_read(unsigned int fd,char *buf,int count); extern asmlinkage ssize_t sys_read(unsigned int fd,char *buf,int count);
extern asmlinkage int sys_write(unsigned int fd,char *buf,int count); extern asmlinkage ssize_t sys_write(unsigned int fd,char *buf,int count);
extern asmlinkage int sys_recv(int fd, void * ubuf, int size, unsigned flags); extern asmlinkage int sys_recv(int fd, void * ubuf, int size, unsigned flags);
extern asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags); extern asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags);
extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen); extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc") OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
OUTPUT_ARCH(sparc) OUTPUT_ARCH(sparc)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS SECTIONS
{ {
. = 0x10000 + SIZEOF_HEADERS; . = 0x10000 + SIZEOF_HEADERS;
......
...@@ -181,11 +181,11 @@ extern void rs_init(void); ...@@ -181,11 +181,11 @@ extern void rs_init(void);
extern void clock_probe(void); extern void clock_probe(void);
extern void power_init(void); extern void power_init(void);
static void __init pcibios_init(void) static int __init pcibios_init(void)
{ {
pci_controller_probe(); pci_controller_probe();
if (pci_controller_root == NULL) if (pci_controller_root == NULL)
return; return 0;
pci_scan_each_controller_bus(); pci_scan_each_controller_bus();
...@@ -197,6 +197,8 @@ static void __init pcibios_init(void) ...@@ -197,6 +197,8 @@ static void __init pcibios_init(void)
rs_init(); rs_init();
clock_probe(); clock_probe();
power_init(); power_init();
return 0;
} }
subsys_initcall(pcibios_init); subsys_initcall(pcibios_init);
......
...@@ -586,13 +586,6 @@ void fault_in_user_windows(void) ...@@ -586,13 +586,6 @@ void fault_in_user_windows(void)
* under SunOS are nothing short of bletcherous: * under SunOS are nothing short of bletcherous:
* Parent --> %o0 == childs pid, %o1 == 0 * Parent --> %o0 == childs pid, %o1 == 0
* Child --> %o0 == parents pid, %o1 == 1 * Child --> %o0 == parents pid, %o1 == 1
*
* NOTE: We have a separate fork kpsr/kwim because
* the parent could change these values between
* sys_fork invocation and when we reach here
* if the parent should sleep while trying to
* allocate the task_struct and kernel stack in
* do_fork().
*/ */
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long unused, unsigned long unused,
......
...@@ -78,29 +78,13 @@ pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr) ...@@ -78,29 +78,13 @@ pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr)
#ifdef DEBUG_PTRACE #ifdef DEBUG_PTRACE
char *pt_rq [] = { char *pt_rq [] = {
"TRACEME", /* 0 */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
"PEEKTEXT", /* 4 */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
"PEEKDATA", /* 8 */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
"PEEKUSR", /* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
"POKETEXT", /* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
"POKEDATA", /* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
"POKEUSR", /* 24 */ "SYSCALL", ""
"CONT",
"KILL",
"SINGLESTEP",
"SUNATTACH",
"SUNDETACH",
"GETREGS",
"SETREGS",
"GETFPREGS",
"SETFPREGS",
"READDATA",
"WRITEDATA",
"READTEXT",
"WRITETEXT",
"GETFPAREGS",
"SETFPAREGS",
""
}; };
#endif #endif
...@@ -134,7 +118,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -134,7 +118,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
{ {
char *s; char *s;
if ((request > 0) && (request < 21)) if ((request >= 0) && (request <= 24))
s = pt_rq [request]; s = pt_rq [request];
else else
s = "unknown"; s = "unknown";
......
...@@ -372,6 +372,10 @@ void VISenter(void); ...@@ -372,6 +372,10 @@ void VISenter(void);
/* RAID code needs this */ /* RAID code needs this */
EXPORT_SYMBOL_NOVERS(VISenter); EXPORT_SYMBOL_NOVERS(VISenter);
extern void batten_down_hatches(void);
/* for input/keybdev */
EXPORT_SYMBOL(batten_down_hatches);
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG); EXPORT_SYMBOL(do_BUG);
#endif #endif
...@@ -1198,8 +1198,8 @@ static inline int check_nonblock(int ret, int fd) ...@@ -1198,8 +1198,8 @@ static inline int check_nonblock(int ret, int fd)
return ret; return ret;
} }
extern asmlinkage int sys_read(unsigned int fd, char *buf, unsigned long count); extern asmlinkage ssize_t sys_read(unsigned int fd, char *buf, unsigned long count);
extern asmlinkage int sys_write(unsigned int fd, char *buf, unsigned long count); extern asmlinkage ssize_t sys_write(unsigned int fd, char *buf, unsigned long count);
extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags); extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags); extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen); extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen);
......
...@@ -3,6 +3,7 @@ OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc") ...@@ -3,6 +3,7 @@ OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc")
OUTPUT_ARCH(sparc:v9a) OUTPUT_ARCH(sparc:v9a)
ENTRY(_start) ENTRY(_start)
jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
swapper_pmd_dir = 0x0000000000402000; swapper_pmd_dir = 0x0000000000402000;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*/ */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64) OUTPUT_ARCH(i386:x86-64)
jiffies = jiffies_64;
ENTRY(_start) ENTRY(_start)
SECTIONS SECTIONS
{ {
......
...@@ -2,6 +2,6 @@ O_TARGET := base.o ...@@ -2,6 +2,6 @@ O_TARGET := base.o
obj-y := core.o sys.o interface.o fs.o power.o obj-y := core.o sys.o interface.o fs.o power.o
export-objs := $(obj-y) export-objs := core.o fs.o power.o sys.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
O_TARGET := driver.o O_TARGET := driver.o
export-objs := access.o hotplug.o pci-driver.o pci.o pool.o probe.o proc.o search.o
obj-y += access.o probe.o pci.o pool.o quirks.o \ obj-y += access.o probe.o pci.o pool.o quirks.o \
compat.o names.o pci-driver.o search.o compat.o names.o pci-driver.o search.o
obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PM) += power.o
...@@ -37,8 +39,6 @@ ifndef CONFIG_X86 ...@@ -37,8 +39,6 @@ ifndef CONFIG_X86
obj-y += syscall.o obj-y += syscall.o
endif endif
export-objs := $(obj-y)
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
names.o: names.c devlist.h classlist.h names.o: names.c devlist.h classlist.h
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/sched.h>
#include <asm/io.h> #include <asm/io.h>
......
...@@ -131,6 +131,21 @@ static struct super_operations isofs_sops = { ...@@ -131,6 +131,21 @@ static struct super_operations isofs_sops = {
statfs: isofs_statfs, statfs: isofs_statfs,
}; };
/* the export_operations structure for describing
* how to export (e.g. via kNFSd) is deliberately
* empty.
* This means that the filesystem want to use iget
* to map an inode number into an inode.
* The lack of a get_parent operation means that
* if something isn't in the cache, then you cannot
* access it.
* It should be possible to write a get_parent,
* but it would be a bit hairy...
*/
static struct export_operations isofs_export_ops = {
};
static struct dentry_operations isofs_dentry_ops[] = { static struct dentry_operations isofs_dentry_ops[] = {
{ {
d_hash: isofs_hash, d_hash: isofs_hash,
...@@ -786,6 +801,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -786,6 +801,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
} }
#endif #endif
s->s_op = &isofs_sops; s->s_op = &isofs_sops;
s->s_export_op = &isofs_export_ops;
sbi->s_mapping = opt.map; sbi->s_mapping = opt.map;
sbi->s_rock = (opt.rock == 'y' ? 2 : 0); sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
......
...@@ -1155,19 +1155,30 @@ int txCommit(tid_t tid, /* transaction identifier */ ...@@ -1155,19 +1155,30 @@ int txCommit(tid_t tid, /* transaction identifier */
jfs_ip = JFS_IP(ip); jfs_ip = JFS_IP(ip);
/* /*
* BUGBUG - Should we call filemap_fdatawrite here instead * BUGBUG - This code has temporarily been removed. The
* of fsync_inode_data? * intent is to ensure that any file data is written before
* If we do, we have a deadlock condition since we may end * the metadata is committed to the journal. This prevents
* up recursively calling jfs_get_block with the IWRITELOCK * uninitialized data from appearing in a file after the
* held. We may be able to do away with IWRITELOCK while * journal has been replayed. (The uninitialized data
* committing transactions and use i_sem instead. * could be sensitive data removed by another user.)
*
* The problem now is that we are holding the IWRITELOCK
* on the inode, and calling filemap_fdatawrite on an
* unmapped page will cause a deadlock in jfs_get_block.
*
* The long term solution is to pare down the use of
* IWRITELOCK. We are currently holding it too long.
* We could also be smarter about which data pages need
* to be written before the transaction is committed and
* when we don't need to worry about it at all.
*
* if ((!S_ISDIR(ip->i_mode))
* && (tblk->flag & COMMIT_DELETE) == 0) {
* filemap_fdatawait(ip->i_mapping);
* filemap_fdatawrite(ip->i_mapping);
* filemap_fdatawait(ip->i_mapping);
* }
*/ */
if ((!S_ISDIR(ip->i_mode))
&& (tblk->flag & COMMIT_DELETE) == 0) {
filemap_fdatawait(ip->i_mapping);
filemap_fdatawrite(ip->i_mapping);
filemap_fdatawait(ip->i_mapping);
}
/* /*
* Mark inode as not dirty. It will still be on the dirty * Mark inode as not dirty. It will still be on the dirty
......
...@@ -313,15 +313,12 @@ exp_export(struct nfsctl_export *nxp) ...@@ -313,15 +313,12 @@ exp_export(struct nfsctl_export *nxp)
* either a device number (so FS_REQUIRES_DEV needed) * either a device number (so FS_REQUIRES_DEV needed)
* or an FSID number (so NFSEXP_FSID needed). * or an FSID number (so NFSEXP_FSID needed).
* 2: We must be able to find an inode from a filehandle. * 2: We must be able to find an inode from a filehandle.
* either using fh_to_dentry (prefered) * This means that s_export_op must be set.
* or using read_inode (the hack).
*/ */
if (((inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) if (((inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)
|| (nxp->ex_flags & NFSEXP_FSID)) || (nxp->ex_flags & NFSEXP_FSID))
&& &&
(inode->i_sb->s_op->read_inode inode->i_sb->s_export_op)
|| inode->i_sb->s_export_op
|| inode->i_sb->s_op->fh_to_dentry))
/* Ok, we can export it */; /* Ok, we can export it */;
else { else {
dprintk("exp_export: export of invalid fs type.\n"); dprintk("exp_export: export of invalid fs type.\n");
......
...@@ -34,474 +34,6 @@ extern struct export_operations export_op_default; ...@@ -34,474 +34,6 @@ extern struct export_operations export_op_default;
#define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun) #define CALL(ops,fun) ((ops->fun)?(ops->fun):export_op_default.fun)
struct nfsd_getdents_callback {
char *name; /* name that was found. It already points to a buffer NAME_MAX+1 is size */
unsigned long ino; /* the inum we are looking for */
int found; /* inode matched? */
int sequence; /* sequence counter */
};
/*
* A rather strange filldir function to capture
* the name matching the specified inode number.
*/
static int filldir_one(void * __buf, const char * name, int len,
loff_t pos, ino_t ino, unsigned int d_type)
{
struct nfsd_getdents_callback *buf = __buf;
int result = 0;
buf->sequence++;
#ifdef NFSD_DEBUG_VERBOSE
dprintk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name);
#endif
if (buf->ino == ino) {
memcpy(buf->name, name, len);
buf->name[len] = '\0';
buf->found = 1;
result = -1;
}
return result;
}
static int nfsd_get_name(struct dentry *dentry, char *name,
struct dentry *child)
{
struct inode *dir = dentry->d_inode;
int error;
struct file file;
struct nfsd_getdents_callback buffer;
error = -ENOTDIR;
if (!dir || !S_ISDIR(dir->i_mode))
goto out;
error = -EINVAL;
if (!dir->i_fop)
goto out;
/*
* Open the directory ...
*/
error = init_private_file(&file, dentry, FMODE_READ);
if (error)
goto out;
error = -EINVAL;
if (!file.f_op->readdir)
goto out_close;
buffer.name = name;
buffer.ino = child->d_inode->i_ino;
buffer.found = 0;
buffer.sequence = 0;
while (1) {
int old_seq = buffer.sequence;
error = vfs_readdir(&file, filldir_one, &buffer);
if (error < 0)
break;
error = 0;
if (buffer.found)
break;
error = -ENOENT;
if (old_seq == buffer.sequence)
break;
}
out_close:
if (file.f_op->release)
file.f_op->release(dir, &file);
out:
return error;
}
static struct dentry *nfsd_iget(struct super_block *sb, unsigned long ino, __u32 generation)
{
/* iget isn't really right if the inode is currently unallocated!!
* This should really all be done inside each filesystem
*
* ext2fs' read_inode has been strengthed to return a bad_inode if the inode
* had been deleted.
*
* Currently we don't know the generation for parent directory, so a generation
* of 0 means "accept any"
*/
struct inode *inode;
struct dentry *result;
if (ino == 0)
return ERR_PTR(-ESTALE);
inode = iget(sb, ino);
if (inode == NULL)
return ERR_PTR(-ENOMEM);
if (is_bad_inode(inode)
|| (generation && inode->i_generation != generation)
) {
/* we didn't find the right inode.. */
dprintk("fh_verify: Inode %lu, Bad count: %d %d or version %u %u\n",
inode->i_ino,
inode->i_nlink, atomic_read(&inode->i_count),
inode->i_generation,
generation);
iput(inode);
return ERR_PTR(-ESTALE);
}
/* now to find a dentry.
* If possible, get a well-connected one
*/
result = d_alloc_anon(inode);
if (!result) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
result->d_vfs_flags |= DCACHE_REFERENCED;
return result;
}
static struct dentry *nfsd_get_dentry(struct super_block *sb, __u32 *fh,
int len, int fhtype, int parent)
{
if (sb->s_op->fh_to_dentry)
return sb->s_op->fh_to_dentry(sb, fh, len, fhtype, parent);
switch (fhtype) {
case 1:
if (len < 2)
break;
if (parent)
break;
return nfsd_iget(sb, fh[0], fh[1]);
case 2:
if (len < 3)
break;
if (parent)
return nfsd_iget(sb,fh[2],0);
return nfsd_iget(sb,fh[0],fh[1]);
default: break;
}
return ERR_PTR(-EINVAL);
}
/* this routine links an IS_ROOT dentry into the dcache tree. It gains "parent"
* as a parent and "name" as a name
* It should possibly go in dcache.c
*/
int d_splice(struct dentry *target, struct dentry *parent, struct qstr *name)
{
struct dentry *tdentry;
#ifdef NFSD_PARANOIA
if (!IS_ROOT(target))
printk("nfsd: d_splice with no-root target: %s/%s\n", parent->d_name.name, name->name);
if (!(target->d_flags & DCACHE_DISCONNECTED))
printk("nfsd: d_splice with non-DISCONNECTED target: %s/%s\n", parent->d_name.name, name->name);
#endif
tdentry = d_alloc(parent, name);
if (tdentry == NULL)
return -ENOMEM;
d_move(target, tdentry);
d_rehash(target);
dput(tdentry);
/* if parent is properly connected, then we can assert that
* the children are connected, but it must be a singluar (non-forking)
* branch
*/
if (!(parent->d_flags & DCACHE_DISCONNECTED)) {
while (target) {
target->d_flags &= ~DCACHE_DISCONNECTED;
parent = target;
spin_lock(&dcache_lock);
if (list_empty(&parent->d_subdirs))
target = NULL;
else {
target = list_entry(parent->d_subdirs.next, struct dentry, d_child);
#ifdef NFSD_PARANOIA
/* must be only child */
if (target->d_child.next != &parent->d_subdirs
|| target->d_child.prev != &parent->d_subdirs) {
printk("nfsd: d_splice found non-singular disconnected branch: %s/%s\n",
parent->d_name.name, target->d_name.name);
spin_unlock(&dcache_lock);
return 0;
}
#endif
}
spin_unlock(&dcache_lock);
}
}
return 0;
}
/* this routine finds the dentry of the parent of a given directory
* it assumes lookup("..") works.
*/
struct dentry *nfsd_findparent(struct dentry *child)
{
struct dentry *tdentry, *pdentry;
tdentry = d_alloc(child, &(const struct qstr) {"..", 2, 0});
if (!tdentry)
return ERR_PTR(-ENOMEM);
/* I'm going to assume that if the returned dentry is different, then
* it is well connected. But nobody returns different dentrys do they?
*/
down(&child->d_inode->i_sem);
pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
up(&child->d_inode->i_sem);
d_drop(tdentry); /* we never want ".." hashed */
if (!pdentry && tdentry->d_inode == NULL) {
/* File system cannot find ".." ... sad but possible */
pdentry = ERR_PTR(-EINVAL);
}
if (!pdentry) {
/* I don't want to return a ".." dentry.
* I would prefer to return an unconnected "IS_ROOT" dentry,
* though a properly connected dentry is even better
*/
/* if first or last of alias list is not tdentry, use that
* else make a root dentry
*/
struct list_head *aliases = &tdentry->d_inode->i_dentry;
spin_lock(&dcache_lock);
if (aliases->next != aliases) {
pdentry = list_entry(aliases->next, struct dentry, d_alias);
if (pdentry == tdentry)
pdentry = list_entry(aliases->prev, struct dentry, d_alias);
if (pdentry == tdentry)
pdentry = NULL;
if (pdentry) dget_locked(pdentry);
}
spin_unlock(&dcache_lock);
if (pdentry == NULL) {
pdentry = d_alloc_root(tdentry->d_inode);
if (pdentry) {
igrab(tdentry->d_inode);
pdentry->d_flags |= DCACHE_DISCONNECTED;
}
}
if (pdentry == NULL)
pdentry = ERR_PTR(-ENOMEM);
}
dput(tdentry); /* it is not hashed, it will be discarded */
return pdentry;
}
static struct dentry *splice(struct dentry *child, struct dentry *parent)
{
int err = 0, nerr;
struct qstr qs;
char namebuf[256];
struct list_head *lp;
/* child is an IS_ROOT (anonymous) dentry, but it is hypothesised that
* it should be a child of parent.
* We see if we can find a name and, if we can - splice it in.
* We lookup the name before locking (i_sem) the directory as namelookup
* also claims i_sem. If the name gets changed then we will loop around
* and try again in find_fh_dentry.
*/
nerr = nfsd_get_name(parent, namebuf, child);
/*
* We now claim the parent i_sem so that no-one else tries to create
* a dentry in the parent while we are.
*/
down(&parent->d_inode->i_sem);
/* Now, things might have changed while we waited.
* Possibly a friendly filesystem found child and spliced it in in response
* to a lookup (though nobody does this yet). In this case, just succeed.
*/
if (child->d_parent == parent) goto out;
/* Possibly a new dentry has been made for this child->d_inode in
* parent by a lookup. In this case return that dentry. Caller must
* notice and act accordingly
*/
spin_lock(&dcache_lock);
list_for_each(lp, &child->d_inode->i_dentry) {
struct dentry *tmp = list_entry(lp,struct dentry, d_alias);
if (!list_empty(&tmp->d_hash) &&
tmp->d_parent == parent) {
child = dget_locked(tmp);
spin_unlock(&dcache_lock);
goto out;
}
}
spin_unlock(&dcache_lock);
/* now we need that name. If there was an error getting it, now is th
* time to bail out.
*/
if ((err = nerr))
goto out;
qs.name = namebuf;
qs.len = strlen(namebuf);
if (find_inode_number(parent, &qs) != 0) {
/* Now that IS odd. I wonder what it means... */
err = -EEXIST;
printk("nfsd-fh: found a name that I didn't expect: %s/%s\n", parent->d_name.name, qs.name);
goto out;
}
err = d_splice(child, parent, &qs);
dprintk("nfsd_fh: found name %s for ino %ld\n", child->d_name.name, child->d_inode->i_ino);
out:
up(&parent->d_inode->i_sem);
if (err)
return ERR_PTR(err);
else
return child;
}
/*
* This is the basic lookup mechanism for turning an NFS file handle
* into a dentry.
* We use nfsd_iget and if that doesn't return a suitably connected dentry,
* we try to find the parent, and the parent of that and so-on until a
* connection if made.
*/
static struct dentry *
find_fh_dentry(struct super_block *sb, __u32 *datap, int len, int fhtype, int needpath)
{
struct dentry *dentry, *result = NULL;
struct dentry *tmp;
int err = -ESTALE;
/* the sb->s_nfsd_free_path_sem semaphore is needed to make sure that only one unconnected (free)
* dcache path ever exists, as otherwise two partial paths might get
* joined together, which would be very confusing.
* If there is ever an unconnected non-root directory, then this lock
* must be held.
*/
nfsdstats.fh_lookup++;
/*
* Attempt to find the inode.
*/
retry:
down(&sb->s_nfsd_free_path_sem);
result = nfsd_get_dentry(sb, datap, len, fhtype, 0);
if (IS_ERR(result)
|| !(result->d_flags & DCACHE_DISCONNECTED)
|| (!S_ISDIR(result->d_inode->i_mode) && ! needpath)) {
up(&sb->s_nfsd_free_path_sem);
err = PTR_ERR(result);
if (IS_ERR(result))
goto err_out;
if ((result->d_flags & DCACHE_DISCONNECTED))
nfsdstats.fh_anon++;
return result;
}
/* It's a directory, or we are required to confirm the file's
* location in the tree.
*/
dprintk("nfs_fh: need to look harder for %s/%d\n", sb->s_id, datap[0]);
lock_kernel();
if (!S_ISDIR(result->d_inode->i_mode)) {
nfsdstats.fh_nocache_nondir++;
/* need to iget dirino and make sure this inode is in that directory */
dentry = nfsd_get_dentry(sb, datap, len, fhtype, 1);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto err_result;
err = -ESTALE;
if (!dentry->d_inode
|| !S_ISDIR(dentry->d_inode->i_mode)) {
goto err_dentry;
}
tmp = splice(result, dentry);
err = PTR_ERR(tmp);
if (IS_ERR(tmp))
goto err_dentry;
if (tmp != result) {
/* it is safe to just use tmp instead, but we must discard result first */
d_drop(result);
dput(result);
result = tmp;
}
} else {
nfsdstats.fh_nocache_dir++;
dentry = dget(result);
}
while(dentry->d_flags & DCACHE_DISCONNECTED) {
/* LOOP INVARIANT */
/* haven't found a place in the tree yet, but we do have a free path
* from dentry down to result, and dentry is a directory.
* Have a hold on dentry and result */
struct dentry *pdentry;
struct inode *parent;
pdentry = nfsd_findparent(dentry);
err = PTR_ERR(pdentry);
if (IS_ERR(pdentry))
goto err_dentry;
parent = pdentry->d_inode;
err = -EACCES;
if (!parent) {
dput(pdentry);
goto err_dentry;
}
tmp = splice(dentry, pdentry);
if (tmp != dentry) {
/* Something wrong. We need to drop the whole dentry->result path
* whatever it was
*/
/*
* FIXME: the loop below will do Bad Things(tm) if
* dentry (or one of its ancestors) become attached
* to the tree (e.g. due to VFAT-style alias handling)
*/
struct dentry *d;
for (d=result ; d ; d=(d->d_parent == d)?NULL:d->d_parent)
d_drop(d);
}
if (IS_ERR(tmp)) {
err = PTR_ERR(tmp);
dput(pdentry);
goto err_dentry;
}
if (tmp != dentry) {
/* we lost a race, try again
*/
dput(pdentry);
dput(tmp);
dput(dentry);
dput(result); /* this will discard the whole free path, so we can up the semaphore */
up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
goto retry;
}
dput(dentry);
dentry = pdentry;
}
dput(dentry);
up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
return result;
err_dentry:
dput(dentry);
err_result:
dput(result);
up(&sb->s_nfsd_free_path_sem);
unlock_kernel();
err_out:
if (err == -ESTALE)
nfsdstats.fh_stale++;
return ERR_PTR(err);
}
/* /*
* our acceptability function. * our acceptability function.
* if NOSUBTREECHECK, accept anything * if NOSUBTREECHECK, accept anything
...@@ -660,15 +192,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -660,15 +192,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
dentry = dget(exp->ex_dentry); dentry = dget(exp->ex_dentry);
else { else {
struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
if (nop)
dentry = CALL(nop,decode_fh)(exp->ex_mnt->mnt_sb, dentry = CALL(nop,decode_fh)(exp->ex_mnt->mnt_sb,
datap, data_left, datap, data_left,
fileid_type, fileid_type,
nfsd_acceptable, exp); nfsd_acceptable, exp);
else
dentry = find_fh_dentry(exp->ex_dentry->d_sb,
datap, data_left, fileid_type,
!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
} }
if (dentry == NULL) if (dentry == NULL)
goto out; goto out;
...@@ -716,56 +243,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -716,56 +243,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
goto out; goto out;
} }
/*
* Security: Check that the export is valid for dentry <gam3@acm.org>
* This is only needed with subtree_check, and if export_operations is
* not being used - export_operations does the check via the "acceptable"
* callback
*/
error = 0;
if (exp->ex_mnt->mnt_sb->s_export_op == NULL &&
!(exp->ex_flags & NFSEXP_NOSUBTREECHECK)) {
if (exp->ex_dentry != dentry) {
struct dentry *tdentry = dentry;
spin_lock(&dcache_lock);
do {
tdentry = tdentry->d_parent;
if (exp->ex_dentry == tdentry)
break;
/* executable only by root and we can't be root */
/*
* FIXME: permissions check is not that simple
*/
if (current->fsuid
&& (exp->ex_flags & NFSEXP_ROOTSQUASH)
&& !(tdentry->d_inode->i_uid
&& (tdentry->d_inode->i_mode & S_IXUSR))
&& !(tdentry->d_inode->i_gid
&& (tdentry->d_inode->i_mode & S_IXGRP))
&& !(tdentry->d_inode->i_mode & S_IXOTH)
) {
error = nfserr_stale;
dprintk("fh_verify: no root_squashed access.\n");
}
} while ((tdentry != tdentry->d_parent));
if (exp->ex_dentry != tdentry) {
error = nfserr_stale;
printk("nfsd Security: %s/%s bad export.\n",
dentry->d_parent->d_name.name,
dentry->d_name.name);
spin_unlock(&dcache_lock);
goto out;
}
spin_unlock(&dcache_lock);
}
}
/* Finally, check access permissions. */ /* Finally, check access permissions. */
if (!error) { error = nfsd_permission(exp, dentry, access);
error = nfsd_permission(exp, dentry, access);
}
#ifdef NFSD_PARANOIA_EXTREME #ifdef NFSD_PARANOIA_EXTREME
if (error) { if (error) {
printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n", printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n",
...@@ -790,38 +270,14 @@ inline int _fh_update(struct dentry *dentry, struct svc_export *exp, ...@@ -790,38 +270,14 @@ inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
__u32 *datap, int *maxsize) __u32 *datap, int *maxsize)
{ {
struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
struct super_block *sb = dentry->d_sb;
if (dentry == exp->ex_dentry) { if (dentry == exp->ex_dentry) {
*maxsize = 0; *maxsize = 0;
return 0; return 0;
} }
if (nop) return CALL(nop,encode_fh)(dentry, datap, maxsize,
return CALL(nop,encode_fh)(dentry, datap, maxsize,
!(exp->ex_flags&NFSEXP_NOSUBTREECHECK)); !(exp->ex_flags&NFSEXP_NOSUBTREECHECK));
if (sb->s_op->dentry_to_fh) {
int need_parent = !S_ISDIR(dentry->d_inode->i_mode) &&
!(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
int type = sb->s_op->dentry_to_fh(dentry, datap, maxsize, need_parent);
return type;
}
if (*maxsize < 2)
return 255;
*datap++ = ino_t_to_u32(dentry->d_inode->i_ino);
*datap++ = dentry->d_inode->i_generation;
if (*maxsize ==2 ||
S_ISDIR(dentry->d_inode->i_mode) ||
(exp->ex_flags & NFSEXP_NOSUBTREECHECK)) {
*maxsize = 2;
return 1;
}
*datap++ = ino_t_to_u32(parent_ino(dentry));
*maxsize = 3;
return 2;
} }
/* /*
...@@ -845,7 +301,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -845,7 +301,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
* of the same version, where possible. * of the same version, where possible.
* Currently, that means that if ref_fh->fh_handle.fh_version == 0xca * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca
* Then create a 32byte filehandle using nfs_fhbase_old * Then create a 32byte filehandle using nfs_fhbase_old
* But only do this if dentry_to_fh is not available
* *
*/ */
...@@ -870,8 +325,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -870,8 +325,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
fhp->fh_export = exp; fhp->fh_export = exp;
if (ref_fh && if (ref_fh &&
ref_fh->fh_handle.fh_version == 0xca && ref_fh->fh_handle.fh_version == 0xca) {
dentry->d_sb->s_op->dentry_to_fh == NULL) {
/* old style filehandle please */ /* old style filehandle please */
memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
fhp->fh_handle.fh_size = NFS_FHSIZE; fhp->fh_handle.fh_size = NFS_FHSIZE;
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
# Makefile for native language support # Makefile for native language support
# #
O_TARGET = nls.o
export-objs := nls_base.o
obj-y := nls_base.o obj-y := nls_base.o
obj-m := obj-m :=
obj-n := obj-n :=
...@@ -53,8 +56,4 @@ obj-$(CONFIG_NLS_KOI8_U) += nls_koi8-u.o nls_koi8-ru.o ...@@ -53,8 +56,4 @@ obj-$(CONFIG_NLS_KOI8_U) += nls_koi8-u.o nls_koi8-ru.o
obj-$(CONFIG_NLS_ABC) += nls_abc.o obj-$(CONFIG_NLS_ABC) += nls_abc.o
obj-$(CONFIG_NLS_UTF8) += nls_utf8.o obj-$(CONFIG_NLS_UTF8) += nls_utf8.o
export-objs = $(obj-y)
O_TARGET = nls.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -1441,14 +1441,7 @@ struct super_operations ntfs_sops = { ...@@ -1441,14 +1441,7 @@ struct super_operations ntfs_sops = {
clear_inode: ntfs_clear_big_inode, /* VFS: Called when an inode is clear_inode: ntfs_clear_big_inode, /* VFS: Called when an inode is
removed from memory. */ removed from memory. */
umount_begin: NULL, /* Forced umount. */ umount_begin: NULL, /* Forced umount. */
/*
* These are NFSd support functions but NTFS is a standard fs so
* shouldn't need to implement these manually. At least we can try
* without and if it doesn't work in some way we can always implement
* something here.
*/
fh_to_dentry: NULL, /* Get dentry for given file handle. */
dentry_to_fh: NULL, /* Get file handle for given dentry. */
show_options: ntfs_show_options, /* Show mount options in proc. */ show_options: ntfs_show_options, /* Show mount options in proc. */
}; };
......
...@@ -58,7 +58,6 @@ static struct super_block *alloc_super(void) ...@@ -58,7 +58,6 @@ static struct super_block *alloc_super(void)
s->s_count = S_BIAS; s->s_count = S_BIAS;
atomic_set(&s->s_active, 1); atomic_set(&s->s_active, 1);
sema_init(&s->s_vfs_rename_sem,1); sema_init(&s->s_vfs_rename_sem,1);
sema_init(&s->s_nfsd_free_path_sem,1);
sema_init(&s->s_dquot.dqio_sem, 1); sema_init(&s->s_dquot.dqio_sem, 1);
sema_init(&s->s_dquot.dqoff_sem, 1); sema_init(&s->s_dquot.dqoff_sem, 1);
s->s_maxbytes = MAX_NON_LFS; s->s_maxbytes = MAX_NON_LFS;
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
extern long ___test_and_set_bit(unsigned long nr, volatile void *addr); extern long ___test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
extern long ___test_and_clear_bit(unsigned long nr, volatile void *addr); extern long ___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
extern long ___test_and_change_bit(unsigned long nr, volatile void *addr); extern long ___test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
#define test_and_set_bit(nr,addr) ({___test_and_set_bit(nr,addr)!=0;}) #define test_and_set_bit(nr,addr) ({___test_and_set_bit(nr,addr)!=0;})
#define test_and_clear_bit(nr,addr) ({___test_and_clear_bit(nr,addr)!=0;}) #define test_and_clear_bit(nr,addr) ({___test_and_clear_bit(nr,addr)!=0;})
...@@ -22,52 +22,64 @@ extern long ___test_and_change_bit(unsigned long nr, volatile void *addr); ...@@ -22,52 +22,64 @@ extern long ___test_and_change_bit(unsigned long nr, volatile void *addr);
#define change_bit(nr,addr) ((void)___test_and_change_bit(nr,addr)) #define change_bit(nr,addr) ((void)___test_and_change_bit(nr,addr))
/* "non-atomic" versions... */ /* "non-atomic" versions... */
#define __set_bit(X,Y) \
do { unsigned long __nr = (X); \ static __inline__ void __set_bit(int nr, volatile unsigned long *addr)
long *__m = ((long *) (Y)) + (__nr >> 6); \ {
*__m |= (1UL << (__nr & 63)); \ volatile unsigned long *m = addr + (nr >> 6);
} while (0)
#define __clear_bit(X,Y) \ *m |= (1UL << (nr & 63));
do { unsigned long __nr = (X); \ }
long *__m = ((long *) (Y)) + (__nr >> 6); \
*__m &= ~(1UL << (__nr & 63)); \ static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
} while (0) {
#define __change_bit(X,Y) \ volatile unsigned long *m = addr + (nr >> 6);
do { unsigned long __nr = (X); \
long *__m = ((long *) (Y)) + (__nr >> 6); \ *m &= ~(1UL << (nr & 63));
*__m ^= (1UL << (__nr & 63)); \ }
} while (0)
#define __test_and_set_bit(X,Y) \ static __inline__ void __change_bit(int nr, volatile unsigned long *addr)
({ unsigned long __nr = (X); \ {
long *__m = ((long *) (Y)) + (__nr >> 6); \ volatile unsigned long *m = addr + (nr >> 6);
long __old = *__m; \
long __mask = (1UL << (__nr & 63)); \ *m ^= (1UL << (nr & 63));
*__m = (__old | __mask); \ }
((__old & __mask) != 0); \
}) static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr)
#define __test_and_clear_bit(X,Y) \ {
({ unsigned long __nr = (X); \ volatile unsigned long *m = addr + (nr >> 6);
long *__m = ((long *) (Y)) + (__nr >> 6); \ long old = *m;
long __old = *__m; \ long mask = (1UL << (nr & 63));
long __mask = (1UL << (__nr & 63)); \
*__m = (__old & ~__mask); \ *m = (old | mask);
((__old & __mask) != 0); \ return ((old & mask) != 0);
}) }
#define __test_and_change_bit(X,Y) \
({ unsigned long __nr = (X); \ static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
long *__m = ((long *) (Y)) + (__nr >> 6); \ {
long __old = *__m; \ volatile unsigned long *m = addr + (nr >> 6);
long __mask = (1UL << (__nr & 63)); \ long old = *m;
*__m = (__old ^ __mask); \ long mask = (1UL << (nr & 63));
((__old & __mask) != 0); \
}) *m = (old & ~mask);
return ((old & mask) != 0);
}
static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
{
volatile unsigned long *m = addr + (nr >> 6);
long old = *m;
long mask = (1UL << (nr & 63));
*m = (old ^ mask);
return ((old & mask) != 0);
}
#define smp_mb__before_clear_bit() do { } while(0) #define smp_mb__before_clear_bit() do { } while(0)
#define smp_mb__after_clear_bit() do { } while(0) #define smp_mb__after_clear_bit() do { } while(0)
static __inline__ int test_bit(int nr, __const__ void *addr) static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
{ {
return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63))) != 0UL; return (1UL & ((addr)[nr >> 6] >> (nr & 63))) != 0UL;
} }
/* The easy/cheese version for now. */ /* The easy/cheese version for now. */
...@@ -177,9 +189,9 @@ static __inline__ unsigned int hweight8(unsigned int w) ...@@ -177,9 +189,9 @@ static __inline__ unsigned int hweight8(unsigned int w)
* @offset: The bitnumber to start searching at * @offset: The bitnumber to start searching at
* @size: The maximum size to search * @size: The maximum size to search
*/ */
static __inline__ unsigned long find_next_bit(void *addr, unsigned long size, unsigned long offset) static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset)
{ {
unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~63UL; unsigned long result = offset & ~63UL;
unsigned long tmp; unsigned long tmp;
...@@ -231,9 +243,9 @@ static __inline__ unsigned long find_next_bit(void *addr, unsigned long size, un ...@@ -231,9 +243,9 @@ static __inline__ unsigned long find_next_bit(void *addr, unsigned long size, un
* on Linus's ALPHA routines, which are pretty portable BTW. * on Linus's ALPHA routines, which are pretty portable BTW.
*/ */
static __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) static __inline__ unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset)
{ {
unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~63UL; unsigned long result = offset & ~63UL;
unsigned long tmp; unsigned long tmp;
...@@ -272,15 +284,15 @@ static __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long siz ...@@ -272,15 +284,15 @@ static __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long siz
#define find_first_zero_bit(addr, size) \ #define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0) find_next_zero_bit((addr), (size), 0)
extern long ___test_and_set_le_bit(int nr, volatile void *addr); extern long ___test_and_set_le_bit(int nr, volatile unsigned long *addr);
extern long ___test_and_clear_le_bit(int nr, volatile void *addr); extern long ___test_and_clear_le_bit(int nr, volatile unsigned long *addr);
#define test_and_set_le_bit(nr,addr) ({___test_and_set_le_bit(nr,addr)!=0;}) #define test_and_set_le_bit(nr,addr) ({___test_and_set_le_bit(nr,addr)!=0;})
#define test_and_clear_le_bit(nr,addr) ({___test_and_clear_le_bit(nr,addr)!=0;}) #define test_and_clear_le_bit(nr,addr) ({___test_and_clear_le_bit(nr,addr)!=0;})
#define set_le_bit(nr,addr) ((void)___test_and_set_le_bit(nr,addr)) #define set_le_bit(nr,addr) ((void)___test_and_set_le_bit(nr,addr))
#define clear_le_bit(nr,addr) ((void)___test_and_clear_le_bit(nr,addr)) #define clear_le_bit(nr,addr) ((void)___test_and_clear_le_bit(nr,addr))
static __inline__ int test_le_bit(int nr, __const__ void * addr) static __inline__ int test_le_bit(int nr, __const__ unsigned long * addr)
{ {
int mask; int mask;
__const__ unsigned char *ADDR = (__const__ unsigned char *) addr; __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
...@@ -293,9 +305,9 @@ static __inline__ int test_le_bit(int nr, __const__ void * addr) ...@@ -293,9 +305,9 @@ static __inline__ int test_le_bit(int nr, __const__ void * addr)
#define find_first_zero_le_bit(addr, size) \ #define find_first_zero_le_bit(addr, size) \
find_next_zero_le_bit((addr), (size), 0) find_next_zero_le_bit((addr), (size), 0)
static __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long size, unsigned long offset) static __inline__ unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset)
{ {
unsigned long *p = ((unsigned long *) addr) + (offset >> 6); unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~63UL; unsigned long result = offset & ~63UL;
unsigned long tmp; unsigned long tmp;
...@@ -332,18 +344,22 @@ static __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long ...@@ -332,18 +344,22 @@ static __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long
#ifdef __KERNEL__ #ifdef __KERNEL__
#define ext2_set_bit test_and_set_le_bit #define ext2_set_bit(nr,addr) test_and_set_le_bit((nr),(unsigned long *)(addr))
#define ext2_clear_bit test_and_clear_le_bit #define ext2_clear_bit(nr,addr) test_and_clear_le_bit((nr),(unsigned long *)(addr))
#define ext2_test_bit test_le_bit #define ext2_test_bit(nr,addr) test_le_bit((nr),(unsigned long *)(addr))
#define ext2_find_first_zero_bit find_first_zero_le_bit #define ext2_find_first_zero_bit(addr, size) \
#define ext2_find_next_zero_bit find_next_zero_le_bit find_first_zero_le_bit((unsigned long *)(addr), (size))
#define ext2_find_next_zero_bit(addr, size, off) \
find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
/* Bitmap functions for the minix filesystem. */ /* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) #define minix_test_and_set_bit(nr,addr) test_and_set_bit((nr),(unsigned long *)(addr))
#define minix_set_bit(nr,addr) set_bit(nr,addr) #define minix_set_bit(nr,addr) set_bit((nr),(unsigned long *)(addr))
#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) #define minix_test_and_clear_bit(nr,addr) \
#define minix_test_bit(nr,addr) test_bit(nr,addr) test_and_clear_bit((nr),(unsigned long *)(addr))
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) #define minix_test_bit(nr,addr) test_bit((nr),(unsigned long *)(addr))
#define minix_find_first_zero_bit(addr,size) \
find_first_zero_bit((unsigned long *)(addr),(size))
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include <asm/pstate.h> #include <asm/pstate.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#define AOFF_task_fpregs (((ASIZ_task) + (64 - 1)) & ~(64 - 1))
/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */ /* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
#define VISEntry \ #define VISEntry \
......
...@@ -660,15 +660,6 @@ struct super_block { ...@@ -660,15 +660,6 @@ struct super_block {
* even looking at it. You had been warned. * even looking at it. You had been warned.
*/ */
struct semaphore s_vfs_rename_sem; /* Kludge */ struct semaphore s_vfs_rename_sem; /* Kludge */
/* The next field is used by knfsd when converting a (inode number based)
* file handle into a dentry. As it builds a path in the dcache tree from
* the bottom up, there may for a time be a subpath of dentrys which is not
* connected to the main tree. This semaphore ensure that there is only ever
* one such free path per filesystem. Note that unconnected files (or other
* non-directories) are allowed, but not unconnected diretories.
*/
struct semaphore s_nfsd_free_path_sem;
}; };
/* /*
...@@ -798,30 +789,6 @@ struct super_operations { ...@@ -798,30 +789,6 @@ struct super_operations {
void (*clear_inode) (struct inode *); void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *); void (*umount_begin) (struct super_block *);
/* Following are for knfsd to interact with "interesting" filesystems
* Currently just reiserfs, but possibly FAT and others later
*
* fh_to_dentry is given a filehandle fragement with length, and a type flag
* and must return a dentry for the referenced object or, if "parent" is
* set, a dentry for the parent of the object.
* If a dentry cannot be found, a "root" dentry should be created and
* flaged as DCACHE_DISCONNECTED. nfsd_iget is an example implementation.
*
* dentry_to_fh is given a dentry and must generate the filesys specific
* part of the file handle. Available length is passed in *lenp and used
* length should be returned therein.
* If need_parent is set, then dentry_to_fh should encode sufficient information
* to find the (current) parent.
* dentry_to_fh should return a 1byte "type" which will be passed back in
* the fhtype arguement to fh_to_dentry. Type of 0 is reserved.
* If filesystem was exportable before the introduction of fh_to_dentry,
* types 1 and 2 should be used is that same way as the generic code.
* Type 255 means error.
*
* Lengths are in units of 4bytes, not bytes.
*/
struct dentry * (*fh_to_dentry)(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent);
int (*dentry_to_fh)(struct dentry *, __u32 *fh, int *lenp, int need_parent);
int (*show_options)(struct seq_file *, struct vfsmount *); int (*show_options)(struct seq_file *, struct vfsmount *);
}; };
......
...@@ -459,6 +459,11 @@ extern void free_uid(struct user_struct *); ...@@ -459,6 +459,11 @@ extern void free_uid(struct user_struct *);
#include <asm/current.h> #include <asm/current.h>
/*
* The 64-bit value is not volatile - you MUST NOT read it
* without holding read_lock_irq(&xtime_lock)
*/
extern u64 jiffies_64;
extern unsigned long volatile jiffies; extern unsigned long volatile jiffies;
extern unsigned long itimer_ticks; extern unsigned long itimer_ticks;
extern unsigned long itimer_next; extern unsigned long itimer_next;
......
...@@ -765,23 +765,25 @@ do { \ ...@@ -765,23 +765,25 @@ do { \
do { \ do { \
if (r) \ if (r) \
{ \ { \
unsigned rtype ur_; \
X##_c = FP_CLS_NORMAL; \ X##_c = FP_CLS_NORMAL; \
\ \
if ((X##_s = (r < 0))) \ if ((X##_s = (r < 0))) \
r = -r; \ r = -r; \
\ \
ur_ = (unsigned rtype) r; \
if (rsize <= _FP_W_TYPE_SIZE) \ if (rsize <= _FP_W_TYPE_SIZE) \
__FP_CLZ(X##_e, r); \ __FP_CLZ(X##_e, ur_); \
else \ else \
__FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \ __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
(_FP_W_TYPE)r); \ (_FP_W_TYPE)ur_); \
if (rsize < _FP_W_TYPE_SIZE) \ if (rsize < _FP_W_TYPE_SIZE) \
X##_e -= (_FP_W_TYPE_SIZE - rsize); \ X##_e -= (_FP_W_TYPE_SIZE - rsize); \
X##_e = rsize - X##_e - 1; \ X##_e = rsize - X##_e - 1; \
\ \
if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \ if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
__FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs + 1), rsize); \ __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
_FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0) \ if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0) \
_FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \ _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
} \ } \
......
...@@ -471,6 +471,7 @@ EXPORT_SYMBOL_GPL(idle_cpu); ...@@ -471,6 +471,7 @@ EXPORT_SYMBOL_GPL(idle_cpu);
EXPORT_SYMBOL_GPL(set_cpus_allowed); EXPORT_SYMBOL_GPL(set_cpus_allowed);
#endif #endif
EXPORT_SYMBOL(jiffies); EXPORT_SYMBOL(jiffies);
EXPORT_SYMBOL(jiffies_64);
EXPORT_SYMBOL(xtime); EXPORT_SYMBOL(xtime);
EXPORT_SYMBOL(do_gettimeofday); EXPORT_SYMBOL(do_gettimeofday);
EXPORT_SYMBOL(do_settimeofday); EXPORT_SYMBOL(do_settimeofday);
......
...@@ -67,7 +67,12 @@ unsigned long event; ...@@ -67,7 +67,12 @@ unsigned long event;
extern int do_setitimer(int, struct itimerval *, struct itimerval *); extern int do_setitimer(int, struct itimerval *, struct itimerval *);
unsigned long volatile jiffies; /*
* The 64-bit value is not volatile - you MUST NOT read it
* without holding read_lock_irq(&xtime_lock).
* jiffies is defined in the linker script...
*/
u64 jiffies_64;
unsigned int * prof_buffer; unsigned int * prof_buffer;
unsigned long prof_len; unsigned long prof_len;
...@@ -664,7 +669,7 @@ void timer_bh(void) ...@@ -664,7 +669,7 @@ void timer_bh(void)
void do_timer(struct pt_regs *regs) void do_timer(struct pt_regs *regs)
{ {
(*(unsigned long *)&jiffies)++; jiffies_64++;
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
/* SMP process accounting uses the local APIC timer */ /* SMP process accounting uses the local APIC timer */
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
* Missing: IPv6 support. * Missing: IPv6 support.
*/ */
#include <linux/config.h>
#if defined(CONFIG_SYN_COOKIES)
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/random.h> #include <linux/random.h>
...@@ -194,4 +192,3 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -194,4 +192,3 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
ret = get_cookie_sock(sk, skb, req, &rt->u.dst); ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
out: return ret; out: return ret;
} }
#endif
...@@ -1518,7 +1518,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) ...@@ -1518,7 +1518,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
NETDEBUG(if (net_ratelimit()) \ NETDEBUG(if (net_ratelimit()) \
printk(KERN_DEBUG "TCP: drop open request from %u.%u.%u.%u/%u\n", \ printk(KERN_DEBUG "TCP: drop open request from %u.%u.%u.%u/%u\n", \
NIPQUAD(saddr), ntohs(skb->h.th->source))); NIPQUAD(saddr), ntohs(skb->h.th->source)));
TCP_INC_STATS_BH(TcpAttemptFails);
dst_release(dst); dst_release(dst);
goto drop_and_free; goto drop_and_free;
} }
......
...@@ -146,8 +146,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) ...@@ -146,8 +146,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
* Unlike normal "enqueue" functions, ingress_enqueue returns a * Unlike normal "enqueue" functions, ingress_enqueue returns a
* firewall FW_* code. * firewall FW_* code.
*/ */
switch (result) {
#ifdef CONFIG_NET_CLS_POLICE #ifdef CONFIG_NET_CLS_POLICE
switch (result) {
case TC_POLICE_SHOT: case TC_POLICE_SHOT:
result = NF_DROP; result = NF_DROP;
sch->stats.drops++; sch->stats.drops++;
...@@ -160,7 +160,7 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) ...@@ -160,7 +160,7 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
sch->stats.bytes += skb->len; sch->stats.bytes += skb->len;
result = NF_ACCEPT; result = NF_ACCEPT;
break; break;
} };
#else #else
sch->stats.packets++; sch->stats.packets++;
sch->stats.bytes += skb->len; sch->stats.bytes += skb->len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment