I've found an inconsistency in the way that some nodes in sysfs handle writes, particularly by writev. I've attached a simple program which illustrates this behavior (I'll call it ./writev from now on). Running "./writev /sys/kernel/mm/ksm/run 1" yields the expected result -- /sys/kernel/mm/ksm/run will contain "1". I notice, via strace, that the newline appears to be discarded: # strace -e writev ./writev /sys/kernel/mm/ksm/run 1 writev(3, [{"1", 1}, {"\n", 1}], 2) = 1 However, running "./writev /sys/class/sda/queue/read_ahead_kb 1024" results in a "0" being stored. This time, strace shows that the entire 5 bytes is written. # strace -e writev ./writev /sys/class/block/sda/queue/read_ahead_kb 1024 writev(3, [{"1024", 4}, {"\n", 1}], 2) = 5 Using fprintf, which boils down to a single write syscall, I get the expected behavior in both cases.
Created attachment 79161 [details] test program to show behavior
As I suspected, this is being treated as 2 separate writes. I added a printk to the queue_var_store function in block/blk-sysfs.c, and dmesg now shows the below when I call the equivalent of "./writev /sys/class/block/sda/queue/read_ahead_kb 1024". [ 0.892319] queue_var_store: 1024 [ 0.892704] queue_var_store: 0
And the root of the issue doesn't seem to be the two writes, but the fact that queue_var_store does not seem to not reject invalid values, and the callers of this function never expect it to fail. I would have expected that writing a letter to queue/read_ahead_kb would just return EINVAL, but it instead stores a 0 in the node. I'm attaching a diff against linus's tree which illustrates this and fixes the immediate issue, but I don't expect this to be a proper/complete fix.
Created attachment 79171 [details] return and check errors from queue_var_store
Please send patches, with a Signed-off-by: line to linux-kernel@vger.kernel.org, we can't accept them without the Signed-off-by: line. thanks
Closing as I don't take patches from bugzilla
This should have been closed as fixed -- my change was merged via LKML by Jens Axboe: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b1f3b64d76cf88cc
A patch referencing this bug report has been merged in Linux v3.7-rc1: commit b1f3b64d76cf88cc250e5cdd1de783ba9737078e Author: Dave Reisner <dreisner@archlinux.org> Date: Sat Sep 8 11:55:45 2012 -0400 block: reject invalid queue attribute values