aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-03-30 04:21:31 -0400
committerChristoph Hellwig <hch@brick.lst.de>2009-03-30 04:21:31 -0400
commit27174203f570b923e5c02c618a5557295bab8755 (patch)
treeeb30774a90705761afa12ce9c78cbb1d8af17aee /fs/xfs/xfs_mount.c
parent1a5902c5d2ad4f3aa1ee747017622d5d4edfa20f (diff)
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: Christoph Hellwig <hch@lst.de> Reviewed-by: Felix Blyakher <felixb@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c124
1 files changed, 83 insertions, 41 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 92fedfcc879a..b101990df027 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -45,7 +45,6 @@
45#include "xfs_fsops.h" 45#include "xfs_fsops.h"
46#include "xfs_utils.h" 46#include "xfs_utils.h"
47 47
48STATIC int xfs_uuid_mount(xfs_mount_t *);
49STATIC void xfs_unmountfs_wait(xfs_mount_t *); 48STATIC void xfs_unmountfs_wait(xfs_mount_t *);
50 49
51 50
@@ -121,6 +120,84 @@ static const struct {
121 { sizeof(xfs_sb_t), 0 } 120 { sizeof(xfs_sb_t), 0 }
122}; 121};
123 122
123static DEFINE_MUTEX(xfs_uuid_table_mutex);
124static int xfs_uuid_table_size;
125static uuid_t *xfs_uuid_table;
126
127/*
128 * See if the UUID is unique among mounted XFS filesystems.
129 * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
130 */
131STATIC int
132xfs_uuid_mount(
133 struct xfs_mount *mp)
134{
135 uuid_t *uuid = &mp->m_sb.sb_uuid;
136 int hole, i;
137
138 if (mp->m_flags & XFS_MOUNT_NOUUID)
139 return 0;
140
141 if (uuid_is_nil(uuid)) {
142 cmn_err(CE_WARN,
143 "XFS: Filesystem %s has nil UUID - can't mount",
144 mp->m_fsname);
145 return XFS_ERROR(EINVAL);
146 }
147
148 mutex_lock(&xfs_uuid_table_mutex);
149 for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) {
150 if (uuid_is_nil(&xfs_uuid_table[i])) {
151 hole = i;
152 continue;
153 }
154 if (uuid_equal(uuid, &xfs_uuid_table[i]))
155 goto out_duplicate;
156 }
157
158 if (hole < 0) {
159 xfs_uuid_table = kmem_realloc(xfs_uuid_table,
160 (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
161 xfs_uuid_table_size * sizeof(*xfs_uuid_table),
162 KM_SLEEP);
163 hole = xfs_uuid_table_size++;
164 }
165 xfs_uuid_table[hole] = *uuid;
166 mutex_unlock(&xfs_uuid_table_mutex);
167
168 return 0;
169
170 out_duplicate:
171 mutex_unlock(&xfs_uuid_table_mutex);
172 cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount",
173 mp->m_fsname);
174 return XFS_ERROR(EINVAL);
175}
176
177STATIC void
178xfs_uuid_unmount(
179 struct xfs_mount *mp)
180{
181 uuid_t *uuid = &mp->m_sb.sb_uuid;
182 int i;
183
184 if (mp->m_flags & XFS_MOUNT_NOUUID)
185 return;
186
187 mutex_lock(&xfs_uuid_table_mutex);
188 for (i = 0; i < xfs_uuid_table_size; i++) {
189 if (uuid_is_nil(&xfs_uuid_table[i]))
190 continue;
191 if (!uuid_equal(uuid, &xfs_uuid_table[i]))
192 continue;
193 memset(&xfs_uuid_table[i], 0, sizeof(uuid_t));
194 break;
195 }
196 ASSERT(i < xfs_uuid_table_size);
197 mutex_unlock(&xfs_uuid_table_mutex);
198}
199
200
124/* 201/*
125 * Free up the resources associated with a mount structure. Assume that 202 * Free up the resources associated with a mount structure. Assume that
126 * the structure was initially zeroed, so we can tell which fields got 203 * the structure was initially zeroed, so we can tell which fields got
@@ -962,18 +1039,9 @@ xfs_mountfs(
962 1039
963 mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); 1040 mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
964 1041
965 /* 1042 error = xfs_uuid_mount(mp);
966 * XFS uses the uuid from the superblock as the unique 1043 if (error)
967 * identifier for fsid. We can not use the uuid from the volume 1044 goto out;
968 * since a single partition filesystem is identical to a single
969 * partition volume/filesystem.
970 */
971 if (!(mp->m_flags & XFS_MOUNT_NOUUID)) {
972 if (xfs_uuid_mount(mp)) {
973 error = XFS_ERROR(EINVAL);
974 goto out;
975 }
976 }
977 1045
978 /* 1046 /*
979 * Set the minimum read and write sizes 1047 * Set the minimum read and write sizes
@@ -1192,8 +1260,7 @@ xfs_mountfs(
1192 out_free_perag: 1260 out_free_perag:
1193 xfs_free_perag(mp); 1261 xfs_free_perag(mp);
1194 out_remove_uuid: 1262 out_remove_uuid:
1195 if (!(mp->m_flags & XFS_MOUNT_NOUUID)) 1263 xfs_uuid_unmount(mp);
1196 uuid_table_remove(&mp->m_sb.sb_uuid);
1197 out: 1264 out:
1198 return error; 1265 return error;
1199} 1266}
@@ -1276,9 +1343,7 @@ xfs_unmountfs(
1276 xfs_unmountfs_wait(mp); /* wait for async bufs */ 1343 xfs_unmountfs_wait(mp); /* wait for async bufs */
1277 xfs_log_unmount_write(mp); 1344 xfs_log_unmount_write(mp);
1278 xfs_log_unmount(mp); 1345 xfs_log_unmount(mp);
1279 1346 xfs_uuid_unmount(mp);
1280 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
1281 uuid_table_remove(&mp->m_sb.sb_uuid);
1282 1347
1283#if defined(DEBUG) 1348#if defined(DEBUG)
1284 xfs_errortag_clearall(mp, 0); 1349 xfs_errortag_clearall(mp, 0);
@@ -1780,29 +1845,6 @@ xfs_freesb(
1780} 1845}
1781 1846
1782/* 1847/*
1783 * See if the UUID is unique among mounted XFS filesystems.
1784 * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
1785 */
1786STATIC int
1787xfs_uuid_mount(
1788 xfs_mount_t *mp)
1789{
1790 if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
1791 cmn_err(CE_WARN,
1792 "XFS: Filesystem %s has nil UUID - can't mount",
1793 mp->m_fsname);
1794 return -1;
1795 }
1796 if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
1797 cmn_err(CE_WARN,
1798 "XFS: Filesystem %s has duplicate UUID - can't mount",
1799 mp->m_fsname);
1800 return -1;
1801 }
1802 return 0;
1803}
1804
1805/*
1806 * Used to log changes to the superblock unit and width fields which could 1848 * Used to log changes to the superblock unit and width fields which could
1807 * be altered by the mount options, as well as any potential sb_features2 1849 * be altered by the mount options, as well as any potential sb_features2
1808 * fixup. Only the first superblock is updated. 1850 * fixup. Only the first superblock is updated.