Messages in this thread |  | | Date | Mon, 27 Jan 1997 11:00:49 +0200 (EET) | From | Linus Torvalds <> | Subject | Re: Small fixes for 2.1.23 |
| |
On Sun, 26 Jan 1997, Ion Badulescu wrote: > > Hi everyone,
Hi there,
> The following patch, relative to 2.1.23, corrects the following > bugs/features:
Ok, the rest of these look ok, but I'm not applying it because of the "poll" buglet..
> - the binfmt_script bug which prevents killall from working on scripts > - the softdog bug which prevents a new daemon from opening the device if > NO_WAY_OUT is defined and the old daemon is killed (e.g. when changing > initlevels) > - the floppy bug - duplicated MODULE_PARM(floppy, "s") - which prevents > floppy.c from compiling > - updates for drivers/sound/* (select->poll) > - finally, my own /proc/swaps patch updated for 2.1.23
The select->poll changes make the source compile, but do not actually do quite the right thing. The poll changes weren't only a matter of naming changes, but also changed semantics somewhat (I don't do naming changes just to change names usually: there is a reason why I didn't want unmodified code to compile - it needs to get subtly fixed first).
Anyway, I should have made the changes clear in my announcement of 2.1.23, but I was too lazy. The changes in the poll behaviour can be broken down into four different sub-areas:
- name change: "select" -> "poll" on the VFS layer - argument change: only "struct file *" and "poll_table *" - return change: instead of returning 0/1, it returns a bitmask of POLL events. The old select code was called three times (once for SEL_IN, once for SEL_OUT and finally once for SEL_EX), while poll() is called just once, and returns a bitmask of all active events. - calling change: we don't call the function twice (like we used to), instead the function is supposed to add the wait entry to the poll_table _first_ before doing the tests (so that any change in state will wake up up correctly without any races - calling the function twice used to do that for us, but was inefficient)
The changes can best be explained by showing a trivial example of a select function that got changed:
static int aux_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) { if (sel_type != SEL_IN) return 0; if (aux_ready) return 1; select_wait(&queue->proc_list, wait); return 0; }
the above got changed to:
static unsigned int aux_poll(struct file *file, poll_table * wait) { poll_wait(&queue->proc_list, wait); if (aux_ready) return POLLIN | POLLRDNORM; return 0; }
Note the differences: calling arguments changed, but most notably the return values changed. Also, the select_wait() _used_ to be last (and only done if we return zero), but in the poll version it is done first and done regardless of what we return (that avoids a race condition - the way linux does wakeups is so subtle to be almost impossible to explain without a whiteboard. Very clever, but subtle).
The above is just a trivial example, and it gets a bit more complex when the old select code used to check for all of SEL_IN/SEL_OUT/SEL_EX (because then the return bitmask becomes more complex to calculate), but it shows the most important changes..
Linus
|  |