]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/xfs/xfs_itable.c
Merge branch 'linux-2.6'
[mv-sheeva.git] / fs / xfs / xfs_itable.c
index b608b8ab1dd6f9fe82240cc3bfde747cd42ea327..4c2454bcc714f6db40d0402b886dc4e44e69bf4e 100644 (file)
 #include "xfs_error.h"
 #include "xfs_btree.h"
 
+int
+xfs_internal_inum(
+       xfs_mount_t     *mp,
+       xfs_ino_t       ino)
+{
+       return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
+               (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+                (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
+}
+
 STATIC int
 xfs_bulkstat_one_iget(
        xfs_mount_t     *mp,            /* mount point for filesystem */
@@ -192,6 +202,16 @@ xfs_bulkstat_one_dinode(
        return 0;
 }
 
+STATIC int
+xfs_bulkstat_one_fmt(
+       void                    __user *ubuffer,
+       const xfs_bstat_t       *buffer)
+{
+       if (copy_to_user(ubuffer, buffer, sizeof(*buffer)))
+               return -EFAULT;
+       return sizeof(*buffer);
+}
+
 /*
  * Return stat information for one inode.
  * Return 0 if ok, else errno.
@@ -211,19 +231,15 @@ xfs_bulkstat_one(
        xfs_bstat_t     *buf;           /* return buffer */
        int             error = 0;      /* error value */
        xfs_dinode_t    *dip;           /* dinode inode pointer */
+       bulkstat_one_fmt_pf formatter = private_data ? : xfs_bulkstat_one_fmt;
 
        dip = (xfs_dinode_t *)dibuff;
+       *stat = BULKSTAT_RV_NOTHING;
 
-       if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
-           (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
-            (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) {
-               *stat = BULKSTAT_RV_NOTHING;
+       if (!buffer || xfs_internal_inum(mp, ino))
                return XFS_ERROR(EINVAL);
-       }
-       if (ubsize < sizeof(*buf)) {
-               *stat = BULKSTAT_RV_NOTHING;
+       if (ubsize < sizeof(*buf))
                return XFS_ERROR(ENOMEM);
-       }
 
        buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
 
@@ -238,15 +254,15 @@ xfs_bulkstat_one(
                xfs_bulkstat_one_dinode(mp, ino, dip, buf);
        }
 
-       if (copy_to_user(buffer, buf, sizeof(*buf)))  {
-               *stat = BULKSTAT_RV_NOTHING;
-               error =  EFAULT;
+       error = formatter(buffer, buf);
+       if (error < 0)  {
+               error = EFAULT;
                goto out_free;
        }
 
        *stat = BULKSTAT_RV_DIDONE;
        if (ubused)
-               *ubused = sizeof(*buf);
+               *ubused = error;
 
  out_free:
        kmem_free(buf, sizeof(*buf));
@@ -577,6 +593,7 @@ xfs_bulkstat(
                                                                      KM_SLEEP);
                                                ip->i_ino = ino;
                                                ip->i_mount = mp;
+                                               spin_lock_init(&ip->i_flags_lock);
                                                if (bp)
                                                        xfs_buf_relse(bp);
                                                error = xfs_itobp(mp, NULL, ip,
@@ -642,6 +659,8 @@ xfs_bulkstat(
                                         }
                                        else if (error == ENOMEM)
                                                ubleft = 0;
+                                       else
+                                               lastino = ino;
                                        continue;
                                }
                                if (fmterror == BULKSTAT_RV_GIVEUP) {
@@ -741,6 +760,19 @@ xfs_bulkstat_single(
        return 0;
 }
 
+int
+xfs_inumbers_fmt(
+       void                    __user *ubuffer, /* buffer to write to */
+       const xfs_inogrp_t      *buffer,        /* buffer to read from */
+       long                    count,          /* # of elements to read */
+       long                    *written)       /* # of bytes written */
+{
+       if (copy_to_user(ubuffer, buffer, count * sizeof(*buffer)))
+               return -EFAULT;
+       *written = count * sizeof(*buffer);
+       return 0;
+}
+
 /*
  * Return inode number table for the filesystem.
  */
@@ -749,7 +781,8 @@ xfs_inumbers(
        xfs_mount_t     *mp,            /* mount point for filesystem */
        xfs_ino_t       *lastino,       /* last inode returned */
        int             *count,         /* size of buffer/count returned */
-       xfs_inogrp_t    __user *ubuffer)/* buffer with inode descriptions */
+       void            __user *ubuffer,/* buffer with inode descriptions */
+       inumbers_fmt_pf formatter)
 {
        xfs_buf_t       *agbp;
        xfs_agino_t     agino;
@@ -802,7 +835,7 @@ xfs_inumbers(
                                xfs_buf_relse(agbp);
                                agbp = NULL;
                                /*
-                                * Move up the the last inode in the current
+                                * Move up the last inode in the current
                                 * chunk.  The lookup_ge will always get
                                 * us the first inode in the next chunk.
                                 */
@@ -828,12 +861,12 @@ xfs_inumbers(
                bufidx++;
                left--;
                if (bufidx == bcount) {
-                       if (copy_to_user(ubuffer, buffer,
-                                       bufidx * sizeof(*buffer))) {
+                       long written;
+                       if (formatter(ubuffer, buffer, bufidx, &written)) {
                                error = XFS_ERROR(EFAULT);
                                break;
                        }
-                       ubuffer += bufidx;
+                       ubuffer += written;
                        *count += bufidx;
                        bufidx = 0;
                }
@@ -855,8 +888,8 @@ xfs_inumbers(
        }
        if (!error) {
                if (bufidx) {
-                       if (copy_to_user(ubuffer, buffer,
-                                       bufidx * sizeof(*buffer)))
+                       long written;
+                       if (formatter(ubuffer, buffer, bufidx, &written))
                                error = XFS_ERROR(EFAULT);
                        else
                                *count += bufidx;