Esempio n. 1
0
/*
 * Convert from 8-byte inode numbers to 4-byte inode numbers.
 * The last 8-byte inode number is gone, but the count is still 1.
 */
static void
xfs_dir2_sf_toino4(
	xfs_da_args_t		*args)		/* operation arguments */
{
	char			*buf;		/* old dir's buffer */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			i;		/* entry index */
	int			newsize;	/* new inode size */
	xfs_dir2_sf_entry_t	*oldsfep;	/* old sf entry */
	xfs_dir2_sf_hdr_t	*oldsfp;	/* old sf directory */
	int			oldsize;	/* old inode size */
	xfs_dir2_sf_entry_t	*sfep;		/* new sf entry */
	xfs_dir2_sf_hdr_t	*sfp;		/* new sf directory */

	trace_xfs_dir2_sf_toino4(args);

	dp = args->dp;

	/*
	 * Copy the old directory to the buffer.
	 * Then nuke it from the inode, and add the new buffer to the inode.
	 * Don't want xfs_idata_realloc copying the data here.
	 */
	oldsize = dp->i_df.if_bytes;
	buf = kmem_alloc(oldsize, KM_SLEEP);
	oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
	ASSERT(oldsfp->i8count == 1);
	memcpy(buf, oldsfp, oldsize);
	/*
	 * Compute the new inode size.
	 */
	newsize =
		oldsize -
		(oldsfp->count + 1) *
		((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
	xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
	xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
	/*
	 * Reset our pointers, the data has moved.
	 */
	oldsfp = (xfs_dir2_sf_hdr_t *)buf;
	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
	/*
	 * Fill in the new header.
	 */
	sfp->count = oldsfp->count;
	sfp->i8count = 0;
	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
	/*
	 * Copy the entries field by field.
	 */
	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
	     i < sfp->count;
	     i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
		  oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
		sfep->namelen = oldsfep->namelen;
		sfep->offset = oldsfep->offset;
		memcpy(sfep->name, oldsfep->name, sfep->namelen);
		xfs_dir2_sfe_put_ino(sfp, sfep,
			xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
	}
	/*
	 * Clean up the inode.
	 */
	kmem_free(buf);
	dp->i_d.di_size = newsize;
	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
}
static void
xfs_dir2_sf_toino4(
	xfs_da_args_t		*args)		/*                     */
{
	char			*buf;		/*                  */
	xfs_inode_t		*dp;		/*                        */
	int			i;		/*             */
	int			newsize;	/*                */
	xfs_dir2_sf_entry_t	*oldsfep;	/*              */
	xfs_dir2_sf_hdr_t	*oldsfp;	/*                  */
	int			oldsize;	/*                */
	xfs_dir2_sf_entry_t	*sfep;		/*              */
	xfs_dir2_sf_hdr_t	*sfp;		/*                  */

	trace_xfs_dir2_sf_toino4(args);

	dp = args->dp;

	/*
                                         
                                                                     
                                                       
  */
	oldsize = dp->i_df.if_bytes;
	buf = kmem_alloc(oldsize, KM_SLEEP);
	oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
	ASSERT(oldsfp->i8count == 1);
	memcpy(buf, oldsfp, oldsize);
	/*
                               
  */
	newsize =
		oldsize -
		(oldsfp->count + 1) *
		((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
	xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
	xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
	/*
                                           
  */
	oldsfp = (xfs_dir2_sf_hdr_t *)buf;
	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
	/*
                           
  */
	sfp->count = oldsfp->count;
	sfp->i8count = 0;
	xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
	/*
                                    
  */
	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
		    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
	     i < sfp->count;
	     i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
		  oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
		sfep->namelen = oldsfep->namelen;
		sfep->offset = oldsfep->offset;
		memcpy(sfep->name, oldsfep->name, sfep->namelen);
		xfs_dir2_sfe_put_ino(sfp, sfep,
			xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
	}
	/*
                       
  */
	kmem_free(buf);
	dp->i_d.di_size = newsize;
	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
}