Skip to content

Commit dce8b50

Browse files
felixfonteinjnaabJohannes Naab
authored
[stable-11] filesystem: xfs resize: minimal required increment (#11033) (#11042)
filesystem: xfs resize: minimal required increment (#11033) Internally XFS uses allocation groups. Allocation groups have a maximum size of 1 TiB - 1 block. For devices >= 4 TiB XFS uses max size allocation groups. If a filesystem is extended and the last allocation group is already at max size, a new allocation group is added. An allocation group seems to require at least 64 4 KiB blocks. For devices with integer TiB size (>4), this creates a filesystem that has initially has 1 unused block per TiB size. The `resize` option detects this unused space, and tries to resize the filesystem. The xfs_growfs call is successful (exit 0), but does not increase the file system size. This is detected as repeated change in the task. Test case: ``` - hosts: localhost tasks: - ansible.builtin.command: cmd: truncate -s 4T /media/xfs.img creates: /media/xfs.img notify: loopdev xfs - ansible.builtin.meta: flush_handlers - name: pickup xfs.img resize ansible.builtin.command: cmd: losetup -c /dev/loop0 changed_when: false - community.general.filesystem: dev: "/dev/loop0" fstype: "xfs" - ansible.posix.mount: src: "/dev/loop0" fstype: "xfs" path: "/media/xfs" state: "mounted" # always shows a diff even for newly created filesystems - community.general.filesystem: dev: "/dev/loop0" fstype: "xfs" resizefs: true handlers: - name: loopdev xfs ansible.builtin.command: cmd: losetup /dev/loop0 /media/xfs.img ``` NB: If the last allocation group is not yet at max size, the filesystem can be resized. Detecting this requires considering the XFS topology. Other filesystems (at least ext4) also seem to require a minimum increment after the initial device size, but seem to use the entire device after initial creation. Fun observation: creating a 64(+) TiB filesystem leaves a 64(+) block gap at the end, that is allocated in a subsequent xfs_growfs call. (cherry picked from commit f594320) Co-authored-by: jnaab <[email protected]> Co-authored-by: Johannes Naab <[email protected]>
1 parent 40eec12 commit dce8b50

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bugfixes:
2+
- filesystem - avoid false positive change detection on XFS resize due to unusable slack space (https://github.com/ansible-collections/community.general/pull/11033).

plugins/modules/filesystem.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class Filesystem(object):
210210
MKFS_SET_UUID_EXTRA_OPTIONS = []
211211
INFO = None
212212
GROW = None
213+
GROW_SLACK = 0
213214
GROW_MAX_SPACE_FLAGS = []
214215
GROW_MOUNTPOINT_ONLY = False
215216
CHANGE_UUID = None
@@ -278,7 +279,7 @@ def grow(self, dev):
278279
self.module.warn("unable to process %s output '%s'" % (self.INFO, to_native(err)))
279280
self.module.fail_json(msg="unable to process %s output for %s" % (self.INFO, dev))
280281

281-
if not fssize_in_bytes < devsize_in_bytes:
282+
if fssize_in_bytes + self.GROW_SLACK >= devsize_in_bytes:
282283
self.module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (self.fstype, dev))
283284
elif self.module.check_mode:
284285
self.module.exit_json(changed=True, msg="resizing filesystem %s on device %s" % (self.fstype, dev))
@@ -356,6 +357,10 @@ class XFS(Filesystem):
356357
MKFS_FORCE_FLAGS = ['-f']
357358
INFO = 'xfs_info'
358359
GROW = 'xfs_growfs'
360+
# XFS (defaults with 4KiB blocksize) requires at least 64 block of free
361+
# space to add a new allocation group, avoid resizing (noop, but shown as
362+
# diff) if the difference between the filesystem and the device is less
363+
GROW_SLACK = 64 * 4096 - 1
359364
GROW_MOUNTPOINT_ONLY = True
360365
CHANGE_UUID = "xfs_admin"
361366
CHANGE_UUID_OPTION = "-U"

0 commit comments

Comments
 (0)