#include <linux/exportfs.h>
#include <linux/quotaops.h>
#include <linux/vfs.h>
-#include <linux/mnt_namespace.h>
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/crc32.h>
+#include <linux/smp_lock.h>
struct file_system_type reiserfs_fs_type;
static int reiserfs_sync_fs(struct super_block *s, int wait)
{
- if (!(s->s_flags & MS_RDONLY)) {
- struct reiserfs_transaction_handle th;
- reiserfs_write_lock(s);
- if (!journal_begin(&th, s, 1))
- if (!journal_end_sync(&th, s, 1))
- reiserfs_flush_old_commits(s);
- s->s_dirt = 0; /* Even if it's not true.
- * We'll loop forever in sync_supers otherwise */
- reiserfs_write_unlock(s);
- } else {
- s->s_dirt = 0;
- }
+ struct reiserfs_transaction_handle th;
+
+ reiserfs_write_lock(s);
+ if (!journal_begin(&th, s, 1))
+ if (!journal_end_sync(&th, s, 1))
+ reiserfs_flush_old_commits(s);
+ s->s_dirt = 0; /* Even if it's not true.
+ * We'll loop forever in sync_supers otherwise */
+ reiserfs_write_unlock(s);
return 0;
}
retval = remove_save_link_only(s, &save_link_key, 0);
continue;
}
- DQUOT_INIT(inode);
+ vfs_dq_init(inode);
if (truncate && S_ISDIR(inode->i_mode)) {
/* We got a truncate request for a dir which is impossible.
static void reiserfs_kill_sb(struct super_block *s)
{
if (REISERFS_SB(s)) {
-#ifdef CONFIG_REISERFS_FS_XATTR
if (REISERFS_SB(s)->xattr_root) {
d_invalidate(REISERFS_SB(s)->xattr_root);
dput(REISERFS_SB(s)->xattr_root);
REISERFS_SB(s)->xattr_root = NULL;
}
-#endif
if (REISERFS_SB(s)->priv_root) {
d_invalidate(REISERFS_SB(s)->priv_root);
dput(REISERFS_SB(s)->priv_root);
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
+ reiserfs_write_lock(s);
+
+ if (s->s_dirt)
+ reiserfs_write_super(s);
+
/* change file system state to current state if it was mounted with read-write permissions */
if (!(s->s_flags & MS_RDONLY)) {
if (!journal_begin(&th, s, 10)) {
reiserfs_proc_info_done(s);
+ reiserfs_write_unlock(s);
+ mutex_destroy(&REISERFS_SB(s)->lock);
kfree(s->s_fs_info);
s->s_fs_info = NULL;
-
- return;
}
static struct kmem_cache *reiserfs_inode_cachep;
INIT_LIST_HEAD(&ei->i_prealloc_list);
inode_init_once(&ei->vfs_inode);
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
- ei->i_acl_access = NULL;
- ei->i_acl_default = NULL;
-#endif
}
static int init_inodecache(void)
reiserfs_write_unlock(inode->i_sb);
}
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-static void reiserfs_clear_inode(struct inode *inode)
-{
- struct posix_acl *acl;
-
- acl = REISERFS_I(inode)->i_acl_access;
- if (acl && !IS_ERR(acl))
- posix_acl_release(acl);
- REISERFS_I(inode)->i_acl_access = NULL;
-
- acl = REISERFS_I(inode)->i_acl_default;
- if (acl && !IS_ERR(acl))
- posix_acl_release(acl);
- REISERFS_I(inode)->i_acl_default = NULL;
-}
-#else
-#define reiserfs_clear_inode NULL
-#endif
-
#ifdef CONFIG_QUOTA
static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
size_t, loff_t);
.write_inode = reiserfs_write_inode,
.dirty_inode = reiserfs_dirty_inode,
.delete_inode = reiserfs_delete_inode,
- .clear_inode = reiserfs_clear_inode,
.put_super = reiserfs_put_super,
.write_super = reiserfs_write_super,
.sync_fs = reiserfs_sync_fs,
#ifdef CONFIG_QUOTA
#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
-static int reiserfs_dquot_initialize(struct inode *, int);
-static int reiserfs_dquot_drop(struct inode *);
static int reiserfs_write_dquot(struct dquot *);
static int reiserfs_acquire_dquot(struct dquot *);
static int reiserfs_release_dquot(struct dquot *);
static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
static struct dquot_operations reiserfs_quota_operations = {
- .initialize = reiserfs_dquot_initialize,
- .drop = reiserfs_dquot_drop,
+ .initialize = dquot_initialize,
+ .drop = dquot_drop,
.alloc_space = dquot_alloc_space,
.alloc_inode = dquot_alloc_inode,
.free_space = dquot_free_space,
{"conv",.setmask = 1 << REISERFS_CONVERT},
{"attrs",.setmask = 1 << REISERFS_ATTRS},
{"noattrs",.clrmask = 1 << REISERFS_ATTRS},
+ {"expose_privroot", .setmask = 1 << REISERFS_EXPOSE_PRIVROOT},
#ifdef CONFIG_REISERFS_FS_XATTR
{"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},
{"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},
unsigned int qfmt = 0;
#ifdef CONFIG_QUOTA
int i;
+#endif
+
+ reiserfs_write_lock(s);
+#ifdef CONFIG_QUOTA
memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names));
#endif
}
out_ok:
- kfree(s->s_options);
- s->s_options = new_opts;
+ replace_mount_options(s, new_opts);
+ reiserfs_write_unlock(s);
return 0;
out_err:
kfree(new_opts);
+ reiserfs_write_unlock(s);
return err;
}
static int reread_meta_blocks(struct super_block *s)
{
ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
+ reiserfs_write_unlock(s);
wait_on_buffer(SB_BUFFER_WITH_SB(s));
+ reiserfs_write_lock(s);
if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
reiserfs_warning(s, "reiserfs-2504", "error reading the super");
return 1;
sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
if (!sbi) {
errval = -ENOMEM;
- goto error;
+ goto error_alloc;
}
s->s_fs_info = sbi;
/* Set default values for options: non-aggressive tails, RO on errors */
/* setup default block allocator options */
reiserfs_init_alloc_options(s);
+ mutex_init(&REISERFS_SB(s)->lock);
+ REISERFS_SB(s)->lock_depth = -1;
+
+ /*
+ * This function is called with the bkl, which also was the old
+ * locking used here.
+ * do_journal_begin() will soon check if we hold the lock (ie: was the
+ * bkl). This is likely because do_journal_begin() has several another
+ * callers because at this time, it doesn't seem to be necessary to
+ * protect against anything.
+ * Anyway, let's be conservative and lock for now.
+ */
+ reiserfs_write_lock(s);
+
jdev_name = NULL;
if (reiserfs_parse_options
(s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,
goto error;
}
- if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+ if ((errval = reiserfs_lookup_privroot(s)) ||
+ (errval = reiserfs_xattr_init(s, s->s_flags))) {
dput(s->s_root);
s->s_root = NULL;
goto error;
reiserfs_info(s, "using 3.5.x disk format\n");
}
- if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+ if ((errval = reiserfs_lookup_privroot(s)) ||
+ (errval = reiserfs_xattr_init(s, s->s_flags))) {
dput(s->s_root);
s->s_root = NULL;
goto error;
init_waitqueue_head(&(sbi->s_wait));
spin_lock_init(&sbi->bitmap_lock);
+ reiserfs_write_unlock(s);
+
return (0);
error:
+ reiserfs_write_unlock(s);
+error_alloc:
if (jinit_done) { /* kill the commit thread, free journal ram */
journal_release_error(NULL, s);
}
buf->f_bsize = dentry->d_sb->s_blocksize;
/* changed to accommodate gcc folks. */
buf->f_type = REISERFS_SUPER_MAGIC;
+ buf->f_fsid.val[0] = (u32)crc32_le(0, rs->s_uuid, sizeof(rs->s_uuid)/2);
+ buf->f_fsid.val[1] = (u32)crc32_le(0, rs->s_uuid + sizeof(rs->s_uuid)/2,
+ sizeof(rs->s_uuid)/2);
+
return 0;
}
#ifdef CONFIG_QUOTA
-static int reiserfs_dquot_initialize(struct inode *inode, int type)
-{
- struct reiserfs_transaction_handle th;
- int ret, err;
-
- /* We may create quota structure so we need to reserve enough blocks */
- reiserfs_write_lock(inode->i_sb);
- ret =
- journal_begin(&th, inode->i_sb,
- 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
- if (ret)
- goto out;
- ret = dquot_initialize(inode, type);
- err =
- journal_end(&th, inode->i_sb,
- 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
- if (!ret && err)
- ret = err;
- out:
- reiserfs_write_unlock(inode->i_sb);
- return ret;
-}
-
-static int reiserfs_dquot_drop(struct inode *inode)
-{
- struct reiserfs_transaction_handle th;
- int ret, err;
-
- /* We may delete quota structure so we need to reserve enough blocks */
- reiserfs_write_lock(inode->i_sb);
- ret =
- journal_begin(&th, inode->i_sb,
- 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
- if (ret) {
- /*
- * We call dquot_drop() anyway to at least release references
- * to quota structures so that umount does not hang.
- */
- dquot_drop(inode);
- goto out;
- }
- ret = dquot_drop(inode);
- err =
- journal_end(&th, inode->i_sb,
- 2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
- if (!ret && err)
- ret = err;
- out:
- reiserfs_write_unlock(inode->i_sb);
- return ret;
-}
-
static int reiserfs_write_dquot(struct dquot *dquot)
{
struct reiserfs_transaction_handle th;