|
@@ -1212,9 +1212,7 @@ static int compare_dents(const void *a, const void *b)
|
|
|
/**
|
|
|
* 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
|
|
@@ -1224,11 +1222,10 @@ static int compare_dents(const void *a, const void *b)
|
|
|
* 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)
|
|
|
{
|
|
@@ -1236,7 +1233,6 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
|
|
|
u64 off, off_next;
|
|
|
unsigned int x, y;
|
|
|
int run = 0;
|
|
|
- int error = 0;
|
|
|
|
|
|
sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL);
|
|
|
|
|
@@ -1253,9 +1249,9 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
|
|
|
off_next = be32_to_cpu(dent_next->de_hash);
|
|
|
off_next = gfs2_disk_hash2offset(off_next);
|
|
|
|
|
|
- if (off < *offset)
|
|
|
+ if (off < ctx->pos)
|
|
|
continue;
|
|
|
- *offset = off;
|
|
|
+ ctx->pos = off;
|
|
|
|
|
|
if (off_next == off) {
|
|
|
if (*copied && !run)
|
|
@@ -1264,26 +1260,25 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
|
|
|
} else
|
|
|
run = 0;
|
|
|
} else {
|
|
|
- if (off < *offset)
|
|
|
+ if (off < ctx->pos)
|
|
|
continue;
|
|
|
- *offset = off;
|
|
|
+ ctx->pos = off;
|
|
|
}
|
|
|
|
|
|
- error = filldir(opaque, (const char *)(dent + 1),
|
|
|
+ if (!dir_emit(ctx, (const char *)(dent + 1),
|
|
|
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)))
|
|
|
return 1;
|
|
|
|
|
|
*copied = 1;
|
|
|
}
|
|
|
|
|
|
- /* 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 */
|
|
|
|
|
|
- (*offset)++;
|
|
|
+ ctx->pos++;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1307,8 +1302,8 @@ static void gfs2_free_sort_buffer(void *ptr)
|
|
|
kfree(ptr);
|
|
|
}
|
|
|
|
|
|
-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);
|
|
@@ -1386,8 +1381,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
|
|
|
} 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]);
|
|
@@ -1446,15 +1440,13 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index,
|
|
|
/**
|
|
|
* 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
|
|
|
*
|
|
|
* Returns: errno
|
|
|
*/
|
|
|
|
|
|
-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;
|
|
@@ -1465,7 +1457,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
|
|
|
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)
|
|
@@ -1477,7 +1469,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
|
|
|
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)
|
|
@@ -1492,8 +1484,8 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
|
|
|
return 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);
|
|
@@ -1507,7 +1499,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
|
|
|
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);
|
|
@@ -1539,7 +1531,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
|
|
|
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);
|