#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 */
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.
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);
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));
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,
}
else if (error == ENOMEM)
ubleft = 0;
+ else
+ lastino = ino;
continue;
}
if (fmterror == BULKSTAT_RV_GIVEUP) {
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.
*/
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;
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.
*/
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;
}
}
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;