{
INITIALIZE_PATH(path);
struct cpu_key max_cpu_key, obj_key;
- struct reiserfs_key save_link_key;
+ struct reiserfs_key save_link_key, last_inode_key;
int retval = 0;
struct item_head *ih;
struct buffer_head *bh;
set_cpu_key_k_offset(&max_cpu_key, ~0U);
max_cpu_key.key_length = 3;
+ memset(&last_inode_key, 0, sizeof(last_inode_key));
+
#ifdef CONFIG_QUOTA
/* Needed for iput() to work correctly and not trash data */
if (s->s_flags & MS_ACTIVE) {
REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
/* not completed unlink (rmdir) found */
reiserfs_info(s, "Removing %k..", INODE_PKEY(inode));
- /* removal gets completed in iput */
- retval = 0;
+ if (memcmp(&last_inode_key, INODE_PKEY(inode),
+ sizeof(last_inode_key))){
+ last_inode_key = *INODE_PKEY(inode);
+ /* removal gets completed in iput */
+ retval = 0;
+ } else {
+ reiserfs_warning(s, "Dead loop in "
+ "finish_unfinished detected, "
+ "just remove save link\n");
+ retval = remove_save_link_only(s,
+ &save_link_key, 0);
+ }
}
iput(inode);
/* to protect file being unlinked from getting lost we "safe" link files
being unlinked. This link will be deleted in the same transaction with last
- item of file. mounting the filesytem we scan all these links and remove
+ item of file. mounting the filesystem we scan all these links and remove
files which almost got lost */
void add_save_link(struct reiserfs_transaction_handle *th,
struct inode *inode, int truncate)
kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
}
-static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
.unlockfs = reiserfs_unlockfs,
.statfs = reiserfs_statfs,
.remount_fs = reiserfs_remount,
+ .show_options = generic_show_options,
#ifdef CONFIG_QUOTA
.quota_read = reiserfs_quota_read,
.quota_write = reiserfs_quota_write,
};
#endif
-static struct export_operations reiserfs_export_ops = {
+static const struct export_operations reiserfs_export_ops = {
.encode_fh = reiserfs_encode_fh,
- .decode_fh = reiserfs_decode_fh,
+ .fh_to_dentry = reiserfs_fh_to_dentry,
+ .fh_to_parent = reiserfs_fh_to_parent,
.get_parent = reiserfs_get_parent,
- .get_dentry = reiserfs_get_dentry,
};
/* this struct is used in reiserfs_getopt () for containing the value for those
unsigned long safe_mask = 0;
unsigned int commit_max_age = (unsigned int)-1;
struct reiserfs_journal *journal = SB_JOURNAL(s);
+ char *new_opts = kstrdup(arg, GFP_KERNEL);
int err;
#ifdef CONFIG_QUOTA
int i;
REISERFS_SB(s)->s_qf_names[i] = NULL;
}
#endif
- return -EINVAL;
+ err = -EINVAL;
+ goto out_err;
}
handle_attrs(s);
}
if (blocks) {
- int rc = reiserfs_resize(s, blocks);
- if (rc != 0)
- return rc;
+ err = reiserfs_resize(s, blocks);
+ if (err != 0)
+ goto out_err;
}
if (*mount_flags & MS_RDONLY) {
/* remount read-only */
if (s->s_flags & MS_RDONLY)
/* it is read-only already */
- return 0;
+ goto out_ok;
/* try to remount file system with read-only permissions */
if (sb_umount_state(rs) == REISERFS_VALID_FS
|| REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
- return 0;
+ goto out_ok;
}
err = journal_begin(&th, s, 10);
if (err)
- return err;
+ goto out_err;
/* Mounting a rw partition read-only. */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
/* remount read-write */
if (!(s->s_flags & MS_RDONLY)) {
reiserfs_xattr_init(s, *mount_flags);
- return 0; /* We are read-write already */
+ goto out_ok; /* We are read-write already */
}
- if (reiserfs_is_journal_aborted(journal))
- return journal->j_errno;
+ if (reiserfs_is_journal_aborted(journal)) {
+ err = journal->j_errno;
+ goto out_err;
+ }
handle_data_mode(s, mount_options);
handle_barrier_mode(s, mount_options);
s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
err = journal_begin(&th, s, 10);
if (err)
- return err;
+ goto out_err;
/* Mount a partition which is read-only, read-write */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
SB_JOURNAL(s)->j_must_wait = 1;
err = journal_end(&th, s, 10);
if (err)
- return err;
+ goto out_err;
s->s_dirt = 0;
if (!(*mount_flags & MS_RDONLY)) {
reiserfs_xattr_init(s, *mount_flags);
}
+out_ok:
+ kfree(s->s_options);
+ s->s_options = new_opts;
return 0;
+
+out_err:
+ kfree(new_opts);
+ return err;
}
static int read_super_block(struct super_block *s, int offset)
struct reiserfs_sb_info *sbi;
int errval = -EINVAL;
+ save_mount_options(s, data);
+
sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
if (!sbi) {
errval = -ENOMEM;
set_sb_umount_state(rs, REISERFS_ERROR_FS);
set_sb_fs_state(rs, 0);
+ /* Clear out s_bmap_nr if it would wrap. We can handle this
+ * case, but older revisions can't. This will cause the
+ * file system to fail mount on those older implementations,
+ * avoiding corruption. -jeffm */
+ if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
+ sb_bmap_nr(rs) != 0) {
+ reiserfs_warning(s, "super-2030: This file system "
+ "claims to use %u bitmap blocks in "
+ "its super block, but requires %u. "
+ "Clearing to zero.", sb_bmap_nr(rs),
+ reiserfs_bmap_count(s));
+
+ set_sb_bmap_nr(rs, 0);
+ }
+
if (old_format_only(s)) {
/* filesystem of format 3.5 either with standard or non-standard
journal */
ret =
journal_begin(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
- if (ret)
+ if (ret) {
+ /* Release dquot anyway to avoid endless cycle in dqput() */
+ dquot_release(dquot);
goto out;
+ }
ret = dquot_release(dquot);
err =
journal_end(&th, dquot->dq_sb,
size_t towrite = len;
struct buffer_head tmp_bh, *bh;
+ if (!current->journal_info) {
+ printk(KERN_WARNING "reiserfs: Quota write (off=%Lu, len=%Lu)"
+ " cancelled because transaction is not started.\n",
+ (unsigned long long)off, (unsigned long long)len);
+ return -EIO;
+ }
mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
while (towrite > 0) {
tocopy = sb->s_blocksize - offset < towrite ?
data += tocopy;
blk++;
}
- out:
+out:
if (len == towrite)
return err;
if (inode->i_size < off + len - towrite)