On Sun, 2016-04-10 at 11:33 -0700, Greg Kroah-Hartman wrote: > 4.5-stable review patch. If anyone has any objections, please let me know. I've dropped stable because this isn't actually broken, but... > ------------------ > > From: Joe Thornber <ejt@xxxxxxxxxx> > > commit d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b upstream. > > Otherwise operations may be attempted that will only ever go on to crash > (since the metadata device is either missing or unreliable if 'fail_io' > is set). > > Signed-off-by: Joe Thornber <ejt@xxxxxxxxxx> > Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> > Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > > --- > drivers/md/dm-cache-metadata.c | 98 ++++++++++++++++++++++++----------------- > drivers/md/dm-cache-metadata.h | 4 - > drivers/md/dm-cache-target.c | 12 ++++- > 3 files changed, 71 insertions(+), 43 deletions(-) > > --- a/drivers/md/dm-cache-metadata.c > +++ b/drivers/md/dm-cache-metadata.c > @@ -867,19 +867,40 @@ static int blocks_are_unmapped_or_clean( > return 0; > } > > -#define WRITE_LOCK(cmd) \ > - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ > +#define WRITE_LOCK(cmd) \ > + down_write(&cmd->root_lock); \ > + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ > + up_write(&cmd->root_lock); \ > return -EINVAL; \ > - down_write(&cmd->root_lock) > + } > > #define WRITE_LOCK_VOID(cmd) \ > - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ > + down_write(&cmd->root_lock); \ > + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ > + up_write(&cmd->root_lock); \ > return; \ > - down_write(&cmd->root_lock) > + } Whenever a macro expands to multiple statements they should be wrapped up in do { ... } while (0) so the macro is safe to use in other compound statements. That's not a regression for these existing macros, but: > #define WRITE_UNLOCK(cmd) \ > up_write(&cmd->root_lock) > > +#define READ_LOCK(cmd) \ > + down_read(&cmd->root_lock); \ > + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ > + up_read(&cmd->root_lock); \ > + return -EINVAL; \ > + } > + > +#define READ_LOCK_VOID(cmd) \ > + down_read(&cmd->root_lock); \ > + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ > + up_read(&cmd->root_lock); \ > + return; \ > + } [...] here you're repeating the same broken pattern in new macros. Which checkpatch.pl would have complained about, if you'd thought to run it. Hiding return statements in macros is another bad idea (who expects exceptions in C?). And once we reject that bad idea, all these macros can be inline functions, like: static inline bool dm_cm_read_lock(struct dm_cache_metadata *cmd) { down_read(&cmd->root_lock); if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { up_read(&cmd->root_lock); return false; } return true; } /* ... */ if (!dm_cm_read_lock(cmd)) return -EINVAL; Actually... I said this wasn't broken, but should the READ_LOCK macros really fail in case dm_bm_is_read_only(), or only if cmd->fail_io? Ben. -- Ben Hutchings This sentence contradicts itself - no actually it doesn't.
Attachment:
signature.asc
Description: This is a digitally signed message part
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel