summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-03-09 20:33:35 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-03-09 20:33:35 +0000
commit116674acc97ba75a720329996877077d988443a2 (patch)
tree6a3f2ff0b612ae2ee8a3f3509370c9e6333a53b3 /fs
parent71118c319fcae4a138f16e35b4f7e0a6d53ce2ca (diff)
Merge with Linux 2.4.2.
Diffstat (limited to 'fs')
-rw-r--r--fs/adfs/super.c2
-rw-r--r--fs/affs/file.c2
-rw-r--r--fs/affs/inode.c2
-rw-r--r--fs/affs/super.c2
-rw-r--r--fs/autofs/autofs_i.h2
-rw-r--r--fs/autofs/inode.c2
-rw-r--r--fs/autofs/waitq.c2
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/waitq.c2
-rw-r--r--fs/binfmt_aout.c2
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/binfmt_em86.c2
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/binfmt_script.c2
-rw-r--r--fs/block_dev.c3
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/coda/cnode.c7
-rw-r--r--fs/coda/psdev.c2
-rw-r--r--fs/coda/sysctl.c2
-rw-r--r--fs/coda/upcall.c8
-rw-r--r--fs/dcache.c16
-rw-r--r--fs/devfs/base.c2
-rw-r--r--fs/devpts/inode.c2
-rw-r--r--fs/dquot.c5
-rw-r--r--fs/exec.c3
-rw-r--r--fs/ext2/namei.c1
-rw-r--r--fs/fat/buffer.c2
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/fifo.c2
-rw-r--r--fs/file.c2
-rw-r--r--fs/hfs/balloc.c2
-rw-r--r--fs/hfs/bdelete.c2
-rw-r--r--fs/hfs/bfind.c2
-rw-r--r--fs/hfs/bins_del.c2
-rw-r--r--fs/hfs/binsert.c2
-rw-r--r--fs/hfs/bitmap.c2
-rw-r--r--fs/hfs/bitops.c2
-rw-r--r--fs/hfs/bnode.c2
-rw-r--r--fs/hfs/brec.c2
-rw-r--r--fs/hfs/btree.c2
-rw-r--r--fs/hfs/catalog.c2
-rw-r--r--fs/hfs/dir.c2
-rw-r--r--fs/hfs/dir_cap.c2
-rw-r--r--fs/hfs/dir_dbl.c2
-rw-r--r--fs/hfs/dir_nat.c2
-rw-r--r--fs/hfs/extent.c2
-rw-r--r--fs/hfs/file.c10
-rw-r--r--fs/hfs/file_cap.c2
-rw-r--r--fs/hfs/file_hdr.c6
-rw-r--r--fs/hfs/hfs.h2
-rw-r--r--fs/hfs/hfs_btree.h2
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfs/mdb.c2
-rw-r--r--fs/hfs/part_tbl.c2
-rw-r--r--fs/hfs/string.c2
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfs/sysdep.c2
-rw-r--r--fs/hfs/trans.c2
-rw-r--r--fs/hfs/version.c2
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/inode.c10
-rw-r--r--fs/iobuf.c1
-rw-r--r--fs/ioctl.c1
-rw-r--r--fs/isofs/dir.c2
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/isofs/joliet.c2
-rw-r--r--fs/isofs/namei.c2
-rw-r--r--fs/isofs/rock.c2
-rw-r--r--fs/jffs/inode-v23.c2
-rw-r--r--fs/jffs/intrep.c2
-rw-r--r--fs/jffs/jffs_fm.c2
-rw-r--r--fs/lockd/host.c2
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/lockd/svc4proc.c2
-rw-r--r--fs/lockd/svcproc.c2
-rw-r--r--fs/lockd/svcshare.c2
-rw-r--r--fs/locks.c2
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/ncpfs/dir.c2
-rw-r--r--fs/ncpfs/file.c2
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--fs/ncpfs/ncplib_kernel.h2
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/flushd.c2
-rw-r--r--fs/nfs/inode.c1
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfs/nfs3xdr.c2
-rw-r--r--fs/nfs/proc.c2
-rw-r--r--fs/nfs/read.c2
-rw-r--r--fs/nfs/symlink.c2
-rw-r--r--fs/nfs/unlink.c2
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/nfsd/export.c2
-rw-r--r--fs/nfsd/nfs3proc.c2
-rw-r--r--fs/nfsd/nfscache.c4
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nfsd/nfsfh.c3
-rw-r--r--fs/nfsd/nfsproc.c17
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/nfsxdr.c13
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nls/nls_base.c2
-rw-r--r--fs/open.c1
-rw-r--r--fs/openpromfs/inode.c4
-rw-r--r--fs/partitions/Config.in1
-rw-r--r--fs/partitions/check.c2
-rw-r--r--fs/partitions/ibm.c179
-rw-r--r--fs/partitions/ibm.h2
-rw-r--r--fs/partitions/msdos.c112
-rw-r--r--fs/partitions/osf.c12
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/qnx4/inode.c2
-rw-r--r--fs/qnx4/truncate.c2
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/namei.c14
-rw-r--r--fs/reiserfs/tail_conversion.c14
-rw-r--r--fs/romfs/inode.c2
-rw-r--r--fs/select.c2
-rw-r--r--fs/smbfs/ChangeLog11
-rw-r--r--fs/smbfs/Makefile1
-rw-r--r--fs/smbfs/cache.c408
-rw-r--r--fs/smbfs/dir.c197
-rw-r--r--fs/smbfs/file.c13
-rw-r--r--fs/smbfs/inode.c30
-rw-r--r--fs/smbfs/proc.c386
-rw-r--r--fs/smbfs/sock.c55
-rw-r--r--fs/super.c3
-rw-r--r--fs/udf/dir.c2
-rw-r--r--fs/udf/namei.c2
-rw-r--r--fs/udf/partition.c2
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/udf/symlink.c2
-rw-r--r--fs/ufs/super.c2
-rw-r--r--fs/ufs/util.c2
-rw-r--r--fs/umsdos/dir.c2
-rw-r--r--fs/umsdos/namei.c2
-rw-r--r--fs/umsdos/rdir.c2
-rw-r--r--fs/vfat/namei.c2
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;
diff --git a/fs/exec.c b/fs/exec.c
index e618a3f18..835d77136 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -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"
diff --git a/fs/fifo.c b/fs/fifo.c
index ee048ac02..f5738c126 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -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)
diff --git a/fs/file.c b/fs/file.c
index 84d0275cd..51d9f7a25 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -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>
diff --git a/fs/open.c b/fs/open.c
index 309aa0667..c6b8f7b89 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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");
diff --git a/fs/pipe.c b/fs/pipe.c
index c7f27a520..94aa78853 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -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"