[readdir] convert xfs
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 22 May 2013 21:07:56 +0000 (17:07 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 29 Jun 2013 08:57:00 +0000 (12:57 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/xfs/xfs_dir2.c
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_priv.h
fs/xfs/xfs_dir2_sf.c
fs/xfs/xfs_file.c
fs/xfs/xfs_vnodeops.h

index b26a50f..8f023de 100644 (file)
@@ -368,10 +368,8 @@ xfs_dir_removename(
 int
 xfs_readdir(
        xfs_inode_t     *dp,
-       void            *dirent,
-       size_t          bufsize,
-       xfs_off_t       *offset,
-       filldir_t       filldir)
+       struct dir_context *ctx,
+       size_t          bufsize)
 {
        int             rval;           /* return value */
        int             v;              /* type-checking value */
@@ -385,14 +383,13 @@ xfs_readdir(
        XFS_STATS_INC(xs_dir_getdents);
 
        if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);
+               rval = xfs_dir2_sf_getdents(dp, ctx);
        else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
                ;
        else if (v)
-               rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);
+               rval = xfs_dir2_block_getdents(dp, ctx);
        else
-               rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,
-                                             filldir);
+               rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
        return rval;
 }
 
index e59f5fc..09aea02 100644 (file)
@@ -569,9 +569,7 @@ xfs_dir2_block_addname(
 int                                            /* error */
 xfs_dir2_block_getdents(
        xfs_inode_t             *dp,            /* incore inode */
-       void                    *dirent,
-       xfs_off_t               *offset,
-       filldir_t               filldir)
+       struct dir_context      *ctx)
 {
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
        struct xfs_buf          *bp;            /* buffer for block */
@@ -589,7 +587,7 @@ xfs_dir2_block_getdents(
        /*
         * If the block number in the offset is out of range, we're done.
         */
-       if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
+       if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
                return 0;
 
        error = xfs_dir3_block_read(NULL, dp, &bp);
@@ -600,7 +598,7 @@ xfs_dir2_block_getdents(
         * Extract the byte offset we start at from the seek pointer.
         * We'll skip entries before this.
         */
-       wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
+       wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
        hdr = bp->b_addr;
        xfs_dir3_data_check(dp, bp);
        /*
@@ -639,13 +637,12 @@ xfs_dir2_block_getdents(
                cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
                                            (char *)dep - (char *)hdr);
 
+               ctx->pos = cook & 0x7fffffff;
                /*
                 * If it didn't fit, set the final offset to here & return.
                 */
-               if (filldir(dirent, (char *)dep->name, dep->namelen,
-                           cook & 0x7fffffff, be64_to_cpu(dep->inumber),
-                           DT_UNKNOWN)) {
-                       *offset = cook & 0x7fffffff;
+               if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
+                           be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
                        xfs_trans_brelse(NULL, bp);
                        return 0;
                }
@@ -655,7 +652,7 @@ xfs_dir2_block_getdents(
         * Reached the end of the block.
         * Set the offset to a non-existent block 1 and return.
         */
-       *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
+       ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
                        0x7fffffff;
        xfs_trans_brelse(NULL, bp);
        return 0;
index da71a18..e0cc124 100644 (file)
@@ -1300,10 +1300,8 @@ out:
 int                                            /* error */
 xfs_dir2_leaf_getdents(
        xfs_inode_t             *dp,            /* incore directory inode */
-       void                    *dirent,
-       size_t                  bufsize,
-       xfs_off_t               *offset,
-       filldir_t               filldir)
+       struct dir_context      *ctx,
+       size_t                  bufsize)
 {
        struct xfs_buf          *bp = NULL;     /* data block buffer */
        xfs_dir2_data_hdr_t     *hdr;           /* data block header */
@@ -1322,7 +1320,7 @@ xfs_dir2_leaf_getdents(
         * If the offset is at or past the largest allowed value,
         * give up right away.
         */
-       if (*offset >= XFS_DIR2_MAX_DATAPTR)
+       if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
                return 0;
 
        mp = dp->i_mount;
@@ -1343,7 +1341,7 @@ xfs_dir2_leaf_getdents(
         * Inside the loop we keep the main offset value as a byte offset
         * in the directory file.
         */
-       curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
+       curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos);
 
        /*
         * Force this conversion through db so we truncate the offset
@@ -1444,8 +1442,8 @@ xfs_dir2_leaf_getdents(
                dep = (xfs_dir2_data_entry_t *)ptr;
                length = xfs_dir2_data_entsize(dep->namelen);
 
-               if (filldir(dirent, (char *)dep->name, dep->namelen,
-                           xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
+               ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
+               if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
                            be64_to_cpu(dep->inumber), DT_UNKNOWN))
                        break;
 
@@ -1462,9 +1460,9 @@ xfs_dir2_leaf_getdents(
         * All done.  Set output offset value to current offset.
         */
        if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
-               *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
+               ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
        else
-               *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
+               ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
        kmem_free(map_info);
        if (bp)
                xfs_trans_brelse(NULL, bp);
index 7cf573c..0511cda 100644 (file)
@@ -33,8 +33,8 @@ extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
 extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
 
 extern int xfs_dir2_block_addname(struct xfs_da_args *args);
-extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
-               xfs_off_t *offset, filldir_t filldir);
+extern int xfs_dir2_block_getdents(struct xfs_inode *dp,
+               struct dir_context *ctx);
 extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
 extern int xfs_dir2_block_removename(struct xfs_da_args *args);
 extern int xfs_dir2_block_replace(struct xfs_da_args *args);
@@ -91,8 +91,8 @@ extern void xfs_dir3_leaf_compact(struct xfs_da_args *args,
 extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
                struct xfs_dir2_leaf_entry *ents, int *indexp,
                int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
-extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
-               size_t bufsize, xfs_off_t *offset, filldir_t filldir);
+extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, struct dir_context *ctx,
+               size_t bufsize);
 extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
                struct xfs_buf **bpp, __uint16_t magic);
 extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp,
@@ -153,8 +153,7 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
                int size, xfs_dir2_sf_hdr_t *sfhp);
 extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
 extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
-extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
-               xfs_off_t *offset, filldir_t filldir);
+extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct dir_context *ctx);
 extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
 extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
 extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
