|
@@ -52,8 +52,10 @@ affs_readdir(struct file *file, struct dir_context *ctx)
|
|
|
int hash_pos;
|
|
|
int chain_pos;
|
|
|
u32 ino;
|
|
|
+ int error = 0;
|
|
|
|
|
|
- pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)ctx->pos);
|
|
|
+ pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",
|
|
|
+ inode->i_ino, (unsigned long)ctx->pos);
|
|
|
|
|
|
if (ctx->pos < 2) {
|
|
|
file->private_data = (void *)0;
|
|
@@ -72,7 +74,7 @@ affs_readdir(struct file *file, struct dir_context *ctx)
|
|
|
}
|
|
|
dir_bh = affs_bread(sb, inode->i_ino);
|
|
|
if (!dir_bh)
|
|
|
- goto readdir_out;
|
|
|
+ goto out_unlock_dir;
|
|
|
|
|
|
/* If the directory hasn't changed since the last call to readdir(),
|
|
|
* we can jump directly to where we left off.
|
|
@@ -88,7 +90,8 @@ affs_readdir(struct file *file, struct dir_context *ctx)
|
|
|
fh_bh = affs_bread(sb, ino);
|
|
|
if (!fh_bh) {
|
|
|
affs_error(sb, "readdir","Cannot read block %d", i);
|
|
|
- return -EIO;
|
|
|
+ error = -EIO;
|
|
|
+ goto out_brelse_dir;
|
|
|
}
|
|
|
ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain);
|
|
|
affs_brelse(fh_bh);
|
|
@@ -107,29 +110,34 @@ inside:
|
|
|
do {
|
|
|
fh_bh = affs_bread(sb, ino);
|
|
|
if (!fh_bh) {
|
|
|
- affs_error(sb, "readdir","Cannot read block %d", ino);
|
|
|
+ affs_error(sb, "readdir",
|
|
|
+ "Cannot read block %d", ino);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30);
|
|
|
name = AFFS_TAIL(sb, fh_bh)->name + 1;
|
|
|
- pr_debug("AFFS: readdir(): filldir(\"%.*s\", ino=%u), hash=%d, f_pos=%x\n",
|
|
|
+ pr_debug("AFFS: readdir(): dir_emit(\"%.*s\", "
|
|
|
+ "ino=%u), hash=%d, f_pos=%x\n",
|
|
|
namelen, name, ino, hash_pos, (u32)ctx->pos);
|
|
|
+
|
|
|
if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN))
|
|
|
- goto readdir_done;
|
|
|
+ goto done;
|
|
|
ctx->pos++;
|
|
|
ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain);
|
|
|
affs_brelse(fh_bh);
|
|
|
fh_bh = NULL;
|
|
|
} while (ino);
|
|
|
}
|
|
|
-readdir_done:
|
|
|
+done:
|
|
|
file->f_version = inode->i_version;
|
|
|
file->private_data = (void *)(long)ino;
|
|
|
+ affs_brelse(fh_bh);
|
|
|
|
|
|
-readdir_out:
|
|
|
+out_brelse_dir:
|
|
|
affs_brelse(dir_bh);
|
|
|
- affs_brelse(fh_bh);
|
|
|
+
|
|
|
+out_unlock_dir:
|
|
|
affs_unlock_dir(inode);
|
|
|
- return 0;
|
|
|
+ return error;
|
|
|
}
|