diff --git a/doc/zio-manual.in b/doc/zio-manual.in index 78f9389719cb155a747563a438f53d40e24e1b94..f4cb74e294dbbec329e827c6cf6622ab64c40d16 100644 --- a/doc/zio-manual.in +++ b/doc/zio-manual.in @@ -915,6 +915,9 @@ the fields are not yet being filled by the core. 5-bit samples aligned in 32-bit words. The number of bits is a device attribute: drivers may allow to change them at run-time. The sample size is however immutable for the lifetime of a cset. + An input driver can reduce @t{nsamples} in the current control, + in order to return a shorter block than requested (the value + is re-initialized every time a trigger is armed). @cindex address of a channel @cindex channel, address @@ -1758,6 +1761,15 @@ or used by the developer are: cset code will call @code{zio_trigger_data_done()} at a later time. Other return values are used to report real errors. +@cindex stop_io +@item void (*stop_io)(struct zio_cset *cset) + + The function, if present, is called when an armed trigger is + aborted. The driver will need to implement this method + if it wants to return a partially-filled block. The method + is called with the lock taken, and can call @t{zio_generic_data_done}, + which is the locked back-end of @t{zio_trigger_data_done}). + @cindex sample size @item unsigned ssize @@ -2158,15 +2170,14 @@ The detailed meaning of the operations is as follows: Abort, if defined, is called when an already-armed trigger event must be aborted. This happens, for example, because event parameters changed (e.g., the block size). The method must - dispose the @i{active_block} for each channel, and set the - pointer to NULL. The trigger may perform @i{data_done} for - partially-filled block. The method + call @t{cset->stop_io} if not NULL and + dispose the @i{active_block} for each channel, setting the + pointer to NULL. Please check how it is used in @t{helpers.c}. + The method is called while holding the cset lock and cannot fail nor sleep. - -@c The trigger will usually call the @i{stop_io} -@c device method and optionally may perform @i{data_done} for -@c partially-filled blocks. The method -@c is called while holding the cset lock and cannot fail nor sleep + A trigger implementing this method will usually call + the @i{stop_io} cset method. See the generic abort implementation + for reference. @item change_status The method, if defined, is called when the trigger is enabled or diff --git a/helpers.c b/helpers.c index 841814e7f58cc5eb64c1cb8b583e0244fc4c15f4..dec070c3fcc246257a2654f98186f8c2f9ac1cc4 100644 --- a/helpers.c +++ b/helpers.c @@ -50,6 +50,8 @@ int zio_trigger_abort_disable(struct zio_cset *cset, int disable) if (ti->flags & ZIO_TI_ARMED) { if (ti->t_op->abort) ti->t_op->abort(ti); + else if (ti->cset->stop_io) + ti->cset->stop_io(ti->cset); else __zio_internal_abort_free(cset); ti->flags &= (~ZIO_TI_ARMED); diff --git a/include/linux/zio-trigger.h b/include/linux/zio-trigger.h index 9ccced7b48b508fe3014d564e4a660207d4e98e3..e2c37c90ac94c14f5dd5bed7303c93d0f505047d 100644 --- a/include/linux/zio-trigger.h +++ b/include/linux/zio-trigger.h @@ -110,8 +110,9 @@ int zio_trigger_abort_disable(struct zio_cset *cset, int disable); /* * This generic_data_done can be used by triggers, as part of their own. - * If not trigger-specific function is specified, the core calls this one. - * When data_done is called, the trigger is armed and the cset lock is taken + * If no trigger-specific function is specified, the core calls this one. + * This can also be called by cset->stop_io to return partial blocks. + * The function is called while holding the cset spin lock. */ static inline void zio_generic_data_done(struct zio_cset *cset) { diff --git a/include/linux/zio.h b/include/linux/zio.h index b82bc0688c45d6c24df5f087da885fcb04b305c0..f2693cce66ffaf7b9a553e3b107cdfc759d35dc2 100644 --- a/include/linux/zio.h +++ b/include/linux/zio.h @@ -175,7 +175,8 @@ struct zio_cset { struct zio_trigger_type *trig; /* trigger type for ti*/ struct zio_ti *ti; /* trigger instance */ int (*raw_io)(struct zio_cset *cset); - spinlock_t lock; /* for flags */ + void (*stop_io)(struct zio_cset *cset); + spinlock_t lock; /* for flags and triggers */ unsigned ssize; /* sample size (bytes) */ unsigned index; /* index within parent */