On Mon, Nov 8, 2021 at 9:26 PM Ira Weiny <ira.weiny@xxxxxxxxx> wrote: > > On Mon, Nov 08, 2021 at 09:02:29PM +0000, Jane Chu wrote: > > On 11/6/2021 9:48 AM, Dan Williams wrote: > > > On Fri, Nov 5, 2021 at 6:17 PM Jane Chu <jane.chu@xxxxxxxxxx> wrote: > > >> > > >> Introduce DAX_OP_NORMAL and DAX_OP_RECOVERY operation modes to > > >> {dax_direct_access, dax_copy_from_iter, dax_copy_to_iter}. > > >> DAX_OP_NORMAL is the default or the existing mode, and > > >> DAX_OP_RECOVERY is a new mode for data recovery purpose. > > >> > > >> When dax-FS suspects dax media error might be encountered > > >> on a read or write, it can enact the recovery mode read or write > > >> by setting DAX_OP_RECOVERY in the aforementioned APIs. A read > > >> in recovery mode attempts to fetch as much data as possible > > >> until the first poisoned page is encountered. A write in recovery > > >> mode attempts to clear poison(s) in a page-aligned range and > > >> then write the user provided data over. > > >> > > >> DAX_OP_NORMAL should be used for all non-recovery code path. > > >> > > >> Signed-off-by: Jane Chu <jane.chu@xxxxxxxxxx> > > > [..] > > >> diff --git a/include/linux/dax.h b/include/linux/dax.h > > >> index 324363b798ec..931586df2905 100644 > > >> --- a/include/linux/dax.h > > >> +++ b/include/linux/dax.h > > >> @@ -9,6 +9,10 @@ > > >> /* Flag for synchronous flush */ > > >> #define DAXDEV_F_SYNC (1UL << 0) > > >> > > >> +/* dax operation mode dynamically set by caller */ > > >> +#define DAX_OP_NORMAL 0 > > > > > > Perhaps this should be called DAX_OP_FAILFAST? > > > > Sure. > > > > > > > >> +#define DAX_OP_RECOVERY 1 > > >> + > > >> typedef unsigned long dax_entry_t; > > >> > > >> struct dax_device; > > >> @@ -22,8 +26,8 @@ struct dax_operations { > > >> * logical-page-offset into an absolute physical pfn. Return the > > >> * number of pages available for DAX at that pfn. > > >> */ > > >> - long (*direct_access)(struct dax_device *, pgoff_t, long, > > >> - void **, pfn_t *); > > >> + long (*direct_access)(struct dax_device *, pgoff_t, long, int, > > > > > > Would be nice if that 'int' was an enum, but I'm not sure a new > > > parameter is needed at all, see below... > > > > Let's do your suggestion below. :) > > > > > > > >> + void **, pfn_t *); > > >> /* > > >> * Validate whether this device is usable as an fsdax backing > > >> * device. > > >> @@ -32,10 +36,10 @@ struct dax_operations { > > >> sector_t, sector_t); > > >> /* copy_from_iter: required operation for fs-dax direct-i/o */ > > >> size_t (*copy_from_iter)(struct dax_device *, pgoff_t, void *, size_t, > > >> - struct iov_iter *); > > >> + struct iov_iter *, int); > > > > > > I'm not sure the flag is needed here as the "void *" could carry a > > > flag in the pointer to indicate that is a recovery kaddr. > > > > Agreed. > > Not sure if this is implied but I would like some macros or other helper > functions to check these flags hidden in the addresses. > > For me I'm a bit scared about having flags hidden in the address like this > because I can't lead to some confusions IMO. > > But if we have some macros or other calls which can make this more obvious of > what is going on I think that would help. You could go further and mark it as an 'unsigned long __bitwise' type to get the compiler to help with enforcing accessors to strip off the flag bits.