introduce strucutures and numbers only. Signed-off-by: Wengang Wang <wen.gang.wang@xxxxxxxxxx> --- fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_fs.h | 1 + fs/xfs/xfs_defrag.c | 60 ++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_defrag.h | 11 ++++++++ fs/xfs/xfs_ioctl.c | 17 ++++++++++++ fs/xfs/xfs_mount.h | 37 ++++++++++++++++++++++++++ 6 files changed, 127 insertions(+) create mode 100644 fs/xfs/xfs_defrag.c create mode 100644 fs/xfs/xfs_defrag.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 7762c01a85cf..ba7f7bc4abf9 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -93,6 +93,7 @@ xfs-y += xfs_aops.o \ xfs_sysfs.o \ xfs_trans.o \ xfs_xattr.o \ + xfs_defrag.o \ kmem.o # low-level transaction/log code diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 6360073865db..4b0fdb900df5 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -837,6 +837,7 @@ struct xfs_scrub_metadata { #define XFS_IOC_FSGEOMETRY _IOR ('X', 126, struct xfs_fsop_geom) #define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req) #define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req) +#define XFS_IOC_DEFRAG _IOWR('X', 129, struct xfs_defrag) /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ diff --git a/fs/xfs/xfs_defrag.c b/fs/xfs/xfs_defrag.c new file mode 100644 index 000000000000..954d05376809 --- /dev/null +++ b/fs/xfs/xfs_defrag.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Oracle. All Rights Reserved. + * Author: Wengang Wang <wen.gang.wang@xxxxxxxxxx> + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_format.h" +#include "xfs_shared.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" +#include "xfs_bmap.h" +#include "xfs_inode_fork.h" +#include "xfs_inode.h" +#include "xfs_reflink.h" +#include "xfs_log_format.h" +#include "xfs_trans.h" +#include "xfs_bit.h" +#include "xfs_buf.h" +#include "xfs_bmap_btree.h" +#include "xfs_trans_space.h" +#include "xfs_ag.h" +#include "xfs_alloc.h" +#include "xfs_refcount_btree.h" +#include "xfs_btree.h" +#include "xfs_refcount.h" +#include "xfs_defer.h" +#include "xfs_log_priv.h" +#include "xfs_extfree_item.h" +#include "xfs_bmap_item.h" +#include "xfs_quota_defs.h" +#include "xfs_quota.h" + +#include <linux/sort.h> + +/* + * The max number of extents in a piece. + * can't be too big, it will have log space presure + */ +#define XFS_DEFRAG_PIECE_MAX_EXT 512 + +/* + * Milliseconds we leave the info unremoved when a defrag failed. + * This aims to give user space a way to get the error code. + */ +#define XFS_DERFAG_GRACE_PERIOD 30000 + +/* limitation of pending online defrag */ +#define XFS_DEFRAG_MAX_PARALLEL 128 + +/* + * The max size, in blocks, of a piece. + * can't be too big, it may hard to get such a free extent + */ +#define XFS_DEFRAG_MAX_PIECE_BLOCKS 4096U + +int xfs_file_defrag(struct file *filp, struct xfs_defrag *defrag) +{ + return -EOPNOTSUPP; +} diff --git a/fs/xfs/xfs_defrag.h b/fs/xfs/xfs_defrag.h new file mode 100644 index 000000000000..21113d8c1567 --- /dev/null +++ b/fs/xfs/xfs_defrag.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Oracle. All Rights Reserved. + * Author: Wengang Wang <wen.gang.wang@xxxxxxxxxx> + */ +#ifndef __XFS_DEFRAG_H__ +#define __XFS_DEFRAG_H__ +void xfs_initialize_defrag(struct xfs_mount *mp); +int xfs_file_defrag(struct file *filp, struct xfs_defrag *defrag); +void xfs_stop_wait_defrags(struct xfs_mount *mp); +#endif /* __XFS_DEFRAG_H__ */ diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 6c3919687ea6..7f7a7094ace9 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -39,6 +39,7 @@ #include "xfs_ioctl.h" #include "xfs_xattr.h" #include "xfs_rtbitmap.h" +#include "xfs_defrag.h" #include <linux/mount.h> #include <linux/namei.h> @@ -2160,6 +2161,22 @@ xfs_file_ioctl( return error; } + case XFS_IOC_DEFRAG: { + struct xfs_defrag defrag; + int ret; + + if (xfs_is_readonly(mp)) + return -EROFS; + + if (copy_from_user(&defrag, arg, sizeof(defrag))) + return -EFAULT; + + ret = xfs_file_defrag(filp, &defrag); + if (ret == 0) + ret = copy_to_user(arg, &defrag, sizeof(defrag)); + return ret; + } + default: return -ENOTTY; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 503fe3c7edbf..05b372cde389 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -71,6 +71,34 @@ struct xfs_inodegc { unsigned int cpu; }; +/* Online Defrag */ +enum xfs_defrag_cmd { + XFS_DEFRAG_CMD_START = 1, /* start defrag, or change configuration */ + XFS_DEFRAG_CMD_STOP, /* stop defrag */ + XFS_DEFRAG_CMD_SUSPEND, /* suspend on going defrag */ + XFS_DEFRAG_CMD_RESUME, /* resume suspended defrag */ + XFS_DEFRAG_CMD_STATUS, /* get status */ +}; + +struct xfs_defrag { + /* [IN] XFS_DEFRAG_CMD_* */ + enum xfs_defrag_cmd df_cmd; + /* [IN] the size of piece in blocks */ + unsigned int df_piece_size; + /* [IN] the target extent size */ + unsigned int df_tgt_extsize; + /* [IN] idle time in ms between adjacent pieces */ + unsigned int df_idle_time; + /* [OUT] current running status */ + int df_status; + /* [OUT] the number of the processed blocks */ + unsigned long long df_blocks_done; + /* [OUT] inode number of the file under defragmentation */ + unsigned long df_ino; + /* [OUT] defragmenting on this file is suspended */ + bool df_suspended; +}; + /* * The struct xfsmount layout is optimised to separate read-mostly variables * from variables that are frequently modified. We put the read-mostly variables @@ -252,6 +280,15 @@ typedef struct xfs_mount { /* cpus that have inodes queued for inactivation */ struct cpumask m_inodegc_cpumask; + + /* lock to serialize the access of defrags fields */ + struct semaphore m_defrag_lock; + /* number of pending defragmentation in this FS */ + unsigned int m_nr_defrag; + /* list that links up all pending defragmentation */ + struct list_head m_defrag_list; + /* the task which does defragmentation job */ + struct task_struct *m_defrag_task; } xfs_mount_t; #define M_IGEO(mp) (&(mp)->m_ino_geo) -- 2.39.3 (Apple Git-145)