Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140136
b: refs/heads/master
c: 2717420
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Hellwig authored and Christoph Hellwig committed Mar 30, 2009
1 parent a3972b0 commit f252b89
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 117 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1a5902c5d2ad4f3aa1ee747017622d5d4edfa20f
refs/heads/master: 27174203f570b923e5c02c618a5557295bab8755
71 changes: 0 additions & 71 deletions trunk/fs/xfs/support/uuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
{
Expand All @@ -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);
}
4 changes: 0 additions & 4 deletions trunk/fs/xfs/support/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
124 changes: 83 additions & 41 deletions trunk/fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f252b89

Please sign in to comment.