From: Jeff Mahoney <jeffm@suse.com>
Subject: xfs: always use iget in bulkstat (dmapi)
Patch-mainline: When DMAPI gets there

 This patch implements the DMAPI portion of
 patches.fixes/xfs-always-use-iget-in-bulkstat

 That patch removed the private_data argument for the formatter function
 pointer in xfs_bulkstat. It has no in-kernel users and has been removed but
 the dmapi code does use it.

 Also, since inline lookup support was removed, I've dropped the code
 to implement it in DMAPI.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 fs/xfs/dmapi/xfs_dm.c          |  246 +----------------------------------------
 fs/xfs/linux-2.6/xfs_ioctl.c   |    4 
 fs/xfs/linux-2.6/xfs_ioctl32.c |    8 -
 fs/xfs/quota/xfs_qm.c          |    3 
 fs/xfs/quota/xfs_qm_syscalls.c |    3 
 fs/xfs/xfs_itable.c            |    9 +
 fs/xfs/xfs_itable.h            |    3 
 7 files changed, 27 insertions(+), 249 deletions(-)

--- a/fs/xfs/dmapi/xfs_dm.c
+++ b/fs/xfs/dmapi/xfs_dm.c
@@ -298,101 +298,6 @@ xfs_ip2dmflags(
 			(XFS_IFORK_Q(ip) ? DM_XFLAG_HASATTR : 0);
 }
 
