diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-03-09 20:33:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-03-09 20:33:35 +0000 |
commit | 116674acc97ba75a720329996877077d988443a2 (patch) | |
tree | 6a3f2ff0b612ae2ee8a3f3509370c9e6333a53b3 /fs | |
parent | 71118c319fcae4a138f16e35b4f7e0a6d53ce2ca (diff) |
Merge with Linux 2.4.2.
Diffstat (limited to 'fs')
141 files changed, 1044 insertions, 721 deletions
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index a53c2b8e1..83ba97166 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -12,7 +12,7 @@ #include <linux/errno.h> #include <linux/fs.h> #include <linux/adfs_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/stat.h> #include <linux/string.h> diff --git a/fs/affs/file.c b/fs/affs/file.c index fac21f70b..848f16701 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -21,7 +21,7 @@ #include <linux/fcntl.h> #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/locks.h> #include <linux/smp_lock.h> diff --git a/fs/affs/inode.c b/fs/affs/inode.c index fcb7e103a..99a81fee8 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -14,7 +14,7 @@ #include <asm/div64.h> #include <linux/errno.h> #include <linux/fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/sched.h> #include <linux/affs_fs.h> diff --git a/fs/affs/super.c b/fs/affs/super.c index 32ad74eb9..c77c3410c 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/errno.h> #include <linux/fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/sched.h> #include <linux/affs_fs.h> diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h index 9dc40922a..6bad5db45 100644 --- a/fs/autofs/autofs_i.h +++ b/fs/autofs/autofs_i.h @@ -19,7 +19,7 @@ #define AUTOFS_IOC_COUNT 32 #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/string.h> #include <linux/wait.h> diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index 0eb91f3c2..1b3ce3edf 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c @@ -11,7 +11,7 @@ * ------------------------------------------------------------------------- */ #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/file.h> #include <linux/locks.h> #include <asm/bitops.h> diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c index 7c7c8baf2..c7da7f518 100644 --- a/fs/autofs/waitq.c +++ b/fs/autofs/waitq.c @@ -10,7 +10,7 @@ * * ------------------------------------------------------------------------- */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/signal.h> #include <linux/file.h> diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 20724eb1c..4dcdcaafc 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -20,7 +20,7 @@ #define AUTOFS_IOC_COUNT 32 #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/string.h> #include <linux/wait.h> diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index dd7dd07ac..f23705aeb 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -11,7 +11,7 @@ * ------------------------------------------------------------------------- */ #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/file.h> #include <linux/locks.h> #include <asm/bitops.h> diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index a76cde227..9e5fe900f 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -10,7 +10,7 @@ * * ------------------------------------------------------------------------- */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/signal.h> #include <linux/file.h> diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index b16b0db6a..42f746fb7 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -20,7 +20,7 @@ #include <linux/fcntl.h> #include <linux/ptrace.h> #include <linux/user.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/binfmts.h> #include <linux/personality.h> #include <linux/init.h> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c84164fc4..6841b4acb 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -24,7 +24,7 @@ #include <linux/file.h> #include <linux/fcntl.h> #include <linux/ptrace.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/shm.h> #include <linux/personality.h> #include <linux/elfcore.h> diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c index 95c24a70a..dfe8df281 100644 --- a/fs/binfmt_em86.c +++ b/fs/binfmt_em86.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/stat.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/locks.h> #include <linux/smp_lock.h> #include <linux/binfmts.h> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index c16536479..5ad853910 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -21,7 +21,7 @@ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/binfmts.h> #include <linux/init.h> #include <linux/proc_fs.h> diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index ae7de4c24..2348332e4 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/stat.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/binfmts.h> #include <linux/init.h> #include <linux/file.h> diff --git a/fs/block_dev.c b/fs/block_dev.c index 103332fc4..876160366 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -9,8 +9,9 @@ #include <linux/mm.h> #include <linux/locks.h> #include <linux/fcntl.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/kmod.h> +#include <linux/major.h> #include <linux/devfs_fs_kernel.h> #include <linux/smp_lock.h> diff --git a/fs/buffer.c b/fs/buffer.c index bea5f09e5..6ca6f166b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -31,7 +31,7 @@ #include <linux/config.h> #include <linux/sched.h> #include <linux/fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/locks.h> #include <linux/errno.h> #include <linux/swap.h> diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 12de14e7b..53208881d 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c @@ -194,9 +194,14 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) return NULL; } - /* check if this inode is linked to a cnode */ cii = ITOC(inode); + /* The inode might already be purged due to memory pressure */ + if ( coda_fideq(&cii->c_fid, &NullFID) ) { + iput(inode); + return NULL; + } + /* we shouldn't have inode collisions anymore */ if ( !coda_fideq(fid, &cii->c_fid) ) BUG(); diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index ef05ac2fb..ed88f70cd 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -23,7 +23,7 @@ #include <linux/major.h> #include <linux/sched.h> #include <linux/lp.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/ioport.h> #include <linux/fcntl.h> #include <linux/delay.h> diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c index 4215c3b41..4bde88515 100644 --- a/fs/coda/sysctl.c +++ b/fs/coda/sysctl.c @@ -17,7 +17,7 @@ #include <linux/sysctl.h> #include <linux/swapctl.h> #include <linux/proc_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/ctype.h> #include <asm/bitops.h> diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 6eb6f2e71..2fee47e4c 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -519,7 +519,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, /* build packet for Venus */ if (data->vi.in_size > VC_MAXDATASIZE) { - error = EINVAL; + error = -EINVAL; goto exit; } @@ -539,7 +539,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, /* get the data out of user space */ if ( copy_from_user((char*)inp + (long)inp->coda_ioctl.data, data->vi.in, data->vi.in_size) ) { - error = EINVAL; + error = -EINVAL; goto exit; } @@ -557,7 +557,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, CDEBUG(D_FILE, "return len %d <= request len %d\n", outp->coda_ioctl.len, data->vi.out_size); - error = EINVAL; + error = -EINVAL; } else { error = verify_area(VERIFY_WRITE, data->vi.out, data->vi.out_size); @@ -566,7 +566,7 @@ int venus_pioctl(struct super_block *sb, struct ViceFid *fid, if (copy_to_user(data->vi.out, (char *)outp + (long)outp->coda_ioctl.data, data->vi.out_size)) { - error = EINVAL; + error = -EINVAL; goto exit; } } diff --git a/fs/dcache.c b/fs/dcache.c index e0b170ad7..5ea250e56 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -18,7 +18,6 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/fs.h> -#include <linux/malloc.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/smp_lock.h> @@ -52,13 +51,8 @@ static unsigned int d_hash_shift; static struct list_head *dentry_hashtable; static LIST_HEAD(dentry_unused); -struct { - int nr_dentry; - int nr_unused; - int age_limit; /* age in seconds */ - int want_pages; /* pages requested by system */ - int dummy[2]; -} dentry_stat = {0, 0, 45, 0,}; +/* Statistics gathering. */ +struct dentry_stat_t dentry_stat = {0, 0, 45, 0,}; /* no dcache_lock, please */ static inline void d_free(struct dentry *dentry) @@ -346,8 +340,7 @@ void prune_dcache(int count) if (dentry->d_flags & DCACHE_REFERENCED) { dentry->d_flags &= ~DCACHE_REFERENCED; list_add(&dentry->d_lru, &dentry_unused); - count--; - continue; + goto next; } dentry_stat.nr_unused--; @@ -356,6 +349,7 @@ void prune_dcache(int count) BUG(); prune_one_dentry(dentry); + next: if (!--count) break; } @@ -696,7 +690,7 @@ struct dentry * d_alloc_root(struct inode * root_inode) static inline struct list_head * d_hash(struct dentry * parent, unsigned long hash) { hash += (unsigned long) parent / L1_CACHE_BYTES; - hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2); + hash = hash ^ (hash >> D_HASHBITS); return dentry_hashtable + (hash & D_HASHMASK); } diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 5c412e301..b26854355 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -491,7 +491,7 @@ #include <linux/kernel.h> #include <linux/wait.h> #include <linux/string.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/ctype.h> diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 0bb8826d8..175a40792 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -19,7 +19,7 @@ #include <linux/kernel.h> #include <linux/locks.h> #include <linux/major.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/tty.h> #include <asm/bitops.h> diff --git a/fs/dquot.c b/fs/dquot.c index a63685d34..769b08ba2 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -47,12 +47,11 @@ #include <linux/stat.h> #include <linux/tty.h> #include <linux/file.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/mount.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/init.h> -#include <linux/slab.h> #include <asm/uaccess.h> @@ -1536,7 +1535,7 @@ asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr) break; case Q_GETQUOTA: if (((type == USRQUOTA && current->euid != id) || - (type == GRPQUOTA && in_egroup_p(id))) && + (type == GRPQUOTA && !in_egroup_p(id))) && !capable(CAP_SYS_RESOURCE)) goto out; break; @@ -395,7 +395,7 @@ static int exec_mmap(void) mm = mm_alloc(); if (mm) { - struct mm_struct *active_mm = current->active_mm; + struct mm_struct *active_mm; if (init_new_context(current, mm)) { mmdrop(mm); @@ -409,6 +409,7 @@ static int exec_mmap(void) spin_unlock(&mmlist_lock); task_lock(current); + active_mm = current->active_mm; current->mm = mm; current->active_mm = mm; task_unlock(current); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 59d3ef492..2ecd748e9 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -235,6 +235,7 @@ int ext2_add_entry (struct inode * dir, const char * name, int namelen, return retval; if (dir->i_size <= offset) { if (dir->i_size == 0) { + brelse(bh); return -ENOENT; } diff --git a/fs/fat/buffer.c b/fs/fat/buffer.c index 6e8716b1e..373dcee83 100644 --- a/fs/fat/buffer.c +++ b/fs/fat/buffer.c @@ -5,7 +5,7 @@ */ #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/fs.h> #include <linux/msdos_fs.h> diff --git a/fs/fat/inode.c b/fs/fat/inode.c index f13260966..b559bbe47 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -27,7 +27,7 @@ #include <linux/stat.h> #include <linux/locks.h> #include <linux/fat_cvf.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp_lock.h> #include "msbuffer.h" @@ -10,7 +10,7 @@ */ #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp_lock.h> static void wait_for_partner(struct inode* inode, unsigned int* cnt) @@ -9,7 +9,7 @@ #include <linux/fs.h> #include <linux/mm.h> #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <asm/bitops.h> diff --git a/fs/hfs/balloc.c b/fs/hfs/balloc.c index 4edd6b748..58d281784 100644 --- a/fs/hfs/balloc.c +++ b/fs/hfs/balloc.c @@ -2,7 +2,7 @@ * linux/fs/hfs/balloc.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * hfs_bnode_alloc() and hfs_bnode_bitop() are based on GPLed code * Copyright (C) 1995 Michael Dreher diff --git a/fs/hfs/bdelete.c b/fs/hfs/bdelete.c index c968c74b7..aec139476 100644 --- a/fs/hfs/bdelete.c +++ b/fs/hfs/bdelete.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bdelete.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to delete records in a B-tree. * diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c index d8d7e933d..8e84133d2 100644 --- a/fs/hfs/bfind.c +++ b/fs/hfs/bfind.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bfind.c * * Copyright (C) 1995, 1996 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to access records in a btree. * diff --git a/fs/hfs/bins_del.c b/fs/hfs/bins_del.c index 4a08a39d1..a03b959e3 100644 --- a/fs/hfs/bins_del.c +++ b/fs/hfs/bins_del.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bins_del.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code common to inserting and deleting records * in a B-tree. diff --git a/fs/hfs/binsert.c b/fs/hfs/binsert.c index 0c0c5076a..6f0853892 100644 --- a/fs/hfs/binsert.c +++ b/fs/hfs/binsert.c @@ -2,7 +2,7 @@ * linux/fs/hfs/binsert.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to insert records in a B-tree. * diff --git a/fs/hfs/bitmap.c b/fs/hfs/bitmap.c index 4fcec675f..c9bb850d3 100644 --- a/fs/hfs/bitmap.c +++ b/fs/hfs/bitmap.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bitmap.c * * Copyright (C) 1996-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * Based on GPLed code Copyright (C) 1995 Michael Dreher * diff --git a/fs/hfs/bitops.c b/fs/hfs/bitops.c index 1d3a113bb..e2cb38877 100644 --- a/fs/hfs/bitops.c +++ b/fs/hfs/bitops.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bitops.c * * Copyright (C) 1996 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains functions to handle bitmaps in "left-to-right" * bit-order such that the MSB of a 32-bit big-endian word is bit 0. diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index e2eb8f70b..d7f0566e3 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -2,7 +2,7 @@ * linux/fs/hfs/bnode.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to access nodes in the B-tree structure. * diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 8f6d70c07..4db76fc4f 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c @@ -2,7 +2,7 @@ * linux/fs/hfs/brec.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to access records in a btree. * diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index fb5fec426..bc23f94c2 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -2,7 +2,7 @@ * linux/fs/hfs/btree.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to manipulate the B-tree structure. * The catalog and extents files are both B-trees. diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index e2b975fae..85134f0b3 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c @@ -2,7 +2,7 @@ * linux/fs/hfs/catalog.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the functions related to the catalog B-tree. * diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index d6de087e9..4f35c2760 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -2,7 +2,7 @@ * linux/fs/hfs/dir.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains directory-related functions independent of which * scheme is being used to represent forks. diff --git a/fs/hfs/dir_cap.c b/fs/hfs/dir_cap.c index 9dfb4ab82..3c000cdd5 100644 --- a/fs/hfs/dir_cap.c +++ b/fs/hfs/dir_cap.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the inode_operations and file_operations * structures for HFS directories under the CAP scheme. diff --git a/fs/hfs/dir_dbl.c b/fs/hfs/dir_dbl.c index 8e39508fa..8b7f876c3 100644 --- a/fs/hfs/dir_dbl.c +++ b/fs/hfs/dir_dbl.c @@ -2,7 +2,7 @@ * linux/fs/hfs/dir_dbl.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the inode_operations and file_operations * structures for HFS directories. diff --git a/fs/hfs/dir_nat.c b/fs/hfs/dir_nat.c index 4d050e698..d378aa3a0 100644 --- a/fs/hfs/dir_nat.c +++ b/fs/hfs/dir_nat.c @@ -2,7 +2,7 @@ * linux/fs/hfs/dir_nat.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the inode_operations and file_operations * structures for HFS directories. diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index eca17bc63..5df23375a 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -2,7 +2,7 @@ * linux/fs/hfs/extent.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the functions related to the extents B-tree. * diff --git a/fs/hfs/file.c b/fs/hfs/file.c index 35fbac9de..b5c444a82 100644 --- a/fs/hfs/file.c +++ b/fs/hfs/file.c @@ -2,7 +2,7 @@ * linux/fs/hfs/file.c * * Copyright (C) 1995, 1996 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the file-related functions which are independent of * which scheme is being used to represent forks. @@ -135,9 +135,9 @@ int hfs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_resul * This is the read field in the inode_operations structure for * "regular" (non-header) files. The purpose is to transfer up to * 'count' bytes from the file corresponding to 'inode', beginning at - * 'filp->offset' bytes into the file. The data is transfered to + * 'filp->offset' bytes into the file. The data is transferred to * user-space at the address 'buf'. Returns the number of bytes - * successfully transfered. This function checks the arguments, does + * successfully transferred. This function checks the arguments, does * some setup and then calls hfs_do_read() to do the actual transfer. */ static hfs_rwret_t hfs_file_read(struct file * filp, char * buf, hfs_rwarg_t count, loff_t *ppos) @@ -277,7 +277,7 @@ static inline int xlate_from_user(char *data, const char *buf, int count) * hfs_do_read() * * This function transfers actual data from disk to user-space memory, - * returning the number of bytes successfully transfered. 'fork' tells + * returning the number of bytes successfully transferred. 'fork' tells * which file on the disk to read from. 'pos' gives the offset into * the Linux file at which to begin the transfer. Note that this will * differ from 'filp->offset' in the case of an AppleDouble header file @@ -433,7 +433,7 @@ hfs_s32 hfs_do_read(struct inode *inode, struct hfs_fork * fork, hfs_u32 pos, * hfs_do_write() * * This function transfers actual data from user-space memory to disk, - * returning the number of bytes successfully transfered. 'fork' tells + * returning the number of bytes successfully transferred. 'fork' tells * which file on the disk to write to. 'pos' gives the offset into * the Linux file at which to begin the transfer. Note that this will * differ from 'filp->offset' in the case of an AppleDouble header file diff --git a/fs/hfs/file_cap.c b/fs/hfs/file_cap.c index 2268185e6..0e8c24f5d 100644 --- a/fs/hfs/file_cap.c +++ b/fs/hfs/file_cap.c @@ -2,7 +2,7 @@ * linux/fs/hfs/file_cap.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the file_ops and inode_ops for the metadata * files under the CAP representation. diff --git a/fs/hfs/file_hdr.c b/fs/hfs/file_hdr.c index ba62615b0..c22f71611 100644 --- a/fs/hfs/file_hdr.c +++ b/fs/hfs/file_hdr.c @@ -2,7 +2,7 @@ * linux/fs/hfs/file_hdr.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the file_ops and inode_ops for the metadata * files under the AppleDouble and Netatalk representations. @@ -348,9 +348,9 @@ static void set_dates(struct hfs_cat_entry *entry, struct inode *inode, * This is the read field in the inode_operations structure for * header files. The purpose is to transfer up to 'count' bytes * from the file corresponding to 'inode', beginning at - * 'filp->offset' bytes into the file. The data is transfered to + * 'filp->offset' bytes into the file. The data is transferred to * user-space at the address 'buf'. Returns the number of bytes - * successfully transfered. + * successfully transferred. */ /* XXX: what about the entry count changing on us? */ static hfs_rwret_t hdr_read(struct file * filp, char * buf, diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h index 9552bbb34..f266bc0c4 100644 --- a/fs/hfs/hfs.h +++ b/fs/hfs/hfs.h @@ -2,7 +2,7 @@ * linux/fs/hfs/hfs.h * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * "XXX" in a comment is a note to myself to consider changing something. */ diff --git a/fs/hfs/hfs_btree.h b/fs/hfs/hfs_btree.h index 39d6df4d5..c3371bfa8 100644 --- a/fs/hfs/hfs_btree.h +++ b/fs/hfs/hfs_btree.h @@ -2,7 +2,7 @@ * linux/fs/hfs/hfs_btree.h * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the declarations of the private B-tree * structures and functions. diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 327125506..705d31341 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -2,7 +2,7 @@ * linux/fs/hfs/inode.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains inode-related functions which do not depend on * which scheme is being used to represent forks. diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index b44fdafc8..d907a632d 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -2,7 +2,7 @@ * linux/fs/hfs/mdb.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains functions for reading/writing the MDB. * diff --git a/fs/hfs/part_tbl.c b/fs/hfs/part_tbl.c index 2392a0791..221157226 100644 --- a/fs/hfs/part_tbl.c +++ b/fs/hfs/part_tbl.c @@ -2,7 +2,7 @@ * linux/fs/hfs/part_tbl.c * * Copyright (C) 1996-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * Original code to handle the new style Mac partition table based on * a patch contributed by Holger Schemel (aeglos@valinor.owl.de). diff --git a/fs/hfs/string.c b/fs/hfs/string.c index 18e59de5d..f499b9a80 100644 --- a/fs/hfs/string.c +++ b/fs/hfs/string.c @@ -2,7 +2,7 @@ * linux/fs/hfs/string.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the string comparison function for the * Macintosh character set. diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 8c91758d6..a39710f09 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -2,7 +2,7 @@ * linux/fs/hfs/super.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains hfs_read_super(), some of the super_ops and * init_module() and cleanup_module(). The remaining super_ops are in diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c index 344856064..4ce747a49 100644 --- a/fs/hfs/sysdep.c +++ b/fs/hfs/sysdep.c @@ -2,7 +2,7 @@ * linux/fs/hfs/sysdep.c * * Copyright (C) 1996 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the code to do various system dependent things. * diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c index 2e5127703..64adf73fc 100644 --- a/fs/hfs/trans.c +++ b/fs/hfs/trans.c @@ -2,7 +2,7 @@ * linux/fs/hfs/trans.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains routines for converting between the Macintosh * character set and various other encodings. This includes dealing diff --git a/fs/hfs/version.c b/fs/hfs/version.c index 365e9f375..ef0283ec0 100644 --- a/fs/hfs/version.c +++ b/fs/hfs/version.c @@ -2,7 +2,7 @@ * linux/fs/hfs/version.c * * Copyright (C) 1995-1997 Paul H. Hargrove - * This file may be distributed under the terms of the GNU Public License. + * This file may be distributed under the terms of the GNU General Public License. * * This file contains the version string for this release. */ diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 78341ca16..e30e6137e 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -12,7 +12,7 @@ #include <linux/fs.h> #include <linux/hpfs_fs.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/locks.h> diff --git a/fs/inode.c b/fs/inode.c index d51bbddbe..822e5187a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -67,11 +67,7 @@ spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; /* * Statistics gathering.. */ -struct { - int nr_inodes; - int nr_unused; - int dummy[5]; -} inodes_stat; +struct inodes_stat_t inodes_stat; static kmem_cache_t * inode_cachep; @@ -728,8 +724,8 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s static inline unsigned long hash(struct super_block *sb, unsigned long i_ino) { - unsigned long tmp = i_ino | ((unsigned long) sb / L1_CACHE_BYTES); - tmp = tmp + (tmp >> I_HASHBITS) + (tmp >> I_HASHBITS*2); + unsigned long tmp = i_ino + ((unsigned long) sb / L1_CACHE_BYTES); + tmp = tmp + (tmp >> I_HASHBITS); return tmp & I_HASHMASK; } diff --git a/fs/iobuf.c b/fs/iobuf.c index 4be225870..bcaa98826 100644 --- a/fs/iobuf.c +++ b/fs/iobuf.c @@ -7,7 +7,6 @@ */ #include <linux/iobuf.h> -#include <linux/malloc.h> #include <linux/slab.h> static kmem_cache_t *kiobuf_cachep; diff --git a/fs/ioctl.c b/fs/ioctl.c index 21af77a3a..f46bdb1ed 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -9,6 +9,7 @@ #include <linux/file.h> #include <asm/uaccess.h> +#include <asm/ioctls.h> static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) { diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 6f0957dce..48a358de8 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -17,7 +17,7 @@ #include <linux/stat.h> #include <linux/string.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/locks.h> #include <linux/config.h> diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 757a87070..90f511bda 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -20,7 +20,7 @@ #include <linux/mm.h> #include <linux/string.h> #include <linux/locks.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/errno.h> #include <linux/cdrom.h> #include <linux/init.h> diff --git a/fs/isofs/joliet.c b/fs/isofs/joliet.c index 5b93f4581..2aac3a8bc 100644 --- a/fs/isofs/joliet.c +++ b/fs/isofs/joliet.c @@ -8,7 +8,7 @@ #include <linux/string.h> #include <linux/nls.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/iso_fs.h> /* diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 3f44d9033..87fe121f8 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -12,7 +12,7 @@ #include <linux/string.h> #include <linux/stat.h> #include <linux/fcntl.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/errno.h> #include <linux/config.h> /* Joliet? */ diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index e20f3ad61..c351f7af0 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -11,7 +11,7 @@ #include <linux/iso_fs.h> #include <linux/string.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/smp_lock.h> diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 94fd0797d..d044ef3a3 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -39,7 +39,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/jffs.h> #include <linux/fs.h> #include <linux/locks.h> diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 09e88d7ba..3af256303 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c @@ -58,7 +58,7 @@ #define __NO_VERSION__ #include <linux/types.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/jffs.h> #include <linux/fs.h> #include <linux/stat.h> diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c index b9bbeb4a9..7ae964ab8 100644 --- a/fs/jffs/jffs_fm.c +++ b/fs/jffs/jffs_fm.c @@ -17,7 +17,7 @@ * */ #define __NO_VERSION__ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/blkdev.h> #include <linux/jffs.h> #include "jffs_fm.h" diff --git a/fs/lockd/host.c b/fs/lockd/host.c index f14c9fcdf..02be5d927 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -10,7 +10,7 @@ #include <linux/types.h> #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/in.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 924741f9e..02e7115fe 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -22,7 +22,7 @@ #include <linux/uio.h> #include <linux/version.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp.h> #include <linux/smp_lock.h> diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index a1e30454e..bb72c629e 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -9,7 +9,7 @@ #include <linux/types.h> #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/in.h> #include <linux/sunrpc/svc.h> #include <linux/sunrpc/clnt.h> diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index b0cbd4a50..5002972ec 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -10,7 +10,7 @@ #include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/in.h> #include <linux/sunrpc/svc.h> #include <linux/sunrpc/clnt.h> diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c index ab06a5d31..73fbb1ba4 100644 --- a/fs/lockd/svcshare.c +++ b/fs/lockd/svcshare.c @@ -9,7 +9,7 @@ #include <linux/sched.h> #include <linux/unistd.h> #include <linux/string.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> diff --git a/fs/locks.c b/fs/locks.c index e65b59394..7eed30fec 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -115,7 +115,7 @@ * Stephen Rothwell <sfr@linuxcare.com>, June, 2000. */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/file.h> #include <linux/smp_lock.h> #include <linux/init.h> diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 7ff0b7bd9..d30699826 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -14,7 +14,7 @@ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/stat.h> #include <linux/locks.h> diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index c16d93614..92d0aaba1 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -15,7 +15,7 @@ #include <linux/errno.h> #include <linux/stat.h> #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/mm.h> #include <asm/uaccess.h> diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index ac4de2b83..3bb051f28 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -16,7 +16,7 @@ #include <linux/stat.h> #include <linux/mm.h> #include <linux/locks.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/ncp_fs.h> diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index badfc7817..6cb6e863f 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -24,7 +24,7 @@ #include <linux/locks.h> #include <linux/file.h> #include <linux/fcntl.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/init.h> diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index 9261eb453..50f52119d 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -14,7 +14,7 @@ #include <linux/errno.h> #include <linux/mman.h> #include <linux/string.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/fcntl.h> #include <linux/ncp_fs.h> diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 162c89b4b..43c1306ac 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -17,7 +17,7 @@ #include <linux/fs.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/pagemap.h> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 564a47b32..c3a3a913e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -23,7 +23,7 @@ #include <linux/fcntl.h> #include <linux/string.h> #include <linux/kernel.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/mm.h> #include <linux/sunrpc/clnt.h> #include <linux/nfs_fs.h> diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 2b3f22777..6f9b324e0 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -24,7 +24,7 @@ #include <linux/nfs_fs.h> #include <linux/nfs_mount.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/lockd/bind.h> #include <linux/smp_lock.h> diff --git a/fs/nfs/flushd.c b/fs/nfs/flushd.c index 502b490b8..601425cff 100644 --- a/fs/nfs/flushd.c +++ b/fs/nfs/flushd.c @@ -24,7 +24,7 @@ #include <linux/config.h> #include <linux/types.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/file.h> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index f741cb6dd..a48e711f5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -100,6 +100,7 @@ nfs_read_inode(struct inode * inode) inode->i_rdev = 0; NFS_FILEID(inode) = 0; NFS_FSID(inode) = 0; + NFS_FLAGS(inode) = 0; INIT_LIST_HEAD(&inode->u.nfs_i.read); INIT_LIST_HEAD(&inode->u.nfs_i.dirty); INIT_LIST_HEAD(&inode->u.nfs_i.commit); diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 7fef7da99..c24021a6d 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -12,7 +12,7 @@ #include <linux/param.h> #include <linux/sched.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/utsname.h> #include <linux/errno.h> #include <linux/string.h> diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index f6260a552..ab1110227 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -9,7 +9,7 @@ #include <linux/param.h> #include <linux/sched.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/utsname.h> #include <linux/errno.h> #include <linux/string.h> diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 17bb39f36..e19009ea7 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -29,7 +29,7 @@ #include <linux/types.h> #include <linux/param.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/utsname.h> diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 211d3a3db..beb7bd8dd 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -22,7 +22,7 @@ #include <linux/fcntl.h> #include <linux/stat.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/sunrpc/clnt.h> #include <linux/nfs_fs.h> diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index eba7a859a..4350cf8e7 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -20,7 +20,7 @@ #include <linux/pagemap.h> #include <linux/stat.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/smp_lock.h> diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index f4abfe7b3..511509714 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -6,7 +6,7 @@ * NOTE: we rely on holding the BKL for list manipulation protection. */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/dcache.h> #include <linux/sunrpc/sched.h> diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 8b9a28556..ac7fe2769 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -48,7 +48,7 @@ #include <linux/config.h> #include <linux/types.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/swap.h> #include <linux/pagemap.h> #include <linux/file.h> diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 2beed5cf9..3db60bcc2 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -15,7 +15,7 @@ */ #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/in.h> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index a513bfbe0..8051b15f8 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -18,7 +18,7 @@ #include <linux/in.h> #include <linux/version.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/major.h> #include <linux/sunrpc/svc.h> diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 8a061ebcb..2157f622a 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -12,7 +12,7 @@ #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/string.h> #include <linux/sunrpc/svc.h> @@ -192,7 +192,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) xid == rp->c_xid && proc == rp->c_proc && proto == rp->c_prot && vers == rp->c_vers && time_before(jiffies, rp->c_timestamp + 120*HZ) && - memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, rqstp->rq_addrlen)==0) { + memcmp((char*)&rqstp->rq_addr, (char*)&rp->c_addr, sizeof(rp->c_addr))==0) { nfsdstats.rchits++; goto found_entry; } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 7a80fe990..7641c5b52 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -18,7 +18,7 @@ #include <linux/net.h> #include <linux/in.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/proc_fs.h> #include <linux/nfs.h> diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 78c729c09..6e2c98a55 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -9,7 +9,7 @@ */ #include <linux/sched.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/fs.h> #include <linux/unistd.h> #include <linux/string.h> @@ -454,6 +454,7 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino, 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 */ diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index b5057d57b..303792b58 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -18,7 +18,7 @@ #include <linux/in.h> #include <linux/version.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h> @@ -252,8 +252,19 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, if (attr->ia_valid & ATTR_MODE) { type = attr->ia_mode & S_IFMT; mode = attr->ia_mode & ~S_IFMT; - if (!type) /* HP weirdness */ - type = S_IFREG; + if (!type) { + /* no type, so if target exists, assume same as that, + * else assume a file */ + if (inode) { + type = inode->i_mode & S_IFMT; + if (type == S_IFCHR || type == S_IFBLK) { + /* reserve rdev for later checking */ + attr->ia_size = inode->i_rdev; + attr->ia_valid |= ATTR_SIZE; + } + } else + type = S_IFREG; + } } else if (inode) { type = inode->i_mode & S_IFMT; mode = inode->i_mode & ~S_IFMT; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index a4a642c44..0537c06d7 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -19,7 +19,7 @@ #include <linux/uio.h> #include <linux/version.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp.h> #include <linux/smp_lock.h> diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index fcbddc5ed..7bcc37c41 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -26,7 +26,7 @@ * Mapping of S_IF* types to NFS file types */ static u32 nfs_ftypes[] = { - NFNON, NFFIFO, NFCHR, NFBAD, + NFNON, NFCHR, NFCHR, NFBAD, NFDIR, NFBAD, NFBLK, NFBAD, NFREG, NFBAD, NFLNK, NFBAD, NFSOCK, NFBAD, NFLNK, NFBAD, @@ -136,20 +136,25 @@ decode_sattr(u32 *p, struct iattr *iap) static inline u32 * encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode) { + int type = (inode->i_mode & S_IFMT); if (!inode) return 0; - *p++ = htonl(nfs_ftypes[(inode->i_mode & S_IFMT) >> 12]); + *p++ = htonl(nfs_ftypes[type >> 12]); *p++ = htonl((u32) inode->i_mode); *p++ = htonl((u32) inode->i_nlink); *p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid)); *p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid)); - if (S_ISLNK(inode->i_mode) && inode->i_size > NFS_MAXPATHLEN) { + + if (S_ISLNK(type) && inode->i_size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); } else { *p++ = htonl((u32) inode->i_size); } *p++ = htonl((u32) inode->i_blksize); - *p++ = htonl((u32) inode->i_rdev); + if (S_ISCHR(type) || S_ISBLK(type)) + *p++ = htonl((u32) inode->i_rdev); + else + *p++ = htonl(0xffffffff); *p++ = htonl((u32) inode->i_blocks); *p++ = htonl((u32) inode->i_dev); *p++ = htonl((u32) inode->i_ino); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index bd01b57f5..43fc14a4f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -29,7 +29,7 @@ #include <linux/fcntl.h> #include <linux/net.h> #include <linux/unistd.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/in.h> #define __NO_VERSION__ #include <linux/module.h> diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index e98d8490c..1db7ffd82 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -13,7 +13,7 @@ #include <linux/string.h> #include <linux/config.h> #include <linux/nls.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/errno.h> #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -13,6 +13,7 @@ #include <linux/dnotify.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/tty.h> #include <asm/uaccess.h> diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index e264dd3d3..946a5ccd7 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -1,4 +1,4 @@ -/* $Id: inode.c,v 1.13 2000/08/12 13:25:46 davem Exp $ +/* $Id: inode.c,v 1.14 2001/02/13 01:17:17 davem Exp $ * openpromfs.c: /proc/openprom handling routines * * Copyright (C) 1996-1999 Jakub Jelinek (jakub@redhat.com) @@ -12,7 +12,7 @@ #include <linux/openprom_fs.h> #include <linux/locks.h> #include <linux/init.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp_lock.h> #include <asm/openprom.h> diff --git a/fs/partitions/Config.in b/fs/partitions/Config.in index 6fadbd846..2a3f6d8b1 100644 --- a/fs/partitions/Config.in +++ b/fs/partitions/Config.in @@ -21,6 +21,7 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then bool ' PC BIOS (MSDOS partition tables) support' CONFIG_MSDOS_PARTITION if [ "$CONFIG_MSDOS_PARTITION" = "y" ]; then bool ' BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL + bool ' Minix subpartition support' CONFIG_MINIX_SUBPARTITION bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL fi diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 53b05e3ef..15568c734 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -76,7 +76,7 @@ static int (*check_part[])(struct gendisk *hd, kdev_t dev, unsigned long first_s }; /* - * disk_name() is used by genhd.c and blkpg.c. + * disk_name() is used by partition check code and the md driver. * It formats the devicename of the indicated disk into * the supplied buffer (of size at least 32), and returns * a pointer to that same buffer (for convenience). diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 765bbc9f9..be3e7eae7 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c @@ -1,8 +1,12 @@ /* - * File...........: linux/fs/partitions/ibm.c + * File...........: linux/fs/partitions/ibm.c * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com> - * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000 + * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 + + * History of changes (starts July 2000) + * 07/10/00 Fixed detection of CMS formatted disks + */ #include <linux/fs.h> @@ -11,9 +15,21 @@ #include <linux/major.h> #include <linux/string.h> #include <linux/blk.h> - +#include <linux/malloc.h> +#include <linux/hdreg.h> +#include <linux/ioctl.h> +#include <linux/version.h> #include <asm/ebcdic.h> -#include "../../drivers/s390/block/dasd_types.h" +#include <asm/uaccess.h> +#include <asm/dasd.h> + +#include "ibm.h" +#include "check.h" + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) +/* We hook in when DASD is a module... */ +int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL; +#endif /* LINUX_IS_24 */ typedef enum { ibm_partition_none = 0, @@ -25,98 +41,131 @@ typedef enum { static ibm_partition_t get_partition_type ( char * type ) { - static char lnx[5]="LNX1"; - static char vol[5]="VOL1"; - static char cms[5]="CMS1"; - if ( ! strncmp ( lnx, "LNX1",4 ) ) { - ASCEBC(lnx,4); - ASCEBC(vol,4); - ASCEBC(cms,4); - } - if ( ! strncmp (type,lnx,4) || - ! strncmp (type,"LNX1",4) ) - return ibm_partition_lnx1; - if ( ! strncmp (type,vol,4) ) - return ibm_partition_vol1; - if ( ! strncmp (type,cms,4) ) - return ibm_partition_cms1; - return ibm_partition_none; + static char lnx[5]="LNX1"; + static char vol[5]="VOL1"; + static char cms[5]="CMS1"; + if ( ! strncmp ( lnx, "LNX1",4 ) ) { + ASCEBC(lnx,4); + ASCEBC(vol,4); + ASCEBC(cms,4); + } + if ( ! strncmp (type,lnx,4) || + ! strncmp (type,"LNX1",4) ) + return ibm_partition_lnx1; + if ( ! strncmp (type,vol,4) ) + return ibm_partition_vol1; + if ( ! strncmp (type,cms,4) ) + return ibm_partition_cms1; + return ibm_partition_none; } -void -ibm_partition (struct gendisk *hd, kdev_t dev) +int +ibm_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int +first_part_minor) { struct buffer_head *bh; ibm_partition_t partition_type; - int di = MINOR(dev) >> PARTN_BITS; char type[5] = {0,}; char name[7] = {0,}; - if ( bh = bread( dev, - dasd_info[di]->sizes.label_block, - get_ptable_blocksize(dev) ) ) { + struct hd_geometry geo; + mm_segment_t old_fs; + int blocksize; + struct file *filp = NULL; + struct inode *inode = NULL; + int offset, size; + + blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)]; + if ( blocksize <= 0 ) { + return 0; + } + set_blocksize(dev, blocksize); /* OUCH !! */ + + /* find out offset of volume label (partn table) */ + inode = get_empty_inode(); + inode -> i_rdev = dev; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) + inode -> i_bdev = bdget(kdev_t_to_nr(dev)); +#endif /* KERNEL_VERSION */ + filp = (struct file *)kmalloc (sizeof(struct file),GFP_KERNEL); + if (!filp) + return 0; + memset(filp,0,sizeof(struct file)); + filp ->f_mode = 1; /* read only */ + blkdev_open(inode,filp); + old_fs=get_fs(); + set_fs(KERNEL_DS); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) + inode-> i_bdev -> bd_op->ioctl (inode, filp, HDIO_GETGEO, (unsigned long)(&geo)); +#else + filp->f_op->ioctl (inode, filp, HDIO_GETGEO, (unsigned long)(&geo)); +#endif /* KERNEL_VERSION */ + set_fs(old_fs); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) + blkdev_put(inode->i_bdev,BDEV_FILE); +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) + blkdev_close(inode,filp); +#else + blkdev_release(inode); +#endif /* LINUX_VERSION_CODE */ + + size = hd -> sizes[MINOR(dev)]<<1; + if ( ( bh = bread( dev, geo.start, blocksize) ) != NULL ) { strncpy ( type,bh -> b_data, 4); strncpy ( name,bh -> b_data + 4, 6); } else { - return; + return 0; } if ( (*(char *)bh -> b_data) & 0x80 ) { EBCASC(name,6); } switch ( partition_type = get_partition_type(type) ) { - case ibm_partition_lnx1: + case ibm_partition_lnx1: + offset = (geo.start + 1); printk ( "(LNX1)/%6s:",name); - add_gd_partition( hd, MINOR(dev) + 1, - (dasd_info [di]->sizes.label_block + 1) << - dasd_info [di]->sizes.s2b_shift, - (dasd_info [di]->sizes.blocks - - dasd_info [di]->sizes.label_block - 1) << - dasd_info [di]->sizes.s2b_shift ); break; case ibm_partition_vol1: + offset = 0; + size = 0; printk ( "(VOL1)/%6s:",name); break; case ibm_partition_cms1: printk ( "(CMS1)/%6s:",name); if (* (((long *)bh->b_data) + 13) == 0) { - /* disk holds a CMS filesystem */ - add_gd_partition( hd, MINOR(dev) + 1, - (dasd_info [di]->sizes.label_block + 1) << - dasd_info [di]->sizes.s2b_shift, - (dasd_info [di]->sizes.blocks - - dasd_info [di]->sizes.label_block) << - dasd_info [di]->sizes.s2b_shift ); - printk ("(CMS)"); + /* disk holds a CMS filesystem */ + offset = (geo.start + 1); + printk ("(CMS)"); } else { - /* disk is reserved minidisk */ - int offset = (*(((long *)bh->b_data) + 13)); - int size = (*(((long *)bh->b_data) + 7)) - 1 - - (*(((long *)bh->b_data) + 13)) * - ((*(((long *)bh->b_data) + 3)) >> 9); - add_gd_partition( hd, MINOR(dev) + 1, - offset << dasd_info [di]->sizes.s2b_shift, - size << dasd_info [di]->sizes.s2b_shift ); - printk ("(MDSK)"); + /* disk is reserved minidisk */ + // mdisk_setup_data.size[i] = + // (label[7] - 1 - label[13]) * + // (label[3] >> 9) >> 1; + long *label=(long*)bh->b_data; + blocksize = label[3]; + offset = label[13]; + size = (label[7]-1)*(blocksize>>9); + printk ("(MDSK)"); } break; case ibm_partition_none: printk ( "(nonl)/ :"); -/* - printk ( "%d %d %d ", MINOR(dev) + 1, - (dasd_info [di]->sizes.label_block + 1) << - dasd_info [di]->sizes.s2b_shift, - (dasd_info [di]->sizes.blocks - - dasd_info [di]->sizes.label_block - 1) << - dasd_info [di]->sizes.s2b_shift ); -*/ - add_gd_partition( hd, MINOR(dev) + 1, - (dasd_info [di]->sizes.label_block + 1) << - dasd_info [di]->sizes.s2b_shift, - (dasd_info [di]->sizes.blocks - - dasd_info [di]->sizes.label_block - 1) << - dasd_info [di]->sizes.s2b_shift ); + offset = (geo.start+1); break; + default: + offset = 0; + size = 0; + } +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) + add_gd_partition( hd, MINOR(dev), 0,size); + add_gd_partition( hd, MINOR(dev) + 1, offset * (blocksize >> 9), + size-offset*(blocksize>>9)); +#else + add_partition( hd, MINOR(dev), 0,size,0); + add_partition( hd, MINOR(dev) + 1, offset * (blocksize >> 9), + size-offset*(blocksize>>9) ,0 ); +#endif /* LINUX_VERSION */ printk ( "\n" ); bforget(bh); + return 1; } diff --git a/fs/partitions/ibm.h b/fs/partitions/ibm.h index 35d01e06c..49ff10bc4 100644 --- a/fs/partitions/ibm.h +++ b/fs/partitions/ibm.h @@ -1 +1 @@ -void ibm_partition (struct gendisk *hd, kdev_t dev); +int ibm_partition(struct gendisk *, kdev_t, unsigned long, int); diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 0d72631c8..952e79b01 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -68,6 +68,23 @@ static inline int is_extended_partition(struct partition *p) } /* + * partition_name() formats the short partition name into the supplied + * buffer, and returns a pointer to that buffer. + * Used by several partition types which makes conditional inclusion messy, + * use __attribute__ ((unused)) instead. + */ +static char __attribute__ ((unused)) + *partition_name (struct gendisk *hd, int minor, char *buf) +{ +#ifdef CONFIG_DEVFS_FS + sprintf(buf, "p%d", (minor & ((1 << hd->minor_shift) - 1))); + return buf; +#else + return disk_name(hd, minor, buf); +#endif +} + +/* * Create devices for each logical partition in an extended partition. * The logical partitions form a linked list, with each entry being * a partition table with two entries. The first entry @@ -194,23 +211,27 @@ solaris_x86_partition(struct gendisk *hd, int minor) { struct buffer_head *bh; struct solaris_x86_vtoc *v; struct solaris_x86_slice *s; + int mask = (1 << hd->minor_shift) - 1; int i; char buf[40]; if(!(bh = get_partition_table_block(hd, minor, 0))) return; v = (struct solaris_x86_vtoc *)(bh->b_data + 512); - if(v->v_sanity != SOLARIS_X86_VTOC_SANE) { + if(le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { brelse(bh); return; } - printk(" %s: <solaris:", disk_name(hd, minor, buf)); - if(v->v_version != 1) { - printk(" cannot handle version %ld vtoc>\n", v->v_version); + printk(" %s: <solaris:", partition_name(hd, minor, buf)); + if(le32_to_cpu(v->v_version) != 1) { + printk(" cannot handle version %d vtoc>\n", + le32_to_cpu(v->v_version)); brelse(bh); return; } for(i=0; i<SOLARIS_X86_NUMSLICE; i++) { + if ((current_minor & mask) == 0) + break; s = &v->v_slice[i]; if (s->s_size == 0) @@ -220,7 +241,8 @@ solaris_x86_partition(struct gendisk *hd, int minor) { * one but add_gd_partition starts relative to sector * zero of the disk. Therefore, must add the offset * of the current partition */ - add_gd_partition(hd, current_minor, s->s_start+offset, s->s_size); + add_gd_partition(hd, current_minor, le32_to_cpu(s->s_start)+offset, + le32_to_cpu(s->s_size)); current_minor++; } brelse(bh); @@ -237,21 +259,22 @@ check_and_add_bsd_partition(struct gendisk *hd, for (lin_p = hd->part + 1 + minor; lin_p - hd->part - minor < current_minor; lin_p++) { /* no relationship -> try again */ - if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset || - lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size) + if (lin_p->start_sect + lin_p->nr_sects <= le32_to_cpu(bsd_p->p_offset) || + lin_p->start_sect >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) continue; /* equal -> no need to add */ - if (lin_p->start_sect == bsd_p->p_offset && - lin_p->nr_sects == bsd_p->p_size) + if (lin_p->start_sect == le32_to_cpu(bsd_p->p_offset) && + lin_p->nr_sects == le32_to_cpu(bsd_p->p_size)) return; /* bsd living within dos partition */ - if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect - + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) { + if (lin_p->start_sect <= le32_to_cpu(bsd_p->p_offset) && lin_p->start_sect + + lin_p->nr_sects >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) { #ifdef DEBUG_BSD_DISKLABEL printk("w: %d %ld+%ld,%d+%d", lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, - bsd_p->p_offset, bsd_p->p_size); + le32_to_cpu(bsd_p->p_offset), + le32_to_cpu(bsd_p->p_size)); #endif break; } @@ -259,14 +282,15 @@ check_and_add_bsd_partition(struct gendisk *hd, #ifdef DEBUG_BSD_DISKLABEL printk("???: %d %ld+%ld,%d+%d", lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, - bsd_p->p_offset, bsd_p->p_size); + le32_to_cpu(bsd_p->p_offset), le32_to_cpu(bsd_p->p_size)); #endif printk("???"); return; } /* if the bsd partition is not currently known to linux, we end * up here */ - add_gd_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size); + add_gd_partition(hd, current_minor, le32_to_cpu(bsd_p->p_offset), + le32_to_cpu(bsd_p->p_size)); current_minor++; } @@ -285,20 +309,20 @@ static void bsd_disklabel_partition(struct gendisk *hd, int minor, int type) { if (!(bh = get_partition_table_block(hd, minor, 0))) return; l = (struct bsd_disklabel *) (bh->b_data+512); - if (l->d_magic != BSD_DISKMAGIC) { + if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) { brelse(bh); return; } - printk(" %s:", disk_name(hd, minor, buf)); + printk(" %s:", partition_name(hd, minor, buf)); printk((type == OPENBSD_PARTITION) ? " <openbsd:" : (type == NETBSD_PARTITION) ? " <netbsd:" : " <bsd:"); max_partitions = ((type == OPENBSD_PARTITION) ? OPENBSD_MAXPARTITIONS : BSD_MAXPARTITIONS); - if (l->d_npartitions < max_partitions) - max_partitions = l->d_npartitions; + if (le16_to_cpu(l->d_npartitions) < max_partitions) + max_partitions = le16_to_cpu(l->d_npartitions); for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { - if ((current_minor & mask) >= (4 + hd->max_p)) + if ((current_minor & mask) == 0) break; if (p->p_fstype != BSD_FS_UNUSED) @@ -332,7 +356,7 @@ static void unixware_partition(struct gendisk *hd, int minor) { brelse(bh); return; } - printk(" %s: <unixware:", disk_name(hd, minor, buf)); + printk(" %s: <unixware:", partition_name(hd, minor, buf)); p = &l->vtoc.v_slice[1]; /* I omit the 0th slice as it is the same as whole disk. */ while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { @@ -352,6 +376,49 @@ static void unixware_partition(struct gendisk *hd, int minor) { } #endif +#ifdef CONFIG_MINIX_SUBPARTITION +/* + * Minix 2.0.0/2.0.2 subpartition support. + * Anand Krishnamurthy <anandk@wiproge.med.ge.com> + * Rajeev V. Pillai <rajeevvp@yahoo.com> + */ +static void minix_partition(struct gendisk *hd, int minor) +{ + struct buffer_head *bh; + struct partition *p; + int mask = (1 << hd->minor_shift) - 1; + int i; + char buf[40]; + + if (!(bh = get_partition_table_block(hd, minor, 0))) + return; + bh->b_state = 0; + + p = (struct partition *)(bh->b_data + 0x1be); + + /* The first sector of a Minix partition can have either + * a secondary MBR describing its subpartitions, or + * the normal boot sector. */ + if ((*(__u16 *) (bh->b_data + 510)) != cpu_to_le16(MSDOS_LABEL_MAGIC) && + SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ + + printk(" %s: <minix:", partition_name(hd, minor, buf)); + for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) { + if ((current_minor & mask) == 0) + break; + /* add each partition in use */ + if (SYS_IND(p) == MINIX_PARTITION) { + add_gd_partition(hd, current_minor, + START_SECT(p), NR_SECTS(p)); + current_minor++; + } + } + printk(" >\n"); + } + brelse(bh); +} +#endif /* CONFIG_MINIX_SUBPARTITION */ + int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor) { int i, minor = current_minor = first_part_minor; @@ -500,6 +567,11 @@ check_table: SYS_IND(p) == OPENBSD_PARTITION) bsd_disklabel_partition(hd, minor, SYS_IND(p)); #endif +#ifdef CONFIG_MINIX_SUBPARTITION + if (SYS_IND(p) == MINIX_PARTITION) { + minix_partition(hd, minor); + } +#endif #ifdef CONFIG_UNIXWARE_DISKLABEL if (SYS_IND(p) == UNIXWARE_PARTITION) unixware_partition(hd, minor); diff --git a/fs/partitions/osf.c b/fs/partitions/osf.c index 7982302a3..52aae3bbd 100644 --- a/fs/partitions/osf.c +++ b/fs/partitions/osf.c @@ -62,21 +62,21 @@ int osf_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, } label = (struct disklabel *) (bh->b_data+64); partition = label->d_partitions; - if (label->d_magic != DISKLABELMAGIC) { + if (le32_to_cpu(label->d_magic) != DISKLABELMAGIC) { brelse(bh); return 0; } - if (label->d_magic2 != DISKLABELMAGIC) { + if (le32_to_cpu(label->d_magic2) != DISKLABELMAGIC) { brelse(bh); return 0; } - for (i = 0 ; i < label->d_npartitions; i++, partition++) { + for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) { if ((current_minor & mask) == 0) break; - if (partition->p_size) + if (le32_to_cpu(partition->p_size)) add_gd_partition(hd, current_minor, - first_sector+partition->p_offset, - partition->p_size); + first_sector+le32_to_cpu(partition->p_offset), + le32_to_cpu(partition->p_size)); current_minor++; } printk("\n"); @@ -7,11 +7,12 @@ #include <linux/mm.h> #include <linux/file.h> #include <linux/poll.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <asm/uaccess.h> +#include <asm/ioctls.h> /* * We use a start+len construction, which provides full use of the diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index c40f488e5..490c3d047 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -17,7 +17,7 @@ #include <linux/types.h> #include <linux/string.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/qnx4_fs.h> #include <linux/fs.h> #include <linux/locks.h> diff --git a/fs/qnx4/truncate.c b/fs/qnx4/truncate.c index a25bf1daf..9dad91a17 100644 --- a/fs/qnx4/truncate.c +++ b/fs/qnx4/truncate.c @@ -13,7 +13,7 @@ #include <linux/config.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/qnx4_fs.h> #include <linux/fs.h> #include <linux/locks.h> diff --git a/fs/read_write.c b/fs/read_write.c index 00b0daf7e..2d264640c 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -4,7 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/file.h> diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index ffb8920bd..27305305e 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -1,11 +1,21 @@ /* * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README + * + * Trivial changes by Alan Cox to remove EHASHCOLLISION for compatibility + * + * Trivial Changes: + * Rights granted to Hans Reiser to redistribute under other terms providing + * he accepts all liability including but not limited to patent, fitness + * for purpose, and direct or indirect claims arising from failure to perform. + * + * NO WARRANTY */ #ifdef __KERNEL__ #include <linux/config.h> #include <linux/sched.h> +#include <linux/bitops.h> #include <linux/reiserfs_fs.h> #include <linux/smp_lock.h> @@ -472,7 +482,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in if (buffer != small_buf) reiserfs_kfree (buffer, buflen, dir->i_sb); pathrelse (&path); - return -EHASHCOLLISION;//EBADSLT + return -EBUSY; //HASHCOLLISION;//EBADSLT } /* adjust offset of directory enrty */ deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (deh_offset (deh), gen_number)); @@ -485,7 +495,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in if (buffer != small_buf) reiserfs_kfree (buffer, buflen, dir->i_sb); pathrelse (&path); - return -EHASHCOLLISION; + return -EBUSY; } } else { deh->deh_offset = cpu_to_le32 (SET_GENERATION_NUMBER (le32_to_cpu (deh->deh_offset), 0)); diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index 25da132b6..f8153be3b 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c @@ -92,7 +92,7 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod /* Move bytes from the direct items to the new unformatted node and delete them. */ while (1) { - int item_len, first_direct; + int tail_size; /* end_key.k_offset is set so, that we will always have found last item of the file */ @@ -103,13 +103,11 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod #ifdef CONFIG_REISERFS_CHECK if (!is_direct_le_ih (p_le_ih)) reiserfs_panic (sb, "vs-14055: direct2indirect: " - "direct item expected, found %h", p_le_ih); + "direct item expected(%k), found %h", + &end_key, p_le_ih); #endif - if ((le_ih_k_offset (p_le_ih) & (n_blk_size - 1)) == 1) - first_direct = 1; - else - first_direct = 0; - item_len = le16_to_cpu (p_le_ih->ih_item_len); + tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1)) + + ih_item_len(p_le_ih) - 1; /* we only send the unbh pointer if the buffer is not up to date. ** this avoids overwriting good data from writepage() with old data @@ -123,7 +121,7 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod n_retval = reiserfs_delete_item (th, path, &end_key, inode, up_to_date_bh) ; - if (first_direct && item_len == n_retval) + if (tail_size == n_retval) // done: file does not have direct items anymore break; diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 76c811852..7edadf2ac 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -67,7 +67,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/romfs_fs.h> #include <linux/fs.h> #include <linux/locks.h> diff --git a/fs/select.c b/fs/select.c index 975013e7f..cf7459d3e 100644 --- a/fs/select.c +++ b/fs/select.c @@ -14,7 +14,7 @@ * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian). */ -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/smp_lock.h> #include <linux/poll.h> #include <linux/file.h> diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog index a57b1cc67..6ceae2331 100644 --- a/fs/smbfs/ChangeLog +++ b/fs/smbfs/ChangeLog @@ -1,5 +1,14 @@ ChangeLog for smbfs. +2001-02-10 Urban Widmark <urban@teststation.com> + + * dir.c: replace non-bigmem safe cache with cache code from ncpfs + and fix some other bigmem bugs in smbfs. + * inode.c: root dentry not properly initialized + * proc.c, sock.c: adjust max parameters & max data to follow max_xmit + lots of servers were having find_next trouble with this. + * proc.c: use documented write method of truncating (NetApp fix) + 2000-08-14 Urban Widmark <urban@svenskatest.se> * dir.c: support case sensitive shares @@ -31,7 +40,7 @@ ChangeLog for smbfs. * *.c: replace ugly #ifdef's with less ugly debug macros. -2000-01-?? cpg@aladdin.de +2000-01-03 Christian Groessler <cpg@aladdin.de> * proc.c: added posix semantics for unlink diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile index db76849be..16e8ceb15 100644 --- a/fs/smbfs/Makefile +++ b/fs/smbfs/Makefile @@ -20,5 +20,6 @@ EXTRA_CFLAGS += -DSMBFS_PARANOIA #EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE #EXTRA_CFLAGS += -DDEBUG_SMB_MALLOC #EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP +#EXTRA_CFLAGS += -Werror include $(TOPDIR)/Rules.make diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c index aa85680ac..e3e9c044f 100644 --- a/fs/smbfs/cache.c +++ b/fs/smbfs/cache.c @@ -4,8 +4,7 @@ * Copyright (C) 1997 by Bill Hawes * * Routines to support directory cacheing using the page cache. - * Right now this only works for smbfs, but will be generalized - * for use with other filesystems. + * This cache code is almost directly taken from ncpfs. * * Please add a note about your changes to smbfs in the ChangeLog file. */ @@ -22,271 +21,222 @@ #include "smb_debug.h" - -static inline struct address_space * -get_cache_inode(struct cache_head *cachep) -{ - return page_cache_entry((unsigned long) cachep)->mapping; -} - /* - * Try to reassemble the old dircache. If we fail - set ->valid to 0. - * In any case, get at least the page at offset 0 (with ->valid==0 if - * the old one didn't make it, indeed). + * Force the next attempt to use the cache to be a timeout. + * If we can't find the page that's fine, it will cause a refresh. */ -struct cache_head * -smb_get_dircache(struct dentry * dentry) +void +smb_invalid_dir_cache(struct inode * dir) { - struct address_space * mapping = &dentry->d_inode->i_data; - struct cache_head * cachep = NULL; - struct page *page; + struct smb_sb_info *server = server_from_inode(dir); + union smb_dir_cache *cache = NULL; + struct page *page = NULL; - page = find_lock_page(mapping, 0); - if (!page) { - /* Sorry, not even page 0 around */ - page = grab_cache_page(mapping, 0); - if (!page) - goto out; - cachep = kmap(page); - memset((char*)cachep, 0, PAGE_SIZE); + page = grab_cache_page(&dir->i_data, 0); + if (!page) goto out; - } - cachep = kmap(page); - if (cachep->valid) { - /* - * OK, at least the page 0 survived and seems to be promising. - * Let's try to reassemble the rest. - */ - struct cache_index * index = cachep->index; - unsigned long offset; - int i; - for (offset = 0, i = 0; i < cachep->pages; i++, index++) { - offset += PAGE_SIZE; - page = find_lock_page(mapping,offset>>PAGE_CACHE_SHIFT); - if (!page) { - /* Alas, poor Yorick */ - cachep->valid = 0; - goto out; - } - index->block = kmap(page); - } - } -out: - return cachep; -} - -/* - * Unlock and release the data blocks. - */ -static void -smb_free_cache_blocks(struct cache_head * cachep) -{ - struct cache_index * index = cachep->index; - struct page * page; - int i; + if (!Page_Uptodate(page)) + goto out_unlock; - VERBOSE("freeing %d blocks\n", cachep->pages); - for (i = 0; i < cachep->pages; i++, index++) { - if (!index->block) - continue; - page = page_cache_entry((unsigned long) index->block); - index->block = NULL; - kunmap(page); - UnlockPage(page); - page_cache_release(page); - } -} + cache = kmap(page); + cache->head.time = jiffies - SMB_MAX_AGE(server); -/* - * Unlocks and releases the dircache. - */ -void -smb_free_dircache(struct cache_head * cachep) -{ - struct page *page; - VERBOSE("freeing cache\n"); - smb_free_cache_blocks(cachep); - page = page_cache_entry((unsigned long) cachep); kunmap(page); + SetPageUptodate(page); +out_unlock: UnlockPage(page); page_cache_release(page); +out: } /* - * Initializes the dircache. We release any existing data blocks, - * and then clear the cache_head structure. + * Mark all dentries for 'parent' as invalid, forcing them to be re-read */ void -smb_init_dircache(struct cache_head * cachep) +smb_invalidate_dircache_entries(struct dentry *parent) { - VERBOSE("initializing cache, %d blocks\n", cachep->pages); - smb_free_cache_blocks(cachep); - memset(cachep, 0, sizeof(struct cache_head)); + struct smb_sb_info *server = server_from_dentry(parent); + struct list_head *next; + struct dentry *dentry; + + spin_lock(&dcache_lock); + next = parent->d_subdirs.next; + while (next != &parent->d_subdirs) { + dentry = list_entry(next, struct dentry, d_child); + dentry->d_fsdata = NULL; + smb_age_dentry(server, dentry); + next = next->next; + } + spin_unlock(&dcache_lock); } -/* - * Add a new entry to the cache. This assumes that the - * entries are coming in order and are added to the end. - */ -void -smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry, - off_t fpos) -{ - struct address_space * mapping = get_cache_inode(cachep); - struct cache_index * index; - struct cache_block * block; - struct page *page; - unsigned long page_off; - unsigned int nent, offset, len = entry->len; - unsigned int needed = len + sizeof(struct cache_entry); - - VERBOSE("cache %p, status %d, adding %.*s at %ld\n", - mapping, cachep->status, entry->len, entry->name, fpos); +static int +smb_d_validate(struct dentry *dentry) +{ + unsigned long dent_addr = (unsigned long) dentry; + unsigned long min_addr = PAGE_OFFSET; + unsigned long align_mask = 0x0F; + unsigned int len; + int valid = 0; + + if (dent_addr < min_addr) + goto bad_addr; + if (dent_addr > (unsigned long)high_memory - sizeof(struct dentry)) + goto bad_addr; + if ((dent_addr & ~align_mask) != dent_addr) + goto bad_align; + if ((!kern_addr_valid(dent_addr)) || (!kern_addr_valid(dent_addr -1 + + sizeof(struct dentry)))) + goto bad_addr; /* - * Don't do anything if we've had an error ... + * Looks safe enough to dereference ... */ - if (cachep->status) + len = dentry->d_name.len; + if (len > SMB_MAXPATHLEN) goto out; - - index = &cachep->index[cachep->idx]; - if (!index->block) - goto get_block; - - /* space available? */ - if (needed < index->space) { - add_entry: - nent = index->num_entries; - index->num_entries++; - index->space -= needed; - offset = index->space + - index->num_entries * sizeof(struct cache_entry); - block = index->block; - memcpy(&block->cb_data.names[offset], entry->name, len); - block->cb_data.table[nent].namelen = len; - block->cb_data.table[nent].offset = offset; - block->cb_data.table[nent].ino = entry->ino; - cachep->entries++; - - VERBOSE("added entry %.*s, len=%d, pos=%ld, entries=%d\n", - entry->len, entry->name, len, fpos, cachep->entries); - return; - } /* - * This block is full ... advance the index. + * Note: d_validate doesn't dereference the parent pointer ... + * just combines it with the name hash to find the hash chain. */ - cachep->idx++; - if (cachep->idx > NINDEX) /* not likely */ - goto out_full; - index++; - /* - * Get the next cache block. We don't care for its contents. - */ -get_block: - cachep->pages++; - page_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT); - page = grab_cache_page(mapping, page_off>>PAGE_CACHE_SHIFT); - if (page) { - block = kmap(page); - index->block = block; - index->space = PAGE_SIZE; - goto add_entry; - } - /* - * On failure, just set the return status ... - */ -out_full: - cachep->status = -ENOMEM; + valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len); out: - return; + return valid; + +bad_addr: + printk(KERN_ERR "smb_d_validate: invalid address %lx\n", dent_addr); + goto out; +bad_align: + printk(KERN_ERR "smb_d_validate: unaligned address %lx\n", dent_addr); + goto out; } -int -smb_find_in_cache(struct cache_head * cachep, off_t pos, - struct cache_dirent *entry) +/* + * dget, but require that fpos and parent matches what the dentry contains. + * dentry is not known to be a valid pointer at entry. + */ +struct dentry * +smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) { - struct cache_index * index = cachep->index; - struct cache_block * block; - unsigned int i, nent, offset = 0; - off_t next_pos = 2; - - VERBOSE("smb_find_in_cache: cache %p, looking for pos=%ld\n", - cachep, pos); - for (i = 0; i < cachep->pages; i++, index++) - { - if (pos < next_pos) - break; - nent = pos - next_pos; - next_pos += index->num_entries; - if (pos >= next_pos) - continue; - /* - * The entry is in this block. Note: we return - * then name as a reference with _no_ null byte. - */ - block = index->block; - entry->ino = block->cb_data.table[nent].ino; - entry->len = block->cb_data.table[nent].namelen; - offset = block->cb_data.table[nent].offset; - entry->name = &block->cb_data.names[offset]; + struct dentry *dent = dentry; + struct list_head *next; + + if (smb_d_validate(dent)) { + if (dent->d_parent == parent && + (unsigned long)dent->d_fsdata == fpos) { + if (!dent->d_inode) { + dput(dent); + dent = NULL; + } + return dent; + } + dput(dent); + } - VERBOSE("found %.*s, len=%d, pos=%ld\n", - entry->len, entry->name, entry->len, pos); - break; + /* If a pointer is invalid, we search the dentry. */ + spin_lock(&dcache_lock); + next = parent->d_subdirs.next; + while (next != &parent->d_subdirs) { + dent = list_entry(next, struct dentry, d_child); + if ((unsigned long)dent->d_fsdata == fpos) { + if (dent->d_inode) + dget_locked(dent); + else + dent = NULL; + goto out_unlock; + } + next = next->next; } - return offset; + dent = NULL; +out_unlock: + spin_unlock(&dcache_lock); + return dent; } + +/* + * Create dentry/inode for this file and add it to the dircache. + */ int -smb_refill_dircache(struct cache_head * cachep, struct dentry *dentry) +smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + struct smb_cache_control *ctrl, struct qstr *qname, + struct smb_fattr *entry) { - struct inode * inode = dentry->d_inode; - int result; + struct dentry *newdent, *dentry = filp->f_dentry; + struct inode *newino, *inode = dentry->d_inode; + struct smb_cache_control ctl = *ctrl; + int valid = 0; + ino_t ino = 0; + + qname->hash = full_name_hash(qname->name, qname->len); + + if (dentry->d_op && dentry->d_op->d_hash) + if (dentry->d_op->d_hash(dentry, qname) != 0) + goto end_advance; + + newdent = d_lookup(dentry, qname); + + if (!newdent) { + newdent = d_alloc(dentry, qname); + if (!newdent) + goto end_advance; + } else + memcpy((char *) newdent->d_name.name, qname->name, + newdent->d_name.len); + + if (!newdent->d_inode) { + smb_renew_times(newdent); + entry->f_ino = iunique(inode->i_sb, 2); + newino = smb_iget(inode->i_sb, entry); + if (newino) { + smb_new_dentry(newdent); + d_add(newdent, newino); + } + } else + smb_set_inode_attr(newdent->d_inode, entry); - VERBOSE("smb_refill_dircache: cache %s/%s, blocks=%d\n", - DENTRY_PATH(dentry), cachep->pages); - /* - * Fill the cache, starting at position 2. - */ -retry: - inode->u.smbfs_i.cache_valid |= SMB_F_CACHEVALID; - result = smb_proc_readdir(dentry, 2, cachep); - if (result < 0) - { - PARANOIA("readdir failed, result=%d\n", result); - goto out; + if (newdent->d_inode) { + ino = newdent->d_inode->i_ino; + newdent->d_fsdata = (void *) ctl.fpos; + smb_new_dentry(newdent); } - /* - * Check whether the cache was invalidated while - * we were doing the scan ... - */ - if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID)) - { - PARANOIA("cache invalidated, retrying\n"); - goto retry; + if (ctl.idx >= SMB_DIRCACHE_SIZE) { + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + } + ctl.cache = NULL; + ctl.idx -= SMB_DIRCACHE_SIZE; + ctl.ofs += 1; + ctl.page = grab_cache_page(&inode->i_data, ctl.ofs); + if (ctl.page) + ctl.cache = kmap(ctl.page); } - - result = cachep->status; - if (!result) - { - cachep->valid = 1; + if (ctl.cache) { + ctl.cache->dentry[ctl.idx] = newdent; + valid = 1; } - VERBOSE("cache %s/%s status=%d, entries=%d\n", - DENTRY_PATH(dentry), cachep->status, cachep->entries); -out: - return result; -} - -void -smb_invalid_dir_cache(struct inode * dir) -{ - /* - * Get rid of any unlocked pages, and clear the - * 'valid' flag in case a scan is in progress. - */ - invalidate_inode_pages(dir); - dir->u.smbfs_i.cache_valid &= ~SMB_F_CACHEVALID; - dir->u.smbfs_i.oldmtime = 0; + dput(newdent); + +end_advance: + if (!valid) + ctl.valid = 0; + if (!ctl.filled && (ctl.fpos == filp->f_pos)) { + if (!ino) + ino = find_inode_number(dentry, qname); + if (!ino) + ino = iunique(inode->i_sb, 2); + ctl.filled = filldir(dirent, qname->name, qname->len, + filp->f_pos, ino, DT_UNKNOWN); + if (!ctl.filled) + filp->f_pos += 1; + } + ctl.fpos += 1; + ctl.idx += 1; + *ctrl = ctl; + return (ctl.valid || !ctl.filled); } diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 7b62899c1..ba7aa95f1 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -19,8 +19,6 @@ #include "smb_debug.h" -#define SMBFS_MAX_AGE 5*HZ - static int smb_readdir(struct file *, void *, filldir_t); static int smb_dir_open(struct inode *, struct file *); @@ -52,27 +50,39 @@ struct inode_operations smb_dir_inode_operations = setattr: smb_notify_change, }; +/* + * Read a directory, using filldir to fill the dirent memory. + * smb_proc_readdir does the actual reading from the smb server. + * + * The cache code is almost directly taken from ncpfs + */ static int smb_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; struct inode *dir = dentry->d_inode; - struct cache_head *cachep; + struct smb_sb_info *server = server_from_dentry(dentry); + union smb_dir_cache *cache = NULL; + struct smb_cache_control ctl; + struct page *page = NULL; int result; + ctl.page = NULL; + ctl.cache = NULL; + VERBOSE("reading %s/%s, f_pos=%d\n", DENTRY_PATH(dentry), (int) filp->f_pos); result = 0; - switch ((unsigned int) filp->f_pos) - { + switch ((unsigned int) filp->f_pos) { case 0: if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) goto out; filp->f_pos = 1; + /* fallthrough */ case 1: if (filldir(dirent, "..", 2, 1, - dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) + dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) goto out; filp->f_pos = 2; } @@ -83,61 +93,119 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir) result = smb_revalidate_inode(dentry); if (result) goto out; - /* - * Get the cache pointer ... - */ - result = -EIO; - cachep = smb_get_dircache(dentry); - if (!cachep) - goto out; - /* - * Make sure the cache is up-to-date. - * - * To detect changes on the server we refill on each "new" access. - * - * Directory mtime would be nice to use for finding changes, - * unfortunately some servers (NT4) doesn't update on local changes. - */ - if (!cachep->valid || filp->f_pos == 2) - { - result = smb_refill_dircache(cachep, dentry); - if (result) - goto out_free; - } - result = 0; + page = grab_cache_page(&dir->i_data, 0); + if (!page) + goto read_really; - while (1) - { - struct cache_dirent this_dirent, *entry = &this_dirent; + ctl.cache = cache = kmap(page); + ctl.head = cache->head; + + if (!Page_Uptodate(page) || !ctl.head.eof) { + VERBOSE("%s/%s, page uptodate=%d, eof=%d\n", + DENTRY_PATH(dentry), Page_Uptodate(page),ctl.head.eof); + goto init_cache; + } + + if (filp->f_pos == 2) { + if (jiffies - ctl.head.time >= SMB_MAX_AGE(server)) + goto init_cache; - if (!smb_find_in_cache(cachep, filp->f_pos, entry)) - break; /* - * Check whether to look up the inode number. + * N.B. ncpfs checks mtime of dentry too here, we don't. + * 1. common smb servers do not update mtime on dir changes + * 2. it requires an extra smb request + * (revalidate has the same timeout as ctl.head.time) + * + * Instead smbfs invalidates its own cache on local changes + * and remote changes are not seen until timeout. */ - if (!entry->ino) { - struct qstr qname; - /* N.B. Make cache_dirent name a qstr! */ - qname.name = entry->name; - qname.len = entry->len; - entry->ino = find_inode_number(dentry, &qname); - if (!entry->ino) - entry->ino = iunique(dentry->d_sb, 2); - } - - if (filldir(dirent, entry->name, entry->len, - filp->f_pos, entry->ino, DT_UNKNOWN) < 0) - break; - filp->f_pos += 1; } - /* - * Release the dircache. - */ -out_free: - smb_free_dircache(cachep); + if (filp->f_pos > ctl.head.end) + goto finished; + + ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2); + ctl.ofs = ctl.fpos / SMB_DIRCACHE_SIZE; + ctl.idx = ctl.fpos % SMB_DIRCACHE_SIZE; + + for (;;) { + if (ctl.ofs != 0) { + ctl.page = find_lock_page(&dir->i_data, ctl.ofs); + if (!ctl.page) + goto invalid_cache; + ctl.cache = kmap(ctl.page); + if (!Page_Uptodate(ctl.page)) + goto invalid_cache; + } + while (ctl.idx < SMB_DIRCACHE_SIZE) { + struct dentry *dent; + int res; + + dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx], + dentry, filp->f_pos); + if (!dent) + goto invalid_cache; + + res = filldir(dirent, dent->d_name.name, + dent->d_name.len, filp->f_pos, + dent->d_inode->i_ino, DT_UNKNOWN); + dput(dent); + if (res) + goto finished; + filp->f_pos += 1; + ctl.idx += 1; + if (filp->f_pos > ctl.head.end) + goto finished; + } + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + ctl.page = NULL; + } + ctl.idx = 0; + ctl.ofs += 1; + } +invalid_cache: + if (ctl.page) { + kunmap(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + ctl.page = NULL; + } + ctl.cache = cache; +init_cache: + smb_invalidate_dircache_entries(dentry); + ctl.head.time = jiffies; + ctl.head.eof = 0; + ctl.fpos = 2; + ctl.ofs = 0; + ctl.idx = SMB_DIRCACHE_START; + ctl.filled = 0; + ctl.valid = 1; +read_really: + result = smb_proc_readdir(filp, dirent, filldir, &ctl); + if (ctl.idx == -1) + goto invalid_cache; /* retry */ + ctl.head.end = ctl.fpos - 1; + ctl.head.eof = ctl.valid; +finished: + if (page) { + cache->head = ctl.head; + kunmap(page); + SetPageUptodate(page); + UnlockPage(page); + page_cache_release(page); + } + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + UnlockPage(ctl.page); + page_cache_release(ctl.page); + } out: return result; } @@ -204,16 +272,17 @@ static struct dentry_operations smbfs_dentry_operations_case = static int smb_lookup_validate(struct dentry * dentry, int flags) { + struct smb_sb_info *server = server_from_dentry(dentry); struct inode * inode = dentry->d_inode; unsigned long age = jiffies - dentry->d_time; int valid; /* * The default validation is based on dentry age: - * we believe in dentries for 5 seconds. (But each + * we believe in dentries for a few seconds. (But each * successful server lookup renews the timestamp.) */ - valid = (age <= SMBFS_MAX_AGE); + valid = (age <= SMB_MAX_AGE(server)); #ifdef SMBFS_DEBUG_VERBOSE if (!valid) VERBOSE("%s/%s not valid, age=%lu\n", @@ -286,6 +355,22 @@ smb_delete_dentry(struct dentry * dentry) } /* + * Initialize a new dentry + */ +void +smb_new_dentry(struct dentry *dentry) +{ + struct smb_sb_info *server = server_from_dentry(dentry); + + if (server->mnt->flags & SMB_MOUNT_CASE) + dentry->d_op = &smbfs_dentry_operations_case; + else + dentry->d_op = &smbfs_dentry_operations; + dentry->d_time = jiffies; +} + + +/* * Whenever a lookup succeeds, we know the parent directories * are all valid, so we want to update the dentry timestamps. * N.B. Move this to dcache? @@ -441,6 +526,7 @@ smb_rmdir(struct inode *dir, struct dentry *dentry) if (!d_unhashed(dentry)) goto out; + smb_invalid_dir_cache(dir); error = smb_proc_rmdir(dentry); out: @@ -457,6 +543,7 @@ smb_unlink(struct inode *dir, struct dentry *dentry) */ smb_close(dentry->d_inode); + smb_invalid_dir_cache(dir); error = smb_proc_unlink(dentry); if (!error) smb_renew_times(dentry); diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 0a95735fd..dfc370f20 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -13,7 +13,7 @@ #include <linux/fcntl.h> #include <linux/stat.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/smp_lock.h> @@ -38,7 +38,7 @@ smb_fsync(struct file *file, struct dentry * dentry, int datasync) static int smb_readpage_sync(struct dentry *dentry, struct page *page) { - char *buffer = page_address(page); + char *buffer = kmap(page); unsigned long offset = page->index << PAGE_CACHE_SHIFT; int rsize = smb_get_rsize(server_from_dentry(dentry)); int count = PAGE_SIZE; @@ -76,6 +76,7 @@ smb_readpage_sync(struct dentry *dentry, struct page *page) result = 0; io_error: + kunmap(page); UnlockPage(page); return result; } @@ -89,8 +90,6 @@ smb_readpage(struct file *file, struct page *page) int error; struct dentry *dentry = file->f_dentry; - DEBUG1("readpage %p\n", page_address(page)); - get_page(page); error = smb_readpage_sync(dentry, page); put_page(page); @@ -105,7 +104,7 @@ static int smb_writepage_sync(struct inode *inode, struct page *page, unsigned long offset, unsigned int count) { - u8 *buffer = page_address(page) + offset; + char *buffer = kmap(page) + offset; int wsize = smb_get_wsize(server_from_inode(inode)); int result, written = 0; @@ -139,8 +138,10 @@ smb_writepage_sync(struct inode *inode, struct page *page, inode->i_mtime = inode->i_atime = CURRENT_TIME; if (offset > inode->i_size) inode->i_size = offset; - inode->u.smbfs_i.cache_valid |= SMB_F_LOCALWRITE; + inode->u.smbfs_i.flags |= SMB_F_LOCALWRITE; } while (count); + + kunmap(page); return written ? written : result; } diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index e502fb60b..40ee12566 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -16,7 +16,7 @@ #include <linux/stat.h> #include <linux/errno.h> #include <linux/locks.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/file.h> #include <linux/dcache.h> @@ -43,7 +43,6 @@ static void smb_delete_inode(struct inode *); static void smb_put_super(struct super_block *); static int smb_statfs(struct super_block *, struct statfs *); -static void smb_set_inode_attr(struct inode *, struct smb_fattr *); static struct super_operations smb_sops = { @@ -110,7 +109,7 @@ smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr) fattr->attr |= aRONLY; } -static void +void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) { inode->i_mode = fattr->f_mode; @@ -125,8 +124,7 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) * Don't change the size and mtime/atime fields * if we're writing to the file. */ - if (!(inode->u.smbfs_i.cache_valid & SMB_F_LOCALWRITE)) - { + if (!(inode->u.smbfs_i.flags & SMB_F_LOCALWRITE)) { inode->i_size = fattr->f_size; inode->i_mtime = fattr->f_mtime; inode->i_atime = fattr->f_atime; @@ -211,6 +209,7 @@ smb_refresh_inode(struct dentry *dentry) int smb_revalidate_inode(struct dentry *dentry) { + struct smb_sb_info *s = server_from_dentry(dentry); struct inode *inode = dentry->d_inode; time_t last_time; int error = 0; @@ -221,8 +220,7 @@ smb_revalidate_inode(struct dentry *dentry) * the inode will be up-to-date. */ lock_kernel(); - if (S_ISREG(inode->i_mode) && smb_is_open(inode)) - { + if (S_ISREG(inode->i_mode) && smb_is_open(inode)) { if (inode->u.smbfs_i.access != SMB_O_RDONLY) goto out; } @@ -230,10 +228,9 @@ smb_revalidate_inode(struct dentry *dentry) /* * Check whether we've recently refreshed the inode. */ - if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10)) - { - VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n", - jiffies, inode->u.smbfs_i.oldmtime); + if (time_before(jiffies, inode->u.smbfs_i.oldmtime + SMB_MAX_AGE(s))) { + VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n", + inode->i_ino, jiffies, inode->u.smbfs_i.oldmtime); goto out; } @@ -243,16 +240,13 @@ smb_revalidate_inode(struct dentry *dentry) */ last_time = inode->i_mtime; error = smb_refresh_inode(dentry); - if (error || inode->i_mtime != last_time) - { + if (error || inode->i_mtime != last_time) { VERBOSE("%s/%s changed, old=%ld, new=%ld\n", DENTRY_PATH(dentry), (long) last_time, (long) inode->i_mtime); if (!S_ISDIR(inode->i_mode)) invalidate_inode_pages(inode); - else - smb_invalid_dir_cache(inode); } out: unlock_kernel(); @@ -287,6 +281,7 @@ struct option opts[] = { { "dir_mode", 1, 0, 'd' }, { "iocharset", 1, 0, 'i' }, { "codepage", 1, 0, 'c' }, + { "ttl", 1, 0, 't' }, { NULL, 0, 0, 0} }; @@ -339,6 +334,9 @@ parse_options(struct smb_mount_data_kernel *mnt, char *options) strncpy(mnt->codepage.remote_name, optarg, SMB_NLS_MAXNAMELEN); break; + case 't': + mnt->ttl = value; + break; default: printk ("smbfs: Unrecognized mount option %s\n", optopt); @@ -437,6 +435,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) strncpy(mnt->codepage.remote_name, SMB_NLS_REMOTE, SMB_NLS_MAXNAMELEN); + mnt->ttl = 1000; if (ver == SMB_MOUNT_OLDVERSION) { mnt->version = oldmnt->version; @@ -483,6 +482,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) goto out_no_root; + smb_new_dentry(sb->s_root); return sb; diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index f0444f97d..9bfdc90a0 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c @@ -9,7 +9,7 @@ #include <linux/types.h> #include <linux/errno.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/stat.h> @@ -78,6 +78,7 @@ str_upper(char *name, int len) } } +#if 0 static void str_lower(char *name, int len) { @@ -88,6 +89,7 @@ str_lower(char *name, int len) name++; } } +#endif /* reverse a string inline. This is used by the dircache walking routines */ static void reverse_string(char *buf, int len) @@ -358,6 +360,72 @@ date_unix2dos(struct smb_sb_info *server, *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9); } +/* The following are taken from fs/ntfs/util.c */ + +/* + * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) + * into Unix UTC (based 1970-01-01, in seconds). + * + * This is very gross because + * 1: We must do 64-bit division on a 32-bit machine + * 2: We can't use libgcc for long long operations in the kernel + * 3: Floating point math in the kernel would corrupt user data + */ +static time_t +smb_ntutc2unixutc(struct smb_sb_info *server, u64 ntutc) +{ + const unsigned int D = 10000000; + unsigned int H = (unsigned int)(ntutc >> 32); + unsigned int L = (unsigned int)ntutc; + unsigned int numerator2; + unsigned int lowseconds; + unsigned int result; + + /* + * It is best to subtract 0x019db1ded53e8000 first. + * Then the 1601-based date becomes a 1970-based date. + */ + if (L < (unsigned)0xd53e8000) H--; + L -= (unsigned)0xd53e8000; + H -= (unsigned)0x019db1de; + + /* + * Now divide 64-bit numbers on a 32-bit machine :-) + * With the subtraction already done, the result fits in 32 bits. + * The numerator fits in 56 bits and the denominator fits + * in 24 bits, so we can shift by 8 bits to make this work. + */ + + numerator2 = (H<<8) | (L>>24); + result = (numerator2 / D); /* shifted 24 right!! */ + lowseconds = result << 24; + + numerator2 = ((numerator2-result*D)<<8) | ((L>>16)&0xff); + result = (numerator2 / D); /* shifted 16 right!! */ + lowseconds |= result << 16; + + numerator2 = ((numerator2-result*D)<<8) | ((L>>8)&0xff); + result = (numerator2 / D); /* shifted 8 right!! */ + lowseconds |= result << 8; + + numerator2 = ((numerator2-result*D)<<8) | (L&0xff); + result = (numerator2 / D); /* not shifted */ + lowseconds |= result; + + return lowseconds; +} + +#if 0 +/* Convert the Unix UTC into NT time */ +static u64 +smb_unixutc2ntutc(struct smb_sb_info *server, time_t t) +{ + /* Note: timezone conversion is probably wrong. */ + return ((utc2local(server, t) + (u64)(369*365+89)*24*3600) * 10000000); +} +#endif + + /*****************************************************************************/ /* */ /* Support section. */ @@ -421,22 +489,16 @@ fail: } /* - * Returns the maximum read or write size for the current packet size - * and max_xmit value. + * Returns the maximum read or write size for the "payload". Making all of the + * packet fit within the negotiated max_xmit size. + * * N.B. Since this value is usually computed before locking the server, * the server's packet size must never be decreased! */ -static int +static inline int smb_get_xmitsize(struct smb_sb_info *server, int overhead) { - int size = server->packet_size; - - /* - * Start with the smaller of packet size and max_xmit ... - */ - if (size > server->opt.max_xmit) - size = server->opt.max_xmit; - return size - overhead; + return server->opt.max_xmit - overhead; } /* @@ -783,6 +845,23 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) server->opt.protocol, server->opt.max_xmit, server->conn_pid, server->opt.capabilities); + /* Make sure we can fit a message of the negotiated size in our + packet buffer. */ + if (server->opt.max_xmit > server->packet_size) { + int len = smb_round_length(server->opt.max_xmit); + char *buf = smb_vmalloc(len); + if (buf) { + server->packet = buf; + server->packet_size = len; + } else { + /* else continue with the too small buffer? */ + PARANOIA("Failed to allocate new packet buffer: " + "max_xmit=%d, packet_size=%d\n", + server->opt.max_xmit, server->packet_size); + server->opt.max_xmit = server->packet_size; + } + } + out: #ifdef SMB_RETRY_INTR wake_up_interruptible(&server->wait); @@ -1025,7 +1104,7 @@ smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino) result = smb_proc_close(server, ino->u.smbfs_i.fileid, ino->i_mtime); - ino->u.smbfs_i.cache_valid &= ~SMB_F_LOCALWRITE; + ino->u.smbfs_i.flags &= ~SMB_F_LOCALWRITE; /* * Force a revalidation after closing ... some servers * don't post the size until the file has been closed. @@ -1115,7 +1194,7 @@ smb_proc_read(struct inode *inode, off_t offset, int count, char *data) out: VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n", - inode->ino, inode->u.smbfs_i.fileid, count, result); + inode->i_ino, inode->u.smbfs_i.fileid, count, result); smb_unlock_server(server); return result; } @@ -1128,7 +1207,7 @@ smb_proc_write(struct inode *inode, off_t offset, int count, const char *data) __u8 *p; VERBOSE("ino=%ld, fileid=%d, count=%d@%ld, packet_size=%d\n", - inode->ino, inode->u.smbfs_i.fileid, count, offset, + inode->i_ino, inode->u.smbfs_i.fileid, count, offset, server->packet_size); smb_lock_server(server); @@ -1355,14 +1434,13 @@ smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length) smb_lock_server(server); retry: - p = smb_setup_header(server, SMBwrite, 5, 0); + p = smb_setup_header(server, SMBwrite, 5, 3); WSET(server->packet, smb_vwv0, fid); WSET(server->packet, smb_vwv1, 0); DSET(server->packet, smb_vwv2, length); WSET(server->packet, smb_vwv4, 0); - *p++ = 4; - *p++ = 0; - smb_setup_bcc(server, p); + *p++ = 1; + WSET(p, 0, 0); if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) { if (smb_retry(server)) @@ -1419,38 +1497,47 @@ smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr) } /* - * Note that we are now returning the name as a reference to avoid - * an extra copy, and that the upper/lower casing is done in place. + * Decode a dirent for old protocols + * + * qname is filled with the decoded, and possibly translated, name. + * fattr receives decoded attributes * * Bugs Noted: * (1) Pathworks servers may pad the name with extra spaces. */ -static __u8 * -smb_decode_dirent(struct smb_sb_info *server, __u8 *p, - struct cache_dirent *entry) +static char * +smb_decode_short_dirent(struct smb_sb_info *server, char *p, + struct qstr *qname, struct smb_fattr *fattr) { int len; /* * SMB doesn't have a concept of inode numbers ... */ - entry->ino = 0; + smb_init_dirent(server, fattr); + fattr->f_ino = 0; /* FIXME: do we need this? */ p += SMB_STATUS_SIZE; /* reserved (search_status) */ - entry->name = p + 9; - len = strlen(entry->name); - if (len > 12) - len = 12; + fattr->attr = *p; + fattr->f_mtime = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1)); + fattr->f_size = DVAL(p, 5); + fattr->f_ctime = fattr->f_mtime; + fattr->f_atime = fattr->f_mtime; + qname->name = p + 9; + len = strnlen(qname->name, 12); /* * Trim trailing blanks for Pathworks servers */ - while (len > 2 && entry->name[len-1] == ' ') + while (len > 2 && qname->name[len-1] == ' ') len--; - entry->len = len; + qname->len = len; + smb_finish_dirent(server, fattr); + +#if 0 /* FIXME: These only work for ascii chars, and recent smbmount doesn't - allow the flag to be set anyway. Remove? */ + allow the flag to be set anyway. It kills const. Remove? */ switch (server->opt.case_handling) { case SMB_CASE_UPPER: str_upper(entry->name, len); @@ -1461,24 +1548,31 @@ smb_decode_dirent(struct smb_sb_info *server, __u8 *p, default: break; } +#endif - entry->len = server->convert(server->name_buf, SMB_MAXNAMELEN, - entry->name, len, + qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN, + qname->name, len, server->remote_nls, server->local_nls); - entry->name = server->name_buf; + qname->name = server->name_buf; - DEBUG1("len=%d, name=%.*s\n", entry->len, entry->len, entry->name); + DEBUG1("len=%d, name=%.*s\n", qname->len, qname->len, qname->name); return p + 22; } -/* This routine is used to read in directory entries from the network. - Note that it is for short directory name seeks, i.e.: protocol < - SMB_PROTOCOL_LANMAN2 */ - +/* + * This routine is used to read in directory entries from the network. + * Note that it is for short directory name seeks, i.e.: protocol < + * SMB_PROTOCOL_LANMAN2 + */ static int -smb_proc_readdir_short(struct smb_sb_info *server, struct dentry *dir, int fpos, - void *cachep) +smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, + struct smb_cache_control *ctl) { + struct dentry *dir = filp->f_dentry; + struct smb_sb_info *server = server_from_dentry(dir); + struct qstr qname; + struct smb_fattr fattr; + unsigned char *p; int result; int i, first, entries_seen, entries; @@ -1489,13 +1583,10 @@ smb_proc_readdir_short(struct smb_sb_info *server, struct dentry *dir, int fpos, static struct qstr mask = { "*.*", 3, 0 }; unsigned char *last_status; - VERBOSE("%s/%s, pos=%d\n", DENTRY_PATH(dir), fpos); + VERBOSE("%s/%s\n", DENTRY_PATH(dir)); smb_lock_server(server); - /* N.B. We need to reinitialize the cache to restart */ -retry: - smb_init_dircache(cachep); first = 1; entries = 0; entries_seen = 2; /* implicit . and .. */ @@ -1530,8 +1621,10 @@ retry: if ((server->rcls == ERRDOS) && (server->err == ERRnofiles)) break; - if (smb_retry(server)) - goto retry; + if (smb_retry(server)) { + ctl->idx = -1; /* retry */ + result = 0; + } goto unlock_return; } p = SMB_VWV(server->packet); @@ -1568,23 +1661,18 @@ retry: /* Now we are ready to parse smb directory entries. */ for (i = 0; i < count; i++) { - struct cache_dirent this_ent, *entry = &this_ent; + p = smb_decode_short_dirent(server, p, + &qname, &fattr); - p = smb_decode_dirent(server, p, entry); - if (entries_seen == 2 && entry->name[0] == '.') { - if (entry->len == 1) + if (entries_seen == 2 && qname.name[0] == '.') { + if (qname.len == 1) continue; - if (entry->name[1] == '.' && entry->len == 2) + if (qname.name[1] == '.' && qname.len == 2) continue; } - if (entries_seen >= fpos) { - DEBUG1("fpos=%u\n", entries_seen); - smb_add_to_cache(cachep, entry, entries_seen); - entries++; - } else { - VERBOSE("skipped, seen=%d, i=%d, fpos=%d\n", - entries_seen, i, fpos); - } + if (!smb_fill_cache(filp, dirent, filldir, ctl, + &qname, &fattr)) + ; /* stop reading? */ entries_seen++; } } @@ -1600,44 +1688,69 @@ unlock_return: * level 1 for anything below NT1 protocol * level 260 for NT1 protocol * - * We return a reference to the name string to avoid copying, and perform - * any needed upper/lower casing in place. + * qname is filled with the decoded, and possibly translated, name + * fattr receives decoded attributes. * * Bugs Noted: * (1) Win NT 4.0 appends a null byte to names and counts it in the length! */ static char * -smb_decode_long_dirent(struct smb_sb_info *server, char *p, - struct cache_dirent *entry, int level) +smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level, + struct qstr *qname, struct smb_fattr *fattr) { char *result; unsigned int len = 0; + __u16 date, time; /* * SMB doesn't have a concept of inode numbers ... */ - entry->ino = 0; + smb_init_dirent(server, fattr); + fattr->f_ino = 0; /* FIXME: do we need this? */ switch (level) { case 1: len = *((unsigned char *) p + 22); - entry->name = p + 23; + qname->name = p + 23; result = p + 24 + len; + date = WVAL(p, 0); + time = WVAL(p, 2); + fattr->f_ctime = date_dos2unix(server, date, time); + + date = WVAL(p, 4); + time = WVAL(p, 6); + fattr->f_atime = date_dos2unix(server, date, time); + + date = WVAL(p, 8); + time = WVAL(p, 10); + fattr->f_mtime = date_dos2unix(server, date, time); + fattr->f_size = DVAL(p, 12); + /* ULONG allocation size */ + fattr->attr = WVAL(p, 20); + VERBOSE("info 1 at %p, len=%d, name=%.*s\n", - p, len, len, entry->name); + p, len, len, qname->name); break; case 260: result = p + WVAL(p, 0); len = DVAL(p, 60); if (len > 255) len = 255; /* NT4 null terminates */ - entry->name = p + 94; - if (len && entry->name[len-1] == '\0') + qname->name = p + 94; + if (len && qname->name[len-1] == '\0') len--; + fattr->f_ctime = smb_ntutc2unixutc(server, LVAL(p, 8)); + fattr->f_atime = smb_ntutc2unixutc(server, LVAL(p, 16)); + fattr->f_mtime = smb_ntutc2unixutc(server, LVAL(p, 24)); + /* change time (32) */ + fattr->f_size = DVAL(p, 40); + /* alloc size (48) */ + fattr->attr = DVAL(p, 56); + VERBOSE("info 260 at %p, len=%d, name=%.*s\n", - p, len, len, entry->name); + p, len, len, qname->name); break; default: PARANOIA("Unknown info level %d\n", level); @@ -1645,21 +1758,28 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, goto out; } + smb_finish_dirent(server, fattr); + +#if 0 + /* FIXME: These only work for ascii chars, and recent smbmount doesn't + allow the flag to be set anyway. Remove? */ switch (server->opt.case_handling) { case SMB_CASE_UPPER: - str_upper(entry->name, len); + str_upper(qname->name, len); break; case SMB_CASE_LOWER: - str_lower(entry->name, len); + str_lower(qname->name, len); break; default: break; } +#endif - entry->len = server->convert(server->name_buf, SMB_MAXNAMELEN, - entry->name, len, + qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN, + qname->name, len, server->remote_nls, server->local_nls); - entry->name = server->name_buf; + qname->name = server->name_buf; + out: return result; } @@ -1682,13 +1802,18 @@ out: * single file. (E.g. echo hi >foo breaks, rm -f foo works.) */ static int -smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos, - void *cachep) +smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, + struct smb_cache_control *ctl) { - unsigned char *p; - char *mask, *lastname, *param = server->temp_buf; + struct dentry *dir = filp->f_dentry; + struct smb_sb_info *server = server_from_dentry(dir); + struct qstr qname; + struct smb_fattr fattr; + + unsigned char *p, *lastname; + char *mask, *param = server->temp_buf; __u16 command; - int first, entries, entries_seen; + int first, entries_seen; /* Both NT and OS/2 accept info level 1 (but see note below). */ int info_level = 260; @@ -1714,7 +1839,6 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos, smb_lock_server(server); -retry: /* * Encode the initial path */ @@ -1722,17 +1846,13 @@ retry: mask_len = smb_encode_path(server, mask, dir, &star); if (mask_len < 0) { - entries = mask_len; + result = mask_len; goto unlock_return; } first = 1; - VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask); + VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask); - /* - * We must reinitialize the dircache when retrying. - */ - smb_init_dircache(cachep); - entries = 0; + result = 0; entries_seen = 2; ff_eos = 0; @@ -1741,7 +1861,7 @@ retry: if (loop_count > 10) { printk(KERN_WARNING "smb_proc_readdir_long: " "Looping in FIND_NEXT??\n"); - entries = -EIO; + result = -EIO; break; } @@ -1773,10 +1893,11 @@ retry: if (result < 0) { if (smb_retry(server)) { PARANOIA("error=%d, retrying\n", result); - goto retry; + ctl->idx = -1; /* retry */ + result = 0; + goto unlock_return; } PARANOIA("error=%d, breaking\n", result); - entries = result; break; } @@ -1788,10 +1909,10 @@ retry: continue; } - if (server->rcls != 0) { - PARANOIA("name=%s, entries=%d, rcls=%d, err=%d\n", - mask, entries, server->rcls, server->err); - entries = -smb_errno(server); + if (server->rcls != 0) { + result = -smb_errno(server); + PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n", + mask, result, server->rcls, server->err); break; } @@ -1810,41 +1931,44 @@ retry: if (ff_searchcount == 0) break; - /* we might need the lastname for continuations */ + /* + * We might need the lastname for continuations. + * + * Note that some servers (win95?) point to the filename and + * others (NT4, Samba using NT1) to the dir entry. We assume + * here that those who do not point to a filename do not need + * this info to continue the listing. OS/2 needs this, but it + * talks "infolevel 1" + */ mask_len = 0; - if (ff_lastname > 0) { + if (info_level == 1 && ff_lastname > 0 && + ff_lastname < resp_data_len) { lastname = resp_data + ff_lastname; - switch (info_level) { - case 260: - if (ff_lastname < resp_data_len) - mask_len = resp_data_len - ff_lastname; - break; - case 1: - /* Win NT 4.0 doesn't set the length byte */ - lastname++; - if (ff_lastname + 2 < resp_data_len) - mask_len = strlen(lastname); - break; - } + + /* lastname points to a length byte */ + mask_len = *lastname++; + if (ff_lastname + 1 + mask_len > resp_data_len) + mask_len = resp_data_len-ff_lastname-1; + /* * Update the mask string for the next message. */ + if (mask_len < 0) + mask_len = 0; if (mask_len > 255) mask_len = 255; if (mask_len) strncpy(mask, lastname, mask_len); } - mask[mask_len] = 0; - VERBOSE("new mask, len=%d@%d, mask=%s\n", - mask_len, ff_lastname, mask); + mask_len = strnlen(mask, mask_len); + VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n", + mask_len, ff_lastname, resp_data_len, mask_len, mask); /* Now we are ready to parse smb directory entries. */ /* point to the data bytes */ p = resp_data; for (i = 0; i < ff_searchcount; i++) { - struct cache_dirent this_ent, *entry = &this_ent; - /* make sure we stay within the buffer */ if (p >= resp_data + resp_data_len) { printk(KERN_ERR "smb_proc_readdir_long: " @@ -1856,21 +1980,21 @@ retry: goto unlock_return; } - p = smb_decode_long_dirent(server, p, entry, - info_level); + p = smb_decode_long_dirent(server, p, info_level, + &qname, &fattr); /* ignore . and .. from the server */ - if (entries_seen == 2 && entry->name[0] == '.') { - if (entry->len == 1) + if (entries_seen == 2 && qname.name[0] == '.') { + if (qname.len == 1) continue; - if (entry->name[1] == '.' && entry->len == 2) + if (qname.name[1] == '.' && qname.len == 2) continue; } - if (entries_seen >= fpos) { - smb_add_to_cache(cachep, entry, entries_seen); - entries += 1; - } - entries_seen++; + + if (!smb_fill_cache(filp, dirent, filldir, ctl, + &qname, &fattr)) + ; /* stop reading? */ + entries_seen++; } VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos); @@ -1881,19 +2005,19 @@ retry: unlock_return: smb_unlock_server(server); - return entries; + return result; } int -smb_proc_readdir(struct dentry *dir, int fpos, void *cachep) +smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir, + struct smb_cache_control *ctl) { - struct smb_sb_info *server; + struct smb_sb_info *server = server_from_dentry(filp->f_dentry); - server = server_from_dentry(dir); if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) - return smb_proc_readdir_long(server, dir, fpos, cachep); + return smb_proc_readdir_long(filp, dirent, filldir, ctl); else - return smb_proc_readdir_short(server, dir, fpos, cachep); + return smb_proc_readdir_short(filp, dirent, filldir, ctl); } /* diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index cb1e697fc..6bad6d304 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -109,7 +109,7 @@ smb_data_callback(void* ptr) struct data_callback* job=ptr; struct socket *socket = job->sk->socket; unsigned char peek_buf[4]; - int result; + int result = 0; mm_segment_t fs; int count = 100; /* this is a lot, we should have some data waiting */ int found = 0; @@ -477,14 +477,12 @@ smb_receive_trans2(struct smb_sb_info *server, unsigned int total_p = 0, total_d = 0, buf_len = 0; int result; - while (1) - { + while (1) { result = smb_receive(server); if (result < 0) goto out; inbuf = server->packet; - if (server->rcls != 0) - { + if (server->rcls != 0) { *parm = *data = inbuf; *ldata = *lparm = 0; goto out; @@ -508,13 +506,11 @@ smb_receive_trans2(struct smb_sb_info *server, parm_len += parm_count; data_len += data_count; - if (!rcv_buf) - { + if (!rcv_buf) { /* * Check for fast track processing ... just this packet. */ - if (parm_count == parm_tot && data_count == data_tot) - { + if (parm_count == parm_tot && data_count == data_tot) { VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n", parm_disp, parm_offset, parm_count, data_disp, data_offset, data_count); @@ -523,10 +519,6 @@ smb_receive_trans2(struct smb_sb_info *server, goto success; } - if (parm_tot > TRANS2_MAX_TRANSFER || - data_tot > TRANS2_MAX_TRANSFER) - goto out_too_long; - /* * Save the total parameter and data length. */ @@ -537,14 +529,15 @@ smb_receive_trans2(struct smb_sb_info *server, if (server->packet_size > buf_len) buf_len = server->packet_size; buf_len = smb_round_length(buf_len); + if (buf_len > SMB_MAX_PACKET_SIZE) + goto out_too_long; rcv_buf = smb_vmalloc(buf_len); if (!rcv_buf) goto out_no_mem; *parm = rcv_buf; *data = rcv_buf + total_p; - } - else if (data_tot > total_d || parm_tot > total_p) + } else if (data_tot > total_d || parm_tot > total_p) goto out_data_grew; if (parm_disp + parm_count > total_p) @@ -571,8 +564,7 @@ smb_receive_trans2(struct smb_sb_info *server, * old one, in which case we just copy the data. */ inbuf = server->packet; - if (buf_len >= server->packet_size) - { + if (buf_len >= server->packet_size) { server->packet_size = buf_len; server->packet = rcv_buf; rcv_buf = inbuf; @@ -716,6 +708,7 @@ smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command, struct socket *sock = server_sock(server); struct scm_cookie scm; int err; + int mparam, mdata; /* I know the following is very ugly, but I want to build the smb packet as efficiently as possible. */ @@ -737,19 +730,30 @@ smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command, struct iovec iov[4]; struct msghdr msg; - /* N.B. This test isn't valid! packet_size may be < max_xmit */ + /* FIXME! this test needs to include SMB overhead too, I think ... */ if ((bcc + oparam) > server->opt.max_xmit) - { return -ENOMEM; - } p = smb_setup_header(server, SMBtrans2, smb_parameters, bcc); + /* + * max parameters + max data + max setup == max_xmit to make NT4 happy + * and not abort the transfer or split into multiple responses. + * + * -100 is to make room for headers, which OS/2 seems to include in the + * size calculation while NT4 does not? + */ + mparam = SMB_TRANS2_MAX_PARAM; + mdata = server->opt.max_xmit - mparam - 100; + if (mdata < 1024) { + mdata = 1024; + mparam = 20; + } + WSET(server->packet, smb_tpscnt, lparam); WSET(server->packet, smb_tdscnt, ldata); - /* N.B. these values should reflect out current packet size */ - WSET(server->packet, smb_mprcnt, TRANS2_MAX_TRANSFER); - WSET(server->packet, smb_mdrcnt, TRANS2_MAX_TRANSFER); - WSET(server->packet, smb_msrcnt, 0); + WSET(server->packet, smb_mprcnt, mparam); + WSET(server->packet, smb_mdrcnt, mdata); + WSET(server->packet, smb_msrcnt, 0); /* max setup always 0 ? */ WSET(server->packet, smb_flags, 0); DSET(server->packet, smb_timeout, 0); WSET(server->packet, smb_pscnt, lparam); @@ -781,8 +785,7 @@ smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command, iov[3].iov_len = ldata; err = scm_send(sock, &msg, &scm); - if (err >= 0) - { + if (err >= 0) { err = sock->ops->sendmsg(sock, &msg, packet_length, &scm); scm_destroy(&scm); } diff --git a/fs/super.c b/fs/super.c index 6262c7675..6482259ce 100644 --- a/fs/super.c +++ b/fs/super.c @@ -22,12 +22,13 @@ #include <linux/config.h> #include <linux/string.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/locks.h> #include <linux/smp_lock.h> #include <linux/devfs_fs_kernel.h> #include <linux/fd.h> #include <linux/init.h> +#include <linux/major.h> #include <linux/quotaops.h> #include <linux/acct.h> diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 9ec279e47..bf6d9988d 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -38,7 +38,7 @@ #include <linux/string.h> #include <linux/errno.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/udf_fs.h> #endif diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9cc2f3d29..c37d298fe 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -31,7 +31,7 @@ #include <linux/string.h> #include <linux/errno.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/quotaops.h> #include <linux/udf_fs.h> diff --git a/fs/udf/partition.c b/fs/udf/partition.c index dcdf7666c..a2c34d518 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -30,7 +30,7 @@ #include <linux/fs.h> #include <linux/string.h> #include <linux/udf_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset) { diff --git a/fs/udf/super.c b/fs/udf/super.c index f5e9b0b44..1e089c0b1 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -48,7 +48,7 @@ #include <linux/config.h> #include <linux/version.h> #include <linux/blkdev.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/kernel.h> #include <linux/locks.h> #include <linux/module.h> diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index be4e80165..caa2b7266 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -32,7 +32,7 @@ #include <linux/sched.h> #include <linux/mm.h> #include <linux/stat.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/smp_lock.h> #include "udf_i.h" diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 6d83d7c51..360291513 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -73,7 +73,7 @@ #include <linux/errno.h> #include <linux/fs.h> #include <linux/ufs_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/stat.h> #include <linux/string.h> diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 334e0efdb..54a0ab80f 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c @@ -7,7 +7,7 @@ */ #include <linux/string.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/locks.h> #include "swab.h" diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c index 2e0b7bb14..c4f28da77 100644 --- a/fs/umsdos/dir.c +++ b/fs/umsdos/dir.c @@ -15,7 +15,7 @@ #include <linux/stat.h> #include <linux/limits.h> #include <linux/umsdos_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <linux/pagemap.h> #define UMSDOS_SPECIAL_DIRFPOS 3 diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c index c29387f3c..560d3f5cd 100644 --- a/fs/umsdos/namei.c +++ b/fs/umsdos/namei.c @@ -20,7 +20,7 @@ #include <linux/string.h> #include <linux/msdos_fs.h> #include <linux/umsdos_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #define UMSDOS_DIR_LOCK diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c index ff208e6ac..e107a95f5 100644 --- a/fs/umsdos/rdir.c +++ b/fs/umsdos/rdir.c @@ -14,7 +14,7 @@ #include <linux/stat.h> #include <linux/limits.h> #include <linux/umsdos_fs.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include <asm/uaccess.h> diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 35c6529be..b8f8d6e1b 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -24,7 +24,7 @@ #include <linux/ctype.h> #include <linux/stat.h> #include <linux/mm.h> -#include <linux/malloc.h> +#include <linux/slab.h> #include "../fat/msbuffer.h" |