aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/journal.c')
-rw-r--r--fs/ocfs2/journal.c118
1 files changed, 44 insertions, 74 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 8bbfc80e5c5c..f9d01e25298d 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1213,17 +1213,49 @@ bail:
1213 return status; 1213 return status;
1214} 1214}
1215 1215
1216struct ocfs2_orphan_filldir_priv {
1217 struct inode *head;
1218 struct ocfs2_super *osb;
1219};
1220
1221static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len,
1222 loff_t pos, u64 ino, unsigned type)
1223{
1224 struct ocfs2_orphan_filldir_priv *p = priv;
1225 struct inode *iter;
1226
1227 if (name_len == 1 && !strncmp(".", name, 1))
1228 return 0;
1229 if (name_len == 2 && !strncmp("..", name, 2))
1230 return 0;
1231
1232 /* Skip bad inodes so that recovery can continue */
1233 iter = ocfs2_iget(p->osb, ino,
1234 OCFS2_FI_FLAG_ORPHAN_RECOVERY);
1235 if (IS_ERR(iter))
1236 return 0;
1237
1238 mlog(0, "queue orphan %llu\n",
1239 (unsigned long long)OCFS2_I(iter)->ip_blkno);
1240 /* No locking is required for the next_orphan queue as there
1241 * is only ever a single process doing orphan recovery. */
1242 OCFS2_I(iter)->ip_next_orphan = p->head;
1243 p->head = iter;
1244
1245 return 0;
1246}
1247
1216static int ocfs2_queue_orphans(struct ocfs2_super *osb, 1248static int ocfs2_queue_orphans(struct ocfs2_super *osb,
1217 int slot, 1249 int slot,
1218 struct inode **head) 1250 struct inode **head)
1219{ 1251{
1220 int status; 1252 int status;
1221 struct inode *orphan_dir_inode = NULL; 1253 struct inode *orphan_dir_inode = NULL;
1222 struct inode *iter; 1254 struct ocfs2_orphan_filldir_priv priv;
1223 unsigned long offset, blk, local; 1255 loff_t pos = 0;
1224 struct buffer_head *bh = NULL; 1256
1225 struct ocfs2_dir_entry *de; 1257 priv.osb = osb;
1226 struct super_block *sb = osb->sb; 1258 priv.head = *head;
1227 1259
1228 orphan_dir_inode = ocfs2_get_system_file_inode(osb, 1260 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
1229 ORPHAN_DIR_SYSTEM_INODE, 1261 ORPHAN_DIR_SYSTEM_INODE,
@@ -1241,77 +1273,15 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
1241 goto out; 1273 goto out;
1242 } 1274 }
1243 1275
1244 offset = 0; 1276 status = ocfs2_dir_foreach(orphan_dir_inode, &pos, &priv,
1245 iter = NULL; 1277 ocfs2_orphan_filldir);
1246 while(offset < i_size_read(orphan_dir_inode)) { 1278 if (status) {
1247 blk = offset >> sb->s_blocksize_bits; 1279 mlog_errno(status);
1248 1280 goto out;
1249 bh = ocfs2_bread(orphan_dir_inode, blk, &status, 0);
1250 if (!bh)
1251 status = -EINVAL;
1252 if (status < 0) {
1253 if (bh)
1254 brelse(bh);
1255 mlog_errno(status);
1256 goto out_unlock;
1257 }
1258
1259 local = 0;
1260 while(offset < i_size_read(orphan_dir_inode)
1261 && local < sb->s_blocksize) {
1262 de = (struct ocfs2_dir_entry *) (bh->b_data + local);
1263
1264 if (!ocfs2_check_dir_entry(orphan_dir_inode,
1265 de, bh, local)) {
1266 status = -EINVAL;
1267 mlog_errno(status);
1268 brelse(bh);
1269 goto out_unlock;
1270 }
1271
1272 local += le16_to_cpu(de->rec_len);
1273 offset += le16_to_cpu(de->rec_len);
1274
1275 /* I guess we silently fail on no inode? */
1276 if (!le64_to_cpu(de->inode))
1277 continue;
1278 if (de->file_type > OCFS2_FT_MAX) {
1279 mlog(ML_ERROR,
1280 "block %llu contains invalid de: "
1281 "inode = %llu, rec_len = %u, "
1282 "name_len = %u, file_type = %u, "
1283 "name='%.*s'\n",
1284 (unsigned long long)bh->b_blocknr,
1285 (unsigned long long)le64_to_cpu(de->inode),
1286 le16_to_cpu(de->rec_len),
1287 de->name_len,
1288 de->file_type,
1289 de->name_len,
1290 de->name);
1291 continue;
1292 }
1293 if (de->name_len == 1 && !strncmp(".", de->name, 1))
1294 continue;
1295 if (de->name_len == 2 && !strncmp("..", de->name, 2))
1296 continue;
1297
1298 iter = ocfs2_iget(osb, le64_to_cpu(de->inode),
1299 OCFS2_FI_FLAG_ORPHAN_RECOVERY);
1300 if (IS_ERR(iter))
1301 continue;
1302
1303 mlog(0, "queue orphan %llu\n",
1304 (unsigned long long)OCFS2_I(iter)->ip_blkno);
1305 /* No locking is required for the next_orphan
1306 * queue as there is only ever a single
1307 * process doing orphan recovery. */
1308 OCFS2_I(iter)->ip_next_orphan = *head;
1309 *head = iter;
1310 }
1311 brelse(bh);
1312 } 1281 }
1313 1282
1314out_unlock: 1283 *head = priv.head;
1284
1315 ocfs2_meta_unlock(orphan_dir_inode, 0); 1285 ocfs2_meta_unlock(orphan_dir_inode, 0);
1316out: 1286out:
1317 mutex_unlock(&orphan_dir_inode->i_mutex); 1287 mutex_unlock(&orphan_dir_inode->i_mutex);