diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-22 21:05:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-22 21:05:23 -0500 |
commit | a27fcb0cd1bcc812017192bdde41cc456dcd6afe (patch) | |
tree | 95f3ac980e2a50d9132074fd07c0cd684bbbf124 /fs/xfs/libxfs/xfs_dir2_node.c | |
parent | 7d91de74436a69c2b78a7a72f1e7f97f8b4396fa (diff) | |
parent | 8d242e932fb7660c24b3a534197e69c241067e0d (diff) |
Merge tag 'xfs-4.11-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Darrick Wong:
"Here are the XFS changes for 4.11. We aren't introducing any major
features in this release cycle except for this being the first merge
window I've managed on my own. :)
Changes since last update:
- Various cleanups
- Livelock fixes for eofblocks scanning
- Improved input verification for on-disk metadata
- Fix races in the copy on write remap mechanism
- Fix buffer io error timeout controls
- Streamlining of directio copy on write
- Asynchronous discard support
- Fix asserts when splitting delalloc reservations
- Don't bloat bmbt when right shifting extents
- Inode alignment fixes for 32k block sizes"
* tag 'xfs-4.11-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (39 commits)
xfs: remove XFS_ALLOCTYPE_ANY_AG and XFS_ALLOCTYPE_START_AG
xfs: simplify xfs_rtallocate_extent
xfs: tune down agno asserts in the bmap code
xfs: Use xfs_icluster_size_fsb() to calculate inode chunk alignment
xfs: don't reserve blocks for right shift transactions
xfs: fix len comparison in xfs_extent_busy_trim
xfs: fix uninitialized variable in _reflink_convert_cow
xfs: split indlen reservations fairly when under reserved
xfs: handle indlen shortage on delalloc extent merge
xfs: resurrect debug mode drop buffered writes mechanism
xfs: clear delalloc and cache on buffered write failure
xfs: don't block the log commit handler for discards
xfs: improve busy extent sorting
xfs: improve handling of busy extents in the low-level allocator
xfs: don't fail xfs_extent_busy allocation
xfs: correct null checks and error processing in xfs_initialize_perag
xfs: update ctime and mtime on clone destinatation inodes
xfs: allocate direct I/O COW blocks in iomap_begin
xfs: go straight to real allocations for direct I/O COW writes
xfs: return the converted extent in __xfs_reflink_convert_cow
...
Diffstat (limited to 'fs/xfs/libxfs/xfs_dir2_node.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_dir2_node.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 75a557432d0f..bbd1238852b3 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c | |||
@@ -155,6 +155,42 @@ const struct xfs_buf_ops xfs_dir3_free_buf_ops = { | |||
155 | .verify_write = xfs_dir3_free_write_verify, | 155 | .verify_write = xfs_dir3_free_write_verify, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | /* Everything ok in the free block header? */ | ||
159 | static bool | ||
160 | xfs_dir3_free_header_check( | ||
161 | struct xfs_inode *dp, | ||
162 | xfs_dablk_t fbno, | ||
163 | struct xfs_buf *bp) | ||
164 | { | ||
165 | struct xfs_mount *mp = dp->i_mount; | ||
166 | unsigned int firstdb; | ||
167 | int maxbests; | ||
168 | |||
169 | maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo); | ||
170 | firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) - | ||
171 | xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) * | ||
172 | maxbests; | ||
173 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
174 | struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; | ||
175 | |||
176 | if (be32_to_cpu(hdr3->firstdb) != firstdb) | ||
177 | return false; | ||
178 | if (be32_to_cpu(hdr3->nvalid) > maxbests) | ||
179 | return false; | ||
180 | if (be32_to_cpu(hdr3->nvalid) < be32_to_cpu(hdr3->nused)) | ||
181 | return false; | ||
182 | } else { | ||
183 | struct xfs_dir2_free_hdr *hdr = bp->b_addr; | ||
184 | |||
185 | if (be32_to_cpu(hdr->firstdb) != firstdb) | ||
186 | return false; | ||
187 | if (be32_to_cpu(hdr->nvalid) > maxbests) | ||
188 | return false; | ||
189 | if (be32_to_cpu(hdr->nvalid) < be32_to_cpu(hdr->nused)) | ||
190 | return false; | ||
191 | } | ||
192 | return true; | ||
193 | } | ||
158 | 194 | ||
159 | static int | 195 | static int |
160 | __xfs_dir3_free_read( | 196 | __xfs_dir3_free_read( |
@@ -168,11 +204,22 @@ __xfs_dir3_free_read( | |||
168 | 204 | ||
169 | err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, | 205 | err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, |
170 | XFS_DATA_FORK, &xfs_dir3_free_buf_ops); | 206 | XFS_DATA_FORK, &xfs_dir3_free_buf_ops); |
207 | if (err || !*bpp) | ||
208 | return err; | ||
209 | |||
210 | /* Check things that we can't do in the verifier. */ | ||
211 | if (!xfs_dir3_free_header_check(dp, fbno, *bpp)) { | ||
212 | xfs_buf_ioerror(*bpp, -EFSCORRUPTED); | ||
213 | xfs_verifier_error(*bpp); | ||
214 | xfs_trans_brelse(tp, *bpp); | ||
215 | return -EFSCORRUPTED; | ||
216 | } | ||
171 | 217 | ||
172 | /* try read returns without an error or *bpp if it lands in a hole */ | 218 | /* try read returns without an error or *bpp if it lands in a hole */ |
173 | if (!err && tp && *bpp) | 219 | if (tp) |
174 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF); | 220 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF); |
175 | return err; | 221 | |
222 | return 0; | ||
176 | } | 223 | } |
177 | 224 | ||
178 | int | 225 | int |