Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27174203 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christoph Hellwig
Browse files

xfs: cleanup uuid handling



The uuid table handling should not be part of a semi-generic uuid library
but in the XFS code using it, so move those bits to xfs_mount.c and
refactor the whole glob to make it a proper abstraction.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarFelix Blyakher <felixb@sgi.com>
parent 1a5902c5
Loading
Loading
Loading
Loading
+0 −71
Original line number Diff line number Diff line
@@ -17,10 +17,6 @@
 */
#include <xfs.h>

static DEFINE_MUTEX(uuid_monitor);
static int	uuid_table_size;
static uuid_t	*uuid_table;

/* IRIX interpretation of an uuid_t */
typedef struct {
	__be32	uu_timelow;
@@ -46,12 +42,6 @@ uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
	fsid[1] = be32_to_cpu(uup->uu_timelow);
}

void
uuid_create_nil(uuid_t *uuid)
{
	memset(uuid, 0, sizeof(*uuid));
}

int
uuid_is_nil(uuid_t *uuid)
{
@@ -71,64 +61,3 @@ uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
{
	return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
}

/*
 * Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
 * 64-bit words.  NOTE: This function can not be changed EVER.  Although
 * brain-dead, some applications depend on this 64-bit value remaining
 * persistent.  Specifically, DMI vendors store the value as a persistent
 * filehandle.
 */
__uint64_t
uuid_hash64(uuid_t *uuid)
{
	__uint64_t	*sp = (__uint64_t *)uuid;

	return sp[0] + sp[1];
}

int
uuid_table_insert(uuid_t *uuid)
{
	int	i, hole;

	mutex_lock(&uuid_monitor);
	for (i = 0, hole = -1; i < uuid_table_size; i++) {
		if (uuid_is_nil(&uuid_table[i])) {
			hole = i;
			continue;
		}
		if (uuid_equal(uuid, &uuid_table[i])) {
			mutex_unlock(&uuid_monitor);
			return 0;
		}
	}
	if (hole < 0) {
		uuid_table = kmem_realloc(uuid_table,
			(uuid_table_size + 1) * sizeof(*uuid_table),
			uuid_table_size  * sizeof(*uuid_table),
			KM_SLEEP);
		hole = uuid_table_size++;
	}
	uuid_table[hole] = *uuid;
	mutex_unlock(&uuid_monitor);
	return 1;
}

void
uuid_table_remove(uuid_t *uuid)
{
	int	i;

	mutex_lock(&uuid_monitor);
	for (i = 0; i < uuid_table_size; i++) {
		if (uuid_is_nil(&uuid_table[i]))
			continue;
		if (!uuid_equal(uuid, &uuid_table[i]))
			continue;
		uuid_create_nil(&uuid_table[i]);
		break;
	}
	ASSERT(i < uuid_table_size);
	mutex_unlock(&uuid_monitor);
}
+0 −4
Original line number Diff line number Diff line
@@ -22,12 +22,8 @@ typedef struct {
	unsigned char	__u_bits[16];
} uuid_t;

extern void uuid_create_nil(uuid_t *uuid);
extern int uuid_is_nil(uuid_t *uuid);
extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
extern __uint64_t uuid_hash64(uuid_t *uuid);
extern int uuid_table_insert(uuid_t *uuid);
extern void uuid_table_remove(uuid_t *uuid);

#endif	/* __XFS_SUPPORT_UUID_H__ */
+83 −41
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@
#include "xfs_fsops.h"
#include "xfs_utils.h"

STATIC int	xfs_uuid_mount(xfs_mount_t *);
STATIC void	xfs_unmountfs_wait(xfs_mount_t *);


@@ -121,6 +120,84 @@ static const struct {
    { sizeof(xfs_sb_t),			 0 }
};

static DEFINE_MUTEX(xfs_uuid_table_mutex);
static int xfs_uuid_table_size;
static uuid_t *xfs_uuid_table;

/*
 * See if the UUID is unique among mounted XFS filesystems.
 * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
 */
STATIC int
xfs_uuid_mount(
	struct xfs_mount	*mp)
{
	uuid_t			*uuid = &mp->m_sb.sb_uuid;
	int			hole, i;

	if (mp->m_flags & XFS_MOUNT_NOUUID)
		return 0;

	if (uuid_is_nil(uuid)) {
		cmn_err(CE_WARN,
			"XFS: Filesystem %s has nil UUID - can't mount",
			mp->m_fsname);
		return XFS_ERROR(EINVAL);
	}

	mutex_lock(&xfs_uuid_table_mutex);
	for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) {
		if (uuid_is_nil(&xfs_uuid_table[i])) {
			hole = i;
			continue;
		}
		if (uuid_equal(uuid, &xfs_uuid_table[i]))
			goto out_duplicate;
	}

	if (hole < 0) {
		xfs_uuid_table = kmem_realloc(xfs_uuid_table,
			(xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
			xfs_uuid_table_size  * sizeof(*xfs_uuid_table),
			KM_SLEEP);
		hole = xfs_uuid_table_size++;
	}
	xfs_uuid_table[hole] = *uuid;
	mutex_unlock(&xfs_uuid_table_mutex);

	return 0;

 out_duplicate:
	mutex_unlock(&xfs_uuid_table_mutex);
	cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount",
			 mp->m_fsname);
	return XFS_ERROR(EINVAL);
}

