Enable zone-append using existing O_APPEND and RWF_APPEND infra. Unlike file-append, zone-apppend requires bit of additional processing in common path to send completion-result to upper layer. To skip that for non-zoned block-devices/files, introduce FMODE_ZONE_APPEND and IOCB_ZONE_APPEND. When a file is opened, it can subscribe to zone-append by setting FMODE_ZONE_APPEND. Add IOCB_ZONE_APPEND which is set in kiocb->ki_flags if write meets existing file-append critera, and file has subscribed to zone-append. Signed-off-by: Selvakumar S <selvakuma.s1@xxxxxxxxxxx> Signed-off-by: Kanchan Joshi <joshi.k@xxxxxxxxxxx> Signed-off-by: Nitesh Shetty <nj.shetty@xxxxxxxxxxx> Signed-off-by: Javier Gonzalez <javier.gonz@xxxxxxxxxxx> --- include/linux/fs.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 6c4ab4d..ef13df4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -175,6 +175,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, /* File does not contribute to nr_files count */ #define FMODE_NOACCOUNT ((__force fmode_t)0x20000000) +/* File can support zone-append */ +#define FMODE_ZONE_APPEND ((__force fmode_t)0x40000000) + /* * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector * that indicates that they should check the contents of the iovec are @@ -315,6 +318,7 @@ enum rw_hint { #define IOCB_SYNC (1 << 5) #define IOCB_WRITE (1 << 6) #define IOCB_NOWAIT (1 << 7) +#define IOCB_ZONE_APPEND (1 << 8) struct kiocb { struct file *ki_filp; @@ -3427,8 +3431,11 @@ static inline bool vma_is_fsdax(struct vm_area_struct *vma) static inline int iocb_flags(struct file *file) { int res = 0; - if (file->f_flags & O_APPEND) + if (file->f_flags & O_APPEND) { res |= IOCB_APPEND; + if (file->f_mode & FMODE_ZONE_APPEND) + res |= IOCB_ZONE_APPEND; + } if (file->f_flags & O_DIRECT) res |= IOCB_DIRECT; if ((file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host)) @@ -3454,8 +3461,11 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags) ki->ki_flags |= IOCB_DSYNC; if (flags & RWF_SYNC) ki->ki_flags |= (IOCB_DSYNC | IOCB_SYNC); - if (flags & RWF_APPEND) + if (flags & RWF_APPEND) { ki->ki_flags |= IOCB_APPEND; + if (ki->ki_filp->f_mode & FMODE_ZONE_APPEND) + ki->ki_flags |= IOCB_ZONE_APPEND; + } return 0; } -- 2.7.4