Commit 79360ddd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull pile 2 of vfs updates from Al Viro:
 "Stuff in this one - assorted fixes, lglock tidy-up, death to
  lock_super().

  There'll be a VFS pile tomorrow (with patches from Jeff Layton,
  sanitizing getname() and related parts of audit and preparing for
  ESTALE fixes), but I'd rather push the stuff in this one ASAP - some
  of the bugs closed here are quite unpleasant."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  vfs: bogus warnings in fs/namei.c
  consitify do_mount() arguments
  lglock: add DEFINE_STATIC_LGLOCK()
  lglock: make the per_cpu locks static
  lglock: remove unused DEFINE_LGLOCK_LOCKDEP()
  MAX_LFS_FILESIZE definition for 64bit needs LL...
  tmpfs,ceph,gfs2,isofs,reiserfs,xfs: fix fh_len checking
  vfs: drop lock/unlock super
  ufs: drop lock/unlock super
  sysv: drop lock/unlock super
  hpfs: drop lock/unlock super
  fat: drop lock/unlock super
  ext3: drop lock/unlock super
  exofs: drop lock/unlock super
  dup3: Return an error when oldfd == newfd.
  fs: handle failed audit_log_start properly
  fs: prevent use after free in auditing when symlink following was denied
parents 8213a2f3 98f6ef64
......@@ -99,7 +99,7 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
* FIXME: we should try harder by querying the mds for the ino.
*/
static struct dentry *__fh_to_dentry(struct super_block *sb,
struct ceph_nfs_fh *fh)
struct ceph_nfs_fh *fh, int fh_len)
{
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
struct inode *inode;
......@@ -107,6 +107,9 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
struct ceph_vino vino;
int err;
if (fh_len < sizeof(*fh) / 4)
return ERR_PTR(-ESTALE);
dout("__fh_to_dentry %llx\n", fh->ino);
vino.ino = fh->ino;
vino.snap = CEPH_NOSNAP;
......@@ -150,7 +153,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
* convert connectable fh to dentry
*/
static struct dentry *__cfh_to_dentry(struct super_block *sb,
struct ceph_nfs_confh *cfh)
struct ceph_nfs_confh *cfh, int fh_len)
{
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
struct inode *inode;
......@@ -158,6 +161,9 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
struct ceph_vino vino;
int err;
if (fh_len < sizeof(*cfh) / 4)
return ERR_PTR(-ESTALE);
dout("__cfh_to_dentry %llx (%llx/%x)\n",
cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
......@@ -207,9 +213,11 @@ static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
if (fh_type == 1)
return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
fh_len);
else
return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
fh_len);
}
/*
......@@ -230,6 +238,8 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb,
if (fh_type == 1)
return ERR_PTR(-ESTALE);
if (fh_len < sizeof(*cfh) / 4)
return ERR_PTR(-ESTALE);
pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
cfh->parent_name_hash);
......
......@@ -389,8 +389,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
if (unlikely(ret))
goto out;
lock_super(sb);
ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
memset(fscb, 0, ios->length);
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
......@@ -406,8 +404,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
if (unlikely(ret))
EXOFS_ERR("%s: ore_write failed.\n", __func__);
unlock_super(sb);
out:
EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
ore_put_io_state(ios);
......
......@@ -2578,11 +2578,9 @@ out:
static int ext3_unfreeze(struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY)) {
lock_super(sb);
/* Reser the needs_recovery flag before the fs is unlocked. */
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
unlock_super(sb);
journal_unlock_updates(EXT3_SB(sb)->s_journal);
}
return 0;
......@@ -2602,7 +2600,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
#endif
/* Store the original options */
lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_resuid = sbi->s_resuid;
......@@ -2708,8 +2705,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
old_opts.s_qf_names[i] != sbi->s_qf_names[i])
kfree(old_opts.s_qf_names[i]);
#endif
unlock_super(sb);
if (enable_quota)
dquot_resume(sb, -1);
return 0;
......@@ -2728,7 +2723,6 @@ restore_opts:
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
}
#endif
unlock_super(sb);
return err;
}
......
......@@ -571,7 +571,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
int short_len = 0, fill_len = 0;
int ret = 0;
lock_super(sb);
mutex_lock(&sbi->s_lock);
cpos = filp->f_pos;
/* Fake . and .. for the root directory. */
......@@ -693,7 +693,7 @@ fill_failed:
if (unicode)
__putname(unicode);
out:
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return ret;
}
......
......@@ -71,8 +71,9 @@ struct msdos_sb_info {
unsigned long root_cluster; /* first cluster of the root directory */
unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
struct mutex fat_lock;
unsigned int prev_free; /* previously allocated cluster number */
unsigned int free_clusters; /* -1 if undefined */
struct mutex s_lock;
unsigned int prev_free; /* previously allocated cluster number */
unsigned int free_clusters; /* -1 if undefined */
unsigned int free_clus_valid; /* is free_clusters valid? */
struct fat_mount_options options;
struct nls_table *nls_disk; /* Codepage used on disk */
......
......@@ -673,9 +673,9 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
if (inode->i_ino == MSDOS_FSINFO_INO) {
struct super_block *sb = inode->i_sb;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = fat_clusters_flush(sb);
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
} else
err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
......@@ -1268,6 +1268,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
b = (struct fat_boot_sector *) bh->b_data;
}
mutex_init(&sbi->s_lock);
sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
sbi->fats = b->fats;
......
......@@ -208,7 +208,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
struct inode *inode;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
switch (err) {
case -ENOENT:
......@@ -221,7 +221,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
default:
inode = ERR_PTR(err);
}
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return d_splice_alias(inode, dentry);
}
......@@ -273,7 +273,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
unsigned char msdos_name[MSDOS_NAME];
int err, is_hid;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
......@@ -302,7 +302,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
d_instantiate(dentry, inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
return err;
......@@ -316,7 +316,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
/*
* Check whether the directory is not in use, then check
* whether it is empty.
......@@ -337,7 +337,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
......@@ -354,7 +354,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct timespec ts;
int err, is_hid, cluster;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
......@@ -392,14 +392,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
d_instantiate(dentry, inode);
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
fat_flush_inodes(sb, dir, inode);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
......@@ -411,7 +411,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
if (err)
goto out;
......@@ -423,7 +423,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
......@@ -606,7 +606,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
int err, is_hid;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(old_dentry->d_name.name,
old_dentry->d_name.len, old_msdos_name,
......@@ -625,7 +625,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
new_dir, new_msdos_name, new_dentry, is_hid);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, old_dir, new_dir);
return err;
......
......@@ -721,7 +721,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
struct dentry *alias;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(dir, &dentry->d_name, &sinfo);
if (err) {
......@@ -752,13 +752,13 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
if (!S_ISDIR(inode->i_mode))
d_move(alias, dentry);
iput(inode);
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return alias;
} else
dput(alias);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
dentry->d_time = dentry->d_parent->d_inode->i_version;
dentry = d_splice_alias(inode, dentry);
if (dentry)
......@@ -766,7 +766,7 @@ out:
return dentry;
error:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return ERR_PTR(err);
}
......@@ -779,7 +779,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
struct timespec ts;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = CURRENT_TIME_SEC;
err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
......@@ -800,7 +800,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
......@@ -811,7 +811,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = fat_dir_empty(inode);
if (err)
......@@ -829,7 +829,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
......@@ -841,7 +841,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(dir, &dentry->d_name, &sinfo);
if (err)
......@@ -854,7 +854,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
......@@ -867,7 +867,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct timespec ts;
int err, cluster;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = CURRENT_TIME_SEC;
cluster = fat_alloc_new_dir(dir, &ts);
......@@ -896,13 +896,13 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
......@@ -921,7 +921,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
lock_super(sb);
mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
if (err)
goto out;
......@@ -996,7 +996,7 @@ out:
brelse(sinfo.bh);
brelse(dotdot_bh);
brelse(old_sinfo.bh);
unlock_super(sb);
mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
......
......@@ -922,6 +922,9 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
if ((flags & ~O_CLOEXEC) != 0)
return -EINVAL;
if (unlikely(oldfd == newfd))
return -EINVAL;
if (newfd >= rlimit(RLIMIT_NOFILE))
return -EMFILE;
......
......@@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
.max_files = NR_FILE
};
DEFINE_LGLOCK(files_lglock);
DEFINE_STATIC_LGLOCK(files_lglock);
/* SLAB cache for file structures */
static struct kmem_cache *filp_cachep __read_mostly;
......
......@@ -161,6 +161,8 @@ static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
case GFS2_SMALL_FH_SIZE:
case GFS2_LARGE_FH_SIZE:
case GFS2_OLD_FH_SIZE:
if (fh_len < GFS2_SMALL_FH_SIZE)
return NULL;
this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
this.no_formal_ino |= be32_to_cpu(fh[1]);
this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
......@@ -180,6 +182,8 @@ static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
switch (fh_type) {
case GFS2_LARGE_FH_SIZE:
case GFS2_OLD_FH_SIZE:
if (fh_len < GFS2_LARGE_FH_SIZE)
return NULL;
parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
parent.no_formal_ino |= be32_to_cpu(fh[5]);
parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
......
......@@ -398,7 +398,6 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
*flags |= MS_NOATIME;
hpfs_lock(s);
lock_super(s);
uid = sbi->sb_uid; gid = sbi->sb_gid;
umask = 0777 & ~sbi->sb_mode;
lowercase = sbi->sb_lowercase;
......@@ -431,12 +430,10 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
replace_mount_options(s, new_opts);
unlock_super(s);
hpfs_unlock(s);
return 0;
out_err:
unlock_super(s);
hpfs_unlock(s);
kfree(new_opts);
return -EINVAL;
......
......@@ -175,7 +175,7 @@ static struct dentry *isofs_fh_to_parent(struct super_block *sb,
{
struct isofs_fid *ifid = (struct isofs_fid *)fid;
if (fh_type != 2)
if (fh_len < 2 || fh_type != 2)
return NULL;
return isofs_export_iget(sb,
......
......@@ -692,9 +692,9 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd)
if (uid_eq(parent->i_uid, inode->i_uid))
return 0;
audit_log_link_denied("follow_link", link);
path_put_conditional(link, nd);
path_put(&nd->path);
audit_log_link_denied("follow_link", link);
return -EACCES;
}
......@@ -810,6 +810,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
return error;
out_put_nd_path:
*p = NULL;
path_put(&nd->path);
path_put(link);
return error;
......
......@@ -1640,7 +1640,7 @@ static int do_change_type(struct path *path, int flag)
/*
* do loopback mount.
*/
static int do_loopback(struct path *path, char *old_name,
static int do_loopback(struct path *path, const char *old_name,
int recurse)
{
LIST_HEAD(umount_list);
......@@ -1764,7 +1764,7 @@ static inline int tree_contains_unbindable(struct mount *mnt)
return 0;
}
static int do_move_mount(struct path *path, char *old_name)
static int do_move_mount(struct path *path, const char *old_name)
{
struct path old_path, parent_path;
struct mount *p;
......@@ -1917,8 +1917,8 @@ unlock:
* create a new mount for userspace and request it to be added into the
* namespace's tree
*/
static int do_new_mount(struct path *path, char *type, int flags,
int mnt_flags, char *name, void *data)
static int do_new_mount(struct path *path, const char *type, int flags,
int mnt_flags, const char *name, void *data)
{
struct vfsmount *mnt;
int err;
......@@ -2191,8 +2191,8 @@ int copy_mount_string(const void __user *data, char **where)
* Therefore, if this magic number is present, it carries no information
* and must be discarded.
*/
long do_mount(char *dev_name, char *dir_name, char *type_page,
unsigned long flags, void *data_page)
long do_mount(const char *dev_name, const char *dir_name,
const char *type_page, unsigned long flags, void *data_page)
{
struct path path;
int retval = 0;
......
......@@ -1573,8 +1573,10 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
reiserfs_warning(sb, "reiserfs-13077",
"nfsd/reiserfs, fhtype=%d, len=%d - odd",
fh_type, fh_len);
fh_type = 5;
fh_type = fh_len;
}
if (fh_len < 2)
return NULL;
return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
......@@ -1583,6 +1585,8 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
if (fh_type > fh_len)
fh_type = fh_len;
if (fh_type < 4)
return NULL;
......
......@@ -186,14 +186,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
spin_lock_init(&s->s_inode_lru_lock);
INIT_LIST_HEAD(&s->s_mounts);
init_rwsem(&s->s_umount);
mutex_init(&s->s_lock);
lockdep_set_class(&s->s_umount, &type->s_umount_key);
/*
* The locking rules for s_lock are up to the
* filesystem. For example ext3fs has different
* lock ordering than usbfs:
*/
lockdep_set_class(&s->s_lock, &type->s_lock_key);
/*
* sget() can have s_umount recursion.
*
......@@ -394,22 +387,6 @@ bool grab_super_passive(struct super_block *sb)
return false;
}
/*
* Superblock locking. We really ought to get rid of these two.
*/
void lock_super(struct super_block * sb)
{
mutex_lock(&sb->s_lock);
}
void unlock_super(struct super_block * sb)
{
mutex_unlock(&sb->s_lock);
}
EXPORT_SYMBOL(lock_super);
EXPORT_SYMBOL(unlock_super);
/**
* generic_shutdown_super - common helper for ->kill_sb()
* @sb: superblock to kill
......
......@@ -60,12 +60,12 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
return;
}
lock_super(sb);
mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count > sbi->s_flc_size) {
printk("sysv_free_block: flc_count > flc_size\n");
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return;
}
/* If the free list head in super-block is full, it is copied
......@@ -77,7 +77,7 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
bh = sb_getblk(sb, block);
if (!bh) {
printk("sysv_free_block: getblk() failed\n");
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return;
}
memset(bh->b_data, 0, sb->s_blocksize);
......@@ -93,7 +93,7 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
fs32_add(sbi, sbi->s_free_blocks, 1);
dirty_sb(sb);
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
}
sysv_zone_t sysv_new_block(struct super_block * sb)
......@@ -104,7 +104,7 @@ sysv_zone_t sysv_new_block(struct super_block * sb)
struct buffer_head * bh;
unsigned count;
lock_super(sb);
mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count == 0) /* Applies only to Coherent FS */
......@@ -147,11 +147,11 @@ sysv_zone_t sysv_new_block(struct super_block * sb)
/* Now the free list head in the superblock is valid again. */
fs32_add(sbi, sbi->s_free_blocks, -1);
dirty_sb(sb);
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return nr;
Enospc:
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return 0;
}
......@@ -173,7 +173,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if (sbi->s_type == FSTYPE_AFS)
return 0;
lock_super(sb);
mutex_lock(&sbi->s_lock);
sb_count = fs32_to_cpu(sbi, *sbi->s_free_blocks);
if (0)
......@@ -211,7 +211,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if (count != sb_count)
goto Ecount;
done:
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return count;
Einval:
......
......@@ -118,7 +118,7 @@ void sysv_free_inode(struct inode * inode)
"%s\n", inode->i_sb->s_id);
return;
}
lock_super(sb);
mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count < sbi->s_fic_size) {
*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sbi, ino);
......@@ -128,7 +128,7 @@ void sysv_free_inode(struct inode * inode)
dirty_sb(sb);
memset(raw_inode, 0, sizeof(struct sysv_inode));
mark_buffer_dirty(bh);
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
brelse(bh);
}
......@@ -147,13 +147,13 @@ struct inode * sysv_new_inode(const struct inode * dir, umode_t mode)
if (!inode)
return ERR_PTR(-ENOMEM);
lock_super(sb);
mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) {
count = refill_free_cache(sb);
if (count == 0) {
iput(inode);
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return ERR_PTR(-ENOSPC);
}
}
......@@ -174,7 +174,7 @@ struct inode * sysv_new_inode(const struct inode * dir, umode_t mode)
sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */
mark_inode_dirty(inode); /* cleared by sysv_write_inode() */
/* That's it. */
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return inode;
}
......@@ -185,7 +185,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
struct sysv_inode * raw_inode;
int ino, count, sb_count;
lock_super(sb);
mutex_lock(&sbi->s_lock);
sb_count = fs16_to_cpu(sbi, *sbi->s_sb_total_free_inodes);
......@@ -213,7 +213,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
if (count != sb_count)
goto Einval;
out:
unlock_super(sb);
mutex_unlock(&sbi->s_lock);
return count;