@@ -730,6 +730,7 @@ xfs_file_fallocate(
{
struct inode *inode = file_inode(file);
struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
long error;
enum xfs_prealloc_flags flags = 0;
uint iolock = XFS_IOLOCK_EXCL;
@@ -749,6 +750,21 @@ xfs_file_fallocate(
xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
iolock |= XFS_MMAPLOCK_EXCL;
+ /*
+ * If fallocating a file < rtfallocmin store it on the non RT device.
+ * In a tiered storage setup, this device might be a device suitable
+ * for better small file storage/performance (e.g. SSD).
+ */
+ if (mp->m_rtdev_targp && mp->m_rtfallocmin && !offset &&
+ !inode->i_size) {
+ if (len >= mp->m_rtfallocmin) {
+ ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+ /* Clear flag if inheritence or rtdefault is being used */
+ } else {
+ ip->i_d.di_flags &= ~XFS_DIFLAG_REALTIME;
+ }
+ }
+
if (mode & FALLOC_FL_PUNCH_HOLE) {
error = xfs_free_file_space(ip, offset, len);
if (error)
@@ -84,6 +84,7 @@ typedef struct xfs_mount {
char *m_fsname; /* filesystem name */
int m_fsname_len; /* strlen of fs name */
char *m_rtname; /* realtime device name */
+ int m_rtfallocmin; /* Min size for RT fallocate */
char *m_logname; /* external log device name */
int m_bsize; /* fs logical block size */
xfs_agnumber_t m_agfrotor; /* last ag where space found */
@@ -84,7 +84,7 @@ enum {
Opt_uquota, Opt_gquota, Opt_pquota,
Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
Opt_discard, Opt_nodiscard, Opt_dax, Opt_rtdefault, Opt_rtstatfs,
- Opt_err,
+ Opt_rtfallocmin, Opt_err,
};
static const match_table_t tokens = {
@@ -137,6 +137,9 @@ static const match_table_t tokens = {
#ifdef CONFIG_XFS_RT
{Opt_rtdefault, "rtdefault"}, /* Default to real-time device */
{Opt_rtstatfs, "rtstatfs"}, /* Use real-time device for statfs */
+ {Opt_rtfallocmin, "rtfallocmin=%u"}, /* Min fallocation required
+ * for rt device
+ */
#endif
/* Deprecated mount options scheduled for removal */
{Opt_barrier, "barrier"}, /* use writer barriers for log write and
@@ -378,6 +381,10 @@ xfs_parseargs(
break;
case Opt_rtstatfs:
mp->m_flags |= XFS_MOUNT_RTSTATFS;
+ break;
+ case Opt_rtfallocmin:
+ if (match_int(args, &mp->m_rtfallocmin))
+ return -EINVAL;
break;
#endif
#ifdef CONFIG_FS_DAX
@@ -543,6 +550,11 @@ xfs_showargs(
if (mp->m_rtname)
seq_show_option(m, "rtdev", mp->m_rtname);
+#ifdef CONFIG_XFS_RT
+ if (mp->m_rtfallocmin > 0)
+ seq_printf(m, ",rtfallocmin=%d", mp->m_rtfallocmin);
+#endif
+
if (mp->m_dalign > 0)
seq_printf(m, ",sunit=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_dalign));