Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
/**
* do_filldir_main - read out directory entries
* @dip: The GFS2 inode
/**
* do_filldir_main - read out directory entries
* @dip: The GFS2 inode
- * @offset: The offset in the file to read from
- * @opaque: opaque data to pass to filldir
- * @filldir: The function to pass entries to
+ * @ctx: what to feed the entries to
* @darr: an array of struct gfs2_dirent pointers to read
* @entries: the number of entries in darr
* @copied: pointer to int that's non-zero if a entry has been copied out
* @darr: an array of struct gfs2_dirent pointers to read
* @entries: the number of entries in darr
* @copied: pointer to int that's non-zero if a entry has been copied out
* the possibility that they will fall into different readdir buffers or
* that someone will want to seek to that location.
*
* the possibility that they will fall into different readdir buffers or
* that someone will want to seek to that location.
*
- * Returns: errno, >0 on exception from filldir
+ * Returns: errno, >0 if the actor tells you to stop
-static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
- void *opaque, filldir_t filldir,
+static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx,
const struct gfs2_dirent **darr, u32 entries,
int *copied)
{
const struct gfs2_dirent **darr, u32 entries,
int *copied)
{
u64 off, off_next;
unsigned int x, y;
int run = 0;
u64 off, off_next;
unsigned int x, y;
int run = 0;
sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL);
sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL);
off_next = be32_to_cpu(dent_next->de_hash);
off_next = gfs2_disk_hash2offset(off_next);
off_next = be32_to_cpu(dent_next->de_hash);
off_next = gfs2_disk_hash2offset(off_next);
if (off_next == off) {
if (*copied && !run)
if (off_next == off) {
if (*copied && !run)
- error = filldir(opaque, (const char *)(dent + 1),
+ if (!dir_emit(ctx, (const char *)(dent + 1),
be16_to_cpu(dent->de_name_len),
be16_to_cpu(dent->de_name_len),
- off, be64_to_cpu(dent->de_inum.no_addr),
- be16_to_cpu(dent->de_type));
- if (error)
+ be64_to_cpu(dent->de_inum.no_addr),
+ be16_to_cpu(dent->de_type)))
- /* Increment the *offset by one, so the next time we come into the
+ /* Increment the ctx->pos by one, so the next time we come into the
do_filldir fxn, we get the next entry instead of the last one in the
current leaf */
do_filldir fxn, we get the next entry instead of the last one in the
current leaf */
-static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
- filldir_t filldir, int *copied, unsigned *depth,
+static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx,
+ int *copied, unsigned *depth,
u64 leaf_no)
{
struct gfs2_inode *ip = GFS2_I(inode);
u64 leaf_no)
{
struct gfs2_inode *ip = GFS2_I(inode);
} while(lfn);
BUG_ON(entries2 != entries);
} while(lfn);
BUG_ON(entries2 != entries);
- error = do_filldir_main(ip, offset, opaque, filldir, darr,
- entries, copied);
+ error = do_filldir_main(ip, ctx, darr, entries, copied);
out_free:
for(i = 0; i < leaf; i++)
brelse(larr[i]);
out_free:
for(i = 0; i < leaf; i++)
brelse(larr[i]);
/**
* dir_e_read - Reads the entries from a directory into a filldir buffer
* @dip: dinode pointer
/**
* dir_e_read - Reads the entries from a directory into a filldir buffer
* @dip: dinode pointer
- * @offset: the hash of the last entry read shifted to the right once
- * @opaque: buffer for the filldir function to fill
- * @filldir: points to the filldir function to use
+ * @ctx: actor to feed the entries to
-static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
- filldir_t filldir, struct file_ra_state *f_ra)
+static int dir_e_read(struct inode *inode, struct dir_context *ctx,
+ struct file_ra_state *f_ra)
{
struct gfs2_inode *dip = GFS2_I(inode);
u32 hsize, len = 0;
{
struct gfs2_inode *dip = GFS2_I(inode);
u32 hsize, len = 0;
unsigned depth = 0;
hsize = 1 << dip->i_depth;
unsigned depth = 0;
hsize = 1 << dip->i_depth;
- hash = gfs2_dir_offset2hash(*offset);
+ hash = gfs2_dir_offset2hash(ctx->pos);
index = hash >> (32 - dip->i_depth);
if (dip->i_hash_cache == NULL)
index = hash >> (32 - dip->i_depth);
if (dip->i_hash_cache == NULL)
gfs2_dir_readahead(inode, hsize, index, f_ra);
while (index < hsize) {
gfs2_dir_readahead(inode, hsize, index, f_ra);
while (index < hsize) {
- error = gfs2_dir_read_leaf(inode, offset, opaque, filldir,
+ error = gfs2_dir_read_leaf(inode, ctx,
&copied, &depth,
be64_to_cpu(lp[index]));
if (error)
&copied, &depth,
be64_to_cpu(lp[index]));
if (error)
-int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
- filldir_t filldir, struct file_ra_state *f_ra)
+int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
+ struct file_ra_state *f_ra)
{
struct gfs2_inode *dip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
{
struct gfs2_inode *dip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
return 0;
if (dip->i_diskflags & GFS2_DIF_EXHASH)
return 0;
if (dip->i_diskflags & GFS2_DIF_EXHASH)
- return dir_e_read(inode, offset, opaque, filldir, f_ra);
+ return dir_e_read(inode, ctx, f_ra);
if (!gfs2_is_stuffed(dip)) {
gfs2_consist_inode(dip);
if (!gfs2_is_stuffed(dip)) {
gfs2_consist_inode(dip);
error = -EIO;
goto out;
}
error = -EIO;
goto out;
}
- error = do_filldir_main(dip, offset, opaque, filldir, darr,
+ error = do_filldir_main(dip, ctx, darr,
dip->i_entries, &copied);
out:
kfree(darr);
dip->i_entries, &copied);
out:
kfree(darr);
extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
const struct gfs2_inode *ip);
extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
const struct gfs2_inode *ip);
extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
-extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
- filldir_t filldir, struct file_ra_state *f_ra);
+extern int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
+ struct file_ra_state *f_ra);
extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
const struct gfs2_inode *nip, unsigned int new_type);
extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
const struct gfs2_inode *nip, unsigned int new_type);
}
struct get_name_filldir {
}
struct get_name_filldir {
+ struct dir_context ctx;
struct gfs2_inum_host inum;
char *name;
};
struct gfs2_inum_host inum;
char *name;
};
struct gfs2_inode *dip, *ip;
struct get_name_filldir gnfd;
struct gfs2_holder gh;
struct gfs2_inode *dip, *ip;
struct get_name_filldir gnfd;
struct gfs2_holder gh;
int error;
struct file_ra_state f_ra = { .start = 0 };
int error;
struct file_ra_state f_ra = { .start = 0 };
gnfd.inum.no_addr = ip->i_no_addr;
gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
gnfd.name = name;
gnfd.inum.no_addr = ip->i_no_addr;
gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
gnfd.name = name;
+ gnfd.ctx.actor = get_name_filldir;
+ gnfd.ctx.pos = 0;
error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
if (error)
return error;
error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
if (error)
return error;
- error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir, &f_ra);
+ error = gfs2_dir_read(dir, &gnfd.ctx, &f_ra);
gfs2_glock_dq_uninit(&gh);
gfs2_glock_dq_uninit(&gh);
- * gfs2_readdir - Read directory entries from a directory
+ * gfs2_readdir - Iterator for a directory
* @file: The directory to read from
* @file: The directory to read from
- * @dirent: Buffer for dirents
- * @filldir: Function used to do the copying
+ * @ctx: What to feed directory entries to
-static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
+static int gfs2_readdir(struct file *file, struct dir_context *ctx)
{
struct inode *dir = file->f_mapping->host;
struct gfs2_inode *dip = GFS2_I(dir);
struct gfs2_holder d_gh;
{
struct inode *dir = file->f_mapping->host;
struct gfs2_inode *dip = GFS2_I(dir);
struct gfs2_holder d_gh;
- u64 offset = file->f_pos;
- gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
- error = gfs2_glock_nq(&d_gh);
- if (error) {
- gfs2_holder_uninit(&d_gh);
+ error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
+ if (error)
- error = gfs2_dir_read(dir, &offset, dirent, filldir, &file->f_ra);
+ error = gfs2_dir_read(dir, ctx, &file->f_ra);
gfs2_glock_dq_uninit(&d_gh);
gfs2_glock_dq_uninit(&d_gh);
- file->f_pos = offset;
-
};
const struct file_operations gfs2_dir_fops = {
};
const struct file_operations gfs2_dir_fops = {
- .readdir = gfs2_readdir,
+ .iterate = gfs2_readdir,
.unlocked_ioctl = gfs2_ioctl,
.open = gfs2_open,
.release = gfs2_release,
.unlocked_ioctl = gfs2_ioctl,
.open = gfs2_open,
.release = gfs2_release,
};
const struct file_operations gfs2_dir_fops_nolock = {
};
const struct file_operations gfs2_dir_fops_nolock = {
- .readdir = gfs2_readdir,
+ .iterate = gfs2_readdir,
.unlocked_ioctl = gfs2_ioctl,
.open = gfs2_open,
.release = gfs2_release,
.unlocked_ioctl = gfs2_ioctl,
.open = gfs2_open,
.release = gfs2_release,