diff options
51 files changed, 595 insertions, 457 deletions
diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index d882f8093871..dcff4d0623ad 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power | |||
| @@ -21,7 +21,7 @@ Description: | |||
| 21 | these states. | 21 | these states. |
| 22 | 22 | ||
| 23 | What: /sys/power/disk | 23 | What: /sys/power/disk |
| 24 | Date: August 2006 | 24 | Date: September 2006 |
| 25 | Contact: Rafael J. Wysocki <rjw@sisk.pl> | 25 | Contact: Rafael J. Wysocki <rjw@sisk.pl> |
| 26 | Description: | 26 | Description: |
| 27 | The /sys/power/disk file controls the operating mode of the | 27 | The /sys/power/disk file controls the operating mode of the |
| @@ -39,6 +39,19 @@ Description: | |||
| 39 | 'reboot' - the memory image will be saved by the kernel and | 39 | 'reboot' - the memory image will be saved by the kernel and |
| 40 | the system will be rebooted. | 40 | the system will be rebooted. |
| 41 | 41 | ||
| 42 | Additionally, /sys/power/disk can be used to turn on one of the | ||
| 43 | two testing modes of the suspend-to-disk mechanism: 'testproc' | ||
| 44 | or 'test'. If the suspend-to-disk mechanism is in the | ||
| 45 | 'testproc' mode, writing 'disk' to /sys/power/state will cause | ||
| 46 | the kernel to disable nonboot CPUs and freeze tasks, wait for 5 | ||
| 47 | seconds, unfreeze tasks and enable nonboot CPUs. If it is in | ||
| 48 | the 'test' mode, writing 'disk' to /sys/power/state will cause | ||
| 49 | the kernel to disable nonboot CPUs and freeze tasks, shrink | ||
| 50 | memory, suspend devices, wait for 5 seconds, resume devices, | ||
| 51 | unfreeze tasks and enable nonboot CPUs. Then, we are able to | ||
| 52 | look in the log messages and work out, for example, which code | ||
| 53 | is being slow and which device drivers are misbehaving. | ||
| 54 | |||
| 42 | The suspend-to-disk method may be chosen by writing to this | 55 | The suspend-to-disk method may be chosen by writing to this |
| 43 | file one of the accepted strings: | 56 | file one of the accepted strings: |
| 44 | 57 | ||
| @@ -46,6 +59,8 @@ Description: | |||
| 46 | 'platform' | 59 | 'platform' |
| 47 | 'shutdown' | 60 | 'shutdown' |
| 48 | 'reboot' | 61 | 'reboot' |
| 62 | 'testproc' | ||
| 63 | 'test' | ||
| 49 | 64 | ||
| 50 | It will only change to 'firmware' or 'platform' if the system | 65 | It will only change to 'firmware' or 'platform' if the system |
| 51 | supports that. | 66 | supports that. |
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 3bf5086574bc..db9499adbed4 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ | 9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ |
| 10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ | 10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ |
| 11 | procfs-guide.xml writing_usb_driver.xml \ | 11 | procfs-guide.xml writing_usb_driver.xml \ |
| 12 | kernel-api.xml filesystems.xml journal-api.xml lsm.xml usb.xml \ | 12 | kernel-api.xml filesystems.xml lsm.xml usb.xml \ |
| 13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ | 13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ |
| 14 | genericirq.xml | 14 | genericirq.xml |
| 15 | 15 | ||
diff --git a/Documentation/DocBook/filesystems.tmpl b/Documentation/DocBook/filesystems.tmpl index 4785032fb6ea..39fa2aba7f9b 100644 --- a/Documentation/DocBook/filesystems.tmpl +++ b/Documentation/DocBook/filesystems.tmpl | |||
| @@ -98,4 +98,304 @@ | |||
| 98 | </sect1> | 98 | </sect1> |
| 99 | </chapter> | 99 | </chapter> |
| 100 | 100 | ||
| 101 | <chapter id="LinuxJDBAPI"> | ||
| 102 | <chapterinfo> | ||
| 103 | <title>The Linux Journalling API</title> | ||
| 104 | |||
| 105 | <authorgroup> | ||
| 106 | <author> | ||
| 107 | <firstname>Roger</firstname> | ||
| 108 | <surname>Gammans</surname> | ||
| 109 | <affiliation> | ||
| 110 | <address> | ||
| 111 | <email>rgammans@computer-surgery.co.uk</email> | ||
| 112 | </address> | ||
| 113 | </affiliation> | ||
| 114 | </author> | ||
| 115 | </authorgroup> | ||
| 116 | |||
| 117 | <authorgroup> | ||
| 118 | <author> | ||
| 119 | <firstname>Stephen</firstname> | ||
| 120 | <surname>Tweedie</surname> | ||
| 121 | <affiliation> | ||
| 122 | <address> | ||
| 123 | <email>sct@redhat.com</email> | ||
| 124 | </address> | ||
| 125 | </affiliation> | ||
| 126 | </author> | ||
| 127 | </authorgroup> | ||
| 128 | |||
| 129 | <copyright> | ||
| 130 | <year>2002</year> | ||
| 131 | <holder>Roger Gammans</holder> | ||
| 132 | </copyright> | ||
| 133 | </chapterinfo> | ||
| 134 | |||
| 135 | <title>The Linux Journalling API</title> | ||
| 136 | |||
| 137 | <sect1> | ||
| 138 | <title>Overview</title> | ||
| 139 | <sect2> | ||
| 140 | <title>Details</title> | ||
| 141 | <para> | ||
| 142 | The journalling layer is easy to use. You need to | ||
| 143 | first of all create a journal_t data structure. There are | ||
| 144 | two calls to do this dependent on how you decide to allocate the physical | ||
| 145 | media on which the journal resides. The journal_init_inode() call | ||
| 146 | is for journals stored in filesystem inodes, or the journal_init_dev() | ||
| 147 | call can be use for journal stored on a raw device (in a continuous range | ||
| 148 | of blocks). A journal_t is a typedef for a struct pointer, so when | ||
| 149 | you are finally finished make sure you call journal_destroy() on it | ||
| 150 | to free up any used kernel memory. | ||
| 151 | </para> | ||
| 152 | |||
| 153 | <para> | ||
| 154 | Once you have got your journal_t object you need to 'mount' or load the journal | ||
| 155 | file, unless of course you haven't initialised it yet - in which case you | ||
| 156 | need to call journal_create(). | ||
| 157 | </para> | ||
| 158 | |||
| 159 | <para> | ||
| 160 | Most of the time however your journal file will already have been created, but | ||
| 161 | before you load it you must call journal_wipe() to empty the journal file. | ||
| 162 | Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the | ||
| 163 | job of the client file system to detect this and skip the call to journal_wipe(). | ||
| 164 | </para> | ||
| 165 | |||
| 166 | <para> | ||
| 167 | In either case the next call should be to journal_load() which prepares the | ||
| 168 | journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() | ||
| 169 | for you if it detects any outstanding transactions in the journal and similarly | ||
| 170 | journal_load() will call journal_recover() if necessary. | ||
| 171 | I would advise reading fs/ext3/super.c for examples on this stage. | ||
| 172 | [RGG: Why is the journal_wipe() call necessary - doesn't this needlessly | ||
| 173 | complicate the API. Or isn't a good idea for the journal layer to hide | ||
| 174 | dirty mounts from the client fs] | ||
| 175 | </para> | ||
| 176 | |||
| 177 | <para> | ||
| 178 | Now you can go ahead and start modifying the underlying | ||
| 179 | filesystem. Almost. | ||
| 180 | </para> | ||
| 181 | |||
| 182 | <para> | ||
| 183 | |||
| 184 | You still need to actually journal your filesystem changes, this | ||
| 185 | is done by wrapping them into transactions. Additionally you | ||
| 186 | also need to wrap the modification of each of the buffers | ||
| 187 | with calls to the journal layer, so it knows what the modifications | ||
| 188 | you are actually making are. To do this use journal_start() which | ||
| 189 | returns a transaction handle. | ||
| 190 | </para> | ||
| 191 | |||
| 192 | <para> | ||
| 193 | journal_start() | ||
| 194 | and its counterpart journal_stop(), which indicates the end of a transaction | ||
| 195 | are nestable calls, so you can reenter a transaction if necessary, | ||
| 196 | but remember you must call journal_stop() the same number of times as | ||
| 197 | journal_start() before the transaction is completed (or more accurately | ||
| 198 | leaves the update phase). Ext3/VFS makes use of this feature to simplify | ||
| 199 | quota support. | ||
| 200 | </para> | ||
| 201 | |||
| 202 | <para> | ||
| 203 | Inside each transaction you need to wrap the modifications to the | ||
| 204 | individual buffers (blocks). Before you start to modify a buffer you | ||
| 205 | need to call journal_get_{create,write,undo}_access() as appropriate, | ||
| 206 | this allows the journalling layer to copy the unmodified data if it | ||
| 207 | needs to. After all the buffer may be part of a previously uncommitted | ||
| 208 | transaction. | ||
| 209 | At this point you are at last ready to modify a buffer, and once | ||
| 210 | you are have done so you need to call journal_dirty_{meta,}data(). | ||
| 211 | Or if you've asked for access to a buffer you now know is now longer | ||
| 212 | required to be pushed back on the device you can call journal_forget() | ||
| 213 | in much the same way as you might have used bforget() in the past. | ||
| 214 | </para> | ||
| 215 | |||
| 216 | <para> | ||
| 217 | A journal_flush() may be called at any time to commit and checkpoint | ||
| 218 | all your transactions. | ||
| 219 | </para> | ||
| 220 | |||
| 221 | <para> | ||
| 222 | Then at umount time , in your put_super() (2.4) or write_super() (2.5) | ||
| 223 | you can then call journal_destroy() to clean up your in-core journal object. | ||
| 224 | </para> | ||
| 225 | |||
| 226 | <para> | ||
| 227 | Unfortunately there a couple of ways the journal layer can cause a deadlock. | ||
| 228 | The first thing to note is that each task can only have | ||
| 229 | a single outstanding transaction at any one time, remember nothing | ||
| 230 | commits until the outermost journal_stop(). This means | ||
| 231 | you must complete the transaction at the end of each file/inode/address | ||
| 232 | etc. operation you perform, so that the journalling system isn't re-entered | ||
| 233 | on another journal. Since transactions can't be nested/batched | ||
| 234 | across differing journals, and another filesystem other than | ||
| 235 | yours (say ext3) may be modified in a later syscall. | ||
| 236 | </para> | ||
| 237 | |||
| 238 | <para> | ||
| 239 | The second case to bear in mind is that journal_start() can | ||
| 240 | block if there isn't enough space in the journal for your transaction | ||
| 241 | (based on the passed nblocks param) - when it blocks it merely(!) needs to | ||
| 242 | wait for transactions to complete and be committed from other tasks, | ||
| 243 | so essentially we are waiting for journal_stop(). So to avoid | ||
| 244 | deadlocks you must treat journal_start/stop() as if they | ||
| 245 | were semaphores and include them in your semaphore ordering rules to prevent | ||
| 246 | deadlocks. Note that journal_extend() has similar blocking behaviour to | ||
| 247 | journal_start() so you can deadlock here just as easily as on journal_start(). | ||
| 248 | </para> | ||
| 249 | |||
| 250 | <para> | ||
| 251 | Try to reserve the right number of blocks the first time. ;-). This will | ||
| 252 | be the maximum number of blocks you are going to touch in this transaction. | ||
| 253 | I advise having a look at at least ext3_jbd.h to see the basis on which | ||
| 254 | ext3 uses to make these decisions. | ||
| 255 | </para> | ||
| 256 | |||
| 257 | <para> | ||
| 258 | Another wriggle to watch out for is your on-disk block allocation strategy. | ||
| 259 | why? Because, if you undo a delete, you need to ensure you haven't reused any | ||
| 260 | of the freed blocks in a later transaction. One simple way of doing this | ||
| 261 | is make sure any blocks you allocate only have checkpointed transactions | ||
| 262 | listed against them. Ext3 does this in ext3_test_allocatable(). | ||
| 263 | </para> | ||
| 264 | |||
| 265 | <para> | ||
| 266 | Lock is also providing through journal_{un,}lock_updates(), | ||
| 267 | ext3 uses this when it wants a window with a clean and stable fs for a moment. | ||
| 268 | eg. | ||
| 269 | </para> | ||
| 270 | |||
| 271 | <programlisting> | ||
| 272 | |||
| 273 | journal_lock_updates() //stop new stuff happening.. | ||
| 274 | journal_flush() // checkpoint everything. | ||
| 275 | ..do stuff on stable fs | ||
| 276 | journal_unlock_updates() // carry on with filesystem use. | ||
| 277 | </programlisting> | ||
| 278 | |||
| 279 | <para> | ||
| 280 | The opportunities for abuse and DOS attacks with this should be obvious, | ||
| 281 | if you allow unprivileged userspace to trigger codepaths containing these | ||
| 282 | calls. | ||
| 283 | </para> | ||
| 284 | |||
| 285 | <para> | ||
| 286 | A new feature of jbd since 2.5.25 is commit callbacks with the new | ||
| 287 | journal_callback_set() function you can now ask the journalling layer | ||
| 288 | to call you back when the transaction is finally committed to disk, so that | ||
| 289 | you can do some of your own management. The key to this is the journal_callback | ||
| 290 | struct, this maintains the internal callback information but you can | ||
| 291 | extend it like this:- | ||
| 292 | </para> | ||
| 293 | <programlisting> | ||
| 294 | struct myfs_callback_s { | ||
| 295 | //Data structure element required by jbd.. | ||
| 296 | struct journal_callback for_jbd; | ||
| 297 | // Stuff for myfs allocated together. | ||
| 298 | myfs_inode* i_commited; | ||
| 299 | |||
| 300 | } | ||
| 301 | </programlisting> | ||
| 302 | |||
| 303 | <para> | ||
| 304 | this would be useful if you needed to know when data was committed to a | ||
| 305 | particular inode. | ||
| 306 | </para> | ||
| 307 | |||
| 308 | </sect2> | ||
| 309 | |||
| 310 | <sect2> | ||
| 311 | <title>Summary</title> | ||
| 312 | <para> | ||
| 313 | Using the journal is a matter of wrapping the different context changes, | ||
| 314 | being each mount, each modification (transaction) and each changed buffer | ||
| 315 | to tell the journalling layer about them. | ||
| 316 | </para> | ||
| 317 | |||
| 318 | <para> | ||
| 319 | Here is a some pseudo code to give you an idea of how it works, as | ||
| 320 | an example. | ||
| 321 | </para> | ||
| 322 | |||
| 323 | <programlisting> | ||
| 324 | journal_t* my_jnrl = journal_create(); | ||
| 325 | journal_init_{dev,inode}(jnrl,...) | ||
| 326 | if (clean) journal_wipe(); | ||
| 327 | journal_load(); | ||
| 328 | |||
| 329 | foreach(transaction) { /*transactions must be | ||
| 330 | completed before | ||
| 331 | a syscall returns to | ||
| 332 | userspace*/ | ||
| 333 | |||
| 334 | handle_t * xct=journal_start(my_jnrl); | ||
| 335 | foreach(bh) { | ||
| 336 | journal_get_{create,write,undo}_access(xact,bh); | ||
| 337 | if ( myfs_modify(bh) ) { /* returns true | ||
| 338 | if makes changes */ | ||
| 339 | journal_dirty_{meta,}data(xact,bh); | ||
| 340 | } else { | ||
| 341 | journal_forget(bh); | ||
| 342 | } | ||
| 343 | } | ||
| 344 | journal_stop(xct); | ||
| 345 | } | ||
| 346 | journal_destroy(my_jrnl); | ||
| 347 | </programlisting> | ||
| 348 | </sect2> | ||
| 349 | |||
| 350 | </sect1> | ||
| 351 | |||
| 352 | <sect1> | ||
| 353 | <title>Data Types</title> | ||
| 354 | <para> | ||
| 355 | The journalling layer uses typedefs to 'hide' the concrete definitions | ||
| 356 | of the structures used. As a client of the JBD layer you can | ||
| 357 | just rely on the using the pointer as a magic cookie of some sort. | ||
| 358 | |||
| 359 | Obviously the hiding is not enforced as this is 'C'. | ||
| 360 | </para> | ||
| 361 | <sect2><title>Structures</title> | ||
| 362 | !Iinclude/linux/jbd.h | ||
| 363 | </sect2> | ||
| 364 | </sect1> | ||
| 365 | |||
| 366 | <sect1> | ||
| 367 | <title>Functions</title> | ||
| 368 | <para> | ||
| 369 | The functions here are split into two groups those that | ||
| 370 | affect a journal as a whole, and those which are used to | ||
| 371 | manage transactions | ||
| 372 | </para> | ||
| 373 | <sect2><title>Journal Level</title> | ||
| 374 | !Efs/jbd/journal.c | ||
| 375 | !Ifs/jbd/recovery.c | ||
| 376 | </sect2> | ||
| 377 | <sect2><title>Transasction Level</title> | ||
| 378 | !Efs/jbd/transaction.c | ||
| 379 | </sect2> | ||
| 380 | </sect1> | ||
| 381 | <sect1> | ||
| 382 | <title>See also</title> | ||
| 383 | <para> | ||
| 384 | <citation> | ||
| 385 | <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz"> | ||
| 386 | Journaling the Linux ext2fs Filesystem, LinuxExpo 98, Stephen Tweedie | ||
| 387 | </ulink> | ||
| 388 | </citation> | ||
| 389 | </para> | ||
| 390 | <para> | ||
| 391 | <citation> | ||
| 392 | <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html"> | ||
| 393 | Ext3 Journalling FileSystem, OLS 2000, Dr. Stephen Tweedie | ||
| 394 | </ulink> | ||
| 395 | </citation> | ||
| 396 | </para> | ||
| 397 | </sect1> | ||
| 398 | |||
| 399 | </chapter> | ||
| 400 | |||
| 101 | </book> | 401 | </book> |
diff --git a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl deleted file mode 100644 index 2077f9a28c19..000000000000 --- a/Documentation/DocBook/journal-api.tmpl +++ /dev/null | |||
| @@ -1,333 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
| 3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
| 4 | |||
| 5 | <book id="LinuxJBDAPI"> | ||
| 6 | <bookinfo> | ||
| 7 | <title>The Linux Journalling API</title> | ||
| 8 | <authorgroup> | ||
| 9 | <author> | ||
| 10 | <firstname>Roger</firstname> | ||
| 11 | <surname>Gammans</surname> | ||
| 12 | <affiliation> | ||
| 13 | <address> | ||
| 14 | <email>rgammans@computer-surgery.co.uk</email> | ||
| 15 | </address> | ||
| 16 | </affiliation> | ||
| 17 | </author> | ||
| 18 | </authorgroup> | ||
| 19 | |||
| 20 | <authorgroup> | ||
| 21 | <author> | ||
| 22 | <firstname>Stephen</firstname> | ||
| 23 | <surname>Tweedie</surname> | ||
| 24 | <affiliation> | ||
| 25 | <address> | ||
| 26 | <email>sct@redhat.com</email> | ||
| 27 | </address> | ||
| 28 | </affiliation> | ||
| 29 | </author> | ||
| 30 | </authorgroup> | ||
| 31 | |||
| 32 | <copyright> | ||
| 33 | <year>2002</year> | ||
| 34 | <holder>Roger Gammans</holder> | ||
| 35 | </copyright> | ||
| 36 | |||
| 37 | <legalnotice> | ||
| 38 | <para> | ||
| 39 | This documentation is free software; you can redistribute | ||
| 40 | it and/or modify it under the terms of the GNU General Public | ||
| 41 | License as published by the Free Software Foundation; either | ||
| 42 | version 2 of the License, or (at your option) any later | ||
| 43 | version. | ||
| 44 | </para> | ||
| 45 | |||
| 46 | <para> | ||
| 47 | This program is distributed in the hope that it will be | ||
| 48 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
| 49 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 50 | See the GNU General Public License for more details. | ||
| 51 | </para> | ||
| 52 | |||
| 53 | <para> | ||
| 54 | You should have received a copy of the GNU General Public | ||
| 55 | License along with this program; if not, write to the Free | ||
| 56 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
| 57 | MA 02111-1307 USA | ||
| 58 | </para> | ||
| 59 | |||
| 60 | <para> | ||
| 61 | For more details see the file COPYING in the source | ||
| 62 | distribution of Linux. | ||
| 63 | </para> | ||
| 64 | </legalnotice> | ||
| 65 | </bookinfo> | ||
| 66 | |||
| 67 | <toc></toc> | ||
| 68 | |||
| 69 | <chapter id="Overview"> | ||
| 70 | <title>Overview</title> | ||
| 71 | <sect1> | ||
| 72 | <title>Details</title> | ||
| 73 | <para> | ||
| 74 | The journalling layer is easy to use. You need to | ||
| 75 | first of all create a journal_t data structure. There are | ||
| 76 | two calls to do this dependent on how you decide to allocate the physical | ||
| 77 | media on which the journal resides. The journal_init_inode() call | ||
| 78 | is for journals stored in filesystem inodes, or the journal_init_dev() | ||
| 79 | call can be use for journal stored on a raw device (in a continuous range | ||
| 80 | of blocks). A journal_t is a typedef for a struct pointer, so when | ||
| 81 | you are finally finished make sure you call journal_destroy() on it | ||
| 82 | to free up any used kernel memory. | ||
| 83 | </para> | ||
| 84 | |||
| 85 | <para> | ||
| 86 | Once you have got your journal_t object you need to 'mount' or load the journal | ||
| 87 | file, unless of course you haven't initialised it yet - in which case you | ||
| 88 | need to call journal_create(). | ||
| 89 | </para> | ||
| 90 | |||
| 91 | <para> | ||
| 92 | Most of the time however your journal file will already have been created, but | ||
| 93 | before you load it you must call journal_wipe() to empty the journal file. | ||
| 94 | Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the | ||
| 95 | job of the client file system to detect this and skip the call to journal_wipe(). | ||
| 96 | </para> | ||
| 97 | |||
| 98 | <para> | ||
| 99 | In either case the next call should be to journal_load() which prepares the | ||
| 100 | journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() | ||
| 101 | for you if it detects any outstanding transactions in the journal and similarly | ||
| 102 | journal_load() will call journal_recover() if necessary. | ||
| 103 | I would advise reading fs/ext3/super.c for examples on this stage. | ||
| 104 | [RGG: Why is the journal_wipe() call necessary - doesn't this needlessly | ||
| 105 | complicate the API. Or isn't a good idea for the journal layer to hide | ||
| 106 | dirty mounts from the client fs] | ||
| 107 | </para> | ||
| 108 | |||
| 109 | <para> | ||
| 110 | Now you can go ahead and start modifying the underlying | ||
| 111 | filesystem. Almost. | ||
| 112 | </para> | ||
| 113 | |||
| 114 | |||
| 115 | <para> | ||
| 116 | |||
| 117 | You still need to actually journal your filesystem changes, this | ||
| 118 | is done by wrapping them into transactions. Additionally you | ||
| 119 | also need to wrap the modification of each of the buffers | ||
| 120 | with calls to the journal layer, so it knows what the modifications | ||
| 121 | you are actually making are. To do this use journal_start() which | ||
| 122 | returns a transaction handle. | ||
| 123 | </para> | ||
| 124 | |||
| 125 | <para> | ||
| 126 | journal_start() | ||
| 127 | and its counterpart journal_stop(), which indicates the end of a transaction | ||
| 128 | are nestable calls, so you can reenter a transaction if necessary, | ||
| 129 | but remember you must call journal_stop() the same number of times as | ||
| 130 | journal_start() before the transaction is completed (or more accurately | ||
| 131 | leaves the update phase). Ext3/VFS makes use of this feature to simplify | ||
| 132 | quota support. | ||
| 133 | </para> | ||
| 134 | |||
| 135 | <para> | ||
| 136 | Inside each transaction you need to wrap the modifications to the | ||
| 137 | individual buffers (blocks). Before you start to modify a buffer you | ||
| 138 | need to call journal_get_{create,write,undo}_access() as appropriate, | ||
| 139 | this allows the journalling layer to copy the unmodified data if it | ||
| 140 | needs to. After all the buffer may be part of a previously uncommitted | ||
| 141 | transaction. | ||
| 142 | At this point you are at last ready to modify a buffer, and once | ||
| 143 | you are have done so you need to call journal_dirty_{meta,}data(). | ||
| 144 | Or if you've asked for access to a buffer you now know is now longer | ||
| 145 | required to be pushed back on the device you can call journal_forget() | ||
| 146 | in much the same way as you might have used bforget() in the past. | ||
| 147 | </para> | ||
| 148 | |||
| 149 | <para> | ||
| 150 | A journal_flush() may be called at any time to commit and checkpoint | ||
| 151 | all your transactions. | ||
| 152 | </para> | ||
| 153 | |||
| 154 | <para> | ||
| 155 | Then at umount time , in your put_super() (2.4) or write_super() (2.5) | ||
| 156 | you can then call journal_destroy() to clean up your in-core journal object. | ||
| 157 | </para> | ||
| 158 | |||
| 159 | |||
| 160 | <para> | ||
| 161 | Unfortunately there a couple of ways the journal layer can cause a deadlock. | ||
| 162 | The first thing to note is that each task can only have | ||
| 163 | a single outstanding transaction at any one time, remember nothing | ||
| 164 | commits until the outermost journal_stop(). This means | ||
| 165 | you must complete the transaction at the end of each file/inode/address | ||
| 166 | etc. operation you perform, so that the journalling system isn't re-entered | ||
| 167 | on another journal. Since transactions can't be nested/batched | ||
| 168 | across differing journals, and another filesystem other than | ||
| 169 | yours (say ext3) may be modified in a later syscall. | ||
| 170 | </para> | ||
| 171 | |||
| 172 | <para> | ||
| 173 | The second case to bear in mind is that journal_start() can | ||
| 174 | block if there isn't enough space in the journal for your transaction | ||
| 175 | (based on the passed nblocks param) - when it blocks it merely(!) needs to | ||
| 176 | wait for transactions to complete and be committed from other tasks, | ||
| 177 | so essentially we are waiting for journal_stop(). So to avoid | ||
| 178 | deadlocks you must treat journal_start/stop() as if they | ||
| 179 | were semaphores and include them in your semaphore ordering rules to prevent | ||
| 180 | deadlocks. Note that journal_extend() has similar blocking behaviour to | ||
| 181 | journal_start() so you can deadlock here just as easily as on journal_start(). | ||
| 182 | </para> | ||
| 183 | |||
| 184 | <para> | ||
| 185 | Try to reserve the right number of blocks the first time. ;-). This will | ||
| 186 | be the maximum number of blocks you are going to touch in this transaction. | ||
| 187 | I advise having a look at at least ext3_jbd.h to see the basis on which | ||
| 188 | ext3 uses to make these decisions. | ||
| 189 | </para> | ||
| 190 | |||
| 191 | <para> | ||
| 192 | Another wriggle to watch out for is your on-disk block allocation strategy. | ||
| 193 | why? Because, if you undo a delete, you need to ensure you haven't reused any | ||
| 194 | of the freed blocks in a later transaction. One simple way of doing this | ||
| 195 | is make sure any blocks you allocate only have checkpointed transactions | ||
| 196 | listed against them. Ext3 does this in ext3_test_allocatable(). | ||
| 197 | </para> | ||
| 198 | |||
| 199 | <para> | ||
| 200 | Lock is also providing through journal_{un,}lock_updates(), | ||
| 201 | ext3 uses this when it wants a window with a clean and stable fs for a moment. | ||
| 202 | eg. | ||
| 203 | </para> | ||
| 204 | |||
| 205 | <programlisting> | ||
| 206 | |||
| 207 | journal_lock_updates() //stop new stuff happening.. | ||
| 208 | journal_flush() // checkpoint everything. | ||
| 209 | ..do stuff on stable fs | ||
| 210 | journal_unlock_updates() // carry on with filesystem use. | ||
| 211 | </programlisting> | ||
| 212 | |||
| 213 | <para> | ||
| 214 | The opportunities for abuse and DOS attacks with this should be obvious, | ||
| 215 | if you allow unprivileged userspace to trigger codepaths containing these | ||
| 216 | calls. | ||
| 217 | </para> | ||
| 218 | |||
| 219 | <para> | ||
| 220 | A new feature of jbd since 2.5.25 is commit callbacks with the new | ||
| 221 | journal_callback_set() function you can now ask the journalling layer | ||
| 222 | to call you back when the transaction is finally committed to disk, so that | ||
| 223 | you can do some of your own management. The key to this is the journal_callback | ||
| 224 | struct, this maintains the internal callback information but you can | ||
| 225 | extend it like this:- | ||
| 226 | </para> | ||
| 227 | <programlisting> | ||
| 228 | struct myfs_callback_s { | ||
| 229 | //Data structure element required by jbd.. | ||
| 230 | struct journal_callback for_jbd; | ||
| 231 | // Stuff for myfs allocated together. | ||
| 232 | myfs_inode* i_commited; | ||
| 233 | |||
| 234 | } | ||
| 235 | </programlisting> | ||
| 236 | |||
| 237 | <para> | ||
| 238 | this would be useful if you needed to know when data was committed to a | ||
| 239 | particular inode. | ||
| 240 | </para> | ||
| 241 | |||
| 242 | </sect1> | ||
| 243 | |||
| 244 | <sect1> | ||
| 245 | <title>Summary</title> | ||
| 246 | <para> | ||
| 247 | Using the journal is a matter of wrapping the different context changes, | ||
| 248 | being each mount, each modification (transaction) and each changed buffer | ||
| 249 | to tell the journalling layer about them. | ||
| 250 | </para> | ||
| 251 | |||
| 252 | <para> | ||
| 253 | Here is a some pseudo code to give you an idea of how it works, as | ||
| 254 | an example. | ||
| 255 | </para> | ||
| 256 | |||
| 257 | <programlisting> | ||
| 258 | journal_t* my_jnrl = journal_create(); | ||
| 259 | journal_init_{dev,inode}(jnrl,...) | ||
| 260 | if (clean) journal_wipe(); | ||
| 261 | journal_load(); | ||
| 262 | |||
| 263 | foreach(transaction) { /*transactions must be | ||
| 264 | completed before | ||
| 265 | a syscall returns to | ||
| 266 | userspace*/ | ||
| 267 | |||
| 268 | handle_t * xct=journal_start(my_jnrl); | ||
| 269 | foreach(bh) { | ||
| 270 | journal_get_{create,write,undo}_access(xact,bh); | ||
| 271 | if ( myfs_modify(bh) ) { /* returns true | ||
| 272 | if makes changes */ | ||
| 273 | journal_dirty_{meta,}data(xact,bh); | ||
| 274 | } else { | ||
| 275 | journal_forget(bh); | ||
| 276 | } | ||
| 277 | } | ||
| 278 | journal_stop(xct); | ||
| 279 | } | ||
| 280 | journal_destroy(my_jrnl); | ||
| 281 | </programlisting> | ||
| 282 | </sect1> | ||
| 283 | |||
| 284 | </chapter> | ||
| 285 | |||
| 286 | <chapter id="adt"> | ||
| 287 | <title>Data Types</title> | ||
| 288 | <para> | ||
| 289 | The journalling layer uses typedefs to 'hide' the concrete definitions | ||
| 290 | of the structures used. As a client of the JBD layer you can | ||
| 291 | just rely on the using the pointer as a magic cookie of some sort. | ||
| 292 | |||
| 293 | Obviously the hiding is not enforced as this is 'C'. | ||
| 294 | </para> | ||
| 295 | <sect1><title>Structures</title> | ||
| 296 | !Iinclude/linux/jbd.h | ||
| 297 | </sect1> | ||
| 298 | </chapter> | ||
| 299 | |||
| 300 | <chapter id="calls"> | ||
| 301 | <title>Functions</title> | ||
| 302 | <para> | ||
| 303 | The functions here are split into two groups those that | ||
| 304 | affect a journal as a whole, and those which are used to | ||
| 305 | manage transactions | ||
| 306 | </para> | ||
| 307 | <sect1><title>Journal Level</title> | ||
| 308 | !Efs/jbd/journal.c | ||
| 309 | !Ifs/jbd/recovery.c | ||
| 310 | </sect1> | ||
| 311 | <sect1><title>Transasction Level</title> | ||
| 312 | !Efs/jbd/transaction.c | ||
| 313 | </sect1> | ||
| 314 | </chapter> | ||
| 315 | <chapter> | ||
| 316 | <title>See also</title> | ||
| 317 | <para> | ||
| 318 | <citation> | ||
| 319 | <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz"> | ||
| 320 | Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie | ||
| 321 | </ulink> | ||
| 322 | </citation> | ||
| 323 | </para> | ||
| 324 | <para> | ||
| 325 | <citation> | ||
| 326 | <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html"> | ||
| 327 | Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie | ||
| 328 | </ulink> | ||
| 329 | </citation> | ||
| 330 | </para> | ||
| 331 | </chapter> | ||
| 332 | |||
| 333 | </book> | ||
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index b11792abd6b6..bf2b0e2f87e1 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
| @@ -49,7 +49,7 @@ __u64 stime, utime; | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /* Maximum size of response requested or message sent */ | 51 | /* Maximum size of response requested or message sent */ |
| 52 | #define MAX_MSG_SIZE 256 | 52 | #define MAX_MSG_SIZE 1024 |
| 53 | /* Maximum number of cpus expected to be specified in a cpumask */ | 53 | /* Maximum number of cpus expected to be specified in a cpumask */ |
| 54 | #define MAX_CPUS 32 | 54 | #define MAX_CPUS 32 |
| 55 | /* Maximum length of pathname to log file */ | 55 | /* Maximum length of pathname to log file */ |
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt index c65233d430f0..284e7e198e93 100644 --- a/Documentation/kernel-doc-nano-HOWTO.txt +++ b/Documentation/kernel-doc-nano-HOWTO.txt | |||
| @@ -17,7 +17,7 @@ are: | |||
| 17 | special place-holders for where the extracted documentation should | 17 | special place-holders for where the extracted documentation should |
| 18 | go. | 18 | go. |
| 19 | 19 | ||
| 20 | - scripts/docproc.c | 20 | - scripts/basic/docproc.c |
| 21 | 21 | ||
| 22 | This is a program for converting SGML template files into SGML | 22 | This is a program for converting SGML template files into SGML |
| 23 | files. When a file is referenced it is searched for symbols | 23 | files. When a file is referenced it is searched for symbols |
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt index a66bec222b16..74311d7e0f3c 100644 --- a/Documentation/power/interface.txt +++ b/Documentation/power/interface.txt | |||
| @@ -30,6 +30,17 @@ testing). The system will support either 'firmware' or 'platform', and | |||
| 30 | that is known a priori. But, the user may choose 'shutdown' or | 30 | that is known a priori. But, the user may choose 'shutdown' or |
| 31 | 'reboot' as alternatives. | 31 | 'reboot' as alternatives. |
| 32 | 32 | ||
| 33 | Additionally, /sys/power/disk can be used to turn on one of the two testing | ||
| 34 | modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the | ||
| 35 | suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to | ||
| 36 | /sys/power/state will cause the kernel to disable nonboot CPUs and freeze | ||
| 37 | tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is | ||
| 38 | in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel | ||
| 39 | to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait | ||
| 40 | for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then, | ||
| 41 | we are able to look in the log messages and work out, for example, which code | ||
| 42 | is being slow and which device drivers are misbehaving. | ||
| 43 | |||
| 33 | Reading from this file will display what the mode is currently set | 44 | Reading from this file will display what the mode is currently set |
| 34 | to. Writing to this file will accept one of | 45 | to. Writing to this file will accept one of |
| 35 | 46 | ||
| @@ -37,6 +48,8 @@ to. Writing to this file will accept one of | |||
| 37 | 'platform' | 48 | 'platform' |
| 38 | 'shutdown' | 49 | 'shutdown' |
| 39 | 'reboot' | 50 | 'reboot' |
| 51 | 'testproc' | ||
| 52 | 'test' | ||
| 40 | 53 | ||
| 41 | It will only change to 'firmware' or 'platform' if the system supports | 54 | It will only change to 'firmware' or 'platform' if the system supports |
| 42 | it. | 55 | it. |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ab974ff97073..22e4c466e5a3 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
| @@ -70,7 +70,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return | |||
| 70 | 70 | ||
| 71 | #define PREFIX "ACPI: " | 71 | #define PREFIX "ACPI: " |
| 72 | 72 | ||
| 73 | int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ | 73 | int acpi_noirq; /* skip ACPI IRQ initialization */ |
| 74 | int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ | 74 | int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ |
| 75 | int acpi_ht __initdata = 1; /* enable HT */ | 75 | int acpi_ht __initdata = 1; /* enable HT */ |
| 76 | 76 | ||
diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h new file mode 100644 index 000000000000..b58d52c5b2f4 --- /dev/null +++ b/arch/um/include/sysdep-i386/barrier.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #ifndef __SYSDEP_I386_BARRIER_H | ||
| 2 | #define __SYSDEP_I386_BARRIER_H | ||
| 3 | |||
| 4 | /* Copied from include/asm-i386 for use by userspace. i386 has the option | ||
| 5 | * of using mfence, but I'm just using this, which works everywhere, for now. | ||
| 6 | */ | ||
| 7 | #define mb() asm volatile("lock; addl $0,0(%esp)") | ||
| 8 | |||
| 9 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/barrier.h b/arch/um/include/sysdep-x86_64/barrier.h new file mode 100644 index 000000000000..7b610befdc8f --- /dev/null +++ b/arch/um/include/sysdep-x86_64/barrier.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __SYSDEP_X86_64_BARRIER_H | ||
| 2 | #define __SYSDEP_X86_64_BARRIER_H | ||
| 3 | |||
| 4 | /* Copied from include/asm-x86_64 for use by userspace. */ | ||
| 5 | #define mb() asm volatile("mfence":::"memory") | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 51f0893640a6..c692a192957a 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include <stdio.h> | 7 | #include <stdio.h> |
| 8 | #include <errno.h> | 8 | #include <errno.h> |
| 9 | #include <signal.h> | 9 | #include <signal.h> |
| 10 | #include <linux/unistd.h> | ||
| 11 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
| 12 | #include <sys/wait.h> | 11 | #include <sys/wait.h> |
| 13 | #include <sys/mman.h> | 12 | #include <sys/mman.h> |
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6b81739279d1..b897e8592d77 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "user.h" | 15 | #include "user.h" |
| 16 | #include "signal_kern.h" | 16 | #include "signal_kern.h" |
| 17 | #include "sysdep/sigcontext.h" | 17 | #include "sysdep/sigcontext.h" |
| 18 | #include "sysdep/barrier.h" | ||
| 18 | #include "sigcontext.h" | 19 | #include "sigcontext.h" |
| 19 | #include "mode.h" | 20 | #include "mode.h" |
| 20 | #include "os.h" | 21 | #include "os.h" |
| @@ -34,8 +35,12 @@ | |||
| 34 | #define SIGALRM_BIT 2 | 35 | #define SIGALRM_BIT 2 |
| 35 | #define SIGALRM_MASK (1 << SIGALRM_BIT) | 36 | #define SIGALRM_MASK (1 << SIGALRM_BIT) |
| 36 | 37 | ||
| 37 | static int signals_enabled = 1; | 38 | /* These are used by both the signal handlers and |
| 38 | static int pending = 0; | 39 | * block/unblock_signals. I don't want modifications cached in a |
| 40 | * register - they must go straight to memory. | ||
| 41 | */ | ||
| 42 | static volatile int signals_enabled = 1; | ||
| 43 | static volatile int pending = 0; | ||
| 39 | 44 | ||
| 40 | void sig_handler(int sig, struct sigcontext *sc) | 45 | void sig_handler(int sig, struct sigcontext *sc) |
| 41 | { | 46 | { |
| @@ -152,6 +157,12 @@ int change_sig(int signal, int on) | |||
| 152 | void block_signals(void) | 157 | void block_signals(void) |
| 153 | { | 158 | { |
| 154 | signals_enabled = 0; | 159 | signals_enabled = 0; |
| 160 | /* This must return with signals disabled, so this barrier | ||
| 161 | * ensures that writes are flushed out before the return. | ||
| 162 | * This might matter if gcc figures out how to inline this and | ||
| 163 | * decides to shuffle this code into the caller. | ||
| 164 | */ | ||
| 165 | mb(); | ||
| 155 | } | 166 | } |
| 156 | 167 | ||
| 157 | void unblock_signals(void) | 168 | void unblock_signals(void) |
| @@ -171,9 +182,23 @@ void unblock_signals(void) | |||
| 171 | */ | 182 | */ |
| 172 | signals_enabled = 1; | 183 | signals_enabled = 1; |
| 173 | 184 | ||
| 185 | /* Setting signals_enabled and reading pending must | ||
| 186 | * happen in this order. | ||
| 187 | */ | ||
| 188 | mb(); | ||
| 189 | |||
| 174 | save_pending = pending; | 190 | save_pending = pending; |
| 175 | if(save_pending == 0) | 191 | if(save_pending == 0){ |
| 192 | /* This must return with signals enabled, so | ||
| 193 | * this barrier ensures that writes are | ||
| 194 | * flushed out before the return. This might | ||
| 195 | * matter if gcc figures out how to inline | ||
| 196 | * this (unlikely, given its size) and decides | ||
| 197 | * to shuffle this code into the caller. | ||
| 198 | */ | ||
| 199 | mb(); | ||
| 176 | return; | 200 | return; |
| 201 | } | ||
| 177 | 202 | ||
| 178 | pending = 0; | 203 | pending = 0; |
| 179 | 204 | ||
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cb9ab54146cc..9b34fe65949a 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <sys/mman.h> | 14 | #include <sys/mman.h> |
| 15 | #include <sys/user.h> | 15 | #include <sys/user.h> |
| 16 | #include <sys/time.h> | 16 | #include <sys/time.h> |
| 17 | #include <asm/unistd.h> | 17 | #include <sys/syscall.h> |
| 18 | #include <asm/types.h> | 18 | #include <asm/types.h> |
| 19 | #include "user.h" | 19 | #include "user.h" |
| 20 | #include "sysdep/ptrace.h" | 20 | #include "sysdep/ptrace.h" |
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index 9f7999f27c77..16215b990804 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #include <errno.h> | 1 | #include <errno.h> |
| 2 | #include <unistd.h> | ||
| 2 | #include <sys/ptrace.h> | 3 | #include <sys/ptrace.h> |
| 3 | #include <sys/syscall.h> | 4 | #include <sys/syscall.h> |
| 4 | #include <unistd.h> | ||
| 5 | #include <asm/ldt.h> | 5 | #include <asm/ldt.h> |
| 6 | #include "sysdep/tls.h" | 6 | #include "sysdep/tls.h" |
| 7 | #include "uml-config.h" | 7 | #include "uml-config.h" |
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index c7b1dac8bee9..9eaee6640535 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
| @@ -3075,11 +3075,12 @@ end_io: | |||
| 3075 | if (maxsector) { | 3075 | if (maxsector) { |
| 3076 | sector_t sector = bio->bi_sector; | 3076 | sector_t sector = bio->bi_sector; |
| 3077 | 3077 | ||
| 3078 | if (maxsector < nr_sectors || maxsector - nr_sectors < sector) { | 3078 | if (maxsector < nr_sectors || |
| 3079 | maxsector - nr_sectors < sector) { | ||
| 3079 | /* | 3080 | /* |
| 3080 | * This may well happen - partitions are not checked | 3081 | * This may well happen - partitions are not |
| 3081 | * to make sure they are within the size of the | 3082 | * checked to make sure they are within the size |
| 3082 | * whole device. | 3083 | * of the whole device. |
| 3083 | */ | 3084 | */ |
| 3084 | handle_bad_sector(bio); | 3085 | handle_bad_sector(bio); |
| 3085 | goto end_io; | 3086 | goto end_io; |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e5cfb1fa47d1..157fa81a264f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -1867,7 +1867,7 @@ static int ipmi_pci_resume(struct pci_dev *pdev) | |||
| 1867 | 1867 | ||
| 1868 | static struct pci_device_id ipmi_pci_devices[] = { | 1868 | static struct pci_device_id ipmi_pci_devices[] = { |
| 1869 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, | 1869 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, |
| 1870 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) } | 1870 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } |
| 1871 | }; | 1871 | }; |
| 1872 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); | 1872 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); |
| 1873 | 1873 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 4bde30bb3be7..75e9e38330ff 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
| @@ -230,34 +230,43 @@ static struct kobj_type ktype_memctrl = { | |||
| 230 | */ | 230 | */ |
| 231 | static int edac_sysfs_memctrl_setup(void) | 231 | static int edac_sysfs_memctrl_setup(void) |
| 232 | { | 232 | { |
| 233 | int err=0; | 233 | int err = 0; |
| 234 | 234 | ||
| 235 | debugf1("%s()\n", __func__); | 235 | debugf1("%s()\n", __func__); |
| 236 | 236 | ||
| 237 | /* create the /sys/devices/system/edac directory */ | 237 | /* create the /sys/devices/system/edac directory */ |
| 238 | err = sysdev_class_register(&edac_class); | 238 | err = sysdev_class_register(&edac_class); |
| 239 | 239 | ||
| 240 | if (!err) { | 240 | if (err) { |
| 241 | /* Init the MC's kobject */ | 241 | debugf1("%s() error=%d\n", __func__, err); |
| 242 | memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); | 242 | return err; |
| 243 | edac_memctrl_kobj.parent = &edac_class.kset.kobj; | 243 | } |
| 244 | edac_memctrl_kobj.ktype = &ktype_memctrl; | ||
| 245 | 244 | ||
| 246 | /* generate sysfs "..../edac/mc" */ | 245 | /* Init the MC's kobject */ |
| 247 | err = kobject_set_name(&edac_memctrl_kobj,"mc"); | 246 | memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); |
| 247 | edac_memctrl_kobj.parent = &edac_class.kset.kobj; | ||
| 248 | edac_memctrl_kobj.ktype = &ktype_memctrl; | ||
| 248 | 249 | ||
| 249 | if (!err) { | 250 | /* generate sysfs "..../edac/mc" */ |
| 250 | /* FIXME: maybe new sysdev_create_subdir() */ | 251 | err = kobject_set_name(&edac_memctrl_kobj,"mc"); |
| 251 | err = kobject_register(&edac_memctrl_kobj); | ||
| 252 | 252 | ||
| 253 | if (err) | 253 | if (err) |
| 254 | debugf1("Failed to register '.../edac/mc'\n"); | 254 | goto fail; |
| 255 | else | 255 | |
| 256 | debugf1("Registered '.../edac/mc' kobject\n"); | 256 | /* FIXME: maybe new sysdev_create_subdir() */ |
| 257 | } | 257 | err = kobject_register(&edac_memctrl_kobj); |
| 258 | } else | 258 | |
| 259 | debugf1("%s() error=%d\n", __func__, err); | 259 | if (err) { |
| 260 | debugf1("Failed to register '.../edac/mc'\n"); | ||
| 261 | goto fail; | ||
| 262 | } | ||
| 260 | 263 | ||
| 264 | debugf1("Registered '.../edac/mc' kobject\n"); | ||
| 265 | |||
| 266 | return 0; | ||
| 267 | |||
| 268 | fail: | ||
| 269 | sysdev_class_unregister(&edac_class); | ||
| 261 | return err; | 270 | return err; |
| 262 | } | 271 | } |
| 263 | 272 | ||
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 2b0ea8b6608d..753fe0e21456 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
| @@ -75,6 +75,7 @@ static struct amd_ide_chip { | |||
| 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, | 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, |
| 76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, | 76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, |
| 77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, | 77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, |
| 78 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, | ||
| 78 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, | 79 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, |
| 79 | { 0 } | 80 | { 0 } |
| 80 | }; | 81 | }; |
| @@ -491,7 +492,8 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
| 491 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), | 492 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), |
| 492 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), | 493 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), |
| 493 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), | 494 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), |
| 494 | /* 19 */ DECLARE_AMD_DEV("AMD5536"), | 495 | /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), |
| 496 | /* 20 */ DECLARE_AMD_DEV("AMD5536"), | ||
| 495 | }; | 497 | }; |
| 496 | 498 | ||
| 497 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 499 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| @@ -530,7 +532,8 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
| 530 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, | 532 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, |
| 531 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, | 533 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, |
| 532 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, | 534 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, |
| 533 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, | 535 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, |
| 536 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 }, | ||
| 534 | { 0, }, | 537 | { 0, }, |
| 535 | }; | 538 | }; |
| 536 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 539 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 1fadf0133e9b..18758772b744 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c | |||
| @@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
| 155 | if (card->debug_flags & LOG_SCHED_ASYN) | 155 | if (card->debug_flags & LOG_SCHED_ASYN) |
| 156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); | 156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); |
| 157 | 157 | ||
| 158 | spin_lock_irqsave(&card->hysdn_lock, flags); | ||
| 159 | while (card->async_busy) { | 158 | while (card->async_busy) { |
| 160 | sti(); | ||
| 161 | 159 | ||
| 162 | if (card->debug_flags & LOG_SCHED_ASYN) | 160 | if (card->debug_flags & LOG_SCHED_ASYN) |
| 163 | hysdn_addlog(card, "async tx-cfg delayed"); | 161 | hysdn_addlog(card, "async tx-cfg delayed"); |
| 164 | 162 | ||
| 165 | msleep_interruptible(20); /* Timeout 20ms */ | 163 | msleep_interruptible(20); /* Timeout 20ms */ |
| 166 | if (!--cnt) { | 164 | if (!--cnt) |
| 167 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
| 168 | return (-ERR_ASYNC_TIME); /* timed out */ | 165 | return (-ERR_ASYNC_TIME); /* timed out */ |
| 169 | } | ||
| 170 | cli(); | ||
| 171 | } /* wait for buffer to become free */ | 166 | } /* wait for buffer to become free */ |
| 172 | 167 | ||
| 168 | spin_lock_irqsave(&card->hysdn_lock, flags); | ||
| 173 | strcpy(card->async_data, line); | 169 | strcpy(card->async_data, line); |
| 174 | card->async_len = strlen(line) + 1; | 170 | card->async_len = strlen(line) + 1; |
| 175 | card->async_channel = chan; | 171 | card->async_channel = chan; |
| @@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
| 177 | 173 | ||
| 178 | /* now queue the task */ | 174 | /* now queue the task */ |
| 179 | schedule_work(&card->irq_queue); | 175 | schedule_work(&card->irq_queue); |
| 180 | sti(); | 176 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
| 181 | 177 | ||
| 182 | if (card->debug_flags & LOG_SCHED_ASYN) | 178 | if (card->debug_flags & LOG_SCHED_ASYN) |
| 183 | hysdn_addlog(card, "async tx-cfg data queued"); | 179 | hysdn_addlog(card, "async tx-cfg data queued"); |
| 184 | 180 | ||
| 185 | cnt++; /* short delay */ | 181 | cnt++; /* short delay */ |
| 186 | cli(); | ||
| 187 | 182 | ||
| 188 | while (card->async_busy) { | 183 | while (card->async_busy) { |
| 189 | sti(); | ||
| 190 | 184 | ||
| 191 | if (card->debug_flags & LOG_SCHED_ASYN) | 185 | if (card->debug_flags & LOG_SCHED_ASYN) |
| 192 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); | 186 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); |
| 193 | 187 | ||
| 194 | msleep_interruptible(20); /* Timeout 20ms */ | 188 | msleep_interruptible(20); /* Timeout 20ms */ |
| 195 | if (!--cnt) { | 189 | if (!--cnt) |
| 196 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
| 197 | return (-ERR_ASYNC_TIME); /* timed out */ | 190 | return (-ERR_ASYNC_TIME); /* timed out */ |
| 198 | } | ||
| 199 | cli(); | ||
| 200 | } /* wait for buffer to become free again */ | 191 | } /* wait for buffer to become free again */ |
| 201 | 192 | ||
| 202 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
| 203 | |||
| 204 | if (card->debug_flags & LOG_SCHED_ASYN) | 193 | if (card->debug_flags & LOG_SCHED_ASYN) |
| 205 | hysdn_addlog(card, "async tx-cfg data send"); | 194 | hysdn_addlog(card, "async tx-cfg data send"); |
| 206 | 195 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 50ab4a936e30..d11135604403 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -3200,6 +3200,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3200 | 3200 | ||
| 3201 | mddev->changed = 1; | 3201 | mddev->changed = 1; |
| 3202 | md_new_event(mddev); | 3202 | md_new_event(mddev); |
| 3203 | kobject_uevent(&mddev->gendisk->kobj, KOBJ_ONLINE); | ||
| 3203 | return 0; | 3204 | return 0; |
| 3204 | } | 3205 | } |
| 3205 | 3206 | ||
| @@ -3313,6 +3314,7 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
| 3313 | 3314 | ||
| 3314 | module_put(mddev->pers->owner); | 3315 | module_put(mddev->pers->owner); |
| 3315 | mddev->pers = NULL; | 3316 | mddev->pers = NULL; |
| 3317 | kobject_uevent(&mddev->gendisk->kobj, KOBJ_OFFLINE); | ||
| 3316 | if (mddev->ro) | 3318 | if (mddev->ro) |
| 3317 | mddev->ro = 0; | 3319 | mddev->ro = 0; |
| 3318 | } | 3320 | } |
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index bbdba7b37e11..46a9c35943bd 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
| @@ -44,12 +44,14 @@ | |||
| 44 | */ | 44 | */ |
| 45 | 45 | ||
| 46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
| 47 | #include <linux/fs.h> | ||
| 47 | #include <linux/module.h> | 48 | #include <linux/module.h> |
| 49 | #include <linux/buffer_head.h> | ||
| 48 | #include <linux/kprobes.h> | 50 | #include <linux/kprobes.h> |
| 49 | #include <linux/kallsyms.h> | 51 | #include <linux/list.h> |
| 50 | #include <linux/init.h> | 52 | #include <linux/init.h> |
| 51 | #include <linux/irq.h> | ||
| 52 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
| 54 | #include <linux/hrtimer.h> | ||
| 53 | #include <scsi/scsi_cmnd.h> | 55 | #include <scsi/scsi_cmnd.h> |
| 54 | 56 | ||
| 55 | #ifdef CONFIG_IDE | 57 | #ifdef CONFIG_IDE |
| @@ -116,16 +118,16 @@ static enum ctype cptype = NONE; | |||
| 116 | static int count = DEFAULT_COUNT; | 118 | static int count = DEFAULT_COUNT; |
| 117 | 119 | ||
| 118 | module_param(recur_count, int, 0644); | 120 | module_param(recur_count, int, 0644); |
| 119 | MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\ | 121 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ |
| 120 | default is 10"); | 122 | "default is 10"); |
| 121 | module_param(cpoint_name, charp, 0644); | 123 | module_param(cpoint_name, charp, 0644); |
| 122 | MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed"); | 124 | MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); |
| 123 | module_param(cpoint_type, charp, 06444); | 125 | module_param(cpoint_type, charp, 0644); |
| 124 | MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\ | 126 | MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ |
| 125 | hitting the crash point"); | 127 | "hitting the crash point"); |
| 126 | module_param(cpoint_count, int, 06444); | 128 | module_param(cpoint_count, int, 0644); |
| 127 | MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \ | 129 | MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ |
| 128 | crash point is to be hit to trigger action"); | 130 | "crash point is to be hit to trigger action"); |
| 129 | 131 | ||
| 130 | unsigned int jp_do_irq(unsigned int irq) | 132 | unsigned int jp_do_irq(unsigned int irq) |
| 131 | { | 133 | { |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 146298ad7371..c3c0626f550b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -281,7 +281,6 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) | |||
| 281 | up(&board_lock); | 281 | up(&board_lock); |
| 282 | return 0; | 282 | return 0; |
| 283 | } | 283 | } |
| 284 | EXPORT_SYMBOL_GPL(spi_register_board_info); | ||
| 285 | 284 | ||
| 286 | /* FIXME someone should add support for a __setup("spi", ...) that | 285 | /* FIXME someone should add support for a __setup("spi", ...) that |
| 287 | * creates board info from kernel command lines | 286 | * creates board info from kernel command lines |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 976a691c5a68..7e056b9b49e8 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -1806,13 +1806,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1806 | } | 1806 | } |
| 1807 | if ((rc < 0) || (smb_read_data == NULL)) { | 1807 | if ((rc < 0) || (smb_read_data == NULL)) { |
| 1808 | cFYI(1, ("Read error in readpages: %d", rc)); | 1808 | cFYI(1, ("Read error in readpages: %d", rc)); |
| 1809 | /* clean up remaing pages off list */ | ||
| 1810 | while (!list_empty(page_list) && (i < num_pages)) { | ||
| 1811 | page = list_entry(page_list->prev, struct page, | ||
| 1812 | lru); | ||
| 1813 | list_del(&page->lru); | ||
| 1814 | page_cache_release(page); | ||
| 1815 | } | ||
| 1816 | break; | 1809 | break; |
| 1817 | } else if (bytes_read > 0) { | 1810 | } else if (bytes_read > 0) { |
| 1818 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 1811 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
| @@ -1831,13 +1824,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1831 | this case is ok - if we are at server EOF | 1824 | this case is ok - if we are at server EOF |
| 1832 | we will hit it on next read */ | 1825 | we will hit it on next read */ |
| 1833 | 1826 | ||
| 1834 | /* while (!list_empty(page_list) && (i < num_pages)) { | 1827 | /* break; */ |
| 1835 | page = list_entry(page_list->prev, | ||
| 1836 | struct page, list); | ||
| 1837 | list_del(&page->list); | ||
| 1838 | page_cache_release(page); | ||
| 1839 | } | ||
| 1840 | break; */ | ||
| 1841 | } | 1828 | } |
| 1842 | } else { | 1829 | } else { |
| 1843 | cFYI(1, ("No bytes read (%d) at offset %lld . " | 1830 | cFYI(1, ("No bytes read (%d) at offset %lld . " |
| @@ -1845,14 +1832,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1845 | bytes_read, offset)); | 1832 | bytes_read, offset)); |
| 1846 | /* BB turn off caching and do new lookup on | 1833 | /* BB turn off caching and do new lookup on |
| 1847 | file size at server? */ | 1834 | file size at server? */ |
| 1848 | while (!list_empty(page_list) && (i < num_pages)) { | ||
| 1849 | page = list_entry(page_list->prev, struct page, | ||
| 1850 | lru); | ||
| 1851 | list_del(&page->lru); | ||
| 1852 | |||
| 1853 | /* BB removeme - replace with zero of page? */ | ||
| 1854 | page_cache_release(page); | ||
| 1855 | } | ||
| 1856 | break; | 1835 | break; |
| 1857 | } | 1836 | } |
| 1858 | if (smb_read_data) { | 1837 | if (smb_read_data) { |
diff --git a/fs/compat.c b/fs/compat.c index 50624d4a70c6..8d0a0018a7d2 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1835,9 +1835,12 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
| 1835 | 1835 | ||
| 1836 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); | 1836 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); |
| 1837 | 1837 | ||
| 1838 | if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) { | 1838 | if (tsp) { |
| 1839 | struct compat_timespec rts; | 1839 | struct compat_timespec rts; |
| 1840 | 1840 | ||
| 1841 | if (current->personality & STICKY_TIMEOUTS) | ||
| 1842 | goto sticky; | ||
| 1843 | |||
| 1841 | rts.tv_sec = timeout / HZ; | 1844 | rts.tv_sec = timeout / HZ; |
| 1842 | rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); | 1845 | rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); |
| 1843 | if (rts.tv_nsec >= NSEC_PER_SEC) { | 1846 | if (rts.tv_nsec >= NSEC_PER_SEC) { |
| @@ -1846,8 +1849,19 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
| 1846 | } | 1849 | } |
| 1847 | if (compat_timespec_compare(&rts, &ts) >= 0) | 1850 | if (compat_timespec_compare(&rts, &ts) >= 0) |
| 1848 | rts = ts; | 1851 | rts = ts; |
| 1849 | if (copy_to_user(tsp, &rts, sizeof(rts))) | 1852 | if (copy_to_user(tsp, &rts, sizeof(rts))) { |
| 1850 | ret = -EFAULT; | 1853 | sticky: |
| 1854 | /* | ||
| 1855 | * If an application puts its timeval in read-only | ||
| 1856 | * memory, we don't want the Linux-specific update to | ||
| 1857 | * the timeval to cause a fault after the select has | ||
| 1858 | * completed successfully. However, because we're not | ||
| 1859 | * updating the timeval, we can't restart the system | ||
| 1860 | * call. | ||
| 1861 | */ | ||
| 1862 | if (ret == -ERESTARTNOHAND) | ||
| 1863 | ret = -EINTR; | ||
| 1864 | } | ||
| 1851 | } | 1865 | } |
| 1852 | 1866 | ||
| 1853 | if (ret == -ERESTARTNOHAND) { | 1867 | if (ret == -ERESTARTNOHAND) { |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f49f105394b7..136175a69332 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -134,7 +134,7 @@ int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, | |||
| 134 | 134 | ||
| 135 | algified_name_len = (chaining_modifier_len + cipher_name_len + 3); | 135 | algified_name_len = (chaining_modifier_len + cipher_name_len + 3); |
| 136 | (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL); | 136 | (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL); |
| 137 | if (!(algified_name)) { | 137 | if (!(*algified_name)) { |
| 138 | rc = -ENOMEM; | 138 | rc = -ENOMEM; |
| 139 | goto out; | 139 | goto out; |
| 140 | } | 140 | } |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 2bb5ace3882d..763a50daf1c0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -397,14 +397,14 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
| 397 | 397 | ||
| 398 | err = -EIO; | 398 | err = -EIO; |
| 399 | if (is_bad_inode(inode)) | 399 | if (is_bad_inode(inode)) |
| 400 | goto clean_pages_up; | 400 | goto out; |
| 401 | 401 | ||
| 402 | data.file = file; | 402 | data.file = file; |
| 403 | data.inode = inode; | 403 | data.inode = inode; |
| 404 | data.req = fuse_get_req(fc); | 404 | data.req = fuse_get_req(fc); |
| 405 | err = PTR_ERR(data.req); | 405 | err = PTR_ERR(data.req); |
| 406 | if (IS_ERR(data.req)) | 406 | if (IS_ERR(data.req)) |
| 407 | goto clean_pages_up; | 407 | goto out; |
| 408 | 408 | ||
| 409 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); | 409 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
| 410 | if (!err) { | 410 | if (!err) { |
| @@ -413,10 +413,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
| 413 | else | 413 | else |
| 414 | fuse_put_request(fc, data.req); | 414 | fuse_put_request(fc, data.req); |
| 415 | } | 415 | } |
| 416 | return err; | 416 | out: |
| 417 | |||
| 418 | clean_pages_up: | ||
| 419 | put_pages_list(pages); | ||
| 420 | return err; | 417 | return err; |
| 421 | } | 418 | } |
| 422 | 419 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 8d5963c7e123..015640b3f123 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
| @@ -337,13 +337,6 @@ out: | |||
| 337 | out_noerror: | 337 | out_noerror: |
| 338 | ret = 0; | 338 | ret = 0; |
| 339 | out_unlock: | 339 | out_unlock: |
| 340 | /* unlock all pages, we can't do any I/O right now */ | ||
| 341 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | ||
| 342 | struct page *page = list_entry(pages->prev, struct page, lru); | ||
| 343 | list_del(&page->lru); | ||
| 344 | unlock_page(page); | ||
| 345 | page_cache_release(page); | ||
| 346 | } | ||
| 347 | if (do_unlock) | 340 | if (do_unlock) |
| 348 | gfs2_holder_uninit(&gh); | 341 | gfs2_holder_uninit(&gh); |
| 349 | goto out; | 342 | goto out; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e9d07704680e..81b8565d3837 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry) | |||
| 274 | * any regular files anyway, just in case the directory was created by | 274 | * any regular files anyway, just in case the directory was created by |
| 275 | * a kernel from the future.... */ | 275 | * a kernel from the future.... */ |
| 276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); | 276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); |
| 277 | mutex_lock(&dir->d_inode->i_mutex); | 277 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
| 278 | status = vfs_rmdir(dir->d_inode, dentry); | 278 | status = vfs_rmdir(dir->d_inode, dentry); |
| 279 | mutex_unlock(&dir->d_inode->i_mutex); | 279 | mutex_unlock(&dir->d_inode->i_mutex); |
| 280 | return status; | 280 | return status; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 9041802df832..17249994110f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -1619,6 +1619,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
| 1619 | "jmacd-8: reiserfs_fill_super: unable to read bitmap"); | 1619 | "jmacd-8: reiserfs_fill_super: unable to read bitmap"); |
| 1620 | goto error; | 1620 | goto error; |
| 1621 | } | 1621 | } |
| 1622 | errval = -EINVAL; | ||
| 1622 | #ifdef CONFIG_REISERFS_CHECK | 1623 | #ifdef CONFIG_REISERFS_CHECK |
| 1623 | SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); | 1624 | SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); |
| 1624 | SWARN(silent, s, "- it is slow mode for debugging."); | 1625 | SWARN(silent, s, "- it is slow mode for debugging."); |
diff --git a/fs/xattr.c b/fs/xattr.c index 395635100f77..0901bdc2ce24 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
| @@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
| 48 | return 0; | 48 | return 0; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | * The trusted.* namespace can only accessed by a privilegued user. | 51 | * The trusted.* namespace can only be accessed by a privileged user. |
| 52 | */ | 52 | */ |
| 53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | 53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) |
| 54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); |
| 55 | 55 | ||
| 56 | /* In user.* namespace, only regular files and directories can have | ||
| 57 | * extended attributes. For sticky directories, only the owner and | ||
| 58 | * privileged user can write attributes. | ||
| 59 | */ | ||
| 56 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { | 60 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
| 57 | if (!S_ISREG(inode->i_mode) && | 61 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
| 58 | (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) | 62 | return -EPERM; |
| 63 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && | ||
| 64 | (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) && | ||
| 65 | !capable(CAP_FOWNER)) | ||
| 59 | return -EPERM; | 66 | return -EPERM; |
| 60 | } | 67 | } |
| 61 | 68 | ||
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h index eac85ce101b6..c6a03187f932 100644 --- a/include/asm-powerpc/systbl.h +++ b/include/asm-powerpc/systbl.h | |||
| @@ -261,7 +261,7 @@ SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) | |||
| 261 | PPC_SYS_SPU(rtas) | 261 | PPC_SYS_SPU(rtas) |
| 262 | OLDSYS(debug_setcontext) | 262 | OLDSYS(debug_setcontext) |
| 263 | SYSCALL(ni_syscall) | 263 | SYSCALL(ni_syscall) |
| 264 | SYSCALL(ni_syscall) | 264 | COMPAT_SYS(migrate_pages) |
| 265 | COMPAT_SYS(mbind) | 265 | COMPAT_SYS(mbind) |
| 266 | COMPAT_SYS(get_mempolicy) | 266 | COMPAT_SYS(get_mempolicy) |
| 267 | COMPAT_SYS(set_mempolicy) | 267 | COMPAT_SYS(set_mempolicy) |
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 464a48cce7f5..b5fe93291c96 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h | |||
| @@ -276,7 +276,7 @@ | |||
| 276 | #define __NR_rtas 255 | 276 | #define __NR_rtas 255 |
| 277 | #define __NR_sys_debug_setcontext 256 | 277 | #define __NR_sys_debug_setcontext 256 |
| 278 | /* Number 257 is reserved for vserver */ | 278 | /* Number 257 is reserved for vserver */ |
| 279 | /* 258 currently unused */ | 279 | #define __NR_migrate_pages 258 |
| 280 | #define __NR_mbind 259 | 280 | #define __NR_mbind 259 |
| 281 | #define __NR_get_mempolicy 260 | 281 | #define __NR_get_mempolicy 260 |
| 282 | #define __NR_set_mempolicy 261 | 282 | #define __NR_set_mempolicy 261 |
diff --git a/include/linux/compat.h b/include/linux/compat.h index f1553196826f..80b17f440ec1 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
| @@ -230,5 +230,9 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); | |||
| 230 | extern int compat_printk(const char *fmt, ...); | 230 | extern int compat_printk(const char *fmt, ...); |
| 231 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); | 231 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); |
| 232 | 232 | ||
| 233 | asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, | ||
| 234 | compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, | ||
| 235 | const compat_ulong_t __user *new_nodes); | ||
| 236 | |||
| 233 | #endif /* CONFIG_COMPAT */ | 237 | #endif /* CONFIG_COMPAT */ |
| 234 | #endif /* _LINUX_COMPAT_H */ | 238 | #endif /* _LINUX_COMPAT_H */ |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 80f39cab470a..24b611147adb 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -171,6 +171,8 @@ __attribute_const__ roundup_pow_of_two(unsigned long x) | |||
| 171 | 171 | ||
| 172 | extern int printk_ratelimit(void); | 172 | extern int printk_ratelimit(void); |
| 173 | extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst); | 173 | extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst); |
| 174 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | ||
| 175 | unsigned int interval_msec); | ||
| 174 | 176 | ||
| 175 | static inline void console_silent(void) | 177 | static inline void console_silent(void) |
| 176 | { | 178 | { |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 6b27e07aef19..070394e846d0 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
| @@ -116,7 +116,9 @@ typedef int __bitwise suspend_disk_method_t; | |||
| 116 | #define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2) | 116 | #define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2) |
| 117 | #define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3) | 117 | #define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3) |
| 118 | #define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4) | 118 | #define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4) |
| 119 | #define PM_DISK_MAX ((__force suspend_disk_method_t) 5) | 119 | #define PM_DISK_TEST ((__force suspend_disk_method_t) 5) |
| 120 | #define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6) | ||
| 121 | #define PM_DISK_MAX ((__force suspend_disk_method_t) 7) | ||
| 120 | 122 | ||
| 121 | struct pm_ops { | 123 | struct pm_ops { |
| 122 | suspend_disk_method_t pm_disk_mode; | 124 | suspend_disk_method_t pm_disk_mode; |
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index 61eef508b041..28967eda9d7b 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h | |||
| @@ -908,7 +908,7 @@ struct ufs_super_block_third { | |||
| 908 | __fs64 fs_csaddr; /* blk addr of cyl grp summary area */ | 908 | __fs64 fs_csaddr; /* blk addr of cyl grp summary area */ |
| 909 | __fs64 fs_pendingblocks;/* blocks in process of being freed */ | 909 | __fs64 fs_pendingblocks;/* blocks in process of being freed */ |
| 910 | __fs32 fs_pendinginodes;/*inodes in process of being freed */ | 910 | __fs32 fs_pendinginodes;/*inodes in process of being freed */ |
| 911 | } fs_u2; | 911 | } __attribute__ ((packed)) fs_u2; |
| 912 | } fs_un1; | 912 | } fs_un1; |
| 913 | union { | 913 | union { |
| 914 | struct { | 914 | struct { |
| @@ -124,6 +124,7 @@ void msg_exit_ns(struct ipc_namespace *ns) | |||
| 124 | } | 124 | } |
| 125 | mutex_unlock(&msg_ids(ns).mutex); | 125 | mutex_unlock(&msg_ids(ns).mutex); |
| 126 | 126 | ||
| 127 | ipc_fini_ids(ns->ids[IPC_MSG_IDS]); | ||
| 127 | kfree(ns->ids[IPC_MSG_IDS]); | 128 | kfree(ns->ids[IPC_MSG_IDS]); |
| 128 | ns->ids[IPC_MSG_IDS] = NULL; | 129 | ns->ids[IPC_MSG_IDS] = NULL; |
| 129 | } | 130 | } |
| @@ -161,6 +161,7 @@ void sem_exit_ns(struct ipc_namespace *ns) | |||
| 161 | } | 161 | } |
| 162 | mutex_unlock(&sem_ids(ns).mutex); | 162 | mutex_unlock(&sem_ids(ns).mutex); |
| 163 | 163 | ||
| 164 | ipc_fini_ids(ns->ids[IPC_SEM_IDS]); | ||
| 164 | kfree(ns->ids[IPC_SEM_IDS]); | 165 | kfree(ns->ids[IPC_SEM_IDS]); |
| 165 | ns->ids[IPC_SEM_IDS] = NULL; | 166 | ns->ids[IPC_SEM_IDS] = NULL; |
| 166 | } | 167 | } |
| @@ -116,6 +116,7 @@ void shm_exit_ns(struct ipc_namespace *ns) | |||
| 116 | } | 116 | } |
| 117 | mutex_unlock(&shm_ids(ns).mutex); | 117 | mutex_unlock(&shm_ids(ns).mutex); |
| 118 | 118 | ||
| 119 | ipc_fini_ids(ns->ids[IPC_SHM_IDS]); | ||
| 119 | kfree(ns->ids[IPC_SHM_IDS]); | 120 | kfree(ns->ids[IPC_SHM_IDS]); |
| 120 | ns->ids[IPC_SHM_IDS] = NULL; | 121 | ns->ids[IPC_SHM_IDS] = NULL; |
| 121 | } | 122 | } |
diff --git a/ipc/util.c b/ipc/util.c index 42479e4eec59..cd8bb14a431f 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -301,7 +301,7 @@ static int grow_ary(struct ipc_ids* ids, int newsize) | |||
| 301 | */ | 301 | */ |
| 302 | rcu_assign_pointer(ids->entries, new); | 302 | rcu_assign_pointer(ids->entries, new); |
| 303 | 303 | ||
| 304 | ipc_rcu_putref(old); | 304 | __ipc_fini_ids(ids, old); |
| 305 | return newsize; | 305 | return newsize; |
| 306 | } | 306 | } |
| 307 | 307 | ||
diff --git a/ipc/util.h b/ipc/util.h index c8fd6b9d77b5..e3aa2c5c97dc 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
| @@ -83,6 +83,18 @@ void* ipc_rcu_alloc(int size); | |||
| 83 | void ipc_rcu_getref(void *ptr); | 83 | void ipc_rcu_getref(void *ptr); |
| 84 | void ipc_rcu_putref(void *ptr); | 84 | void ipc_rcu_putref(void *ptr); |
| 85 | 85 | ||
| 86 | static inline void __ipc_fini_ids(struct ipc_ids *ids, | ||
| 87 | struct ipc_id_ary *entries) | ||
| 88 | { | ||
| 89 | if (entries != &ids->nullentry) | ||
| 90 | ipc_rcu_putref(entries); | ||
| 91 | } | ||
| 92 | |||
| 93 | static inline void ipc_fini_ids(struct ipc_ids *ids) | ||
| 94 | { | ||
| 95 | __ipc_fini_ids(ids, ids->entries); | ||
| 96 | } | ||
| 97 | |||
| 86 | struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id); | 98 | struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id); |
| 87 | struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); | 99 | struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); |
| 88 | void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp); | 100 | void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp); |
diff --git a/kernel/compat.c b/kernel/compat.c index d4898aad6cfa..6952dd057300 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -982,4 +982,37 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages, | |||
| 982 | } | 982 | } |
| 983 | return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); | 983 | return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); |
| 984 | } | 984 | } |
| 985 | |||
| 986 | asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, | ||
| 987 | compat_ulong_t maxnode, | ||
| 988 | const compat_ulong_t __user *old_nodes, | ||
| 989 | const compat_ulong_t __user *new_nodes) | ||
| 990 | { | ||
| 991 | unsigned long __user *old = NULL; | ||
| 992 | unsigned long __user *new = NULL; | ||
| 993 | nodemask_t tmp_mask; | ||
| 994 | unsigned long nr_bits; | ||
| 995 | unsigned long size; | ||
| 996 | |||
| 997 | nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES); | ||
| 998 | size = ALIGN(nr_bits, BITS_PER_LONG) / 8; | ||
| 999 | if (old_nodes) { | ||
| 1000 | if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits)) | ||
| 1001 | return -EFAULT; | ||
| 1002 | old = compat_alloc_user_space(new_nodes ? size * 2 : size); | ||
| 1003 | if (new_nodes) | ||
| 1004 | new = old + size / sizeof(unsigned long); | ||
| 1005 | if (copy_to_user(old, nodes_addr(tmp_mask), size)) | ||
| 1006 | return -EFAULT; | ||
| 1007 | } | ||
| 1008 | if (new_nodes) { | ||
| 1009 | if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits)) | ||
| 1010 | return -EFAULT; | ||
| 1011 | if (new == NULL) | ||
| 1012 | new = compat_alloc_user_space(size); | ||
| 1013 | if (copy_to_user(new, nodes_addr(tmp_mask), size)) | ||
| 1014 | return -EFAULT; | ||
| 1015 | } | ||
| 1016 | return sys_migrate_pages(pid, nr_bits + 1, old, new); | ||
| 1017 | } | ||
| 985 | #endif | 1018 | #endif |
diff --git a/kernel/futex.c b/kernel/futex.c index b364e0026191..93ef30ba209f 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -1507,6 +1507,13 @@ static int futex_fd(u32 __user *uaddr, int signal) | |||
| 1507 | struct futex_q *q; | 1507 | struct futex_q *q; |
| 1508 | struct file *filp; | 1508 | struct file *filp; |
| 1509 | int ret, err; | 1509 | int ret, err; |
| 1510 | static unsigned long printk_interval; | ||
| 1511 | |||
| 1512 | if (printk_timed_ratelimit(&printk_interval, 60 * 60 * 1000)) { | ||
| 1513 | printk(KERN_WARNING "Process `%s' used FUTEX_FD, which " | ||
| 1514 | "will be removed from the kernel in June 2007\n", | ||
| 1515 | current->comm); | ||
| 1516 | } | ||
| 1510 | 1517 | ||
| 1511 | ret = -EINVAL; | 1518 | ret = -EINVAL; |
| 1512 | if (!valid_signal(signal)) | 1519 | if (!valid_signal(signal)) |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index d3a158a60312..b1fb7866b0b3 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
| @@ -71,7 +71,7 @@ static inline void platform_finish(void) | |||
| 71 | 71 | ||
| 72 | static int prepare_processes(void) | 72 | static int prepare_processes(void) |
| 73 | { | 73 | { |
| 74 | int error; | 74 | int error = 0; |
| 75 | 75 | ||
| 76 | pm_prepare_console(); | 76 | pm_prepare_console(); |
| 77 | 77 | ||
| @@ -84,6 +84,12 @@ static int prepare_processes(void) | |||
| 84 | goto thaw; | 84 | goto thaw; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | if (pm_disk_mode == PM_DISK_TESTPROC) { | ||
| 88 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
| 89 | mdelay(5000); | ||
| 90 | goto thaw; | ||
| 91 | } | ||
| 92 | |||
| 87 | /* Free memory before shutting down devices. */ | 93 | /* Free memory before shutting down devices. */ |
| 88 | if (!(error = swsusp_shrink_memory())) | 94 | if (!(error = swsusp_shrink_memory())) |
| 89 | return 0; | 95 | return 0; |
| @@ -120,13 +126,21 @@ int pm_suspend_disk(void) | |||
| 120 | if (error) | 126 | if (error) |
| 121 | return error; | 127 | return error; |
| 122 | 128 | ||
| 129 | if (pm_disk_mode == PM_DISK_TESTPROC) | ||
| 130 | goto Thaw; | ||
| 131 | |||
| 123 | suspend_console(); | 132 | suspend_console(); |
| 124 | error = device_suspend(PMSG_FREEZE); | 133 | error = device_suspend(PMSG_FREEZE); |
| 125 | if (error) { | 134 | if (error) { |
| 126 | resume_console(); | 135 | resume_console(); |
| 127 | printk("Some devices failed to suspend\n"); | 136 | printk("Some devices failed to suspend\n"); |
| 128 | unprepare_processes(); | 137 | goto Thaw; |
| 129 | return error; | 138 | } |
| 139 | |||
| 140 | if (pm_disk_mode == PM_DISK_TEST) { | ||
| 141 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
| 142 | mdelay(5000); | ||
| 143 | goto Done; | ||
| 130 | } | 144 | } |
| 131 | 145 | ||
| 132 | pr_debug("PM: snapshotting memory.\n"); | 146 | pr_debug("PM: snapshotting memory.\n"); |
| @@ -143,16 +157,17 @@ int pm_suspend_disk(void) | |||
| 143 | power_down(pm_disk_mode); | 157 | power_down(pm_disk_mode); |
| 144 | else { | 158 | else { |
| 145 | swsusp_free(); | 159 | swsusp_free(); |
| 146 | unprepare_processes(); | 160 | goto Thaw; |
| 147 | return error; | ||
| 148 | } | 161 | } |
| 149 | } else | 162 | } else { |
| 150 | pr_debug("PM: Image restored successfully.\n"); | 163 | pr_debug("PM: Image restored successfully.\n"); |
| 164 | } | ||
| 151 | 165 | ||
| 152 | swsusp_free(); | 166 | swsusp_free(); |
| 153 | Done: | 167 | Done: |
| 154 | device_resume(); | 168 | device_resume(); |
| 155 | resume_console(); | 169 | resume_console(); |
| 170 | Thaw: | ||
| 156 | unprepare_processes(); | 171 | unprepare_processes(); |
| 157 | return error; | 172 | return error; |
| 158 | } | 173 | } |
| @@ -249,6 +264,8 @@ static const char * const pm_disk_modes[] = { | |||
| 249 | [PM_DISK_PLATFORM] = "platform", | 264 | [PM_DISK_PLATFORM] = "platform", |
| 250 | [PM_DISK_SHUTDOWN] = "shutdown", | 265 | [PM_DISK_SHUTDOWN] = "shutdown", |
| 251 | [PM_DISK_REBOOT] = "reboot", | 266 | [PM_DISK_REBOOT] = "reboot", |
| 267 | [PM_DISK_TEST] = "test", | ||
| 268 | [PM_DISK_TESTPROC] = "testproc", | ||
| 252 | }; | 269 | }; |
| 253 | 270 | ||
| 254 | /** | 271 | /** |
| @@ -303,17 +320,19 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) | |||
| 303 | } | 320 | } |
| 304 | } | 321 | } |
| 305 | if (mode) { | 322 | if (mode) { |
| 306 | if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT) | 323 | if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT || |
| 324 | mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) { | ||
| 307 | pm_disk_mode = mode; | 325 | pm_disk_mode = mode; |
| 308 | else { | 326 | } else { |
| 309 | if (pm_ops && pm_ops->enter && | 327 | if (pm_ops && pm_ops->enter && |
| 310 | (mode == pm_ops->pm_disk_mode)) | 328 | (mode == pm_ops->pm_disk_mode)) |
| 311 | pm_disk_mode = mode; | 329 | pm_disk_mode = mode; |
| 312 | else | 330 | else |
| 313 | error = -EINVAL; | 331 | error = -EINVAL; |
| 314 | } | 332 | } |
| 315 | } else | 333 | } else { |
| 316 | error = -EINVAL; | 334 | error = -EINVAL; |
| 335 | } | ||
| 317 | 336 | ||
| 318 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", | 337 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", |
| 319 | pm_disk_modes[mode]); | 338 | pm_disk_modes[mode]); |
diff --git a/kernel/printk.c b/kernel/printk.c index f7d427ef5038..66426552fbfe 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/security.h> | 31 | #include <linux/security.h> |
| 32 | #include <linux/bootmem.h> | 32 | #include <linux/bootmem.h> |
| 33 | #include <linux/syscalls.h> | 33 | #include <linux/syscalls.h> |
| 34 | #include <linux/jiffies.h> | ||
| 34 | 35 | ||
| 35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 36 | 37 | ||
| @@ -1101,3 +1102,23 @@ int printk_ratelimit(void) | |||
| 1101 | printk_ratelimit_burst); | 1102 | printk_ratelimit_burst); |
| 1102 | } | 1103 | } |
| 1103 | EXPORT_SYMBOL(printk_ratelimit); | 1104 | EXPORT_SYMBOL(printk_ratelimit); |
| 1105 | |||
| 1106 | /** | ||
| 1107 | * printk_timed_ratelimit - caller-controlled printk ratelimiting | ||
| 1108 | * @caller_jiffies: pointer to caller's state | ||
| 1109 | * @interval_msecs: minimum interval between prints | ||
| 1110 | * | ||
| 1111 | * printk_timed_ratelimit() returns true if more than @interval_msecs | ||
| 1112 | * milliseconds have elapsed since the last time printk_timed_ratelimit() | ||
| 1113 | * returned true. | ||
| 1114 | */ | ||
| 1115 | bool printk_timed_ratelimit(unsigned long *caller_jiffies, | ||
| 1116 | unsigned int interval_msecs) | ||
| 1117 | { | ||
| 1118 | if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) { | ||
| 1119 | *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs); | ||
| 1120 | return true; | ||
| 1121 | } | ||
| 1122 | return false; | ||
| 1123 | } | ||
| 1124 | EXPORT_SYMBOL(printk_timed_ratelimit); | ||
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0e53314b14de..d7306d0f3dfc 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
| @@ -135,6 +135,7 @@ cond_syscall(sys_madvise); | |||
| 135 | cond_syscall(sys_mremap); | 135 | cond_syscall(sys_mremap); |
| 136 | cond_syscall(sys_remap_file_pages); | 136 | cond_syscall(sys_remap_file_pages); |
| 137 | cond_syscall(compat_sys_move_pages); | 137 | cond_syscall(compat_sys_move_pages); |
| 138 | cond_syscall(compat_sys_migrate_pages); | ||
| 138 | 139 | ||
| 139 | /* block-layer dependent */ | 140 | /* block-layer dependent */ |
| 140 | cond_syscall(sys_bdflush); | 141 | cond_syscall(sys_bdflush); |
diff --git a/mm/migrate.c b/mm/migrate.c index ba2453f9483d..b4979d423d2b 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -952,7 +952,8 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, | |||
| 952 | goto out; | 952 | goto out; |
| 953 | 953 | ||
| 954 | pm[i].node = node; | 954 | pm[i].node = node; |
| 955 | } | 955 | } else |
| 956 | pm[i].node = 0; /* anything to not match MAX_NUMNODES */ | ||
| 956 | } | 957 | } |
| 957 | /* End marker */ | 958 | /* End marker */ |
| 958 | pm[nr_pages].node = MAX_NUMNODES; | 959 | pm[nr_pages].node = MAX_NUMNODES; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b55bb358b832..bf2f6cff1d6a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -853,7 +853,7 @@ again: | |||
| 853 | pcp = &zone_pcp(zone, cpu)->pcp[cold]; | 853 | pcp = &zone_pcp(zone, cpu)->pcp[cold]; |
| 854 | local_irq_save(flags); | 854 | local_irq_save(flags); |
| 855 | if (!pcp->count) { | 855 | if (!pcp->count) { |
| 856 | pcp->count += rmqueue_bulk(zone, 0, | 856 | pcp->count = rmqueue_bulk(zone, 0, |
| 857 | pcp->batch, &pcp->list); | 857 | pcp->batch, &pcp->list); |
| 858 | if (unlikely(!pcp->count)) | 858 | if (unlikely(!pcp->count)) |
| 859 | goto failed; | 859 | goto failed; |
diff --git a/mm/readahead.c b/mm/readahead.c index 1ba736ac0367..23cb61a01c6e 100644 --- a/mm/readahead.c +++ b/mm/readahead.c | |||
| @@ -173,6 +173,8 @@ static int read_pages(struct address_space *mapping, struct file *filp, | |||
| 173 | 173 | ||
| 174 | if (mapping->a_ops->readpages) { | 174 | if (mapping->a_ops->readpages) { |
| 175 | ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages); | 175 | ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages); |
| 176 | /* Clean up the remaining pages */ | ||
| 177 | put_pages_list(pages); | ||
| 176 | goto out; | 178 | goto out; |
| 177 | } | 179 | } |
| 178 | 180 | ||
| @@ -883,7 +883,7 @@ static void init_reap_node(int cpu) | |||
| 883 | if (node == MAX_NUMNODES) | 883 | if (node == MAX_NUMNODES) |
| 884 | node = first_node(node_online_map); | 884 | node = first_node(node_online_map); |
| 885 | 885 | ||
| 886 | __get_cpu_var(reap_node) = node; | 886 | per_cpu(reap_node, cpu) = node; |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | static void next_reap_node(void) | 889 | static void next_reap_node(void) |
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 4ab6cbf09225..d6071cbf13d7 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
| @@ -250,7 +250,7 @@ void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } | |||
| 250 | void extfunc(char * filename) { docfunctions(filename, FUNCTION); } | 250 | void extfunc(char * filename) { docfunctions(filename, FUNCTION); } |
| 251 | 251 | ||
| 252 | /* | 252 | /* |
| 253 | * Document spåecific function(s) in a file. | 253 | * Document specific function(s) in a file. |
| 254 | * Call kernel-doc with the following parameters: | 254 | * Call kernel-doc with the following parameters: |
| 255 | * kernel-doc -docbook -function function1 [-function function2] | 255 | * kernel-doc -docbook -function function1 [-function function2] |
| 256 | */ | 256 | */ |
