mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 23:39:18 +00:00
ocfs2: Remove open coded readdir()
ocfs2_queue_orphans() has an open coded readdir loop which can easily just use a directory accessor function. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Reviewed-by: Joel Becker <joel.becker@oracle.com>
This commit is contained in:
parent
7e8536797d
commit
5eae5b96fc
@ -81,10 +81,10 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
|
||||
struct ocfs2_alloc_context *meta_ac,
|
||||
struct buffer_head **new_bh);
|
||||
|
||||
int ocfs2_check_dir_entry(struct inode * dir,
|
||||
struct ocfs2_dir_entry * de,
|
||||
struct buffer_head * bh,
|
||||
unsigned long offset)
|
||||
static int ocfs2_check_dir_entry(struct inode * dir,
|
||||
struct ocfs2_dir_entry * de,
|
||||
struct buffer_head * bh,
|
||||
unsigned long offset)
|
||||
{
|
||||
const char *error_msg = NULL;
|
||||
const int rlen = le16_to_cpu(de->rec_len);
|
||||
@ -531,6 +531,26 @@ out:
|
||||
return stored;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is intended to be called from inside other kernel functions,
|
||||
* so we fake some arguments.
|
||||
*/
|
||||
int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
|
||||
filldir_t filldir)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long version = inode->i_version;
|
||||
|
||||
while (*f_pos < i_size_read(inode)) {
|
||||
ret = ocfs2_dir_foreach_blk(inode, &version, f_pos, priv,
|
||||
filldir);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ocfs2_readdir()
|
||||
*
|
||||
|
@ -62,6 +62,8 @@ int ocfs2_find_files_on_disk(const char *name,
|
||||
struct buffer_head **dirent_bh,
|
||||
struct ocfs2_dir_entry **dirent);
|
||||
int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
|
||||
int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
|
||||
filldir_t filldir);
|
||||
int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
|
||||
struct inode *dir,
|
||||
struct buffer_head *parent_fe_bh,
|
||||
@ -76,9 +78,4 @@ int ocfs2_fill_new_dir(struct ocfs2_super *osb,
|
||||
struct buffer_head *fe_bh,
|
||||
struct ocfs2_alloc_context *data_ac);
|
||||
|
||||
int ocfs2_check_dir_entry(struct inode *dir,
|
||||
struct ocfs2_dir_entry *de,
|
||||
struct buffer_head *bh,
|
||||
unsigned long offset);
|
||||
|
||||
#endif /* OCFS2_DIR_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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user