Re: [RFC PATCH] xfs: support shrinking unused space in the last AG

Gao Xiang
2020-10-14T01:06:20Z

On Wed, Oct 14, 2020 at 08:58:09AM +0800, Gao Xiang wrote:
> From: Gao Xiang <hsiangkao@redhat.com>
>
> At the first step of shrinking, this attempts to enable shrinking
> unused space in the last allocation group by fixing up freespace
> btree, agi, agf and adjusting super block.
>
> This can be all done in one transaction for now, so I think no
> additional protection is needed.
>
> Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
> ---
>
> Honestly, I've got headache about shrinking entire AGs
> since the codebase doesn't expect agcount can be decreased
> suddenly, I got some ideas from people but the modification
> seems all over the codebase, I will keep on this at least
> to learn more about XFS internals.
>
> It might be worth sending out shrinking the last AG first
> since users might need to shrink a little unused space
> occasionally, yet I'm not quite sure the log space reservation
> calculation in this patch and other details are correct.
> I've done some manual test and it seems work. Yeah, as a
> formal patch it needs more test to be done but I'd like
> to hear more ideas about this first since I'm not quite
> familiar with XFS for now and this topic involves a lot
> new XFS-specific implementation details.
>
> Kindly point out all strange places and what I'm missing
> so I can revise it. It would be of great help for me to
> learn more about XFS. At least just as a record on this
> topic for further discussion.
>

and a simple user prog is attached:
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

#define XFS_IOC_FSGROWFSDATA _IOW ('X', 110, struct xfs_growfs_data)

/*
* Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
*/
typedef struct xfs_growfs_data {
int64_t newblocks; /* new data subvol size, fsblocks */
uint32_t imaxpct; /* new inode space percentage limit */
} xfs_growfs_data_t;

int main(int argc, char *argv[])
{
xfs_growfs_data_t in;
int fd = open(argv[1], O_RDONLY);

in.newblocks = strtoll(argv[2], NULL, 10);
in.imaxpct = 0;
if (ioctl(fd, XFS_IOC_FSGROWFSDATA, &in) < 0) {
fprintf(stderr, "XFS_IOC_FSGROWFSDATA xfsctl failed: %s\n",
strerror(errno));
return 1;
}

return 0;
}