[readdir] convert logfs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
070a0ebf42
commit
46d0733801
@ -281,17 +281,23 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
|
|
||||||
/* FIXME: readdir currently has it's own dir_walk code. I don't see a good
|
/* FIXME: readdir currently has it's own dir_walk code. I don't see a good
|
||||||
* way to combine the two copies */
|
* way to combine the two copies */
|
||||||
#define IMPLICIT_NODES 2
|
static int logfs_readdir(struct file *file, struct dir_context *ctx)
|
||||||
static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
|
|
||||||
{
|
{
|
||||||
struct inode *dir = file_inode(file);
|
struct inode *dir = file_inode(file);
|
||||||
loff_t pos = file->f_pos - IMPLICIT_NODES;
|
loff_t pos;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
struct logfs_disk_dentry *dd;
|
struct logfs_disk_dentry *dd;
|
||||||
int full;
|
|
||||||
|
|
||||||
|
if (ctx->pos < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!dir_emit_dots(file, ctx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pos = ctx->pos - 2;
|
||||||
BUG_ON(pos < 0);
|
BUG_ON(pos < 0);
|
||||||
for (;; pos++) {
|
for (;; pos++, ctx->pos++) {
|
||||||
|
bool full;
|
||||||
if (beyond_eof(dir, pos))
|
if (beyond_eof(dir, pos))
|
||||||
break;
|
break;
|
||||||
if (!logfs_exist_block(dir, pos)) {
|
if (!logfs_exist_block(dir, pos)) {
|
||||||
@ -306,42 +312,17 @@ static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
|
|||||||
dd = kmap(page);
|
dd = kmap(page);
|
||||||
BUG_ON(dd->namelen == 0);
|
BUG_ON(dd->namelen == 0);
|
||||||
|
|
||||||
full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
|
full = !dir_emit(ctx, (char *)dd->name,
|
||||||
pos, be64_to_cpu(dd->ino), dd->type);
|
be16_to_cpu(dd->namelen),
|
||||||
|
be64_to_cpu(dd->ino), dd->type);
|
||||||
kunmap(page);
|
kunmap(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
if (full)
|
if (full)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->f_pos = pos + IMPLICIT_NODES;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int logfs_readdir(struct file *file, void *buf, filldir_t filldir)
|
|
||||||
{
|
|
||||||
struct inode *inode = file_inode(file);
|
|
||||||
ino_t pino = parent_ino(file->f_dentry);
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (file->f_pos < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (file->f_pos == 0) {
|
|
||||||
if (filldir(buf, ".", 1, 1, inode->i_ino, DT_DIR) < 0)
|
|
||||||
return 0;
|
|
||||||
file->f_pos++;
|
|
||||||
}
|
|
||||||
if (file->f_pos == 1) {
|
|
||||||
if (filldir(buf, "..", 2, 2, pino, DT_DIR) < 0)
|
|
||||||
return 0;
|
|
||||||
file->f_pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = __logfs_readdir(file, buf, filldir);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name)
|
static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name)
|
||||||
{
|
{
|
||||||
dd->namelen = cpu_to_be16(name->len);
|
dd->namelen = cpu_to_be16(name->len);
|
||||||
@ -814,7 +795,7 @@ const struct inode_operations logfs_dir_iops = {
|
|||||||
const struct file_operations logfs_dir_fops = {
|
const struct file_operations logfs_dir_fops = {
|
||||||
.fsync = logfs_fsync,
|
.fsync = logfs_fsync,
|
||||||
.unlocked_ioctl = logfs_ioctl,
|
.unlocked_ioctl = logfs_ioctl,
|
||||||
.readdir = logfs_readdir,
|
.iterate = logfs_readdir,
|
||||||
.read = generic_read_dir,
|
.read = generic_read_dir,
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user