static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag) { struct the_nilfs *nilfs = sbi->s_nilfs; int err; retry: set_buffer_dirty(nilfs->ns_sbh[0]); if (nilfs_test_opt(sbi, BARRIER)) { err = __sync_dirty_buffer(nilfs->ns_sbh[0], WRITE_SYNC | WRITE_FLUSH_FUA); } else { err = sync_dirty_buffer(nilfs->ns_sbh[0]); } if (unlikely(err)) { printk(KERN_ERR "NILFS: unable to write superblock (err=%d)\n", err); if (err == -EIO && nilfs->ns_sbh[1]) { /* * sbp[0] points to newer log than sbp[1], * so copy sbp[0] to sbp[1] to take over sbp[0]. */ memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0], nilfs->ns_sbsize); nilfs_fall_back_super_block(nilfs); goto retry; } } else { struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; nilfs->ns_sbwcount++; /* * The latest segment becomes trailable from the position * written in superblock. */ clear_nilfs_discontinued(nilfs); /* update GC protection for recent segments */ if (nilfs->ns_sbh[1]) { if (flag == NILFS_SB_COMMIT_ALL) { set_buffer_dirty(nilfs->ns_sbh[1]); if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0) goto out; } if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) < le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno)) sbp = nilfs->ns_sbp[1]; } spin_lock(&nilfs->ns_last_segment_lock); nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq); spin_unlock(&nilfs->ns_last_segment_lock); } out: return err; }
static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb) { struct the_nilfs *nilfs = sbi->s_nilfs; int err; int barrier_done = 0; if (nilfs_test_opt(sbi, BARRIER)) { set_buffer_ordered(nilfs->ns_sbh[0]); barrier_done = 1; } retry: set_buffer_dirty(nilfs->ns_sbh[0]); err = sync_dirty_buffer(nilfs->ns_sbh[0]); if (err == -EOPNOTSUPP && barrier_done) { nilfs_warning(sbi->s_super, __func__, "barrier-based sync failed. " "disabling barriers\n"); nilfs_clear_opt(sbi, BARRIER); barrier_done = 0; clear_buffer_ordered(nilfs->ns_sbh[0]); goto retry; } if (unlikely(err)) { printk(KERN_ERR "NILFS: unable to write superblock (err=%d)\n", err); if (err == -EIO && nilfs->ns_sbh[1]) { nilfs_fall_back_super_block(nilfs); goto retry; } } else { struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; /* * The latest segment becomes trailable from the position * written in superblock. */ clear_nilfs_discontinued(nilfs); /* update GC protection for recent segments */ if (nilfs->ns_sbh[1]) { sbp = NULL; if (dupsb) { set_buffer_dirty(nilfs->ns_sbh[1]); if (!sync_dirty_buffer(nilfs->ns_sbh[1])) sbp = nilfs->ns_sbp[1]; } } if (sbp) { spin_lock(&nilfs->ns_last_segment_lock); nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq); spin_unlock(&nilfs->ns_last_segment_lock); } } return err; }
static int nilfs_sync_super(struct super_block *sb, int flag) { struct the_nilfs *nilfs = sb->s_fs_info; int err; #if HAVE_BH_ORDERED int barrier_done = 0; if (nilfs_sb_barrier(nilfs)) { set_buffer_ordered(nilfs->ns_sbh[0]); barrier_done = 1; } retry: set_buffer_dirty(nilfs->ns_sbh[0]); err = sync_dirty_buffer(nilfs->ns_sbh[0]); if (err == -EOPNOTSUPP && barrier_done) { nilfs_warning(sb, __func__, "barrier-based sync failed. " "disabling barriers for superblock\n"); clear_nilfs_sb_barrier(nilfs); barrier_done = 0; clear_buffer_ordered(nilfs->ns_sbh[0]); goto retry; } #else retry: set_buffer_dirty(nilfs->ns_sbh[0]); if (nilfs_sb_barrier(nilfs)) { #if HAVE_BIO_BARRIER err = __sync_dirty_buffer(nilfs->ns_sbh[0], WRITE_SYNC | WRITE_BARRIER); if (err == -EOPNOTSUPP) { nilfs_warning(sb, __func__, "barrier-based sync failed. " "disabling barriers for superblock\n"); clear_nilfs_sb_barrier(nilfs); goto retry; } #else err = __sync_dirty_buffer(nilfs->ns_sbh[0], WRITE_SYNC | WRITE_FLUSH_FUA); #endif /* HAVE_BIO_BARRIER */ } else { err = sync_dirty_buffer(nilfs->ns_sbh[0]); } #endif /* HAVE_BH_ORDERED */ if (unlikely(err)) { printk(KERN_ERR "NILFS: unable to write superblock (err=%d)\n", err); if (err == -EIO && nilfs->ns_sbh[1]) { /* * sbp[0] points to newer log than sbp[1], * so copy sbp[0] to sbp[1] to take over sbp[0]. */ memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0], nilfs->ns_sbsize); nilfs_fall_back_super_block(nilfs); goto retry; } } else { struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; nilfs->ns_sbwcount++; /* * The latest segment becomes trailable from the position * written in superblock. */ clear_nilfs_discontinued(nilfs); /* update GC protection for recent segments */ if (nilfs->ns_sbh[1]) { if (flag == NILFS_SB_COMMIT_ALL) { set_buffer_dirty(nilfs->ns_sbh[1]); if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0) goto out; } if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) < le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno)) sbp = nilfs->ns_sbp[1]; } spin_lock(&nilfs->ns_last_segment_lock); nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq); spin_unlock(&nilfs->ns_last_segment_lock); } out: return err; }