linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / xfs / xfs_itable.c
index 7d44fdb..d2a21c4 100644 (file)
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
+#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_error.h"
 #include "xfs_btree.h"
 
+#ifndef HAVE_USERACC
+#define useracc(ubuffer, size, flags, foo) (0)
+#define unuseracc(ubuffer, size, flags)
+#endif
+
 STATIC int
 xfs_bulkstat_one_iget(
        xfs_mount_t     *mp,            /* mount point for filesystem */
@@ -49,7 +56,7 @@ xfs_bulkstat_one_iget(
 {
        xfs_dinode_core_t *dic;         /* dinode core info pointer */
        xfs_inode_t     *ip;            /* incore inode pointer */
-       bhv_vnode_t     *vp;
+       vnode_t         *vp;
        int             error;
 
        error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@@ -267,7 +274,7 @@ xfs_bulkstat(
        size_t                  statstruct_size, /* sizeof struct filling */
        char                    __user *ubuffer, /* buffer with inode stats */
        int                     flags,  /* defined in xfs_itable.h */
-       int                     *done)  /* 1 if there are more stats to get */
+       int                     *done)  /* 1 if there're more stats to get */
 {
        xfs_agblock_t           agbno=0;/* allocation group block number */
        xfs_buf_t               *agbp;  /* agi header buffer */
@@ -330,6 +337,15 @@ xfs_bulkstat(
                (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
        nimask = ~(nicluster - 1);
        nbcluster = nicluster >> mp->m_sb.sb_inopblog;
+       /*
+        * Lock down the user's buffer. If a buffer was not sent, as in the case
+        * disk quota code calls here, we skip this.
+        */
+       if (ubuffer &&
+           (error = useracc(ubuffer, ubcount * statstruct_size,
+                       (B_READ|B_PHYS), NULL))) {
+               return error;
+       }
        /*
         * Allocate a page-sized buffer for inode btree records.
         * We could try allocating something smaller, but for normal
@@ -548,8 +564,7 @@ xfs_bulkstat(
                                                if (bp)
                                                        xfs_buf_relse(bp);
                                                error = xfs_itobp(mp, NULL, ip,
-                                                               &dip, &bp, bno,
-                                                               XFS_IMAP_BULKSTAT);
+                                                                 &dip, &bp, bno);
                                                if (!error)
                                                        clustidx = ip->i_boffset / mp->m_sb.sb_inodesize;
                                                kmem_zone_free(xfs_inode_zone, ip);
@@ -557,8 +572,6 @@ xfs_bulkstat(
                                                                   mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK,
                                                                   XFS_RANDOM_BULKSTAT_READ_CHUNK)) {
                                                        bp = NULL;
-                                                       ubleft = 0;
-                                                       rval = error;
                                                        break;
                                                }
                                        }
@@ -636,6 +649,8 @@ xfs_bulkstat(
         * Done, we're either out of filesystem or space to put the data.
         */
        kmem_free(irbuf, NBPC);
+       if (ubuffer)
+               unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
        *ubcountp = ubelem;
        if (agno >= mp->m_sb.sb_agcount) {
                /*
@@ -660,7 +675,7 @@ xfs_bulkstat_single(
        xfs_mount_t             *mp,    /* mount point for filesystem */
        xfs_ino_t               *lastinop, /* inode to return */
        char                    __user *buffer, /* buffer with inode stats */
-       int                     *done)  /* 1 if there are more stats to get */
+       int                     *done)  /* 1 if there're more stats to get */
 {
        int                     count;  /* count value for bulkstat call */
        int                     error;  /* return value */