]> git.karo-electronics.de Git - linux-beck.git/commitdiff
xfs: reduce direct usage of mp->m_dir_geo
authorDave Chinner <dchinner@redhat.com>
Fri, 6 Jun 2014 05:20:32 +0000 (15:20 +1000)
committerDave Chinner <david@fromorbit.com>
Fri, 6 Jun 2014 05:20:32 +0000 (15:20 +1000)
There are many places in the directory code were we don't pass the
args into and so have to extract the geometry direct from the mount
structure. Push the args or the geometry into these leaf functions
so that we don't need to grab it from the struct xfs_mount.

This, in turn, brings use to the point where directory geometry is
no longer a property of the struct xfs_mount; it is not a global
property anymore, and hence we can start to consider per-directory
configuration of physical geometries.

Start by converting the xfs_dir_isblock/leaf code - pass in the
xfs_da_args and convert the readdir code to use xfs_da_args like
the rest of the directory code to pass information around.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_dir2.c
fs/xfs/xfs_dir2.h
fs/xfs/xfs_dir2_readdir.c

index 97f1802a9018a6ee219e2a9b60e180db37d5f4c0..07aa3907d237ea3dcea89de0870c94e23a95b88b 100644 (file)
@@ -282,7 +282,7 @@ xfs_dir_createname(
                goto out_free;
        }
 
