recovery.c (d9a145fb6e5f37b9903dea8371ab5c3e34e8e2d1) | recovery.c (155130a4f7848b1aac439cab6bda1a175507c71c) |
---|---|
1/* 2 * recovery.c - NILFS recovery logic 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 77 unchanged lines hidden (view full) --- 86 case NILFS_SEG_NO_SUPER_ROOT: 87 printk(KERN_WARNING 88 "NILFS warning: No super root in the last segment\n"); 89 break; 90 } 91 return -EINVAL; 92} 93 | 1/* 2 * recovery.c - NILFS recovery logic 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 77 unchanged lines hidden (view full) --- 86 case NILFS_SEG_NO_SUPER_ROOT: 87 printk(KERN_WARNING 88 "NILFS warning: No super root in the last segment\n"); 89 break; 90 } 91 return -EINVAL; 92} 93 |
94static void store_segsum_info(struct nilfs_segsum_info *ssi, 95 struct nilfs_segment_summary *sum, 96 unsigned int blocksize) 97{ 98 ssi->flags = le16_to_cpu(sum->ss_flags); 99 ssi->seg_seq = le64_to_cpu(sum->ss_seq); 100 ssi->ctime = le64_to_cpu(sum->ss_create); 101 ssi->next = le64_to_cpu(sum->ss_next); 102 ssi->nblocks = le32_to_cpu(sum->ss_nblocks); 103 ssi->nfinfo = le32_to_cpu(sum->ss_nfinfo); 104 ssi->sumbytes = le32_to_cpu(sum->ss_sumbytes); 105 106 ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize); 107 ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi); 108 109 /* need to verify ->ss_bytes field if read ->ss_cno */ 110} 111 |
|
94/** | 112/** |
95 * nilfs_compute_checksum - compute checksum of blocks continuously 96 * @nilfs: nilfs object | 113 * calc_crc_cont - check CRC of blocks continuously 114 * @sbi: nilfs_sb_info |
97 * @bhs: buffer head of start block 98 * @sum: place to store result 99 * @offset: offset bytes in the first block 100 * @check_bytes: number of bytes to be checked 101 * @start: DBN of start block 102 * @nblock: number of blocks to be checked 103 */ | 115 * @bhs: buffer head of start block 116 * @sum: place to store result 117 * @offset: offset bytes in the first block 118 * @check_bytes: number of bytes to be checked 119 * @start: DBN of start block 120 * @nblock: number of blocks to be checked 121 */ |
104static int nilfs_compute_checksum(struct the_nilfs *nilfs, 105 struct buffer_head *bhs, u32 *sum, 106 unsigned long offset, u64 check_bytes, 107 sector_t start, unsigned long nblock) | 122static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs, 123 u32 *sum, unsigned long offset, u64 check_bytes, 124 sector_t start, unsigned long nblock) |
108{ | 125{ |
109 unsigned int blocksize = nilfs->ns_blocksize; | 126 unsigned long blocksize = sbi->s_super->s_blocksize; |
110 unsigned long size; 111 u32 crc; 112 113 BUG_ON(offset >= blocksize); 114 check_bytes -= offset; 115 size = min_t(u64, check_bytes, blocksize - offset); | 127 unsigned long size; 128 u32 crc; 129 130 BUG_ON(offset >= blocksize); 131 check_bytes -= offset; 132 size = min_t(u64, check_bytes, blocksize - offset); |
116 crc = crc32_le(nilfs->ns_crc_seed, | 133 crc = crc32_le(sbi->s_nilfs->ns_crc_seed, |
117 (unsigned char *)bhs->b_data + offset, size); 118 if (--nblock > 0) { 119 do { | 134 (unsigned char *)bhs->b_data + offset, size); 135 if (--nblock > 0) { 136 do { |
120 struct buffer_head *bh; 121 122 bh = __bread(nilfs->ns_bdev, ++start, blocksize); | 137 struct buffer_head *bh 138 = sb_bread(sbi->s_super, ++start); |
123 if (!bh) 124 return -EIO; 125 check_bytes -= size; 126 size = min_t(u64, check_bytes, blocksize); 127 crc = crc32_le(crc, bh->b_data, size); 128 brelse(bh); 129 } while (--nblock > 0); 130 } 131 *sum = crc; 132 return 0; 133} 134 135/** 136 * nilfs_read_super_root_block - read super root block | 139 if (!bh) 140 return -EIO; 141 check_bytes -= size; 142 size = min_t(u64, check_bytes, blocksize); 143 crc = crc32_le(crc, bh->b_data, size); 144 brelse(bh); 145 } while (--nblock > 0); 146 } 147 *sum = crc; 148 return 0; 149} 150 151/** 152 * nilfs_read_super_root_block - read super root block |
137 * @nilfs: nilfs object | 153 * @sb: super_block |
138 * @sr_block: disk block number of the super root block 139 * @pbh: address of a buffer_head pointer to return super root buffer 140 * @check: CRC check flag 141 */ | 154 * @sr_block: disk block number of the super root block 155 * @pbh: address of a buffer_head pointer to return super root buffer 156 * @check: CRC check flag 157 */ |
142int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block, | 158int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block, |
143 struct buffer_head **pbh, int check) 144{ 145 struct buffer_head *bh_sr; 146 struct nilfs_super_root *sr; 147 u32 crc; 148 int ret; 149 150 *pbh = NULL; | 159 struct buffer_head **pbh, int check) 160{ 161 struct buffer_head *bh_sr; 162 struct nilfs_super_root *sr; 163 u32 crc; 164 int ret; 165 166 *pbh = NULL; |
151 bh_sr = __bread(nilfs->ns_bdev, sr_block, nilfs->ns_blocksize); | 167 bh_sr = sb_bread(sb, sr_block); |
152 if (unlikely(!bh_sr)) { 153 ret = NILFS_SEG_FAIL_IO; 154 goto failed; 155 } 156 157 sr = (struct nilfs_super_root *)bh_sr->b_data; 158 if (check) { 159 unsigned bytes = le16_to_cpu(sr->sr_bytes); 160 | 168 if (unlikely(!bh_sr)) { 169 ret = NILFS_SEG_FAIL_IO; 170 goto failed; 171 } 172 173 sr = (struct nilfs_super_root *)bh_sr->b_data; 174 if (check) { 175 unsigned bytes = le16_to_cpu(sr->sr_bytes); 176 |
161 if (bytes == 0 || bytes > nilfs->ns_blocksize) { | 177 if (bytes == 0 || bytes > sb->s_blocksize) { |
162 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 163 goto failed_bh; 164 } | 178 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 179 goto failed_bh; 180 } |
165 if (nilfs_compute_checksum( 166 nilfs, bh_sr, &crc, sizeof(sr->sr_sum), bytes, 167 sr_block, 1)) { | 181 if (calc_crc_cont(NILFS_SB(sb), bh_sr, &crc, 182 sizeof(sr->sr_sum), bytes, sr_block, 1)) { |
168 ret = NILFS_SEG_FAIL_IO; 169 goto failed_bh; 170 } 171 if (crc != le32_to_cpu(sr->sr_sum)) { 172 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 173 goto failed_bh; 174 } 175 } 176 *pbh = bh_sr; 177 return 0; 178 179 failed_bh: 180 brelse(bh_sr); 181 182 failed: 183 return nilfs_warn_segment_error(ret); 184} 185 186/** | 183 ret = NILFS_SEG_FAIL_IO; 184 goto failed_bh; 185 } 186 if (crc != le32_to_cpu(sr->sr_sum)) { 187 ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; 188 goto failed_bh; 189 } 190 } 191 *pbh = bh_sr; 192 return 0; 193 194 failed_bh: 195 brelse(bh_sr); 196 197 failed: 198 return nilfs_warn_segment_error(ret); 199} 200 201/** |
187 * nilfs_read_log_header - read summary header of the specified log 188 * @nilfs: nilfs object 189 * @start_blocknr: start block number of the log 190 * @sum: pointer to return segment summary structure | 202 * load_segment_summary - read segment summary of the specified partial segment 203 * @sbi: nilfs_sb_info 204 * @pseg_start: start disk block number of partial segment 205 * @seg_seq: sequence number requested 206 * @ssi: pointer to nilfs_segsum_info struct to store information |
191 */ | 207 */ |
192static struct buffer_head * 193nilfs_read_log_header(struct the_nilfs *nilfs, sector_t start_blocknr, 194 struct nilfs_segment_summary **sum) | 208static int 209load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start, 210 u64 seg_seq, struct nilfs_segsum_info *ssi) |
195{ 196 struct buffer_head *bh_sum; | 211{ 212 struct buffer_head *bh_sum; |
197 198 bh_sum = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); 199 if (bh_sum) 200 *sum = (struct nilfs_segment_summary *)bh_sum->b_data; 201 return bh_sum; 202} 203 204/** 205 * nilfs_validate_log - verify consistency of log 206 * @nilfs: nilfs object 207 * @seg_seq: sequence number of segment 208 * @bh_sum: buffer head of summary block 209 * @sum: segment summary struct 210 */ 211static int nilfs_validate_log(struct the_nilfs *nilfs, u64 seg_seq, 212 struct buffer_head *bh_sum, 213 struct nilfs_segment_summary *sum) 214{ | 213 struct nilfs_segment_summary *sum; |
215 unsigned long nblock; 216 u32 crc; | 214 unsigned long nblock; 215 u32 crc; |
217 int ret; | 216 int ret = NILFS_SEG_FAIL_IO; |
218 | 217 |
219 ret = NILFS_SEG_FAIL_MAGIC; 220 if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) | 218 bh_sum = sb_bread(sbi->s_super, pseg_start); 219 if (!bh_sum) |
221 goto out; 222 | 220 goto out; 221 |
223 ret = NILFS_SEG_FAIL_SEQ; 224 if (le64_to_cpu(sum->ss_seq) != seg_seq) 225 goto out; | 222 sum = (struct nilfs_segment_summary *)bh_sum->b_data; |
226 | 223 |
227 nblock = le32_to_cpu(sum->ss_nblocks); 228 ret = NILFS_SEG_FAIL_CONSISTENCY; 229 if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment)) 230 /* This limits the number of blocks read in the CRC check */ 231 goto out; | 224 /* Check consistency of segment summary */ 225 if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) { 226 ret = NILFS_SEG_FAIL_MAGIC; 227 goto failed; 228 } 229 store_segsum_info(ssi, sum, sbi->s_super->s_blocksize); 230 if (seg_seq != ssi->seg_seq) { 231 ret = NILFS_SEG_FAIL_SEQ; 232 goto failed; 233 } |
232 | 234 |
233 ret = NILFS_SEG_FAIL_IO; 234 if (nilfs_compute_checksum(nilfs, bh_sum, &crc, sizeof(sum->ss_datasum), 235 ((u64)nblock << nilfs->ns_blocksize_bits), 236 bh_sum->b_blocknr, nblock)) 237 goto out; 238 239 ret = NILFS_SEG_FAIL_CHECKSUM_FULL; 240 if (crc != le32_to_cpu(sum->ss_datasum)) 241 goto out; 242 ret = 0; 243out: | 235 nblock = ssi->nblocks; 236 if (unlikely(nblock == 0 || 237 nblock > sbi->s_nilfs->ns_blocks_per_segment)) { 238 /* This limits the number of blocks read in the CRC check */ 239 ret = NILFS_SEG_FAIL_CONSISTENCY; 240 goto failed; 241 } 242 if (calc_crc_cont(sbi, bh_sum, &crc, sizeof(sum->ss_datasum), 243 ((u64)nblock << sbi->s_super->s_blocksize_bits), 244 pseg_start, nblock)) { 245 ret = NILFS_SEG_FAIL_IO; 246 goto failed; 247 } 248 if (crc == le32_to_cpu(sum->ss_datasum)) 249 ret = 0; 250 else 251 ret = NILFS_SEG_FAIL_CHECKSUM_FULL; 252 failed: 253 brelse(bh_sum); 254 out: |
244 return ret; 245} 246 | 255 return ret; 256} 257 |
247/** 248 * nilfs_read_summary_info - read an item on summary blocks of a log 249 * @nilfs: nilfs object 250 * @pbh: the current buffer head on summary blocks [in, out] 251 * @offset: the current byte offset on summary blocks [in, out] 252 * @bytes: byte size of the item to be read 253 */ 254static void *nilfs_read_summary_info(struct the_nilfs *nilfs, 255 struct buffer_head **pbh, 256 unsigned int *offset, unsigned int bytes) | 258static void *segsum_get(struct super_block *sb, struct buffer_head **pbh, 259 unsigned int *offset, unsigned int bytes) |
257{ 258 void *ptr; 259 sector_t blocknr; 260 261 BUG_ON((*pbh)->b_size < *offset); 262 if (bytes > (*pbh)->b_size - *offset) { 263 blocknr = (*pbh)->b_blocknr; 264 brelse(*pbh); | 260{ 261 void *ptr; 262 sector_t blocknr; 263 264 BUG_ON((*pbh)->b_size < *offset); 265 if (bytes > (*pbh)->b_size - *offset) { 266 blocknr = (*pbh)->b_blocknr; 267 brelse(*pbh); |
265 *pbh = __bread(nilfs->ns_bdev, blocknr + 1, 266 nilfs->ns_blocksize); | 268 *pbh = sb_bread(sb, blocknr + 1); |
267 if (unlikely(!*pbh)) 268 return NULL; 269 *offset = 0; 270 } 271 ptr = (*pbh)->b_data + *offset; 272 *offset += bytes; 273 return ptr; 274} 275 | 269 if (unlikely(!*pbh)) 270 return NULL; 271 *offset = 0; 272 } 273 ptr = (*pbh)->b_data + *offset; 274 *offset += bytes; 275 return ptr; 276} 277 |
276/** 277 * nilfs_skip_summary_info - skip items on summary blocks of a log 278 * @nilfs: nilfs object 279 * @pbh: the current buffer head on summary blocks [in, out] 280 * @offset: the current byte offset on summary blocks [in, out] 281 * @bytes: byte size of the item to be skipped 282 * @count: number of items to be skipped 283 */ 284static void nilfs_skip_summary_info(struct the_nilfs *nilfs, 285 struct buffer_head **pbh, 286 unsigned int *offset, unsigned int bytes, 287 unsigned long count) | 278static void segsum_skip(struct super_block *sb, struct buffer_head **pbh, 279 unsigned int *offset, unsigned int bytes, 280 unsigned long count) |
288{ 289 unsigned int rest_item_in_current_block 290 = ((*pbh)->b_size - *offset) / bytes; 291 292 if (count <= rest_item_in_current_block) { 293 *offset += bytes * count; 294 } else { 295 sector_t blocknr = (*pbh)->b_blocknr; 296 unsigned int nitem_per_block = (*pbh)->b_size / bytes; 297 unsigned int bcnt; 298 299 count -= rest_item_in_current_block; 300 bcnt = DIV_ROUND_UP(count, nitem_per_block); 301 *offset = bytes * (count - (bcnt - 1) * nitem_per_block); 302 303 brelse(*pbh); | 281{ 282 unsigned int rest_item_in_current_block 283 = ((*pbh)->b_size - *offset) / bytes; 284 285 if (count <= rest_item_in_current_block) { 286 *offset += bytes * count; 287 } else { 288 sector_t blocknr = (*pbh)->b_blocknr; 289 unsigned int nitem_per_block = (*pbh)->b_size / bytes; 290 unsigned int bcnt; 291 292 count -= rest_item_in_current_block; 293 bcnt = DIV_ROUND_UP(count, nitem_per_block); 294 *offset = bytes * (count - (bcnt - 1) * nitem_per_block); 295 296 brelse(*pbh); |
304 *pbh = __bread(nilfs->ns_bdev, blocknr + bcnt, 305 nilfs->ns_blocksize); | 297 *pbh = sb_bread(sb, blocknr + bcnt); |
306 } 307} 308 | 298 } 299} 300 |
309/** 310 * nilfs_scan_dsync_log - get block information of a log written for data sync 311 * @nilfs: nilfs object 312 * @start_blocknr: start block number of the log 313 * @sum: log summary information 314 * @head: list head to add nilfs_recovery_block struct 315 */ 316static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, 317 struct nilfs_segment_summary *sum, 318 struct list_head *head) | 301static int 302collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr, 303 struct nilfs_segsum_info *ssi, 304 struct list_head *head) |
319{ 320 struct buffer_head *bh; 321 unsigned int offset; | 305{ 306 struct buffer_head *bh; 307 unsigned int offset; |
322 u32 nfinfo, sumbytes; 323 sector_t blocknr; | 308 unsigned long nfinfo = ssi->nfinfo; 309 sector_t blocknr = sum_blocknr + ssi->nsumblk; |
324 ino_t ino; 325 int err = -EIO; 326 | 310 ino_t ino; 311 int err = -EIO; 312 |
327 nfinfo = le32_to_cpu(sum->ss_nfinfo); | |
328 if (!nfinfo) 329 return 0; 330 | 313 if (!nfinfo) 314 return 0; 315 |
331 sumbytes = le32_to_cpu(sum->ss_sumbytes); 332 blocknr = start_blocknr + DIV_ROUND_UP(sumbytes, nilfs->ns_blocksize); 333 bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); | 316 bh = sb_bread(sbi->s_super, sum_blocknr); |
334 if (unlikely(!bh)) 335 goto out; 336 | 317 if (unlikely(!bh)) 318 goto out; 319 |
337 offset = le16_to_cpu(sum->ss_bytes); | 320 offset = le16_to_cpu( 321 ((struct nilfs_segment_summary *)bh->b_data)->ss_bytes); |
338 for (;;) { 339 unsigned long nblocks, ndatablk, nnodeblk; 340 struct nilfs_finfo *finfo; 341 | 322 for (;;) { 323 unsigned long nblocks, ndatablk, nnodeblk; 324 struct nilfs_finfo *finfo; 325 |
342 finfo = nilfs_read_summary_info(nilfs, &bh, &offset, 343 sizeof(*finfo)); | 326 finfo = segsum_get(sbi->s_super, &bh, &offset, sizeof(*finfo)); |
344 if (unlikely(!finfo)) 345 goto out; 346 347 ino = le64_to_cpu(finfo->fi_ino); 348 nblocks = le32_to_cpu(finfo->fi_nblocks); 349 ndatablk = le32_to_cpu(finfo->fi_ndatablk); 350 nnodeblk = nblocks - ndatablk; 351 352 while (ndatablk-- > 0) { 353 struct nilfs_recovery_block *rb; 354 struct nilfs_binfo_v *binfo; 355 | 327 if (unlikely(!finfo)) 328 goto out; 329 330 ino = le64_to_cpu(finfo->fi_ino); 331 nblocks = le32_to_cpu(finfo->fi_nblocks); 332 ndatablk = le32_to_cpu(finfo->fi_ndatablk); 333 nnodeblk = nblocks - ndatablk; 334 335 while (ndatablk-- > 0) { 336 struct nilfs_recovery_block *rb; 337 struct nilfs_binfo_v *binfo; 338 |
356 binfo = nilfs_read_summary_info(nilfs, &bh, &offset, 357 sizeof(*binfo)); | 339 binfo = segsum_get(sbi->s_super, &bh, &offset, 340 sizeof(*binfo)); |
358 if (unlikely(!binfo)) 359 goto out; 360 361 rb = kmalloc(sizeof(*rb), GFP_NOFS); 362 if (unlikely(!rb)) { 363 err = -ENOMEM; 364 goto out; 365 } 366 rb->ino = ino; 367 rb->blocknr = blocknr++; 368 rb->vblocknr = le64_to_cpu(binfo->bi_vblocknr); 369 rb->blkoff = le64_to_cpu(binfo->bi_blkoff); 370 /* INIT_LIST_HEAD(&rb->list); */ 371 list_add_tail(&rb->list, head); 372 } 373 if (--nfinfo == 0) 374 break; | 341 if (unlikely(!binfo)) 342 goto out; 343 344 rb = kmalloc(sizeof(*rb), GFP_NOFS); 345 if (unlikely(!rb)) { 346 err = -ENOMEM; 347 goto out; 348 } 349 rb->ino = ino; 350 rb->blocknr = blocknr++; 351 rb->vblocknr = le64_to_cpu(binfo->bi_vblocknr); 352 rb->blkoff = le64_to_cpu(binfo->bi_blkoff); 353 /* INIT_LIST_HEAD(&rb->list); */ 354 list_add_tail(&rb->list, head); 355 } 356 if (--nfinfo == 0) 357 break; |
375 blocknr += nnodeblk; /* always 0 for data sync logs */ 376 nilfs_skip_summary_info(nilfs, &bh, &offset, sizeof(__le64), 377 nnodeblk); | 358 blocknr += nnodeblk; /* always 0 for the data sync segments */ 359 segsum_skip(sbi->s_super, &bh, &offset, sizeof(__le64), 360 nnodeblk); |
378 if (unlikely(!bh)) 379 goto out; 380 } 381 err = 0; 382 out: 383 brelse(bh); /* brelse(NULL) is just ignored */ 384 return err; 385} --- 93 unchanged lines hidden (view full) --- 479 nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; 480 481 failed: 482 /* No need to recover sufile because it will be destroyed on error */ 483 nilfs_detach_writer(nilfs, sbi); 484 return err; 485} 486 | 361 if (unlikely(!bh)) 362 goto out; 363 } 364 err = 0; 365 out: 366 brelse(bh); /* brelse(NULL) is just ignored */ 367 return err; 368} --- 93 unchanged lines hidden (view full) --- 462 nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; 463 464 failed: 465 /* No need to recover sufile because it will be destroyed on error */ 466 nilfs_detach_writer(nilfs, sbi); 467 return err; 468} 469 |
487static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, | 470static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi, |
488 struct nilfs_recovery_block *rb, 489 struct page *page) 490{ 491 struct buffer_head *bh_org; 492 void *kaddr; 493 | 471 struct nilfs_recovery_block *rb, 472 struct page *page) 473{ 474 struct buffer_head *bh_org; 475 void *kaddr; 476 |
494 bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize); | 477 bh_org = sb_bread(sbi->s_super, rb->blocknr); |
495 if (unlikely(!bh_org)) 496 return -EIO; 497 498 kaddr = kmap_atomic(page, KM_USER0); 499 memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size); 500 kunmap_atomic(kaddr, KM_USER0); 501 brelse(bh_org); 502 return 0; 503} 504 | 478 if (unlikely(!bh_org)) 479 return -EIO; 480 481 kaddr = kmap_atomic(page, KM_USER0); 482 memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size); 483 kunmap_atomic(kaddr, KM_USER0); 484 brelse(bh_org); 485 return 0; 486} 487 |
505static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, 506 struct nilfs_sb_info *sbi, 507 struct list_head *head, 508 unsigned long *nr_salvaged_blocks) | 488static int recover_dsync_blocks(struct nilfs_sb_info *sbi, 489 struct list_head *head, 490 unsigned long *nr_salvaged_blocks) |
509{ 510 struct inode *inode; 511 struct nilfs_recovery_block *rb, *n; | 491{ 492 struct inode *inode; 493 struct nilfs_recovery_block *rb, *n; |
512 unsigned blocksize = nilfs->ns_blocksize; | 494 unsigned blocksize = sbi->s_super->s_blocksize; |
513 struct page *page; 514 loff_t pos; 515 int err = 0, err2 = 0; 516 517 list_for_each_entry_safe(rb, n, head, list) { 518 inode = nilfs_iget(sbi->s_super, rb->ino); 519 if (IS_ERR(inode)) { 520 err = PTR_ERR(inode); 521 inode = NULL; 522 goto failed_inode; 523 } 524 525 pos = rb->blkoff << inode->i_blkbits; | 495 struct page *page; 496 loff_t pos; 497 int err = 0, err2 = 0; 498 499 list_for_each_entry_safe(rb, n, head, list) { 500 inode = nilfs_iget(sbi->s_super, rb->ino); 501 if (IS_ERR(inode)) { 502 err = PTR_ERR(inode); 503 inode = NULL; 504 goto failed_inode; 505 } 506 507 pos = rb->blkoff << inode->i_blkbits; |
526 page = NULL; 527 err = block_write_begin(NULL, inode->i_mapping, pos, blocksize, 528 0, &page, NULL, nilfs_get_block); 529 if (unlikely(err)) | 508 err = block_write_begin(inode->i_mapping, pos, blocksize, 509 0, &page, nilfs_get_block); 510 if (unlikely(err)) { 511 loff_t isize = inode->i_size; 512 if (pos + blocksize > isize) 513 vmtruncate(inode, isize); |
530 goto failed_inode; | 514 goto failed_inode; |
515 } |
|
531 | 516 |
532 err = nilfs_recovery_copy_block(nilfs, rb, page); | 517 err = nilfs_recovery_copy_block(sbi, rb, page); |
533 if (unlikely(err)) 534 goto failed_page; 535 536 err = nilfs_set_file_dirty(sbi, inode, 1); 537 if (unlikely(err)) 538 goto failed_page; 539 540 block_write_end(NULL, inode->i_mapping, pos, blocksize, --- 23 unchanged lines hidden (view full) --- 564 kfree(rb); 565 } 566 return err2; 567} 568 569/** 570 * nilfs_do_roll_forward - salvage logical segments newer than the latest 571 * checkpoint | 518 if (unlikely(err)) 519 goto failed_page; 520 521 err = nilfs_set_file_dirty(sbi, inode, 1); 522 if (unlikely(err)) 523 goto failed_page; 524 525 block_write_end(NULL, inode->i_mapping, pos, blocksize, --- 23 unchanged lines hidden (view full) --- 549 kfree(rb); 550 } 551 return err2; 552} 553 554/** 555 * nilfs_do_roll_forward - salvage logical segments newer than the latest 556 * checkpoint |
572 * @nilfs: nilfs object | |
573 * @sbi: nilfs_sb_info | 557 * @sbi: nilfs_sb_info |
558 * @nilfs: the_nilfs |
|
574 * @ri: pointer to a nilfs_recovery_info 575 */ 576static int nilfs_do_roll_forward(struct the_nilfs *nilfs, 577 struct nilfs_sb_info *sbi, 578 struct nilfs_recovery_info *ri) 579{ | 559 * @ri: pointer to a nilfs_recovery_info 560 */ 561static int nilfs_do_roll_forward(struct the_nilfs *nilfs, 562 struct nilfs_sb_info *sbi, 563 struct nilfs_recovery_info *ri) 564{ |
580 struct buffer_head *bh_sum = NULL; 581 struct nilfs_segment_summary *sum; | 565 struct nilfs_segsum_info ssi; |
582 sector_t pseg_start; 583 sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */ 584 unsigned long nsalvaged_blocks = 0; | 566 sector_t pseg_start; 567 sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */ 568 unsigned long nsalvaged_blocks = 0; |
585 unsigned int flags; | |
586 u64 seg_seq; 587 __u64 segnum, nextnum = 0; 588 int empty_seg = 0; 589 int err = 0, ret; 590 LIST_HEAD(dsync_blocks); /* list of data blocks to be recovered */ 591 enum { 592 RF_INIT_ST, 593 RF_DSYNC_ST, /* scanning data-sync segments */ 594 }; 595 int state = RF_INIT_ST; 596 597 nilfs_attach_writer(nilfs, sbi); 598 pseg_start = ri->ri_lsegs_start; 599 seg_seq = ri->ri_lsegs_start_seq; 600 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 601 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 602 603 while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) { | 569 u64 seg_seq; 570 __u64 segnum, nextnum = 0; 571 int empty_seg = 0; 572 int err = 0, ret; 573 LIST_HEAD(dsync_blocks); /* list of data blocks to be recovered */ 574 enum { 575 RF_INIT_ST, 576 RF_DSYNC_ST, /* scanning data-sync segments */ 577 }; 578 int state = RF_INIT_ST; 579 580 nilfs_attach_writer(nilfs, sbi); 581 pseg_start = ri->ri_lsegs_start; 582 seg_seq = ri->ri_lsegs_start_seq; 583 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 584 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 585 586 while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) { |
604 brelse(bh_sum); 605 bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); 606 if (!bh_sum) { 607 err = -EIO; 608 goto failed; 609 } | |
610 | 587 |
611 ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); | 588 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi); |
612 if (ret) { 613 if (ret == NILFS_SEG_FAIL_IO) { 614 err = -EIO; 615 goto failed; 616 } 617 goto strayed; 618 } | 589 if (ret) { 590 if (ret == NILFS_SEG_FAIL_IO) { 591 err = -EIO; 592 goto failed; 593 } 594 goto strayed; 595 } |
619 620 flags = le16_to_cpu(sum->ss_flags); 621 if (flags & NILFS_SS_SR) | 596 if (unlikely(NILFS_SEG_HAS_SR(&ssi))) |
622 goto confused; 623 624 /* Found a valid partial segment; do recovery actions */ | 597 goto confused; 598 599 /* Found a valid partial segment; do recovery actions */ |
625 nextnum = nilfs_get_segnum_of_block(nilfs, 626 le64_to_cpu(sum->ss_next)); | 600 nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); |
627 empty_seg = 0; | 601 empty_seg = 0; |
628 nilfs->ns_ctime = le64_to_cpu(sum->ss_create); 629 if (!(flags & NILFS_SS_GC)) 630 nilfs->ns_nongc_ctime = nilfs->ns_ctime; | 602 nilfs->ns_ctime = ssi.ctime; 603 if (!(ssi.flags & NILFS_SS_GC)) 604 nilfs->ns_nongc_ctime = ssi.ctime; |
631 632 switch (state) { 633 case RF_INIT_ST: | 605 606 switch (state) { 607 case RF_INIT_ST: |
634 if (!(flags & NILFS_SS_LOGBGN) || 635 !(flags & NILFS_SS_SYNDT)) | 608 if (!NILFS_SEG_LOGBGN(&ssi) || !NILFS_SEG_DSYNC(&ssi)) |
636 goto try_next_pseg; 637 state = RF_DSYNC_ST; 638 /* Fall through */ 639 case RF_DSYNC_ST: | 609 goto try_next_pseg; 610 state = RF_DSYNC_ST; 611 /* Fall through */ 612 case RF_DSYNC_ST: |
640 if (!(flags & NILFS_SS_SYNDT)) | 613 if (!NILFS_SEG_DSYNC(&ssi)) |
641 goto confused; 642 | 614 goto confused; 615 |
643 err = nilfs_scan_dsync_log(nilfs, pseg_start, sum, 644 &dsync_blocks); | 616 err = collect_blocks_from_segsum( 617 sbi, pseg_start, &ssi, &dsync_blocks); |
645 if (unlikely(err)) 646 goto failed; | 618 if (unlikely(err)) 619 goto failed; |
647 if (flags & NILFS_SS_LOGEND) { 648 err = nilfs_recover_dsync_blocks( 649 nilfs, sbi, &dsync_blocks, 650 &nsalvaged_blocks); | 620 if (NILFS_SEG_LOGEND(&ssi)) { 621 err = recover_dsync_blocks( 622 sbi, &dsync_blocks, &nsalvaged_blocks); |
651 if (unlikely(err)) 652 goto failed; 653 state = RF_INIT_ST; 654 } 655 break; /* Fall through to try_next_pseg */ 656 } 657 658 try_next_pseg: 659 if (pseg_start == ri->ri_lsegs_end) 660 break; | 623 if (unlikely(err)) 624 goto failed; 625 state = RF_INIT_ST; 626 } 627 break; /* Fall through to try_next_pseg */ 628 } 629 630 try_next_pseg: 631 if (pseg_start == ri->ri_lsegs_end) 632 break; |
661 pseg_start += le32_to_cpu(sum->ss_nblocks); | 633 pseg_start += ssi.nblocks; |
662 if (pseg_start < seg_end) 663 continue; 664 goto feed_segment; 665 666 strayed: 667 if (pseg_start == ri->ri_lsegs_end) 668 break; 669 --- 8 unchanged lines hidden (view full) --- 678 } 679 680 if (nsalvaged_blocks) { 681 printk(KERN_INFO "NILFS (device %s): salvaged %lu blocks\n", 682 sbi->s_super->s_id, nsalvaged_blocks); 683 ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE; 684 } 685 out: | 634 if (pseg_start < seg_end) 635 continue; 636 goto feed_segment; 637 638 strayed: 639 if (pseg_start == ri->ri_lsegs_end) 640 break; 641 --- 8 unchanged lines hidden (view full) --- 650 } 651 652 if (nsalvaged_blocks) { 653 printk(KERN_INFO "NILFS (device %s): salvaged %lu blocks\n", 654 sbi->s_super->s_id, nsalvaged_blocks); 655 ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE; 656 } 657 out: |
686 brelse(bh_sum); | |
687 dispose_recovery_list(&dsync_blocks); | 658 dispose_recovery_list(&dsync_blocks); |
688 nilfs_detach_writer(nilfs, sbi); | 659 nilfs_detach_writer(sbi->s_nilfs, sbi); |
689 return err; 690 691 confused: 692 err = -EINVAL; 693 failed: 694 printk(KERN_ERR 695 "NILFS (device %s): Error roll-forwarding " 696 "(err=%d, pseg block=%llu). ", 697 sbi->s_super->s_id, err, (unsigned long long)pseg_start); 698 goto out; 699} 700 701static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, | 660 return err; 661 662 confused: 663 err = -EINVAL; 664 failed: 665 printk(KERN_ERR 666 "NILFS (device %s): Error roll-forwarding " 667 "(err=%d, pseg block=%llu). ", 668 sbi->s_super->s_id, err, (unsigned long long)pseg_start); 669 goto out; 670} 671 672static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, |
673 struct nilfs_sb_info *sbi, |
|
702 struct nilfs_recovery_info *ri) 703{ 704 struct buffer_head *bh; 705 int err; 706 707 if (nilfs_get_segnum_of_block(nilfs, ri->ri_lsegs_start) != 708 nilfs_get_segnum_of_block(nilfs, ri->ri_super_root)) 709 return; 710 | 674 struct nilfs_recovery_info *ri) 675{ 676 struct buffer_head *bh; 677 int err; 678 679 if (nilfs_get_segnum_of_block(nilfs, ri->ri_lsegs_start) != 680 nilfs_get_segnum_of_block(nilfs, ri->ri_super_root)) 681 return; 682 |
711 bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize); | 683 bh = sb_getblk(sbi->s_super, ri->ri_lsegs_start); |
712 BUG_ON(!bh); 713 memset(bh->b_data, 0, bh->b_size); 714 set_buffer_dirty(bh); 715 err = sync_dirty_buffer(bh); 716 if (unlikely(err)) 717 printk(KERN_WARNING 718 "NILFS warning: buffer sync write failed during " 719 "post-cleaning of recovery.\n"); 720 brelse(bh); 721} 722 723/** | 684 BUG_ON(!bh); 685 memset(bh->b_data, 0, bh->b_size); 686 set_buffer_dirty(bh); 687 err = sync_dirty_buffer(bh); 688 if (unlikely(err)) 689 printk(KERN_WARNING 690 "NILFS warning: buffer sync write failed during " 691 "post-cleaning of recovery.\n"); 692 brelse(bh); 693} 694 695/** |
724 * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint 725 * @nilfs: nilfs object | 696 * nilfs_recover_logical_segments - salvage logical segments written after 697 * the latest super root 698 * @nilfs: the_nilfs |
726 * @sbi: nilfs_sb_info 727 * @ri: pointer to a nilfs_recovery_info struct to store search results. 728 * 729 * Return Value: On success, 0 is returned. On error, one of the following 730 * negative error code is returned. 731 * 732 * %-EINVAL - Inconsistent filesystem state. 733 * 734 * %-EIO - I/O error 735 * 736 * %-ENOSPC - No space left on device (only in a panic state). 737 * 738 * %-ERESTARTSYS - Interrupted. 739 * 740 * %-ENOMEM - Insufficient memory available. 741 */ | 699 * @sbi: nilfs_sb_info 700 * @ri: pointer to a nilfs_recovery_info struct to store search results. 701 * 702 * Return Value: On success, 0 is returned. On error, one of the following 703 * negative error code is returned. 704 * 705 * %-EINVAL - Inconsistent filesystem state. 706 * 707 * %-EIO - I/O error 708 * 709 * %-ENOSPC - No space left on device (only in a panic state). 710 * 711 * %-ERESTARTSYS - Interrupted. 712 * 713 * %-ENOMEM - Insufficient memory available. 714 */ |
742int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, 743 struct nilfs_sb_info *sbi, 744 struct nilfs_recovery_info *ri) | 715int nilfs_recover_logical_segments(struct the_nilfs *nilfs, 716 struct nilfs_sb_info *sbi, 717 struct nilfs_recovery_info *ri) |
745{ 746 int err; 747 748 if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0) 749 return 0; 750 751 err = nilfs_attach_checkpoint(sbi, ri->ri_cno); 752 if (unlikely(err)) { --- 23 unchanged lines hidden (view full) --- 776 nilfs_detach_segment_constructor(sbi); 777 778 if (unlikely(err)) { 779 printk(KERN_ERR "NILFS: Oops! recovery failed. " 780 "(err=%d)\n", err); 781 goto failed; 782 } 783 | 718{ 719 int err; 720 721 if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0) 722 return 0; 723 724 err = nilfs_attach_checkpoint(sbi, ri->ri_cno); 725 if (unlikely(err)) { --- 23 unchanged lines hidden (view full) --- 749 nilfs_detach_segment_constructor(sbi); 750 751 if (unlikely(err)) { 752 printk(KERN_ERR "NILFS: Oops! recovery failed. " 753 "(err=%d)\n", err); 754 goto failed; 755 } 756 |
784 nilfs_finish_roll_forward(nilfs, ri); | 757 nilfs_finish_roll_forward(nilfs, sbi, ri); |
785 } 786 787 failed: 788 nilfs_detach_checkpoint(sbi); 789 return err; 790} 791 792/** 793 * nilfs_search_super_root - search the latest valid super root 794 * @nilfs: the_nilfs | 758 } 759 760 failed: 761 nilfs_detach_checkpoint(sbi); 762 return err; 763} 764 765/** 766 * nilfs_search_super_root - search the latest valid super root 767 * @nilfs: the_nilfs |
768 * @sbi: nilfs_sb_info |
|
795 * @ri: pointer to a nilfs_recovery_info struct to store search results. 796 * 797 * nilfs_search_super_root() looks for the latest super-root from a partial 798 * segment pointed by the superblock. It sets up struct the_nilfs through 799 * this search. It fills nilfs_recovery_info (ri) required for recovery. 800 * 801 * Return Value: On success, 0 is returned. On error, one of the following 802 * negative error code is returned. 803 * 804 * %-EINVAL - No valid segment found 805 * 806 * %-EIO - I/O error | 769 * @ri: pointer to a nilfs_recovery_info struct to store search results. 770 * 771 * nilfs_search_super_root() looks for the latest super-root from a partial 772 * segment pointed by the superblock. It sets up struct the_nilfs through 773 * this search. It fills nilfs_recovery_info (ri) required for recovery. 774 * 775 * Return Value: On success, 0 is returned. On error, one of the following 776 * negative error code is returned. 777 * 778 * %-EINVAL - No valid segment found 779 * 780 * %-EIO - I/O error |
807 * 808 * %-ENOMEM - Insufficient memory available. | |
809 */ | 781 */ |
810int nilfs_search_super_root(struct the_nilfs *nilfs, | 782int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, |
811 struct nilfs_recovery_info *ri) 812{ | 783 struct nilfs_recovery_info *ri) 784{ |
813 struct buffer_head *bh_sum = NULL; 814 struct nilfs_segment_summary *sum; | 785 struct nilfs_segsum_info ssi; |
815 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 816 sector_t seg_start, seg_end; /* range of full segment (block number) */ 817 sector_t b, end; | 786 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 787 sector_t seg_start, seg_end; /* range of full segment (block number) */ 788 sector_t b, end; |
818 unsigned long nblocks; 819 unsigned int flags; | |
820 u64 seg_seq; 821 __u64 segnum, nextnum = 0; 822 __u64 cno; 823 LIST_HEAD(segments); 824 int empty_seg = 0, scan_newer = 0; 825 int ret; 826 827 pseg_start = nilfs->ns_last_pseg; 828 seg_seq = nilfs->ns_last_seq; 829 cno = nilfs->ns_last_cno; 830 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 831 832 /* Calculate range of segment */ 833 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 834 835 /* Read ahead segment */ 836 b = seg_start; 837 while (b <= seg_end) | 789 u64 seg_seq; 790 __u64 segnum, nextnum = 0; 791 __u64 cno; 792 LIST_HEAD(segments); 793 int empty_seg = 0, scan_newer = 0; 794 int ret; 795 796 pseg_start = nilfs->ns_last_pseg; 797 seg_seq = nilfs->ns_last_seq; 798 cno = nilfs->ns_last_cno; 799 segnum = nilfs_get_segnum_of_block(nilfs, pseg_start); 800 801 /* Calculate range of segment */ 802 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 803 804 /* Read ahead segment */ 805 b = seg_start; 806 while (b <= seg_end) |
838 __breadahead(nilfs->ns_bdev, b++, nilfs->ns_blocksize); | 807 sb_breadahead(sbi->s_super, b++); |
839 840 for (;;) { | 808 809 for (;;) { |
841 brelse(bh_sum); 842 ret = NILFS_SEG_FAIL_IO; 843 bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); 844 if (!bh_sum) 845 goto failed; 846 847 ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); | 810 /* Load segment summary */ 811 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi); |
848 if (ret) { 849 if (ret == NILFS_SEG_FAIL_IO) 850 goto failed; 851 goto strayed; 852 } | 812 if (ret) { 813 if (ret == NILFS_SEG_FAIL_IO) 814 goto failed; 815 goto strayed; 816 } |
853 854 nblocks = le32_to_cpu(sum->ss_nblocks); 855 pseg_end = pseg_start + nblocks - 1; | 817 pseg_end = pseg_start + ssi.nblocks - 1; |
856 if (unlikely(pseg_end > seg_end)) { 857 ret = NILFS_SEG_FAIL_CONSISTENCY; 858 goto strayed; 859 } 860 861 /* A valid partial segment */ 862 ri->ri_pseg_start = pseg_start; 863 ri->ri_seq = seg_seq; 864 ri->ri_segnum = segnum; | 818 if (unlikely(pseg_end > seg_end)) { 819 ret = NILFS_SEG_FAIL_CONSISTENCY; 820 goto strayed; 821 } 822 823 /* A valid partial segment */ 824 ri->ri_pseg_start = pseg_start; 825 ri->ri_seq = seg_seq; 826 ri->ri_segnum = segnum; |
865 nextnum = nilfs_get_segnum_of_block(nilfs, 866 le64_to_cpu(sum->ss_next)); | 827 nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); |
867 ri->ri_nextnum = nextnum; 868 empty_seg = 0; 869 | 828 ri->ri_nextnum = nextnum; 829 empty_seg = 0; 830 |
870 flags = le16_to_cpu(sum->ss_flags); 871 if (!(flags & NILFS_SS_SR) && !scan_newer) { | 831 if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) { |
872 /* This will never happen because a superblock 873 (last_segment) always points to a pseg 874 having a super root. */ 875 ret = NILFS_SEG_FAIL_CONSISTENCY; 876 goto failed; 877 } 878 879 if (pseg_start == seg_start) { 880 nilfs_get_segment_range(nilfs, nextnum, &b, &end); 881 while (b <= end) | 832 /* This will never happen because a superblock 833 (last_segment) always points to a pseg 834 having a super root. */ 835 ret = NILFS_SEG_FAIL_CONSISTENCY; 836 goto failed; 837 } 838 839 if (pseg_start == seg_start) { 840 nilfs_get_segment_range(nilfs, nextnum, &b, &end); 841 while (b <= end) |
882 __breadahead(nilfs->ns_bdev, b++, 883 nilfs->ns_blocksize); | 842 sb_breadahead(sbi->s_super, b++); |
884 } | 843 } |
885 if (!(flags & NILFS_SS_SR)) { 886 if (!ri->ri_lsegs_start && (flags & NILFS_SS_LOGBGN)) { | 844 if (!NILFS_SEG_HAS_SR(&ssi)) { 845 if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { |
887 ri->ri_lsegs_start = pseg_start; 888 ri->ri_lsegs_start_seq = seg_seq; 889 } | 846 ri->ri_lsegs_start = pseg_start; 847 ri->ri_lsegs_start_seq = seg_seq; 848 } |
890 if (flags & NILFS_SS_LOGEND) | 849 if (NILFS_SEG_LOGEND(&ssi)) |
891 ri->ri_lsegs_end = pseg_start; 892 goto try_next_pseg; 893 } 894 895 /* A valid super root was found. */ 896 ri->ri_cno = cno++; 897 ri->ri_super_root = pseg_end; 898 ri->ri_lsegs_start = ri->ri_lsegs_end = 0; 899 900 nilfs_dispose_segment_list(&segments); | 850 ri->ri_lsegs_end = pseg_start; 851 goto try_next_pseg; 852 } 853 854 /* A valid super root was found. */ 855 ri->ri_cno = cno++; 856 ri->ri_super_root = pseg_end; 857 ri->ri_lsegs_start = ri->ri_lsegs_end = 0; 858 859 nilfs_dispose_segment_list(&segments); |
901 sr_pseg_start = pseg_start; 902 nilfs->ns_pseg_offset = pseg_start + nblocks - seg_start; | 860 nilfs->ns_pseg_offset = (sr_pseg_start = pseg_start) 861 + ssi.nblocks - seg_start; |
903 nilfs->ns_seg_seq = seg_seq; 904 nilfs->ns_segnum = segnum; 905 nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */ | 862 nilfs->ns_seg_seq = seg_seq; 863 nilfs->ns_segnum = segnum; 864 nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */ |
906 nilfs->ns_ctime = le64_to_cpu(sum->ss_create); | 865 nilfs->ns_ctime = ssi.ctime; |
907 nilfs->ns_nextnum = nextnum; 908 909 if (scan_newer) 910 ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; 911 else { 912 if (nilfs->ns_mount_state & NILFS_VALID_FS) 913 goto super_root_found; 914 scan_newer = 1; 915 } 916 | 866 nilfs->ns_nextnum = nextnum; 867 868 if (scan_newer) 869 ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; 870 else { 871 if (nilfs->ns_mount_state & NILFS_VALID_FS) 872 goto super_root_found; 873 scan_newer = 1; 874 } 875 |
876 /* reset region for roll-forward */ 877 pseg_start += ssi.nblocks; 878 if (pseg_start < seg_end) 879 continue; 880 goto feed_segment; 881 |
|
917 try_next_pseg: 918 /* Standing on a course, or met an inconsistent state */ | 882 try_next_pseg: 883 /* Standing on a course, or met an inconsistent state */ |
919 pseg_start += nblocks; | 884 pseg_start += ssi.nblocks; |
920 if (pseg_start < seg_end) 921 continue; 922 goto feed_segment; 923 924 strayed: 925 /* Off the trail */ 926 if (!scan_newer) 927 /* --- 14 unchanged lines hidden (view full) --- 942 seg_seq++; 943 segnum = nextnum; 944 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 945 pseg_start = seg_start; 946 } 947 948 super_root_found: 949 /* Updating pointers relating to the latest checkpoint */ | 885 if (pseg_start < seg_end) 886 continue; 887 goto feed_segment; 888 889 strayed: 890 /* Off the trail */ 891 if (!scan_newer) 892 /* --- 14 unchanged lines hidden (view full) --- 907 seg_seq++; 908 segnum = nextnum; 909 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 910 pseg_start = seg_start; 911 } 912 913 super_root_found: 914 /* Updating pointers relating to the latest checkpoint */ |
950 brelse(bh_sum); | |
951 list_splice_tail(&segments, &ri->ri_used_segments); 952 nilfs->ns_last_pseg = sr_pseg_start; 953 nilfs->ns_last_seq = nilfs->ns_seg_seq; 954 nilfs->ns_last_cno = ri->ri_cno; 955 return 0; 956 957 failed: | 915 list_splice_tail(&segments, &ri->ri_used_segments); 916 nilfs->ns_last_pseg = sr_pseg_start; 917 nilfs->ns_last_seq = nilfs->ns_seg_seq; 918 nilfs->ns_last_cno = ri->ri_cno; 919 return 0; 920 921 failed: |
958 brelse(bh_sum); | |
959 nilfs_dispose_segment_list(&segments); 960 return (ret < 0) ? ret : nilfs_warn_segment_error(ret); 961} | 922 nilfs_dispose_segment_list(&segments); 923 return (ret < 0) ? ret : nilfs_warn_segment_error(ret); 924} |