aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-09-26 15:55:20 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:12:49 -0400
commit8f6d7f4f45f18a5b669dbbf068c74b3d5be59dbf (patch)
tree6a43f6ec137c0c491a308ba258552a0b47cbc8c0 /fs
parent726c35fa0edf1d9b8a88b73255532e73089aedda (diff)
Btrfs: break out of orphan cleanup if we can't make progress
I noticed while running xfstests 83 that if we didn't have enough space to delete our inode the orphan cleanup would just loop. This is because it keeps finding the same orphan item and keeps trying to kill it but can't because we don't get an error back from iput for deleting the inode. So keep track of the last guy we tried to kill, if it's the same as the one we're trying to kill currently we know we are having problems and can just error out. I don't have a way to test this so look hard and make sure it's right. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 96fc9e342219..15adfb542502 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2230,6 +2230,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
2230 struct btrfs_key key, found_key; 2230 struct btrfs_key key, found_key;
2231 struct btrfs_trans_handle *trans; 2231 struct btrfs_trans_handle *trans;
2232 struct inode *inode; 2232 struct inode *inode;
2233 u64 last_objectid = 0;
2233 int ret = 0, nr_unlink = 0, nr_truncate = 0; 2234 int ret = 0, nr_unlink = 0, nr_truncate = 0;
2234 2235
2235 if (cmpxchg(&root->orphan_cleanup_state, 0, ORPHAN_CLEANUP_STARTED)) 2236 if (cmpxchg(&root->orphan_cleanup_state, 0, ORPHAN_CLEANUP_STARTED))
@@ -2281,6 +2282,16 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
2281 * crossing root thing. we store the inode number in the 2282 * crossing root thing. we store the inode number in the
2282 * offset of the orphan item. 2283 * offset of the orphan item.
2283 */ 2284 */
2285
2286 if (found_key.offset == last_objectid) {
2287 printk(KERN_ERR "btrfs: Error removing orphan entry, "
2288 "stopping orphan cleanup\n");
2289 ret = -EINVAL;
2290 goto out;
2291 }
2292
2293 last_objectid = found_key.offset;
2294
2284 found_key.objectid = found_key.offset; 2295 found_key.objectid = found_key.offset;
2285 found_key.type = BTRFS_INODE_ITEM_KEY; 2296 found_key.type = BTRFS_INODE_ITEM_KEY;
2286 found_key.offset = 0; 2297 found_key.offset = 0;