-STATIC uint
-xfs_dic2dmflags(
-	xfs_dinode_t	*dip)
-{
-	return _xfs_dic2dmflags(be16_to_cpu(dip->di_flags)) |
-			(XFS_DFORK_Q(dip) ? DM_XFLAG_HASATTR : 0);
-}
-
-/*
- * This copies selected fields in an inode into a dm_stat structure.  Because
- * these fields must return the same values as they would in stat(), the
- * majority of this code was copied directly from xfs_getattr().  Any future
- * changes to xfs_gettattr() must also be reflected here.
- */
-STATIC void
-xfs_dip_to_stat(
-	xfs_mount_t		*mp,
-	xfs_ino_t		ino,
-	xfs_dinode_t		*dip,
-	dm_stat_t		*buf)
-{
-	xfs_dinode_t	*dic = dip;
-
-	/*
-	 * The inode format changed when we moved the link count and
-	 * made it 32 bits long.  If this is an old format inode,
-	 * convert it in memory to look like a new one.  If it gets
-	 * flushed to disk we will convert back before flushing or
-	 * logging it.  We zero out the new projid field and the old link
-	 * count field.  We'll handle clearing the pad field (the remains
-	 * of the old uuid field) when we actually convert the inode to
-	 * the new format. We don't change the version number so that we
-	 * can distinguish this from a real new format inode.
-	 */
-	if (dic->di_version == 1) {
-		buf->dt_nlink = be16_to_cpu(dic->di_onlink);
-		/*buf->dt_xfs_projid = 0;*/
-	} else {
-		buf->dt_nlink = be32_to_cpu(dic->di_nlink);
-		/*buf->dt_xfs_projid = be16_to_cpu(dic->di_projid);*/
-	}
-	buf->dt_ino = ino;
-	buf->dt_dev = new_encode_dev(mp->m_ddev_targp->bt_dev);
-	buf->dt_mode = be16_to_cpu(dic->di_mode);
-	buf->dt_uid = be32_to_cpu(dic->di_uid);
-	buf->dt_gid = be32_to_cpu(dic->di_gid);
-	buf->dt_size = be64_to_cpu(dic->di_size);
-	buf->dt_atime = be32_to_cpu(dic->di_atime.t_sec);
-	buf->dt_mtime = be32_to_cpu(dic->di_mtime.t_sec);
-	buf->dt_ctime = be32_to_cpu(dic->di_ctime.t_sec);
-	buf->dt_xfs_xflags = xfs_dic2dmflags(dip);
-	buf->dt_xfs_extsize =
-		be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
-	buf->dt_xfs_extents = be32_to_cpu(dic->di_nextents);
-	buf->dt_xfs_aextents = be16_to_cpu(dic->di_anextents);
-	buf->dt_xfs_igen = be32_to_cpu(dic->di_gen);
-	buf->dt_xfs_dmstate = be16_to_cpu(dic->di_dmstate);
-
-	switch (dic->di_format) {
-	case XFS_DINODE_FMT_DEV:
-		buf->dt_rdev = xfs_dinode_get_rdev(dic);
-		buf->dt_blksize = BLKDEV_IOSIZE;
-		buf->dt_blocks = 0;
-		break;
-	case XFS_DINODE_FMT_LOCAL:
-	case XFS_DINODE_FMT_UUID:
-		buf->dt_rdev = 0;
-		buf->dt_blksize = mp->m_sb.sb_blocksize;
-		buf->dt_blocks = 0;
-		break;
-	case XFS_DINODE_FMT_EXTENTS:
-	case XFS_DINODE_FMT_BTREE:
-		buf->dt_rdev = 0;
-		buf->dt_blksize = mp->m_sb.sb_blocksize;
-		buf->dt_blocks =
-			XFS_FSB_TO_BB(mp, be64_to_cpu(dic->di_nblocks));
-		break;
-	}
-
-	memset(&buf->dt_pad1, 0, sizeof(buf->dt_pad1));
-	memset(&buf->dt_pad2, 0, sizeof(buf->dt_pad2));
-	memset(&buf->dt_pad3, 0, sizeof(buf->dt_pad3));
-
-	/* Finally fill in the DMAPI specific fields */
-	buf->dt_pers = 0;
-	buf->dt_change = 0;
-	buf->dt_nevents = DM_EVENT_MAX;
-	buf->dt_emask = be32_to_cpu(dic->di_dmevmask);
-	buf->dt_dtime = be32_to_cpu(dic->di_ctime.t_sec);
-	/* Set if one of READ, WRITE or TRUNCATE bits is set in emask */
-	buf->dt_pmanreg = (DMEV_ISSET(DM_EVENT_READ, buf->dt_emask) ||
-			DMEV_ISSET(DM_EVENT_WRITE, buf->dt_emask) ||
-			DMEV_ISSET(DM_EVENT_TRUNCATE, buf->dt_emask)) ? 1 : 0;
-}
-
 /*
  * Pull out both ondisk and incore fields, incore has preference.
  * The inode must be kept locked SHARED by the caller.
@@ -533,109 +438,6 @@ xfs_dm_bulkall_iget_one(
 	return 0;
 }
 
-
-STATIC int
-xfs_dm_inline_attr(
-	xfs_mount_t	*mp,
-	xfs_dinode_t	*dip,
-	char		*attr_name,
-	caddr_t		attr_buf,
-	int		*value_lenp)
-{
-	if (dip->di_aformat == XFS_DINODE_FMT_LOCAL) {
-		xfs_attr_shortform_t	*sf;
-		xfs_attr_sf_entry_t	*sfe;
-		unsigned int		namelen = strlen(attr_name);
-		unsigned int		valuelen = *value_lenp;
-		int			i;
-
-		sf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
-		sfe = &sf->list[0];
-		for (i = 0; i < sf->hdr.count;
-				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
-			if (sfe->namelen != namelen)
-				continue;
-			if (!(sfe->flags & XFS_ATTR_ROOT))
-				continue;
-			if (memcmp(attr_name, sfe->nameval, namelen) != 0)
-				continue;
-			if (valuelen < sfe->valuelen)
-				return ERANGE;
-			valuelen = sfe->valuelen;
-			memcpy(attr_buf, &sfe->nameval[namelen], valuelen);
-			*value_lenp = valuelen;
-			return 0;
-		}
-	}
-	*value_lenp = 0;
-	return ENOATTR;
-}
-
-STATIC void
-dm_dip_to_handle(
-	xfs_ino_t	ino,
-	xfs_dinode_t	*dip,
-	dm_fsid_t	*fsid,
-	dm_handle_t	*handlep)
-{
-	dm_fid_t	fid;
-	int		hsize;
-
-	fid.dm_fid_len = sizeof(struct dm_fid) - sizeof(fid.dm_fid_len);
-	fid.dm_fid_pad = 0;
-	fid.dm_fid_ino = ino;
-	fid.dm_fid_gen = be32_to_cpu(dip->di_gen);
-
-	memcpy(&handlep->ha_fsid, fsid, sizeof(*fsid));
-	memcpy(&handlep->ha_fid, &fid, fid.dm_fid_len + sizeof(fid.dm_fid_len));
-	hsize = DM_HSIZE(*handlep);
-	memset((char *)handlep + hsize, 0, sizeof(*handlep) - hsize);
-}
-
-STATIC int
-xfs_dm_bulkall_inline_one(
-	xfs_mount_t	*mp,
-	xfs_ino_t	ino,
-	xfs_dinode_t	*dip,
-	dm_fsid_t	*fsid,
-	int		*value_lenp,
-	dm_xstat_t	*xbuf,
-	u_int		*xstat_szp,
-	char		*attr_name,
-	caddr_t		attr_buf)
-{
-	dm_handle_t	handle;
-	u_int		xstat_sz = *xstat_szp;
-	int		value_len = *value_lenp;
-	int		error;
-
-	if (dip->di_mode == 0)
-		return ENOENT;
-
-	xfs_dip_to_stat(mp, ino, dip, &xbuf->dx_statinfo);
-	dm_dip_to_handle(ino, dip, fsid, &handle);
-	xfs_dm_handle_to_xstat(xbuf, xstat_sz, &handle, sizeof(handle));
-
-	memset(&xbuf->dx_attrdata, 0, sizeof(dm_vardata_t));
-	error = xfs_dm_inline_attr(mp, dip, attr_name, attr_buf, &value_len);
-	DM_EA_XLATE_ERR(error);
-	if (error && (error != ENOATTR)) {
-		if (error == E2BIG)
-			error = ENOMEM;
-		return error;
-	}
-
-	/* How much space was in the attr? */
-	if (error != ENOATTR) {
-		xbuf->dx_attrdata.vd_offset = xstat_sz;
-		xbuf->dx_attrdata.vd_length = value_len;
-		xstat_sz += (value_len+(DM_STAT_ALIGN-1)) & ~(DM_STAT_ALIGN-1);
-	}
-	*xstat_szp = xbuf->dx_statinfo._link = xstat_sz;
-	*value_lenp = value_len;
-	return 0;
-}
-
 /*
  * This is used by dm_get_bulkall().
  * Given a inumber, it igets the inode and fills the given buffer
@@ -650,7 +452,6 @@ xfs_dm_bulkall_one(
 	void		*private_data,	/* my private data */
 	xfs_daddr_t	bno,		/* starting block of inode cluster */
 	int		*ubused,	/* amount of buffer we used */
