Commit 772fd530 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] hpfs: hpfs iget locking cleanup

Killed the nightmares in hpfs iget handling.  Since in some (fairly
frequent) cases hpfs_read_inode() could avoid any IO (basically, lookup
hitting a native HPFS regular file can get all data from directory
entry) hpfs had a flag passed to that sucker.  Said flag had been
protected by a semaphore lookalike made out of spit and duct-tape and
callers of iget looked like

	hpfs_lock_iget(sb, flag);
	result = iget(sb, ino);
	hpfs_unlock_iget(sb);

Since now we are calling hpfs_read_inode() directly (note that calling
it without hpfs_lock_iget() would simply break) we can forget all that
crap and get rid of the flag - caller knows what it wants to call.

BTW, that had killed one of the last sleep_on() users in fs/*/*.
parent b5b83bae
...@@ -26,24 +26,6 @@ void hpfs_unlock_creation(struct super_block *s) ...@@ -26,24 +26,6 @@ void hpfs_unlock_creation(struct super_block *s)
up(&hpfs_sb(s)->hpfs_creation_de); up(&hpfs_sb(s)->hpfs_creation_de);
} }
void hpfs_lock_iget(struct super_block *s, int mode)
{
#ifdef DEBUG_LOCKS
printk("lock iget\n");
#endif
while (hpfs_sb(s)->sb_rd_inode) sleep_on(&hpfs_sb(s)->sb_iget_q);
hpfs_sb(s)->sb_rd_inode = mode;
}
void hpfs_unlock_iget(struct super_block *s)
{
#ifdef DEBUG_LOCKS
printk("unlock iget\n");
#endif
hpfs_sb(s)->sb_rd_inode = 0;
wake_up(&hpfs_sb(s)->sb_iget_q);
}
void hpfs_lock_inode(struct inode *i) void hpfs_lock_inode(struct inode *i)
{ {
if (i) { if (i) {
......
...@@ -243,20 +243,28 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name ...@@ -243,20 +243,28 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
* Go find or make an inode. * Go find or make an inode.
*/ */
hpfs_lock_iget(dir->i_sb, de->directory || (de->ea_size && hpfs_sb(dir->i_sb)->sb_eas) ? 1 : 2);
result = iget_locked(dir->i_sb, ino); result = iget_locked(dir->i_sb, ino);
if (!result) { if (!result) {
hpfs_unlock_iget(dir->i_sb);
hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode"); hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode");
goto bail1; goto bail1;
} }
if (result->i_state & I_NEW) { if (result->i_state & I_NEW) {
hpfs_read_inode(result); hpfs_init_inode(result);
if (de->directory)
hpfs_read_inode(result);
else if (de->ea_size && hpfs_sb(dir->i_sb)->sb_eas)
hpfs_read_inode(result);
else {
result->i_mode |= S_IFREG;
result->i_mode &= ~0111;
result->i_op = &hpfs_file_iops;
result->i_fop = &hpfs_file_ops;
result->i_nlink = 1;
}
unlock_new_inode(result); unlock_new_inode(result);
} }
hpfs_result = hpfs_i(result); hpfs_result = hpfs_i(result);
if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino; if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino;
hpfs_unlock_iget(dir->i_sb);
hpfs_decide_conv(result, (char *)name, len); hpfs_decide_conv(result, (char *)name, len);
......
...@@ -192,8 +192,6 @@ void hpfs_remove_fnode(struct super_block *, fnode_secno fno); ...@@ -192,8 +192,6 @@ void hpfs_remove_fnode(struct super_block *, fnode_secno fno);
void hpfs_lock_creation(struct super_block *); void hpfs_lock_creation(struct super_block *);
void hpfs_unlock_creation(struct super_block *); void hpfs_unlock_creation(struct super_block *);
void hpfs_lock_iget(struct super_block *, int);
void hpfs_unlock_iget(struct super_block *);
void hpfs_lock_inode(struct inode *); void hpfs_lock_inode(struct inode *);
void hpfs_unlock_inode(struct inode *); void hpfs_unlock_inode(struct inode *);
void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int); void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int);
......
...@@ -98,18 +98,6 @@ void hpfs_read_inode(struct inode *i) ...@@ -98,18 +98,6 @@ void hpfs_read_inode(struct inode *i)
unsigned char *ea; unsigned char *ea;
int ea_size; int ea_size;
hpfs_init_inode(i);
if (!hpfs_sb(i->i_sb)->sb_rd_inode)
hpfs_error(i->i_sb, "read_inode: sb_rd_inode == 0");
if (hpfs_sb(i->i_sb)->sb_rd_inode == 2) {
i->i_mode |= S_IFREG;
i->i_mode &= ~0111;
i->i_op = &hpfs_file_iops;
i->i_fop = &hpfs_file_ops;
i->i_nlink = 1;
return;
}
if (!(fnode = hpfs_map_fnode(sb, i->i_ino, &bh))) { if (!(fnode = hpfs_map_fnode(sb, i->i_ino, &bh))) {
/*i->i_mode |= S_IFREG; /*i->i_mode |= S_IFREG;
i->i_mode &= ~0111; i->i_mode &= ~0111;
...@@ -248,21 +236,19 @@ void hpfs_write_inode(struct inode *i) ...@@ -248,21 +236,19 @@ void hpfs_write_inode(struct inode *i)
kfree(hpfs_inode->i_rddir_off); kfree(hpfs_inode->i_rddir_off);
hpfs_inode->i_rddir_off = NULL; hpfs_inode->i_rddir_off = NULL;
} }
hpfs_lock_iget(i->i_sb, 1);
parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir);
if (parent) { if (parent) {
hpfs_inode->i_dirty = 0; hpfs_inode->i_dirty = 0;
if (parent->i_state & I_NEW) { if (parent->i_state & I_NEW) {
hpfs_init_inode(parent);
hpfs_read_inode(parent); hpfs_read_inode(parent);
unlock_new_inode(parent); unlock_new_inode(parent);
} }
hpfs_unlock_iget(i->i_sb);
hpfs_lock_inode(parent); hpfs_lock_inode(parent);
hpfs_write_inode_nolock(i); hpfs_write_inode_nolock(i);
hpfs_unlock_inode(parent); hpfs_unlock_inode(parent);
iput(parent); iput(parent);
} else { } else {
hpfs_unlock_iget(i->i_sb);
mark_inode_dirty(i); mark_inode_dirty(i);
} }
} }
......
...@@ -211,7 +211,6 @@ static struct super_operations hpfs_sops = ...@@ -211,7 +211,6 @@ static struct super_operations hpfs_sops =
{ {
.alloc_inode = hpfs_alloc_inode, .alloc_inode = hpfs_alloc_inode,
.destroy_inode = hpfs_destroy_inode, .destroy_inode = hpfs_destroy_inode,
.read_inode = hpfs_read_inode,
.delete_inode = hpfs_delete_inode, .delete_inode = hpfs_delete_inode,
.put_super = hpfs_put_super, .put_super = hpfs_put_super,
.statfs = hpfs_statfs, .statfs = hpfs_statfs,
...@@ -470,9 +469,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -470,9 +469,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
sbi->sb_bmp_dir = NULL; sbi->sb_bmp_dir = NULL;
sbi->sb_cp_table = NULL; sbi->sb_cp_table = NULL;
sbi->sb_rd_inode = 0;
init_MUTEX(&sbi->hpfs_creation_de); init_MUTEX(&sbi->hpfs_creation_de);
init_waitqueue_head(&sbi->sb_iget_q);
uid = current->uid; uid = current->uid;
gid = current->gid; gid = current->gid;
...@@ -613,15 +610,12 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) ...@@ -613,15 +610,12 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
brelse(bh1); brelse(bh1);
brelse(bh0); brelse(bh0);
hpfs_lock_iget(s, 1);
root = iget_locked(s, sbi->sb_root); root = iget_locked(s, sbi->sb_root);
if (!root) { if (!root)
hpfs_unlock_iget(s);
goto bail0; goto bail0;
} hpfs_init_inode(root);
hpfs_read_inode(root); hpfs_read_inode(root);
unlock_new_inode(root); unlock_new_inode(root);
hpfs_unlock_iget(s);
s->s_root = d_alloc_root(root); s->s_root = d_alloc_root(root);
if (!s->s_root) { if (!s->s_root) {
iput(root); iput(root);
......
...@@ -20,11 +20,6 @@ struct hpfs_sb_info { ...@@ -20,11 +20,6 @@ struct hpfs_sb_info {
unsigned sb_lowercase : 1; /* downcase filenames hackery */ unsigned sb_lowercase : 1; /* downcase filenames hackery */
unsigned sb_was_error : 1; /* there was an error, set dirty flag */ unsigned sb_was_error : 1; /* there was an error, set dirty flag */
unsigned sb_chkdsk : 2; /* chkdsk: 0-no, 1-on errs, 2-allways */ unsigned sb_chkdsk : 2; /* chkdsk: 0-no, 1-on errs, 2-allways */
unsigned sb_rd_fnode : 2; /* read fnode 0-no 1-dirs 2-all */
unsigned sb_rd_inode : 2; /* lookup tells read_inode: 1-read fnode
2-don't read fnode, file
3-don't read fnode, direcotry */
wait_queue_head_t sb_iget_q;
unsigned char *sb_cp_table; /* code page tables: */ unsigned char *sb_cp_table; /* code page tables: */
/* 128 bytes uppercasing table & */ /* 128 bytes uppercasing table & */
/* 128 bytes lowercasing table */ /* 128 bytes lowercasing table */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment