diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
commit | 06615f62b17d7de6e12d2f5ec6b88cf30af08413 (patch) | |
tree | 8766f208847d4876a6db619aebbf54d53b76eb44 /fs | |
parent | fa9bdb574f4febb751848a685d9a9017e04e1d53 (diff) |
Merge with Linux 2.4.0-test10.
Diffstat (limited to 'fs')
54 files changed, 348 insertions, 217 deletions
@@ -110,6 +110,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr) time_t now = CURRENT_TIME; unsigned int ia_valid = attr->ia_valid; + if (!inode) + BUG(); + attr->ia_ctime = now; if (!(ia_valid & ATTR_ATIME_SET)) attr->ia_atime = now; @@ -117,7 +120,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) attr->ia_mtime = now; lock_kernel(); - if (inode && inode->i_op && inode->i_op->setattr) + if (inode->i_op && inode->i_op->setattr) error = inode->i_op->setattr(dentry, attr); else { error = inode_change_ok(inode, attr); diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 9d21624bc..9dfde83e8 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -3,7 +3,7 @@ * linux/fs/autofs/expire.c * * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org> + * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> * * This file is part of the Linux kernel and is made available under * the terms of the GNU General Public License, version 2, or at your @@ -15,46 +15,139 @@ /* * Determine if a subtree of the namespace is busy. + * + * mnt is the mount tree under the autofs mountpoint */ -static int is_tree_busy(struct vfsmount *mnt) +static inline int is_vfsmnt_tree_busy(struct vfsmount *mnt) { struct vfsmount *this_parent = mnt; struct list_head *next; int count; - spin_lock(&dcache_lock); - count = atomic_read(&mnt->mnt_count) - 2; - if (!is_autofs4_dentry(mnt->mnt_mountpoint)) - count--; + count = atomic_read(&mnt->mnt_count) - 1; + repeat: next = this_parent->mnt_mounts.next; + DPRINTK(("is_vfsmnt_tree_busy: mnt=%p, this_parent=%p, next=%p\n", + mnt, this_parent, next)); resume: - while (next != &this_parent->mnt_mounts) { - struct list_head *tmp = next; - struct vfsmount *p = list_entry(tmp, struct vfsmount, + for( ; next != &this_parent->mnt_mounts; next = next->next) { + struct vfsmount *p = list_entry(next, struct vfsmount, mnt_child); - next = tmp->next; - /* Decrement count for unused children */ - count += atomic_read(&p->mnt_count) - 2; + + /* -1 for struct vfs_mount's normal count, + -1 to compensate for child's reference to parent */ + count += atomic_read(&p->mnt_count) - 1 - 1; + + DPRINTK(("is_vfsmnt_tree_busy: p=%p, count now %d\n", + p, count)); + if (!list_empty(&p->mnt_mounts)) { this_parent = p; goto repeat; } /* root is busy if any leaf is busy */ - if (atomic_read(&p->mnt_count) > 1) { - spin_unlock(&dcache_lock); + if (atomic_read(&p->mnt_count) > 1) return 1; - } } - /* - * All done at this level ... ascend and resume the search. - */ + + /* All done at this level ... ascend and resume the search. */ if (this_parent != mnt) { next = this_parent->mnt_child.next; this_parent = this_parent->mnt_parent; goto resume; } - spin_unlock(&dcache_lock); + + DPRINTK(("is_vfsmnt_tree_busy: count=%d\n", count)); + return count != 0; /* remaining users? */ +} + +/* Traverse a dentry's list of vfsmounts and return the number of + non-busy mounts */ +static int check_vfsmnt(struct vfsmount *mnt, struct dentry *dentry) +{ + int ret = 0; + struct list_head *tmp; + + list_for_each(tmp, &dentry->d_vfsmnt) { + struct vfsmount *vfs = list_entry(tmp, struct vfsmount, + mnt_clash); + DPRINTK(("check_vfsmnt: mnt=%p, dentry=%p, tmp=%p, vfs=%p\n", + mnt, dentry, tmp, vfs)); + if (vfs->mnt_parent != mnt || /* don't care about busy-ness of other namespaces */ + !is_vfsmnt_tree_busy(vfs)) + ret++; + } + + DPRINTK(("check_vfsmnt: ret=%d\n", ret)); + return ret; +} + +/* Check dentry tree for busyness. If a dentry appears to be busy + because it is a mountpoint, check to see if the mounted + filesystem is busy. */ +static int is_tree_busy(struct vfsmount *topmnt, struct dentry *top) +{ + struct dentry *this_parent; + struct list_head *next; + int count; + + count = atomic_read(&top->d_count); + + DPRINTK(("is_tree_busy: top=%p initial count=%d\n", + top, count)); + this_parent = top; + + count--; /* top is passed in after being dgot */ + + if (is_autofs4_dentry(top)) { + count--; + DPRINTK(("is_tree_busy: autofs; count=%d\n", count)); + } + + if (d_mountpoint(top)) + count -= check_vfsmnt(topmnt, top); + + repeat: + next = this_parent->d_subdirs.next; + resume: + while (next != &this_parent->d_subdirs) { + int adj = 0; + struct dentry *dentry = list_entry(next, struct dentry, + d_child); + next = next->next; + + count += atomic_read(&dentry->d_count) - 1; + + if (d_mountpoint(dentry)) + adj += check_vfsmnt(topmnt, dentry); + + if (is_autofs4_dentry(dentry)) { + adj++; + DPRINTK(("is_tree_busy: autofs; adj=%d\n", + adj)); + } + + count -= adj; + + if (!list_empty(&dentry->d_subdirs)) { + this_parent = dentry; + goto repeat; + } + + if (atomic_read(&dentry->d_count) != adj) { + DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n", + atomic_read(&dentry->d_count), adj)); + return 1; + } + } + + /* All done at this level ... ascend and resume the search. */ + if (this_parent != top) { + next = this_parent->d_child.next; + this_parent = this_parent->d_parent; + goto resume; + } DPRINTK(("is_tree_busy: count=%d\n", count)); return count != 0; /* remaining users? */ @@ -67,11 +160,11 @@ resume: * - it has been unused for exp_timeout time */ static struct dentry *autofs4_expire(struct super_block *sb, - struct vfsmount *mnt, - struct autofs_sb_info *sbi, - int do_now) + struct vfsmount *mnt, + struct autofs_sb_info *sbi, + int do_now) { - unsigned long now = jiffies; /* snapshot of now */ + unsigned long now = jiffies; unsigned long timeout; struct dentry *root = sb->s_root; struct list_head *tmp; @@ -106,36 +199,32 @@ static struct dentry *autofs4_expire(struct super_block *sb, if (!do_now) { /* Too young to die */ - if (time_after(ino->last_used+timeout, now)) + if (time_after(ino->last_used + timeout, now)) continue; /* update last_used here :- - obviously makes sense if it is in use now - less obviously, prevents rapid-fire expire - attempts if expire fails the first time */ + attempts if expire fails the first time */ ino->last_used = now; } p = mntget(mnt); - d = dget(dentry); - spin_unlock(&dcache_lock); - while(d_mountpoint(d) && follow_down(&p, &d)) - ; + d = dget_locked(dentry); - if (!is_tree_busy(p)) { - dput(d); - mntput(p); + if (!is_tree_busy(p, d)) { DPRINTK(("autofs_expire: returning %p %.*s\n", - dentry, dentry->d_name.len, dentry->d_name.name)); + dentry, (int)dentry->d_name.len, dentry->d_name.name)); /* Start from here next time */ - spin_lock(&dcache_lock); list_del(&root->d_subdirs); list_add(&root->d_subdirs, &dentry->d_child); spin_unlock(&dcache_lock); + + dput(d); + mntput(p); return dentry; } dput(d); mntput(p); - spin_lock(&dcache_lock); } spin_unlock(&dcache_lock); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 72b5e1b27..6bdc3d358 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -3,7 +3,7 @@ * linux/fs/autofs/root.c * * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org> + * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> * * This file is part of the Linux kernel and is made available under * the terms of the GNU General Public License, version 2, or at your @@ -115,7 +115,6 @@ static int try_to_fill_dentry(struct dentry *dentry, /* Return a negative dentry, but leave it "pending" */ return 1; } - /* status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT); */ } /* If this is an unused directory that isn't a mount point, @@ -201,30 +200,34 @@ static int autofs4_revalidate(struct dentry *dentry, int flags) static void autofs4_dentry_release(struct dentry *de) { - struct autofs_info *inf = autofs4_dentry_ino(de); + struct autofs_info *inf; + + lock_kernel(); DPRINTK(("autofs4_dentry_release: releasing %p\n", de)); - lock_kernel(); + inf = autofs4_dentry_ino(de); de->d_fsdata = NULL; + if (inf) { inf->dentry = NULL; inf->inode = NULL; autofs4_free_ino(inf); } + unlock_kernel(); } /* For dentries of directories in the root dir */ static struct dentry_operations autofs4_root_dentry_operations = { - d_revalidate: autofs4_root_revalidate, /* d_revalidate */ + d_revalidate: autofs4_root_revalidate, d_release: autofs4_dentry_release, }; /* For other dentries */ static struct dentry_operations autofs4_dentry_operations = { - d_revalidate: autofs4_revalidate, /* d_revalidate */ + d_revalidate: autofs4_revalidate, d_release: autofs4_dentry_release, }; @@ -521,11 +524,11 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, /* return a single thing to expire */ case AUTOFS_IOC_EXPIRE: return autofs4_expire_run(inode->i_sb,filp->f_vfsmnt,sbi, - (struct autofs_packet_expire *)arg); + (struct autofs_packet_expire *)arg); /* same as above, but can send multiple expires through pipe */ case AUTOFS_IOC_EXPIRE_MULTI: return autofs4_expire_multi(inode->i_sb,filp->f_vfsmnt,sbi, - (int *)arg); + (int *)arg); default: return -ENOSYS; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 9ebea1ca7..1a0532420 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -1,7 +1,7 @@ /* * fs/bfs/dir.c * BFS directory operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@ocston.org> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> */ #include <linux/sched.h> diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 1da12e6ae..f0ee10a15 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -1,7 +1,7 @@ /* * fs/bfs/file.c * BFS file operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@ocston.org> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> */ #include <linux/fs.h> @@ -26,7 +26,7 @@ struct file_operations bfs_file_operations = { static int bfs_move_block(unsigned long from, unsigned long to, kdev_t dev) { - struct buffer_head *bh, *new = NULL; + struct buffer_head *bh, *new; bh = bread(dev, from, BFS_BSIZE); if (!bh) @@ -56,11 +56,12 @@ static int bfs_move_blocks(kdev_t dev, unsigned long start, unsigned long end, static int bfs_get_block(struct inode * inode, long block, struct buffer_head * bh_result, int create) { - long phys, next_free_block; + long phys; int err; - struct super_block *s = inode->i_sb; + struct super_block *sb = inode->i_sb; + struct buffer_head *sbh = sb->su_sbh; - if (block < 0 || block > s->su_blocks) + if (block < 0 || block > sb->su_blocks) return -EIO; phys = inode->iu_sblock + block; @@ -90,24 +91,25 @@ static int bfs_get_block(struct inode * inode, long block, /* if the last data block for this file is the last allocated block, we can extend the file trivially, without moving it anywhere */ - if (inode->iu_eblock == s->su_lf_eblk) { + if (inode->iu_eblock == sb->su_lf_eblk) { dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", create, block, phys); bh_result->b_dev = inode->i_dev; bh_result->b_blocknr = phys; bh_result->b_state |= (1UL << BH_Mapped); - s->su_lf_eblk = inode->iu_eblock = inode->iu_sblock + block; + sb->su_freeb -= phys - inode->iu_eblock; + sb->su_lf_eblk = inode->iu_eblock = phys; mark_inode_dirty(inode); - mark_buffer_dirty(s->su_sbh); + mark_buffer_dirty(sbh); err = 0; goto out; } /* Ok, we have to move this entire file to the next free block */ - next_free_block = s->su_lf_eblk + 1; + phys = sb->su_lf_eblk + 1; if (inode->iu_sblock) { /* if data starts on block 0 then there is no data */ err = bfs_move_blocks(inode->i_dev, inode->iu_sblock, - inode->iu_eblock, next_free_block); + inode->iu_eblock, phys); if (err) { dprintf("failed to move ino=%08lx -> fs corruption\n", inode->i_ino); goto out; @@ -115,12 +117,18 @@ static int bfs_get_block(struct inode * inode, long block, } else err = 0; - inode->iu_sblock = next_free_block; - s->su_lf_eblk = inode->iu_eblock = next_free_block + block; + dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys); + inode->iu_sblock = phys; + phys += block; + sb->su_lf_eblk = inode->iu_eblock = phys; + + /* this assumes nothing can write the inode back while we are here + * and thus update inode->i_blocks! (XXX)*/ + sb->su_freeb -= inode->iu_eblock - inode->iu_sblock + 1 - inode->i_blocks; mark_inode_dirty(inode); - mark_buffer_dirty(s->su_sbh); + mark_buffer_dirty(sbh); bh_result->b_dev = inode->i_dev; - bh_result->b_blocknr = inode->iu_sblock + block; + bh_result->b_blocknr = phys; bh_result->b_state |= (1UL << BH_Mapped); out: unlock_kernel(); @@ -153,8 +161,7 @@ struct address_space_operations bfs_aops = { sync_page: block_sync_page, prepare_write: bfs_prepare_write, commit_write: generic_commit_write, - bmap: bfs_bmap + bmap: bfs_bmap, }; -struct inode_operations bfs_file_inops = { -}; +struct inode_operations bfs_file_inops; diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index fe1396497..b3827a7ae 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -1,7 +1,7 @@ /* * fs/bfs/inode.c * BFS superblock and inode operations. - * Copyright (C) 1999 Tigran Aivazian <tigran@veritas.com> + * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. */ @@ -325,7 +325,7 @@ out: return NULL; } -static DECLARE_FSTYPE_DEV( bfs_fs_type, "bfs", bfs_read_super); +static DECLARE_FSTYPE_DEV(bfs_fs_type, "bfs", bfs_read_super); static int __init init_bfs_fs(void) { diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 445c47aa6..861ede356 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -33,6 +33,7 @@ #include <linux/smp_lock.h> #include <asm/uaccess.h> +#include <asm/param.h> #include <asm/pgalloc.h> #define DLINFO_ITEMS 13 @@ -159,23 +160,24 @@ create_elf_tables(char *p, int argc, int envc, sp -= 2; NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform); } - sp -= 2; + sp -= 3*2; NEW_AUX_ENT(0, AT_HWCAP, hwcap); + NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE); + NEW_AUX_ENT(2, AT_CLKTCK, CLOCKS_PER_SEC); if (exec) { - sp -= 11*2; + sp -= 10*2; NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff); NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr)); NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum); - NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE); - NEW_AUX_ENT(4, AT_BASE, interp_load_addr); - NEW_AUX_ENT(5, AT_FLAGS, 0); - NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry); - NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid); - NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid); - NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid); - NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid); + NEW_AUX_ENT(3, AT_BASE, interp_load_addr); + NEW_AUX_ENT(4, AT_FLAGS, 0); + NEW_AUX_ENT(5, AT_ENTRY, load_bias + exec->e_entry); + NEW_AUX_ENT(6, AT_UID, (elf_addr_t) current->uid); + NEW_AUX_ENT(7, AT_EUID, (elf_addr_t) current->euid); + NEW_AUX_ENT(8, AT_GID, (elf_addr_t) current->gid); + NEW_AUX_ENT(9, AT_EGID, (elf_addr_t) current->egid); } #undef NEW_AUX_ENT diff --git a/fs/buffer.c b/fs/buffer.c index 145e11793..4de38a0e4 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -586,7 +586,7 @@ unsigned int get_hardblocksize(kdev_t dev) These are two special cases. Normal usage imply the device driver to issue a sync on the device (without waiting I/O completation) and - then an invalidate_buffers call that doesn't trashes dirty buffers. */ + then an invalidate_buffers call that doesn't trash dirty buffers. */ void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers) { int i, nlist, slept; @@ -618,6 +618,8 @@ void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers) __remove_from_queues(bh); put_last_free(bh); } + /* else complain loudly? */ + write_unlock(&hash_table_lock); if (slept) goto out; @@ -706,7 +708,7 @@ void set_blocksize(kdev_t dev, int size) static void refill_freelist(int size) { if (!grow_buffers(size)) { - wakeup_bdflush(1); + wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */ current->policy |= SCHED_YIELD; schedule(); } @@ -1041,13 +1043,9 @@ struct buffer_head * breada(kdev_t dev, int block, int bufsize, blocks = (filesize - pos) >> (9+index); - if (blocks < (read_ahead[MAJOR(dev)] >> index)) - blocks = read_ahead[MAJOR(dev)] >> index; if (blocks > NBUF) blocks = NBUF; -/* if (blocks) printk("breada (new) %d blocks\n",blocks); */ - bhlist[0] = bh; j = 1; for(i=1; i<blocks; i++) { @@ -2060,7 +2058,7 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], buffer_heads and exit. */ spin_lock(&unused_list_lock); for (i = bhind; --i >= 0; ) { - __put_unused_buffer_head(bh[bhind]); + __put_unused_buffer_head(bh[i]); } spin_unlock(&unused_list_lock); goto finished; diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 1629be782..e1ab9e896 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -58,7 +58,7 @@ static int coda_venus_readdir(struct file *filp, void *dirent, filldir_t filldir); int coda_fsync(struct file *, struct dentry *dentry, int datasync); -int coda_hasmknod = 0; +int coda_hasmknod; struct dentry_operations coda_dentry_operations = { diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 94a3be389..45acf28c6 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -93,7 +93,7 @@ static int get_device_index(struct coda_mount_data *data) static struct super_block * coda_read_super(struct super_block *sb, void *data, int silent) { - struct inode *psdev = 0, *root = 0; + struct inode *root = 0; struct coda_sb_info *sbi = NULL; struct venus_comm *vc = NULL; ViceFid fid; diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 486e42185..ef05ac2fb 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -54,7 +54,7 @@ extern struct file_system_type coda_fs_type; /* statistics */ -int coda_hard = 0; /* allows signals during upcalls */ +int coda_hard; /* allows signals during upcalls */ unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */ @@ -376,7 +376,7 @@ static struct file_operations coda_psdev_fops = { release: coda_psdev_release, }; -static devfs_handle_t devfs_handle = NULL; +static devfs_handle_t devfs_handle; static int init_coda_psdev(void) { diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a0cf6ba97..4b34da094 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -95,7 +95,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE]; static unsigned buffer_blocknr[READ_BUFFERS]; static struct super_block * buffer_dev[READ_BUFFERS]; -static int next_buffer = 0; +static int next_buffer; /* * Returns a pointer to a buffer containing at least LEN bytes of diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 3ffb8275e..264992d3f 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -654,7 +654,7 @@ struct devfs_entry }; /* The root of the device tree */ -static struct devfs_entry *root_entry = NULL; +static struct devfs_entry *root_entry; struct devfsd_buf_entry { diff --git a/fs/devfs/util.c b/fs/devfs/util.c index 9f71763b1..05b681b6c 100644 --- a/fs/devfs/util.c +++ b/fs/devfs/util.c @@ -114,8 +114,8 @@ void devfs_register_tape (devfs_handle_t de) int pos; devfs_handle_t parent, slave; char name[16], dest[64]; - static unsigned int tape_counter = 0; - static devfs_handle_t tape_dir = NULL; + static unsigned int tape_counter; + static devfs_handle_t tape_dir; if (tape_dir == NULL) tape_dir = devfs_mk_dir (NULL, "tapes", NULL); parent = devfs_get_parent (de); @@ -314,9 +314,9 @@ int setup_arg_pages(struct linux_binprm *bprm) mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; mpnt->vm_private_data = (void *) 0; - vmlist_modify_lock(current->mm); + spin_lock(¤t->mm->page_table_lock); insert_vm_struct(current->mm, mpnt); - vmlist_modify_unlock(current->mm); + spin_unlock(¤t->mm->page_table_lock); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index e4234cb45..3c981f75c 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -183,25 +183,22 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry) return NULL; } +#define S_SHIFT 12 +static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { + [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, + [S_IFDIR >> S_SHIFT] EXT2_FT_DIR, + [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV, + [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV, + [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO, + [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK, + [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK, +}; + static inline void ext2_set_de_type(struct super_block *sb, struct ext2_dir_entry_2 *de, umode_t mode) { - if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) - return; - if (S_ISREG(mode)) - de->file_type = EXT2_FT_REG_FILE; - else if (S_ISDIR(mode)) - de->file_type = EXT2_FT_DIR; - else if (S_ISLNK(mode)) - de->file_type = EXT2_FT_SYMLINK; - else if (S_ISSOCK(mode)) - de->file_type = EXT2_FT_SOCK; - else if (S_ISFIFO(mode)) - de->file_type = EXT2_FT_FIFO; - else if (S_ISCHR(mode)) - de->file_type = EXT2_FT_CHRDEV; - else if (S_ISBLK(mode)) - de->file_type = EXT2_FT_BLKDEV; + if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) + de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; } /* @@ -437,7 +434,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) inode->i_nlink--; /* is this nlink == 0? */ mark_inode_dirty(inode); iput (inode); - return -EIO; + return err; } de = (struct ext2_dir_entry_2 *) dir_block->b_data; de->inode = cpu_to_le32(inode->i_ino); diff --git a/fs/fat/cvf.c b/fs/fat/cvf.c index 5bfbaeb64..91462e135 100644 --- a/fs/fat/cvf.c +++ b/fs/fat/cvf.c @@ -98,8 +98,8 @@ struct cvf_format bigblock_cvf = { NULL }; -struct cvf_format *cvf_formats[MAX_CVF_FORMATS]={NULL,NULL,NULL}; -int cvf_format_use_count[MAX_CVF_FORMATS]={0,0,0}; +struct cvf_format *cvf_formats[MAX_CVF_FORMATS]; +int cvf_format_use_count[MAX_CVF_FORMATS]; int register_cvf_format(struct cvf_format*cvf_format) { int i,j; diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c index fe8d02ad6..2e5127703 100644 --- a/fs/hfs/trans.c +++ b/fs/hfs/trans.c @@ -514,7 +514,7 @@ void hfs_latin2mac(struct hfs_name *out, const char *in, int len) int hi, lo; unsigned char code, c, *count; unsigned char *p = out->Name; - static int map_initialized = 0; + static int map_initialized; if (!map_initialized) { int i; diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 43eb2cb57..5f5ec196f 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -125,8 +125,7 @@ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head kdev_t dev = s->s_dev; struct buffer_head *bh; - /* vvvv - workaround for the breada bug */ - if (!ahead || secno + ahead + (read_ahead[MAJOR(dev)] >> 9) >= s->s_hpfs_fs_size) + if (!ahead || secno + ahead >= s->s_hpfs_fs_size) *bhp = bh = bread(dev, secno, 512); else *bhp = bh = breada(dev, secno, 512, 0, (ahead + 1) << 9); if (bh != NULL) @@ -174,8 +173,7 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe goto bail; } - /* vvvv - workaround for the breada bug */ - if (!ahead || secno + 4 + ahead + (read_ahead[MAJOR(dev)] >> 9) > s->s_hpfs_fs_size) + if (!ahead || secno + 4 + ahead > s->s_hpfs_fs_size) qbh->bh[0] = bh = bread(dev, secno, 512); else qbh->bh[0] = bh = breada(dev, secno, 512, 0, (ahead + 4) << 9); if (!bh) diff --git a/fs/inode.c b/fs/inode.c index ba0a3546f..96e3664e5 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -547,7 +547,7 @@ static void clean_inode(struct inode *inode) struct inode * get_empty_inode(void) { - static unsigned long last_ino = 0; + static unsigned long last_ino; struct inode * inode; inode = alloc_inode(); diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 4413b9989..1a7cbe374 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -215,7 +215,7 @@ int get_rock_ridge_filename(struct iso_directory_record * de, printk("RR: RE (%x)\n", inode->i_ino); #endif if (buffer) kfree(buffer); - return -1; + return 0; default: break; } diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 820bc4c7b..249e7514d 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -41,7 +41,7 @@ struct nlm_wait { u32 b_status; /* grant callback status */ }; -static struct nlm_wait * nlm_blocked = NULL; +static struct nlm_wait * nlm_blocked; /* * Block on a lock diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c60f48da1..dbe3f69b5 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -11,6 +11,7 @@ #include <linux/fs.h> #include <linux/nfs_fs.h> #include <linux/utsname.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> @@ -64,11 +65,11 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) int nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) { - nlmclnt_next_cookie(&call->a_args.cookie); - call->a_args.lock = *lock; + locks_copy_lock(&call->a_args.lock.fl, &lock->fl); + memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh)); call->a_args.lock.caller = system_utsname.nodename; + call->a_args.lock.oh.len = lock->oh.len; - init_waitqueue_head(&call->a_args.lock.fl.fl_wait); /* set default data area */ call->a_args.lock.oh.data = call->a_owner; @@ -406,15 +407,19 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) static void nlmclnt_insert_lock_callback(struct file_lock *fl) { + lock_kernel(); nlm_get_host(fl->fl_u.nfs_fl.host); + unlock_kernel(); } static void nlmclnt_remove_lock_callback(struct file_lock *fl) { + lock_kernel(); if (fl->fl_u.nfs_fl.host) { nlm_release_host(fl->fl_u.nfs_fl.host); fl->fl_u.nfs_fl.host = NULL; } + unlock_kernel(); } /* diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 283d66e97..9fcbad317 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -24,7 +24,7 @@ extern struct rpc_program nsm_program; /* * Local NSM state */ -u32 nsm_local_state = 0; +u32 nsm_local_state; /* * Common procedure for SM_MON/SM_UNMON calls diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index a175d39eb..5460e8c9f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -24,6 +24,8 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> #include <linux/lockd/nlm.h> @@ -40,7 +42,7 @@ static void nlmsvc_notify_blocked(struct file_lock *); /* * The list of blocked locks to retry */ -static struct nlm_block * nlm_blocked = NULL; +static struct nlm_block * nlm_blocked; /* * Insert a blocked lock into the global list @@ -53,9 +55,15 @@ nlmsvc_insert_block(struct nlm_block *block, unsigned long when) dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when); if (block->b_queued) nlmsvc_remove_block(block); - for (bp = &nlm_blocked; (b = *bp); bp = &b->b_next) - if (when < b->b_when) - break; + bp = &nlm_blocked; + if (when != NLM_NEVER) { + if ((when += jiffies) == NLM_NEVER) + when ++; + while ((b = *bp) && time_before_eq(b->b_when,when)) + bp = &b->b_next; + } else + while ((b = *bp)) + bp = &b->b_next; block->b_queued = 1; block->b_when = when; @@ -106,8 +114,10 @@ nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) (long long)fl->fl_end, fl->fl_type, *(unsigned int*)(block->b_call.a_args.cookie.data)); if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { - if (remove) + if (remove) { *head = block->b_next; + block->b_queued = 0; + } return block; } } @@ -173,10 +183,11 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file, locks_init_lock(&block->b_call.a_args.lock.fl); locks_init_lock(&block->b_call.a_res.lock.fl); - /* Set notifier function for VFS, and init args */ - lock->fl.fl_notify = nlmsvc_notify_blocked; if (!nlmclnt_setgrantargs(&block->b_call, lock)) goto failed_free; + + /* Set notifier function for VFS, and init args */ + block->b_call.a_args.lock.fl.fl_notify = nlmsvc_notify_blocked; block->b_call.a_args.cookie = *cookie; /* see above */ dprintk("lockd: created block %p...\n", block); @@ -349,7 +360,7 @@ again: /* Append to list of blocked */ nlmsvc_insert_block(block, NLM_NEVER); - if (list_empty(&block->b_call.a_args.lock.fl.fl_list)) { + if (list_empty(&block->b_call.a_args.lock.fl.fl_block)) { /* Now add block to block list of the conflicting lock if we haven't done so. */ dprintk("lockd: blocking on this lock.\n"); @@ -457,13 +468,15 @@ nlmsvc_notify_blocked(struct file_lock *fl) dprintk("lockd: VFS unblock notification for block %p\n", fl); posix_unblock_lock(fl); + lock_kernel(); for (bp = &nlm_blocked; (block = *bp); bp = &block->b_next) { if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { - svc_wake_up(block->b_daemon); nlmsvc_insert_block(block, 0); + svc_wake_up(block->b_daemon); return; } } + unlock_kernel(); printk(KERN_WARNING "lockd: notification for unknown block!\n"); } @@ -520,7 +533,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) if ((error = posix_lock_file(&file->f_file, &lock->fl, 0)) < 0) { printk(KERN_WARNING "lockd: unexpected error %d in %s!\n", -error, __FUNCTION__); - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); up(&file->f_sema); return; } @@ -532,7 +545,7 @@ callback: block->b_incall = 1; /* Schedule next grant callback in 30 seconds */ - nlmsvc_insert_block(block, jiffies + 30 * HZ); + nlmsvc_insert_block(block, 30 * HZ); /* Call the client */ nlm_get_host(block->b_call.a_host); @@ -570,13 +583,13 @@ nlmsvc_grant_callback(struct rpc_task *task) * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ - timeout = jiffies + 10 * HZ; + timeout = 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ - timeout = jiffies + 60 * HZ; + timeout = 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); @@ -604,7 +617,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) if ((block = nlmsvc_find_block(cookie)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ - nlmsvc_insert_block(block, jiffies + 10 * HZ); + nlmsvc_insert_block(block, 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. @@ -635,7 +648,11 @@ nlmsvc_retry_blocked(void) dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", nlm_blocked, nlm_blocked? nlm_blocked->b_when : 0); - while ((block = nlm_blocked) && block->b_when <= jiffies) { + while ((block = nlm_blocked)) { + if (block->b_when == NLM_NEVER) + break; + if (time_after(block->b_when,jiffies)) + break; dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", block, block->b_when, block->b_done); if (block->b_done) diff --git a/fs/locks.c b/fs/locks.c index 95310133d..0e92b740f 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -164,7 +164,7 @@ static inline void locks_free_lock(struct file_lock *fl) if (!list_empty(&fl->fl_block)) panic("Attempting to free lock with active block list"); - if (!list_empty(&fl->fl_link) || !list_empty(&fl->fl_list)) + if (!list_empty(&fl->fl_link)) panic("Attempting to free lock on active lock list"); kmem_cache_free(filelock_cache, fl); @@ -174,7 +174,6 @@ void locks_init_lock(struct file_lock *fl) { INIT_LIST_HEAD(&fl->fl_link); INIT_LIST_HEAD(&fl->fl_block); - INIT_LIST_HEAD(&fl->fl_list); init_waitqueue_head(&fl->fl_wait); fl->fl_next = NULL; fl->fl_fasync = NULL; @@ -403,8 +402,8 @@ locks_same_owner(struct file_lock *fl1, struct file_lock *fl2) */ static void locks_delete_block(struct file_lock *waiter) { - list_del(&waiter->fl_list); - INIT_LIST_HEAD(&waiter->fl_list); + list_del(&waiter->fl_block); + INIT_LIST_HEAD(&waiter->fl_block); list_del(&waiter->fl_link); INIT_LIST_HEAD(&waiter->fl_link); waiter->fl_next = NULL; @@ -418,13 +417,13 @@ static void locks_delete_block(struct file_lock *waiter) static void locks_insert_block(struct file_lock *blocker, struct file_lock *waiter) { - if (!list_empty(&waiter->fl_list)) { + if (!list_empty(&waiter->fl_block)) { printk(KERN_ERR "locks_insert_block: removing duplicated lock " "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid, waiter->fl_start, waiter->fl_end, waiter->fl_type); locks_delete_block(waiter); } - list_add_tail(&waiter->fl_list, &blocker->fl_block); + list_add_tail(&waiter->fl_block, &blocker->fl_block); waiter->fl_next = blocker; list_add(&waiter->fl_link, &blocked_list); } @@ -436,7 +435,7 @@ static void locks_insert_block(struct file_lock *blocker, static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait) { while (!list_empty(&blocker->fl_block)) { - struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_list); + struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_block); /* N.B. Is it possible for the notify function to block?? */ if (waiter->fl_notify) waiter->fl_notify(waiter); @@ -644,7 +643,6 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, caller_pid = caller_fl->fl_pid; blocked_owner = block_fl->fl_owner; blocked_pid = block_fl->fl_pid; - tmp = blocked_list.next; next_task: if (caller_owner == blocked_owner && caller_pid == blocked_pid) @@ -1708,7 +1706,7 @@ void posix_unblock_lock(struct file_lock *waiter) { acquire_fl_sem(); - if (!list_empty(&waiter->fl_list)) { + if (!list_empty(&waiter->fl_block)) { locks_delete_block(waiter); wake_up(&waiter->fl_wait); } @@ -1815,7 +1813,7 @@ int get_locks_status(char *buffer, char **start, off_t offset, int length) list_for_each(btmp, &fl->fl_block) { struct file_lock *bfl = list_entry(btmp, - struct file_lock, fl_list); + struct file_lock, fl_block); lock_get_status(q, bfl, i, " ->"); move_lock_status(&q, &pos, offset); diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index a268be2f1..dce2687ee 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -225,13 +225,16 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) int i,j; inode = get_empty_inode(); - if (!inode) + if (!inode) { + *error = -ENOMEM; return NULL; + } sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = 0; j = 8192; bh = NULL; + *error = -ENOSPC; lock_super(sb); for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) { bh = inode->i_sb->u.minix_sb.s_imap[i]; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 870656cb7..eadbb79e3 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -210,10 +210,8 @@ static int minix_create(struct inode * dir, struct dentry *dentry, int mode) struct minix_dir_entry * de; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_op = &minix_file_inode_operations; inode->i_fop = &minix_file_operations; inode->i_mapping->a_ops = &minix_aops; @@ -242,10 +240,8 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int struct minix_dir_entry * de; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_uid = current->fsuid; init_special_inode(inode, mode, rdev); mark_inode_dirty(inode); @@ -275,10 +271,8 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) if (dir->i_nlink >= info->s_link_max) return -EMLINK; inode = minix_new_inode(dir, &error); - if (error) - return error; if (!inode) - return -ENOSPC; + return error; inode->i_op = &minix_dir_inode_operations; inode->i_fop = &minix_dir_operations; inode->i_size = 2 * info->s_dirsize; @@ -461,9 +455,6 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry, if (i>1024) goto out; inode = minix_new_inode(dir, &err); - if (err) - goto out; - err = -ENOSPC; if (!inode) goto out; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ec4540f12..3f6b770aa 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -796,7 +796,7 @@ static int nfs_rmdir(struct inode *dir_i, struct dentry *dentry) static int nfs_sillyrename(struct inode *dir_i, struct dentry *dentry) { struct dentry *dir = dentry->d_parent; - static unsigned int sillycounter = 0; + static unsigned int sillycounter; const int i_inosize = sizeof(dir_i->i_ino)*2; const int countersize = sizeof(sillycounter)*2; const int slen = strlen(".nfs") + i_inosize + countersize; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 21ae090a3..c30fc5062 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -176,11 +176,16 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse */ static int nfs_sync_page(struct page *page) { - struct inode *inode = (struct inode *)page->mapping->host; + struct address_space *mapping; + struct inode *inode; unsigned long index = page_index(page); unsigned int rpages, wpages; int result; + mapping = page->mapping; + if (!mapping) + return 0; + inode = (struct inode *)mapping->host; if (!inode) return 0; @@ -281,7 +286,9 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) * Flush all pending writes before doing anything * with locks.. */ + down(&filp->f_dentry->d_inode->i_sem); status = nfs_wb_all(inode); + up(&filp->f_dentry->d_inode->i_sem); if (status < 0) return status; @@ -296,8 +303,10 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl) */ out_ok: if ((cmd == F_SETLK || cmd == F_SETLKW) && fl->fl_type != F_UNLCK) { + down(&filp->f_dentry->d_inode->i_sem); nfs_wb_all(inode); /* we may have slept */ nfs_zap_caches(inode); + up(&filp->f_dentry->d_inode->i_sem); } return status; } diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index a8b61c2e7..7fef7da99 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -104,7 +104,8 @@ xdr_decode_string2(u32 *p, char **string, unsigned int *len, static inline u32* xdr_decode_time(u32 *p, u64 *timep) { - *timep = ((u64)ntohl(*p++) << 32) + (u64)ntohl(*p++); + u64 tmp = (u64)ntohl(*p++) << 32; + *timep = tmp + (u64)ntohl(*p++); return p; } diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index ef8580c02..f6260a552 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -143,7 +143,8 @@ xdr_encode_time(u32 *p, time_t time) static inline u32 * xdr_decode_time3(u32 *p, u64 *timep) { - *timep = ((u64)ntohl(*p++) << 32) + (u64)ntohl(*p++); + u64 tmp = (u64)ntohl(*p++) << 32; + *timep = tmp + (u64)ntohl(*p++); return p; } @@ -184,7 +185,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) p = xdr_decode_hyper(p, &fattr->size); p = xdr_decode_hyper(p, &fattr->du.nfs3.used); /* Turn remote device info into Linux-specific dev_t */ - fattr->rdev = (ntohl(*p++) << MINORBITS) | (ntohl(*p++) & MINORMASK); + fattr->rdev = ntohl(*p++) << MINORBITS; + fattr->rdev |= ntohl(*p++) & MINORMASK; p = xdr_decode_hyper(p, &fattr->fsid); p = xdr_decode_hyper(p, &fattr->fileid); p = xdr_decode_time3(p, &fattr->atime); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6575040d9..7c1aad253 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -54,7 +54,7 @@ static void nfs_readpage_result(struct rpc_task *task); # define IS_SWAPFILE(inode) (0) #endif -static kmem_cache_t *nfs_rdata_cachep = NULL; +static kmem_cache_t *nfs_rdata_cachep; static __inline__ struct nfs_read_data *nfs_readdata_alloc(void) { diff --git a/fs/nfs/write.c b/fs/nfs/write.c index a5bda60ba..5346e6302 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -102,8 +102,8 @@ static void nfs_commit_done(struct rpc_task *); # define IS_SWAPFILE(inode) (0) #endif -static kmem_cache_t *nfs_page_cachep = NULL; -static kmem_cache_t *nfs_wdata_cachep = NULL; +static kmem_cache_t *nfs_page_cachep; +static kmem_cache_t *nfs_wdata_cachep; static __inline__ struct nfs_page *nfs_page_alloc(void) { @@ -1207,7 +1207,7 @@ nfs_writeback_done(struct rpc_task *task) /* We can't handle that yet but we check for it nevertheless */ if (resp->count < argp->count && task->tk_status >= 0) { - static unsigned long complain = 0; + static unsigned long complain; if (time_before(complain, jiffies)) { printk(KERN_WARNING "NFS: Server wrote less than requested.\n"); @@ -1227,7 +1227,7 @@ nfs_writeback_done(struct rpc_task *task) * NFS_FILE_SYNC. We therefore implement this checking * as a dprintk() in order to avoid filling syslog. */ - static unsigned long complain = 0; + static unsigned long complain; if (time_before(complain, jiffies)) { dprintk("NFS: faulty NFSv3 server %s:" @@ -1239,9 +1239,6 @@ nfs_writeback_done(struct rpc_task *task) } #endif - /* Update attributes as result of writeback. */ - nfs_write_attributes(inode, resp->fattr); - while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); @@ -1281,6 +1278,9 @@ nfs_writeback_done(struct rpc_task *task) next: nfs_unlock_request(req); } + /* Update attributes as result of writeback. */ + nfs_write_attributes(inode, resp->fattr); + } @@ -1395,7 +1395,6 @@ nfs_commit_done(struct rpc_task *task) dprintk("NFS: %4d nfs_commit_done (status %d)\n", task->tk_pid, task->tk_status); - nfs_refresh_inode(inode, resp->fattr); while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); @@ -1427,6 +1426,8 @@ nfs_commit_done(struct rpc_task *task) next: nfs_unlock_request(req); } + + nfs_write_attributes(inode, resp->fattr); } #endif diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index d97e1717d..4cf7c897c 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -144,9 +144,9 @@ decode_sattr3(u32 *p, struct iattr *iap) iap->ia_valid |= ATTR_SIZE; p = dec64(p, &newsize); if (newsize <= NFS_OFFSET_MAX) - iap->ia_size = (u32) newsize; + iap->ia_size = newsize; else - iap->ia_size = ~(size_t) 0; + iap->ia_size = NFS_OFFSET_MAX; } if ((tmp = ntohl(*p++)) == 1) { /* set to server time */ iap->ia_valid |= ATTR_ATIME; diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 425778412..8a061ebcb 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -38,7 +38,7 @@ static struct nfscache_head * hash_list; static struct svc_cacherep * lru_head; static struct svc_cacherep * lru_tail; static struct svc_cacherep * nfscache; -static int cache_initialized = 0; +static int cache_initialized; static int cache_disabled = 1; static int nfsd_cache_append(struct svc_rqst *rqstp, struct svc_buf *data); @@ -215,7 +215,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) /* This should not happen */ if (rp == NULL) { - static int complaints = 0; + static int complaints; printk(KERN_WARNING "nfsd: all repcache entries locked!\n"); if (++complaints > 5) { diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 672d66bf8..7bf572e34 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -25,8 +25,8 @@ /* #define NFSD_DEBUG_VERBOSE 1 */ -static int nfsd_nr_verified = 0; -static int nfsd_nr_put = 0; +static int nfsd_nr_verified; +static int nfsd_nr_put; struct nfsd_getdents_callback { diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a796885e3..f01f1de86 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -74,8 +74,8 @@ struct raparms { p_rawin; }; -static struct raparms * raparml = NULL; -static struct raparms * raparm_cache = NULL; +static struct raparms * raparml; +static struct raparms * raparm_cache; /* * Look up one component of a pathname. @@ -714,7 +714,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, } if (err >= 0 && stable) { - static unsigned long last_ino = 0; + static unsigned long last_ino; static kdev_t last_dev = NODEV; /* diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 3ea51cdfa..e98d8490c 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -20,7 +20,7 @@ #endif #include <linux/spinlock.h> -static struct nls_table *tables = (struct nls_table *) NULL; +static struct nls_table *tables; static spinlock_t nls_lock = SPIN_LOCK_UNLOCKED; /* diff --git a/fs/nls/nls_big5.c b/fs/nls/nls_big5.c index 847904ba1..250098337 100644 --- a/fs/nls/nls_big5.c +++ b/fs/nls/nls_big5.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "big5", diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c index 98b380e59..196a07698 100644 --- a/fs/nls/nls_euc-jp.c +++ b/fs/nls/nls_euc-jp.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; #define SS2 (0x8E) /* Single Shift 2 */ diff --git a/fs/nls/nls_euc-kr.c b/fs/nls/nls_euc-kr.c index 5219c2371..f015c21bf 100644 --- a/fs/nls/nls_euc-kr.c +++ b/fs/nls/nls_euc-kr.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "euc-kr", diff --git a/fs/nls/nls_gb2312.c b/fs/nls/nls_gb2312.c index 542a10e97..06c184a27 100644 --- a/fs/nls/nls_gb2312.c +++ b/fs/nls/nls_gb2312.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "gb2312", diff --git a/fs/nls/nls_sjis.c b/fs/nls/nls_sjis.c index ec6fb598f..463ee02a5 100644 --- a/fs/nls/nls_sjis.c +++ b/fs/nls/nls_sjis.c @@ -8,7 +8,7 @@ #include <linux/nls.h> #include <linux/errno.h> -static struct nls_table *p_nls = NULL; +static struct nls_table *p_nls; static struct nls_table table = { "sjis", diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index c99e81e6a..f9ffb0a40 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -416,8 +416,7 @@ static struct file_operations ntfs_file_operations_nommap = { #endif }; -static struct inode_operations ntfs_inode_operations_nobmap = { -}; +static struct inode_operations ntfs_inode_operations_nobmap; #ifdef CONFIG_NTFS_RW static int @@ -577,8 +576,7 @@ static struct file_operations ntfs_file_operations = { #endif }; -static struct inode_operations ntfs_inode_operations = { -}; +static struct inode_operations ntfs_inode_operations; static struct file_operations ntfs_dir_operations = { read: generic_read_dir, @@ -103,7 +103,7 @@ static inline long do_sys_truncate(const char * path, loff_t length) inode = nd.dentry->d_inode; error = -EACCES; - if (S_ISDIR(inode->i_mode)) + if (!S_ISREG(inode->i_mode)) goto dput_and_out; error = permission(inode,MAY_WRITE); @@ -164,7 +164,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length) dentry = file->f_dentry; inode = dentry->d_inode; error = -EACCES; - if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) + if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) goto out_putf; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) diff --git a/fs/partitions/atari.c b/fs/partitions/atari.c index a94f8f5fc..0180daca8 100644 --- a/fs/partitions/atari.c +++ b/fs/partitions/atari.c @@ -62,6 +62,7 @@ int atari_partition (struct gendisk *hd, kdev_t dev, /* if there's no valid primary partition, assume that no Atari format partition table (there's no reliable magic or the like :-() */ + brelse(bh); return 0; } diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 5d4c2526c..87b88d04a 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -338,8 +338,8 @@ static void devfs_register_disc (struct gendisk *dev, int minor) devfs_handle_t dir, slave; unsigned int devfs_flags = DEVFS_FL_DEFAULT; char dirname[64], symlink[16]; - static unsigned int disc_counter = 0; - static devfs_handle_t devfs_handle = NULL; + static unsigned int disc_counter; + static devfs_handle_t devfs_handle; if (dev->part[minor].de) return; if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) @@ -284,7 +284,7 @@ pipe_poll(struct file *filp, poll_table *wait) poll_wait(filp, PIPE_WAIT(*inode), wait); - /* Reading only -- no need for aquiring the semaphore. */ + /* Reading only -- no need for acquiring the semaphore. */ mask = POLLIN | POLLRDNORM; if (PIPE_EMPTY(*inode)) mask = POLLOUT | POLLWRNORM; diff --git a/fs/proc/array.c b/fs/proc/array.c index 81884a281..d12a577fa 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -157,7 +157,7 @@ static inline char * task_state(struct task_struct *p, char *buffer) "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), - p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_opptr->pid : 0, + p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_pptr->pid : 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); read_unlock(&tasklist_lock); @@ -575,7 +575,7 @@ ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * goto getlen_out; /* Check whether the mmaps could change if we sleep */ - volatile_task = (task != current || atomic_read(&mm->mm_users) > 1); + volatile_task = (task != current || atomic_read(&mm->mm_users) > 2); /* decode f_pos */ lineno = *ppos >> MAPS_LINE_SHIFT; diff --git a/fs/proc/base.c b/fs/proc/base.c index 7625e4d5a..a1f7efe0f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -347,6 +347,10 @@ static ssize_t mem_read(struct file * file, char * buf, return copied; } +#define mem_write NULL + +#ifndef mem_write +/* This is a security hazard */ static ssize_t mem_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { @@ -385,6 +389,7 @@ static ssize_t mem_write(struct file * file, const char * buf, free_page((unsigned long) page); return copied; } +#endif static struct file_operations proc_mem_operations = { read: mem_read, diff --git a/fs/super.c b/fs/super.c index fb5c5895c..4f2e3908a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -884,24 +884,27 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type, return sb; } -static struct block_device *kill_super(struct super_block *sb, int umount_root) +static void kill_super(struct super_block *sb, int umount_root) { struct block_device *bdev; kdev_t dev; struct dentry *root = sb->s_root; + struct file_system_type *fs = sb->s_type; + struct super_operations *sop = sb->s_op; + sb->s_root = NULL; /* Need to clean after the sucker */ - if (sb->s_type->fs_flags & FS_LITTER) + if (fs->fs_flags & FS_LITTER) d_genocide(root); - if (sb->s_type->fs_flags & (FS_SINGLE|FS_LITTER)) + if (fs->fs_flags & (FS_SINGLE|FS_LITTER)) shrink_dcache_parent(root); dput(root); lock_super(sb); - if (sb->s_op) { - if (sb->s_op->write_super && sb->s_dirt) - sb->s_op->write_super(sb); - if (sb->s_op->put_super) - sb->s_op->put_super(sb); + if (sop) { + if (sop->write_super && sb->s_dirt) + sop->write_super(sb); + if (sop->put_super) + sop->put_super(sb); } /* Forget any remaining inodes */ @@ -914,7 +917,7 @@ static struct block_device *kill_super(struct super_block *sb, int umount_root) sb->s_dev = 0; /* Free the superblock */ bdev = sb->s_bdev; sb->s_bdev = NULL; - put_filesystem(sb->s_type); + put_filesystem(fs); sb->s_type = NULL; unlock_super(sb); if (umount_root) { @@ -928,7 +931,6 @@ static struct block_device *kill_super(struct super_block *sb, int umount_root) bdput(bdev); } else put_unnamed_dev(dev); - return bdev; } /* diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c index 4aebe9bda..4b661b5af 100644 --- a/fs/umsdos/inode.c +++ b/fs/umsdos/inode.c @@ -22,8 +22,8 @@ extern struct dentry_operations umsdos_dentry_operations; -struct dentry *saved_root = NULL; /* Original root if changed */ -struct inode *pseudo_root = NULL; /* Useful to simulate the pseudo DOS */ +struct dentry *saved_root; /* Original root if changed */ +struct inode *pseudo_root; /* Useful to simulate the pseudo DOS */ /* directory. See UMSDOS_readdir_x() */ static struct dentry *check_pseudo_root(struct super_block *); diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 0ac6d5314..1f4829709 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -618,12 +618,11 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, sz = len; ext_start = NULL; } - break; + goto stop0; } } - if (charbuf[chi] == '.') - break; } +stop0:; if (ext_start == name - 1) { sz = len; ext_start = NULL; @@ -640,10 +639,12 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, if (chl == 0) break; for (chi = 0; chi < chl; chi++) - if (!strchr(skip_chars, charbuf[chi])) - break; + if (!strchr(skip_chars, charbuf[chi])) { + goto stop1; + } name_start++; } +stop1:; if (name_start != ext_start) { sz = ext_start - name; ext_start++; |