#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
+#include <linux/exportfs.h>
#include <linux/vfs.h>
#include <linux/mnt_namespace.h>
#include <linux/mount.h>
{
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);
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);
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;
- if (flags & SLAB_CTOR_CONSTRUCTOR) {
- INIT_LIST_HEAD(&ei->i_prealloc_list);
- inode_init_once(&ei->vfs_inode);
+ 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;
+ ei->i_acl_access = NULL;
+ ei->i_acl_default = NULL;
#endif
- }
}
static int init_inodecache(void)
reiserfs_inode_info),
0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
- init_once, NULL);
+ init_once);
if (reiserfs_inode_cachep == NULL)
return -ENOMEM;
return 0;
REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
/* Preallocate by 16 blocks (17-1) at once */
REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
+#ifdef CONFIG_REISERFS_FS_XATTR
/* Initialize the rwsem for xattr dir */
init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
-
+#endif
/* setup default block allocator options */
reiserfs_init_alloc_options(s);
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)