summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /fs
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'fs')
-rw-r--r--fs/Makefile2
-rw-r--r--fs/adfs/super.c6
-rw-r--r--fs/affs/super.c6
-rw-r--r--fs/bfs/inode.c1
-rw-r--r--fs/binfmt_aout.c14
-rw-r--r--fs/binfmt_elf.c24
-rw-r--r--fs/buffer.c6
-rw-r--r--fs/coda/inode.c1
-rw-r--r--fs/cramfs/inode.c4
-rw-r--r--fs/dcache.c77
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/exec.c45
-rw-r--r--fs/ext2/ialloc.c1
-rw-r--r--fs/ext2/inode.c1
-rw-r--r--fs/hfs/super.c1
-rw-r--r--fs/hpfs/super.c1
-rw-r--r--fs/inode.c3
-rw-r--r--fs/iobuf.c2
-rw-r--r--fs/isofs/inode.c5
-rw-r--r--fs/jffs/inode-v23.c5
-rw-r--r--fs/minix/inode.c3
-rw-r--r--fs/namei.c8
-rw-r--r--fs/ncpfs/dir.c56
-rw-r--r--fs/ncpfs/inode.c1
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--fs/nfs/dir.c6
-rw-r--r--fs/nfs/inode.c5
-rw-r--r--fs/nfsd/nfsproc.c32
-rw-r--r--fs/nfsd/nfssvc.c6
-rw-r--r--fs/nfsd/vfs.c33
-rw-r--r--fs/proc/array.c18
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/proc_misc.c4
-rw-r--r--fs/qnx4/inode.c1
-rw-r--r--fs/reiserfs/dir.c4
-rw-r--r--fs/reiserfs/fix_node.c18
-rw-r--r--fs/reiserfs/inode.c63
-rw-r--r--fs/reiserfs/ioctl.c4
-rw-r--r--fs/reiserfs/stree.c22
-rw-r--r--fs/reiserfs/super.c10
-rw-r--r--fs/reiserfs/tail_conversion.c10
-rw-r--r--fs/romfs/inode.c3
-rw-r--r--fs/smbfs/ChangeLog17
-rw-r--r--fs/smbfs/cache.c55
-rw-r--r--fs/smbfs/inode.c24
-rw-r--r--fs/smbfs/proc.c16
-rw-r--r--fs/super.c2
-rw-r--r--fs/sysv/inode.c1
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/ufs/super.c6
-rw-r--r--fs/ufs/truncate.c4
-rw-r--r--fs/umsdos/emd.c3
53 files changed, 333 insertions, 319 deletions
diff --git a/fs/Makefile b/fs/Makefile
index 738e4418c..998909436 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -7,7 +7,7 @@
O_TARGET := fs.o
-export-objs := filesystems.o
+export-objs := filesystems.o dcache.o
mod-subdirs := nls
obj-y := open.o read_write.o devices.o file_table.o buffer.o \
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 83ba97166..ff11b6e9b 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -385,6 +385,12 @@ struct super_block *adfs_read_super(struct super_block *sb, void *data, int sile
sb->u.adfs_sb.s_size = adfs_discsize(dr, sb->s_blocksize_bits);
sb->u.adfs_sb.s_version = dr->format_version;
sb->u.adfs_sb.s_log2sharesize = dr->log2sharesize;
+
+ /*
+ * Max file size is 2Gb
+ */
+
+ sb->s_maxbytes = MAX_NON_LFS;
sb->u.adfs_sb.s_map = adfs_read_map(sb, dr);
if (!sb->u.adfs_sb.s_map)
diff --git a/fs/affs/super.c b/fs/affs/super.c
index c77c3410c..78aa98372 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -415,6 +415,12 @@ got_root:
s->s_flags |= MS_NODEV | MS_NOSUID;
+ /*
+ * Max file size is 2Gb
+ */
+
+ s->s_maxbytes = MAX_NON_LFS;
+
/* Keep super block in cache */
bb = affs_bread(dev,root_block,s->s_blocksize);
if (!bb)
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 8e33b4ab2..ce6e778eb 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -250,6 +250,7 @@ static struct super_block * bfs_read_super(struct super_block * s,
set_blocksize(dev, BFS_BSIZE);
s->s_blocksize = BFS_BSIZE;
s->s_blocksize_bits = BFS_BSIZE_BITS;
+ s->s_maxbytes = MAX_NON_LFS;
bh = bread(dev, 0, BFS_BSIZE);
if(!bh)
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 42f746fb7..8a907e037 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -342,7 +342,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
error = bprm->file->f_op->read(bprm->file, (char *)text_addr,
ex.a_text+ex.a_data, &pos);
- if (error < 0) {
+ if ((signed long)error < 0) {
send_sig(SIGKILL, current, 0);
return error;
}
@@ -377,24 +377,24 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto beyond_if;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -476,12 +476,12 @@ static int load_aout_library(struct file *file)
goto out;
}
/* Now use mmap to map the library into memory. */
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
N_TXTOFF(ex));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
retval = error;
if (error != start_addr)
goto out;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6841b4acb..7538f9b2c 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -214,11 +214,11 @@ elf_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int pro
{
unsigned long map_addr;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
map_addr = do_mmap(filep, ELF_PAGESTART(addr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return(map_addr);
}
@@ -732,10 +732,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */
/* N.B. Shouldn't the size here be PAGE_SIZE?? */
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
}
#ifdef ELF_PLAT_INIT
@@ -816,7 +816,7 @@ static int load_elf_library(struct file *file)
while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
/* Now use mmap to map the library into memory. */
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(file,
ELF_PAGESTART(elf_phdata->p_vaddr),
(elf_phdata->p_filesz +
@@ -825,7 +825,7 @@ static int load_elf_library(struct file *file)
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
(elf_phdata->p_offset -
ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
goto out_free_ph;
@@ -1203,15 +1203,15 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
pte_t *pte;
pgd = pgd_offset(vma->vm_mm, addr);
- pmd = pmd_alloc(pgd, addr);
+ pmd = pmd_offset(pgd, addr);
if (!pmd)
- goto end_coredump;
- pte = pte_alloc(pmd, addr);
+ goto nextpage_coredump;
+ pte = pte_offset(pmd, addr);
if (!pte)
- goto end_coredump;
- if (!pte_present(*pte) &&
- pte_none(*pte)) {
+ goto nextpage_coredump;
+ if (pte_none(*pte)) {
+nextpage_coredump:
DUMP_SEEK (file->f_pos + PAGE_SIZE);
} else {
DUMP_WRITE((void*)addr, PAGE_SIZE);
diff --git a/fs/buffer.c b/fs/buffer.c
index 6ca6f166b..c5cedb6e3 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1880,8 +1880,8 @@ int block_truncate_page(struct address_space *mapping, loff_t from, get_block_t
iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
page = grab_cache_page(mapping, index);
- err = PTR_ERR(page);
- if (IS_ERR(page))
+ err = -ENOMEM;
+ if (!page)
goto out;
if (!page->buffers)
@@ -2750,7 +2750,7 @@ int kupdate(void *sem)
tsk->session = 1;
tsk->pgrp = 1;
- strcpy(tsk->comm, "kupdate");
+ strcpy(tsk->comm, "kupdated");
/* sigstop and sigcont will stop and wakeup kupdate */
spin_lock_irq(&tsk->sigmask_lock);
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 3cf258a23..4897e4ad1 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -141,6 +141,7 @@ static struct super_block * coda_read_super(struct super_block *sb,
sb->s_magic = CODA_SUPER_MAGIC;
sb->s_dev = dev;
sb->s_op = &coda_super_operations;
+ sb->s_maxbytes = MAX_NON_LFS;
/* get root fid from Venus: this needs the root inode */
error = venus_rootfid(sb, &fid);
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 3ce1b2e01..6c937c813 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -194,9 +194,9 @@ static struct super_block * cramfs_read_super(struct super_block *sb, void *data
/* Set it all up.. */
sb->s_op = &cramfs_ops;
- sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
+ sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
+ sb->s_maxbytes = MAX_NON_LFS;
retval = sb;
-
out:
return retval;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 5ea250e56..30cd770fa 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/cache.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -223,8 +224,7 @@ static inline struct dentry * __dget_locked(struct dentry *dentry)
atomic_inc(&dentry->d_count);
if (atomic_read(&dentry->d_count) == 1) {
dentry_stat.nr_unused--;
- list_del(&dentry->d_lru);
- INIT_LIST_HEAD(&dentry->d_lru); /* make "list_empty()" work */
+ list_del_init(&dentry->d_lru);
}
return dentry;
}
@@ -413,8 +413,7 @@ repeat:
if (atomic_read(&dentry->d_count))
continue;
dentry_stat.nr_unused--;
- list_del(tmp);
- INIT_LIST_HEAD(tmp);
+ list_del_init(tmp);
prune_one_dentry(dentry);
goto repeat;
}
@@ -656,6 +655,7 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
void d_instantiate(struct dentry *entry, struct inode * inode)
{
+ if (!list_empty(&entry->d_alias)) BUG();
spin_lock(&dcache_lock);
if (inode)
list_add(&entry->d_alias, &inode->i_dentry);
@@ -744,58 +744,48 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
/**
* d_validate - verify dentry provided from insecure source
- * @dentry: The dentry alleged to be valid
- * @dparent: The parent dentry
+ * @dentry: The dentry alleged to be valid child of @dparent
+ * @dparent: The parent dentry (known to be valid)
* @hash: Hash of the dentry
* @len: Length of the name
*
* An insecure source has sent us a dentry, here we verify it and dget() it.
* This is used by ncpfs in its readdir implementation.
* Zero is returned in the dentry is invalid.
- *
- * NOTE: This function does _not_ dereference the pointers before we have
- * validated them. We can test the pointer values, but we
- * must not actually use them until we have found a valid
- * copy of the pointer in kernel space..
*/
-int d_validate(struct dentry *dentry, struct dentry *dparent,
- unsigned int hash, unsigned int len)
+int d_validate(struct dentry *dentry, struct dentry *dparent)
{
+ unsigned long dent_addr = (unsigned long) dentry;
+ unsigned long min_addr = PAGE_OFFSET;
+ unsigned long align_mask = 0x0F;
struct list_head *base, *lhp;
- int valid = 1;
- spin_lock(&dcache_lock);
- if (dentry != dparent) {
- base = d_hash(dparent, hash);
- lhp = base;
- while ((lhp = lhp->next) != base) {
- if (dentry == list_entry(lhp, struct dentry, d_hash)) {
- __dget_locked(dentry);
- goto out;
- }
- }
- } else {
- /*
- * Special case: local mount points don't live in
- * the hashes, so we search the super blocks.
- */
- struct super_block *sb = sb_entry(super_blocks.next);
+ if (dent_addr < min_addr)
+ goto out;
+ if (dent_addr > (unsigned long)high_memory - sizeof(struct dentry))
+ goto out;
+ if (dent_addr & align_mask)
+ goto out;
+ if ((!kern_addr_valid(dent_addr)) || (!kern_addr_valid(dent_addr -1 +
+ sizeof(struct dentry))))
+ goto out;
- for (; sb != sb_entry(&super_blocks);
- sb = sb_entry(sb->s_list.next)) {
- if (!sb->s_dev)
- continue;
- if (sb->s_root == dentry) {
- __dget_locked(dentry);
- goto out;
- }
+ if (dentry->d_parent != dparent)
+ goto out;
+
+ spin_lock(&dcache_lock);
+ lhp = base = d_hash(dparent, dentry->d_name.hash);
+ while ((lhp = lhp->next) != base) {
+ if (dentry == list_entry(lhp, struct dentry, d_hash)) {
+ __dget_locked(dentry);
+ spin_unlock(&dcache_lock);
+ return 1;
}
}
- valid = 0;
-out:
spin_unlock(&dcache_lock);
- return valid;
+out:
+ return 0;
}
/*
@@ -848,6 +838,7 @@ void d_delete(struct dentry * dentry)
void d_rehash(struct dentry * entry)
{
struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+ if (!list_empty(&entry->d_hash)) BUG();
spin_lock(&dcache_lock);
list_add(&entry->d_hash, list);
spin_unlock(&dcache_lock);
@@ -922,8 +913,7 @@ void d_move(struct dentry * dentry, struct dentry * target)
list_add(&dentry->d_hash, &target->d_hash);
/* Unhash the target: dput() will then get rid of it */
- list_del(&target->d_hash);
- INIT_LIST_HEAD(&target->d_hash);
+ list_del_init(&target->d_hash);
list_del(&dentry->d_child);
list_del(&target->d_child);
@@ -1250,6 +1240,7 @@ kmem_cache_t *dquot_cachep;
/* SLAB cache for buffer_head structures */
kmem_cache_t *bh_cachep;
+EXPORT_SYMBOL(bh_cachep);
void __init vfs_caches_init(unsigned long mempages)
{
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 04b5fe91d..07398d6bb 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -178,6 +178,8 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int silent) {
s->s_magic = EFS_SUPER_MAGIC;
s->s_blocksize = EFS_BLOCKSIZE;
s->s_blocksize_bits = EFS_BLOCKSIZE_BITS;
+ s->s_maxbytes = MAX_NON_LFS;
+
if (!(s->s_flags & MS_RDONLY)) {
#ifdef DEBUG
printk(KERN_INFO "EFS: forcing read-only mode\n");
diff --git a/fs/exec.c b/fs/exec.c
index 835d77136..26778aba0 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -252,6 +252,8 @@ int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm)
/*
* This routine is used to map in a page into an address space: needed by
* execve() for the initial stack and environment pages.
+ *
+ * tsk->mmap_sem is held for writing.
*/
void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address)
{
@@ -262,27 +264,29 @@ void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long a
if (page_count(page) != 1)
printk("mem_map disagrees with %p at %08lx\n", page, address);
pgd = pgd_offset(tsk->mm, address);
- pmd = pmd_alloc(pgd, address);
- if (!pmd) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return;
- }
- pte = pte_alloc(pmd, address);
- if (!pte) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return;
- }
- if (!pte_none(*pte)) {
- pte_ERROR(*pte);
- __free_page(page);
- return;
- }
+
+ spin_lock(&tsk->mm->page_table_lock);
+ pmd = pmd_alloc(tsk->mm, pgd, address);
+ if (!pmd)
+ goto out;
+ pte = pte_alloc(tsk->mm, pmd, address);
+ if (!pte)
+ goto out;
+ if (!pte_none(*pte))
+ goto out;
flush_dcache_page(page);
flush_page_to_ram(page);
set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
-/* no need for flush_tlb */
+ tsk->mm->rss++;
+ spin_unlock(&tsk->mm->page_table_lock);
+
+ /* no need for flush_tlb */
+ return;
+out:
+ spin_unlock(&tsk->mm->page_table_lock);
+ __free_page(page);
+ force_sig(SIGKILL, tsk);
+ return;
}
int setup_arg_pages(struct linux_binprm *bprm)
@@ -302,7 +306,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
if (!mpnt)
return -ENOMEM;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -321,12 +325,11 @@ int setup_arg_pages(struct linux_binprm *bprm)
struct page *page = bprm->page[i];
if (page) {
bprm->page[i] = NULL;
- current->mm->rss++;
put_dirty_page(current,page,stack_base);
}
stack_base += PAGE_SIZE;
}
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return 0;
}
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 9e4a9b6b0..c23a94d40 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -442,6 +442,7 @@ repeat:
inode->u.ext2_i.i_file_acl = 0;
inode->u.ext2_i.i_dir_acl = 0;
inode->u.ext2_i.i_dtime = 0;
+ inode->u.ext2_i.i_prealloc_count = 0;
inode->u.ext2_i.i_block_group = i;
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
inode->i_flags |= S_SYNC;
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index fd54c3040..2272fe393 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1047,6 +1047,7 @@ void ext2_read_inode (struct inode * inode)
inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
}
inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+ inode->u.ext2_i.i_prealloc_count = 0;
inode->u.ext2_i.i_block_group = block_group;
/*
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index a39710f09..a88a705a5 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -436,6 +436,7 @@ struct super_block *hfs_read_super(struct super_block *s, void *data,
goto bail1;
}
+ s->s_maxbytes = MAX_NON_LFS;
s->s_magic = HFS_SUPER_MAGIC;
s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS;
s->s_blocksize = HFS_SECTOR_SIZE;
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index a5db0acd3..08ac66772 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -427,6 +427,7 @@ struct super_block *hpfs_read_super(struct super_block *s, void *options,
s->s_blocksize = 512;
s->s_blocksize_bits = 9;
s->s_op = &hpfs_sops;
+ s->s_maxbytes = MAX_NON_LFS;
s->s_hpfs_root = superblock->root;
s->s_hpfs_fs_size = superblock->n_sectors;
diff --git a/fs/inode.c b/fs/inode.c
index 822e5187a..382e9ef97 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -133,7 +133,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if (sb) {
/* Don't do this for I_DIRTY_PAGES - that doesn't actually dirty the inode itself */
- if (flags & (I_DIRTY | I_DIRTY_SYNC)) {
+ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
if (sb->s_op && sb->s_op->dirty_inode)
sb->s_op->dirty_inode(inode);
}
@@ -613,6 +613,7 @@ static void clean_inode(struct inode *inode)
inode->i_bdev = NULL;
inode->i_data.a_ops = &empty_aops;
inode->i_data.host = inode;
+ inode->i_data.gfp_mask = GFP_HIGHUSER;
inode->i_mapping = &inode->i_data;
}
diff --git a/fs/iobuf.c b/fs/iobuf.c
index bcaa98826..540124355 100644
--- a/fs/iobuf.c
+++ b/fs/iobuf.c
@@ -55,7 +55,7 @@ int alloc_kiovec(int nr, struct kiobuf **bufp)
return -ENOMEM;
}
kiobuf_init(iobuf);
- *bufp++ = iobuf;
+ bufp[i] = iobuf;
}
return 0;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 91f55dfb7..68741046a 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -663,6 +663,11 @@ root_found:
s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
+ /* Set this for reference. Its not currently used except on write
+ which we don't have .. */
+
+ s->s_maxbytes = MAX_NON_LFS;
+
/* RDE: data zone now byte offset! */
first_data_zone = ((isonum_733 (rootp->extent) +
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index d044ef3a3..f80193e7d 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -10,8 +10,8 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: inode-v23.c,v 1.43 2000/08/22 08:00:22 dwmw2 Exp $
- *
+ * $Id: inode-v23.c,v 1.43.2.6 2001/01/09 00:32:48 dwmw2 Exp $
+ * + sb_maxbytes / generic_file_open() fixes for 2.4.0-ac4
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -84,6 +84,7 @@ jffs_read_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->u.generic_sbp = (void *) 0;
+ sb->s_maxbytes = 0xFFFFFFFF;
/* Build the file system. */
if (jffs_build_fs(sb) < 0) {
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index d30699826..db6168073 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -259,6 +259,9 @@ static struct super_block *minix_read_super(struct super_block *s, void *data,
minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
+
+ s->s_maxbytes = MAX_NON_LFS;
+
/* set up enough so that it can read an inode */
s->s_op = &minix_sops;
root_inode = iget(s, MINIX_ROOT_INO);
diff --git a/fs/namei.c b/fs/namei.c
index 105833e4e..0f25265ac 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1013,7 +1013,7 @@ do_last:
error = -ELOOP;
if (flag & O_NOFOLLOW)
goto exit_dput;
- do __follow_down(&nd->mnt,&dentry); while(d_mountpoint(dentry));
+ while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
}
error = -ENOENT;
if (!dentry->d_inode)
@@ -1927,13 +1927,11 @@ out:
* bloody create() on broken symlinks. Furrfu...
*/
name = __getname();
- if (IS_ERR(name))
- goto fail_name;
+ if (!name)
+ return -ENOMEM;
strcpy(name, nd->last.name);
nd->last.name = name;
return 0;
-fail_name:
- link = name;
fail:
path_release(nd);
return PTR_ERR(link);
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 92d0aaba1..25ac483a1 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -326,56 +326,15 @@ ncp_lookup_validate(struct dentry * dentry, int flags)
return res;
}
-/* most parts from nfsd_d_validate() */
-static int
-ncp_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;
- /*
- * Looks safe enough to dereference ...
- */
- len = dentry->d_name.len;
- if (len > NCP_MAXPATHLEN)
- goto out;
- /*
- * Note: d_validate doesn't dereference the parent pointer ...
- * just combines it with the name hash to find the hash chain.
- */
- valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len);
-out:
- return valid;
-
-bad_addr:
- PRINTK("ncp_d_validate: invalid address %lx\n", dent_addr);
- goto out;
-bad_align:
- PRINTK("ncp_d_validate: unaligned address %lx\n", dent_addr);
- goto out;
-}
-
static struct dentry *
ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
{
struct dentry *dent = dentry;
struct list_head *next;
- if (ncp_d_validate(dent)) {
- if (dent->d_parent == parent &&
- (unsigned long)dent->d_fsdata == fpos) {
+ if (d_validate(dent, parent)) {
+ if (dent->d_name.len <= NCP_MAXPATHLEN &&
+ (unsigned long)dent->d_fsdata == fpos) {
if (!dent->d_inode) {
dput(dent);
dent = NULL;
@@ -580,6 +539,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
struct ncp_cache_control ctl = *ctrl;
struct qstr qname;
int valid = 0;
+ int hashed = 0;
ino_t ino = 0;
__u8 __name[256];
@@ -602,9 +562,11 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
newdent = d_alloc(dentry, &qname);
if (!newdent)
goto end_advance;
- } else
+ } else {
+ hashed = 1;
memcpy((char *) newdent->d_name.name, qname.name,
newdent->d_name.len);
+ }
if (!newdent->d_inode) {
entry->opened = 0;
@@ -612,7 +574,9 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
newino = ncp_iget(inode->i_sb, entry);
if (newino) {
newdent->d_op = &ncp_dentry_operations;
- d_add(newdent, newino);
+ d_instantiate(newdent, newino);
+ if (!hashed)
+ d_rehash(newdent);
}
} else
ncp_update_inode2(newdent->d_inode, entry);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 6cb6e863f..d839cbf0d 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -327,6 +327,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
else
default_bufsize = 1024;
+ sb->s_maxbytes = MAX_NON_LFS;
sb->s_blocksize = 1024; /* Eh... Is this correct? */
sb->s_blocksize_bits = 10;
sb->s_magic = NCP_SUPER_MAGIC;
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 50f52119d..ed4153dd6 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -43,7 +43,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
int bufsize;
int pos;
- page = alloc_page(GFP_HIGHMEM); /* ncpfs has nothing against GFP_HIGHMEM
+ page = alloc_page(GFP_HIGHUSER); /* ncpfs has nothing against high pages
as long as recvmsg and memset works on it */
if (!page)
return page;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c3a3a913e..35303cf20 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -321,7 +321,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
desc->page = NULL;
}
- page = page_cache_alloc();
+ page = alloc_page(GFP_HIGHUSER);
if (!page) {
status = -ENOMEM;
goto out;
@@ -1097,6 +1097,10 @@ nfs_permission(struct inode *inode, int mask)
if (!NFS_PROTO(inode)->access)
goto out;
+
+ if (error == -EROFS)
+ goto out;
+
/*
* Trust UNIX mode bits except:
*
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a48e711f5..abd08eebc 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -434,6 +434,11 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
if (server->namelen == 0 || server->namelen > maxlen)
server->namelen = maxlen;
+ if(version == 2)
+ sb->s_maxbytes = MAX_NON_LFS;
+ else
+ sb->s_maxbytes = ~0ULL; /* Unlimited on NFSv3 */
+
/* Fire up the writeback cache */
if (nfs_reqlist_alloc(server) < 0) {
printk(KERN_NOTICE "NFS: cannot initialize writeback cache.\n");
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 303792b58..896a978cd 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -196,7 +196,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
struct iattr *attr = &argp->attrs;
struct inode *inode;
struct dentry *dchild;
- int nfserr, type, mode, rdonly = 0;
+ int nfserr, type, mode;
dev_t rdev = NODEV;
dprintk("nfsd: CREATE %s %s\n",
@@ -207,13 +207,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
if (nfserr)
goto done; /* must fh_put dirfhp even on error */
- /* Check for MAY_WRITE separately. */
- nfserr = nfsd_permission(dirfhp->fh_export, dirfhp->fh_dentry,
- MAY_WRITE);
- if (nfserr == nfserr_rofs) {
- rdonly = 1; /* Non-fatal error for echo > /dev/null */
- } else if (nfserr)
- goto done;
+ /* Check for MAY_WRITE in nfsd_create if necessary */
nfserr = nfserr_acces;
if (!argp->len)
@@ -257,10 +251,25 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
* else assume a file */
if (inode) {
type = inode->i_mode & S_IFMT;
- if (type == S_IFCHR || type == S_IFBLK) {
+ switch(type) {
+ case S_IFCHR:
+ case S_IFBLK:
/* reserve rdev for later checking */
attr->ia_size = inode->i_rdev;
attr->ia_valid |= ATTR_SIZE;
+
+ /* FALLTHROUGH */
+ case S_IFIFO:
+ /* this is probably a permission check..
+ * at least IRIX implements perm checking on
+ * echo thing > device-special-file-or-pipe
+ * by does a CREATE with type==0
+ */
+ nfserr = nfsd_permission(newfhp->fh_export,
+ newfhp->fh_dentry,
+ MAY_WRITE);
+ if (nfserr && nfserr != nfserr_rofs)
+ goto out_unlock;
}
} else
type = S_IFREG;
@@ -273,11 +282,6 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
mode = 0; /* ??? */
}
- /* This is for "echo > /dev/null" a la SunOS. Argh. */
- nfserr = nfserr_rofs;
- if (rdonly && (!inode || type == S_IFREG))
- goto out_unlock;
-
attr->ia_valid |= ATTR_MODE;
attr->ia_mode = mode;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ae3cb8a48..0f68337d3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -149,12 +149,8 @@ nfsd(struct svc_rqst *rqstp)
/* Lock module and set up kernel thread */
MOD_INC_USE_COUNT;
lock_kernel();
- exit_mm(current);
- current->session = 1;
- current->pgrp = 1;
+ daemonize();
sprintf(current->comm, "nfsd");
- current->fs->umask = 0;
-
current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
nfsdstats.th_cnt++;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 43fc14a4f..3d0c84007 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -737,27 +737,24 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
* nice and simple solution (IMHO), and it seems to
* work:-)
*/
- if (EX_WGATHER(exp) && (atomic_read(&inode->i_writecount) > 1
- || (last_ino == inode->i_ino && last_dev == inode->i_dev))) {
-#if 0
- interruptible_sleep_on_timeout(&inode->i_wait, 10 * HZ / 1000);
-#else
- dprintk("nfsd: write defer %d\n", current->pid);
-/* FIXME: Olaf commented this out [gam3] */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((HZ+99)/100);
- current->state = TASK_RUNNING;
- dprintk("nfsd: write resume %d\n", current->pid);
-#endif
- }
+ if (EX_WGATHER(exp)) {
+ if (atomic_read(&inode->i_writecount) > 1
+ || (last_ino == inode->i_ino && last_dev == inode->i_dev)) {
+ dprintk("nfsd: write defer %d\n", current->pid);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout((HZ+99)/100);
+ current->state = TASK_RUNNING;
+ dprintk("nfsd: write resume %d\n", current->pid);
+ }
- if (inode->i_state & I_DIRTY) {
- dprintk("nfsd: write sync %d\n", current->pid);
- nfsd_sync(&file);
- }
+ if (inode->i_state & I_DIRTY) {
+ dprintk("nfsd: write sync %d\n", current->pid);
+ nfsd_sync(&file);
+ }
#if 0
- wake_up(&inode->i_wait);
+ wake_up(&inode->i_wait);
#endif
+ }
last_ino = inode->i_ino;
last_dev = inode->i_dev;
}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index e98061fa8..65d182add 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -181,7 +181,7 @@ static inline char * task_mem(struct mm_struct *mm, char *buffer)
unsigned long data = 0, stack = 0;
unsigned long exec = 0, lib = 0;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
if (!vma->vm_file) {
@@ -212,7 +212,7 @@ static inline char * task_mem(struct mm_struct *mm, char *buffer)
mm->rss << (PAGE_SHIFT-10),
data - stack, stack,
exec - lib, lib);
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return buffer;
}
@@ -321,7 +321,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
task_unlock(task);
if (mm) {
struct vm_area_struct *vma;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
vsize += vma->vm_end - vma->vm_start;
@@ -329,7 +329,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
}
eip = KSTK_EIP(task);
esp = KSTK_ESP(task);
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
}
wchan = get_wchan(task);
@@ -484,7 +484,7 @@ int proc_pid_statm(struct task_struct *task, char * buffer)
task_unlock(task);
if (mm) {
struct vm_area_struct * vma;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
pgd_t *pgd = pgd_offset(mm, vma->vm_start);
@@ -505,7 +505,7 @@ int proc_pid_statm(struct task_struct *task, char * buffer)
drs += pages;
vma = vma->vm_next;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
mmput(mm);
}
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
@@ -582,7 +582,7 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char *
column = *ppos & (MAPS_LINE_LENGTH-1);
/* quickly go to line lineno */
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
for (map = mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++)
continue;
@@ -644,9 +644,7 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char *
i = len-column;
if (i > count)
i = count;
- up(&mm->mmap_sem);
copy_to_user(destptr, line+column, i); /* may have slept */
- down(&mm->mmap_sem);
destptr += i;
count -= i;
column += i;
@@ -665,7 +663,7 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char *
if (volatile_task)
break;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/* encode f_pos */
*ppos = (lineno << MAPS_LINE_SHIFT) + column;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index c1a960c5d..a25126e77 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -64,7 +64,7 @@ static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfs
task_unlock(task);
if (!mm)
goto out;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
if ((vma->vm_flags & VM_EXECUTABLE) &&
@@ -76,7 +76,7 @@ static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfs
}
vma = vma->vm_next;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
mmput(mm);
out:
return result;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 3453bf88b..2e99938b1 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -188,6 +188,8 @@ struct super_block *proc_read_super(struct super_block *s,void *data,
s->s_blocksize_bits = 10;
s->s_magic = PROC_SUPER_MAGIC;
s->s_op = &proc_sops;
+ s->s_maxbytes = MAX_NON_LFS;
+
root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
if (!root_inode)
goto out_no_root;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index d24f65b50..5863e45ac 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -293,8 +293,8 @@ static int kstat_read_proc(char *page, char **start, off_t off,
"page %u %u\n"
"swap %u %u\n"
"intr %u",
- kstat.pgpgin,
- kstat.pgpgout,
+ kstat.pgpgin >> 1,
+ kstat.pgpgout >> 1,
kstat.pswpin,
kstat.pswpout,
sum
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 490c3d047..b1e90e849 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -369,6 +369,7 @@ static struct super_block *qnx4_read_super(struct super_block *s,
}
s->s_op = &qnx4_sops;
s->s_magic = QNX4_SUPER_MAGIC;
+ s->s_maxbytes = MAX_NON_LFS;
#ifndef CONFIG_QNX4FS_RW
s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
#endif
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 48ca45c0c..ad184a145 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -51,6 +51,8 @@ int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
int windex ;
struct reiserfs_transaction_handle th ;
+ lock_kernel();
+
journal_begin(&th, dentry->d_inode->i_sb, 1) ;
windex = push_journal_writer("dir_fsync") ;
reiserfs_prepare_for_journal(th.t_super, SB_BUFFER_WITH_SB(th.t_super), 1) ;
@@ -58,6 +60,8 @@ int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
pop_journal_writer(windex) ;
journal_end_sync(&th, dentry->d_inode->i_sb, 1) ;
+ unlock_kernel();
+
return ret ;
}
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index daa30b588..f050e24af 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -840,7 +840,7 @@ void free_buffers_in_tb (
/* Get new buffers for storing new nodes that are created while balancing.
- * Returns: SCHEDULE_OCCURED - schedule occured while the function worked;
+ * Returns: SCHEDULE_OCCURRED - schedule occurred while the function worked;
* CARRY_ON - schedule didn't occur while the function worked;
* NO_DISK_SPACE - no disk space.
*/
@@ -1077,7 +1077,7 @@ static void decrement_key (struct cpu_key * p_s_key)
* Calculate left/right common parent of the current node and L[h]/R[h].
* Calculate left/right delimiting key position.
* Returns: PATH_INCORRECT - path in the tree is not correct;
- SCHEDULE_OCCURRED - schedule occured while the function worked;
+ SCHEDULE_OCCURRED - schedule occurred while the function worked;
* CARRY_ON - schedule didn't occur while the function worked;
*/
static int get_far_parent (struct tree_balance * p_s_tb,
@@ -1198,7 +1198,7 @@ static int get_far_parent (struct tree_balance * p_s_tb,
* S[n_path_offset] and L[n_path_offset]/R[n_path_offset]: F[n_path_offset], FL[n_path_offset],
* FR[n_path_offset], CFL[n_path_offset], CFR[n_path_offset].
* Calculate numbers of left and right delimiting keys position: lkey[n_path_offset], rkey[n_path_offset].
- * Returns: SCHEDULE_OCCURRED - schedule occured while the function worked;
+ * Returns: SCHEDULE_OCCURRED - schedule occurred while the function worked;
* CARRY_ON - schedule didn't occur while the function worked;
*/
static int get_parents (struct tree_balance * p_s_tb, int n_h)
@@ -1340,7 +1340,7 @@ static inline int can_node_be_removed (int mode, int lfree, int sfree, int rfree
* h current level of the node;
* inum item number in S[h];
* mode i - insert, p - paste;
- * Returns: 1 - schedule occured;
+ * Returns: 1 - schedule occurred;
* 0 - balancing for higher levels needed;
* -1 - no balancing for higher levels needed;
* -2 - no disk space.
@@ -1678,7 +1678,7 @@ static int ip_check_balance (struct tree_balance * tb, int h)
* h current level of the node;
* inum item number in S[h];
* mode i - insert, p - paste;
- * Returns: 1 - schedule occured;
+ * Returns: 1 - schedule occurred;
* 0 - balancing for higher levels needed;
* -1 - no balancing for higher levels needed;
* -2 - no disk space.
@@ -1848,7 +1848,7 @@ static int dc_check_balance_internal (struct tree_balance * tb, int h)
* h current level of the node;
* inum item number in S[h];
* mode i - insert, p - paste;
- * Returns: 1 - schedule occured;
+ * Returns: 1 - schedule occurred;
* 0 - balancing for higher levels needed;
* -1 - no balancing for higher levels needed;
* -2 - no disk space.
@@ -1951,7 +1951,7 @@ static int dc_check_balance_leaf (struct tree_balance * tb, int h)
* h current level of the node;
* inum item number in S[h];
* mode d - delete, c - cut.
- * Returns: 1 - schedule occured;
+ * Returns: 1 - schedule occurred;
* 0 - balancing for higher levels needed;
* -1 - no balancing for higher levels needed;
* -2 - no disk space.
@@ -1985,7 +1985,7 @@ static int dc_check_balance (struct tree_balance * tb, int h)
* h current level of the node;
* inum item number in S[h];
* mode i - insert, p - paste, d - delete, c - cut.
- * Returns: 1 - schedule occured;
+ * Returns: 1 - schedule occurred;
* 0 - balancing for higher levels needed;
* -1 - no balancing for higher levels needed;
* -2 - no disk space.
@@ -2075,7 +2075,7 @@ static int get_direct_parent(
/* Using lnum[n_h] and rnum[n_h] we should determine what neighbors
* of S[n_h] we
* need in order to balance S[n_h], and get them if necessary.
- * Returns: SCHEDULE_OCCURRED - schedule occured while the function worked;
+ * Returns: SCHEDULE_OCCURRED - schedule occurred while the function worked;
* CARRY_ON - schedule didn't occur while the function worked;
*/
static int get_neighbors(
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 12ab13894..323c36cd6 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -304,6 +304,7 @@ static int _get_block_create_0 (struct inode * inode, long block,
char * p = NULL;
int chars;
int ret ;
+ int done = 0 ;
unsigned long offset ;
// prepare the key to look for the 'block'-th block of file
@@ -355,6 +356,14 @@ research:
return -ENOENT;
}
+ /* if we've got a direct item, and the buffer was uptodate,
+ ** we don't want to pull data off disk again. skip to the
+ ** end, where we map the buffer and return
+ */
+ if (buffer_uptodate(bh_result)) {
+ goto finished ;
+ }
+
// read file tail into part of page
offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1) ;
fs_gen = get_generation(inode->i_sb) ;
@@ -375,8 +384,24 @@ research:
if (!is_direct_le_ih (ih)) {
BUG ();
}
- chars = le16_to_cpu (ih->ih_item_len) - path.pos_in_item;
+ /* make sure we don't read more bytes than actually exist in
+ ** the file. This can happen in odd cases where i_size isn't
+ ** correct, and when direct item padding results in a few
+ ** extra bytes at the end of the direct item
+ */
+ if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
+ break ;
+ if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
+ chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item;
+ done = 1 ;
+ } else {
+ chars = le16_to_cpu (ih->ih_item_len) - path.pos_in_item;
+ }
memcpy (p, B_I_PITEM (bh, ih) + path.pos_in_item, chars);
+
+ if (done)
+ break ;
+
p += chars;
if (PATH_LAST_POSITION (&path) != (B_NR_ITEMS (bh) - 1))
@@ -395,16 +420,14 @@ research:
ih = get_ih (&path);
} while (1);
+finished:
pathrelse (&path);
-
- // FIXME: b_blocknr == 0 here. but b_data contains correct data
- // from tail. ll_rw_block will skip uptodate buffers
bh_result->b_blocknr = 0 ;
bh_result->b_dev = inode->i_dev;
mark_buffer_uptodate (bh_result, 1);
bh_result->b_state |= (1UL << BH_Mapped);
+ flush_dcache_page(bh_result->b_page) ;
kunmap(bh_result->b_page) ;
-
return 0;
}
@@ -476,8 +499,8 @@ static int convert_tail_for_hole(struct inode *inode,
index = tail_offset >> PAGE_CACHE_SHIFT ;
if (index != hole_page->index) {
tail_page = grab_cache_page(inode->i_mapping, index) ;
- retval = PTR_ERR(tail_page) ;
- if (IS_ERR(tail_page)) {
+ retval = -ENOMEM;
+ if (!tail_page) {
goto out ;
}
} else {
@@ -771,6 +794,7 @@ int reiserfs_get_block (struct inode * inode, long block,
** flush unbh before the transaction commits
*/
reiserfs_add_page_to_flush_list(&th, inode, unbh) ;
+ mark_buffer_dirty(unbh) ;
//inode->i_blocks += inode->i_sb->s_blocksize / 512;
//mark_tail_converted (inode);
@@ -1260,7 +1284,7 @@ static int reiserfs_new_directory (struct reiserfs_transaction_handle *th,
retval = search_item (sb, &key, path);
if (retval == IO_ERROR) {
reiserfs_warning ("vs-13080: reiserfs_new_directory: "
- "i/o failure occured creating new directory\n");
+ "i/o failure occurred creating new directory\n");
return -EIO;
}
if (retval == ITEM_FOUND) {
@@ -1296,7 +1320,7 @@ static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th,
retval = search_item (sb, &key, path);
if (retval == IO_ERROR) {
reiserfs_warning ("vs-13080: reiserfs_new_symlinik: "
- "i/o failure occured creating new symlink\n");
+ "i/o failure occurred creating new symlink\n");
return -EIO;
}
if (retval == ITEM_FOUND) {
@@ -1486,8 +1510,8 @@ static int grab_tail_page(struct inode *p_s_inode,
return -ENOENT ;
}
page = grab_cache_page(p_s_inode->i_mapping, index) ;
- error = PTR_ERR(page) ;
- if (IS_ERR(page)) {
+ error = -ENOMEM ;
+ if (!page) {
goto out ;
}
/* start within the page of the last block in the file */
@@ -1566,8 +1590,9 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
/* so, if page != NULL, we have a buffer head for the offset at
** the end of the file. if the bh is mapped, and bh->b_blocknr != 0,
** then we have an unformatted node. Otherwise, we have a direct item,
- ** and no zeroing is required. We zero after the truncate, because the
- ** truncate might pack the item anyway (it will unmap bh if it packs).
+ ** and no zeroing is required on disk. We zero after the truncate,
+ ** because the truncate might pack the item anyway
+ ** (it will unmap bh if it packs).
*/
prevent_flush_page_lock(page, p_s_inode) ;
journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
@@ -1577,7 +1602,7 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
allow_flush_page_lock(page, p_s_inode) ;
- if (page && buffer_mapped(bh) && bh->b_blocknr != 0) {
+ if (page) {
length = offset & (blocksize - 1) ;
/* if we are not on a block boundary */
if (length) {
@@ -1585,14 +1610,14 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
memset((char *)kmap(page) + offset, 0, length) ;
flush_dcache_page(page) ;
kunmap(page) ;
- mark_buffer_dirty(bh) ;
+ if (buffer_mapped(bh) && bh->b_blocknr != 0) {
+ mark_buffer_dirty(bh) ;
+ }
}
- }
-
- if (page) {
UnlockPage(page) ;
page_cache_release(page) ;
}
+
return ;
}
@@ -1645,6 +1670,7 @@ research:
goto out ;
}
set_block_dev_mapped(bh_result, le32_to_cpu(item[pos_in_item]), inode);
+ mark_buffer_uptodate(bh_result, 1);
} else if (is_direct_le_ih(ih)) {
char *p ;
p = page_address(bh_result->b_page) ;
@@ -1664,6 +1690,7 @@ research:
journal_mark_dirty(&th, inode->i_sb, bh) ;
bytes_copied += copy_size ;
set_block_dev_mapped(bh_result, 0, inode);
+ mark_buffer_uptodate(bh_result, 1);
/* are there still bytes left? */
if (bytes_copied < bh_result->b_size &&
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 72054ce3a..c8761c2ed 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -77,8 +77,8 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
*/
index = inode->i_size >> PAGE_CACHE_SHIFT ;
page = grab_cache_page(inode->i_mapping, index) ;
- retval = PTR_ERR(page) ;
- if (IS_ERR(page)) {
+ retval = -ENOMEM;
+ if (!page) {
goto out ;
}
retval = reiserfs_prepare_write(NULL, page, write_from, blocksize) ;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index f4b24b590..83c7cd8f4 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -734,7 +734,7 @@ int search_by_key (struct super_block * p_s_sb,
return IO_ERROR;
}
- /* It is possible that schedule occured. We must check whether the key
+ /* It is possible that schedule occurred. We must check whether the key
to search is still in the tree rooted from the current buffer. If
not then repeat search from the root. */
if ( fs_changed (fs_gen, p_s_sb) &&
@@ -1438,7 +1438,6 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
if ( p_s_un_bh ) {
int off;
- int block_off ;
char *data ;
/* We are in direct2indirect conversion, so move tail contents
@@ -1452,7 +1451,8 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
** the unformatted node, which might schedule, meaning we'd have to
** loop all the way back up to the start of the while loop.
**
- ** The unformatted node is prepared and logged after the do_balance.
+ ** The unformatted node must be dirtied later on. We can't be
+ ** sure here if the entire tail has been deleted yet.
**
** p_s_un_bh is from the page cache (all unformatted nodes are
** from the page cache) and might be a highmem page. So, we
@@ -1463,25 +1463,13 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
data = page_address(p_s_un_bh->b_page) ;
off = ((le_ih_k_offset (&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
- block_off = off & (p_s_un_bh->b_size - 1) ;
memcpy(data + off,
B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);
-
- /* clear out the rest of the block past the end of the file. */
- if (block_off + n_ret_value < p_s_un_bh->b_size) {
- memset(data + off + n_ret_value, 0,
- p_s_un_bh->b_size - block_off - n_ret_value) ;
- }
}
/* Perform balancing after all resources have been collected at once. */
do_balance(&s_del_balance, NULL, NULL, M_DELETE);
- /* see comment above for why this is after the do_balance */
- if (p_s_un_bh) {
- mark_buffer_dirty(p_s_un_bh) ;
- }
-
/* Return deleted body length */
return n_ret_value;
}
@@ -1521,7 +1509,7 @@ static void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
retval = search_item (th->t_super, &cpu_key, &path);
if (retval == IO_ERROR) {
reiserfs_warning ("vs-: reiserfs_delete_solid_item: "
- "i/o failure occured trying to delete %K\n", &cpu_key);
+ "i/o failure occurred trying to delete %K\n", &cpu_key);
break;
}
if (retval != ITEM_FOUND) {
@@ -1869,7 +1857,7 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
retval = search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path);
if (retval == IO_ERROR) {
reiserfs_warning ("vs-5657: reiserfs_do_truncate: "
- "i/o failure occured trying to truncate %K\n", &s_item_key);
+ "i/o failure occurred trying to truncate %K\n", &s_item_key);
return;
}
if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 9838a1dcd..2d35ffe4f 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1,5 +1,14 @@
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
+ *
+ * Trivial changes by Alan Cox to add the LFS fixes
+ *
+ * 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__
@@ -483,6 +492,7 @@ static int read_super_block (struct super_block * s, int size)
SB_BUFFER_WITH_SB (s) = bh;
SB_DISK_SUPER_BLOCK (s) = rs;
s->s_op = &reiserfs_sops;
+ s->s_maxbytes = 0xFFFFFFFF; /* 4Gig */
return 0;
}
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index f8153be3b..6493bd800 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -32,6 +32,7 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod
struct super_block * sb = inode->i_sb;
struct buffer_head *up_to_date_bh ;
struct item_head * p_le_ih = PATH_PITEM_HEAD (path);
+ unsigned long total_tail = 0 ;
struct cpu_key end_key; /* Key to search for the last byte of the
converted item. */
struct item_head ind_ih; /* new indirect item to be inserted or
@@ -121,11 +122,20 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod
n_retval = reiserfs_delete_item (th, path, &end_key, inode,
up_to_date_bh) ;
+ total_tail += n_retval ;
if (tail_size == n_retval)
// done: file does not have direct items anymore
break;
}
+ /* if we've copied bytes from disk into the page, we need to zero
+ ** out the unused part of the block (it was not up to date before)
+ ** the page is still kmapped (by whoever called reiserfs_get_block)
+ */
+ if (up_to_date_bh) {
+ unsigned pgoff = (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
+ memset(page_address(unbh->b_page) + pgoff, 0, n_blk_size - total_tail) ;
+ }
inode->u.reiserfs_i.i_first_direct_byte = U32_MAX;
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 7edadf2ac..c9cdea972 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -110,6 +110,9 @@ romfs_read_super(struct super_block *s, void *data, int silent)
set_blocksize(dev, ROMBSIZE);
s->s_blocksize = ROMBSIZE;
s->s_blocksize_bits = ROMBSBITS;
+ s->u.generic_sbp = (void *) 0;
+ s->s_maxbytes = 0xFFFFFFFF;
+
bh = bread(dev, 0, ROMBSIZE);
if (!bh) {
/* XXX merge with other printk? */
diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog
index 6ceae2331..5eeeb6829 100644
--- a/fs/smbfs/ChangeLog
+++ b/fs/smbfs/ChangeLog
@@ -1,9 +1,22 @@
ChangeLog for smbfs.
+2001-03-06 Urban Widmark <urban@teststation.com>
+
+ * cache.c: d_add on hashed dentries corrupts d_hash list and
+ causes loops in d_lookup. Inherited bug. :)
+ * inode.c: tail -f fix for non-readonly opened files
+ (related to the smb_proc_open change).
+ * inode.c: tail -f fix for fast size changes with the same mtime.
+
+2001-03-02 Michael Kockelkorn <m.kockelkorn@biodata.com>
+
+ * proc.c: fix smb_proc_open to allow open being called more than once
+ with different modes (O_RDONLY -> O_WRONLY) without closing.
+
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.
+ * dir.c, cache.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.
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
index e3e9c044f..3dc17d229 100644
--- a/fs/smbfs/cache.c
+++ b/fs/smbfs/cache.c
@@ -48,6 +48,7 @@ out_unlock:
UnlockPage(page);
page_cache_release(page);
out:
+ return;
}
/*
@@ -71,47 +72,6 @@ smb_invalidate_dircache_entries(struct dentry *parent)
spin_unlock(&dcache_lock);
}
-
-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;
- /*
- * Looks safe enough to dereference ...
- */
- len = dentry->d_name.len;
- if (len > SMB_MAXPATHLEN)
- goto out;
- /*
- * Note: d_validate doesn't dereference the parent pointer ...
- * just combines it with the name hash to find the hash chain.
- */
- valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len);
-out:
- 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;
-}
-
/*
* dget, but require that fpos and parent matches what the dentry contains.
* dentry is not known to be a valid pointer at entry.
@@ -122,8 +82,8 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
struct dentry *dent = dentry;
struct list_head *next;
- if (smb_d_validate(dent)) {
- if (dent->d_parent == parent &&
+ if (d_validate(dent, parent)) {
+ if (dent->d_name.len <= SMB_MAXPATHLEN &&
(unsigned long)dent->d_fsdata == fpos) {
if (!dent->d_inode) {
dput(dent);
@@ -167,6 +127,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
struct inode *newino, *inode = dentry->d_inode;
struct smb_cache_control ctl = *ctrl;
int valid = 0;
+ int hashed = 0;
ino_t ino = 0;
qname->hash = full_name_hash(qname->name, qname->len);
@@ -181,9 +142,11 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
newdent = d_alloc(dentry, qname);
if (!newdent)
goto end_advance;
- } else
+ } else {
+ hashed = 1;
memcpy((char *) newdent->d_name.name, qname->name,
newdent->d_name.len);
+ }
if (!newdent->d_inode) {
smb_renew_times(newdent);
@@ -191,7 +154,9 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
newino = smb_iget(inode->i_sb, entry);
if (newino) {
smb_new_dentry(newdent);
- d_add(newdent, newino);
+ d_instantiate(newdent, newino);
+ if (!hashed)
+ d_rehash(newdent);
}
} else
smb_set_inode_attr(newdent->d_inode, entry);
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 40ee12566..d86ce6de2 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -161,17 +161,15 @@ smb_refresh_inode(struct dentry *dentry)
struct smb_fattr fattr;
error = smb_proc_getattr(dentry, &fattr);
- if (!error)
- {
+ if (!error) {
smb_renew_times(dentry);
/*
* Check whether the type part of the mode changed,
* and don't update the attributes if it did.
*/
- if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
+ if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
smb_set_inode_attr(inode, &fattr);
- else
- {
+ } else {
/*
* Big trouble! The inode has become a new object,
* so any operations attempted on it are invalid.
@@ -212,18 +210,11 @@ 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;
+ loff_t last_sz;
int error = 0;
DEBUG1("smb_revalidate_inode\n");
- /*
- * If this is a file opened with write permissions,
- * the inode will be up-to-date.
- */
lock_kernel();
- if (S_ISREG(inode->i_mode) && smb_is_open(inode)) {
- if (inode->u.smbfs_i.access != SMB_O_RDONLY)
- goto out;
- }
/*
* Check whether we've recently refreshed the inode.
@@ -236,11 +227,13 @@ smb_revalidate_inode(struct dentry *dentry)
/*
* Save the last modified time, then refresh the inode.
- * (Note: a size change should have a different mtime.)
+ * (Note: a size change should have a different mtime,
+ * or same mtime but different size.)
*/
last_time = inode->i_mtime;
+ last_sz = inode->i_size;
error = smb_refresh_inode(dentry);
- if (error || inode->i_mtime != last_time) {
+ if (error || inode->i_mtime != last_time || inode->i_size != last_sz) {
VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
DENTRY_PATH(dentry),
(long) last_time, (long) inode->i_mtime);
@@ -399,6 +392,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
sb->s_magic = SMB_SUPER_MAGIC;
sb->s_flags = 0;
sb->s_op = &smb_sops;
+ sb->s_maxbytes = MAX_NON_LFS; /* client support missing */
sb->u.smbfs_sb.mnt = NULL;
sb->u.smbfs_sb.sock_file = NULL;
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index 9bfdc90a0..4725ab70f 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -950,7 +950,10 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
#if 0
/* FIXME: why is this code not in? below we fix it so that a caller
wanting RO doesn't get RW. smb_revalidate_inode does some
- optimization based on access mode. tail -f needs it to be correct. */
+ optimization based on access mode. tail -f needs it to be correct.
+
+ We must open rw since we don't do the open if called a second time
+ with different 'wish'. Is that not supported by smb servers? */
if (!(wish & (O_WRONLY | O_RDWR)))
mode = read_only;
#endif
@@ -989,8 +992,6 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
/* smb_vwv2 has mtime */
/* smb_vwv4 has size */
ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK);
- if (!(wish & (O_WRONLY | O_RDWR)))
- ino->u.smbfs_i.access = SMB_O_RDONLY;
ino->u.smbfs_i.open = server->generation;
out:
@@ -1008,23 +1009,20 @@ smb_open(struct dentry *dentry, int wish)
int result;
result = -ENOENT;
- if (!inode)
- {
+ if (!inode) {
printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
DENTRY_PATH(dentry));
goto out;
}
- if (!smb_is_open(inode))
- {
+ if (!smb_is_open(inode)) {
struct smb_sb_info *server = SMB_SERVER(inode);
smb_lock_server(server);
result = 0;
if (!smb_is_open(inode))
result = smb_proc_open(server, dentry, wish);
smb_unlock_server(server);
- if (result)
- {
+ if (result) {
PARANOIA("%s/%s open failed, result=%d\n",
DENTRY_PATH(dentry), result);
goto out;
diff --git a/fs/super.c b/fs/super.c
index 6482259ce..601e3d63f 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1412,6 +1412,8 @@ fs_out:
return retval;
fail:
+ if (fstype->fs_flags & FS_SINGLE)
+ put_filesystem(fstype);
if (list_empty(&sb->s_mounts))
kill_super(sb, 0);
goto unlock_out;
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 1fb7beaa8..0f3618512 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -365,6 +365,7 @@ static struct super_block *sysv_read_super(struct super_block *sb,
panic("sysv fs: bad i-node size");
set_blocksize(dev,BLOCK_SIZE);
sb->sv_block_base = 0;
+ sb->s_maxbytes = MAX_NON_LFS;
/* Try to read Xenix superblock */
if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 1e089c0b1..a23159427 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1415,7 +1415,7 @@ udf_read_super(struct super_block *sb, void *options, int silent)
iput(inode);
goto error_out;
}
-
+ sb->s_maxbytes = ~0ULL;
return sb;
error_out:
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 360291513..091a5cd6c 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -489,6 +489,12 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
if (!uspi)
goto failed;
+ /* Set a 2Gig file limit. Some UFS variants need to override
+ this but as I don't know which I'll let those in the know loosen
+ the rules */
+
+ sb->s_maxbytes = MAX_NON_LFS;
+
switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) {
case UFS_MOUNT_UFSTYPE_44BSD:
UFSD(("ufstype=44bsd\n"))
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 183ccfb13..d154f58d1 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -160,7 +160,7 @@ next1:
frag_to_free = tmp;
free_count = uspi->s_fpb;
}
-next2:
+next2:;
}
if (free_count > 0)
@@ -261,7 +261,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, u32 * p)
}
inode->i_blocks -= uspi->s_nspb;
mark_inode_dirty(inode);
-next:
+next:;
}
if (free_count > 0) {
diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c
index 93c6af317..0b4cd7f51 100644
--- a/fs/umsdos/emd.c
+++ b/fs/umsdos/emd.c
@@ -16,8 +16,7 @@
#include <linux/umsdos_fs.h>
#include <linux/dcache.h>
#include <linux/pagemap.h>
-
-#include <asm/delay.h>
+#include <linux/delay.h>
static void copy_entry(struct umsdos_dirent *p, struct umsdos_dirent *q)
{