Commit 90e0c225 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
  ext3: Fix dirtying of journalled buffers in data=journal mode
  ext3: default to ordered mode
  quota: Use mark_inode_dirty_sync instead of mark_inode_dirty
  quota: Change quota error message to print out disk and function name
  MAINTAINERS: Update entries of ext2 and ext3
  MAINTAINERS: Update address of Andreas Dilger
  ext3: Avoid filesystem corruption after a crash under heavy delete load
  ext3: remove vestiges of nobh support
  ext3: Fix set but unused variables
  quota: clean up quota active checks
  quota: Clean up the namespace in dqblk_xfs.h
  quota: check quota reservation on remove_dquot_ref
parents 938a73b9 5f11e6a4
...@@ -2237,6 +2237,7 @@ S: Maintained ...@@ -2237,6 +2237,7 @@ S: Maintained
F: drivers/net/eth16i.c F: drivers/net/eth16i.c
EXT2 FILE SYSTEM EXT2 FILE SYSTEM
M: Jan Kara <jack@suse.cz>
L: linux-ext4@vger.kernel.org L: linux-ext4@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/filesystems/ext2.txt F: Documentation/filesystems/ext2.txt
...@@ -2244,8 +2245,9 @@ F: fs/ext2/ ...@@ -2244,8 +2245,9 @@ F: fs/ext2/
F: include/linux/ext2* F: include/linux/ext2*
EXT3 FILE SYSTEM EXT3 FILE SYSTEM
M: Jan Kara <jack@suse.cz>
M: Andrew Morton <akpm@linux-foundation.org> M: Andrew Morton <akpm@linux-foundation.org>
M: Andreas Dilger <adilger@sun.com> M: Andreas Dilger <adilger.kernel@dilger.ca>
L: linux-ext4@vger.kernel.org L: linux-ext4@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/filesystems/ext3.txt F: Documentation/filesystems/ext3.txt
...@@ -2254,7 +2256,7 @@ F: include/linux/ext3* ...@@ -2254,7 +2256,7 @@ F: include/linux/ext3*
EXT4 FILE SYSTEM EXT4 FILE SYSTEM
M: "Theodore Ts'o" <tytso@mit.edu> M: "Theodore Ts'o" <tytso@mit.edu>
M: Andreas Dilger <adilger@sun.com> M: Andreas Dilger <adilger.kernel@dilger.ca>
L: linux-ext4@vger.kernel.org L: linux-ext4@vger.kernel.org
W: http://ext4.wiki.kernel.org W: http://ext4.wiki.kernel.org
Q: http://patchwork.ozlabs.org/project/linux-ext4/list/ Q: http://patchwork.ozlabs.org/project/linux-ext4/list/
......
...@@ -31,6 +31,7 @@ config EXT3_FS ...@@ -31,6 +31,7 @@ config EXT3_FS
config EXT3_DEFAULTS_TO_ORDERED config EXT3_DEFAULTS_TO_ORDERED
bool "Default to 'data=ordered' in ext3" bool "Default to 'data=ordered' in ext3"
depends on EXT3_FS depends on EXT3_FS
default y
help help
The journal mode options for ext3 have different tradeoffs The journal mode options for ext3 have different tradeoffs
between when data is guaranteed to be on disk and between when data is guaranteed to be on disk and
......
...@@ -1149,9 +1149,25 @@ static int walk_page_buffers( handle_t *handle, ...@@ -1149,9 +1149,25 @@ static int walk_page_buffers( handle_t *handle,
static int do_journal_get_write_access(handle_t *handle, static int do_journal_get_write_access(handle_t *handle,
struct buffer_head *bh) struct buffer_head *bh)
{ {
int dirty = buffer_dirty(bh);
int ret;
if (!buffer_mapped(bh) || buffer_freed(bh)) if (!buffer_mapped(bh) || buffer_freed(bh))
return 0; return 0;
return ext3_journal_get_write_access(handle, bh); /*
* __block_prepare_write() could have dirtied some buffers. Clean
* the dirty bit as jbd2_journal_get_write_access() could complain
* otherwise about fs integrity issues. Setting of the dirty bit
* by __block_prepare_write() isn't a real problem here as we clear
* the bit before releasing a page lock and thus writeback cannot
* ever write the buffer.
*/
if (dirty)
clear_buffer_dirty(bh);
ret = ext3_journal_get_write_access(handle, bh);
if (!ret && dirty)
ret = ext3_journal_dirty_metadata(handle, bh);
return ret;
} }
/* /*
...@@ -1625,10 +1641,7 @@ static int ext3_writeback_writepage(struct page *page, ...@@ -1625,10 +1641,7 @@ static int ext3_writeback_writepage(struct page *page,
goto out_fail; goto out_fail;
} }
if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) ret = block_write_full_page(page, ext3_get_block, wbc);
ret = nobh_writepage(page, ext3_get_block, wbc);
else
ret = block_write_full_page(page, ext3_get_block, wbc);
err = ext3_journal_stop(handle); err = ext3_journal_stop(handle);
if (!ret) if (!ret)
...@@ -1922,17 +1935,6 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page, ...@@ -1922,17 +1935,6 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page,
length = blocksize - (offset & (blocksize - 1)); length = blocksize - (offset & (blocksize - 1));
iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
/*
* For "nobh" option, we can only work if we don't need to
* read-in the page - otherwise we create buffers to do the IO.
*/
if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) &&
ext3_should_writeback_data(inode) && PageUptodate(page)) {
zero_user(page, offset, length);
set_page_dirty(page);
goto unlock;
}
if (!page_has_buffers(page)) if (!page_has_buffers(page))
create_empty_buffers(page, blocksize, 0); create_empty_buffers(page, blocksize, 0);
...@@ -2283,27 +2285,6 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, ...@@ -2283,27 +2285,6 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
(__le32*)bh->b_data + addr_per_block, (__le32*)bh->b_data + addr_per_block,
depth); depth);
/*
* We've probably journalled the indirect block several
* times during the truncate. But it's no longer
* needed and we now drop it from the transaction via
* journal_revoke().
*
* That's easy if it's exclusively part of this
* transaction. But if it's part of the committing
* transaction then journal_forget() will simply
* brelse() it. That means that if the underlying
* block is reallocated in ext3_get_block(),
* unmap_underlying_metadata() will find this block
* and will try to get rid of it. damn, damn.
*
* If this block has already been committed to the
* journal, a revoke record will be written. And
* revoke records must be emitted *before* clearing
* this block's bit in the bitmaps.
*/
ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
/* /*
* Everything below this this pointer has been * Everything below this this pointer has been
* released. Now let this top-of-subtree go. * released. Now let this top-of-subtree go.
...@@ -2327,6 +2308,31 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, ...@@ -2327,6 +2308,31 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
truncate_restart_transaction(handle, inode); truncate_restart_transaction(handle, inode);
} }
/*
* We've probably journalled the indirect block several
* times during the truncate. But it's no longer
* needed and we now drop it from the transaction via
* journal_revoke().
*
* That's easy if it's exclusively part of this
* transaction. But if it's part of the committing
* transaction then journal_forget() will simply
* brelse() it. That means that if the underlying
* block is reallocated in ext3_get_block(),
* unmap_underlying_metadata() will find this block
* and will try to get rid of it. damn, damn. Thus
* we don't allow a block to be reallocated until
* a transaction freeing it has fully committed.
*
* We also have to make sure journal replay after a
* crash does not overwrite non-journaled data blocks
* with old metadata when the block got reallocated for
* data. Thus we have to store a revoke record for a
* block in the same transaction in which we free the
* block.
*/
ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
ext3_free_blocks(handle, inode, nr, 1); ext3_free_blocks(handle, inode, nr, 1);
if (parent_bh) { if (parent_bh) {
......
...@@ -1447,7 +1447,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, ...@@ -1447,7 +1447,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
struct inode *inode) struct inode *inode)
{ {
struct inode *dir = dentry->d_parent->d_inode; struct inode *dir = dentry->d_parent->d_inode;
unsigned long offset;
struct buffer_head * bh; struct buffer_head * bh;
struct ext3_dir_entry_2 *de; struct ext3_dir_entry_2 *de;
struct super_block * sb; struct super_block * sb;
...@@ -1469,7 +1468,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, ...@@ -1469,7 +1468,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
ext3_mark_inode_dirty(handle, dir); ext3_mark_inode_dirty(handle, dir);
} }
blocks = dir->i_size >> sb->s_blocksize_bits; blocks = dir->i_size >> sb->s_blocksize_bits;
for (block = 0, offset = 0; block < blocks; block++) { for (block = 0; block < blocks; block++) {
bh = ext3_bread(handle, dir, block, 0, &retval); bh = ext3_bread(handle, dir, block, 0, &retval);
if(!bh) if(!bh)
return retval; return retval;
......
...@@ -964,7 +964,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, ...@@ -964,7 +964,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
ext3_fsblk_t n_blocks_count) ext3_fsblk_t n_blocks_count)
{ {
ext3_fsblk_t o_blocks_count; ext3_fsblk_t o_blocks_count;
unsigned long o_groups_count;
ext3_grpblk_t last; ext3_grpblk_t last;
ext3_grpblk_t add; ext3_grpblk_t add;
struct buffer_head * bh; struct buffer_head * bh;
...@@ -976,7 +975,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, ...@@ -976,7 +975,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
* yet: we're going to revalidate es->s_blocks_count after * yet: we're going to revalidate es->s_blocks_count after
* taking the s_resize_lock below. */ * taking the s_resize_lock below. */
o_blocks_count = le32_to_cpu(es->s_blocks_count); o_blocks_count = le32_to_cpu(es->s_blocks_count);
o_groups_count = EXT3_SB(sb)->s_groups_count;
if (test_opt(sb, DEBUG)) if (test_opt(sb, DEBUG))
printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n", printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n",
......
...@@ -661,9 +661,6 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) ...@@ -661,9 +661,6 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
*/ */
seq_puts(seq, ",barrier="); seq_puts(seq, ",barrier=");
seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
if (test_opt(sb, NOBH))
seq_puts(seq, ",nobh");
seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS))); seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS)));
if (test_opt(sb, DATA_ERR_ABORT)) if (test_opt(sb, DATA_ERR_ABORT))
seq_puts(seq, ",data_err=abort"); seq_puts(seq, ",data_err=abort");
...@@ -1255,10 +1252,12 @@ static int parse_options (char *options, struct super_block *sb, ...@@ -1255,10 +1252,12 @@ static int parse_options (char *options, struct super_block *sb,
*n_blocks_count = option; *n_blocks_count = option;
break; break;
case Opt_nobh: case Opt_nobh:
set_opt(sbi->s_mount_opt, NOBH); ext3_msg(sb, KERN_WARNING,
"warning: ignoring deprecated nobh option");
break; break;
case Opt_bh: case Opt_bh:
clear_opt(sbi->s_mount_opt, NOBH); ext3_msg(sb, KERN_WARNING,
"warning: ignoring deprecated bh option");
break; break;
default: default:
ext3_msg(sb, KERN_ERR, ext3_msg(sb, KERN_ERR,
...@@ -2001,14 +2000,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) ...@@ -2001,14 +2000,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
break; break;
} }
if (test_opt(sb, NOBH)) {
if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) {
ext3_msg(sb, KERN_WARNING,
"warning: ignoring nobh option - "
"it is supported only with writeback mode");
clear_opt(sbi->s_mount_opt, NOBH);
}
}
/* /*
* The journal_load will have done any necessary log recovery, * The journal_load will have done any necessary log recovery,
* so we can safely mount the rest of the filesystem now. * so we can safely mount the rest of the filesystem now.
......
...@@ -1449,10 +1449,10 @@ static int gfs2_quota_get_xstate(struct super_block *sb, ...@@ -1449,10 +1449,10 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
switch (sdp->sd_args.ar_quota) { switch (sdp->sd_args.ar_quota) {
case GFS2_QUOTA_ON: case GFS2_QUOTA_ON:
fqs->qs_flags |= (XFS_QUOTA_UDQ_ENFD | XFS_QUOTA_GDQ_ENFD); fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
/*FALLTHRU*/ /*FALLTHRU*/
case GFS2_QUOTA_ACCOUNT: case GFS2_QUOTA_ACCOUNT:
fqs->qs_flags |= (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT); fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
break; break;
case GFS2_QUOTA_OFF: case GFS2_QUOTA_OFF:
break; break;
...@@ -1498,7 +1498,7 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, ...@@ -1498,7 +1498,7 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb; qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
fdq->d_version = FS_DQUOT_VERSION; fdq->d_version = FS_DQUOT_VERSION;
fdq->d_flags = (type == QUOTA_USER) ? XFS_USER_QUOTA : XFS_GROUP_QUOTA; fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
fdq->d_id = id; fdq->d_id = id;
fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit); fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn); fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
...@@ -1533,12 +1533,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, ...@@ -1533,12 +1533,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
switch(type) { switch(type) {
case USRQUOTA: case USRQUOTA:
type = QUOTA_USER; type = QUOTA_USER;
if (fdq->d_flags != XFS_USER_QUOTA) if (fdq->d_flags != FS_USER_QUOTA)
return -EINVAL; return -EINVAL;
break; break;
case GRPQUOTA: case GRPQUOTA:
type = QUOTA_GROUP; type = QUOTA_GROUP;
if (fdq->d_flags != XFS_GROUP_QUOTA) if (fdq->d_flags != FS_GROUP_QUOTA)
return -EINVAL; return -EINVAL;
break; break;
default: default:
......
...@@ -1281,13 +1281,9 @@ int journal_check_used_features (journal_t *journal, unsigned long compat, ...@@ -1281,13 +1281,9 @@ int journal_check_used_features (journal_t *journal, unsigned long compat,
int journal_check_available_features (journal_t *journal, unsigned long compat, int journal_check_available_features (journal_t *journal, unsigned long compat,
unsigned long ro, unsigned long incompat) unsigned long ro, unsigned long incompat)
{ {
journal_superblock_t *sb;
if (!compat && !ro && !incompat) if (!compat && !ro && !incompat)
return 1; return 1;
sb = journal->j_superblock;
/* We can support any known requested features iff the /* We can support any known requested features iff the
* superblock is in version 2. Otherwise we fail to support any * superblock is in version 2. Otherwise we fail to support any
* extended sb features. */ * extended sb features. */
...@@ -1481,7 +1477,6 @@ int journal_flush(journal_t *journal) ...@@ -1481,7 +1477,6 @@ int journal_flush(journal_t *journal)
int journal_wipe(journal_t *journal, int write) int journal_wipe(journal_t *journal, int write)
{ {
journal_superblock_t *sb;
int err = 0; int err = 0;
J_ASSERT (!(journal->j_flags & JFS_LOADED)); J_ASSERT (!(journal->j_flags & JFS_LOADED));
...@@ -1490,8 +1485,6 @@ int journal_wipe(journal_t *journal, int write) ...@@ -1490,8 +1485,6 @@ int journal_wipe(journal_t *journal, int write)
if (err) if (err)
return err; return err;
sb = journal->j_superblock;
if (!journal->j_tail) if (!journal->j_tail)
goto no_recovery; goto no_recovery;
......
...@@ -283,12 +283,9 @@ int journal_recover(journal_t *journal) ...@@ -283,12 +283,9 @@ int journal_recover(journal_t *journal)
int journal_skip_recovery(journal_t *journal) int journal_skip_recovery(journal_t *journal)
{ {
int err; int err;
journal_superblock_t * sb;
struct recovery_info info; struct recovery_info info;
memset (&info, 0, sizeof(info)); memset (&info, 0, sizeof(info));
sb = journal->j_superblock;
err = do_one_pass(journal, &info, PASS_SCAN); err = do_one_pass(journal, &info, PASS_SCAN);
...@@ -297,7 +294,8 @@ int journal_skip_recovery(journal_t *journal) ...@@ -297,7 +294,8 @@ int journal_skip_recovery(journal_t *journal)
++journal->j_transaction_sequence; ++journal->j_transaction_sequence;
} else { } else {
#ifdef CONFIG_JBD_DEBUG #ifdef CONFIG_JBD_DEBUG
int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); int dropped = info.end_transaction -
be32_to_cpu(journal->j_superblock->s_sequence);
#endif #endif
jbd_debug(1, jbd_debug(1,
"JBD: ignoring %d transaction%s from the journal.\n", "JBD: ignoring %d transaction%s from the journal.\n",
...@@ -321,11 +319,6 @@ static int do_one_pass(journal_t *journal, ...@@ -321,11 +319,6 @@ static int do_one_pass(journal_t *journal,
unsigned int sequence; unsigned int sequence;
int blocktype; int blocktype;
/* Precompute the maximum metadata descriptors in a descriptor block */
int MAX_BLOCKS_PER_DESC;
MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
/ sizeof(journal_block_tag_t));
/* /*
* First thing is to establish what we expect to find in the log * First thing is to establish what we expect to find in the log
* (in terms of transaction IDs), and where (in terms of log * (in terms of transaction IDs), and where (in terms of log
......
...@@ -132,6 +132,22 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); ...@@ -132,6 +132,22 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock);
EXPORT_SYMBOL(dq_data_lock); EXPORT_SYMBOL(dq_data_lock);
void __quota_error(struct super_block *sb, const char *func,
const char *fmt, ...)
{
va_list args;
if (printk_ratelimit()) {
va_start(args, fmt);
printk(KERN_ERR "Quota error (device %s): %s: ",
sb->s_id, func);
vprintk(fmt, args);
printk("\n");
va_end(args);
}
}
EXPORT_SYMBOL(__quota_error);
#if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING) #if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING)
static char *quotatypes[] = INITQFNAMES; static char *quotatypes[] = INITQFNAMES;
#endif #endif
...@@ -705,11 +721,8 @@ void dqput(struct dquot *dquot) ...@@ -705,11 +721,8 @@ void dqput(struct dquot *dquot)
return; return;
#ifdef CONFIG_QUOTA_DEBUG #ifdef CONFIG_QUOTA_DEBUG
if (!atomic_read(&dquot->dq_count)) { if (!atomic_read(&dquot->dq_count)) {
printk("VFS: dqput: trying to free free dquot\n"); quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
printk("VFS: device %s, dquot of %s %d\n", quotatypes[dquot->dq_type], dquot->dq_id);
dquot->dq_sb->s_id,
quotatypes[dquot->dq_type],
dquot->dq_id);
BUG(); BUG();
} }
#endif #endif
...@@ -732,9 +745,9 @@ void dqput(struct dquot *dquot) ...@@ -732,9 +745,9 @@ void dqput(struct dquot *dquot)
/* Commit dquot before releasing */ /* Commit dquot before releasing */
ret = dquot->dq_sb->dq_op->write_dquot(dquot); ret = dquot->dq_sb->dq_op->write_dquot(dquot);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "VFS: cannot write quota structure on " quota_error(dquot->dq_sb, "Can't write quota structure"
"device %s (error %d). Quota may get out of " " (error %d). Quota may get out of sync!",
"sync!\n", dquot->dq_sb->s_id, ret); ret);
/* /*
* We clear dirty bit anyway, so that we avoid * We clear dirty bit anyway, so that we avoid
* infinite loop here * infinite loop here
...@@ -914,9 +927,9 @@ static void add_dquot_ref(struct super_block *sb, int type) ...@@ -914,9 +927,9 @@ static void add_dquot_ref(struct super_block *sb, int type)
#ifdef CONFIG_QUOTA_DEBUG #ifdef CONFIG_QUOTA_DEBUG
if (reserved) { if (reserved) {
printk(KERN_WARNING "VFS (%s): Writes happened before quota" quota_error(sb, "Writes happened before quota was turned on "
" was turned on thus quota information is probably " "thus quota information is probably inconsistent. "
"inconsistent. Please run quotacheck(8).\n", sb->s_id); "Please run quotacheck(8)");
} }
#endif #endif
} }
...@@ -947,7 +960,9 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, ...@@ -947,7 +960,9 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
if (dqput_blocks(dquot)) { if (dqput_blocks(dquot)) {
#ifdef CONFIG_QUOTA_DEBUG #ifdef CONFIG_QUOTA_DEBUG
if (atomic_read(&dquot->dq_count) != 1) if (atomic_read(&dquot->dq_count) != 1)
printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); quota_error(inode->i_sb, "Adding dquot with "
"dq_count %d to dispose list",
atomic_read(&dquot->dq_count));
#endif #endif
spin_lock(&dq_list_lock); spin_lock(&dq_list_lock);
/* As dquot must have currently users it can't be on /* As dquot must have currently users it can't be on
...@@ -986,6 +1001,7 @@ static void remove_dquot_ref(struct super_block *sb, int type, ...@@ -986,6 +1001,7 @@ static void remove_dquot_ref(struct super_block *sb, int type,
struct list_head *tofree_head) struct list_head *tofree_head)
{ {
struct inode *inode; struct inode *inode;
int reserved = 0;
spin_lock(&inode_lock); spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
...@@ -995,10 +1011,20 @@ static void remove_dquot_ref(struct super_block *sb, int type, ...@@ -995,10 +1011,20 @@ static void remove_dquot_ref(struct super_block *sb, int type,
* only quota pointers and these have separate locking * only quota pointers and these have separate locking
* (dqptr_sem). * (dqptr_sem).
*/ */
if (!IS_NOQUOTA(inode)) if (!IS_NOQUOTA(inode)) {
if (unlikely(inode_get_rsv_space(inode) > 0))
reserved = 1;
remove_inode_dquot_ref(inode, type, tofree_head); remove_inode_dquot_ref(inode, type, tofree_head);
}
} }
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
#ifdef CONFIG_QUOTA_DEBUG
if (reserved) {
printk(KERN_WARNING "VFS (%s): Writes happened after quota"
" was disabled thus quota information is probably "
"inconsistent. Please run quotacheck(8).\n", sb->s_id);
}
#endif
} }
/* Gather all references from inodes and drop them */ /* Gather all references from inodes and drop them */
...@@ -1304,6 +1330,15 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space) ...@@ -1304,6 +1330,15 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space)
return QUOTA_NL_NOWARN; return QUOTA_NL_NOWARN;
} }
static int dquot_active(const struct inode *inode)
{
struct super_block *sb = inode->i_sb;
if (IS_NOQUOTA(inode))
return 0;
return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
}
/* /*
* Initialize quota pointers in inode * Initialize quota pointers in inode
* *
...@@ -1323,7 +1358,7 @@ static void __dquot_initialize(struct inode *inode, int type) ...@@ -1323,7 +1358,7 @@ static void __dquot_initialize(struct inode *inode, int type)
/* First test before acquiring mutex - solves deadlocks when we /* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */ * re-enter the quota code and are already holding the mutex */
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) if (!dquot_active(inode))
return; return;
/* First get references to structures we might need. */ /* First get references to structures we might need. */
...@@ -1507,7 +1542,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) ...@@ -1507,7 +1542,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
* First test before acquiring mutex - solves deadlocks when we * First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex * re-enter the quota code and are already holding the mutex
*/ */
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) { if (!dquot_active(inode)) {
inode_incr_space(inode, number, reserve); inode_incr_space(inode, number, reserve);
goto out; goto out;
} }
...@@ -1559,7 +1594,7 @@ int dquot_alloc_inode(const struct inode *inode) ...@@ -1559,7 +1594,7 @@ int dquot_alloc_inode(const struct inode *inode)
/* First test before acquiring mutex - solves deadlocks when we /* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */ * re-enter the quota code and are already holding the mutex */
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) if (!dquot_active(inode))
return 0; return 0;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = QUOTA_NL_NOWARN; warntype[cnt] = QUOTA_NL_NOWARN;
...@@ -1596,7 +1631,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) ...@@ -1596,7 +1631,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{ {
int cnt; int cnt;
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) { if (!dquot_active(inode)) {
inode_claim_rsv_space(inode, number); inode_claim_rsv_space(inode, number);
return 0; return 0;
} }
...@@ -1629,7 +1664,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) ...@@ -1629,7 +1664,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
/* First test before acquiring mutex - solves deadlocks when we /* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */ * re-enter the quota code and are already holding the mutex */
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) { if (!dquot_active(inode)) {
inode_decr_space(inode, number, reserve); inode_decr_space(inode, number, reserve);
return; return;
} }
...@@ -1667,7 +1702,7 @@ void dquot_free_inode(const struct inode *inode) ...@@ -1667,7 +1702,7 @@ void dquot_free_inode(const struct inode *inode)
/* First test before acquiring mutex - solves deadlocks when we /* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */ * re-enter the quota code and are already holding the mutex */
if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) if (!dquot_active(inode))
return; return;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
...@@ -1790,7 +1825,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) ...@@ -1790,7 +1825,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
int ret; int ret;
if (!sb_any_quota_active(sb) || IS_NOQUOTA(inode)) if (!dquot_active(inode))
return 0; return 0;
if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid)
...@@ -1957,7 +1992,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags) ...@@ -1957,7 +1992,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
truncate_inode_pages(&toputinode[cnt]->i_data, truncate_inode_pages(&toputinode[cnt]->i_data,
0); 0);
mutex_unlock(&toputinode[cnt]->i_mutex); mutex_unlock(&toputinode[cnt]->i_mutex);
mark_inode_dirty(toputinode[cnt]); mark_inode_dirty_sync(toputinode[cnt]);
} }
mutex_unlock(&dqopt->dqonoff_mutex); mutex_unlock(&dqopt->dqonoff_mutex);
} }
...@@ -2270,7 +2305,7 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) ...@@ -2270,7 +2305,7 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
memset(di, 0, sizeof(*di)); memset(di, 0, sizeof(*di));
di->d_version = FS_DQUOT_VERSION; di->d_version = FS_DQUOT_VERSION;
di->d_flags = dquot->dq_type == USRQUOTA ? di->d_flags = dquot->dq_type == USRQUOTA ?
XFS_USER_QUOTA : XFS_GROUP_QUOTA; FS_USER_QUOTA : FS_GROUP_QUOTA;
di->d_id = dquot->dq_id; di->d_id = dquot->dq_id;
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
......
...@@ -65,8 +65,7 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) ...@@ -65,8 +65,7 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
ret = sb->s_op->quota_write(sb, info->dqi_type, buf, ret = sb->s_op->quota_write(sb, info->dqi_type, buf,
info->dqi_usable_bs, blk << info->dqi_blocksize_bits); info->dqi_usable_bs, blk << info->dqi_blocksize_bits);
if (ret != info->dqi_usable_bs) { if (ret != info->dqi_usable_bs) {
q_warn(KERN_WARNING "VFS: dquota write failed on " quota_error(sb, "dquota write failed");
"dev %s\n", sb->s_id);
if (ret >= 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
} }
...@@ -160,9 +159,8 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, ...@@ -160,9 +159,8 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
/* No matter whether write succeeds block is out of list */ /* No matter whether write succeeds block is out of list */
if (write_blk(info, blk, buf) < 0) if (write_blk(info, blk, buf) < 0)
q_warn(KERN_ERR quota_error(info->dqi_sb, "Can't write block (%u) "
"VFS: Can't write block (%u) with free entries.\n", "with free entries", blk);
blk);
return 0; return 0;
out_buf: out_buf:
kfree(tmpbuf); kfree(tmpbuf);
...@@ -252,9 +250,8 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, ...@@ -252,9 +250,8 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) {
*err = remove_free_dqentry(info, buf, blk); *err = remove_free_dqentry(info, buf, blk);
if (*err < 0) { if (*err < 0) {
q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't " quota_error(dquot->dq_sb, "Can't remove block (%u) "
"remove block (%u) from entry free list.\n", "from entry free list", blk);
blk);
goto out_buf; goto out_buf;
} }
} }
...@@ -268,16 +265,15 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, ...@@ -268,16 +265,15 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
} }
#ifdef __QUOTA_QT_PARANOIA #ifdef __QUOTA_QT_PARANOIA
if (i == qtree_dqstr_in_blk(info)) { if (i == qtree_dqstr_in_blk(info)) {
printk(KERN_ERR "VFS: find_free_dqentry(): Data block full " quota_error(dquot->dq_sb, "Data block full but it shouldn't");
"but it shouldn't.\n");
*err = -EIO; *err = -EIO;
goto out_buf; goto out_buf;
} }
#endif #endif
*err = write_blk(info, blk, buf); *err = write_blk(info, blk, buf);
if (*err < 0) { if (*err < 0) {
q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " quota_error(dquot->dq_sb, "Can't write quota data block %u",
"data block %u.\n", blk); blk);
goto out_buf; goto out_buf;
} }
dquot->dq_off = (blk << info->dqi_blocksize_bits) + dquot->dq_off = (blk << info->dqi_blocksize_bits) +
...@@ -311,8 +307,8 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -311,8 +307,8 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
} else { } else {
ret = read_blk(info, *treeblk, buf); ret = read_blk(info, *treeblk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't read tree quota block " quota_error(dquot->dq_sb, "Can't read tree quota "
"%u.\n", *treeblk); "block %u", *treeblk);
goto out_buf; goto out_buf;
} }
} }
...@@ -323,9 +319,9 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -323,9 +319,9 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
if (depth == info->dqi_qtree_depth - 1) { if (depth == info->dqi_qtree_depth - 1) {
#ifdef __QUOTA_QT_PARANOIA #ifdef __QUOTA_QT_PARANOIA
if (newblk) { if (newblk) {
printk(KERN_ERR "VFS: Inserting already present quota " quota_error(dquot->dq_sb, "Inserting already present "
"entry (block %u).\n", "quota entry (block %u)",
le32_to_cpu(ref[get_index(info, le32_to_cpu(ref[get_index(info,
dquot->dq_id, depth)])); dquot->dq_id, depth)]));
ret = -EIO; ret = -EIO;
goto out_buf; goto out_buf;
...@@ -373,8 +369,8 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ...@@ -373,8 +369,8 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
if (!dquot->dq_off) { if (!dquot->dq_off) {
ret = dq_insert_tree(info, dquot); ret = dq_insert_tree(info, dquot);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Error %zd occurred while " quota_error(sb, "Error %zd occurred while creating "
"creating quota.\n", ret); "quota", ret);
kfree(ddquot); kfree(ddquot);
return ret; return ret;
} }
...@@ -385,8 +381,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ...@@ -385,8 +381,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
dquot->dq_off); dquot->dq_off);
if (ret != info->dqi_entry_size) { if (ret != info->dqi_entry_size) {
q_warn(KERN_WARNING "VFS: dquota write failed on dev %s\n", quota_error(sb, "dquota write failed");
sb->s_id);
if (ret >= 0) if (ret >= 0)
ret = -ENOSPC; ret = -ENOSPC;
} else { } else {
...@@ -410,14 +405,15 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -410,14 +405,15 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { if (dquot->dq_off >> info->dqi_blocksize_bits != blk) {
q_warn(KERN_ERR "VFS: Quota structure has offset to other " quota_error(dquot->dq_sb, "Quota structure has offset to "
"block (%u) than it should (%u).\n", blk, "other block (%u) than it should (%u)", blk,
(uint)(dquot->dq_off >> info->dqi_blocksize_bits)); (uint)(dquot->dq_off >> info->dqi_blocksize_bits));
goto out_buf; goto out_buf;
} }
ret = read_blk(info, blk, buf); ret = read_blk(info, blk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", blk); quota_error(dquot->dq_sb, "Can't read quota data block %u",
blk);
goto out_buf; goto out_buf;
} }
dh = (struct qt_disk_dqdbheader *)buf; dh = (struct qt_disk_dqdbheader *)buf;
...@@ -427,8 +423,8 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -427,8 +423,8 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
if (ret >= 0) if (ret >= 0)
ret = put_free_dqblk(info, buf, blk); ret = put_free_dqblk(info, buf, blk);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't move quota data block (%u) " quota_error(dquot->dq_sb, "Can't move quota data block "
"to free list.\n", blk); "(%u) to free list", blk);
goto out_buf; goto out_buf;
} }
} else { } else {
...@@ -440,15 +436,15 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -440,15 +436,15 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
/* Insert will write block itself */ /* Insert will write block itself */
ret = insert_free_dqentry(info, buf, blk); ret = insert_free_dqentry(info, buf, blk);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't insert quota data " quota_error(dquot->dq_sb, "Can't insert quota "
"block (%u) to free entry list.\n", blk); "data block (%u) to free entry list", blk);
goto out_buf; goto out_buf;
} }
} else { } else {
ret = write_blk(info, blk, buf); ret = write_blk(info, blk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't write quota data " quota_error(dquot->dq_sb, "Can't write quota "
"block %u\n", blk); "data block %u", blk);
goto out_buf; goto out_buf;
} }
} }
...@@ -472,7 +468,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -472,7 +468,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
return -ENOMEM; return -ENOMEM;
ret = read_blk(info, *blk, buf); ret = read_blk(info, *blk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); quota_error(dquot->dq_sb, "Can't read quota data "
"block %u", blk);
goto out_buf; goto out_buf;
} }
newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
...@@ -496,8 +493,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, ...@@ -496,8 +493,8 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
} else { } else {
ret = write_blk(info, *blk, buf); ret = write_blk(info, *blk, buf);
if (ret < 0) if (ret < 0)
q_warn(KERN_ERR "VFS: Can't write quota tree " quota_error(dquot->dq_sb, "Can't write quota "
"block %u.\n", *blk); "tree block %u", blk);
} }
} }
out_buf: out_buf:
...@@ -529,7 +526,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, ...@@ -529,7 +526,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
return -ENOMEM; return -ENOMEM;
ret = read_blk(info, blk, buf); ret = read_blk(info, blk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); quota_error(dquot->dq_sb, "Can't read quota tree "
"block %u", blk);
goto out_buf; goto out_buf;
} }
ddquot = buf + sizeof(struct qt_disk_dqdbheader); ddquot = buf + sizeof(struct qt_disk_dqdbheader);
...@@ -539,8 +537,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, ...@@ -539,8 +537,8 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
ddquot += info->dqi_entry_size; ddquot += info->dqi_entry_size;
} }
if (i == qtree_dqstr_in_blk(info)) { if (i == qtree_dqstr_in_blk(info)) {
q_warn(KERN_ERR "VFS: Quota for id %u referenced " quota_error(dquot->dq_sb, "Quota for id %u referenced "
"but not present.\n", dquot->dq_id); "but not present", dquot->dq_id);
ret = -EIO; ret = -EIO;
goto out_buf; goto out_buf;
} else { } else {
...@@ -564,7 +562,8 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, ...@@ -564,7 +562,8 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
return -ENOMEM; return -ENOMEM;
ret = read_blk(info, blk, buf); ret = read_blk(info, blk, buf);
if (ret < 0) { if (ret < 0) {
q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); quota_error(dquot->dq_sb, "Can't read quota tree block %u",
blk);
goto out_buf; goto out_buf;
} }
ret = 0; ret = 0;
...@@ -598,7 +597,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ...@@ -598,7 +597,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
#ifdef __QUOTA_QT_PARANOIA #ifdef __QUOTA_QT_PARANOIA
/* Invalidated quota? */ /* Invalidated quota? */
if (!sb_dqopt(dquot->dq_sb)->files[type]) { if (!sb_dqopt(dquot->dq_sb)->files[type]) {
printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); quota_error(sb, "Quota invalidated while reading!");
return -EIO; return -EIO;
} }
#endif #endif
...@@ -607,8 +606,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ...@@ -607,8 +606,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
offset = find_dqentry(info, dquot); offset = find_dqentry(info, dquot);
if (offset <= 0) { /* Entry not present? */ if (offset <= 0) { /* Entry not present? */
if (offset < 0) if (offset < 0)
q_warn(KERN_ERR "VFS: Can't read quota " quota_error(sb, "Can't read quota structure "
"structure for id %u.\n", dquot->dq_id); "for id %u", dquot->dq_id);
dquot->dq_off = 0; dquot->dq_off = 0;
set_bit(DQ_FAKE_B, &dquot->dq_flags); set_bit(DQ_FAKE_B, &dquot->dq_flags);
memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
...@@ -625,8 +624,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) ...@@ -625,8 +624,8 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
if (ret != info->dqi_entry_size) { if (ret != info->dqi_entry_size) {
if (ret >= 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
q_warn(KERN_ERR "VFS: Error while reading quota " quota_error(sb, "Error while reading quota structure for id %u",
"structure for id %u.\n", dquot->dq_id); dquot->dq_id);
set_bit(DQ_FAKE_B, &dquot->dq_flags); set_bit(DQ_FAKE_B, &dquot->dq_flags);
memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
kfree(ddquot); kfree(ddquot);
......
...@@ -22,10 +22,4 @@ struct qt_disk_dqdbheader { ...@@ -22,10 +22,4 @@ struct qt_disk_dqdbheader {
#define QT_TREEOFF 1 /* Offset of tree in file in blocks */ #define QT_TREEOFF 1 /* Offset of tree in file in blocks */
#define q_warn(fmt, args...) \
do { \
if (printk_ratelimit()) \
printk(fmt, ## args); \
} while(0)
#endif /* _LINUX_QUOTAIO_TREE_H */ #endif /* _LINUX_QUOTAIO_TREE_H */
...@@ -95,8 +95,7 @@ static int v1_commit_dqblk(struct dquot *dquot) ...@@ -95,8 +95,7 @@ static int v1_commit_dqblk(struct dquot *dquot)
(char *)&dqblk, sizeof(struct v1_disk_dqblk), (char *)&dqblk, sizeof(struct v1_disk_dqblk),
v1_dqoff(dquot->dq_id)); v1_dqoff(dquot->dq_id));
if (ret != sizeof(struct v1_disk_dqblk)) { if (ret != sizeof(struct v1_disk_dqblk)) {
printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", quota_error(dquot->dq_sb, "dquota write failed");
dquot->dq_sb->s_id);
if (ret >= 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
goto out; goto out;
......
...@@ -63,9 +63,8 @@ static int v2_read_header(struct super_block *sb, int type, ...@@ -63,9 +63,8 @@ static int v2_read_header(struct super_block *sb, int type,
size = sb->s_op->quota_read(sb, type, (char *)dqhead, size = sb->s_op->quota_read(sb, type, (char *)dqhead,
sizeof(struct v2_disk_dqheader), 0); sizeof(struct v2_disk_dqheader), 0);
if (size != sizeof(struct v2_disk_dqheader)) { if (size != sizeof(struct v2_disk_dqheader)) {
q_warn(KERN_WARNING "quota_v2: Failed header read:" quota_error(sb, "Failed header read: expected=%zd got=%zd",
" expected=%zd got=%zd\n", sizeof(struct v2_disk_dqheader), size);
sizeof(struct v2_disk_dqheader), size);
return 0; return 0;
} }
return 1; return 1;
...@@ -106,8 +105,7 @@ static int v2_read_file_info(struct super_block *sb, int type) ...@@ -106,8 +105,7 @@ static int v2_read_file_info(struct super_block *sb, int type)
size = sb->s_op->quota_read(sb, type, (char *)&dinfo, size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
if (size != sizeof(struct v2_disk_dqinfo)) { if (size != sizeof(struct v2_disk_dqinfo)) {
q_warn(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n", quota_error(sb, "Can't read info structure");
sb->s_id);
return -1; return -1;
} }
info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS); info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS);
...@@ -167,8 +165,7 @@ static int v2_write_file_info(struct super_block *sb, int type) ...@@ -167,8 +165,7 @@ static int v2_write_file_info(struct super_block *sb, int type)
size = sb->s_op->quota_write(sb, type, (char *)&dinfo, size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
if (size != sizeof(struct v2_disk_dqinfo)) { if (size != sizeof(struct v2_disk_dqinfo)) {
q_warn(KERN_WARNING "Can't write info structure on device %s.\n", quota_error(sb, "Can't write info structure");
sb->s_id);
return -1; return -1;
} }
return 0; return 0;
......
...@@ -68,15 +68,15 @@ xfs_fs_set_xstate( ...@@ -68,15 +68,15 @@ xfs_fs_set_xstate(
if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp)) if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
return -ENOSYS; return -ENOSYS;
if (uflags & XFS_QUOTA_UDQ_ACCT) if (uflags & FS_QUOTA_UDQ_ACCT)
flags |= XFS_UQUOTA_ACCT; flags |= XFS_UQUOTA_ACCT;
if (uflags & XFS_QUOTA_PDQ_ACCT) if (uflags & FS_QUOTA_PDQ_ACCT)
flags |= XFS_PQUOTA_ACCT; flags |= XFS_PQUOTA_ACCT;
if (uflags & XFS_QUOTA_GDQ_ACCT) if (uflags & FS_QUOTA_GDQ_ACCT)
flags |= XFS_GQUOTA_ACCT; flags |= XFS_GQUOTA_ACCT;
if (uflags & XFS_QUOTA_UDQ_ENFD) if (uflags & FS_QUOTA_UDQ_ENFD)
flags |= XFS_UQUOTA_ENFD; flags |= XFS_UQUOTA_ENFD;
if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) if (uflags & (FS_QUOTA_PDQ_ENFD|FS_QUOTA_GDQ_ENFD))
flags |= XFS_OQUOTA_ENFD; flags |= XFS_OQUOTA_ENFD;
switch (op) { switch (op) {
......
...@@ -810,9 +810,9 @@ xfs_qm_export_dquot( ...@@ -810,9 +810,9 @@ xfs_qm_export_dquot(
} }
#ifdef DEBUG #ifdef DEBUG
if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) || if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) ||
(XFS_IS_OQUOTA_ENFORCED(mp) && (XFS_IS_OQUOTA_ENFORCED(mp) &&
(dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) && (dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
dst->d_id != 0) { dst->d_id != 0) {
if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) && if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
(dst->d_blk_softlimit > 0)) { (dst->d_blk_softlimit > 0)) {
...@@ -833,17 +833,17 @@ xfs_qm_export_qtype_flags( ...@@ -833,17 +833,17 @@ xfs_qm_export_qtype_flags(
/* /*
* Can't be more than one, or none. * Can't be more than one, or none.
*/ */
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) != ASSERT((flags & (FS_PROJ_QUOTA | FS_USER_QUOTA)) !=
(XFS_PROJ_QUOTA | XFS_USER_QUOTA)); (FS_PROJ_QUOTA | FS_USER_QUOTA));
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) != ASSERT((flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)) !=
(XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)); (FS_PROJ_QUOTA | FS_GROUP_QUOTA));
ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) != ASSERT((flags & (FS_USER_QUOTA | FS_GROUP_QUOTA)) !=
(XFS_USER_QUOTA | XFS_GROUP_QUOTA)); (FS_USER_QUOTA | FS_GROUP_QUOTA));
ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0); ASSERT((flags & (FS_PROJ_QUOTA|FS_USER_QUOTA|FS_GROUP_QUOTA)) != 0);
return (flags & XFS_DQ_USER) ? return (flags & XFS_DQ_USER) ?
XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? FS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
XFS_PROJ_QUOTA : XFS_GROUP_QUOTA; FS_PROJ_QUOTA : FS_GROUP_QUOTA;
} }
STATIC uint STATIC uint
...@@ -854,16 +854,16 @@ xfs_qm_export_flags( ...@@ -854,16 +854,16 @@ xfs_qm_export_flags(
uflags = 0; uflags = 0;
if (flags & XFS_UQUOTA_ACCT) if (flags & XFS_UQUOTA_ACCT)
uflags |= XFS_QUOTA_UDQ_ACCT; uflags |= FS_QUOTA_UDQ_ACCT;
if (flags & XFS_PQUOTA_ACCT) if (flags & XFS_PQUOTA_ACCT)
uflags |= XFS_QUOTA_PDQ_ACCT; uflags |= FS_QUOTA_PDQ_ACCT;
if (flags & XFS_GQUOTA_ACCT) if (flags & XFS_GQUOTA_ACCT)
uflags |= XFS_QUOTA_GDQ_ACCT; uflags |= FS_QUOTA_GDQ_ACCT;
if (flags & XFS_UQUOTA_ENFD) if (flags & XFS_UQUOTA_ENFD)
uflags |= XFS_QUOTA_UDQ_ENFD; uflags |= FS_QUOTA_UDQ_ENFD;
if (flags & (XFS_OQUOTA_ENFD)) { if (flags & (XFS_OQUOTA_ENFD)) {
uflags |= (flags & XFS_GQUOTA_ACCT) ? uflags |= (flags & XFS_GQUOTA_ACCT) ?
XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD; FS_QUOTA_GDQ_ENFD : FS_QUOTA_PDQ_ENFD;
} }
return (uflags); return (uflags);
} }
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */ #define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
typedef struct fs_disk_quota { typedef struct fs_disk_quota {
__s8 d_version; /* version of this structure */ __s8 d_version; /* version of this structure */
__s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ __s8 d_flags; /* FS_{USER,PROJ,GROUP}_QUOTA */
__u16 d_fieldmask; /* field specifier */ __u16 d_fieldmask; /* field specifier */
__u32 d_id; /* user, project, or group ID */ __u32 d_id; /* user, project, or group ID */
__u64 d_blk_hardlimit;/* absolute limit on disk blks */ __u64 d_blk_hardlimit;/* absolute limit on disk blks */
...@@ -119,18 +119,18 @@ typedef struct fs_disk_quota { ...@@ -119,18 +119,18 @@ typedef struct fs_disk_quota {
#define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT) #define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
/* /*
* Various flags related to quotactl(2). Only relevant to XFS filesystems. * Various flags related to quotactl(2).
*/ */
#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */ #define FS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */ #define FS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */ #define FS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */ #define FS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
#define XFS_QUOTA_PDQ_ACCT (1<<4) /* project quota accounting */ #define FS_QUOTA_PDQ_ACCT (1<<4) /* project quota accounting */
#define XFS_QUOTA_PDQ_ENFD (1<<5) /* project quota limits enforcement */ #define FS_QUOTA_PDQ_ENFD (1<<5) /* project quota limits enforcement */
#define XFS_USER_QUOTA (1<<0) /* user quota type */ #define FS_USER_QUOTA (1<<0) /* user quota type */
#define XFS_PROJ_QUOTA (1<<1) /* project quota type */ #define FS_PROJ_QUOTA (1<<1) /* project quota type */
#define XFS_GROUP_QUOTA (1<<2) /* group quota type */ #define FS_GROUP_QUOTA (1<<2) /* group quota type */
/* /*
* fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system. * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
...@@ -151,7 +151,7 @@ typedef struct fs_qfilestat { ...@@ -151,7 +151,7 @@ typedef struct fs_qfilestat {
typedef struct fs_quota_stat { typedef struct fs_quota_stat {
__s8 qs_version; /* version number for future changes */ __s8 qs_version; /* version number for future changes */
__u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */ __u16 qs_flags; /* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
__s8 qs_pad; /* unused */ __s8 qs_pad; /* unused */
fs_qfilestat_t qs_uquota; /* user quota storage information */ fs_qfilestat_t qs_uquota; /* user quota storage information */
fs_qfilestat_t qs_gquota; /* group quota storage information */ fs_qfilestat_t qs_gquota; /* group quota storage information */
......
...@@ -400,7 +400,6 @@ struct ext3_inode { ...@@ -400,7 +400,6 @@ struct ext3_inode {
#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ #define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ #define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */
#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */
#define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */
#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
......
...@@ -28,6 +28,12 @@ static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) ...@@ -28,6 +28,12 @@ static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
#if defined(CONFIG_QUOTA) #if defined(CONFIG_QUOTA)
#define quota_error(sb, fmt, args...) \
__quota_error((sb), __func__, fmt , ## args)
extern void __quota_error(struct super_block *sb, const char *func,
const char *fmt, ...);
/* /*
* declaration of quota_function calls in kernel. * declaration of quota_function calls in kernel.
*/ */
...@@ -145,11 +151,6 @@ static inline bool sb_has_quota_active(struct super_block *sb, int type) ...@@ -145,11 +151,6 @@ static inline bool sb_has_quota_active(struct super_block *sb, int type)
!sb_has_quota_suspended(sb, type); !sb_has_quota_suspended(sb, type);
} }
static inline unsigned sb_any_quota_active(struct super_block *sb)
{
return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
}
/* /*
* Operations supported for diskquotas. * Operations supported for diskquotas.
*/ */
...@@ -194,11 +195,6 @@ static inline int sb_has_quota_active(struct super_block *sb, int type) ...@@ -194,11 +195,6 @@ static inline int sb_has_quota_active(struct super_block *sb, int type)
return 0; return 0;
} }
static inline int sb_any_quota_active(struct super_block *sb)
{
return 0;
}
static inline void dquot_initialize(struct inode *inode) static inline void dquot_initialize(struct inode *inode)
{ {
} }
...@@ -270,7 +266,7 @@ static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr) ...@@ -270,7 +266,7 @@ static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr)
static inline void dquot_alloc_space_nofail(struct inode *inode, qsize_t nr) static inline void dquot_alloc_space_nofail(struct inode *inode, qsize_t nr)
{ {
__dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN|DQUOT_SPACE_NOFAIL); __dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN|DQUOT_SPACE_NOFAIL);
mark_inode_dirty(inode); mark_inode_dirty_sync(inode);
} }
static inline int dquot_alloc_space(struct inode *inode, qsize_t nr) static inline int dquot_alloc_space(struct inode *inode, qsize_t nr)
...@@ -279,7 +275,7 @@ static inline int dquot_alloc_space(struct inode *inode, qsize_t nr) ...@@ -279,7 +275,7 @@ static inline int dquot_alloc_space(struct inode *inode, qsize_t nr)
ret = dquot_alloc_space_nodirty(inode, nr); ret = dquot_alloc_space_nodirty(inode, nr);
if (!ret) if (!ret)
mark_inode_dirty(inode); mark_inode_dirty_sync(inode);
return ret; return ret;
} }
...@@ -309,7 +305,7 @@ static inline int dquot_prealloc_block(struct inode *inode, qsize_t nr) ...@@ -309,7 +305,7 @@ static inline int dquot_prealloc_block(struct inode *inode, qsize_t nr)
ret = dquot_prealloc_block_nodirty(inode, nr); ret = dquot_prealloc_block_nodirty(inode, nr);
if (!ret) if (!ret)
mark_inode_dirty(inode); mark_inode_dirty_sync(inode);
return ret; return ret;
} }
...@@ -325,7 +321,7 @@ static inline int dquot_claim_block(struct inode *inode, qsize_t nr) ...@@ -325,7 +321,7 @@ static inline int dquot_claim_block(struct inode *inode, qsize_t nr)
ret = dquot_claim_space_nodirty(inode, nr << inode->i_blkbits); ret = dquot_claim_space_nodirty(inode, nr << inode->i_blkbits);
if (!ret) if (!ret)
mark_inode_dirty(inode); mark_inode_dirty_sync(inode);
return ret; return ret;
} }
...@@ -337,7 +333,7 @@ static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr) ...@@ -337,7 +333,7 @@ static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr)
static inline void dquot_free_space(struct inode *inode, qsize_t nr) static inline void dquot_free_space(struct inode *inode, qsize_t nr)
{ {
dquot_free_space_nodirty(inode, nr); dquot_free_space_nodirty(inode, nr);
mark_inode_dirty(inode); mark_inode_dirty_sync(inode);
} }
static inline void dquot_free_block_nodirty(struct inode *inode, qsize_t nr) static inline void dquot_free_block_nodirty(struct inode *inode, qsize_t nr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment