···5656#include "btnode.h"5757#include "page.h"5858#include "cpfile.h"5959+#include "sufile.h" /* nilfs_sufile_resize(), nilfs_sufile_set_alloc_range() */5960#include "ifile.h"6061#include "dat.h"6162#include "segment.h"···401400 } else {402401 brelse(nsbh);403402 }403403+out:404404+ return ret;405405+}406406+407407+/**408408+ * nilfs_resize_fs - resize the filesystem409409+ * @sb: super block instance410410+ * @newsize: new size of the filesystem (in bytes)411411+ */412412+int nilfs_resize_fs(struct super_block *sb, __u64 newsize)413413+{414414+ struct the_nilfs *nilfs = sb->s_fs_info;415415+ struct nilfs_super_block **sbp;416416+ __u64 devsize, newnsegs;417417+ loff_t sb2off;418418+ int ret;419419+420420+ ret = -ERANGE;421421+ devsize = i_size_read(sb->s_bdev->bd_inode);422422+ if (newsize > devsize)423423+ goto out;424424+425425+ /*426426+ * Write lock is required to protect some functions depending427427+ * on the number of segments, the number of reserved segments,428428+ * and so forth.429429+ */430430+ down_write(&nilfs->ns_segctor_sem);431431+432432+ sb2off = NILFS_SB2_OFFSET_BYTES(newsize);433433+ newnsegs = sb2off >> nilfs->ns_blocksize_bits;434434+ do_div(newnsegs, nilfs->ns_blocks_per_segment);435435+436436+ ret = nilfs_sufile_resize(nilfs->ns_sufile, newnsegs);437437+ up_write(&nilfs->ns_segctor_sem);438438+ if (ret < 0)439439+ goto out;440440+441441+ ret = nilfs_construct_segment(sb);442442+ if (ret < 0)443443+ goto out;444444+445445+ down_write(&nilfs->ns_sem);446446+ nilfs_move_2nd_super(sb, sb2off);447447+ ret = -EIO;448448+ sbp = nilfs_prepare_super(sb, 0);449449+ if (likely(sbp)) {450450+ nilfs_set_log_cursor(sbp[0], nilfs);451451+ /*452452+ * Drop NILFS_RESIZE_FS flag for compatibility with453453+ * mount-time resize which may be implemented in a454454+ * future release.455455+ */456456+ sbp[0]->s_state = cpu_to_le16(le16_to_cpu(sbp[0]->s_state) &457457+ ~NILFS_RESIZE_FS);458458+ sbp[0]->s_dev_size = cpu_to_le64(newsize);459459+ sbp[0]->s_nsegments = cpu_to_le64(nilfs->ns_nsegments);460460+ if (sbp[1])461461+ memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);462462+ ret = nilfs_commit_super(sb, NILFS_SB_COMMIT_ALL);463463+ }464464+ up_write(&nilfs->ns_sem);465465+466466+ /*467467+ * Reset the range of allocatable segments last. This order468468+ * is important in the case of expansion because the secondary469469+ * superblock must be protected from log write until migration470470+ * completes.471471+ */472472+ if (!ret)473473+ nilfs_sufile_set_alloc_range(nilfs->ns_sufile, 0, newnsegs - 1);404474out:405475 return ret;406476}
+19-5
fs/nilfs2/the_nilfs.c
···363363 return res;364364}365365366366+/**367367+ * nilfs_nrsvsegs - calculate the number of reserved segments368368+ * @nilfs: nilfs object369369+ * @nsegs: total number of segments370370+ */371371+unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs)372372+{373373+ return max_t(unsigned long, NILFS_MIN_NRSVSEGS,374374+ DIV_ROUND_UP(nsegs * nilfs->ns_r_segments_percentage,375375+ 100));376376+}377377+378378+void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)379379+{380380+ nilfs->ns_nsegments = nsegs;381381+ nilfs->ns_nrsvsegs = nilfs_nrsvsegs(nilfs, nsegs);382382+}383383+366384static int nilfs_store_disk_layout(struct the_nilfs *nilfs,367385 struct nilfs_super_block *sbp)368386{···407389 }408390409391 nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);410410- nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments);411392 nilfs->ns_r_segments_percentage =412393 le32_to_cpu(sbp->s_r_segments_percentage);413413- nilfs->ns_nrsvsegs =414414- max_t(unsigned long, NILFS_MIN_NRSVSEGS,415415- DIV_ROUND_UP(nilfs->ns_nsegments *416416- nilfs->ns_r_segments_percentage, 100));394394+ nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));417395 nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);418396 return 0;419397}