diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index c344bf987b63..63ea5417de84 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -173,7 +173,9 @@ struct liveupdate_flb_ops { * @lock: A mutex that protects all fields within this structure, providing * the synchronization service for the FLB's ops. * @finished: True once the FLB's finish() callback has run. - * @retrieved: True once the FLB's retrieve() callback has run. + * @retrieve_status: Status code indicating whether retrieve() has been + * attempted. 0 means not attempted, 1 means successful, + * and negative value means it failed with that error code. */ struct luo_flb_private_state { refcount_t count; @@ -181,7 +183,7 @@ struct luo_flb_private_state { void *obj; struct mutex lock; bool finished; - bool retrieved; + int retrieve_status; }; /* diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index 02b449e1e98b..cd715a7c1d99 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -168,7 +168,10 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb) if (private->incoming.finished) return -ENODATA; - if (private->incoming.retrieved) + if (private->incoming.retrieve_status < 0) + return private->incoming.retrieve_status; + + if (private->incoming.retrieve_status > 0) return 0; if (!fh->active) @@ -194,12 +197,13 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb) err = flb->ops->retrieve(&args); if (err) { + private->incoming.retrieve_status = err; module_put(flb->ops->owner); return err; } private->incoming.obj = args.obj; - private->incoming.retrieved = true; + private->incoming.retrieve_status = 1; return 0; } @@ -213,7 +217,7 @@ void liveupdate_flb_put_incoming(struct liveupdate_flb *flb) if (!refcount_dec_and_test(&private->incoming.count)) return; - if (!private->incoming.retrieved) { + if (private->incoming.retrieve_status <= 0) { int err = luo_flb_retrieve_one(flb); if (WARN_ON(err))