-       rval = xfs_dir2_isblock(dp, &v);
+       rval = xfs_dir2_isblock(args, &v);
        if (rval)
                goto out_free;
        if (v) {
@@ -290,7 +290,7 @@ xfs_dir_createname(
                goto out_free;
        }
 
-       rval = xfs_dir2_isleaf(dp, &v);
+       rval = xfs_dir2_isleaf(args, &v);
        if (rval)
                goto out_free;
        if (v)
@@ -375,7 +375,7 @@ xfs_dir_lookup(
                goto out_check_rval;
        }
 
-       rval = xfs_dir2_isblock(dp, &v);
+       rval = xfs_dir2_isblock(args, &v);
        if (rval)
                goto out_free;
        if (v) {
@@ -383,7 +383,7 @@ xfs_dir_lookup(
                goto out_check_rval;
        }
 
-       rval = xfs_dir2_isleaf(dp, &v);
+       rval = xfs_dir2_isleaf(args, &v);
        if (rval)
                goto out_free;
        if (v)
@@ -448,7 +448,7 @@ xfs_dir_removename(
                goto out_free;
        }
 
-       rval = xfs_dir2_isblock(dp, &v);
+       rval = xfs_dir2_isblock(args, &v);
        if (rval)
                goto out_free;
        if (v) {
@@ -456,7 +456,7 @@ xfs_dir_removename(
                goto out_free;
        }
 
-       rval = xfs_dir2_isleaf(dp, &v);
+       rval = xfs_dir2_isleaf(args, &v);
        if (rval)
                goto out_free;
        if (v)
@@ -513,7 +513,7 @@ xfs_dir_replace(
                goto out_free;
        }
 
-       rval = xfs_dir2_isblock(dp, &v);
+       rval = xfs_dir2_isblock(args, &v);
        if (rval)
                goto out_free;
        if (v) {
@@ -521,7 +521,7 @@ xfs_dir_replace(
                goto out_free;
        }
 
-       rval = xfs_dir2_isleaf(dp, &v);
+       rval = xfs_dir2_isleaf(args, &v);
        if (rval)
                goto out_free;
        if (v)
@@ -573,7 +573,7 @@ xfs_dir_canenter(
                goto out_free;
        }
 
-       rval = xfs_dir2_isblock(dp, &v);
+       rval = xfs_dir2_isblock(args, &v);
        if (rval)
                goto out_free;
        if (v) {
@@ -581,7 +581,7 @@ xfs_dir_canenter(
                goto out_free;
        }
 
-       rval = xfs_dir2_isleaf(dp, &v);
+       rval = xfs_dir2_isleaf(args, &v);
        if (rval)
                goto out_free;
        if (v)
@@ -649,18 +649,16 @@ xfs_dir2_grow_inode(
  */
 int
 xfs_dir2_isblock(
-       xfs_inode_t     *dp,
-       int             *vp)            /* out: 1 is block, 0 is not block */
+       struct xfs_da_args      *args,
+       int                     *vp)    /* out: 1 is block, 0 is not block */
 {
-       xfs_fileoff_t   last;           /* last file offset */
-       xfs_mount_t     *mp;
-       int             rval;
+       xfs_fileoff_t           last;   /* last file offset */
+       int                     rval;
 
-       mp = dp->i_mount;
-       if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
+       if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
                return rval;
-       rval = XFS_FSB_TO_B(mp, last) == mp->m_dir_geo->blksize;
-       ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dir_geo->blksize);
+       rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
+       ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
        *vp = rval;
        return 0;
 }
@@ -670,17 +668,15 @@ xfs_dir2_isblock(
  */
 int
 xfs_dir2_isleaf(
-       xfs_inode_t     *dp,
-       int             *vp)            /* out: 1 is leaf, 0 is not leaf */
+       struct xfs_da_args      *args,
+       int                     *vp)    /* out: 1 is block, 0 is not block */
 {
-       xfs_fileoff_t   last;           /* last file offset */
-       xfs_mount_t     *mp;
-       int             rval;
+       xfs_fileoff_t           last;   /* last file offset */
+       int                     rval;
 
-       mp = dp->i_mount;
-       if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
+       if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
                return rval;
-       *vp = last == mp->m_dir_geo->leafblk + (1 << mp->m_sb.sb_dirblklog);
+       *vp = last == args->geo->leafblk + args->geo->fsbcount;
        return 0;
 }
 
index 9b709ae3ba1e4a2bca14b7497d9f4d68865efd48..1292e780e5b7b7e70aaa0cc354303bacca1d677a 100644 (file)
@@ -146,8 +146,8 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
 /*
  * Interface routines used by userspace utilities
  */
-extern int xfs_dir2_isblock(struct xfs_inode *dp, int *r);
-extern int xfs_dir2_isleaf(struct xfs_inode *dp, int *r);
+extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
+extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
 extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
                                struct xfs_buf *bp);
 
index fa393d5c2a148f25c5c94514db95e4da22e724e2..ca1f43cd39399d3cb498fc02d8ac376f4ba90842 100644 (file)
@@ -76,28 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
 
 STATIC int
 xfs_dir2_sf_getdents(
-       xfs_inode_t             *dp,            /* incore directory inode */
+       struct xfs_da_args      *args,
        struct dir_context      *ctx)
 {
        int                     i;              /* shortform entry number */
-       xfs_mount_t             *mp;            /* filesystem mount point */
+       struct xfs_inode        *dp = args->dp; /* incore directory inode */
        xfs_dir2_dataptr_t      off;            /* current entry's offset */
        xfs_dir2_sf_entry_t     *sfep;          /* shortform directory entry */
        xfs_dir2_sf_hdr_t       *sfp;           /* shortform structure */
        xfs_dir2_dataptr_t      dot_offset;
        xfs_dir2_dataptr_t      dotdot_offset;
        xfs_ino_t               ino;
-       struct xfs_da_geometry  *geo;
-
-       mp = dp->i_mount;
-       geo = mp->m_dir_geo;
+       struct xfs_da_geometry  *geo = args->geo;
 
        ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
        /*
         * Give up if the directory is way too short.
         */
        if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
-               ASSERT(XFS_FORCED_SHUTDOWN(mp));
+               ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
                return XFS_ERROR(EIO);
        }
 
@@ -163,13 +160,13 @@ xfs_dir2_sf_getdents(
                filetype = dp->d_ops->sf_get_ftype(sfep);
                ctx->pos = off & 0x7fffffff;
                if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
-                           xfs_dir3_get_dtype(mp, filetype)))
+                           xfs_dir3_get_dtype(dp->i_mount, filetype)))
                        return 0;
                sfep = dp->d_ops->sf_nextentry(sfp, sfep);
        }
 
        ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
-                       0x7fffffff;
+                                                               0x7fffffff;
        return 0;
 }
 
