diff options
author | obrien <obrien@FreeBSD.org> | 2013-02-08 16:10:16 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2013-02-08 16:10:16 +0000 |
commit | 3028e3f8aba938dfd0bf9fda987b8a72140b8027 (patch) | |
tree | b2f038222ff8a70f687652441df00d2b564c8abe /sbin/growfs | |
parent | 952a6d5a7cd3d3f9007acfa06805262fc04a105f (diff) | |
parent | 1d08d5f677c1dfa810e381073590adbae19cc69f (diff) | |
download | FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.zip FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.tar.gz |
Sync with HEAD.
Diffstat (limited to 'sbin/growfs')
-rw-r--r-- | sbin/growfs/growfs.8 | 5 | ||||
-rw-r--r-- | sbin/growfs/growfs.c | 53 |
2 files changed, 44 insertions, 14 deletions
diff --git a/sbin/growfs/growfs.8 b/sbin/growfs/growfs.8 index 92508da..664e723 100644 --- a/sbin/growfs/growfs.8 +++ b/sbin/growfs/growfs.8 @@ -115,11 +115,16 @@ The .Nm utility first appeared in .Fx 4.4 . +The ability to resize mounted filesystems was added in +.Fx 10.0 . .Sh AUTHORS .An Christoph Herrmann Aq chm@FreeBSD.org .An Thomas-Henning von Kamptz Aq tomsoft@FreeBSD.org .An The GROWFS team Aq growfs@Tomsoft.COM .An Edward Tomasz Napierala Aq trasz@FreeBSD.org +.Sh CAVEATS +When expanding a file system mounted read-write, any writes to that file system +will be temporarily suspended until the expansion is finished. .Sh BUGS Normally .Nm diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index ad837a8..745e9e9 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include <inttypes.h> #include <limits.h> #include <mntopts.h> +#include <paths.h> #include <stdlib.h> #include <stdint.h> #include <string.h> @@ -1486,6 +1487,12 @@ main(int argc, char **argv) } } + /* + * Make sure the new size is a multiple of fs_fsize; /dev/ufssuspend + * only supports fragment-aligned IO requests. + */ + size -= size % osblock.fs_fsize; + if (size <= (uint64_t)(osblock.fs_size * osblock.fs_fsize)) { humanize_number(oldsizebuf, sizeof(oldsizebuf), osblock.fs_size * osblock.fs_fsize, @@ -1525,8 +1532,9 @@ main(int argc, char **argv) if (yflag == 0 && Nflag == 0) { if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) - errx(1, "%s is mounted read-write on %s", - statfsp->f_mntfromname, statfsp->f_mntonname); + printf("Device is mounted read-write; resizing will " + "result in temporary write suspension for %s.\n", + statfsp->f_mntonname); printf("It's strongly recommended to make a backup " "before growing the file system.\n" "OK to grow filesystem on %s", device); @@ -1555,9 +1563,18 @@ main(int argc, char **argv) if (Nflag) { fso = -1; } else { - fso = open(device, O_WRONLY); - if (fso < 0) - err(1, "%s", device); + if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) { + fso = open(_PATH_UFSSUSPEND, O_RDWR); + if (fso == -1) + err(1, "unable to open %s", _PATH_UFSSUSPEND); + error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid); + if (error != 0) + err(1, "UFSSUSPEND"); + } else { + fso = open(device, O_WRONLY); + if (fso < 0) + err(1, "%s", device); + } } /* @@ -1594,17 +1611,20 @@ main(int argc, char **argv) } sblock.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg); + /* + * Allocate last cylinder group only if there is enough room + * for at least one data block. + */ if (sblock.fs_size % sblock.fs_fpg != 0 && - sblock.fs_size % sblock.fs_fpg < cgdmin(&sblock, sblock.fs_ncg)) { - /* - * The space in the new last cylinder group is too small, - * so revert back. - */ + sblock.fs_size <= cgdmin(&sblock, sblock.fs_ncg - 1)) { + humanize_number(oldsizebuf, sizeof(oldsizebuf), + (sblock.fs_size % sblock.fs_fpg) * sblock.fs_fsize, + "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); + warnx("no room to allocate last cylinder group; " + "leaving %s unused", oldsizebuf); sblock.fs_ncg--; if (sblock.fs_magic == FS_UFS1_MAGIC) sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg; - printf("Warning: %jd sector(s) cannot be allocated.\n", - (intmax_t)fsbtodb(&sblock, sblock.fs_size % sblock.fs_fpg)); sblock.fs_size = sblock.fs_ncg * sblock.fs_fpg; } @@ -1627,12 +1647,17 @@ main(int argc, char **argv) close(fsi); if (fso > -1) { + if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) { + error = ioctl(fso, UFSRESUME); + if (error != 0) + err(1, "UFSRESUME"); + } error = close(fso); if (error != 0) err(1, "close"); + if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0) + mount_reload(statfsp); } - if (statfsp != NULL) - mount_reload(statfsp); DBG_CLOSE; |