--- fs/hpfs/buffer.c | 16 --------- fs/hpfs/dir.c | 77 ++++++++++++++++------------------------------ fs/hpfs/file.c | 11 ------ fs/hpfs/hpfs_fn.h | 3 - fs/hpfs/inode.c | 13 ++++--- fs/hpfs/namei.c | 56 ++++++++++++++++----------------- fs/hpfs/super.c | 3 + include/linux/hpfs_fs_i.h | 3 + 8 files changed, 68 insertions(+), 114 deletions(-) diff -puN fs/hpfs/buffer.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/buffer.c --- 25/fs/hpfs/buffer.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/buffer.c 2004-02-29 12:48:33.000000000 -0800 @@ -26,22 +26,6 @@ void hpfs_unlock_creation(struct super_b up(&hpfs_sb(s)->hpfs_creation_de); } -void hpfs_lock_inode(struct inode *i) -{ - if (i) { - struct hpfs_inode_info *hpfs_inode = hpfs_i(i); - down(&hpfs_inode->i_sem); - } -} - -void hpfs_unlock_inode(struct inode *i) -{ - if (i) { - struct hpfs_inode_info *hpfs_inode = hpfs_i(i); - up(&hpfs_inode->i_sem); - } -} - /* Map a sector into a buffer and return pointers to it and to the buffer. */ void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp, diff -puN fs/hpfs/dir.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/dir.c --- 25/fs/hpfs/dir.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/dir.c 2004-02-29 12:48:33.000000000 -0800 @@ -35,19 +35,19 @@ loff_t hpfs_dir_lseek(struct file *filp, /*printk("dir lseek\n");*/ if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; - hpfs_lock_inode(i); + down(&i->i_sem); pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; while (pos != new_off) { if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh); else goto fail; if (pos == 12) goto fail; } - hpfs_unlock_inode(i); - ok: + up(&i->i_sem); +ok: unlock_kernel(); return filp->f_pos = new_off; - fail: - hpfs_unlock_inode(i); +fail: + up(&i->i_sem); /*printk("illegal lseek: %016llx\n", new_off);*/ unlock_kernel(); return -ESPIPE; @@ -109,8 +109,6 @@ int hpfs_readdir(struct file *filp, void goto out; } - hpfs_lock_inode(inode); - while (1) { again: /* This won't work when cycle is longer than number of dirents @@ -118,31 +116,22 @@ int hpfs_readdir(struct file *filp, void maybe killall -9 ls helps */ if (hpfs_sb(inode->i_sb)->sb_chk) if (hpfs_stop_cycles(inode->i_sb, filp->f_pos, &c1, &c2, "hpfs_readdir")) { - hpfs_unlock_inode(inode); ret = -EFSERROR; goto out; } - if (filp->f_pos == 12) { - hpfs_unlock_inode(inode); + if (filp->f_pos == 12) goto out; - } - if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) { + if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) printk("HPFS: warning: pos==%d\n",(int)filp->f_pos); - hpfs_unlock_inode(inode); goto out; - } if (filp->f_pos == 0) { - if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) { - hpfs_unlock_inode(inode); + if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) goto out; - } filp->f_pos = 11; } if (filp->f_pos == 11) { - if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0) { - hpfs_unlock_inode(inode); + if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0) goto out; - } filp->f_pos = 1; } if (filp->f_pos == 1) { @@ -150,35 +139,28 @@ int hpfs_readdir(struct file *filp, void hpfs_add_pos(inode, &filp->f_pos); filp->f_version = inode->i_version; } - /*if (filp->f_version != inode->i_version) { - hpfs_unlock_inode(inode); - ret = -ENOENT; - goto out; - }*/ - old_pos = filp->f_pos; - if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) { - hpfs_unlock_inode(inode); - ret = -EIOERROR; - goto out; - } - if (de->first || de->last) { - if (hpfs_sb(inode->i_sb)->sb_chk) { - if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos); - if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos); - } - hpfs_brelse4(&qbh); - goto again; - } - tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3); - if (filldir(dirent, tempname, de->namelen, old_pos, de->fnode, DT_UNKNOWN) < 0) { - filp->f_pos = old_pos; - if (tempname != (char *)de->name) kfree(tempname); - hpfs_brelse4(&qbh); - hpfs_unlock_inode(inode); - goto out; + old_pos = filp->f_pos; + if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) { + ret = -EIOERROR; + goto out; + } + if (de->first || de->last) { + if (hpfs_sb(inode->i_sb)->sb_chk) { + if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos); + if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos); } + hpfs_brelse4(&qbh); + goto again; + } + tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3); + if (filldir(dirent, tempname, de->namelen, old_pos, de->fnode, DT_UNKNOWN) < 0) { + filp->f_pos = old_pos; if (tempname != (char *)de->name) kfree(tempname); hpfs_brelse4(&qbh); + goto out; + } + if (tempname != (char *)de->name) kfree(tempname); + hpfs_brelse4(&qbh); } out: unlock_kernel(); @@ -220,7 +202,6 @@ struct dentry *hpfs_lookup(struct inode goto end_add; } - hpfs_lock_inode(dir); /* * '.' and '..' will never be passed here. */ @@ -306,7 +287,6 @@ struct dentry *hpfs_lookup(struct inode */ end: - hpfs_unlock_inode(dir); end_add: hpfs_set_dentry_operations(dentry); unlock_kernel(); @@ -322,7 +302,6 @@ struct dentry *hpfs_lookup(struct inode /*bail:*/ - hpfs_unlock_inode(dir); unlock_kernel(); return ERR_PTR(-ENOENT); } diff -puN fs/hpfs/file.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/file.c --- 25/fs/hpfs/file.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/file.c 2004-02-29 12:48:33.000000000 -0800 @@ -15,17 +15,6 @@ #define BLOCKS(size) (((size) + 511) >> 9) -/* HUH? */ -int hpfs_open(struct inode *i, struct file *f) -{ - lock_kernel(); - hpfs_lock_inode(i); - hpfs_unlock_inode(i); /* make sure nobody is deleting the file */ - unlock_kernel(); - if (!i->i_nlink) return -ENOENT; - return 0; -} - int hpfs_file_release(struct inode *inode, struct file *file) { lock_kernel(); diff -puN fs/hpfs/hpfs_fn.h~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/hpfs_fn.h --- 25/fs/hpfs/hpfs_fn.h~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/hpfs_fn.h 2004-02-29 12:48:33.000000000 -0800 @@ -192,8 +192,6 @@ void hpfs_remove_fnode(struct super_bloc void hpfs_lock_creation(struct super_block *); void hpfs_unlock_creation(struct super_block *); -void hpfs_lock_inode(struct inode *); -void hpfs_unlock_inode(struct inode *); void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int); void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **); void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int); @@ -238,7 +236,6 @@ void hpfs_set_ea(struct inode *, struct /* file.c */ int hpfs_file_release(struct inode *, struct file *); -int hpfs_open(struct inode *, struct file *); int hpfs_file_fsync(struct file *, struct dentry *, int); secno hpfs_bmap(struct inode *, unsigned); void hpfs_truncate(struct inode *); diff -puN fs/hpfs/inode.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/inode.c --- 25/fs/hpfs/inode.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/inode.c 2004-02-29 12:48:33.000000000 -0800 @@ -18,7 +18,6 @@ static struct file_operations hpfs_file_ .read = generic_file_read, .write = hpfs_file_write, .mmap = generic_file_mmap, - .open = hpfs_open, .release = hpfs_file_release, .fsync = hpfs_file_fsync, .sendfile = generic_file_sendfile, @@ -35,7 +34,6 @@ static struct file_operations hpfs_dir_o .llseek = hpfs_dir_lseek, .read = generic_read_dir, .readdir = hpfs_readdir, - .open = hpfs_open, .release = hpfs_dir_release, .fsync = hpfs_file_fsync, }; @@ -261,13 +259,17 @@ void hpfs_write_inode(struct inode *i) { struct hpfs_inode_info *hpfs_inode = hpfs_i(i); struct inode *parent; - if (!i->i_nlink) return; if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return; if (hpfs_inode->i_rddir_off && !atomic_read(&i->i_count)) { if (*hpfs_inode->i_rddir_off) printk("HPFS: write_inode: some position still there\n"); kfree(hpfs_inode->i_rddir_off); hpfs_inode->i_rddir_off = NULL; } + down(&hpfs_inode->i_parent); + if (!i->i_nlink) { + up(&hpfs_inode->i_parent); + return; + } hpfs_inode->i_dirty = 0; parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); if (parent) { @@ -275,11 +277,12 @@ void hpfs_write_inode(struct inode *i) hpfs_read_inode(parent); unlock_new_inode(parent); } - hpfs_lock_inode(parent); + down_read(&hpfs_i(parent)->i_sem); hpfs_write_inode_nolock(i); - hpfs_unlock_inode(parent); + up_read(&hpfs_i(parent)->i_sem); iput(parent); } + up(&hpfs_inode->i_parent); } void hpfs_write_inode_nolock(struct inode *i) diff -puN fs/hpfs/namei.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/namei.c --- 25/fs/hpfs/namei.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/namei.c 2004-02-29 12:48:33.000000000 -0800 @@ -42,7 +42,7 @@ int hpfs_mkdir(struct inode *dir, struct dee.hidden = name[0] == '.'; dee.fnode = fno; dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); - hpfs_lock_inode(dir); + down_write(&hpfs_i(dir)->i_sem); r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0); if (r == 1) goto bail2; @@ -98,13 +98,13 @@ int hpfs_mkdir(struct inode *dir, struct d_instantiate(dentry, result); out: - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); unlock_kernel(); return 0; bail2: hpfs_brelse4(&qbh0); hpfs_free_dnode(dir->i_sb, dno); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); @@ -137,7 +137,7 @@ int hpfs_create(struct inode *dir, struc dee.hidden = name[0] == '.'; dee.fnode = fno; dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); - hpfs_lock_inode(dir); + down_write(&hpfs_i(dir)->i_sem); r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0); if (r == 1) goto bail1; @@ -182,13 +182,13 @@ int hpfs_create(struct inode *dir, struc } d_instantiate(dentry, result); out: - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); unlock_kernel(); return 0; bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); bail: unlock_kernel(); return err; @@ -220,7 +220,7 @@ int hpfs_mknod(struct inode *dir, struct dee.hidden = name[0] == '.'; dee.fnode = fno; dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); - hpfs_lock_inode(dir); + down_write(&hpfs_i(dir)->i_sem); r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0); if (r == 1) goto bail1; @@ -258,14 +258,14 @@ int hpfs_mknod(struct inode *dir, struct d_instantiate(dentry, result); out: - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); brelse(bh); unlock_kernel(); return 0; bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); bail: unlock_kernel(); return err; @@ -299,7 +299,7 @@ int hpfs_symlink(struct inode *dir, stru dee.hidden = name[0] == '.'; dee.fnode = fno; dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds()); - hpfs_lock_inode(dir); + down_write(&hpfs_i(dir)->i_sem); r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0); if (r == 1) goto bail1; @@ -344,13 +344,13 @@ int hpfs_symlink(struct inode *dir, stru d_instantiate(dentry, result); out: - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); unlock_kernel(); return 0; bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); bail: unlock_kernel(); return err; @@ -372,8 +372,8 @@ int hpfs_unlink(struct inode *dir, struc lock_kernel(); hpfs_adjust_length((char *)name, &len); again: - hpfs_lock_inode(dir); - hpfs_lock_inode(inode); + down(&hpfs_i(inode)->i_parent); + down_write(&hpfs_i(dir)->i_sem); de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh); err = -ENOENT; if (!de) @@ -400,8 +400,8 @@ again: if (rep++) break; - hpfs_unlock_inode(inode); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); + up(&hpfs_i(inode)->i_parent); d_drop(dentry); spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1 || @@ -432,8 +432,8 @@ again: out1: hpfs_brelse4(&qbh); out: - hpfs_unlock_inode(inode); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); + up(&hpfs_i(inode)->i_parent); unlock_kernel(); return err; } @@ -453,8 +453,8 @@ int hpfs_rmdir(struct inode *dir, struct hpfs_adjust_length((char *)name, &len); lock_kernel(); - hpfs_lock_inode(dir); - hpfs_lock_inode(inode); + down(&hpfs_i(inode)->i_parent); + down_write(&hpfs_i(dir)->i_sem); err = -ENOENT; de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh); if (!de) @@ -492,8 +492,8 @@ int hpfs_rmdir(struct inode *dir, struct out1: hpfs_brelse4(&qbh); out: - hpfs_unlock_inode(inode); - hpfs_unlock_inode(dir); + up_write(&hpfs_i(dir)->i_sem); + up(&hpfs_i(inode)->i_parent); unlock_kernel(); return err; } @@ -550,10 +550,10 @@ int hpfs_rename(struct inode *old_dir, s hpfs_adjust_length((char *)old_name, &old_len); lock_kernel(); - hpfs_lock_inode(old_dir); + down(&hpfs_i(i)->i_parent); + down_write(&hpfs_i(old_dir)->i_sem); if (new_dir != old_dir) - hpfs_lock_inode(new_dir); - hpfs_lock_inode(i); + down_write(&hpfs_i(new_dir)->i_sem); /* Erm? Moving over the empty non-busy directory is perfectly legal */ if (new_inode && S_ISDIR(new_inode->i_mode)) { @@ -632,10 +632,10 @@ int hpfs_rename(struct inode *old_dir, s hpfs_i(i)->i_conv = hpfs_sb(i->i_sb)->sb_conv; hpfs_decide_conv(i, (char *)new_name, new_len); end1: - hpfs_unlock_inode(i); if (old_dir != new_dir) - hpfs_unlock_inode(new_dir); - hpfs_unlock_inode(old_dir); + up_write(&hpfs_i(new_dir)->i_sem); + up_write(&hpfs_i(old_dir)->i_sem); + up(&hpfs_i(i)->i_parent); unlock_kernel(); return err; } diff -puN fs/hpfs/super.c~HPFS5-hpfs_locking-RC4-rc1 fs/hpfs/super.c --- 25/fs/hpfs/super.c~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/fs/hpfs/super.c 2004-02-29 12:48:33.000000000 -0800 @@ -183,7 +183,8 @@ static void init_once(void * foo, kmem_c if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { - init_MUTEX(&ei->i_sem); + init_rwsem(&ei->i_sem); + init_MUTEX(&ei->i_parent); inode_init_once(&ei->vfs_inode); } } diff -puN include/linux/hpfs_fs_i.h~HPFS5-hpfs_locking-RC4-rc1 include/linux/hpfs_fs_i.h --- 25/include/linux/hpfs_fs_i.h~HPFS5-hpfs_locking-RC4-rc1 2004-02-29 12:48:33.000000000 -0800 +++ 25-akpm/include/linux/hpfs_fs_i.h 2004-02-29 12:48:33.000000000 -0800 @@ -16,7 +16,8 @@ struct hpfs_inode_info { unsigned i_ea_uid : 1; /* file's uid is stored in ea */ unsigned i_ea_gid : 1; /* file's gid is stored in ea */ unsigned i_dirty : 1; - struct semaphore i_sem; /* semaphore */ + struct rw_semaphore i_sem; + struct semaphore i_parent; loff_t **i_rddir_off; struct inode vfs_inode; }; _