@@ -178,9 +175,10 @@ xfs_dir2_sf_getdents(
  */
 STATIC int
 xfs_dir2_block_getdents(
-       xfs_inode_t             *dp,            /* incore inode */
+       struct xfs_da_args      *args,
        struct dir_context      *ctx)
 {
+       struct xfs_inode        *dp = args->dp; /* incore directory inode */
        xfs_dir2_data_hdr_t     *hdr;           /* block header */
        struct xfs_buf          *bp;            /* buffer for block */
        xfs_dir2_block_tail_t   *btp;           /* block tail */
@@ -188,14 +186,11 @@ xfs_dir2_block_getdents(
        xfs_dir2_data_unused_t  *dup;           /* block unused entry */
        char                    *endptr;        /* end of the data entries */
        int                     error;          /* error return value */
-       xfs_mount_t             *mp;            /* filesystem mount point */
        char                    *ptr;           /* current data entry */
        int                     wantoff;        /* starting block offset */
        xfs_off_t               cook;
-       struct xfs_da_geometry  *geo;
+       struct xfs_da_geometry  *geo = args->geo;
 
-       mp = dp->i_mount;
-       geo = mp->m_dir_geo;
        /*
         * If the block number in the offset is out of range, we're done.
         */
@@ -258,7 +253,7 @@ xfs_dir2_block_getdents(
                 */
                if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
                            be64_to_cpu(dep->inumber),
-                           xfs_dir3_get_dtype(mp, filetype))) {
+                           xfs_dir3_get_dtype(dp->i_mount, filetype))) {
                        xfs_trans_brelse(NULL, bp);
                        return 0;
                }
@@ -269,7 +264,7 @@ xfs_dir2_block_getdents(
         * Set the offset to a non-existent block 1 and return.
         */
        ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
-                       0x7fffffff;
+                                                               0x7fffffff;
        xfs_trans_brelse(NULL, bp);
        return 0;
 }
@@ -290,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
 
 STATIC int
 xfs_dir2_leaf_readbuf(
-       struct xfs_inode        *dp,
+       struct xfs_da_args      *args,
        size_t                  bufsize,
        struct xfs_dir2_leaf_map_info *mip,
        xfs_dir2_off_t          *curoff,
        struct xfs_buf          **bpp)
 {
-       struct xfs_mount        *mp = dp->i_mount;
+       struct xfs_inode        *dp = args->dp;
        struct xfs_buf          *bp = *bpp;
        struct xfs_bmbt_irec    *map = mip->map;
        struct blk_plug         plug;
@@ -304,7 +299,7 @@ xfs_dir2_leaf_readbuf(
        int                     length;
        int                     i;
        int                     j;
-       struct xfs_da_geometry  *geo = mp->m_dir_geo;
+       struct xfs_da_geometry  *geo = args->geo;
 
        /*
         * If we have a buffer, we need to release it and
@@ -338,8 +333,7 @@ xfs_dir2_leaf_readbuf(
        /*
         * Recalculate the readahead blocks wanted.
         */
-       mip->ra_want = howmany(bufsize + geo->blksize,
-                              mp->m_sb.sb_blocksize) - 1;
+       mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;
        ASSERT(mip->ra_want >= 0);
 
        /*
@@ -411,8 +405,8 @@ xfs_dir2_leaf_readbuf(
        mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);
        error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
                        map->br_blockcount >= geo->fsbcount ?
-                           XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
-
+                           XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) :
+                           -1, &bp);
        /*
         * Should just skip over the data block instead of giving up.
         */
@@ -441,7 +435,7 @@ xfs_dir2_leaf_readbuf(
                    map[mip->ra_index].br_blockcount >= geo->fsbcount) {
                        xfs_dir3_data_readahead(dp,
                                map[mip->ra_index].br_startoff + mip->ra_offset,
-                               XFS_FSB_TO_DADDR(mp,
+                               XFS_FSB_TO_DADDR(dp->i_mount,
                                        map[mip->ra_index].br_startblock +
                                                        mip->ra_offset));
                        mip->ra_current = i;
@@ -493,23 +487,23 @@ out:
  */
 STATIC int
 xfs_dir2_leaf_getdents(
-       xfs_inode_t             *dp,            /* incore directory inode */
+       struct xfs_da_args      *args,
        struct dir_context      *ctx,
        size_t                  bufsize)
 {
+       struct xfs_inode        *dp = args->dp;
        struct xfs_buf          *bp = NULL;     /* data block buffer */
        xfs_dir2_data_hdr_t     *hdr;           /* data block header */
        xfs_dir2_data_entry_t   *dep;           /* data entry */
        xfs_dir2_data_unused_t  *dup;           /* unused entry */
        int                     error = 0;      /* error return value */
        int                     length;         /* temporary length value */
-       xfs_mount_t             *mp;            /* filesystem mount point */
        int                     byteoff;        /* offset in current block */
        xfs_dir2_off_t          curoff;         /* current overall offset */
        xfs_dir2_off_t          newoff;         /* new curoff after new blk */
        char                    *ptr = NULL;    /* pointer to current data */
        struct xfs_dir2_leaf_map_info *map_info;
-       struct xfs_da_geometry  *geo;
+       struct xfs_da_geometry  *geo = args->geo;
 
        /*
         * If the offset is at or past the largest allowed value,
@@ -518,15 +512,12 @@ xfs_dir2_leaf_getdents(
        if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
                return 0;
 
-       mp = dp->i_mount;
-       geo = mp->m_dir_geo;
-
        /*
         * Set up to bmap a number of blocks based on the caller's
         * buffer size, the directory block size, and the filesystem
         * block size.
         */
-       length = howmany(bufsize + geo->blksize, mp->m_sb.sb_blocksize);
+       length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
        map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
                                (length * sizeof(struct xfs_bmbt_irec)),
                               KM_SLEEP | KM_NOFS);
@@ -558,7 +549,7 @@ xfs_dir2_leaf_getdents(
                 */
                if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
 
-                       error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info,
+                       error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,
                                                      &curoff, &bp);
                        if (error || !map_info->map_valid)
                                break;
@@ -566,7 +557,7 @@ xfs_dir2_leaf_getdents(
                        /*
                         * Having done a read, we need to set a new offset.
                         */
-                       newoff = xfs_dir2_db_off_to_byte(mp->m_dir_geo,
+                       newoff = xfs_dir2_db_off_to_byte(geo,
                                                         map_info->curdb, 0);
                        /*
                         * Start of the current block.
@@ -585,7 +576,7 @@ xfs_dir2_leaf_getdents(
                         * Find our position in the block.
                         */
                        ptr = (char *)dp->d_ops->data_entry_p(hdr);
-                       byteoff = xfs_dir2_byte_to_off(mp->m_dir_geo, curoff);
+                       byteoff = xfs_dir2_byte_to_off(geo, curoff);
                        /*
                         * Skip past the header.
                         */
@@ -644,7 +635,7 @@ xfs_dir2_leaf_getdents(
                ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
                if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
                            be64_to_cpu(dep->inumber),
-                           xfs_dir3_get_dtype(mp, filetype)))
+                           xfs_dir3_get_dtype(dp->i_mount, filetype)))
                        break;
 
                /*
@@ -674,13 +665,14 @@ xfs_dir2_leaf_getdents(
  */
 int
 xfs_readdir(
-       xfs_inode_t     *dp,
-       struct dir_context *ctx,
-       size_t          bufsize)
+       struct xfs_inode        *dp,
+       struct dir_context      *ctx,
+       size_t                  bufsize)
 {
-       int             rval;           /* return value */
-       int             v;              /* type-checking value */
-       uint            lock_mode;
+       struct xfs_da_args      args = {0};
+       int                     rval;
+       int                     v;
+       uint                    lock_mode;
 
        trace_xfs_readdir(dp);
 
@@ -690,15 +682,18 @@ xfs_readdir(
        ASSERT(S_ISDIR(dp->i_d.di_mode));
        XFS_STATS_INC(xs_dir_getdents);
 
+       args.dp = dp;
+       args.geo = dp->i_mount->m_dir_geo;
+
        lock_mode = xfs_ilock_data_map_shared(dp);
        if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_getdents(dp, ctx);
-       else if ((rval = xfs_dir2_isblock(dp, &v)))
+               rval = xfs_dir2_sf_getdents(&args, ctx);
+       else if ((rval = xfs_dir2_isblock(&args, &v)))
                ;
        else if (v)
-               rval = xfs_dir2_block_getdents(dp, ctx);
+               rval = xfs_dir2_block_getdents(&args, ctx);
        else
-               rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
+               rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
        xfs_iunlock(dp, lock_mode);
 
        return rval;