@@ -1213,7 +1213,8 @@ void bdev_statx(struct inode *backing_inode, struct kstat *stat,
generic_fill_statx_atomic_writes(stat,
queue_atomic_write_unit_min_bytes(bd_queue),
- queue_atomic_write_unit_max_bytes(bd_queue));
+ queue_atomic_write_unit_max_bytes(bd_queue),
+ true);
}
blkdev_put_no_open(bdev);
@@ -94,19 +94,26 @@ EXPORT_SYMBOL(generic_fill_statx_attr);
* @stat: Where to fill in the attribute flags
* @unit_min: Minimum supported atomic write length in bytes
* @unit_max: Maximum supported atomic write length in bytes
+ * @dio: Whether filling in the fields for direct-IO
*
- * Fill in the STATX{_ATTR}_WRITE_ATOMIC_DIO flags in the kstat structure
- * from atomic write unit_min and unit_max values.
+ * Fill in the STATX{_ATTR}_WRITE_ATOMIC_{DIO, BUF} flags in the kstat
+ * structure from atomic write unit_min and unit_max values.
*/
void generic_fill_statx_atomic_writes(struct kstat *stat,
unsigned int unit_min,
- unsigned int unit_max)
+ unsigned int unit_max,
+ bool dio)
{
/* Confirm that the request type is known */
- stat->result_mask |= STATX_WRITE_ATOMIC_DIO;
-
- /* Confirm that the file attribute type is known */
- stat->attributes_mask |= STATX_ATTR_WRITE_ATOMIC_DIO;
+ if (dio) {
+ /* Confirm that the request type is known */
+ stat->result_mask |= STATX_WRITE_ATOMIC_DIO;
+ /* Confirm that the file attribute type is known */
+ stat->attributes_mask |= STATX_ATTR_WRITE_ATOMIC_DIO;
+ } else {
+ stat->attributes_mask |= STATX_ATTR_WRITE_ATOMIC_BUF;
+ stat->result_mask |= STATX_WRITE_ATOMIC_BUF;
+ }
if (unit_min) {
stat->atomic_write_unit_min = unit_min;
@@ -115,7 +122,10 @@ void generic_fill_statx_atomic_writes(struct kstat *stat,
stat->atomic_write_segments_max = 1;
/* Confirm atomic writes are actually supported */
- stat->attributes |= STATX_ATTR_WRITE_ATOMIC_DIO;
+ if (dio)
+ stat->attributes |= STATX_ATTR_WRITE_ATOMIC_DIO;
+ else
+ stat->attributes |= STATX_ATTR_WRITE_ATOMIC_BUF;
}
}
EXPORT_SYMBOL_GPL(generic_fill_statx_atomic_writes);
@@ -655,7 +655,7 @@ xfs_vn_getattr(
xfs_get_atomic_write_attr(ip, &unit_min, &unit_max);
generic_fill_statx_atomic_writes(stat,
- unit_min, unit_max);
+ unit_min, unit_max, true);
}
fallthrough;
default:
@@ -3243,7 +3243,8 @@ void generic_fillattr(struct mnt_idmap *, u32, struct inode *, struct kstat *);
void generic_fill_statx_attr(struct inode *inode, struct kstat *stat);
void generic_fill_statx_atomic_writes(struct kstat *stat,
unsigned int unit_min,
- unsigned int unit_max);
+ unsigned int unit_max,
+ bool dio);
extern int vfs_getattr_nosec(const struct path *, struct kstat *, u32, unsigned int);
extern int vfs_getattr(const struct path *, struct kstat *, u32, unsigned int);
void __inode_add_bytes(struct inode *inode, loff_t bytes);
@@ -161,6 +161,7 @@ struct statx {
#define STATX_DIOALIGN 0x00002000U /* Want/got direct I/O alignment info */
#define STATX_MNT_ID_UNIQUE 0x00004000U /* Want/got extended stx_mount_id */
#define STATX_WRITE_ATOMIC_DIO 0x00008000U /* Want/got atomic_write_* fields for dio */
+#define STATX_WRITE_ATOMIC_BUF 0x00010000U /* Want/got atomic_write_* fields for non-dio */
#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */
@@ -197,6 +198,7 @@ struct statx {
#define STATX_ATTR_VERITY 0x00100000 /* [I] Verity protected file */
#define STATX_ATTR_DAX 0x00200000 /* File is currently in DAX state */
#define STATX_ATTR_WRITE_ATOMIC_DIO 0x00400000 /* File supports atomic write dio operations */
+#define STATX_ATTR_WRITE_ATOMIC_BUF 0x00800000 /* File supports atomic write non-dio operations */
#endif /* _UAPI_LINUX_STAT_H */
Extend statx system call to return additional info for buffered atomic write support for a file. Currently only direct IO is supported. New flags STATX_WRITE_ATOMIC_BUF and STATX_ATTR_WRITE_ATOMIC_BUF are for indicating whether the file knows and supports buffered atomic writes. Structure statx members stx_atomic_write_unit_{min, max, segments_max} will be reused for bufferd atomic writes. Flags STATX_WRITE_ATOMIC_DIO and STATX_WRITE_ATOMIC_BUF are mutually exclusive. With both flags set, neither fields in statx.result_mask will be set. For buffered atomic writes, stx_atomic_write_unit_{min, max} must hold the same value. Signed-off-by: John Garry <john.g.garry@oracle.com> --- block/bdev.c | 3 ++- fs/stat.c | 26 ++++++++++++++++++-------- fs/xfs/xfs_iops.c | 2 +- include/linux/fs.h | 3 ++- include/uapi/linux/stat.h | 2 ++ 5 files changed, 25 insertions(+), 11 deletions(-)