diff options
author | James Bottomley <JBottomley@Parallels.com> | 2013-06-26 23:08:22 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-26 23:08:22 -0700 |
commit | a9e94ec3504ead4b87a929bc57f5aa99a6590437 (patch) | |
tree | b6e7aaec0e844dc066e93296a85e5769542ef525 /drivers/tty/vt/vt_ioctl.c | |
parent | 36a279686bc02d340eb213a9f2a0b67e50de64b4 (diff) | |
parent | 2884d4230867c8a46cf701214051e923301e7429 (diff) |
Merge tag 'fcoe1' into fixes
This patch fixes a critical bug that was introduced in 3.9
related to VLAN tagging FCoE frames.
Diffstat (limited to 'drivers/tty/vt/vt_ioctl.c')
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 98ff1735eaf..2bd78e2ac8e 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -283,6 +283,48 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_ return 0; } +/* deallocate a single console, if possible (leave 0) */ +static int vt_disallocate(unsigned int vc_num) +{ + struct vc_data *vc = NULL; + int ret = 0; + + console_lock(); + if (VT_BUSY(vc_num)) + ret = -EBUSY; + else if (vc_num) + vc = vc_deallocate(vc_num); + console_unlock(); + + if (vc && vc_num >= MIN_NR_CONSOLES) { + tty_port_destroy(&vc->port); + kfree(vc); + } + + return ret; +} + +/* deallocate all unused consoles, but leave 0 */ +static void vt_disallocate_all(void) +{ + struct vc_data *vc[MAX_NR_CONSOLES]; + int i; + + console_lock(); + for (i = 1; i < MAX_NR_CONSOLES; i++) + if (!VT_BUSY(i)) + vc[i] = vc_deallocate(i); + else + vc[i] = NULL; + console_unlock(); + + for (i = 1; i < MAX_NR_CONSOLES; i++) { + if (vc[i] && i >= MIN_NR_CONSOLES) { + tty_port_destroy(&vc[i]->port); + kfree(vc[i]); + } + } +} /* @@ -769,24 +811,10 @@ int vt_ioctl(struct tty_struct *tty, ret = -ENXIO; break; } - if (arg == 0) { - /* deallocate all unused consoles, but leave 0 */ - console_lock(); - for (i=1; i<MAX_NR_CONSOLES; i++) - if (! VT_BUSY(i)) - vc_deallocate(i); - console_unlock(); - } else { - /* deallocate a single console, if possible */ - arg--; - if (VT_BUSY(arg)) - ret = -EBUSY; - else if (arg) { /* leave 0 */ - console_lock(); - vc_deallocate(arg); - console_unlock(); - } - } + if (arg == 0) + vt_disallocate_all(); + else + ret = vt_disallocate(--arg); break; case VT_RESIZE: |