summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
commitb63ad0882a16a5d28003e57f2b0b81dee3fb322b (patch)
tree0a343ce219e2b8b38a5d702d66032c57b83d9720 /fs
parenta9d7bff9a84dba79609a0002e5321b74c4d64c64 (diff)
Merge with 2.4.0-test11.
Diffstat (limited to 'fs')
-rw-r--r--fs/Config.in1
-rw-r--r--fs/adfs/inode.c4
-rw-r--r--fs/affs/inode.c7
-rw-r--r--fs/affs/symlink.c2
-rw-r--r--fs/autofs/inode.c1
-rw-r--r--fs/autofs4/inode.c8
-rw-r--r--fs/bfs/dir.c4
-rw-r--r--fs/buffer.c13
-rw-r--r--fs/coda/symlink.c2
-rw-r--r--fs/cramfs/inode.c14
-rw-r--r--fs/devfs/base.c7
-rw-r--r--fs/devpts/inode.c9
-rw-r--r--fs/dnotify.c11
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/efs/dir.c3
-rw-r--r--fs/efs/symlink.c2
-rw-r--r--fs/exec.c4
-rw-r--r--fs/ext2/ialloc.c9
-rw-r--r--fs/fat/inode.c10
-rw-r--r--fs/fcntl.c4
-rw-r--r--fs/file_table.c7
-rw-r--r--fs/hpfs/namei.c2
-rw-r--r--fs/isofs/dir.c100
-rw-r--r--fs/isofs/inode.c249
-rw-r--r--fs/isofs/joliet.c3
-rw-r--r--fs/isofs/namei.c197
-rw-r--r--fs/isofs/rock.c2
-rw-r--r--fs/jffs/inode-v23.c7
-rw-r--r--fs/jffs/intrep.c141
-rw-r--r--fs/lockd/clntlock.c4
-rw-r--r--fs/lockd/clntproc.c4
-rw-r--r--fs/lockd/svclock.c2
-rw-r--r--fs/locks.c115
-rw-r--r--fs/minix/bitmap.c8
-rw-r--r--fs/namei.c7
-rw-r--r--fs/ncpfs/dir.c6
-rw-r--r--fs/ncpfs/file.c9
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/ncpfs/ioctl.c10
-rw-r--r--fs/ncpfs/mmap.c7
-rw-r--r--fs/ncpfs/ncplib_kernel.c2
-rw-r--r--fs/ncpfs/symlink.c2
-rw-r--r--fs/nfs/dir.c8
-rw-r--r--fs/nfs/inode.c7
-rw-r--r--fs/nfs/read.c4
-rw-r--r--fs/nfs/symlink.c4
-rw-r--r--fs/nfs/write.c23
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/ntfs/fs.c8
-rw-r--r--fs/ntfs/inode.c6
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--fs/pipe.c4
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/base.c32
-rw-r--r--fs/proc/generic.c10
-rw-r--r--fs/proc/inode.c15
-rw-r--r--fs/proc/proc_misc.c174
-rw-r--r--fs/proc/root.c14
-rw-r--r--fs/ramfs/inode.c15
-rw-r--r--fs/select.c9
-rw-r--r--fs/smbfs/cache.c8
-rw-r--r--fs/smbfs/inode.c4
-rw-r--r--fs/sysv/ialloc.c8
-rw-r--r--fs/udf/dir.c6
-rw-r--r--fs/udf/file.c4
-rw-r--r--fs/udf/ialloc.c10
-rw-r--r--fs/udf/inode.c7
-rw-r--r--fs/udf/symlink.c2
-rw-r--r--fs/ufs/ialloc.c10
-rw-r--r--fs/umsdos/dir.c2
-rw-r--r--fs/umsdos/emd.c8
71 files changed, 516 insertions, 897 deletions
diff --git a/fs/Config.in b/fs/Config.in
index d728d2166..53380d067 100644
--- a/fs/Config.in
+++ b/fs/Config.in
@@ -117,6 +117,7 @@ if [ "$CONFIG_NET" = "y" ]; then
else
# for fs/nls/Config.in
define_bool CONFIG_NCPFS_NLS n
+ define_bool CONFIG_SMB_FS n
fi
mainmenu_option next_comment
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index c1c621179..42f19e292 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -245,13 +245,11 @@ adfs_iget(struct super_block *sb, struct object_info *obj)
{
struct inode *inode;
- inode = get_empty_inode();
+ inode = new_inode(sb);
if (!inode)
goto out;
inode->i_version = ++event;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_uid = sb->u.adfs_sb.s_uid;
inode->i_gid = sb->u.adfs_sb.s_gid;
inode->i_ino = obj->file_id;
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 2f8c36aa5..fcb7e103a 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -306,18 +306,19 @@ affs_new_inode(const struct inode *dir)
struct super_block *sb;
s32 block;
- if (!dir || !(inode = get_empty_inode()))
+ if (!dir)
return NULL;
sb = dir->i_sb;
- inode->i_sb = sb;
+ inode = new_inode(sb);
+ if (!inode)
+ return NULL;
if (!(block = affs_new_header((struct inode *)dir))) {
iput(inode);
return NULL;
}
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
inode->i_gid = current->fsgid;
inode->i_ino = block;
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index f7e78a75d..b125dee4e 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -20,7 +20,7 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
{
struct buffer_head *bh;
struct inode *inode = (struct inode*)page->mapping->host;
- char *link = (char*)kmap(page);
+ char *link = kmap(page);
struct slink_front *lf;
int err;
int i, j;
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index ae157d1ac..0eb91f3c2 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -211,7 +211,6 @@ static void autofs_read_inode(struct inode *inode)
inode->i_fop = &autofs_dir_operations;
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
inode->i_nlink = 2;
- inode->i_size = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_blocks = 0;
inode->i_blksize = 1024;
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 077df4c2b..dd7dd07ac 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -292,14 +292,12 @@ static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
struct inode *autofs4_get_inode(struct super_block *sb,
struct autofs_info *inf)
{
- struct inode *inode = get_empty_inode();
+ struct inode *inode = new_inode(sb);
if (inode == NULL)
return NULL;
inf->inode = inode;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_mode = inf->mode;
if (sb->s_root) {
inode->i_uid = sb->s_root->d_inode->i_uid;
@@ -308,13 +306,9 @@ struct inode *autofs4_get_inode(struct super_block *sb,
inode->i_uid = 0;
inode->i_gid = 0;
}
- inode->i_size = 0;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_rdev = 0;
- inode->i_nlink = 1;
- inode->i_op = NULL;
- inode->i_fop = NULL;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
if (S_ISDIR(inf->mode)) {
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 1a0532420..5caf04a7b 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -80,10 +80,9 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode)
struct super_block * s = dir->i_sb;
unsigned long ino;
- inode = get_empty_inode();
+ inode = new_inode(s);
if (!inode)
return -ENOSPC;
- inode->i_sb = s;
ino = find_first_zero_bit(s->su_imap, s->su_lasti);
if (ino > s->su_lasti) {
iput(inode);
@@ -91,7 +90,6 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode)
}
set_bit(ino, s->su_imap);
s->su_freei--;
- inode->i_dev = s->s_dev;
inode->i_uid = current->fsuid;
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
diff --git a/fs/buffer.c b/fs/buffer.c
index 4de38a0e4..9f9fbbfbd 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -707,11 +707,8 @@ void set_blocksize(kdev_t dev, int size)
*/
static void refill_freelist(int size)
{
- if (!grow_buffers(size)) {
+ if (!grow_buffers(size))
wakeup_bdflush(1); /* Sets task->state to TASK_RUNNING */
- current->policy |= SCHED_YIELD;
- schedule();
- }
}
void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
@@ -1470,7 +1467,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
int err = 0;
unsigned blocksize, bbits;
struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
- char *kaddr = (char *)kmap(page);
+ char *kaddr = kmap(page);
blocksize = inode->i_sb->s_blocksize;
if (!page->buffers)
@@ -1585,7 +1582,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
unsigned long iblock, lblock;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
unsigned int blocksize, blocks;
- unsigned long kaddr = 0;
+ char *kaddr = NULL;
int nr, i;
if (!PageLocked(page))
@@ -1614,7 +1611,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
if (!buffer_mapped(bh)) {
if (!kaddr)
kaddr = kmap(page);
- memset((char *)(kaddr + i*blocksize), 0, blocksize);
+ memset(kaddr + i*blocksize, 0, blocksize);
flush_dcache_page(page);
set_bit(BH_Uptodate, &bh->b_state);
continue;
@@ -1818,7 +1815,7 @@ int block_truncate_page(struct address_space *mapping, loff_t from, get_block_t
goto unlock;
}
- memset((char *) kmap(page) + offset, 0, length);
+ memset(kmap(page) + offset, 0, length);
flush_dcache_page(page);
kunmap(page);
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c
index dbdc946f4..2df6cf719 100644
--- a/fs/coda/symlink.c
+++ b/fs/coda/symlink.c
@@ -28,7 +28,7 @@ static int coda_symlink_filler(struct file *file, struct page *page)
int error;
struct coda_inode_info *cnp;
unsigned int len = PAGE_SIZE;
- char *p = (char*)kmap(page);
+ char *p = kmap(page);
lock_kernel();
cnp = ITOC(inode);
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 4b34da094..51eff1caa 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -34,7 +34,7 @@ static struct address_space_operations cramfs_aops;
static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode)
{
- struct inode * inode = get_empty_inode();
+ struct inode * inode = new_inode(sb);
if (inode) {
inode->i_mode = cramfs_inode->mode;
@@ -42,14 +42,10 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
inode->i_size = cramfs_inode->size;
inode->i_gid = cramfs_inode->gid;
inode->i_ino = CRAMINO(cramfs_inode);
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
- inode->i_nlink = 1; /* arguably wrong for directories,
- but it's the best we can do
- without reading the directory
- contents. 1 yields the right
- result in GNU find, even
- without -noleaf option. */
+ /* inode->i_nlink is left 1 - arguably wrong for directories,
+ but it's the best we can do without reading the directory
+ contents. 1 yields the right result in GNU find, even
+ without -noleaf option. */
insert_inode_hash(inode);
if (S_ISREG(inode->i_mode)) {
inode->i_fop = &generic_ro_fops;
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 264992d3f..5c412e301 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2250,7 +2250,6 @@ static void devfs_read_inode (struct inode *inode)
printk ("%s: read_inode(%d): VFS inode: %p devfs_entry: %p\n",
DEVFS_NAME, (int) inode->i_ino, inode, de);
#endif
- inode->i_size = 0;
inode->i_blocks = 0;
inode->i_blksize = 1024;
inode->i_op = &devfs_iops;
@@ -2416,11 +2415,6 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
struct devfs_entry *parent, *de;
struct inode *inode = file->f_dentry->d_inode;
- if (inode == NULL)
- {
- printk ("%s: readdir(): NULL inode\n", DEVFS_NAME);
- return -EBADF;
- }
if ( !S_ISDIR (inode->i_mode) )
{
printk ("%s: readdir(): inode is not a directory\n", DEVFS_NAME);
@@ -3185,6 +3179,7 @@ static ssize_t devfsd_read (struct file *file, char *buf, size_t len,
current->state = TASK_RUNNING;
return -EINTR;
}
+ set_current_state(TASK_INTERRUPTIBLE);
}
remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
current->state = TASK_RUNNING;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index c3667b208..0bb8826d8 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -140,14 +140,11 @@ struct super_block *devpts_read_super(struct super_block *s, void *data,
goto fail_free;
}
- inode = get_empty_inode();
+ inode = new_inode(s);
if (!inode)
goto fail_free;
- inode->i_sb = s;
- inode->i_dev = s->s_dev;
inode->i_ino = 1;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_size = 0;
inode->i_blocks = 0;
inode->i_blksize = 1024;
inode->i_uid = inode->i_gid = 0;
@@ -192,11 +189,9 @@ void devpts_pty_new(int number, kdev_t device)
if ( sbi->inodes[number] )
return; /* Already registered, this does happen */
- inode = get_empty_inode();
+ inode = new_inode(sb);
if (!inode)
return;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_ino = number+2;
inode->i_blocks = 0;
inode->i_blksize = 1024;
diff --git a/fs/dnotify.c b/fs/dnotify.c
index 90fd86b06..5711e6b41 100644
--- a/fs/dnotify.c
+++ b/fs/dnotify.c
@@ -103,14 +103,14 @@ void __inode_dir_notify(struct inode *inode, unsigned long event)
write_lock(&dn_lock);
prev = &inode->i_dnotify;
while ((dn = *prev) != NULL) {
- if ((dn->dn_mask & event) == 0) {
- prev = &dn->dn_next;
- continue;
- }
if (dn->dn_magic != DNOTIFY_MAGIC) {
printk(KERN_ERR "__inode_dir_notify: bad magic "
"number in dnotify_struct!\n");
- return;
+ goto out;
+ }
+ if ((dn->dn_mask & event) == 0) {
+ prev = &dn->dn_next;
+ continue;
}
fown = &dn->dn_filp->f_owner;
if (fown->pid)
@@ -125,6 +125,7 @@ void __inode_dir_notify(struct inode *inode, unsigned long event)
}
if (changed)
redo_inode_mask(inode);
+out:
write_unlock(&dn_lock);
}
diff --git a/fs/dquot.c b/fs/dquot.c
index ef1f15016..1bcd12ceb 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -679,8 +679,6 @@ restart:
if (!filp->f_dentry)
continue;
inode = filp->f_dentry->d_inode;
- if (!inode)
- continue;
if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
file_list_unlock();
sb->dq_op->initialize(inode, type);
diff --git a/fs/efs/dir.c b/fs/efs/dir.c
index ac64b8aeb..9bba7a2cb 100644
--- a/fs/efs/dir.c
+++ b/fs/efs/dir.c
@@ -28,9 +28,6 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
int slot, namelen;
char *nameptr;
- if (!inode || !S_ISDIR(inode->i_mode))
- return -EBADF;
-
if (inode->i_size & (EFS_DIRBSIZE-1))
printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n");
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c
index 20840409d..d1c788cc2 100644
--- a/fs/efs/symlink.c
+++ b/fs/efs/symlink.c
@@ -13,7 +13,7 @@
static int efs_symlink_readpage(struct file *file, struct page *page)
{
- char *link = (char*)kmap(page);
+ char *link = kmap(page);
struct buffer_head * bh;
struct inode * inode = (struct inode*)page->mapping->host;
efs_block_t size = inode->i_size;
diff --git a/fs/exec.c b/fs/exec.c
index 203100d33..1e24a4ace 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -212,7 +212,7 @@ int copy_strings(int argc,char ** argv, struct linux_binprm *bprm)
return -ENOMEM;
new = 1;
}
- kaddr = (char *)kmap(page);
+ kaddr = kmap(page);
if (new && offset)
memset(kaddr, 0, offset);
@@ -748,7 +748,7 @@ void remove_arg_zero(struct linux_binprm *bprm)
kunmap(page);
inside:
page = bprm->page[bprm->p/PAGE_SIZE];
- kaddr = (char *)kmap(page);
+ kaddr = kmap(page);
}
kunmap(page);
bprm->argc--;
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index adaab9c74..cf8fa5154 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -274,15 +274,13 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)
return NULL;
}
- inode = get_empty_inode ();
+ sb = dir->i_sb;
+ inode = new_inode(sb);
if (!inode) {
*err = -ENOMEM;
return NULL;
}
- sb = dir->i_sb;
- inode->i_sb = sb;
- inode->i_flags = 0;
lock_super (sb);
es = sb->u.ext2_sb.s_es;
repeat:
@@ -430,9 +428,6 @@ repeat:
mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
sb->s_dirt = 1;
inode->i_mode = mode;
- inode->i_sb = sb;
- inode->i_nlink = 1;
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
if (test_opt (sb, GRPID))
inode->i_gid = dir->i_gid;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index d1e8557f7..7537ee569 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -138,13 +138,11 @@ struct inode *fat_build_inode(struct super_block *sb,
inode = fat_iget(sb, ino);
if (inode)
goto out;
- inode = get_empty_inode();
+ inode = new_inode(sb);
*res = -ENOMEM;
if (!inode)
goto out;
*res = 0;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
fat_fill_inode(inode, de);
fat_attach(inode, ino);
@@ -658,11 +656,9 @@ fat_read_super(struct super_block *sb, void *data, int silent,
if (! sbi->nls_io)
sbi->nls_io = load_nls_default();
- root_inode=get_empty_inode();
+ root_inode=new_inode(sb);
if (!root_inode)
goto out_unload_nls;
- root_inode->i_sb = sb;
- root_inode->i_dev = sb->s_dev;
root_inode->i_ino = MSDOS_ROOT_INO;
fat_read_root(root_inode);
insert_inode_hash(root_inode);
@@ -798,7 +794,6 @@ static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_nlink = 1;
}
#endif
- inode->i_size = 0;
if ((nr = MSDOS_I(inode)->i_start) != 0)
while (nr != -1) {
inode->i_size += SECTOR_SIZE*sbi->cluster_size;
@@ -822,7 +817,6 @@ static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
(CF_LE_W(de->starthi) << 16);
}
MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
- inode->i_nlink = 1;
inode->i_size = CF_LE_L(de->size);
inode->i_op = &fat_file_inode_operations;
inode->i_fop = &fat_file_operations;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index d075c5c4e..9c9fcafbc 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -391,13 +391,13 @@ static void send_sigio_to_task(struct task_struct *p,
back to SIGIO in that case. --sct */
si.si_signo = fown->signum;
si.si_errno = 0;
- si.si_code = reason;
+ si.si_code = reason & ~__SI_MASK;
/* Make sure we are called with one of the POLL_*
reasons, otherwise we could leak kernel stack into
userspace. */
if ((reason & __SI_MASK) != __SI_POLL)
BUG();
- if (reason - POLL_IN > NSIGPOLL)
+ if (reason - POLL_IN >= NSIGPOLL)
si.si_band = ~0L;
else
si.si_band = band_table[reason - POLL_IN];
diff --git a/fs/file_table.c b/fs/file_table.c
index 931314661..09b28574d 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -176,10 +176,13 @@ int fs_may_remount_ro(struct super_block *sb)
file_list_lock();
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *file = list_entry(p, struct file, f_list);
- struct inode *inode = file->f_dentry->d_inode;
- if (!inode)
+ struct inode *inode;
+
+ if (!file->f_dentry)
continue;
+ inode = file->f_dentry->d_inode;
+
/* File with pending delete? */
if (inode->i_nlink == 0)
goto too_bad;
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index 3438cdb85..0d38b408c 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -401,7 +401,7 @@ int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
int hpfs_symlink_readpage(struct file *file, struct page *page)
{
- char *link = (char*)kmap(page);
+ char *link = kmap(page);
struct inode *i = (struct inode*)page->mapping->host;
struct fnode *fnode;
struct buffer_head *bh;
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 41b201767..c9915cf80 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -40,14 +40,17 @@ struct inode_operations isofs_dir_inode_operations =
lookup: isofs_lookup,
};
-static int isofs_name_translate(char * old, int len, char * new)
+int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
{
- int i, c;
+ char * old = de->name;
+ int len = de->name_len[0];
+ int i;
for (i = 0; i < len; i++) {
- c = old[i];
+ unsigned char c = old[i];
if (!c)
break;
+
if (c >= 'A' && c <= 'Z')
c |= 0x20; /* lower case */
@@ -74,8 +77,7 @@ int get_acorn_filename(struct iso_directory_record * de,
{
int std;
unsigned char * chr;
- int retnamlen = isofs_name_translate(de->name,
- de->name_len[0], retname);
+ int retnamlen = isofs_name_translate(de, retname, inode);
if (retnamlen == 0) return 0;
std = sizeof(struct iso_directory_record) + de->name_len[0];
if (std & 1) std++;
@@ -105,7 +107,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
unsigned int block, offset;
int inode_number = 0; /* Quiet GCC */
- struct buffer_head *bh;
+ struct buffer_head *bh = NULL;
int len;
int map;
int high_sierra;
@@ -117,46 +119,22 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
return 0;
offset = filp->f_pos & (bufsize - 1);
- block = isofs_bmap(inode, filp->f_pos >> bufbits);
+ block = filp->f_pos >> bufbits;
high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
- if (!block)
- return 0;
-
- if (!(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size)))
- return 0;
-
while (filp->f_pos < inode->i_size) {
int de_len;
-#ifdef DEBUG
- printk("Block, offset, f_pos: %x %x %x\n",
- block, offset, filp->f_pos);
- printk("inode->i_size = %x\n",inode->i_size);
-#endif
- /* Next directory_record on next CDROM sector */
- if (offset >= bufsize) {
-#ifdef DEBUG
- printk("offset >= bufsize\n");
-#endif
- brelse(bh);
- offset = 0;
- block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
- if (!block)
- return 0;
- bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
+
+ if (!bh) {
+ bh = isofs_bread(inode, bufsize, block);
if (!bh)
return 0;
- continue;
}
de = (struct iso_directory_record *) (bh->b_data + offset);
- if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
+ if (first_de) inode_number = (bh->b_blocknr << bufbits) + offset;
de_len = *(unsigned char *) de;
-#ifdef DEBUG
- printk("de_len = %d\n", de_len);
-#endif
-
/* If the length byte is zero, we should move on to the next
CDROM sector. If we are at the end of the directory, we
@@ -164,36 +142,33 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
if (de_len == 0) {
brelse(bh);
- filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
- + ISOFS_BLOCK_SIZE);
+ bh = NULL;
+ filp->f_pos = (filp->f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
+ block = filp->f_pos >> bufbits;
offset = 0;
-
- if (filp->f_pos >= inode->i_size)
- return 0;
-
- block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
- if (!block)
- return 0;
- bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
- if (!bh)
- return 0;
continue;
}
- offset += de_len;
- if (offset > bufsize) {
- /*
- * This would only normally happen if we had
- * a buggy cdrom image. All directory
- * entries should terminate with a null size
- * or end exactly at the end of the sector.
- */
- printk("next_offset (%x) > bufsize (%lx)\n",
- offset,bufsize);
- break;
+ offset += de_len;
+
+ /* Make sure we have a full directory entry */
+ if (offset >= bufsize) {
+ int slop = bufsize - offset + de_len;
+ memcpy(tmpde, de, slop);
+ offset &= bufsize - 1;
+ block++;
+ brelse(bh);
+ bh = NULL;
+ if (offset) {
+ bh = isofs_bread(inode, bufsize, block);
+ if (!bh)
+ return 0;
+ memcpy((void *) tmpde + slop, bh->b_data, offset);
+ }
+ de = tmpde;
}
- if(de->flags[-high_sierra] & 0x80) {
+ if (de->flags[-high_sierra] & 0x80) {
first_de = 0;
filp->f_pos += de_len;
continue;
@@ -240,7 +215,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
if (map) {
#ifdef CONFIG_JOLIET
if (inode->i_sb->u.isofs_sb.s_joliet_level) {
- len = get_joliet_filename(de, inode, tmpname);
+ len = get_joliet_filename(de, tmpname, inode);
p = tmpname;
} else
#endif
@@ -249,8 +224,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
p = tmpname;
} else
if (inode->i_sb->u.isofs_sb.s_mapping == 'n') {
- len = isofs_name_translate(de->name,
- de->name_len[0], tmpname);
+ len = isofs_name_translate(de, tmpname, inode);
p = tmpname;
} else {
p = de->name;
@@ -265,7 +239,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
continue;
}
- brelse(bh);
+ if (bh) brelse(bh);
return 0;
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 157b8ebba..453e4a456 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -972,14 +972,24 @@ int isofs_bmap(struct inode *inode, int block)
return 0;
}
+struct buffer_head *isofs_bread(struct inode *inode, unsigned int bufsize, unsigned int block)
+{
+ unsigned int blknr = isofs_bmap(inode, block);
+ if (!blknr)
+ return NULL;
+ return bread(inode->i_dev, blknr, bufsize);
+}
+
static int isofs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,isofs_get_block);
}
+
static int _isofs_bmap(struct address_space *mapping, long block)
{
return generic_block_bmap(mapping,block,isofs_get_block);
}
+
static struct address_space_operations isofs_aops = {
readpage: isofs_readpage,
sync_page: block_sync_page,
@@ -1002,93 +1012,89 @@ static inline void test_and_set_gid(gid_t *p, gid_t value)
static int isofs_read_level3_size(struct inode * inode)
{
- unsigned long ino = inode->i_ino;
+ unsigned long f_pos = inode->i_ino;
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
int high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
struct buffer_head * bh = NULL;
- int block = 0;
+ unsigned long block, offset;
int i = 0;
int more_entries = 0;
- void *cpnt;
- struct iso_directory_record * raw_inode;
+ struct iso_directory_record * tmpde = kmalloc(256, GFP_KERNEL);
+
+ if (!tmpde)
+ return -ENOMEM;
inode->i_size = 0;
inode->u.isofs_i.i_next_section_ino = 0;
+
+ block = f_pos >> ISOFS_BUFFER_BITS(inode);
+ offset = f_pos & (bufsize-1);
+
do {
- unsigned char *pnt;
- unsigned int reclen;
- int offset = (ino & (bufsize - 1));
-
- cpnt = NULL;
- /* Check whether to update our buffer */
- if (block != ino >> ISOFS_BUFFER_BITS(inode)) {
- block = ino >> ISOFS_BUFFER_BITS(inode);
- brelse(bh);
+ struct iso_directory_record * de;
+ unsigned int de_len;
+
+ if (!bh) {
bh = bread(inode->i_dev, block, bufsize);
if (!bh)
goto out_noread;
}
- pnt = ((unsigned char *) bh->b_data + offset);
- /*
- * Note: this is invariant even if the record
- * spans buffers and must be copied ...
- */
- reclen = *pnt;
+ de = (struct iso_directory_record *) (bh->b_data + offset);
+ de_len = *(unsigned char *) de;
- /* N.B. this test doesn't trigger the i++ code ... */
- if(reclen == 0) {
- ino = (ino & ~(ISOFS_BLOCK_SIZE - 1)) + ISOFS_BLOCK_SIZE;
+ if (de_len == 0) {
+ brelse(bh);
+ bh = NULL;
+ f_pos = (f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
+ block = f_pos >> ISOFS_BUFFER_BITS(inode);
+ offset = 0;
continue;
}
- raw_inode = ((struct iso_directory_record *) pnt);
-
- /* Check whether the raw inode spans the buffer ... */
- if (offset + reclen > bufsize){
- int frag1 = bufsize - offset;
-
- cpnt = kmalloc(reclen, GFP_KERNEL);
- if (cpnt == NULL)
- goto out_nomem;
- memcpy(cpnt, pnt, frag1);
+
+ offset += de_len;
+
+ /* Make sure we have a full directory entry */
+ if (offset >= bufsize) {
+ int slop = bufsize - offset + de_len;
+ memcpy(tmpde, de, slop);
+ offset &= bufsize - 1;
+ block++;
brelse(bh);
- bh = bread(inode->i_dev, ++block, bufsize);
- if (!bh)
- goto out_noread;
- offset += reclen - bufsize;
- memcpy((char *)cpnt+frag1, bh->b_data, offset);
- raw_inode = ((struct iso_directory_record *) cpnt);
+ bh = NULL;
+ if (offset) {
+ bh = bread(inode->i_dev, block, bufsize);
+ if (!bh)
+ goto out_noread;
+ memcpy((void *) tmpde + slop, bh->b_data, offset);
+ }
+ de = tmpde;
}
- inode->i_size += isonum_733 (raw_inode->size);
- if(i == 1) inode->u.isofs_i.i_next_section_ino = ino;
+ inode->i_size += isonum_733(de->size);
+ if (i == 1)
+ inode->u.isofs_i.i_next_section_ino = f_pos;
- more_entries = raw_inode->flags[-high_sierra] & 0x80;
+ more_entries = de->flags[-high_sierra] & 0x80;
- ino += reclen;
- if (cpnt)
- kfree (cpnt);
+ f_pos += de_len;
i++;
if(i > 100)
goto out_toomany;
} while(more_entries);
out:
- brelse(bh);
+ kfree(tmpde);
+ if (bh) brelse(bh);
return 0;
-out_nomem:
- printk(KERN_INFO "ISOFS: NoMem ISO inode %lu\n", inode->i_ino);
- brelse(bh);
- return 1;
out_noread:
- printk(KERN_INFO "ISOFS: unable to read i-node block %d\n", block);
- if (cpnt)
- kfree(cpnt);
+ printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
+ kfree(tmpde);
return 1;
out_toomany:
printk(KERN_INFO "isofs_read_level3_size: "
"More than 100 file sections ?!?, aborting...\n"
"isofs_read_level3_size: inode=%lu ino=%lu\n",
- inode->i_ino, ino);
+ inode->i_ino, f_pos);
goto out;
}
@@ -1259,143 +1265,6 @@ static void isofs_read_inode(struct inode * inode)
return;
}
-/* There are times when we need to know the inode number of a parent of
- a particular directory. When control passes through a routine that
- has access to the parent information, it fills it into the inode structure,
- but sometimes the inode gets flushed out of the queue, and someone
- remembers the number. When they try to open up again, we have lost
- the information. The '..' entry on the disc points to the data area
- for a particular inode, so we can follow these links back up, but since
- we do not know the inode number, we do not actually know how large the
- directory is. The disc is almost always correct, and there is
- enough error checking on the drive itself, but an open ended search
- makes me a little nervous.
-
- The BSD iso filesystem uses the extent number for an inode, and this
- would work really nicely for us except that the read_inode function
- would not have any clean way of finding the actual directory record
- that goes with the file. If we had such info, then it would pay
- to change the inode numbers and eliminate this function.
-*/
-
-int isofs_lookup_grandparent(struct inode * parent, int extent)
-{
- unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
- unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
- unsigned int block,offset;
- int parent_dir, inode_number;
- int result;
- int directory_size;
- struct buffer_head * bh;
- struct iso_directory_record * de;
-
- offset = 0;
- block = extent << (ISOFS_ZONE_BITS(parent) - bufbits);
- if (!(bh = bread(parent->i_dev, block, bufsize))) return -1;
-
- while (1 == 1) {
- de = (struct iso_directory_record *) (bh->b_data + offset);
- if (*((unsigned char *) de) == 0)
- {
- brelse(bh);
- printk("Directory .. not found\n");
- return -1;
- }
-
- offset += *((unsigned char *) de);
-
- if (offset >= bufsize)
- {
- printk(".. Directory not in first block"
- " of directory.\n");
- brelse(bh);
- return -1;
- }
-
- if (de->name_len[0] == 1 && de->name[0] == 1)
- {
- parent_dir = find_rock_ridge_relocation(de, parent);
- directory_size = isonum_733 (de->size);
- brelse(bh);
- break;
- }
- }
-#ifdef DEBUG
- printk("Parent dir:%x\n",parent_dir);
-#endif
- /* Now we know the extent where the parent dir starts on. */
-
- result = -1;
-
- offset = 0;
- block = parent_dir << (ISOFS_ZONE_BITS(parent) - bufbits);
- if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
- {
- return -1;
- }
-
- for(;;)
- {
- de = (struct iso_directory_record *) (bh->b_data + offset);
- inode_number = (block << bufbits)+(offset & (bufsize - 1));
-
- /* If the length byte is zero, we should move on to the next
- CDROM sector. If we are at the end of the directory, we
- kick out of the while loop. */
-
- if ((*((unsigned char *) de) == 0) || (offset == bufsize) )
- {
- brelse(bh);
- offset = 0;
- block++;
- directory_size -= bufsize;
- if(directory_size < 0) return -1;
- if((block & 1) && (ISOFS_ZONE_BITS(parent) - bufbits) == 1)
- {
- return -1;
- }
- if((block & 3) && (ISOFS_ZONE_BITS(parent) - bufbits) == 2)
- {
- return -1;
- }
- if (!block
- || !(bh = bread(parent->i_dev,block, bufsize)))
- {
- return -1;
- }
- continue;
- }
-
- /* Make sure that the entire directory record is in the current
- bh block. If not, we malloc a buffer, and put the two
- halves together, so that we can cleanly read the block. */
-
- offset += *((unsigned char *) de);
-
- if (offset > bufsize)
- {
- printk("Directory overrun\n");
- goto out;
- }
-
- if (find_rock_ridge_relocation(de, parent) == extent){
- result = inode_number;
- goto out;
- }
-
- }
-
- /* We go here for any condition we cannot handle.
- We also drop through to here at the end of the directory. */
-
- out:
- brelse(bh);
-#ifdef DEBUG
- printk("Resultant Inode %d\n",result);
-#endif
- return result;
-}
-
#ifdef LEAK_CHECK
#undef malloc
#undef free_s
diff --git a/fs/isofs/joliet.c b/fs/isofs/joliet.c
index 009314a82..5b93f4581 100644
--- a/fs/isofs/joliet.c
+++ b/fs/isofs/joliet.c
@@ -70,8 +70,7 @@ wcsntombs_be(__u8 *s, const __u8 *pwcs, int inlen, int maxlen)
}
int
-get_joliet_filename(struct iso_directory_record * de, struct inode * inode,
- unsigned char *outname)
+get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode)
{
unsigned char utf8;
struct nls_table *nls;
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index 7d4ca4e98..4473f7c0d 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -57,147 +57,87 @@ isofs_cmp(struct dentry * dentry, const char * compare, int dlen)
* itself (as an inode number). It does NOT read the inode of the
* entry - you'll have to do that yourself if you want to.
*/
-static struct buffer_head *
-isofs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino)
+static unsigned long
+isofs_find_entry(struct inode *dir, struct dentry *dentry,
+ char * tmpname, struct iso_directory_record * tmpde)
{
+ unsigned long inode_number;
unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
- unsigned int block, i, f_pos, offset,
- inode_number = 0; /* shut gcc up */
- struct buffer_head * bh , * retval = NULL;
- unsigned int old_offset;
- int dlen, match;
- char * dpnt;
- unsigned char *page = NULL;
- struct iso_directory_record * de = NULL; /* shut gcc up */
- char de_not_in_buf = 0; /* true if de is in kmalloc'd memory */
- char c;
-
- *ino = 0;
-
- if (!(block = dir->u.isofs_i.i_first_extent)) return NULL;
+ unsigned int block, f_pos, offset;
+ struct buffer_head * bh = NULL;
+
+ if (!dir->u.isofs_i.i_first_extent)
+ return 0;
f_pos = 0;
-
- offset = f_pos & (bufsize - 1);
- block = isofs_bmap(dir,f_pos >> bufbits);
-
- if (!block || !(bh = bread(dir->i_dev,block,bufsize))) return NULL;
+ offset = 0;
+ block = 0;
while (f_pos < dir->i_size) {
+ struct iso_directory_record * de;
+ int de_len, match, i, dlen;
+ char *dpnt;
- /* if de is in kmalloc'd memory, do not point to the
- next de, instead we will move to the next sector */
- if(!de_not_in_buf) {
- de = (struct iso_directory_record *)
- (bh->b_data + offset);
+ if (!bh) {
+ bh = isofs_bread(dir, bufsize, block);
+ if (!bh)
+ return 0;
}
- inode_number = (block << bufbits) + (offset & (bufsize - 1));
-
- /* If byte is zero, or we had to fetch this de past
- the end of the buffer, this is the end of file, or
- time to move to the next sector. Usually 2048 byte
- boundaries. */
-
- if (*((unsigned char *) de) == 0 || de_not_in_buf) {
- if(de_not_in_buf) {
- /* james@bpgc.com: Since we slopped
- past the end of the last buffer, we
- must start some way into the new
- one */
- de_not_in_buf = 0;
- kfree(de);
- f_pos += offset;
- }
- else {
- offset = 0;
- f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1))
- + ISOFS_BLOCK_SIZE);
- }
- brelse(bh);
- bh = NULL;
-
- if (f_pos >= dir->i_size)
- break;
- block = isofs_bmap(dir,f_pos>>bufbits);
- if (!block || !(bh = bread(dir->i_dev,block,bufsize)))
- break;
+ de = (struct iso_directory_record *) (bh->b_data + offset);
+ inode_number = (bh->b_blocknr << bufbits) + offset;
- continue; /* Will kick out if past end of directory */
+ de_len = *(unsigned char *) de;
+ if (!de_len) {
+ brelse(bh);
+ bh = NULL;
+ f_pos = (f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
+ block = f_pos >> bufbits;
+ offset = 0;
+ continue;
}
- old_offset = offset;
- offset += *((unsigned char *) de);
- f_pos += *((unsigned char *) de);
+ offset += de_len;
+ f_pos += de_len;
- /* james@bpgc.com: new code to handle case where the
- directory entry spans two blocks. Usually 1024
- byte boundaries */
+ /* Make sure we have a full directory entry */
if (offset >= bufsize) {
- struct buffer_head *bh_next;
-
- /* james@bpgc.com: read the next block, and
- copy the split de into a newly kmalloc'd
- buffer */
- block = isofs_bmap(dir,f_pos>>bufbits);
- if (!block ||
- !(bh_next = bread(dir->i_dev,block,bufsize)))
- break;
-
- de = (struct iso_directory_record *)
- kmalloc(offset - old_offset, GFP_KERNEL);
- memcpy((char *)de, bh->b_data + old_offset,
- bufsize - old_offset);
- memcpy((char *)de + bufsize - old_offset,
- bh_next->b_data, offset - bufsize);
- brelse(bh_next);
- de_not_in_buf = 1;
- offset -= bufsize;
+ int slop = bufsize - offset + de_len;
+ memcpy(tmpde, de, slop);
+ offset &= bufsize - 1;
+ block++;
+ brelse(bh);
+ bh = NULL;
+ if (offset) {
+ bh = isofs_bread(dir, bufsize, block);
+ if (!bh)
+ return 0;
+ memcpy((void *) tmpde + slop, bh->b_data, offset);
+ }
+ de = tmpde;
}
+
dlen = de->name_len[0];
dpnt = de->name;
- if (dir->i_sb->u.isofs_sb.s_rock ||
- dir->i_sb->u.isofs_sb.s_joliet_level ||
- dir->i_sb->u.isofs_sb.s_mapping == 'n' ||
- dir->i_sb->u.isofs_sb.s_mapping == 'a') {
- if (! page) {
- page = (unsigned char *)
- __get_free_page(GFP_KERNEL);
- if (!page) break;
- }
- }
if (dir->i_sb->u.isofs_sb.s_rock &&
- ((i = get_rock_ridge_filename(de, page, dir)))) {
+ ((i = get_rock_ridge_filename(de, tmpname, dir)))) {
dlen = i;
- dpnt = page;
+ dpnt = tmpname;
#ifdef CONFIG_JOLIET
} else if (dir->i_sb->u.isofs_sb.s_joliet_level) {
- dlen = get_joliet_filename(de, dir, page);
- dpnt = page;
+ dlen = get_joliet_filename(de, tmpname, dir);
+ dpnt = tmpname;
#endif
} else if (dir->i_sb->u.isofs_sb.s_mapping == 'a') {
- dlen = get_acorn_filename(de, page, dir);
- dpnt = page;
+ dlen = get_acorn_filename(de, tmpname, dir);
+ dpnt = tmpname;
} else if (dir->i_sb->u.isofs_sb.s_mapping == 'n') {
- for (i = 0; i < dlen; i++) {
- c = dpnt[i];
- /* lower case */
- if (c >= 'A' && c <= 'Z') c |= 0x20;
- if (c == ';' && i == dlen-2 && dpnt[i+1] == '1') {
- dlen -= 2;
- break;
- }
- if (c == ';') c = '.';
- page[i] = c;
- }
- /* This allows us to match with and without
- * a trailing period. */
- if(page[dlen-1] == '.' && dentry->d_name.len == dlen-1)
- dlen--;
- dpnt = page;
+ dlen = isofs_name_translate(de, tmpname, dir);
+ dpnt = tmpname;
}
+
/*
* Skip hidden or associated files unless unhide is set
*/
@@ -208,43 +148,32 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino)
match = (isofs_cmp(dentry,dpnt,dlen) == 0);
}
if (match) {
- if(inode_number == -1) {
- /* Should only happen for the '..' entry */
- inode_number =
- isofs_lookup_grandparent(dir,
- find_rock_ridge_relocation(de,dir));
- }
- *ino = inode_number;
- retval = bh;
- bh = NULL;
- break;
+ if (bh) brelse(bh);
+ return inode_number;
}
}
- if (page) free_page((unsigned long) page);
if (bh) brelse(bh);
- if(de_not_in_buf)
- kfree(de);
- return retval;
+ return 0;
}
struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
{
unsigned long ino;
- struct buffer_head * bh;
struct inode *inode;
+ struct page *page;
#ifdef DEBUG
printk("lookup: %x %s\n",dir->i_ino, dentry->d_name.name);
#endif
dentry->d_op = dir->i_sb->s_root->d_op;
- bh = isofs_find_entry(dir, dentry, &ino);
+ page = alloc_page(GFP_USER);
+ ino = isofs_find_entry(dir, dentry, page_address(page), 1024 + page_address(page));
+ __free_page(page);
inode = NULL;
- if (bh) {
- brelse(bh);
-
- inode = iget(dir->i_sb,ino);
+ if (ino) {
+ inode = iget(dir->i_sb, ino);
if (!inode)
return ERR_PTR(-EACCES);
}
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index 1a7cbe374..b2eff877f 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -449,7 +449,7 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr)
static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
{
struct inode *inode = (struct inode*)page->mapping->host;
- char *link = (char*)kmap(page);
+ char *link = kmap(page);
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
struct buffer_head *bh;
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 3ac27df92..f61005aac 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -327,17 +327,15 @@ jffs_new_inode(const struct inode * dir, struct jffs_raw_inode *raw_inode,
struct inode * inode;
struct jffs_control *c;
- inode = get_empty_inode();
+ sb = dir->i_sb;
+ inode = new_inode(sb);
if (!inode) {
*err = -ENOMEM;
return NULL;
}
- sb = dir->i_sb;
c = (struct jffs_control *)sb->u.generic_sbp;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_ino = raw_inode->ino;
inode->i_mode = raw_inode->mode;
inode->i_nlink = raw_inode->nlink;
@@ -351,7 +349,6 @@ jffs_new_inode(const struct inode * dir, struct jffs_raw_inode *raw_inode,
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = (inode->i_size + 511) >> 9;
inode->i_version = 0;
- inode->i_flags = sb->s_flags;
inode->u.generic_ip = (void *)jffs_find_file(c, raw_inode->ino);
insert_inode_hash(inode);
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 5cf82f468..09e88d7ba 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -10,7 +10,8 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: intrep.c,v 1.69 2000/08/24 09:35:47 dwmw2 Exp $
+ * - Based on Id: intrep.c,v 1.71 2000/10/27 16:51:29 dwmw2 Exp
+ * - With the ctype() changes from v1.77.
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -68,15 +69,11 @@
#include <linux/version.h>
#include <linux/smp_lock.h>
#include <linux/sched.h>
-
+#include <linux/ctype.h>
#include "intrep.h"
#include "jffs_fm.h"
-#if LINUX_VERSION_CODE < 0x20300
-#define set_current_state(x) do{current->state = x;} while (0)
-#endif
-
#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
long no_jffs_file = 0;
long no_jffs_node = 0;
@@ -94,48 +91,7 @@ static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);
static __u8 flash_read_u8(struct mtd_info *mtd, loff_t from);
#if 1
-#define _U 01
-#define _L 02
-#define _N 04
-#define _S 010
-#define _P 020
-#define _C 040
-#define _X 0100
-#define _B 0200
-
-const unsigned char jffs_ctype_[1 + 256] = {
- 0,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _S|_B, _P, _P, _P, _P, _P, _P, _P,
- _P, _P, _P, _P, _P, _P, _P, _P,
- _N, _N, _N, _N, _N, _N, _N, _N,
- _N, _N, _P, _P, _P, _P, _P, _P,
- _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _P, _P, _P, _P, _P,
- _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _P, _P, _P, _P, _C
-};
-
-#define jffs_isalpha(c) ((jffs_ctype_+1)[(int)c]&(_U|_L))
-#define jffs_isupper(c) ((jffs_ctype_+1)[(int)c]&_U)
-#define jffs_islower(c) ((jffs_ctype_+1)[(int)c]&_L)
-#define jffs_isdigit(c) ((jffs_ctype_+1)[(int)c]&_N)
-#define jffs_isxdigit(c) ((jffs_ctype_+1)[(int)c]&(_X|_N))
-#define jffs_isspace(c) ((jffs_ctype_+1)[(int)c]&_S)
-#define jffs_ispunct(c) ((jffs_ctype_+1)[(int)c]&_P)
-#define jffs_isalnum(c) ((jffs_ctype_+1)[(int)c]&(_U|_L|_N))
-#define jffs_isprint(c) ((jffs_ctype_+1)[(int)c]&(_P|_U|_L|_N|_B))
-#define jffs_isgraph(c) ((jffs_ctype_+1)[(int)c]&(_P|_U|_L|_N))
-#define jffs_iscntrl(c) ((jffs_ctype_+1)[(int)c]&_C)
-
-void
+static void
jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
{
char line[16];
@@ -169,7 +125,7 @@ jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
printk(" ");
for (i = 0; i < j; i++) {
- if (jffs_isgraph(line[i])) {
+ if (isgraph(line[i])) {
printk("%c", line[i]);
}
else {
@@ -193,9 +149,12 @@ flash_safe_read(struct mtd_info *mtd, loff_t from,
size_t retlen;
int res;
+ D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",
+ mtd, from, buf, count));
+
res = MTD_READ(mtd, from, count, &retlen, buf);
if (retlen != count) {
- printk("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);
+ panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);
}
return res?res:retlen;
}
@@ -367,9 +326,37 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size)
{
__u32 sum = 0;
loff_t ptr = start;
- while (size-- > 0) {
- sum += flash_read_u8(mtd, ptr++);
+ __u8 *read_buf;
+ int i, length;
+
+ /* Allocate read buffer */
+ read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+
+ /* Loop until checksum done */
+ while (size) {
+ /* Get amount of data to read */
+ if (size < 4096)
+ length = size;
+ else
+ length = 4096;
+
+ /* Perform flash read */
+ D3(printk(KERN_NOTICE "jffs_checksum_flash\n"));
+ flash_safe_read(mtd, ptr, &read_buf[0], length);
+
+ /* Compute checksum */
+ for (i=0; i < length ; i++)
+ sum += read_buf[i];
+
+ /* Update pointer and size */
+ size -= length;
+ ptr += length;
}
+
+ /* Free read buffer */
+ kfree (read_buf);
+
+ /* Return result */
D3(printk("checksum result: 0x%08x\n", sum));
return sum;
}
@@ -609,12 +596,17 @@ jffs_scan_flash(struct jffs_control *c)
loff_t pos = fmc->flash_start;
loff_t start;
loff_t end = fmc->flash_start + fmc->flash_size;
+ __u8 *read_buf;
+ int i, len, retlen;
D1(printk("jffs_scan_flash(): start pos = 0x%lx, end = 0x%lx\n",
(long)pos, (long)end));
flash_safe_acquire(fmc->mtd);
+ /* Allocate read buffer */
+ read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+
/* Start the scan. */
while (pos < end) {
deleted_file = 0;
@@ -629,9 +621,22 @@ jffs_scan_flash(struct jffs_control *c)
something else than 0xff is found. */
D1(printk("jffs_scan_flash(): 0xff at pos 0x%lx.\n",
(long)pos));
- for (; pos < end
- && JFFS_EMPTY_BITMASK == flash_read_u32(fmc->mtd, pos);
- pos += 4);
+
+ len = end - pos < 4096 ? end - pos : 4096;
+
+ retlen = flash_safe_read(fmc->mtd, pos,
+ &read_buf[0], len);
+
+ retlen &= ~3;
+
+ for (i=0 ; i < retlen ; i+=4, pos += 4) {
+ if(*((__u32 *) &read_buf[i]) !=
+ JFFS_EMPTY_BITMASK)
+ break;
+ }
+ if (i == retlen)
+ continue;
+
D1(printk("jffs_scan_flash(): 0xff ended at "
"pos 0x%lx.\n", (long)pos));
@@ -748,7 +753,12 @@ jffs_scan_flash(struct jffs_control *c)
if (!(node = (struct jffs_node *)
kmalloc(sizeof(struct jffs_node),
GFP_KERNEL))) {
+ /* Free read buffer */
+ kfree (read_buf);
+
+ /* Release the flash device */
flash_safe_release(fmc->mtd);
+
return -ENOMEM;
}
DJM(no_jffs_node++);
@@ -893,7 +903,13 @@ jffs_scan_flash(struct jffs_control *c)
D(printk("jffs_scan_flash(): !node->fm\n"));
kfree(node);
DJM(no_jffs_node--);
+
+ /* Free read buffer */
+ kfree (read_buf);
+
+ /* Release the flash device */
flash_safe_release(fmc->mtd);
+
return -ENOMEM;
}
if ((err = jffs_insert_node(c, 0, &raw_inode,
@@ -911,7 +927,13 @@ jffs_scan_flash(struct jffs_control *c)
D(printk("jffs_scan_flash: !dl\n"));
kfree(node);
DJM(no_jffs_node--);
+
+ /* Release the flash device */
flash_safe_release(fmc->flash_part);
+
+ /* Free read buffer */
+ kfree (read_buf);
+
return -ENOMEM;
}
dl->ino = deleted_file;
@@ -936,6 +958,11 @@ jffs_scan_flash(struct jffs_control *c)
DJM(no_jffs_node--);
}
jffs_build_end(fmc);
+
+ /* Free read buffer */
+ kfree (read_buf);
+
+ /* Return happy */
D3(printk("jffs_scan_flash(): Leaving...\n"));
flash_safe_release(fmc->mtd);
return 0;
@@ -1598,6 +1625,7 @@ jffs_get_node_data(struct jffs_file *f, struct jffs_node *node,
f->name, node->ino, node->version, node_offset));
r = jffs_min(avail, max_size);
+ D3(printk(KERN_NOTICE "jffs_get_node_data\n"));
flash_safe_read(fmc->mtd, pos, buf, r);
D3(printk(" jffs_get_node_data(): Read %u byte%s.\n",
@@ -3026,9 +3054,8 @@ jffs_garbage_collect_thread(void *ptr)
case SIGKILL:
D1(printk("jffs_garbage_collect_thread(): SIGKILL received.\n"));
c->gc_task = NULL;
- up(&c->gc_thread_sem);
unlock_kernel();
- return(0);
+ up_and_exit(&c->gc_thread_sem, 0);
}
}
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 249e7514d..b5194b561 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -168,7 +168,6 @@ reclaimer(void *ptr)
* reclaim is in progress */
lock_kernel();
lockd_up();
- down(&file_lock_sem);
/* First, reclaim all locks that have been granted previously. */
restart:
@@ -181,12 +180,11 @@ restart:
fl->fl_u.nfs_fl.state != host->h_state &&
(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) {
fl->fl_u.nfs_fl.flags &= ~ NFS_LCK_GRANTED;
- nlmclnt_reclaim(host, fl);
+ nlmclnt_reclaim(host, fl); /* This sleeps */
goto restart;
}
tmp = tmp->next;
}
- up(&file_lock_sem);
host->h_reclaiming = 0;
wake_up(&host->h_gracewait);
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index dbe3f69b5..211b01530 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -407,19 +407,15 @@ 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/svclock.c b/fs/lockd/svclock.c
index 5460e8c9f..078f568b7 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -468,7 +468,6 @@ 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)) {
nlmsvc_insert_block(block, 0);
@@ -476,7 +475,6 @@ nlmsvc_notify_blocked(struct file_lock *fl)
return;
}
}
- unlock_kernel();
printk(KERN_WARNING "lockd: notification for unknown block!\n");
}
diff --git a/fs/locks.c b/fs/locks.c
index 0e92b740f..7da293a31 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -125,11 +125,6 @@
#include <asm/semaphore.h>
#include <asm/uaccess.h>
-DECLARE_MUTEX(file_lock_sem);
-
-#define acquire_fl_sem() down(&file_lock_sem)
-#define release_fl_sem() up(&file_lock_sem)
-
int leases_enable = 1;
int lease_break_time = 45;
@@ -428,6 +423,15 @@ static void locks_insert_block(struct file_lock *blocker,
list_add(&waiter->fl_link, &blocked_list);
}
+static inline
+void locks_notify_blocked(struct file_lock *waiter)
+{
+ if (waiter->fl_notify)
+ waiter->fl_notify(waiter);
+ else
+ wake_up(&waiter->fl_wait);
+}
+
/* Wake up processes blocked waiting for blocker.
* If told to wait then schedule the processes until the block list
* is empty, otherwise empty the block list ourselves.
@@ -436,11 +440,9 @@ 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_block);
- /* N.B. Is it possible for the notify function to block?? */
- if (waiter->fl_notify)
- waiter->fl_notify(waiter);
- wake_up(&waiter->fl_wait);
+
if (wait) {
+ locks_notify_blocked(waiter);
/* Let the blocked process remove waiter from the
* block list when it gets scheduled.
*/
@@ -451,6 +453,7 @@ static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait)
* time it wakes up blocker won't exist any more.
*/
locks_delete_block(waiter);
+ locks_notify_blocked(waiter);
}
}
}
@@ -477,7 +480,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
*/
static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait)
{
- int (*lock)(struct file *, int, struct file_lock *);
struct file_lock *fl = *thisfl_p;
*thisfl_p = fl->fl_next;
@@ -488,7 +490,7 @@ static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait)
fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync);
if (fl->fl_fasync != NULL){
- printk("locks_delete_lock: fasync == %p\n", fl->fl_fasync);
+ printk(KERN_ERR "locks_delete_lock: fasync == %p\n", fl->fl_fasync);
fl->fl_fasync = NULL;
}
@@ -496,12 +498,24 @@ static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait)
fl->fl_remove(fl);
locks_wake_up_blocks(fl, wait);
- lock = fl->fl_file->f_op->lock;
- if (lock) {
+ locks_free_lock(fl);
+}
+
+/*
+ * Call back client filesystem in order to get it to unregister a lock,
+ * then delete lock. Essentially useful only in locks_remove_*().
+ * Note: this must be called with the semaphore already held!
+ */
+static inline void locks_unlock_delete(struct file_lock **thisfl_p)
+{
+ struct file_lock *fl = *thisfl_p;
+ int (*lock)(struct file *, int, struct file_lock *);
+
+ if ((lock = fl->fl_file->f_op->lock) != NULL) {
fl->fl_type = F_UNLCK;
lock(fl->fl_file, F_SETLK, fl);
}
- locks_free_lock(fl);
+ locks_delete_lock(thisfl_p, 0);
}
/* Determine if lock sys_fl blocks lock caller_fl. Common functionality
@@ -562,22 +576,19 @@ static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *s
return (locks_conflict(caller_fl, sys_fl));
}
-int interruptible_sleep_on_locked(wait_queue_head_t *fl_wait, struct semaphore *sem, int timeout)
+static int interruptible_sleep_on_locked(wait_queue_head_t *fl_wait, int timeout)
{
int result = 0;
- wait_queue_t wait;
- init_waitqueue_entry(&wait, current);
+ DECLARE_WAITQUEUE(wait, current);
- __add_wait_queue(fl_wait, &wait);
current->state = TASK_INTERRUPTIBLE;
- up(sem);
+ add_wait_queue(fl_wait, &wait);
if (timeout == 0)
schedule();
else
result = schedule_timeout(timeout);
if (signal_pending(current))
result = -ERESTARTSYS;
- down(sem);
remove_wait_queue(fl_wait, &wait);
current->state = TASK_RUNNING;
return result;
@@ -587,7 +598,7 @@ static int locks_block_on(struct file_lock *blocker, struct file_lock *waiter)
{
int result;
locks_insert_block(blocker, waiter);
- result = interruptible_sleep_on_locked(&waiter->fl_wait, &file_lock_sem, 0);
+ result = interruptible_sleep_on_locked(&waiter->fl_wait, 0);
locks_delete_block(waiter);
return result;
}
@@ -596,7 +607,7 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w
{
int result;
locks_insert_block(blocker, waiter);
- result = interruptible_sleep_on_locked(&waiter->fl_wait, &file_lock_sem, time);
+ result = interruptible_sleep_on_locked(&waiter->fl_wait, time);
locks_delete_block(waiter);
return result;
}
@@ -606,14 +617,14 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
{
struct file_lock *cfl;
- acquire_fl_sem();
+ lock_kernel();
for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
if (!(cfl->fl_flags & FL_POSIX))
continue;
if (posix_locks_conflict(cfl, fl))
break;
}
- release_fl_sem();
+ unlock_kernel();
return (cfl);
}
@@ -668,14 +679,14 @@ int locks_mandatory_locked(struct inode *inode)
/*
* Search the lock list for this inode for any POSIX locks.
*/
- acquire_fl_sem();
+ lock_kernel();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & FL_POSIX))
continue;
if (fl->fl_owner != owner)
break;
}
- release_fl_sem();
+ unlock_kernel();
return fl ? -EAGAIN : 0;
}
@@ -696,7 +707,7 @@ int locks_mandatory_area(int read_write, struct inode *inode,
new_fl->fl_end = offset + count - 1;
error = 0;
- acquire_fl_sem();
+ lock_kernel();
repeat:
/* Search the lock list for this inode for locks that conflict with
@@ -729,7 +740,7 @@ repeat:
}
}
locks_free_lock(new_fl);
- release_fl_sem();
+ unlock_kernel();
return error;
}
@@ -847,7 +858,7 @@ int posix_lock_file(struct file *filp, struct file_lock *caller,
if (!(new_fl && new_fl2))
goto out;
- acquire_fl_sem();
+ lock_kernel();
if (caller->fl_type != F_UNLCK) {
repeat:
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
@@ -951,7 +962,7 @@ int posix_lock_file(struct file *filp, struct file_lock *caller,
* as the change in lock type might satisfy
* their needs.
*/
- locks_wake_up_blocks(fl, 0);
+ locks_wake_up_blocks(fl, 0); /* This cannot schedule()! */
fl->fl_start = caller->fl_start;
fl->fl_end = caller->fl_end;
fl->fl_type = caller->fl_type;
@@ -992,7 +1003,7 @@ int posix_lock_file(struct file *filp, struct file_lock *caller,
locks_wake_up_blocks(left, 0);
}
out:
- release_fl_sem();
+ unlock_kernel();
/*
* Free any unused locks.
*/
@@ -1038,7 +1049,7 @@ int __get_lease(struct inode *inode, unsigned int mode)
alloc_err = lease_alloc(NULL, 0, &new_fl);
- acquire_fl_sem();
+ lock_kernel();
flock = inode->i_flock;
if (flock->fl_type & F_INPROGRESS) {
if ((mode & O_NONBLOCK)
@@ -1107,7 +1118,7 @@ restart:
}
out:
- release_fl_sem();
+ unlock_kernel();
if (!alloc_err)
locks_free_lock(new_fl);
return error;
@@ -1210,7 +1221,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
before = &inode->i_flock;
- acquire_fl_sem();
+ lock_kernel();
while ((fl = *before) != NULL) {
if (fl->fl_flags != FL_LEASE)
@@ -1261,7 +1272,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
filp->f_owner.uid = current->uid;
filp->f_owner.euid = current->euid;
out_unlock:
- release_fl_sem();
+ unlock_kernel();
return error;
}
@@ -1307,10 +1318,10 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
&& !(filp->f_mode & 3))
goto out_putf;
- acquire_fl_sem();
+ lock_kernel();
error = flock_lock_file(filp, type,
(cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1);
- release_fl_sem();
+ unlock_kernel();
out_putf:
fput(filp);
@@ -1643,16 +1654,16 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
*/
return;
}
- acquire_fl_sem();
+ lock_kernel();
before = &inode->i_flock;
while ((fl = *before) != NULL) {
if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) {
- locks_delete_lock(before, 0);
+ locks_unlock_delete(before);
continue;
}
before = &fl->fl_next;
}
- release_fl_sem();
+ unlock_kernel();
}
/*
@@ -1667,7 +1678,7 @@ void locks_remove_flock(struct file *filp)
if (!inode->i_flock)
return;
- acquire_fl_sem();
+ lock_kernel();
before = &inode->i_flock;
while ((fl = *before) != NULL) {
@@ -1678,7 +1689,7 @@ void locks_remove_flock(struct file *filp)
}
before = &fl->fl_next;
}
- release_fl_sem();
+ unlock_kernel();
}
/**
@@ -1691,9 +1702,7 @@ void locks_remove_flock(struct file *filp)
void
posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
{
- acquire_fl_sem();
locks_insert_block(blocker, waiter);
- release_fl_sem();
}
/**
@@ -1705,12 +1714,8 @@ posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
void
posix_unblock_lock(struct file_lock *waiter)
{
- acquire_fl_sem();
- if (!list_empty(&waiter->fl_block)) {
+ if (!list_empty(&waiter->fl_block))
locks_delete_block(waiter);
- wake_up(&waiter->fl_wait);
- }
- release_fl_sem();
}
static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
@@ -1801,7 +1806,7 @@ int get_locks_status(char *buffer, char **start, off_t offset, int length)
off_t pos = 0;
int i = 0;
- acquire_fl_sem();
+ lock_kernel();
list_for_each(tmp, &file_lock_list) {
struct list_head *btmp;
struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
@@ -1822,7 +1827,7 @@ int get_locks_status(char *buffer, char **start, off_t offset, int length)
}
}
done:
- release_fl_sem();
+ unlock_kernel();
*start = buffer;
if(q-buffer < length)
return (q-buffer);
@@ -1847,7 +1852,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
{
struct file_lock *fl;
int result = 1;
- acquire_fl_sem();
+ lock_kernel();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (fl->fl_flags == FL_POSIX) {
if (fl->fl_type == F_RDLCK)
@@ -1864,7 +1869,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
result = 0;
break;
}
- release_fl_sem();
+ unlock_kernel();
return result;
}
@@ -1885,7 +1890,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
{
struct file_lock *fl;
int result = 1;
- acquire_fl_sem();
+ lock_kernel();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (fl->fl_flags == FL_POSIX) {
if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
@@ -1900,7 +1905,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
result = 0;
break;
}
- release_fl_sem();
+ unlock_kernel();
return result;
}
#endif
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index dce2687ee..49f757e80 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -224,14 +224,12 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
struct buffer_head * bh;
int i,j;
- inode = get_empty_inode();
+ sb = dir->i_sb;
+ inode = new_inode(sb);
if (!inode) {
*error = -ENOMEM;
return NULL;
}
- sb = dir->i_sb;
- inode->i_sb = sb;
- inode->i_flags = 0;
j = 8192;
bh = NULL;
*error = -ENOSPC;
@@ -259,8 +257,6 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
unlock_super(sb);
return NULL;
}
- inode->i_nlink = 1;
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
inode->i_ino = j;
diff --git a/fs/namei.c b/fs/namei.c
index c22fc2ec3..c0d1abc36 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1381,7 +1381,10 @@ asmlinkage long sys_rmdir(const char * pathname)
case LAST_DOTDOT:
error = -ENOTEMPTY;
goto exit1;
- case LAST_ROOT: case LAST_DOT:
+ case LAST_DOT:
+ error = -EINVAL;
+ goto exit1;
+ case LAST_ROOT:
error = -EBUSY;
goto exit1;
}
@@ -1949,7 +1952,7 @@ static char *page_getlink(struct dentry * dentry, struct page **ppage)
if (!Page_Uptodate(page))
goto async_fail;
*ppage = page;
- return (char*) kmap(page);
+ return kmap(page);
async_fail:
page_cache_release(page);
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index eda3fe6af..a187b1199 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -462,7 +462,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (!page)
goto read_really;
- ctl.cache = cache = (union ncp_dir_cache *) kmap(page);
+ ctl.cache = cache = kmap(page);
ctl.head = cache->head;
if (!Page_Uptodate(page) || !ctl.head.eof)
@@ -490,7 +490,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
ctl.page = find_lock_page(&inode->i_data, ctl.ofs);
if (!ctl.page)
goto invalid_cache;
- ctl.cache = (union ncp_dir_cache *) kmap(ctl.page);
+ ctl.cache = kmap(ctl.page);
if (!Page_Uptodate(ctl.page))
goto invalid_cache;
}
@@ -635,7 +635,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
ctl.ofs += 1;
ctl.page = grab_cache_page(&inode->i_data, ctl.ofs);
if (ctl.page)
- ctl.cache = (union ncp_dir_cache *) kmap(ctl.page);
+ ctl.cache = kmap(ctl.page);
}
if (ctl.cache) {
ctl.cache->dentry[ctl.idx] = newdent;
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 139c9262d..ac4de2b83 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -120,11 +120,6 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
DPRINTK("ncp_file_read: enter %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
- error = -EINVAL;
- if (inode == NULL) {
- DPRINTK("ncp_file_read: inode = NULL\n");
- goto out;
- }
error = -EIO;
if (!ncp_conn_valid(NCP_SERVER(inode)))
goto out;
@@ -210,10 +205,6 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
DPRINTK("ncp_file_write: enter %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
- if (inode == NULL) {
- DPRINTK("ncp_file_write: inode = NULL\n");
- return -EINVAL;
- }
errno = -EIO;
if (!ncp_conn_valid(NCP_SERVER(inode)))
goto out;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index ff0c1fd03..badfc7817 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -214,13 +214,11 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
return NULL;
}
- inode = get_empty_inode();
+ inode = new_inode(sb);
if (inode) {
init_MUTEX(&NCP_FINFO(inode)->open_sem);
atomic_set(&NCP_FINFO(inode)->opened, info->opened);
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_ino = info->ino;
ncp_set_attr(inode, info);
if (S_ISREG(inode->i_mode)) {
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 4df91abe3..4b6afe2e9 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -86,10 +86,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
case NCP_IOC_CONN_LOGGED_IN:
- if ((permission(inode, MAY_WRITE) != 0)
- && (current->uid != server->m.mounted_uid)) {
+ if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- }
if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
return -EINVAL;
if (server->root_setuped)
@@ -207,8 +205,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
struct nw_info_struct i;
struct dentry* dentry;
- if ( (permission(inode, MAY_WRITE) != 0)
- && (current->uid != server->m.mounted_uid))
+ if (!capable(CAP_SYS_ADMIN))
{
return -EACCES;
}
@@ -513,8 +510,7 @@ outrel:
* Thanks Petr Vandrovec for idea and many hints.
*/
case NCP_IOC_SETCHARSETS:
- if ((permission(inode, MAY_WRITE) != 0) &&
- (current->uid != server->m.mounted_uid))
+ if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (server->root_setuped)
return -EBUSY;
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 041dd0785..9261eb453 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -37,7 +37,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode;
struct page* page;
- unsigned long pg_addr;
+ char *pg_addr;
unsigned int already_read;
unsigned int count;
int bufsize;
@@ -71,7 +71,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
if (ncp_read_kernel(NCP_SERVER(inode),
NCP_FINFO(inode)->file_handle,
pos, to_read,
- (char *) (pg_addr + already_read),
+ pg_addr + already_read,
&read_this_time) != 0) {
read_this_time = 0;
}
@@ -87,8 +87,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
}
if (already_read < PAGE_SIZE)
- memset((char*)(pg_addr + already_read), 0,
- PAGE_SIZE - already_read);
+ memset(pg_addr + already_read, 0, PAGE_SIZE - already_read);
flush_dcache_page(page);
kunmap(page);
return page;
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index 9272822a4..6e09c8bf2 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -1005,6 +1005,8 @@ ncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen,
/* this is wrong! */
vname_cc = kmalloc(vlen, GFP_KERNEL);
+ if (!vname_cc)
+ return -ENOMEM;
for (i = 0; i < vlen; i++)
vname_cc[i] = ncp_tolower(in, vname[i]);
vname = vname_cc;
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c
index 0962593da..022cbce78 100644
--- a/fs/ncpfs/symlink.c
+++ b/fs/ncpfs/symlink.c
@@ -48,7 +48,7 @@ static int ncp_symlink_readpage(struct file *file, struct page *page)
struct inode *inode = (struct inode*)page->mapping->host;
int error, length, len, cnt;
char *link;
- char *buf = (char*)kmap(page);
+ char *buf = kmap(page);
error = -ENOMEM;
for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3f6b770aa..c66d870d9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -97,7 +97,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
{
struct file *file = desc->file;
struct inode *inode = file->f_dentry->d_inode;
- void *buffer = (void *)kmap(page);
+ void *buffer = kmap(page);
int plus = NFS_USE_READDIRPLUS(inode);
int error;
@@ -145,7 +145,7 @@ static inline
int find_dirent(nfs_readdir_descriptor_t *desc, struct page *page)
{
struct nfs_entry *entry = desc->entry;
- char *start = (char *)kmap(page),
+ char *start = kmap(page),
*p = start;
int loop_count = 0,
status = 0;
@@ -251,7 +251,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
{
struct file *file = desc->file;
struct nfs_entry *entry = desc->entry;
- char *start = (char *)kmap(desc->page),
+ char *start = kmap(desc->page),
*p = start + desc->page_offset;
unsigned long fileid;
int loop_count = 0,
@@ -323,7 +323,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
status = -ENOMEM;
goto out;
}
- p = (u32 *)kmap(page);
+ p = kmap(page);
status = NFS_PROTO(inode)->readdir(file, desc->target, p,
NFS_SERVER(inode)->dtsize, 0);
if (status >= 0) {
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b21592528..5b582024e 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -720,12 +720,9 @@ nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle,
if ((dentry->d_parent->d_inode->u.nfs_i.flags & NFS_IS_SNAPSHOT) ||
(dentry->d_name.len == 9 &&
memcmp(dentry->d_name.name, ".snapshot", 9) == 0)) {
- struct inode *inode = get_empty_inode();
+ struct inode *inode = new_inode(sb);
if (!inode)
- goto out;
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
- inode->i_flags = 0;
+ goto out;
inode->i_ino = nfs_fattr_to_ino_t(fattr);
nfs_read_inode(inode);
nfs_fill_inode(inode, fattr);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 7c1aad253..76fc2f437 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -101,7 +101,7 @@ nfs_readpage_sync(struct file *file, struct page *page)
* This works now because the socket layer never tries to DMA
* into this buffer directly.
*/
- buffer = (char *) kmap(page);
+ buffer = kmap(page);
do {
if (count < rsize)
rsize = count;
@@ -257,7 +257,7 @@ nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data)
struct nfs_page *req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_list_add_request(req, &data->pages);
- iov->iov_base = (void *)(kmap(req->wb_page) + req->wb_offset);
+ iov->iov_base = kmap(req->wb_page) + req->wb_offset;
iov->iov_len = req->wb_bytes;
count += req->wb_bytes;
iov++;
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 4c9c45e2a..4960526b4 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -30,7 +30,7 @@
static int nfs_symlink_filler(struct dentry *dentry, struct page *page)
{
struct inode *inode = dentry->d_inode;
- void *buffer = (void *)kmap(page);
+ void *buffer = kmap(page);
int error;
/* We place the length at the beginning of the page,
@@ -69,7 +69,7 @@ static char *nfs_getlink(struct dentry *dentry, struct page **ppage)
if (!Page_Uptodate(page))
goto getlink_read_error;
*ppage = page;
- p = (u32 *) kmap(page);
+ p = kmap(page);
return (char*)(p+1);
getlink_read_error:
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5346e6302..230954993 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -184,7 +184,7 @@ nfs_writepage_sync(struct file *file, struct page *page,
dentry->d_parent->d_name.name, dentry->d_name.name,
count, (long long)(page_offset(page) + offset));
- buffer = (u8 *) kmap(page) + offset;
+ buffer = kmap(page) + offset;
base = page_offset(page) + offset;
flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC;
@@ -601,14 +601,10 @@ nfs_wait_on_request(struct nfs_page *req)
{
struct inode *inode = req->wb_dentry->d_inode;
struct rpc_clnt *clnt = NFS_CLIENT(inode);
- int retval;
if (!NFS_WBACK_BUSY(req))
return 0;
- req->wb_count++;
- retval = nfs_wait_event(clnt, req->wb_wait, !NFS_WBACK_BUSY(req));
- nfs_release_request(req);
- return retval;
+ return nfs_wait_event(clnt, req->wb_wait, !NFS_WBACK_BUSY(req));
}
/*
@@ -1065,7 +1061,7 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data)
struct nfs_page *req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_list_add_request(req, &data->pages);
- iov->iov_base = (void *)(kmap(req->wb_page) + req->wb_offset);
+ iov->iov_base = kmap(req->wb_page) + req->wb_offset;
iov->iov_len = req->wb_bytes;
count += req->wb_bytes;
iov++;
@@ -1239,6 +1235,13 @@ nfs_writeback_done(struct rpc_task *task)
}
#endif
+ /*
+ * Update attributes as result of writeback.
+ * FIXME: There is an inherent race with invalidate_inode_pages and
+ * writebacks since the page->count is kept > 1 for as long
+ * as the page has a write request pending.
+ */
+ nfs_write_attributes(inode, resp->fattr);
while (!list_empty(&data->pages)) {
req = nfs_list_entry(data->pages.next);
nfs_list_remove_request(req);
@@ -1278,9 +1281,6 @@ 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,6 +1395,7 @@ nfs_commit_done(struct rpc_task *task)
dprintk("NFS: %4d nfs_commit_done (status %d)\n",
task->tk_pid, task->tk_status);
+ nfs_write_attributes(inode, resp->fattr);
while (!list_empty(&data->pages)) {
req = nfs_list_entry(data->pages.next);
nfs_list_remove_request(req);
@@ -1426,8 +1427,6 @@ nfs_commit_done(struct rpc_task *task)
next:
nfs_unlock_request(req);
}
-
- nfs_write_attributes(inode, resp->fattr);
}
#endif
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f01f1de86..b57b85ca1 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1538,6 +1538,8 @@ nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
inode->i_uid == current->fsuid)
return 0;
+ acc &= ~ MAY_OWNER_OVERRIDE; /* This bit is no longer needed,
+ and gets in the way later */
err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC));
diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c
index f9ffb0a40..49d2160a6 100644
--- a/fs/ntfs/fs.c
+++ b/fs/ntfs/fs.c
@@ -428,7 +428,7 @@ ntfs_create(struct inode* dir,struct dentry *d,int mode)
int error=0;
ntfs_attribute *si;
- r=get_empty_inode();
+ r=new_inode(dir->i_sb);
if(!r){
error=ENOMEM;
goto fail;
@@ -456,8 +456,6 @@ ntfs_create(struct inode* dir,struct dentry *d,int mode)
r->i_uid=vol->uid;
r->i_gid=vol->gid;
- r->i_nlink=1;
- r->i_sb=dir->i_sb;
/* FIXME: dirty? dev? */
/* get the file modification times from the standard information */
si=ntfs_find_attr(ino,vol->at_standard_information,NULL);
@@ -502,7 +500,7 @@ _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
goto out;
error = EIO;
- r = get_empty_inode();
+ r = new_inode(dir->i_sb);
if (!r)
goto out;
@@ -522,8 +520,6 @@ _linux_ntfs_mkdir(struct inode *dir, struct dentry* d, int mode)
goto out;
r->i_uid = vol->uid;
r->i_gid = vol->gid;
- r->i_nlink = 1;
- r->i_sb = dir->i_sb;
si = ntfs_find_attr(ino,vol->at_standard_information,NULL);
if(si){
char *attr = si->d.data;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 910ffe095..3fdc84ed1 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1050,7 +1050,7 @@ ntfs_clear_bit (unsigned char *byte, int bit)
/* We have to skip the 16 metafiles and the 8 reserved entries */
static int
-new_inode (ntfs_volume* vol,int* result)
+ntfs_new_inode (ntfs_volume* vol,int* result)
{
int byte,error;
int bit;
@@ -1236,11 +1236,11 @@ int ntfs_alloc_inode (ntfs_inode *dir, ntfs_inode *result,
ntfs_volume* vol=dir->vol;
int byte,bit;
- error=new_inode (vol,&(result->i_number));
+ error=ntfs_new_inode (vol,&(result->i_number));
if(error==ENOSPC){
error=ntfs_extend_mft(vol);
if(error)return error;
- error=new_inode(vol,&(result->i_number));
+ error=ntfs_new_inode(vol,&(result->i_number));
}
if(error){
ntfs_error ("ntfs_get_empty_inode: no free inodes\n");
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 3b7b5b2af..1e6f1c854 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -125,7 +125,7 @@ ntfs_init_upcase(ntfs_inode *upcase)
io.param=(char*)upcase->vol->upcase;
io.size=2*UPCASE_LENGTH;
ntfs_read_attr(upcase,upcase->vol->at_data,0,0,&io);
- upcase->vol->upcase_length = io.size;
+ upcase->vol->upcase_length = io.size / 2;
}
static int
diff --git a/fs/pipe.c b/fs/pipe.c
index 1856d54d3..c7f27a520 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -608,14 +608,12 @@ static struct super_operations pipefs_ops = {
static struct super_block * pipefs_read_super(struct super_block *sb, void *data, int silent)
{
- struct inode *root = get_empty_inode();
+ struct inode *root = new_inode(sb);
if (!root)
return NULL;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
- root->i_sb = sb;
- root->i_dev = sb->s_dev;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = PIPEFS_MAGIC;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d12a577fa..e98061fa8 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -372,7 +372,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
task->start_time,
vsize,
mm ? mm->rss : 0, /* you might want to shift this left 3 */
- task->rlim ? task->rlim[RLIMIT_RSS].rlim_cur : 0,
+ task->rlim[RLIMIT_RSS].rlim_cur,
mm ? mm->start_code : 0,
mm ? mm->end_code : 0,
mm ? mm->start_stack : 0,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a1f7efe0f..c1a960c5d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -207,15 +207,12 @@ static int standard_permission(struct inode *inode, int mask)
return -EACCES;
}
-static int proc_permission(struct inode *inode, int mask)
+static int proc_check_root(struct inode *inode)
{
struct dentry *de, *base, *root;
struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
int res = 0;
- if (standard_permission(inode, mask) != 0)
- return -EACCES;
-
if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
return -ENOENT;
read_lock(&current->fs->lock);
@@ -250,6 +247,13 @@ out:
goto exit;
}
+static int proc_permission(struct inode *inode, int mask)
+{
+ if (standard_permission(inode, mask) != 0)
+ return -EACCES;
+ return proc_check_root(inode);
+}
+
static ssize_t pid_maps_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
@@ -403,12 +407,14 @@ static struct inode_operations proc_mem_inode_operations = {
static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
- int error;
+ int error = -EACCES;
/* We don't need a base pointer in the /proc filesystem */
path_release(nd);
- error = proc_permission(inode, MAY_EXEC);
+ if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ goto out;
+ error = proc_check_root(inode);
if (error)
goto out;
@@ -441,12 +447,14 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
{
- int error;
+ int error = -EACCES;
struct inode *inode = dentry->d_inode;
struct dentry *de;
struct vfsmount *mnt = NULL;
- error = proc_permission(inode, MAY_EXEC);
+ if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ goto out;
+ error = proc_check_root(inode);
if (error)
goto out;
@@ -618,14 +626,12 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* We need a new inode */
- inode = get_empty_inode();
+ inode = new_inode(sb);
if (!inode)
goto out;
/* Common stuff */
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(task->pid, ino);
@@ -910,11 +916,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
name = dentry->d_name.name;
len = dentry->d_name.len;
if (len == 4 && !memcmp(name, "self", 4)) {
- inode = get_empty_inode();
+ inode = new_inode(dir->i_sb);
if (!inode)
return ERR_PTR(-ENOMEM);
- inode->i_sb = dir->i_sb;
- inode->i_dev = dir->i_sb->s_dev;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(0, PROC_PID_INO);
inode->u.proc_i.file = NULL;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 0dd6e6063..e58b04e02 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -215,7 +215,7 @@ static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
static struct inode_operations proc_link_inode_operations = {
readlink: proc_readlink,
- follow_link: proc_follow_link
+ follow_link: proc_follow_link,
};
/*
@@ -396,8 +396,6 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
if (dentry->d_op != &proc_dentry_operations)
continue;
inode = dentry->d_inode;
- if (!inode)
- continue;
if (inode->u.generic_ip != de)
continue;
fops_put(filp->f_op);
@@ -573,12 +571,12 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
(void *) proc_alloc_map);
proc_kill_inodes(de);
de->nlink = 0;
- de->deleted = 1;
- if (!de->count)
+ if (!atomic_read(&de->count))
free_proc_entry(de);
else {
+ de->deleted = 1;
printk("remove_proc_entry: %s/%s busy, count=%d\n",
- parent->name, de->name, de->count);
+ parent->name, de->name, atomic_read(&de->count));
}
break;
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 7b571398a..3453bf88b 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -25,7 +25,7 @@ extern void free_proc_entry(struct proc_dir_entry *);
struct proc_dir_entry * de_get(struct proc_dir_entry *de)
{
if (de)
- de->count++;
+ atomic_inc(&de->count);
return de;
}
@@ -34,20 +34,21 @@ struct proc_dir_entry * de_get(struct proc_dir_entry *de)
*/
void de_put(struct proc_dir_entry *de)
{
- if (de) {
- lock_kernel(); /* FIXME: count should be atomic_t */
- if (!de->count) {
+ if (de) {
+ lock_kernel();
+ if (!atomic_read(&de->count)) {
printk("de_put: entry %s already free!\n", de->name);
+ unlock_kernel();
return;
}
- if (!--de->count) {
+ if (atomic_dec_and_test(&de->count)) {
if (de->deleted) {
printk("de_put: deferred delete of %s\n",
de->name);
free_proc_entry(de);
}
- }
+ }
unlock_kernel();
}
}
@@ -139,7 +140,7 @@ struct inode * proc_get_inode(struct super_block * sb, int ino,
#if 1
/* shouldn't ever happen */
if (de && de->deleted)
-printk("proc_iget: using deleted entry %s, count=%d\n", de->name, de->count);
+printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count));
#endif
inode = iget(sb, ino);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5e94c6aa5..d24f65b50 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -9,6 +9,10 @@
* there. I took this into a separate file and switched the thing to generic
* proc_file_inode_operations, leaving in array.c only per-process stuff.
* Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
+ *
+ * Changes:
+ * Fulton Green : Encapsulated position metric calculations.
+ * <kernel@FultonGreen.com>
*/
#include <linux/types.h>
@@ -68,6 +72,17 @@ extern int get_swaparea_info (char *);
extern int get_ds1286_status(char *);
#endif
+static int proc_calc_metrics(char *page, char **start, off_t off,
+ int count, int *eof, int len)
+{
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
+ return len;
+}
+
static int loadavg_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -82,12 +97,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
LOAD_INT(b), LOAD_FRAC(b),
LOAD_INT(c), LOAD_FRAC(c),
nr_running, nr_threads, last_pid);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int uptime_read_proc(char *page, char **start, off_t off,
@@ -122,12 +132,7 @@ static int uptime_read_proc(char *page, char **start, off_t off,
idle / HZ,
idle % HZ);
#endif
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int meminfo_read_proc(char *page, char **start, off_t off,
@@ -187,12 +192,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
K(i.totalswap),
K(i.freeswap));
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
#undef B
#undef K
}
@@ -205,20 +205,14 @@ static int version_read_proc(char *page, char **start, off_t off,
strcpy(page, linux_banner);
len = strlen(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int cpuinfo_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_cpuinfo(page, start, off, count);
- if (len < count) *eof = 1;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#ifdef CONFIG_PROC_HARDWARE
@@ -226,12 +220,7 @@ static int hardware_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_hardware_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -240,12 +229,7 @@ static int stram_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_stram_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -254,12 +238,7 @@ static int malloc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_malloc(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -268,12 +247,7 @@ static int modules_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_module_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int ksyms_read_proc(char *page, char **start, off_t off,
@@ -356,24 +330,14 @@ static int kstat_read_proc(char *page, char **start, off_t off,
xtime.tv_sec - jif / HZ,
total_forks);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int devices_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_device_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int partitions_read_proc(char *page, char **start, off_t off,
@@ -389,12 +353,7 @@ static int interrupts_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_irq_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -402,36 +361,21 @@ static int filesystems_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_filesystem_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int dma_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_dma_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int ioports_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_ioport_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int cmdline_read_proc(char *page, char **start, off_t off,
@@ -442,12 +386,7 @@ static int cmdline_read_proc(char *page, char **start, off_t off,
len = sprintf(page, "%s\n", saved_command_line);
len = strlen(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#ifdef CONFIG_SGI_DS1286
@@ -455,12 +394,7 @@ static int ds1286_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_ds1286_status(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -479,48 +413,28 @@ static int mounts_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_filesystem_info(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int execdomains_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_exec_domain_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int swaps_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_swaparea_info(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int memory_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_mem_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
/*
@@ -631,9 +545,9 @@ void __init proc_misc_init(void)
{"swaps", swaps_read_proc},
{"iomem", memory_read_proc},
{"execdomains", execdomains_read_proc},
- {NULL,NULL}
+ {NULL,}
};
- for(p=simple_ones;p->name;p++)
+ for (p = simple_ones; p->name; p++)
create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
/* And now for trickier ones */
@@ -661,12 +575,8 @@ void __init proc_misc_init(void)
entry->proc_fops = &ppc_htab_operations;
}
#endif
- {
- struct proc_dir_entry *res = create_proc_entry("slabinfo",
- S_IWUSR | S_IRUGO, NULL);
- if (res) {
- res->read_proc = slabinfo_read_proc;
- res->write_proc = slabinfo_write_proc;
- }
- }
+ entry = create_proc_read_entry("slabinfo", S_IWUSR | S_IRUGO, NULL,
+ slabinfo_read_proc, NULL);
+ if (entry)
+ entry->write_proc = slabinfo_write_proc;
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 075a5843d..cae861960 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -96,10 +96,12 @@ static struct inode_operations proc_root_inode_operations = {
* This is the root "inode" in the /proc tree..
*/
struct proc_dir_entry proc_root = {
- PROC_ROOT_INO, 5, "/proc",
- S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
- 0, &proc_root_inode_operations, &proc_root_operations,
- NULL, NULL,
- NULL,
- &proc_root, NULL
+ low_ino: PROC_ROOT_INO,
+ namelen: 5,
+ name: "/proc",
+ mode: S_IFDIR | S_IRUGO | S_IXUGO,
+ nlink: 2,
+ proc_iops: &proc_root_inode_operations,
+ proc_fops: &proc_root_operations,
+ parent: &proc_root,
};
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index f13ba4f3d..31461669c 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -65,7 +65,8 @@ static struct dentry * ramfs_lookup(struct inode *dir, struct dentry *dentry)
static int ramfs_readpage(struct file *file, struct page * page)
{
if (!Page_Uptodate(page)) {
- memset(page_address(page), 0, PAGE_CACHE_SIZE);
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ kunmap(page);
flush_dcache_page(page);
SetPageUptodate(page);
}
@@ -85,9 +86,7 @@ static int ramfs_writepage(struct file *file, struct page *page)
static int ramfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
- void *addr;
-
- addr = (void *) kmap(page);
+ void *addr = kmap(page);
if (!Page_Uptodate(page)) {
memset(addr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
@@ -110,21 +109,15 @@ static int ramfs_commit_write(struct file *file, struct page *page, unsigned off
struct inode *ramfs_get_inode(struct super_block *sb, int mode, int dev)
{
- struct inode * inode = get_empty_inode();
+ struct inode * inode = new_inode(sb);
if (inode) {
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_mode = mode;
inode->i_uid = current->fsuid;
inode->i_gid = current->fsgid;
- inode->i_size = 0;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_rdev = to_kdev_t(dev);
- inode->i_nlink = 1;
- inode->i_op = NULL;
- inode->i_fop = NULL;
inode->i_mapping->a_ops = &ramfs_aops;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
diff --git a/fs/select.c b/fs/select.c
index a49213ecb..975013e7f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -382,13 +382,14 @@ static void do_pollfd(unsigned int num, struct pollfd * fdpage,
static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
struct pollfd *fds[], poll_table *wait, long timeout)
{
- int count = 0;
+ int count;
poll_table* pt = wait;
for (;;) {
unsigned int i;
set_current_state(TASK_INTERRUPTIBLE);
+ count = 0;
for (i=0; i < nchunks; i++)
do_pollfd(POLLFD_PER_PAGE, fds[i], &pt, &count);
if (nleft)
@@ -396,9 +397,9 @@ static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
pt = NULL;
if (count || !timeout || signal_pending(current))
break;
- if(wait->error) {
- return wait->error;
- }
+ count = wait->error;
+ if (count)
+ break;
timeout = schedule_timeout(timeout);
}
current->state = TASK_RUNNING;
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
index 0b42c2387..aa85680ac 100644
--- a/fs/smbfs/cache.c
+++ b/fs/smbfs/cache.c
@@ -47,11 +47,11 @@ smb_get_dircache(struct dentry * dentry)
page = grab_cache_page(mapping, 0);
if (!page)
goto out;
- cachep = (struct cache_head *)kmap(page);
+ cachep = kmap(page);
memset((char*)cachep, 0, PAGE_SIZE);
goto out;
}
- cachep = (struct cache_head *)kmap(page);
+ cachep = kmap(page);
if (cachep->valid) {
/*
* OK, at least the page 0 survived and seems to be promising.
@@ -69,7 +69,7 @@ smb_get_dircache(struct dentry * dentry)
cachep->valid = 0;
goto out;
}
- index->block = (struct cache_block *) kmap(page);
+ index->block = kmap(page);
}
}
out:
@@ -188,7 +188,7 @@ get_block:
page_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT);
page = grab_cache_page(mapping, page_off>>PAGE_CACHE_SHIFT);
if (page) {
- block = (struct cache_block *)kmap(page);
+ block = kmap(page);
index->block = block;
index->space = PAGE_SIZE;
goto add_entry;
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 0406f72cb..bcc900626 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -78,11 +78,9 @@ smb_iget(struct super_block *sb, struct smb_fattr *fattr)
DEBUG1("smb_iget: %p\n", fattr);
- result = get_empty_inode();
+ result = new_inode(sb);
if (!result)
return result;
- result->i_sb = sb;
- result->i_dev = sb->s_dev;
result->i_ino = fattr->f_ino;
memset(&(result->u.smbfs_i), 0, sizeof(result->u.smbfs_i));
smb_set_inode_attr(result, fattr);
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index 8469366cf..7709ade8d 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -91,10 +91,12 @@ struct inode * sysv_new_inode(const struct inode * dir)
struct sysv_inode * raw_inode;
int i,j,ino,block;
- if (!dir || !(inode = get_empty_inode()))
+ if (!dir)
return NULL;
sb = dir->i_sb;
- inode->i_sb = sb;
+ inode = new_inode(sb);
+ if (!inode)
+ return NULL;
lock_super(sb); /* protect against task switches */
if ((*sb->sv_sb_fic_count == 0)
|| (*sv_sb_fic_inode(sb,(*sb->sv_sb_fic_count)-1) == 0) /* Applies only to SystemV2 FS */
@@ -131,7 +133,6 @@ struct inode * sysv_new_inode(const struct inode * dir)
mark_buffer_dirty(sb->sv_bh1); /* super-block has been modified */
if (sb->sv_bh1 != sb->sv_bh2) mark_buffer_dirty(sb->sv_bh2);
sb->s_dirt = 1; /* and needs time stamp */
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
inode->i_ino = ino;
@@ -141,7 +142,6 @@ struct inode * sysv_new_inode(const struct inode * dir)
mark_inode_dirty(inode);
/* Change directory entry: */
inode->i_mode = 0; /* for sysv_write_inode() */
- inode->i_size = 0; /* ditto */
sysv_write_inode(inode, 0); /* ensure inode not allocated again */
/* FIXME: caller may call this too. */
mark_inode_dirty(inode); /* cleared by sysv_write_inode() */
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 9f093c536..9ec279e47 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -86,12 +86,6 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct inode *dir = filp->f_dentry->d_inode;
int result;
- if (!dir)
- return -EBADF;
-
- if (!S_ISDIR(dir->i_mode))
- return -ENOTDIR;
-
if ( filp->f_pos == 0 )
{
if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR))
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 9ba4a6641..7e8ac9b7d 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -54,7 +54,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page)
if (!PageLocked(page))
PAGE_BUG(page);
- kaddr = (char *)kmap(page);
+ kaddr = kmap(page);
memset(kaddr, 0, PAGE_CACHE_SIZE);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize);
@@ -78,7 +78,7 @@ static int udf_adinicb_writepage(struct file *file, struct page *page)
if (!PageLocked(page))
PAGE_BUG(page);
- kaddr = (char *)kmap(page);
+ kaddr = kmap(page);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize);
memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size);
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 5377773ce..5a2e7a1dc 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -77,15 +77,13 @@ struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
int block;
Uint32 start = UDF_I_LOCATION(dir).logicalBlockNum;
- inode = get_empty_inode();
+ sb = dir->i_sb;
+ inode = new_inode(sb);
if (!inode)
{
*err = -ENOMEM;
return NULL;
}
- sb = dir->i_sb;
- inode->i_sb = sb;
- inode->i_flags = 0;
*err = -ENOSPC;
block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
@@ -115,9 +113,6 @@ struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
}
inode->i_mode = mode;
- inode->i_sb = sb;
- inode->i_nlink = 1;
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
@@ -132,7 +127,6 @@ struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = 0;
- inode->i_size = 0;
UDF_I_LENEATTR(inode) = 0;
UDF_I_LENALLOC(inode) = 0;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 4219c505f..83a34f258 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -158,7 +158,6 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
{
struct buffer_head *bh = NULL;
struct page *page;
- unsigned long kaddr = 0;
int block;
/* from now on we have normal address_space methods */
@@ -183,10 +182,10 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
PAGE_BUG(page);
if (!Page_Uptodate(page))
{
- kaddr = kmap(page);
- memset((char *)kaddr + UDF_I_LENALLOC(inode), 0x00,
+ char *kaddr = kmap(page);
+ memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
- memcpy((char *)kaddr, bh->b_data + udf_file_entry_alloc_offset(inode),
+ memcpy(kaddr, bh->b_data + udf_file_entry_alloc_offset(inode),
UDF_I_LENALLOC(inode));
flush_dcache_page(page);
SetPageUptodate(page);
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 8a0dde5e4..547fc784b 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -83,7 +83,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
struct buffer_head *bh = NULL;
char *symlink;
int err = -EIO;
- char *p = (char *)kmap(page);
+ char *p = kmap(page);
lock_kernel();
if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index 1a97daf7c..d7fef19cd 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -161,19 +161,16 @@ struct inode * ufs_new_inode (const struct inode * dir, int mode, int * err )
*err = -EPERM;
return NULL;
}
- inode = get_empty_inode ();
+ sb = dir->i_sb;
+ inode = new_inode(sb);
if (!inode) {
*err = -ENOMEM;
return NULL;
}
- sb = dir->i_sb;
swab = sb->u.ufs_sb.s_swab;
uspi = sb->u.ufs_sb.s_uspi;
usb1 = ubh_get_usb_first(USPI_UBH);
- inode->i_sb = sb;
- inode->i_flags = 0;
-
lock_super (sb);
*err = -ENOSPC;
@@ -261,9 +258,6 @@ cg_found:
sb->s_dirt = 1;
inode->i_mode = mode;
- inode->i_sb = sb;
- inode->i_nlink = 1;
- inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c
index 63ee81b16..2e0b7bb14 100644
--- a/fs/umsdos/dir.c
+++ b/fs/umsdos/dir.c
@@ -700,7 +700,7 @@ struct dentry *umsdos_solve_hlink (struct dentry *hlink)
path = (char *) kmalloc (PATH_MAX, GFP_KERNEL);
if (path == NULL)
goto out_release;
- memcpy(path, (char*)kmap(page), hlink->d_inode->i_size);
+ memcpy(path, kmap(page), hlink->d_inode->i_size);
kunmap(page);
page_cache_release(page);
diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c
index 551c9662f..93c6af317 100644
--- a/fs/umsdos/emd.c
+++ b/fs/umsdos/emd.c
@@ -129,7 +129,7 @@ int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_di
wait_on_page(page);
if (!Page_Uptodate(page))
goto async_fail;
- p = (struct umsdos_dirent*)((char*)kmap(page)+offs);
+ p = (struct umsdos_dirent*)(kmap(page)+offs);
/* if this is an invalid entry (invalid name length), ignore it */
if( p->name_len > UMSDOS_MAXNAME )
@@ -158,7 +158,7 @@ int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_di
goto async_fail;
}
memcpy(entry->spare,p->spare,part);
- memcpy(entry->spare+part,(char*)kmap(page2),
+ memcpy(entry->spare+part,kmap(page2),
recsize+offs-PAGE_CACHE_SIZE);
kunmap(page2);
page_cache_release(page2);
@@ -399,7 +399,7 @@ static int umsdos_find (struct dentry *demd, struct umsdos_info *info)
wait_on_page(page);
if (!Page_Uptodate(page))
goto async_fail;
- p = (char*)kmap(page);
+ p = kmap(page);
}
rentry = (struct umsdos_dirent *)(p+offs);
@@ -451,7 +451,7 @@ static int umsdos_find (struct dentry *demd, struct umsdos_info *info)
page = next_page;
goto async_fail;
}
- q = (char*)kmap(next_page);
+ q = kmap(next_page);
if (memcmp(entry->name, rentry->name, len) ||
memcmp(entry->name+len, q, entry->name_len-len)) {
kunmap(next_page);