config HPFS_FS
tristate "OS/2 HPFS file system support"
depends on BLOCK
- depends on BKL # nontrivial to fix
+ depends on BROKEN || !PREEMPT
help
OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
is the file system used for organizing files on OS/2 hard disk
* directory VFS functions
*/
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include "hpfs_fn.h"
static int hpfs_dir_release(struct inode *inode, struct file *filp)
{
- lock_kernel();
+ hpfs_lock(inode->i_sb);
hpfs_del_pos(inode, &filp->f_pos);
/*hpfs_write_if_changed(inode);*/
- unlock_kernel();
+ hpfs_unlock(inode->i_sb);
return 0;
}
struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
struct super_block *s = i->i_sb;
- lock_kernel();
+ hpfs_lock(s);
/*printk("dir lseek\n");*/
if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
}
mutex_unlock(&i->i_mutex);
ok:
- unlock_kernel();
+ hpfs_unlock(s);
return filp->f_pos = new_off;
fail:
mutex_unlock(&i->i_mutex);
/*printk("illegal lseek: %016llx\n", new_off);*/
- unlock_kernel();
+ hpfs_unlock(s);
return -ESPIPE;
}
int c1, c2 = 0;
int ret = 0;
- lock_kernel();
+ hpfs_lock(inode->i_sb);
if (hpfs_sb(inode->i_sb)->sb_chk) {
if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
hpfs_brelse4(&qbh);
}
out:
- unlock_kernel();
+ hpfs_unlock(inode->i_sb);
return ret;
}
struct inode *result = NULL;
struct hpfs_inode_info *hpfs_result;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
if ((err = hpfs_chk_name(name, &len))) {
if (err == -ENAMETOOLONG) {
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return ERR_PTR(-ENAMETOOLONG);
}
goto end_add;
end:
end_add:
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
d_add(dentry, result);
return NULL;
/*bail:*/
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return ERR_PTR(-ENOENT);
}
* file VFS functions
*/
-#include <linux/smp_lock.h>
#include "hpfs_fn.h"
#define BLOCKS(size) (((size) + 511) >> 9)
static int hpfs_file_release(struct inode *inode, struct file *file)
{
- lock_kernel();
+ hpfs_lock(inode->i_sb);
hpfs_write_if_changed(inode);
- unlock_kernel();
+ hpfs_unlock(inode->i_sb);
return 0;
}
static void hpfs_truncate(struct inode *i)
{
if (IS_IMMUTABLE(i)) return /*-EPERM*/;
- lock_kernel();
+ hpfs_lock(i->i_sb);
hpfs_i(i)->i_n_secs = 0;
i->i_blocks = 1 + ((i->i_size + 511) >> 9);
hpfs_i(i)->mmu_private = i->i_size;
hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
hpfs_write_inode(i);
hpfs_i(i)->i_n_secs = 0;
- unlock_kernel();
+ hpfs_unlock(i->i_sb);
}
static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
extern struct timezone sys_tz;
return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
}
+
+/*
+ * Locking:
+ *
+ * hpfs_lock() is a leftover from the big kernel lock.
+ * Right now, these functions are empty and only left
+ * for documentation purposes. The file system no longer
+ * works on SMP systems, so the lock is not needed
+ * any more.
+ *
+ * If someone is interested in making it work again, this
+ * would be the place to start by adding a per-superblock
+ * mutex and fixing all the bugs and performance issues
+ * caused by that.
+ */
+static inline void hpfs_lock(struct super_block *s)
+{
+}
+
+static inline void hpfs_unlock(struct super_block *s)
+{
+}
* inode VFS functions
*/
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include "hpfs_fn.h"
struct inode *inode = dentry->d_inode;
int error = -EINVAL;
- lock_kernel();
+ hpfs_lock(inode->i_sb);
if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root)
goto out_unlock;
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
hpfs_write_inode(inode);
out_unlock:
- unlock_kernel();
+ hpfs_unlock(inode->i_sb);
return error;
}
truncate_inode_pages(&inode->i_data, 0);
end_writeback(inode);
if (!inode->i_nlink) {
- lock_kernel();
+ hpfs_lock(inode->i_sb);
hpfs_remove_fnode(inode->i_sb, inode->i_ino);
- unlock_kernel();
+ hpfs_unlock(inode->i_sb);
}
}
* adding & removing files & directories
*/
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include "hpfs_fn.h"
static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct hpfs_dirent dee;
int err;
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
err = -ENOSPC;
fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
if (!fnode)
}
d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return 0;
bail3:
mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
bail:
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
int err;
if ((err = hpfs_chk_name(name, &len)))
return err==-ENOENT ? -EINVAL : err;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
err = -ENOSPC;
fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
if (!fnode)
}
d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return 0;
bail2:
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
bail:
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
if (!new_valid_dev(rdev))
return -EINVAL;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
err = -ENOSPC;
fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
if (!fnode)
d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return 0;
bail2:
mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
bail:
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
struct inode *result;
int err;
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return -EPERM;
}
err = -ENOSPC;
hpfs_write_inode_nolock(result);
d_instantiate(dentry, result);
mutex_unlock(&hpfs_i(dir)->i_mutex);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return 0;
bail2:
mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh);
hpfs_free_sectors(dir->i_sb, fno, 1);
bail:
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
int rep = 0;
int err;
- lock_kernel();
+ hpfs_lock(dir->i_sb);
hpfs_adjust_length(name, &len);
again:
mutex_lock(&hpfs_i(inode)->i_parent_mutex);
dentry_unhash(dentry);
if (!d_unhashed(dentry)) {
dput(dentry);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return -ENOSPC;
}
if (generic_permission(inode, MAY_WRITE, 0, NULL) ||
if (!err)
goto again;
}
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return -ENOSPC;
default:
drop_nlink(inode);
out:
mutex_unlock(&hpfs_i(dir)->i_mutex);
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
int r;
hpfs_adjust_length(name, &len);
- lock_kernel();
+ hpfs_lock(dir->i_sb);
mutex_lock(&hpfs_i(inode)->i_parent_mutex);
mutex_lock(&hpfs_i(dir)->i_mutex);
err = -ENOENT;
out:
mutex_unlock(&hpfs_i(dir)->i_mutex);
mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
- unlock_kernel();
+ hpfs_unlock(dir->i_sb);
return err;
}
int err;
err = -EIO;
- lock_kernel();
+ hpfs_lock(i->i_sb);
if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
goto fail;
err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
brelse(bh);
if (err)
goto fail;
- unlock_kernel();
+ hpfs_unlock(i->i_sb);
SetPageUptodate(page);
kunmap(page);
unlock_page(page);
return 0;
fail:
- unlock_kernel();
+ hpfs_unlock(i->i_sb);
SetPageError(page);
kunmap(page);
unlock_page(page);
err = 0;
hpfs_adjust_length(old_name, &old_len);
- lock_kernel();
+ hpfs_lock(i->i_sb);
/* order doesn't matter, due to VFS exclusion */
mutex_lock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
mutex_unlock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
mutex_unlock(&hpfs_i(new_inode)->i_parent_mutex);
- unlock_kernel();
+ hpfs_unlock(i->i_sb);
return err;
}
#include <linux/statfs.h>
#include <linux/magic.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
{
struct hpfs_sb_info *sbi = hpfs_sb(s);
- lock_kernel();
-
kfree(sbi->sb_cp_table);
kfree(sbi->sb_bmp_dir);
unmark_dirty(s);
s->s_fs_info = NULL;
kfree(sbi);
-
- unlock_kernel();
}
unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
struct super_block *s = dentry->d_sb;
struct hpfs_sb_info *sbi = hpfs_sb(s);
u64 id = huge_encode_dev(s->s_bdev->bd_dev);
- lock_kernel();
+ hpfs_lock(s);
/*if (sbi->sb_n_free == -1) {*/
sbi->sb_n_free = count_bitmaps(s);
buf->f_fsid.val[1] = (u32)(id >> 32);
buf->f_namelen = 254;
- unlock_kernel();
+ hpfs_unlock(s);
return 0;
}
*flags |= MS_NOATIME;
- lock_kernel();
+ hpfs_lock(s);
lock_super(s);
uid = sbi->sb_uid; gid = sbi->sb_gid;
umask = 0777 & ~sbi->sb_mode;
replace_mount_options(s, new_opts);
unlock_super(s);
- unlock_kernel();
+ hpfs_unlock(s);
return 0;
out_err:
unlock_super(s);
- unlock_kernel();
+ hpfs_unlock(s);
kfree(new_opts);
return -EINVAL;
}
int o;
- lock_kernel();
+ if (num_possible_cpus() > 1) {
+ printk(KERN_ERR "HPFS is not SMP safe\n");
+ return -EINVAL;
+ }
save_mount_options(s, options);
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) {
- unlock_kernel();
return -ENOMEM;
}
s->s_fs_info = sbi;
root->i_blocks = 5;
hpfs_brelse4(&qbh);
}
- unlock_kernel();
return 0;
bail4: brelse(bh2);
kfree(sbi->sb_cp_table);
s->s_fs_info = NULL;
kfree(sbi);
- unlock_kernel();
return -EINVAL;
}