-	void		*dibuff,	/* on-disk inode buffer */
 	int		*res)		/* bulkstat result code */
 {
 	dm_xstat_t	*xbuf;
@@ -687,18 +488,10 @@ xfs_dm_bulkall_one(
 	attr_buf_sz = value_len;
 	attr_buf = kmem_alloc(attr_buf_sz, KM_SLEEP);
 
-	if (!dibuff)
-		error = xfs_dm_bulkall_iget_one(mp, ino, bno,
-						&value_len, xbuf, &xstat_sz,
-						dmb->attrname.dan_chars,
-						attr_buf);
-	else
-		error = xfs_dm_bulkall_inline_one(mp, ino,
-						  (xfs_dinode_t *)dibuff,
-						  &dmb->fsid,
-						  &value_len, xbuf, &xstat_sz,
-						  dmb->attrname.dan_chars,
-						  attr_buf);
+	error = xfs_dm_bulkall_iget_one(mp, ino, bno,
+					&value_len, xbuf, &xstat_sz,
+					dmb->attrname.dan_chars,
+					attr_buf);
 	if (error)
 		goto out_free_buffers;
 
@@ -770,25 +563,6 @@ xfs_dm_bulkattr_iget_one(
 	return 0;
 }
 
-STATIC int
-xfs_dm_bulkattr_inline_one(
-	xfs_mount_t	*mp,
-	xfs_ino_t	ino,
-	xfs_dinode_t	*dip,
-	dm_fsid_t	*fsid,
-	dm_stat_t	*sbuf,
-	u_int		stat_sz)
-{
-	dm_handle_t	handle;
-
-	if (dip->di_mode == 0)
-		return ENOENT;
-	xfs_dip_to_stat(mp, ino, dip, sbuf);
-	dm_dip_to_handle(ino, dip, fsid, &handle);
-	xfs_dm_handle_to_stat(sbuf, stat_sz, &handle, sizeof(handle));
-	return 0;
-}
-
 /*
  * This is used by dm_get_bulkattr().
  * Given a inumber, it igets the inode and fills the given buffer
@@ -803,7 +577,6 @@ xfs_dm_bulkattr_one(
 	void		*private_data,	/* my private data */
 	xfs_daddr_t	bno,		/* starting block of inode cluster */
 	int		*ubused,	/* amount of buffer we used */
-	void		*dibuff,	/* on-disk inode buffer */
 	int		*res)		/* bulkstat result code */
 {
 	dm_stat_t	*sbuf;
@@ -825,12 +598,7 @@ xfs_dm_bulkattr_one(
 
 	sbuf = kmem_alloc(stat_sz, KM_SLEEP);
 
-	if (!dibuff)
-		error = xfs_dm_bulkattr_iget_one(mp, ino, bno, sbuf, stat_sz);
-	else
-		error = xfs_dm_bulkattr_inline_one(mp, ino,
-						   (xfs_dinode_t *)dibuff,
-						   &dmb->fsid, sbuf, stat_sz);
+	error = xfs_dm_bulkattr_iget_one(mp, ino, bno, sbuf, stat_sz);
 	if (error)
 		goto out_free_buffer;
 
@@ -1425,7 +1193,7 @@ xfs_dm_get_bulkall_rvp(
 	memcpy(&dmb.fsid, mp->m_fixedfsid, sizeof(dm_fsid_t));
 	error = xfs_bulkstat(mp, (xfs_ino_t *)&loc, &nelems,
 			     xfs_dm_bulkall_one, (void*)&dmb, statstruct_sz,
-			     bufp, BULKSTAT_FG_INLINE, &done);
+			     bufp, &done);
 	if (error)
 		return(-error); /* Return negative error to DMAPI */
 
@@ -1521,7 +1289,7 @@ xfs_dm_get_bulkattr_rvp(
 	memcpy(&dmb.fsid, mp->m_fixedfsid, sizeof(dm_fsid_t));
 	error = xfs_bulkstat(mp, (xfs_ino_t *)&loc, &nelems,
 				xfs_dm_bulkattr_one, (void*)&dmb,
-				statstruct_sz, bufp, BULKSTAT_FG_INLINE, &done);
+				statstruct_sz, bufp, &done);
 	if (error)
 		return(-error); /* Return negative error to DMAPI */
 
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -674,8 +674,8 @@ xfs_ioc_bulkstat(
 						bulkreq.ubuffer, &done);
 	else	/* XFS_IOC_FSBULKSTAT */
 		error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
-				     sizeof(xfs_bstat_t), bulkreq.ubuffer,
-				     &done);
+				     NULL, sizeof(xfs_bstat_t),
+				     bulkreq.ubuffer, &done);
 
 	if (error)
 		return -error;
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -235,6 +235,7 @@ xfs_bulkstat_one_compat(
 	xfs_ino_t	ino,		/* inode number to get data for */
 	void		__user *buffer,	/* buffer to place output in */
 	int		ubsize,		/* size of buffer */
+	void		*private_data,	/* my private data */
 	int		*ubused,	/* bytes used by me */
 	int		*stat)		/* BULKSTAT_RV_... */
 {
@@ -293,11 +294,12 @@ xfs_compat_ioc_bulkstat(
 		int res;
 
 		error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer,
-				sizeof(compat_xfs_bstat_t), 0, &res);
+					        sizeof(compat_xfs_bstat_t),
+						NULL, 0, &res);
 	} else if (cmd == XFS_IOC_FSBULKSTAT_32) {
 		error = xfs_bulkstat(mp, &inlast, &count,
-			xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t),
-			bulkreq.ubuffer, &done);
+			xfs_bulkstat_one_compat, NULL,
+			sizeof(compat_xfs_bstat_t), bulkreq.ubuffer, &done);
 	} else
 		error = XFS_ERROR(EINVAL);
 	if (error)
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1606,6 +1606,7 @@ xfs_qm_dqusage_adjust(
 	xfs_ino_t	ino,		/* inode number to get data for */
 	void		__user *buffer,	/* not used */
 	int		ubsize,		/* not used */
+	void		*private_data,	/* not used */
 	int		*ubused,	/* not used */
 	int		*res)		/* result code value */
 {
@@ -1765,7 +1766,7 @@ xfs_qm_quotacheck(
 		 */
 		error = xfs_bulkstat(mp, &lastino, &count,
 				     xfs_qm_dqusage_adjust,
-				     structsz, NULL, &done);
+				     NULL, structsz, NULL, &done);
 		if (error)
 			break;
 
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -1114,6 +1114,7 @@ xfs_qm_internalqcheck_adjust(
 	xfs_ino_t	ino,		/* inode number to get data for */
 	void		__user *buffer,	/* not used */
 	int		ubsize,		/* not used */
+	void		*private_data,	/* not used */
 	int		*ubused,	/* not used */
 	int		*res)		/* bulkstat result code */
 {
@@ -1211,7 +1212,7 @@ xfs_qm_internalqcheck(
 		 */
 		error = xfs_bulkstat(mp, &lastino, &count,
 				 xfs_qm_internalqcheck_adjust,
-				 0, NULL, &done);
+				 NULL, 0, NULL, &done);
 		if (error) {
 			xfs_debug(mp, "Bulkstat returned error 0x%x", error);
 			break;
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -177,6 +177,7 @@ xfs_bulkstat_one(
 	xfs_ino_t	ino,		/* inode number to get data for */
 	void		__user *buffer,	/* buffer to place output in */
 	int		ubsize,		/* size of buffer */
+	void		*private_data,	/* my private data */
 	int		*ubused,	/* bytes used by me */
 	int		*stat)		/* BULKSTAT_RV_... */
 {
@@ -195,6 +196,7 @@ xfs_bulkstat(
 	xfs_ino_t		*lastinop, /* last inode returned */
 	int			*ubcountp, /* size of buffer/count returned */
 	bulkstat_one_pf		formatter, /* func that'd fill a single buf */
+	void			*private_data,/* private data for formatter */
 	size_t			statstruct_size, /* sizeof struct filling */
 	char			__user *ubuffer, /* buffer with inode stats */
 	int			*done)	/* 1 if there are more stats to get */
@@ -481,7 +483,7 @@ xfs_bulkstat(
 				 * Get the inode and fill in a single buffer.
 				 */
 				ubused = statstruct_size;
-				error = formatter(mp, ino, ubufp, ubleft,
+				error = formatter(mp, ino, ubufp, ubleft, NULL,
 						  &ubused, &fmterror);
 				if (fmterror == BULKSTAT_RV_NOTHING) {
 					if (error && error != ENOENT &&
@@ -574,7 +576,8 @@ xfs_bulkstat_single(
 	 */
 
 	ino = (xfs_ino_t)*lastinop;
-	error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 0, &res);
+	error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), NULL, 0,
+				 &res);
 	if (error) {
 		/*
 		 * Special case way failed, do it the "long" way
@@ -582,7 +585,7 @@ xfs_bulkstat_single(
 		 */
 		(*lastinop)--;
 		count = 1;
-		if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one,
+		if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one, NULL,
 				sizeof(xfs_bstat_t), buffer, done))
 			return error;
 		if (count == 0 || (xfs_ino_t)*lastinop != ino)
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -27,6 +27,7 @@ typedef int (*bulkstat_one_pf)(struct xf
 			       xfs_ino_t	ino,
 			       void		__user *buffer,
 			       int		ubsize,
+			       void		*private_data,
 			       int		*ubused,
 			       int		*stat);
 
@@ -46,6 +47,7 @@ xfs_bulkstat(
 	xfs_ino_t	*lastino,	/* last inode returned */
 	int		*count,		/* size of buffer/count returned */
 	bulkstat_one_pf formatter,	/* func that'd fill a single buf */
+	void		*private_data,	/* private data for formatter */
 	size_t		statstruct_size,/* sizeof struct that we're filling */
 	char		__user *ubuffer,/* buffer with inode stats */
 	int		*done);		/* 1 if there are more stats to get */
@@ -79,6 +81,7 @@ xfs_bulkstat_one(
 	xfs_ino_t		ino,
 	void			__user *buffer,
 	int			ubsize,
+	void			*private_data,
 	int			*ubused,
 	int			*stat);
 
