aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2017-02-02 18:13:58 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-08 03:30:30 -0400
commit7e2dd1fb71020e12b60a886b06f2b7fe8c465eaa (patch)
treefa515b7b0e3320e4047ffe92f4fe7609a3632ce9
parent0a6844abacc1adf428f80ad1b4b1f4cce915d2b2 (diff)
xfs: fail _dir_open when readahead fails
commit 7a652bbe366464267190c2792a32ce4fff5595ef upstream. When we open a directory, we try to readahead block 0 of the directory on the assumption that we're going to need it soon. If the bmbt is corrupt, the directory will never be usable and the readahead fails immediately, so we might as well prevent the directory from being opened at all. This prevents a subsequent read or modify operation from hitting it and taking the fs offline. NOTE: We're only checking for early failures in the block mapping, not the readahead directory block itself. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/xfs/libxfs/xfs_da_btree.c6
-rw-r--r--fs/xfs/libxfs/xfs_da_btree.h2
-rw-r--r--fs/xfs/xfs_file.c4
3 files changed, 5 insertions, 7 deletions
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
index f2dc1a950c85..1bdf2888295b 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -2633,7 +2633,7 @@ out_free:
2633/* 2633/*
2634 * Readahead the dir/attr block. 2634 * Readahead the dir/attr block.
2635 */ 2635 */
2636xfs_daddr_t 2636int
2637xfs_da_reada_buf( 2637xfs_da_reada_buf(
2638 struct xfs_inode *dp, 2638 struct xfs_inode *dp,
2639 xfs_dablk_t bno, 2639 xfs_dablk_t bno,
@@ -2664,7 +2664,5 @@ out_free:
2664 if (mapp != &map) 2664 if (mapp != &map)
2665 kmem_free(mapp); 2665 kmem_free(mapp);
2666 2666
2667 if (error) 2667 return error;
2668 return -1;
2669 return mappedbno;
2670} 2668}
diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 98c75cbe6ac2..4e29cb6a3627 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -201,7 +201,7 @@ int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp,
201 xfs_dablk_t bno, xfs_daddr_t mappedbno, 201 xfs_dablk_t bno, xfs_daddr_t mappedbno,
202 struct xfs_buf **bpp, int whichfork, 202 struct xfs_buf **bpp, int whichfork,
203 const struct xfs_buf_ops *ops); 203 const struct xfs_buf_ops *ops);
204xfs_daddr_t xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno, 204int xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno,
205 xfs_daddr_t mapped_bno, int whichfork, 205 xfs_daddr_t mapped_bno, int whichfork,
206 const struct xfs_buf_ops *ops); 206 const struct xfs_buf_ops *ops);
207int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 207int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 81b7fee40b54..780be7a7abe9 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -992,9 +992,9 @@ xfs_dir_open(
992 */ 992 */
993 mode = xfs_ilock_data_map_shared(ip); 993 mode = xfs_ilock_data_map_shared(ip);
994 if (ip->i_d.di_nextents > 0) 994 if (ip->i_d.di_nextents > 0)
995 xfs_dir3_data_readahead(ip, 0, -1); 995 error = xfs_dir3_data_readahead(ip, 0, -1);
996 xfs_iunlock(ip, mode); 996 xfs_iunlock(ip, mode);
997 return 0; 997 return error;
998} 998}
999 999
1000STATIC int 1000STATIC int