diff options
| author | Jan Kara <jack@suse.cz> | 2009-08-03 12:24:21 -0400 |
|---|---|---|
| committer | Joel Becker <joel.becker@oracle.com> | 2009-08-17 15:50:12 -0400 |
| commit | ada508274b8698a33cb0e5bd037db0f9dc781795 (patch) | |
| tree | 43788f6393117159d75897bb75496c0ddb6c4e1b | |
| parent | b409d7a0ab46fe530efe52734984b4ed5d46c3eb (diff) | |
ocfs2: Handle quota file corruption more gracefully
ocfs2_read_virt_blocks() does BUG when we try to read a block from a file
beyond its end. Since this can happen due to filesystem corruption, it
is not really an appropriate answer. Make ocfs2_read_quota_block() check
the condition and handle it by calling ocfs2_error() and returning EIO.
[ Modified to print ip_blkno in the error - Joel ]
Reported-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
| -rw-r--r-- | fs/ocfs2/quota_global.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index bf7742d0ee3b..44f2a5e1d042 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "sysfile.h" | 23 | #include "sysfile.h" |
| 24 | #include "dlmglue.h" | 24 | #include "dlmglue.h" |
| 25 | #include "uptodate.h" | 25 | #include "uptodate.h" |
| 26 | #include "super.h" | ||
| 26 | #include "quota.h" | 27 | #include "quota.h" |
| 27 | 28 | ||
| 28 | static struct workqueue_struct *ocfs2_quota_wq = NULL; | 29 | static struct workqueue_struct *ocfs2_quota_wq = NULL; |
| @@ -114,6 +115,15 @@ int ocfs2_read_quota_block(struct inode *inode, u64 v_block, | |||
| 114 | int rc = 0; | 115 | int rc = 0; |
| 115 | struct buffer_head *tmp = *bh; | 116 | struct buffer_head *tmp = *bh; |
| 116 | 117 | ||
| 118 | if (i_size_read(inode) >> inode->i_sb->s_blocksize_bits <= v_block) { | ||
| 119 | ocfs2_error(inode->i_sb, | ||
| 120 | "Quota file %llu is probably corrupted! Requested " | ||
| 121 | "to read block %Lu but file has size only %Lu\n", | ||
| 122 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
| 123 | (unsigned long long)v_block, | ||
| 124 | (unsigned long long)i_size_read(inode)); | ||
| 125 | return -EIO; | ||
| 126 | } | ||
| 117 | rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0, | 127 | rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0, |
| 118 | ocfs2_validate_quota_block); | 128 | ocfs2_validate_quota_block); |
| 119 | if (rc) | 129 | if (rc) |
