diff options
Diffstat (limited to 'fs/gfs2/super.c')
| -rw-r--r-- | fs/gfs2/super.c | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ca831991cbc2..c3ba3d9d0aac 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
| @@ -33,313 +33,6 @@ | |||
| 33 | #include "trans.h" | 33 | #include "trans.h" |
| 34 | #include "util.h" | 34 | #include "util.h" |
| 35 | 35 | ||
| 36 | static const u32 gfs2_old_fs_formats[] = { | ||
| 37 | 0 | ||
| 38 | }; | ||
| 39 | |||
| 40 | static const u32 gfs2_old_multihost_formats[] = { | ||
| 41 | 0 | ||
| 42 | }; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * gfs2_tune_init - Fill a gfs2_tune structure with default values | ||
| 46 | * @gt: tune | ||
| 47 | * | ||
| 48 | */ | ||
| 49 | |||
| 50 | void gfs2_tune_init(struct gfs2_tune *gt) | ||
| 51 | { | ||
| 52 | spin_lock_init(>->gt_spin); | ||
| 53 | |||
| 54 | gt->gt_demote_secs = 300; | ||
| 55 | gt->gt_incore_log_blocks = 1024; | ||
| 56 | gt->gt_log_flush_secs = 60; | ||
| 57 | gt->gt_recoverd_secs = 60; | ||
| 58 | gt->gt_logd_secs = 1; | ||
| 59 | gt->gt_quotad_secs = 5; | ||
| 60 | gt->gt_quota_simul_sync = 64; | ||
| 61 | gt->gt_quota_warn_period = 10; | ||
| 62 | gt->gt_quota_scale_num = 1; | ||
| 63 | gt->gt_quota_scale_den = 1; | ||
| 64 | gt->gt_quota_cache_secs = 300; | ||
| 65 | gt->gt_quota_quantum = 60; | ||
| 66 | gt->gt_atime_quantum = 3600; | ||
| 67 | gt->gt_new_files_jdata = 0; | ||
| 68 | gt->gt_max_readahead = 1 << 18; | ||
| 69 | gt->gt_stall_secs = 600; | ||
| 70 | gt->gt_complain_secs = 10; | ||
| 71 | gt->gt_statfs_quantum = 30; | ||
| 72 | gt->gt_statfs_slow = 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * gfs2_check_sb - Check superblock | ||
| 77 | * @sdp: the filesystem | ||
| 78 | * @sb: The superblock | ||
| 79 | * @silent: Don't print a message if the check fails | ||
| 80 | * | ||
| 81 | * Checks the version code of the FS is one that we understand how to | ||
| 82 | * read and that the sizes of the various on-disk structures have not | ||
| 83 | * changed. | ||
| 84 | */ | ||
| 85 | |||
| 86 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) | ||
| 87 | { | ||
| 88 | unsigned int x; | ||
| 89 | |||
| 90 | if (sb->sb_magic != GFS2_MAGIC || | ||
| 91 | sb->sb_type != GFS2_METATYPE_SB) { | ||
| 92 | if (!silent) | ||
| 93 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); | ||
| 94 | return -EINVAL; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* If format numbers match exactly, we're done. */ | ||
| 98 | |||
| 99 | if (sb->sb_fs_format == GFS2_FORMAT_FS && | ||
| 100 | sb->sb_multihost_format == GFS2_FORMAT_MULTI) | ||
| 101 | return 0; | ||
| 102 | |||
| 103 | if (sb->sb_fs_format != GFS2_FORMAT_FS) { | ||
| 104 | for (x = 0; gfs2_old_fs_formats[x]; x++) | ||
| 105 | if (gfs2_old_fs_formats[x] == sb->sb_fs_format) | ||
| 106 | break; | ||
| 107 | |||
| 108 | if (!gfs2_old_fs_formats[x]) { | ||
| 109 | printk(KERN_WARNING | ||
| 110 | "GFS2: code version (%u, %u) is incompatible " | ||
| 111 | "with ondisk format (%u, %u)\n", | ||
| 112 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | ||
| 113 | sb->sb_fs_format, sb->sb_multihost_format); | ||
| 114 | printk(KERN_WARNING | ||
| 115 | "GFS2: I don't know how to upgrade this FS\n"); | ||
| 116 | return -EINVAL; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) { | ||
| 121 | for (x = 0; gfs2_old_multihost_formats[x]; x++) | ||
| 122 | if (gfs2_old_multihost_formats[x] == | ||
| 123 | sb->sb_multihost_format) | ||
| 124 | break; | ||
| 125 | |||
| 126 | if (!gfs2_old_multihost_formats[x]) { | ||
| 127 | printk(KERN_WARNING | ||
| 128 | "GFS2: code version (%u, %u) is incompatible " | ||
| 129 | "with ondisk format (%u, %u)\n", | ||
| 130 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | ||
| 131 | sb->sb_fs_format, sb->sb_multihost_format); | ||
| 132 | printk(KERN_WARNING | ||
| 133 | "GFS2: I don't know how to upgrade this FS\n"); | ||
| 134 | return -EINVAL; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | if (!sdp->sd_args.ar_upgrade) { | ||
| 139 | printk(KERN_WARNING | ||
| 140 | "GFS2: code version (%u, %u) is incompatible " | ||
| 141 | "with ondisk format (%u, %u)\n", | ||
| 142 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | ||
| 143 | sb->sb_fs_format, sb->sb_multihost_format); | ||
| 144 | printk(KERN_INFO | ||
| 145 | "GFS2: Use the \"upgrade\" mount option to upgrade " | ||
| 146 | "the FS\n"); | ||
| 147 | printk(KERN_INFO "GFS2: See the manual for more details\n"); | ||
| 148 | return -EINVAL; | ||
| 149 | } | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | static void end_bio_io_page(struct bio *bio, int error) | ||
| 156 | { | ||
| 157 | struct page *page = bio->bi_private; | ||
| 158 | |||
| 159 | if (!error) | ||
| 160 | SetPageUptodate(page); | ||
| 161 | else | ||
| 162 | printk(KERN_WARNING "gfs2: error %d reading superblock\n", error); | ||
| 163 | unlock_page(page); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | ||
| 167 | { | ||
| 168 | const struct gfs2_sb *str = buf; | ||
| 169 | |||
| 170 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); | ||
| 171 | sb->sb_type = be32_to_cpu(str->sb_header.mh_type); | ||
| 172 | sb->sb_format = be32_to_cpu(str->sb_header.mh_format); | ||
| 173 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); | ||
| 174 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); | ||
| 175 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); | ||
| 176 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); | ||
| 177 | sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); | ||
| 178 | sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); | ||
| 179 | sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); | ||
| 180 | sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); | ||
| 181 | |||
| 182 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | ||
| 183 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | ||
| 184 | } | ||
| 185 | |||
| 186 | /** | ||
| 187 | * gfs2_read_super - Read the gfs2 super block from disk | ||
| 188 | * @sdp: The GFS2 super block | ||
| 189 | * @sector: The location of the super block | ||
| 190 | * @error: The error code to return | ||
| 191 | * | ||
| 192 | * This uses the bio functions to read the super block from disk | ||
| 193 | * because we want to be 100% sure that we never read cached data. | ||
| 194 | * A super block is read twice only during each GFS2 mount and is | ||
| 195 | * never written to by the filesystem. The first time its read no | ||
| 196 | * locks are held, and the only details which are looked at are those | ||
| 197 | * relating to the locking protocol. Once locking is up and working, | ||
| 198 | * the sb is read again under the lock to establish the location of | ||
| 199 | * the master directory (contains pointers to journals etc) and the | ||
| 200 | * root directory. | ||
| 201 | * | ||
| 202 | * Returns: 0 on success or error | ||
| 203 | */ | ||
| 204 | |||
| 205 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | ||
| 206 | { | ||
| 207 | struct super_block *sb = sdp->sd_vfs; | ||
| 208 | struct gfs2_sb *p; | ||
| 209 | struct page *page; | ||
| 210 | struct bio *bio; | ||
| 211 | |||
| 212 | page = alloc_page(GFP_NOFS); | ||
| 213 | if (unlikely(!page)) | ||
| 214 | return -ENOBUFS; | ||
| 215 | |||
| 216 | ClearPageUptodate(page); | ||
| 217 | ClearPageDirty(page); | ||
| 218 | lock_page(page); | ||
| 219 | |||
| 220 | bio = bio_alloc(GFP_NOFS, 1); | ||
| 221 | if (unlikely(!bio)) { | ||
| 222 | __free_page(page); | ||
| 223 | return -ENOBUFS; | ||
| 224 | } | ||
| 225 | |||
| 226 | bio->bi_sector = sector * (sb->s_blocksize >> 9); | ||
| 227 | bio->bi_bdev = sb->s_bdev; | ||
| 228 | bio_add_page(bio, page, PAGE_SIZE, 0); | ||
| 229 | |||
| 230 | bio->bi_end_io = end_bio_io_page; | ||
| 231 | bio->bi_private = page; | ||
| 232 | submit_bio(READ_SYNC | (1 << BIO_RW_META), bio); | ||
| 233 | wait_on_page_locked(page); | ||
| 234 | bio_put(bio); | ||
| 235 | if (!PageUptodate(page)) { | ||
| 236 | __free_page(page); | ||
| 237 | return -EIO; | ||
| 238 | } | ||
| 239 | p = kmap(page); | ||
| 240 | gfs2_sb_in(&sdp->sd_sb, p); | ||
| 241 | kunmap(page); | ||
| 242 | __free_page(page); | ||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | /** | ||
| 247 | * gfs2_read_sb - Read super block | ||
| 248 | * @sdp: The GFS2 superblock | ||
| 249 | * @gl: the glock for the superblock (assumed to be held) | ||
| 250 | * @silent: Don't print message if mount fails | ||
| 251 | * | ||
| 252 | */ | ||
| 253 | |||
| 254 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) | ||
| 255 | { | ||
| 256 | u32 hash_blocks, ind_blocks, leaf_blocks; | ||
| 257 | u32 tmp_blocks; | ||
| 258 | unsigned int x; | ||
| 259 | int error; | ||
| 260 | |||
| 261 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | ||
| 262 | if (error) { | ||
| 263 | if (!silent) | ||
| 264 | fs_err(sdp, "can't read superblock\n"); | ||
| 265 | return error; | ||
| 266 | } | ||
| 267 | |||
| 268 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | ||
| 269 | if (error) | ||
| 270 | return error; | ||
| 271 | |||
| 272 | sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - | ||
| 273 | GFS2_BASIC_BLOCK_SHIFT; | ||
| 274 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; | ||
| 275 | sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - | ||
| 276 | sizeof(struct gfs2_dinode)) / sizeof(u64); | ||
| 277 | sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - | ||
| 278 | sizeof(struct gfs2_meta_header)) / sizeof(u64); | ||
| 279 | sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); | ||
| 280 | sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; | ||
| 281 | sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; | ||
| 282 | sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64); | ||
| 283 | sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - | ||
| 284 | sizeof(struct gfs2_meta_header)) / | ||
| 285 | sizeof(struct gfs2_quota_change); | ||
| 286 | |||
| 287 | /* Compute maximum reservation required to add a entry to a directory */ | ||
| 288 | |||
| 289 | hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH), | ||
| 290 | sdp->sd_jbsize); | ||
| 291 | |||
| 292 | ind_blocks = 0; | ||
| 293 | for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { | ||
| 294 | tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs); | ||
| 295 | ind_blocks += tmp_blocks; | ||
| 296 | } | ||
| 297 | |||
| 298 | leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH; | ||
| 299 | |||
| 300 | sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; | ||
| 301 | |||
| 302 | sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - | ||
| 303 | sizeof(struct gfs2_dinode); | ||
| 304 | sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; | ||
| 305 | for (x = 2;; x++) { | ||
| 306 | u64 space, d; | ||
| 307 | u32 m; | ||
| 308 | |||
| 309 | space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; | ||
| 310 | d = space; | ||
| 311 | m = do_div(d, sdp->sd_inptrs); | ||
| 312 | |||
| 313 | if (d != sdp->sd_heightsize[x - 1] || m) | ||
| 314 | break; | ||
| 315 | sdp->sd_heightsize[x] = space; | ||
| 316 | } | ||
| 317 | sdp->sd_max_height = x; | ||
| 318 | sdp->sd_heightsize[x] = ~0; | ||
| 319 | gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT); | ||
| 320 | |||
| 321 | sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - | ||
| 322 | sizeof(struct gfs2_dinode); | ||
| 323 | sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; | ||
| 324 | for (x = 2;; x++) { | ||
| 325 | u64 space, d; | ||
| 326 | u32 m; | ||
| 327 | |||
| 328 | space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; | ||
| 329 | d = space; | ||
| 330 | m = do_div(d, sdp->sd_inptrs); | ||
| 331 | |||
| 332 | if (d != sdp->sd_jheightsize[x - 1] || m) | ||
| 333 | break; | ||
| 334 | sdp->sd_jheightsize[x] = space; | ||
| 335 | } | ||
| 336 | sdp->sd_max_jheight = x; | ||
| 337 | sdp->sd_jheightsize[x] = ~0; | ||
| 338 | gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT); | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | 36 | /** |
| 344 | * gfs2_jindex_hold - Grab a lock on the jindex | 37 | * gfs2_jindex_hold - Grab a lock on the jindex |
| 345 | * @sdp: The GFS2 superblock | 38 | * @sdp: The GFS2 superblock |
| @@ -581,39 +274,6 @@ fail: | |||
| 581 | return error; | 274 | return error; |
| 582 | } | 275 | } |
| 583 | 276 | ||
| 584 | /** | ||
| 585 | * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one | ||
| 586 | * @sdp: the filesystem | ||
| 587 | * | ||
| 588 | * Returns: errno | ||
| 589 | */ | ||
| 590 | |||
| 591 | int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | ||
| 592 | { | ||
| 593 | struct gfs2_holder t_gh; | ||
| 594 | int error; | ||
| 595 | |||
| 596 | gfs2_quota_sync(sdp); | ||
| 597 | gfs2_statfs_sync(sdp); | ||
| 598 | |||
| 599 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | ||
| 600 | &t_gh); | ||
| 601 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
| 602 | return error; | ||
| 603 | |||
| 604 | gfs2_meta_syncfs(sdp); | ||
| 605 | gfs2_log_shutdown(sdp); | ||
| 606 | |||
| 607 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
| 608 | |||
| 609 | if (t_gh.gh_gl) | ||
| 610 | gfs2_glock_dq_uninit(&t_gh); | ||
| 611 | |||
| 612 | gfs2_quota_cleanup(sdp); | ||
| 613 | |||
| 614 | return error; | ||
| 615 | } | ||
| 616 | |||
| 617 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) | 277 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) |
| 618 | { | 278 | { |
| 619 | const struct gfs2_statfs_change *str = buf; | 279 | const struct gfs2_statfs_change *str = buf; |
