Commit dca14191 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

tty/vt: consolemap: extract dict unsharing to con_unshare_unimap()

The code in con_set_unimap() is too nested. Extract its obvious part
into a separate function and name it after what the code does:
con_unshare_unimap().
Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20220607104946.18710-19-jslaby@suse.czSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f052f62c
...@@ -563,49 +563,28 @@ int con_clear_unimap(struct vc_data *vc) ...@@ -563,49 +563,28 @@ int con_clear_unimap(struct vc_data *vc)
return ret; return ret;
} }
int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) static struct uni_pagedict *con_unshare_unimap(struct vc_data *vc,
struct uni_pagedict *p)
{ {
int err = 0, err1, i; struct uni_pagedict *q;
struct uni_pagedict *p, *q;
struct unipair *unilist, *plist;
if (!ct)
return 0;
unilist = vmemdup_user(list, array_size(sizeof(*unilist), ct));
if (IS_ERR(unilist))
return PTR_ERR(unilist);
console_lock();
/* Save original vc_unipagdir_loc in case we allocate a new one */
p = *vc->vc_uni_pagedir_loc;
if (!p) {
err = -EINVAL;
goto out_unlock;
}
if (p->refcount > 1) {
int j, k;
u16 **p1, *p2, l; u16 **p1, *p2, l;
int ret;
int i, j, k;
err1 = con_do_clear_unimap(vc); ret = con_do_clear_unimap(vc);
if (err1) { if (ret)
err = err1; return ERR_PTR(ret);
goto out_unlock;
}
/* /*
* Since refcount was > 1, con_clear_unimap() allocated a * Since refcount was > 1, con_clear_unimap() allocated a new
* a new uni_pagedict for this vc. Re: p != q * uni_pagedict for this vc. Re: p != q
*/ */
q = *vc->vc_uni_pagedir_loc; q = *vc->vc_uni_pagedir_loc;
/* /*
* uni_pgdir is a 32*32*64 table with rows allocated * uni_pgdir is a 32*32*64 table with rows allocated when its first
* when its first entry is added. The unicode value must * entry is added. The unicode value must still be incremented for
* still be incremented for empty rows. We are copying * empty rows. We are copying entries from "p" (old) to "q" (new).
* entries from "p" (old) to "q" (new).
*/ */
l = 0; /* unicode value */ l = 0; /* unicode value */
for (i = 0; i < UNI_DIRS; i++) { for (i = 0; i < UNI_DIRS; i++) {
...@@ -619,9 +598,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) ...@@ -619,9 +598,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
for (j = 0; j < UNI_DIR_ROWS; j++) { for (j = 0; j < UNI_DIR_ROWS; j++) {
p2 = p1[j]; p2 = p1[j];
if (!p2) { if (!p2) {
/* /* Account for row of 64 empty entries */
* Account for row of 64 empty entries
*/
l += UNI_ROW_GLYPHS; l += UNI_ROW_GLYPHS;
continue; continue;
} }
...@@ -630,26 +607,52 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) ...@@ -630,26 +607,52 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
if (p2[k] == 0xffff) if (p2[k] == 0xffff)
continue; continue;
/* /*
* Found one, copy entry for unicode * Found one, copy entry for unicode l with
* l with fontpos value p2[k]. * fontpos value p2[k].
*/ */
err1 = con_insert_unipair(q, l, p2[k]); ret = con_insert_unipair(q, l, p2[k]);
if (err1) { if (ret) {
p->refcount++; p->refcount++;
*vc->vc_uni_pagedir_loc = p; *vc->vc_uni_pagedir_loc = p;
con_release_unimap(q); con_release_unimap(q);
kfree(q); kfree(q);
err = err1; return ERR_PTR(ret);
goto out_unlock;
} }
} }
} }
} }
/* return q;
* Finished copying font table, set vc_uni_pagedir to new table }
*/
p = q; int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
{
int err = 0, err1;
struct uni_pagedict *p;
struct unipair *unilist, *plist;
if (!ct)
return 0;
unilist = vmemdup_user(list, array_size(sizeof(*unilist), ct));
if (IS_ERR(unilist))
return PTR_ERR(unilist);
console_lock();
/* Save original vc_unipagdir_loc in case we allocate a new one */
p = *vc->vc_uni_pagedir_loc;
if (!p) {
err = -EINVAL;
goto out_unlock;
}
if (p->refcount > 1) {
p = con_unshare_unimap(vc, p);
if (IS_ERR(p)) {
err = PTR_ERR(p);
goto out_unlock;
}
} else if (p == dflt) { } else if (p == dflt) {
dflt = NULL; dflt = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment