[readdir] convert hfsplus
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -121,9 +121,9 @@ fail:
|
|||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = file_inode(file);
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
int len, err;
|
int len, err;
|
||||||
char strbuf[HFSPLUS_MAX_STRLEN + 1];
|
char strbuf[HFSPLUS_MAX_STRLEN + 1];
|
||||||
@@ -132,7 +132,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
struct hfsplus_readdir_data *rd;
|
struct hfsplus_readdir_data *rd;
|
||||||
u16 type;
|
u16 type;
|
||||||
|
|
||||||
if (filp->f_pos >= inode->i_size)
|
if (file->f_pos >= inode->i_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
|
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
|
||||||
@@ -143,14 +143,13 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
switch ((u32)filp->f_pos) {
|
if (ctx->pos == 0) {
|
||||||
case 0:
|
|
||||||
/* This is completely artificial... */
|
/* This is completely artificial... */
|
||||||
if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
|
if (!dir_emit_dot(file, ctx))
|
||||||
goto out;
|
goto out;
|
||||||
filp->f_pos++;
|
ctx->pos = 1;
|
||||||
/* fall through */
|
}
|
||||||
case 1:
|
if (ctx->pos == 1) {
|
||||||
if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
|
if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -168,19 +167,16 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (filldir(dirent, "..", 2, 1,
|
if (!dir_emit(ctx, "..", 2,
|
||||||
be32_to_cpu(entry.thread.parentID), DT_DIR))
|
be32_to_cpu(entry.thread.parentID), DT_DIR))
|
||||||
goto out;
|
goto out;
|
||||||
filp->f_pos++;
|
ctx->pos = 2;
|
||||||
/* fall through */
|
|
||||||
default:
|
|
||||||
if (filp->f_pos >= inode->i_size)
|
|
||||||
goto out;
|
|
||||||
err = hfs_brec_goto(&fd, filp->f_pos - 1);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
if (ctx->pos >= inode->i_size)
|
||||||
|
goto out;
|
||||||
|
err = hfs_brec_goto(&fd, ctx->pos - 1);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) {
|
if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) {
|
||||||
pr_err("walked past end of dir\n");
|
pr_err("walked past end of dir\n");
|
||||||
@@ -211,7 +207,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
HFSPLUS_SB(sb)->hidden_dir->i_ino ==
|
HFSPLUS_SB(sb)->hidden_dir->i_ino ==
|
||||||
be32_to_cpu(entry.folder.id))
|
be32_to_cpu(entry.folder.id))
|
||||||
goto next;
|
goto next;
|
||||||
if (filldir(dirent, strbuf, len, filp->f_pos,
|
if (!dir_emit(ctx, strbuf, len,
|
||||||
be32_to_cpu(entry.folder.id), DT_DIR))
|
be32_to_cpu(entry.folder.id), DT_DIR))
|
||||||
break;
|
break;
|
||||||
} else if (type == HFSPLUS_FILE) {
|
} else if (type == HFSPLUS_FILE) {
|
||||||
@@ -220,7 +216,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (filldir(dirent, strbuf, len, filp->f_pos,
|
if (!dir_emit(ctx, strbuf, len,
|
||||||
be32_to_cpu(entry.file.id), DT_REG))
|
be32_to_cpu(entry.file.id), DT_REG))
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -229,22 +225,22 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
next:
|
next:
|
||||||
filp->f_pos++;
|
ctx->pos++;
|
||||||
if (filp->f_pos >= inode->i_size)
|
if (ctx->pos >= inode->i_size)
|
||||||
goto out;
|
goto out;
|
||||||
err = hfs_brec_goto(&fd, 1);
|
err = hfs_brec_goto(&fd, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
rd = filp->private_data;
|
rd = file->private_data;
|
||||||
if (!rd) {
|
if (!rd) {
|
||||||
rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL);
|
rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL);
|
||||||
if (!rd) {
|
if (!rd) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
filp->private_data = rd;
|
file->private_data = rd;
|
||||||
rd->file = filp;
|
rd->file = file;
|
||||||
list_add(&rd->list, &HFSPLUS_I(inode)->open_dir_list);
|
list_add(&rd->list, &HFSPLUS_I(inode)->open_dir_list);
|
||||||
}
|
}
|
||||||
memcpy(&rd->key, fd.key, sizeof(struct hfsplus_cat_key));
|
memcpy(&rd->key, fd.key, sizeof(struct hfsplus_cat_key));
|
||||||
@@ -538,7 +534,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
|
|||||||
const struct file_operations hfsplus_dir_operations = {
|
const struct file_operations hfsplus_dir_operations = {
|
||||||
.fsync = hfsplus_file_fsync,
|
.fsync = hfsplus_file_fsync,
|
||||||
.read = generic_read_dir,
|
.read = generic_read_dir,
|
||||||
.readdir = hfsplus_readdir,
|
.iterate = hfsplus_readdir,
|
||||||
.unlocked_ioctl = hfsplus_ioctl,
|
.unlocked_ioctl = hfsplus_ioctl,
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.release = hfsplus_dir_release,
|
.release = hfsplus_dir_release,
|
||||||
|
Reference in New Issue
Block a user