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
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* Further, this software is distributed without any warranty that it is * Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement * free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or * or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if * otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with * any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever. * other software, or any other product whatsoever.
...@@ -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,24 +83,24 @@ uuid_is_nil(uuid_t *uuid) ...@@ -119,24 +83,24 @@ 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;
} }
/* /*
* Given a 128-bit uuid, return a 64-bit value by adding the top and bottom * 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 * 64-bit words. NOTE: This function can not be changed EVER. Although
* brain-dead, some applications depend on this 64-bit value remaining * brain-dead, some applications depend on this 64-bit value remaining
* persistent. Specifically, DMI vendors store the value as a persistent * persistent. Specifically, DMI vendors store the value as a persistent
* filehandle. * filehandle.
*/ */
__uint64_t __uint64_t
...@@ -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? */ mutex_lock(&uuid_monitor, PVFS);
static int uuid_is_init = 0; /* time/clockseq inited? */ for (i = 0, hole = -1; i < uuid_table_size; i++) {
if (uuid_is_nil(&uuid_table[i])) {
down(&uuid_lock); hole = i;
if (!uuid_is_init) { continue;
timespec_t ts; }
if (uuid_equal(uuid, &uuid_table[i])) {
nanotime(&ts); mutex_unlock(&uuid_monitor);
/* return 0;
* The clock sequence must be initialized randomly. }
*/
uuid_clockseq = ((unsigned long)jiffies & 0xfff) | 0x8000;
/*
* Initialize the uuid time, it's in 100 nanosecond
* units since a time base in 1582.
*/
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 {
...@@ -1169,7 +1165,7 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) ...@@ -1169,7 +1165,7 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
void void
xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
{ {
xfs_buf_t *bp; xfs_buf_t *bp;
int first; int first;
int last; int last;
xfs_mount_t *mp; xfs_mount_t *mp;
...@@ -1217,7 +1213,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field, ...@@ -1217,7 +1213,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
{ {
int scounter; /* short counter for 32 bit fields */ int scounter; /* short counter for 32 bit fields */
long long lcounter; /* long counter for 64 bit fields */ long long lcounter; /* long counter for 64 bit fields */
long long res_used, rem; long long res_used, rem;
/* /*
* With the in-core superblock spin lock held, switch * With the in-core superblock spin lock held, switch
...@@ -1400,7 +1396,7 @@ xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd) ...@@ -1400,7 +1396,7 @@ xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd)
int int
xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd) xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd)
{ {
unsigned long s; unsigned long s;
int status=0; int status=0;
xfs_mod_sb_t *msbp; xfs_mod_sb_t *msbp;
...@@ -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(
int flags) xfs_mount_t *mp,
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])) { mp->m_fsname);
hole = i; return -1;
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);
mutex_unlock(&xfs_uuidtabmon);
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);
} }
/* /*
...@@ -1564,10 +1531,10 @@ xfs_uuid_unmount(xfs_mount_t *mp) ...@@ -1564,10 +1531,10 @@ xfs_uuid_unmount(xfs_mount_t *mp)
*/ */
STATIC void STATIC void
xfs_mount_log_sbunit( xfs_mount_log_sbunit(
xfs_mount_t *mp, xfs_mount_t *mp,
__int64_t fields) __int64_t fields)
{ {
xfs_trans_t *tp; xfs_trans_t *tp;
ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID)); ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID));
...@@ -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
...@@ -1603,7 +1570,7 @@ xfs_start_freeze( ...@@ -1603,7 +1570,7 @@ xfs_start_freeze(
void void
xfs_finish_freeze( xfs_finish_freeze(
xfs_mount_t *mp) xfs_mount_t *mp)
{ {
unsigned long s = mutex_spinlock(&mp->m_freeze_lock); unsigned long s = mutex_spinlock(&mp->m_freeze_lock);
...@@ -1617,11 +1584,11 @@ xfs_finish_freeze( ...@@ -1617,11 +1584,11 @@ xfs_finish_freeze(
void void
xfs_check_frozen( xfs_check_frozen(
xfs_mount_t *mp, xfs_mount_t *mp,
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