diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 22:04:00 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-12 22:04:00 (GMT) |
commit | a6e3d7dba92e19acffaa36aad962741a762aa8c5 (patch) | |
tree | 4170e6cfe524b3714f35aba07890073ae8ae75c5 /fs/ocfs2/journal.c | |
parent | 42f04b6d4c8c69ccffc10863418c5b5f100a8554 (diff) | |
parent | e7b34019606ab1dd06196635e931b0c302799228 (diff) | |
download | linux-fsl-qoriq-a6e3d7dba92e19acffaa36aad962741a762aa8c5.tar.xz |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: (23 commits)
ocfs2: Optionally return filldir errors
ocfs2: Write support for directories with inline data
ocfs2: Read support for directories with inline data
ocfs2: Write support for inline data
ocfs2: Read support for inline data
ocfs2: Structure updates for inline data
ocfs2: Cleanup dirent size check
ocfs2: Rename cleanups
ocfs2: Provide convenience function for ino lookup
ocfs2: Implement ocfs2_empty_dir() as a caller of ocfs2_dir_foreach()
ocfs2: Remove open coded readdir()
ocfs2: Pass raw u64 to filldir
ocfs2: Abstract out core dir listing functionality
ocfs2: Move directory manipulation code into dir.c
ocfs2: Small refactor of truncate zeroing code
ocfs2: move nonsparse hole-filling into ocfs2_write_begin()
ocfs2: Sync ocfs2_fs.h with ocfs2-tools
[PATCH] fs/ocfs2/: removed unneeded initial value and function's return value
ocfs2: Implement show_options()
ocfs2: Clear slot map when umounting a local volume
...
Diffstat (limited to 'fs/ocfs2/journal.c')
-rw-r--r-- | fs/ocfs2/journal.c | 120 |
1 files changed, 45 insertions, 75 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index dbfb20b..f9d01e2 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -35,13 +35,13 @@ #include "ocfs2.h" #include "alloc.h" +#include "dir.h" #include "dlmglue.h" #include "extent_map.h" #include "heartbeat.h" #include "inode.h" #include "journal.h" #include "localalloc.h" -#include "namei.h" #include "slot_map.h" #include "super.h" #include "vote.h" @@ -1213,17 +1213,49 @@ bail: return status; } +struct ocfs2_orphan_filldir_priv { + struct inode *head; + struct ocfs2_super *osb; +}; + +static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len, + loff_t pos, u64 ino, unsigned type) +{ + struct ocfs2_orphan_filldir_priv *p = priv; + struct inode *iter; + + if (name_len == 1 && !strncmp(".", name, 1)) + return 0; + if (name_len == 2 && !strncmp("..", name, 2)) + return 0; + + /* Skip bad inodes so that recovery can continue */ + iter = ocfs2_iget(p->osb, ino, + OCFS2_FI_FLAG_ORPHAN_RECOVERY); + if (IS_ERR(iter)) + return 0; + + mlog(0, "queue orphan %llu\n", + (unsigned long long)OCFS2_I(iter)->ip_blkno); + /* No locking is required for the next_orphan queue as there + * is only ever a single process doing orphan recovery. */ + OCFS2_I(iter)->ip_next_orphan = p->head; + p->head = iter; + + return 0; +} + static int ocfs2_queue_orphans(struct ocfs2_super *osb, int slot, struct inode **head) { int status; struct inode *orphan_dir_inode = NULL; - struct inode *iter; - unsigned long offset, blk, local; - struct buffer_head *bh = NULL; - struct ocfs2_dir_entry *de; - struct super_block *sb = osb->sb; + struct ocfs2_orphan_filldir_priv priv; + loff_t pos = 0; + + priv.osb = osb; + priv.head = *head; orphan_dir_inode = ocfs2_get_system_file_inode(osb, ORPHAN_DIR_SYSTEM_INODE, @@ -1241,77 +1273,15 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, goto out; } - offset = 0; - iter = NULL; - while(offset < i_size_read(orphan_dir_inode)) { - blk = offset >> sb->s_blocksize_bits; - - bh = ocfs2_bread(orphan_dir_inode, blk, &status, 0); - if (!bh) - status = -EINVAL; - if (status < 0) { - if (bh) - brelse(bh); - mlog_errno(status); - goto out_unlock; - } - - local = 0; - while(offset < i_size_read(orphan_dir_inode) - && local < sb->s_blocksize) { - de = (struct ocfs2_dir_entry *) (bh->b_data + local); - - if (!ocfs2_check_dir_entry(orphan_dir_inode, - de, bh, local)) { - status = -EINVAL; - mlog_errno(status); - brelse(bh); - goto out_unlock; - } - - local += le16_to_cpu(de->rec_len); - offset += le16_to_cpu(de->rec_len); - - /* I guess we silently fail on no inode? */ - if (!le64_to_cpu(de->inode)) - continue; - if (de->file_type > OCFS2_FT_MAX) { - mlog(ML_ERROR, - "block %llu contains invalid de: " - "inode = %llu, rec_len = %u, " - "name_len = %u, file_type = %u, " - "name='%.*s'\n", - (unsigned long long)bh->b_blocknr, - (unsigned long long)le64_to_cpu(de->inode), - le16_to_cpu(de->rec_len), - de->name_len, - de->file_type, - de->name_len, - de->name); - continue; - } - if (de->name_len == 1 && !strncmp(".", de->name, 1)) - continue; - if (de->name_len == 2 && !strncmp("..", de->name, 2)) - continue; - - iter = ocfs2_iget(osb, le64_to_cpu(de->inode), - OCFS2_FI_FLAG_ORPHAN_RECOVERY); - if (IS_ERR(iter)) - continue; - - mlog(0, "queue orphan %llu\n", - (unsigned long long)OCFS2_I(iter)->ip_blkno); - /* No locking is required for the next_orphan - * queue as there is only ever a single - * process doing orphan recovery. */ - OCFS2_I(iter)->ip_next_orphan = *head; - *head = iter; - } - brelse(bh); + status = ocfs2_dir_foreach(orphan_dir_inode, &pos, &priv, + ocfs2_orphan_filldir); + if (status) { + mlog_errno(status); + goto out; } -out_unlock: + *head = priv.head; + ocfs2_meta_unlock(orphan_dir_inode, 0); out: mutex_unlock(&orphan_dir_inode->i_mutex); |