STATIC void
xfs_uuid_unmount(
	struct xfs_mount	*mp)
{
	uuid_t			*uuid = &mp->m_sb.sb_uuid;
	int			i;

	if (mp->m_flags & XFS_MOUNT_NOUUID)
		return;

	mutex_lock(&xfs_uuid_table_mutex);
	for (i = 0; i < xfs_uuid_table_size; i++) {
		if (uuid_is_nil(&xfs_uuid_table[i]))
			continue;
		if (!uuid_equal(uuid, &xfs_uuid_table[i]))
			continue;
		memset(&xfs_uuid_table[i], 0, sizeof(uuid_t));
		break;
	}
	ASSERT(i < xfs_uuid_table_size);
	mutex_unlock(&xfs_uuid_table_mutex);
}


/*
 * Free up the resources associated with a mount structure.  Assume that
 * the structure was initially zeroed, so we can tell which fields got
@@ -962,18 +1039,9 @@ xfs_mountfs(

	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);

	/*
	 * XFS uses the uuid from the superblock as the unique
	 * identifier for fsid.  We can not use the uuid from the volume
	 * since a single partition filesystem is identical to a single
	 * partition volume/filesystem.
	 */
	if (!(mp->m_flags & XFS_MOUNT_NOUUID)) {
		if (xfs_uuid_mount(mp)) {
			error = XFS_ERROR(EINVAL);
	error = xfs_uuid_mount(mp);
	if (error)
		goto out;
		}
	}

	/*
	 * Set the minimum read and write sizes
@@ -1192,8 +1260,7 @@ xfs_mountfs(
 out_free_perag:
	xfs_free_perag(mp);
 out_remove_uuid:
	if (!(mp->m_flags & XFS_MOUNT_NOUUID))
		uuid_table_remove(&mp->m_sb.sb_uuid);
	xfs_uuid_unmount(mp);
 out:
	return error;
}
@@ -1276,9 +1343,7 @@ xfs_unmountfs(
	xfs_unmountfs_wait(mp); 		/* wait for async bufs */
	xfs_log_unmount_write(mp);
	xfs_log_unmount(mp);

	if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
		uuid_table_remove(&mp->m_sb.sb_uuid);
	xfs_uuid_unmount(mp);

#if defined(DEBUG)
	xfs_errortag_clearall(mp, 0);
@@ -1779,29 +1844,6 @@ xfs_freesb(
	mp->m_sb_bp = NULL;
}

/*
 * See if the UUID is unique among mounted XFS filesystems.
 * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
 */
STATIC int
xfs_uuid_mount(
	xfs_mount_t	*mp)
{
	if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
		cmn_err(CE_WARN,
			"XFS: Filesystem %s has nil UUID - can't mount",
			mp->m_fsname);
		return -1;
	}
	if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
		cmn_err(CE_WARN,
			"XFS: Filesystem %s has duplicate UUID - can't mount",
			mp->m_fsname);
		return -1;
	}
	return 0;
}

/*
 * Used to log changes to the superblock unit and width fields which could
 * be altered by the mount options, as well as any potential sb_features2