diff options
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r-- | fs/gfs2/super.c | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index faccffd19907..f916b9740c75 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -95,8 +95,8 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) | |||
95 | { | 95 | { |
96 | unsigned int x; | 96 | unsigned int x; |
97 | 97 | ||
98 | if (sb->sb_header.mh_magic != GFS2_MAGIC || | 98 | if (sb->sb_magic != GFS2_MAGIC || |
99 | sb->sb_header.mh_type != GFS2_METATYPE_SB) { | 99 | sb->sb_type != GFS2_METATYPE_SB) { |
100 | if (!silent) | 100 | if (!silent) |
101 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); | 101 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); |
102 | return -EINVAL; | 102 | return -EINVAL; |
@@ -174,10 +174,31 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
177 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | ||
178 | { | ||
179 | const struct gfs2_sb *str = buf; | ||
180 | |||
181 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); | ||
182 | sb->sb_type = be32_to_cpu(str->sb_header.mh_type); | ||
183 | sb->sb_format = be32_to_cpu(str->sb_header.mh_format); | ||
184 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); | ||
185 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); | ||
186 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); | ||
187 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); | ||
188 | sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); | ||
189 | sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); | ||
190 | sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); | ||
191 | sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); | ||
192 | |||
193 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | ||
194 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | ||
195 | } | ||
196 | |||
177 | /** | 197 | /** |
178 | * gfs2_read_super - Read the gfs2 super block from disk | 198 | * gfs2_read_super - Read the gfs2 super block from disk |
179 | * @sb: The VFS super block | 199 | * @sdp: The GFS2 super block |
180 | * @sector: The location of the super block | 200 | * @sector: The location of the super block |
201 | * @error: The error code to return | ||
181 | * | 202 | * |
182 | * This uses the bio functions to read the super block from disk | 203 | * This uses the bio functions to read the super block from disk |
183 | * because we want to be 100% sure that we never read cached data. | 204 | * because we want to be 100% sure that we never read cached data. |
@@ -189,17 +210,19 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
189 | * the master directory (contains pointers to journals etc) and the | 210 | * the master directory (contains pointers to journals etc) and the |
190 | * root directory. | 211 | * root directory. |
191 | * | 212 | * |
192 | * Returns: A page containing the sb or NULL | 213 | * Returns: 0 on success or error |
193 | */ | 214 | */ |
194 | 215 | ||
195 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | 216 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) |
196 | { | 217 | { |
218 | struct super_block *sb = sdp->sd_vfs; | ||
219 | struct gfs2_sb *p; | ||
197 | struct page *page; | 220 | struct page *page; |
198 | struct bio *bio; | 221 | struct bio *bio; |
199 | 222 | ||
200 | page = alloc_page(GFP_KERNEL); | 223 | page = alloc_page(GFP_KERNEL); |
201 | if (unlikely(!page)) | 224 | if (unlikely(!page)) |
202 | return NULL; | 225 | return -ENOBUFS; |
203 | 226 | ||
204 | ClearPageUptodate(page); | 227 | ClearPageUptodate(page); |
205 | ClearPageDirty(page); | 228 | ClearPageDirty(page); |
@@ -208,7 +231,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
208 | bio = bio_alloc(GFP_KERNEL, 1); | 231 | bio = bio_alloc(GFP_KERNEL, 1); |
209 | if (unlikely(!bio)) { | 232 | if (unlikely(!bio)) { |
210 | __free_page(page); | 233 | __free_page(page); |
211 | return NULL; | 234 | return -ENOBUFS; |
212 | } | 235 | } |
213 | 236 | ||
214 | bio->bi_sector = sector * (sb->s_blocksize >> 9); | 237 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
@@ -222,9 +245,13 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
222 | bio_put(bio); | 245 | bio_put(bio); |
223 | if (!PageUptodate(page)) { | 246 | if (!PageUptodate(page)) { |
224 | __free_page(page); | 247 | __free_page(page); |
225 | return NULL; | 248 | return -EIO; |
226 | } | 249 | } |
227 | return page; | 250 | p = kmap(page); |
251 | gfs2_sb_in(&sdp->sd_sb, p); | ||
252 | kunmap(page); | ||
253 | __free_page(page); | ||
254 | return 0; | ||
228 | } | 255 | } |
229 | 256 | ||
230 | /** | 257 | /** |
@@ -241,19 +268,13 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) | |||
241 | u32 tmp_blocks; | 268 | u32 tmp_blocks; |
242 | unsigned int x; | 269 | unsigned int x; |
243 | int error; | 270 | int error; |
244 | struct page *page; | ||
245 | char *sb; | ||
246 | 271 | ||
247 | page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 272 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); |
248 | if (!page) { | 273 | if (error) { |
249 | if (!silent) | 274 | if (!silent) |
250 | fs_err(sdp, "can't read superblock\n"); | 275 | fs_err(sdp, "can't read superblock\n"); |
251 | return -EIO; | 276 | return error; |
252 | } | 277 | } |
253 | sb = kmap(page); | ||
254 | gfs2_sb_in(&sdp->sd_sb, sb); | ||
255 | kunmap(page); | ||
256 | __free_page(page); | ||
257 | 278 | ||
258 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | 279 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); |
259 | if (error) | 280 | if (error) |
@@ -593,6 +614,24 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
593 | return error; | 614 | return error; |
594 | } | 615 | } |
595 | 616 | ||
617 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) | ||
618 | { | ||
619 | const struct gfs2_statfs_change *str = buf; | ||
620 | |||
621 | sc->sc_total = be64_to_cpu(str->sc_total); | ||
622 | sc->sc_free = be64_to_cpu(str->sc_free); | ||
623 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | ||
624 | } | ||
625 | |||
626 | static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) | ||
627 | { | ||
628 | struct gfs2_statfs_change *str = buf; | ||
629 | |||
630 | str->sc_total = cpu_to_be64(sc->sc_total); | ||
631 | str->sc_free = cpu_to_be64(sc->sc_free); | ||
632 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | ||
633 | } | ||
634 | |||
596 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 635 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
597 | { | 636 | { |
598 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 637 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
@@ -772,7 +811,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | |||
772 | struct gfs2_statfs_change_host *sc) | 811 | struct gfs2_statfs_change_host *sc) |
773 | { | 812 | { |
774 | gfs2_rgrp_verify(rgd); | 813 | gfs2_rgrp_verify(rgd); |
775 | sc->sc_total += rgd->rd_ri.ri_data; | 814 | sc->sc_total += rgd->rd_data; |
776 | sc->sc_free += rgd->rd_rg.rg_free; | 815 | sc->sc_free += rgd->rd_rg.rg_free; |
777 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; | 816 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; |
778 | return 0; | 817 | return 0; |