Commit b94ca00e authored by Nathan Scott's avatar Nathan Scott

[XFS] UUID cleanup - remove unused functions, create a decent table abstraction

and make the mount code simpler in the process.

SGI Modid: 2.5.x-xfs:slinx:144596a
parent f78a06f5
...@@ -959,6 +959,7 @@ init_xfs_fs( void ) ...@@ -959,6 +959,7 @@ init_xfs_fs( void )
vn_init(); vn_init();
xfs_init(); xfs_init();
uuid_init();
vfs_initdmapi(); vfs_initdmapi();
vfs_initquota(); vfs_initquota();
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as * under the terms of version 2 of the GNU General Public License as
...@@ -31,58 +31,22 @@ ...@@ -31,58 +31,22 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/random.h>
#include <linux/time.h>
#ifdef __sparc__
#include <asm/idprom.h>
#else
#include <linux/netdevice.h>
#endif
#include <xfs_types.h> #include <xfs_types.h>
#include <xfs_arch.h> #include <xfs_arch.h>
#include "time.h" #include "time.h"
#include "move.h"
#include "uuid.h" #include "uuid.h"
#include "kmem.h"
#include "debug.h"
#include "mutex.h"
#ifndef CONFIG_NET static mutex_t uuid_monitor;
#define dev_get_by_name(x) (NULL) static int uuid_table_size;
#define dev_put(x) do { } while (0) static uuid_t *uuid_table;
#endif
/* NODE_SIZE is the number of bytes used for the node identifier portion. */
#define NODE_SIZE 6
/*
* Total size must be 128 bits. N.B. definition of uuid_t in uuid.h!
*/
typedef struct {
u_int32_t uu_timelow; /* time "low" */
u_int16_t uu_timemid; /* time "mid" */
u_int16_t uu_timehi; /* time "hi" and version */
u_int16_t uu_clockseq; /* "reserved" and clock sequence */
u_int16_t uu_node[NODE_SIZE / 2]; /* ethernet hardware address */
} uu_t;
/*
* The Time Base Correction is the amount to add on to a UNIX-based
* time value (i.e. seconds since 1 Jan. 1970) to convert it to the
* time base for UUIDs (15 Oct. 1582).
*/
#define UUID_TBC 0x01B21DD2138140LL
static short uuid_eaddr[NODE_SIZE / 2]; /* ethernet address */
static __int64_t uuid_time; /* last time basis used */
static u_int16_t uuid_clockseq; /* boot-time randomizer */
DECLARE_MUTEX(uuid_lock);
/*
* uuid_init - called from out of init_tbl[]
*/
void void
uuid_init(void) uuid_init(void)
{ {
mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor");
} }
/* /*
...@@ -94,7 +58,7 @@ uuid_init(void) ...@@ -94,7 +58,7 @@ uuid_init(void)
void void
uuid_getnodeuniq(uuid_t *uuid, int fsid [2]) uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
{ {
char *uu=(char*)uuid; char *uu = (char *)uuid;
/* on IRIX, this function assumes big-endian fields within /* on IRIX, this function assumes big-endian fields within
* the uuid, so we use INT_GET to get the same result on * the uuid, so we use INT_GET to get the same result on
...@@ -119,17 +83,17 @@ uuid_is_nil(uuid_t *uuid) ...@@ -119,17 +83,17 @@ uuid_is_nil(uuid_t *uuid)
char *cp = (char *)uuid; char *cp = (char *)uuid;
if (uuid == NULL) if (uuid == NULL)
return B_TRUE; return 0;
/* implied check of version number here... */ /* implied check of version number here... */
for (i = 0; i < sizeof *uuid; i++) for (i = 0; i < sizeof *uuid; i++)
if (*cp++) return B_FALSE; /* not nil */ if (*cp++) return 0; /* not nil */
return B_TRUE; /* is nil */ return 1; /* is nil */
} }
int int
uuid_equal(uuid_t *uuid1, uuid_t *uuid2) uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
{ {
return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? B_FALSE : B_TRUE; return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
} }
/* /*
...@@ -145,94 +109,50 @@ uuid_hash64(uuid_t *uuid) ...@@ -145,94 +109,50 @@ uuid_hash64(uuid_t *uuid)
__uint64_t *sp = (__uint64_t *)uuid; __uint64_t *sp = (__uint64_t *)uuid;
return sp[0] + sp[1]; return sp[0] + sp[1];
} /* uuid_hash64 */
static void
get_eaddr(char *junk)
{
#ifdef __sparc__
memcpy(uuid_eaddr, idprom->id_ethaddr, 6);
#else
struct net_device *dev;
dev = dev_get_by_name("eth0");
if (!dev || !dev->addr_len) {
get_random_bytes(uuid_eaddr, sizeof(uuid_eaddr));
} else {
memcpy(uuid_eaddr, dev->dev_addr,
dev->addr_len<sizeof(uuid_eaddr)?
dev->addr_len:sizeof(uuid_eaddr));
dev_put(dev);
}
#endif
} }
/* int
* uuid_create - kernel version, does the actual work uuid_table_insert(uuid_t *uuid)
*/
void
uuid_create(uuid_t *uuid)
{ {
int i; int i, hole;
uu_t *uu = (uu_t *)uuid;
static int uuid_have_eaddr = 0; /* ethernet addr inited? */
static int uuid_is_init = 0; /* time/clockseq inited? */
down(&uuid_lock);
if (!uuid_is_init) {
timespec_t ts;
nanotime(&ts); mutex_lock(&uuid_monitor, PVFS);
/* for (i = 0, hole = -1; i < uuid_table_size; i++) {
* The clock sequence must be initialized randomly. if (uuid_is_nil(&uuid_table[i])) {
*/ hole = i;
uuid_clockseq = ((unsigned long)jiffies & 0xfff) | 0x8000; continue;
/* }
* Initialize the uuid time, it's in 100 nanosecond if (uuid_equal(uuid, &uuid_table[i])) {
* units since a time base in 1582. mutex_unlock(&uuid_monitor);
*/ return 0;
uuid_time = ts.tv_sec * 10000000LL + }
ts.tv_nsec / 100LL +
UUID_TBC;
uuid_is_init = 1;
} }
if (!uuid_have_eaddr) { if (hole < 0) {
uuid_have_eaddr = 1; uuid_table = kmem_realloc(uuid_table,
get_eaddr((char *)uuid_eaddr); (uuid_table_size + 1) * sizeof(*uuid_table),
uuid_table_size * sizeof(*uuid_table),
KM_SLEEP);
hole = uuid_table_size++;
} }
uuid_time++; uuid_table[hole] = *uuid;
uu->uu_timelow = (u_int32_t)(uuid_time & 0x00000000ffffffffLL); mutex_unlock(&uuid_monitor);
uu->uu_timemid = (u_int16_t)((uuid_time >> 32) & 0x0000ffff); return 1;
uu->uu_timehi = (u_int16_t)((uuid_time >> 48) & 0x00000fff) | 0x1000;
up(&uuid_lock);
uu->uu_clockseq = uuid_clockseq;
for (i = 0; i < (NODE_SIZE / 2); i++)
uu->uu_node [i] = uuid_eaddr [i];
} }
int void
uuid_compare(uuid_t *uuid1, uuid_t *uuid2) uuid_table_remove(uuid_t *uuid)
{ {
int i; int i;
char *cp1 = (char *) uuid1;
char *cp2 = (char *) uuid2;
if (uuid1 == NULL) {
if (uuid2 == NULL) {
return 0; /* equal because both are nil */
} else {
return -1; /* uuid1 nil, so precedes uuid2 */
}
} else if (uuid2 == NULL) {
return 1;
}
/* implied check of version number here... */ mutex_lock(&uuid_monitor, PVFS);
for (i = 0; i < sizeof(uuid_t); i++) { for (i = 0; i < uuid_table_size; i++) {
if (*cp1 < *cp2) if (uuid_is_nil(&uuid_table[i]))
return -1; continue;
if (*cp1++ > *cp2++) if (!uuid_equal(uuid, &uuid_table[i]))
return 1; continue;
uuid_create_nil(&uuid_table[i]);
break;
} }
return 0; /* they're equal */ ASSERT(i < uuid_table_size);
mutex_unlock(&uuid_monitor);
} }
...@@ -36,10 +36,13 @@ typedef struct { ...@@ -36,10 +36,13 @@ typedef struct {
unsigned char __u_bits[16]; unsigned char __u_bits[16];
} uuid_t; } uuid_t;
void uuid_init(void);
void uuid_create_nil(uuid_t *uuid); void uuid_create_nil(uuid_t *uuid);
int uuid_is_nil(uuid_t *uuid); int uuid_is_nil(uuid_t *uuid);
int uuid_equal(uuid_t *uuid1, uuid_t *uuid2); int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]); void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
__uint64_t uuid_hash64(uuid_t *uuid); __uint64_t uuid_hash64(uuid_t *uuid);
int uuid_table_insert(uuid_t *uuid);
void uuid_table_remove(uuid_t *uuid);
#endif /* __XFS_SUPPORT_UUID_H__ */ #endif /* __XFS_SUPPORT_UUID_H__ */
...@@ -36,10 +36,6 @@ STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); ...@@ -36,10 +36,6 @@ STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
STATIC int xfs_uuid_mount(xfs_mount_t *); STATIC int xfs_uuid_mount(xfs_mount_t *);
STATIC void xfs_uuid_unmount(xfs_mount_t *mp); STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
mutex_t xfs_uuidtabmon; /* monitor for uuidtab */
STATIC int xfs_uuidtab_size;
STATIC uuid_t *xfs_uuidtab;
void xfs_xlatesb(void *, xfs_sb_t *, int, xfs_arch_t, __int64_t); void xfs_xlatesb(void *, xfs_sb_t *, int, xfs_arch_t, __int64_t);
static struct { static struct {
...@@ -1457,10 +1453,12 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) ...@@ -1457,10 +1453,12 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd)
* If it can't then we'll return NULL. * If it can't then we'll return NULL.
*/ */
xfs_buf_t * xfs_buf_t *
xfs_getsb(xfs_mount_t *mp, xfs_getsb(
xfs_mount_t *mp,
int flags) int flags)
{ {
xfs_buf_t *bp; xfs_buf_t *bp;
ASSERT(mp->m_sb_bp != NULL); ASSERT(mp->m_sb_bp != NULL);
bp = mp->m_sb_bp; bp = mp->m_sb_bp;
if (flags & XFS_BUF_TRYLOCK) { if (flags & XFS_BUF_TRYLOCK) {
...@@ -1495,67 +1493,36 @@ xfs_freesb( ...@@ -1495,67 +1493,36 @@ xfs_freesb(
} }
/* /*
* See if the uuid is unique among mounted xfs filesystems. * 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 * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
* mounted
*/ */
STATIC int STATIC int
xfs_uuid_mount(xfs_mount_t *mp) xfs_uuid_mount(
xfs_mount_t *mp)
{ {
int hole;
int i;
if (uuid_is_nil(&mp->m_sb.sb_uuid)) { if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
cmn_err(CE_WARN, "XFS: Filesystem %s has nil UUID - can't mount", cmn_err(CE_WARN,
"XFS: Filesystem %s has nil UUID - can't mount",
mp->m_fsname); mp->m_fsname);
return -1; return -1;
} }
if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
mutex_lock(&xfs_uuidtabmon, PVFS); cmn_err(CE_WARN,
for (i = 0, hole = -1; i < xfs_uuidtab_size; i++) { "XFS: Filesystem %s has duplicate UUID - can't mount",
if (uuid_is_nil(&xfs_uuidtab[i])) {
hole = i;
continue;
}
if (uuid_equal(&mp->m_sb.sb_uuid, &xfs_uuidtab[i])) {
cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount",
mp->m_fsname); mp->m_fsname);
mutex_unlock(&xfs_uuidtabmon);
return -1; return -1;
} }
}
if (hole < 0) {
xfs_uuidtab = kmem_realloc(xfs_uuidtab,
(xfs_uuidtab_size + 1) * sizeof(*xfs_uuidtab),
xfs_uuidtab_size * sizeof(*xfs_uuidtab),
KM_SLEEP);
hole = xfs_uuidtab_size++;
}
xfs_uuidtab[hole] = mp->m_sb.sb_uuid;
mutex_unlock(&xfs_uuidtabmon);
return 0; return 0;
} }
/* /*
* Remove filesystem from the uuid table. * Remove filesystem from the UUID table.
*/ */
STATIC void STATIC void
xfs_uuid_unmount(xfs_mount_t *mp) xfs_uuid_unmount(
xfs_mount_t *mp)
{ {
int i; uuid_table_remove(&mp->m_sb.sb_uuid);
mutex_lock(&xfs_uuidtabmon, PVFS);
for (i = 0; i < xfs_uuidtab_size; i++) {
if (uuid_is_nil(&xfs_uuidtab[i]))
continue;
if (!uuid_equal(&mp->m_sb.sb_uuid, &xfs_uuidtab[i]))
continue;
uuid_create_nil(&xfs_uuidtab[i]);
break;
}
ASSERT(i < xfs_uuidtab_size);
mutex_unlock(&xfs_uuidtabmon);
} }
/* /*
...@@ -1578,7 +1545,7 @@ xfs_mount_log_sbunit( ...@@ -1578,7 +1545,7 @@ xfs_mount_log_sbunit(
return; return;
} }
xfs_mod_sb(tp, fields); xfs_mod_sb(tp, fields);
(void)xfs_trans_commit(tp, 0, NULL); xfs_trans_commit(tp, 0, NULL);
} }
/* Functions to lock access out of the filesystem for forced /* Functions to lock access out of the filesystem for forced
...@@ -1621,7 +1588,7 @@ xfs_check_frozen( ...@@ -1621,7 +1588,7 @@ xfs_check_frozen(
bhv_desc_t *bdp, bhv_desc_t *bdp,
int level) int level)
{ {
SPLDECL(s); unsigned long s;
if (mp->m_frozen) { if (mp->m_frozen) {
s = mutex_spinlock(&mp->m_freeze_lock); s = mutex_spinlock(&mp->m_freeze_lock);
......
...@@ -65,7 +65,6 @@ xfs_init(void) ...@@ -65,7 +65,6 @@ xfs_init(void)
#ifdef XFS_DABUF_DEBUG #ifdef XFS_DABUF_DEBUG
spinlock_init(&xfs_dabuf_global_lock, "xfsda"); spinlock_init(&xfs_dabuf_global_lock, "xfsda");
#endif #endif
mutex_init(&xfs_uuidtabmon, MUTEX_DEFAULT, "xfs_uuidtab");
/* /*
* Initialize all of the zone allocators we use. * Initialize all of the zone allocators we use.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment