From: Stanislav Kinsbursky Date: Fri, 9 Nov 2012 03:05:07 +0000 (+1100) Subject: ipc: cleanup do_msgrcv() around MSG_COPY feature X-Git-Tag: next-20121112~5^2~38 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=d9e3a813ba12473fe5a3e4fbd201b02139715128;p=karo-tx-linux.git ipc: cleanup do_msgrcv() around MSG_COPY feature MSG_COPY feature was developed for Checkpoint/Restart In User space project and thus wrapped in CONFIG_CHECKPOINT_RESTORE macro. But code look a bit ugly. So this patch is an attempt to cleanup do_msgrcv() a bit and make it looks better. Signed-off-by: Stanislav Kinsbursky Cc: Serge Hallyn Cc: "Eric W. Biederman" Cc: Pavel Emelyanov Cc: KOSAKI Motohiro Signed-off-by: Andrew Morton --- diff --git a/ipc/msg.c b/ipc/msg.c index 91873dfb2e5f..d20ffc7d3f24 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -769,6 +769,45 @@ static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) return msgsz; } +#ifdef CONFIG_CHECKPOINT_RESTORE +static inline struct msg_msg *fill_copy(unsigned long copy_nr, + unsigned long msg_nr, + struct msg_msg *msg, + struct msg_msg *copy) +{ + if (copy_nr == msg_nr) + return copy_msg(msg, copy); + return NULL; +} + +static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz, + int msgflg, long *msgtyp, + unsigned long *copy_number) +{ + struct msg_msg *copy; + + *copy_number = *msgtyp; + *msgtyp = 0; + /* + * Create dummy message to copy real message to. + */ + copy = load_msg(buf, bufsz); + if (!IS_ERR(copy)) + copy->m_ts = bufsz; + return copy; +} + +static inline void free_copy(int msgflg, struct msg_msg *copy) +{ + if (msgflg & MSG_COPY) + free_msg(copy); +} +#else +#define free_copy(msgflg, copy) do {} while (0) +#define prepare_copy(buf, sz, msgflg, msgtyp, copy_nr) ERR_PTR(-ENOSYS) +#define fill_copy(copy_nr, msg_nr, msg, copy) NULL +#endif + long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, long (*msg_handler)(void __user *, struct msg_msg *, size_t)) @@ -777,38 +816,22 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, struct msg_msg *msg; int mode; struct ipc_namespace *ns; -#ifdef CONFIG_CHECKPOINT_RESTORE - struct msg_msg *copy = NULL; - unsigned long copy_number = 0; -#endif + struct msg_msg *copy; + unsigned long __maybe_unused copy_number; if (msqid < 0 || (long) bufsz < 0) return -EINVAL; if (msgflg & MSG_COPY) { -#ifdef CONFIG_CHECKPOINT_RESTORE - copy_number = msgtyp; - msgtyp = 0; - - /* - * Create dummy message to copy real message to. - */ - copy = load_msg(buf, bufsz); + copy = prepare_copy(buf, bufsz, msgflg, &msgtyp, ©_number); if (IS_ERR(copy)) return PTR_ERR(copy); - copy->m_ts = bufsz; -#else - return -ENOSYS; -#endif } mode = convert_mode(&msgtyp, msgflg); ns = current->nsproxy->ipc_ns; msq = msg_lock_check(ns, msqid); if (IS_ERR(msq)) { -#ifdef CONFIG_CHECKPOINT_RESTORE - if (msgflg & MSG_COPY) - free_msg(copy); -#endif + free_copy(msgflg, copy); return PTR_ERR(msq); } @@ -835,13 +858,12 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, if (mode == SEARCH_LESSEQUAL && walk_msg->m_type != 1) { msgtyp = walk_msg->m_type - 1; -#ifdef CONFIG_CHECKPOINT_RESTORE } else if (msgflg & MSG_COPY) { - if (copy_number == msg_counter) { - msg = copy_msg(walk_msg, copy); + msg = fill_copy(copy_number, + msg_counter, + walk_msg, copy); + if (msg) break; - } -#endif } else break; msg_counter++; @@ -857,10 +879,8 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, msg = ERR_PTR(-E2BIG); goto out_unlock; } -#ifdef CONFIG_CHECKPOINT_RESTORE if (msgflg & MSG_COPY) goto out_unlock; -#endif list_del(&msg->m_list); msq->q_qnum--; msq->q_rtime = get_seconds(); @@ -945,10 +965,7 @@ out_unlock: } } if (IS_ERR(msg)) { -#ifdef CONFIG_CHECKPOINT_RESTORE - if (msgflg & MSG_COPY) - free_msg(copy); -#endif + free_copy(msgflg, copy); return PTR_ERR(msg); }