index 6157424..97676a3 100644 (file)
@@ -768,9 +768,7 @@ xfs_dir2_sf_create(
 int                                            /* error */
 xfs_dir2_sf_getdents(
        xfs_inode_t             *dp,            /* incore directory inode */
-       void                    *dirent,
-       xfs_off_t               *offset,
-       filldir_t               filldir)
+       struct dir_context      *ctx)
 {
        int                     i;              /* shortform entry number */
        xfs_mount_t             *mp;            /* filesystem mount point */
@@ -802,7 +800,7 @@ xfs_dir2_sf_getdents(
        /*
         * If the block number in the offset is out of range, we're done.
         */
-       if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
+       if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
                return 0;
 
        /*
@@ -819,22 +817,20 @@ xfs_dir2_sf_getdents(
        /*
         * Put . entry unless we're starting past it.
         */
-       if (*offset <= dot_offset) {
-               if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, dp->i_ino, DT_DIR)) {
-                       *offset = dot_offset & 0x7fffffff;
+       if (ctx->pos <= dot_offset) {
+               ctx->pos = dot_offset & 0x7fffffff;
+               if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR))
                        return 0;
-               }
        }
 
        /*
         * Put .. entry unless we're starting past it.
         */
-       if (*offset <= dotdot_offset) {
+       if (ctx->pos <= dotdot_offset) {
                ino = xfs_dir2_sf_get_parent_ino(sfp);
-               if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
-                       *offset = dotdot_offset & 0x7fffffff;
+               ctx->pos = dotdot_offset & 0x7fffffff;
+               if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
                        return 0;
-               }
        }
 
        /*
@@ -845,21 +841,20 @@ xfs_dir2_sf_getdents(
                off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
                                xfs_dir2_sf_get_offset(sfep));
 
-               if (*offset > off) {
+               if (ctx->pos > off) {
                        sfep = xfs_dir2_sf_nextentry(sfp, sfep);
                        continue;
                }
 
                ino = xfs_dir2_sfe_get_ino(sfp, sfep);
-               if (filldir(dirent, (char *)sfep->name, sfep->namelen,
-                           off & 0x7fffffff, ino, DT_UNKNOWN)) {
-                       *offset = off & 0x7fffffff;
+               ctx->pos = off & 0x7fffffff;
+               if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen,
+                           ino, DT_UNKNOWN))
                        return 0;
-               }
                sfep = xfs_dir2_sf_nextentry(sfp, sfep);
        }
 
-       *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
+       ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
                        0x7fffffff;
        return 0;
 }
index a5f2042..0ad2b95 100644 (file)
@@ -906,11 +906,10 @@ xfs_file_release(
 
 STATIC int
 xfs_file_readdir(
-       struct file     *filp,
-       void            *dirent,
-       filldir_t       filldir)
+       struct file     *file,
+       struct dir_context *ctx)
 {
-       struct inode    *inode = file_inode(filp);
+       struct inode    *inode = file_inode(file);
        xfs_inode_t     *ip = XFS_I(inode);
        int             error;
        size_t          bufsize;
@@ -929,8 +928,7 @@ xfs_file_readdir(
         */
        bufsize = (size_t)min_t(loff_t, 32768, ip->i_d.di_size);
 
-       error = xfs_readdir(ip, dirent, bufsize,
-                               (xfs_off_t *)&filp->f_pos, filldir);
+       error = xfs_readdir(ip, ctx, bufsize);
        if (error)
                return -error;
        return 0;
@@ -1432,7 +1430,7 @@ const struct file_operations xfs_file_operations = {
 const struct file_operations xfs_dir_file_operations = {
        .open           = xfs_dir_open,
        .read           = generic_read_dir,
-       .readdir        = xfs_file_readdir,
+       .iterate        = xfs_file_readdir,
        .llseek         = generic_file_llseek,
        .unlocked_ioctl = xfs_file_ioctl,
 #ifdef CONFIG_COMPAT
index 5163022..38c67c3 100644 (file)
@@ -31,8 +31,7 @@ int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
                struct xfs_inode *ip);
 int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
                struct xfs_name *target_name);
-int xfs_readdir(struct xfs_inode       *dp, void *dirent, size_t bufsize,
-                      xfs_off_t *offset, filldir_t filldir);
+int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, size_t bufsize);
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
                const char *target_path, umode_t mode, struct xfs_inode **ipp);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);