aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-13 17:49:18 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:36:53 -0500
commit4ae1d69bedc8d174cb8a558694607e013157cde1 (patch)
treece5c599415435d24ddc5cae88207f5f26c0a18b4 /fs/ocfs2/xattr.c
parenta22305cc693254a2aa651e797875669112ef8635 (diff)
ocfs2: Wrap xattr block reads in a dedicated function
We weren't consistently checking xattr blocks after we read them. Most places checked the signature, but none checked xb_blkno or xb_fs_signature. Create a toplevel ocfs2_read_xattr_block() that does the read and the validation. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c94
1 files changed, 70 insertions, 24 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 3cc8385f9738..ef4aa5482d01 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -314,6 +314,65 @@ static void ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket *dest,
314 } 314 }
315} 315}
316 316
317static int ocfs2_validate_xattr_block(struct super_block *sb,
318 struct buffer_head *bh)
319{
320 struct ocfs2_xattr_block *xb =
321 (struct ocfs2_xattr_block *)bh->b_data;
322
323 mlog(0, "Validating xattr block %llu\n",
324 (unsigned long long)bh->b_blocknr);
325
326 if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
327 ocfs2_error(sb,
328 "Extended attribute block #%llu has bad "
329 "signature %.*s",
330 (unsigned long long)bh->b_blocknr, 7,
331 xb->xb_signature);
332 return -EINVAL;
333 }
334
335 if (le64_to_cpu(xb->xb_blkno) != bh->b_blocknr) {
336 ocfs2_error(sb,
337 "Extended attribute block #%llu has an "
338 "invalid xb_blkno of %llu",
339 (unsigned long long)bh->b_blocknr,
340 (unsigned long long)le64_to_cpu(xb->xb_blkno));
341 return -EINVAL;
342 }
343
344 if (le32_to_cpu(xb->xb_fs_generation) != OCFS2_SB(sb)->fs_generation) {
345 ocfs2_error(sb,
346 "Extended attribute block #%llu has an invalid "
347 "xb_fs_generation of #%u",
348 (unsigned long long)bh->b_blocknr,
349 le32_to_cpu(xb->xb_fs_generation));
350 return -EINVAL;
351 }
352
353 return 0;
354}
355
356static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno,
357 struct buffer_head **bh)
358{
359 int rc;
360 struct buffer_head *tmp = *bh;
361
362 rc = ocfs2_read_block(inode, xb_blkno, &tmp);
363 if (!rc) {
364 rc = ocfs2_validate_xattr_block(inode->i_sb, tmp);
365 if (rc)
366 brelse(tmp);
367 }
368
369 /* If ocfs2_read_block() got us a new bh, pass it up. */
370 if (!rc && !*bh)
371 *bh = tmp;
372
373 return rc;
374}
375
317static inline const char *ocfs2_xattr_prefix(int name_index) 376static inline const char *ocfs2_xattr_prefix(int name_index)
318{ 377{
319 struct xattr_handler *handler = NULL; 378 struct xattr_handler *handler = NULL;
@@ -739,18 +798,14 @@ static int ocfs2_xattr_block_list(struct inode *inode,
739 if (!di->i_xattr_loc) 798 if (!di->i_xattr_loc)
740 return ret; 799 return ret;
741 800
742 ret = ocfs2_read_block(inode, le64_to_cpu(di->i_xattr_loc), &blk_bh); 801 ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc),
802 &blk_bh);
743 if (ret < 0) { 803 if (ret < 0) {
744 mlog_errno(ret); 804 mlog_errno(ret);
745 return ret; 805 return ret;
746 } 806 }
747 807
748 xb = (struct ocfs2_xattr_block *)blk_bh->b_data; 808 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
749 if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
750 ret = -EIO;
751 goto cleanup;
752 }
753
754 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { 809 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
755 struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header; 810 struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header;
756 ret = ocfs2_xattr_list_entries(inode, header, 811 ret = ocfs2_xattr_list_entries(inode, header,
@@ -760,7 +815,7 @@ static int ocfs2_xattr_block_list(struct inode *inode,
760 ret = ocfs2_xattr_tree_list_index_block(inode, xt, 815 ret = ocfs2_xattr_tree_list_index_block(inode, xt,
761 buffer, buffer_size); 816 buffer, buffer_size);
762 } 817 }
763cleanup: 818
764 brelse(blk_bh); 819 brelse(blk_bh);
765 820
766 return ret; 821 return ret;
@@ -1693,24 +1748,19 @@ static int ocfs2_xattr_free_block(struct inode *inode,
1693 u64 blk, bg_blkno; 1748 u64 blk, bg_blkno;
1694 u16 bit; 1749 u16 bit;
1695 1750
1696 ret = ocfs2_read_block(inode, block, &blk_bh); 1751 ret = ocfs2_read_xattr_block(inode, block, &blk_bh);
1697 if (ret < 0) { 1752 if (ret < 0) {
1698 mlog_errno(ret); 1753 mlog_errno(ret);
1699 goto out; 1754 goto out;
1700 } 1755 }
1701 1756
1702 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1703 if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
1704 ret = -EIO;
1705 goto out;
1706 }
1707
1708 ret = ocfs2_xattr_block_remove(inode, blk_bh); 1757 ret = ocfs2_xattr_block_remove(inode, blk_bh);
1709 if (ret < 0) { 1758 if (ret < 0) {
1710 mlog_errno(ret); 1759 mlog_errno(ret);
1711 goto out; 1760 goto out;
1712 } 1761 }
1713 1762
1763 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1714 blk = le64_to_cpu(xb->xb_blkno); 1764 blk = le64_to_cpu(xb->xb_blkno);
1715 bit = le16_to_cpu(xb->xb_suballoc_bit); 1765 bit = le16_to_cpu(xb->xb_suballoc_bit);
1716 bg_blkno = ocfs2_which_suballoc_group(blk, bit); 1766 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
@@ -1950,19 +2000,15 @@ static int ocfs2_xattr_block_find(struct inode *inode,
1950 if (!di->i_xattr_loc) 2000 if (!di->i_xattr_loc)
1951 return ret; 2001 return ret;
1952 2002
1953 ret = ocfs2_read_block(inode, le64_to_cpu(di->i_xattr_loc), &blk_bh); 2003 ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc),
2004 &blk_bh);
1954 if (ret < 0) { 2005 if (ret < 0) {
1955 mlog_errno(ret); 2006 mlog_errno(ret);
1956 return ret; 2007 return ret;
1957 } 2008 }
1958 2009
1959 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1960 if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
1961 ret = -EIO;
1962 goto cleanup;
1963 }
1964
1965 xs->xattr_bh = blk_bh; 2010 xs->xattr_bh = blk_bh;
2011 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1966 2012
1967 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { 2013 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
1968 xs->header = &xb->xb_attrs.xb_header; 2014 xs->header = &xb->xb_attrs.xb_header;
@@ -2259,9 +2305,9 @@ meta_guess:
2259 /* calculate metadata allocation. */ 2305 /* calculate metadata allocation. */
2260 if (di->i_xattr_loc) { 2306 if (di->i_xattr_loc) {
2261 if (!xbs->xattr_bh) { 2307 if (!xbs->xattr_bh) {
2262 ret = ocfs2_read_block(inode, 2308 ret = ocfs2_read_xattr_block(inode,
2263 le64_to_cpu(di->i_xattr_loc), 2309 le64_to_cpu(di->i_xattr_loc),
2264 &bh); 2310 &bh);
2265 if (ret) { 2311 if (ret) {
2266 mlog_errno(ret); 2312 mlog_errno(ret);
2267 goto out; 2313 goto out;