xfs: cleanup uuid handling
authorChristoph Hellwig <hch@lst.de>
Mon, 30 Mar 2009 08:21:31 +0000 (10:21 +0200)
committerChristoph Hellwig <hch@brick.lst.de>
Mon, 30 Mar 2009 08:21:31 +0000 (10:21 +0200)
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: Christoph Hellwig <hch@lst.de>
Reviewed-by: Felix Blyakher <felixb@sgi.com>
fs/xfs/support/uuid.c
fs/xfs/support/uuid.h
fs/xfs/xfs_mount.c

index 5830c04..b83f76b 100644 (file)
  */
 #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);
-}
index cff5b60..4732d71 100644 (file)
@@ -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__ */
index 92fedfc..b101990 100644 (file)
@@ -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);
-                       goto out;
-               }
-       }
+       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);
@@ -1780,29 +1845,6 @@ xfs_freesb(
 }
 
 /*
- * 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
  * fixup. Only the first superblock is updated.