diff --git a/kmod/src/server.c b/kmod/src/server.c index fc07a1a5..d077d858 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -584,6 +584,7 @@ static void scoutfs_server_commit_func(struct work_struct *work) struct server_info *server = container_of(work, struct server_info, commit_work); struct super_block *sb = server->sb; + struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; struct commit_waiter *cw; struct commit_waiter *pos; struct llist_node *node; @@ -611,7 +612,7 @@ static void scoutfs_server_commit_func(struct work_struct *work) goto out; } - ret = scoutfs_write_dirty_super(sb); + ret = scoutfs_write_super(sb, super); if (ret) { scoutfs_err(sb, "server error writing super block: %d", ret); goto out; @@ -623,7 +624,6 @@ static void scoutfs_server_commit_func(struct work_struct *work) server->stable_manifest_root = SCOUTFS_SB(sb)->super.manifest.root; write_seqcount_end(&server->stable_seqcount); - scoutfs_advance_dirty_super(sb); ret = 0; out: @@ -2325,7 +2325,6 @@ static void scoutfs_server_worker(struct work_struct *work) complete(&server->start_comp); - scoutfs_advance_dirty_super(sb); server->stable_manifest_root = super->manifest.root; scoutfs_info(sb, "server started on "SIN_FMT, SIN_ARG(&sin)); diff --git a/kmod/src/super.c b/kmod/src/super.c index cc6b37c3..b4dcf658 100644 --- a/kmod/src/super.c +++ b/kmod/src/super.c @@ -221,28 +221,15 @@ static const struct super_operations scoutfs_super_ops = { }; /* - * The caller advances the sequence number in the super block header - * every time it wants to dirty it and eventually write it to reference - * dirty data that's been written. - */ -void scoutfs_advance_dirty_super(struct super_block *sb) -{ - struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); - struct scoutfs_super_block *super = &sbi->super; - - le64_add_cpu(&super->hdr.seq, 1); - trace_scoutfs_advance_dirty_super(sb, le64_to_cpu(super->hdr.seq)); -} - -/* - * The caller is responsible for setting the super header's blkno - * and seq to something reasonable. + * Write the caller's super. The caller has always read a valid super + * before modifying and writing it. The caller's super is modified + * to reflect the write. * * XXX it'd be pretty easy to preallocate to avoid failure here. */ -int scoutfs_write_dirty_super(struct super_block *sb) +int scoutfs_write_super(struct super_block *sb, + struct scoutfs_super_block *caller) { - struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct scoutfs_super_block *super; struct page *page; int ret; @@ -251,9 +238,10 @@ int scoutfs_write_dirty_super(struct super_block *sb) if (!page) return -ENOMEM; + le64_add_cpu(&caller->hdr.seq, 1); + super = page_address(page); - memcpy(super, &sbi->super, sizeof(*super)); - super->hdr.magic = cpu_to_le32(SCOUTFS_BLOCK_MAGIC_SUPER); + memcpy(super, caller, sizeof(*super)); super->hdr.crc = scoutfs_block_calc_crc(&super->hdr); ret = scoutfs_bio_write(sb, &page, le64_to_cpu(super->hdr.blkno), 1); diff --git a/kmod/src/super.h b/kmod/src/super.h index 08004731..741f2ddc 100644 --- a/kmod/src/super.h +++ b/kmod/src/super.h @@ -127,8 +127,8 @@ static inline bool SCOUTFS_HAS_SBI(struct super_block *sb) int scoutfs_read_super(struct super_block *sb, struct scoutfs_super_block *super_res); -void scoutfs_advance_dirty_super(struct super_block *sb); -int scoutfs_write_dirty_super(struct super_block *sb); +int scoutfs_write_super(struct super_block *sb, + struct scoutfs_super_block *super); /* to keep this out of the ioctl.h public interface definition */ long scoutfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);