diff options
author | Christoph Hellwig <hch@lst.de> | 2009-03-30 04:21:31 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@brick.lst.de> | 2009-03-30 04:21:31 -0400 |
commit | 27174203f570b923e5c02c618a5557295bab8755 (patch) | |
tree | eb30774a90705761afa12ce9c78cbb1d8af17aee /fs/xfs/xfs_mount.c | |
parent | 1a5902c5d2ad4f3aa1ee747017622d5d4edfa20f (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.c | 124 |
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 | ||
48 | STATIC int xfs_uuid_mount(xfs_mount_t *); | ||
49 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); | 48 | STATIC 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 | ||
123 | static DEFINE_MUTEX(xfs_uuid_table_mutex); | ||
124 | static int xfs_uuid_table_size; | ||
125 | static 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 | */ | ||
131 | STATIC int | ||
132 | xfs_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 | |||
177 | STATIC void | ||
178 | xfs_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 | */ | ||
1786 | STATIC int | ||
1787 | xfs_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. |