diff options
73 files changed, 980 insertions, 301 deletions
@@ -2601,7 +2601,7 @@ S: Germany N: Geert Uytterhoeven E: geert@linux-m68k.org -W: http://www.cs.kuleuven.ac.be/~geert/ +W: http://home.tvd.be/cr26864/ P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1 CD 9E AE DC 4B 4A 2F 41 D: m68k/Amiga and PPC/CHRP Longtrail coordinator D: Frame buffer device and XF68_FBDev maintainer diff --git a/Documentation/DocBook/parportbook.tmpl b/Documentation/DocBook/parportbook.tmpl index bf4d77873..754f1a96b 100644 --- a/Documentation/DocBook/parportbook.tmpl +++ b/Documentation/DocBook/parportbook.tmpl @@ -24,30 +24,12 @@ <legalnotice> <para> - This documentation is free software; you can redistribute - it and/or modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later - version. - </para> - - <para> - This program is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - </para> - - <para> - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, - MA 02111-1307 USA - </para> - - <para> - For more details see the file COPYING in the source - distribution of Linux. + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.1 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included + in the section entitled "GNU Free Documentation License". </para> </legalnotice> </bookinfo> @@ -2209,9 +2191,9 @@ ssize_t write_printer (int fd, const void *ptr, size_t count) </chapter> - <appendix> + <appendix id="api"> <title> - API reference + Linux parallel port driver API reference </title> !Fdrivers/parport/daisy.c parport_device_num @@ -2314,10 +2296,375 @@ ssize_t write_printer (int fd, const void *ptr, size_t count) removed. </para> </appendix> + + <appendix id="fdl"> + <title> + GNU Free Documentation License + </title> + + <literallayout class="monospaced"> + GNU Free Documentation License + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http:///www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + </literallayout> + </appendix> + </book> <!-- Local Variables: --> <!-- sgml-indent-step: 1 --> <!-- sgml-indent-data: 1 --> <!-- End: --> - diff --git a/Documentation/fb/framebuffer.txt b/Documentation/fb/framebuffer.txt index e8c51d1b5..94da7175d 100644 --- a/Documentation/fb/framebuffer.txt +++ b/Documentation/fb/framebuffer.txt @@ -332,7 +332,7 @@ and on its mirrors. The latest version of fbset can be found at - http://www.cs.kuleuven.ac.be/~geert/bin/ + http://home.tvd.be/cr26864/Linux/fbdev/ 10. Credits diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking new file mode 100644 index 000000000..0dd2cc8eb --- /dev/null +++ b/Documentation/filesystems/Locking @@ -0,0 +1,315 @@ + The text below describes the locking rules for VFS-related methods. +It is (believed to be) up-to-date. *Please*, if you change anything in +prototypes or locking protocols - update this file. And update the relevant +instances in the tree, don't leave that to maintainers of filesystems/devices/ +etc. At the very least, put the list of dubious cases in the end of this file. +Don't turn it into log - maintainers of out-of-the-tree code are supposed to +be able to use diff(1). + Thing currently missing here: socket operations. Alexey? + +--------------------------- dentry_operations -------------------------- +prototypes: + int (*d_revalidate)(struct dentry *, int); + int (*d_hash) (struct dentry *, struct qstr *); + int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); + int (*d_delete)(struct dentry *); + void (*d_release)(struct dentry *); + void (*d_iput)(struct dentry *, struct inode *); + +locking rules: + none have BKL + dcache_lock may block +d_revalidate: no yes +d_hash no yes +d_compare: yes no +d_delete: yes no +d_release: no yes +d_iput: no yes + +--------------------------- inode_operations --------------------------- +prototypes: + int (*create) (struct inode *,struct dentry *,int); + struct dentry * (*lookup) (struct inode *,struct dentry *); + int (*link) (struct dentry *,struct inode *,struct dentry *); + int (*unlink) (struct inode *,struct dentry *); + int (*symlink) (struct inode *,struct dentry *,const char *); + int (*mkdir) (struct inode *,struct dentry *,int); + int (*rmdir) (struct inode *,struct dentry *); + int (*mknod) (struct inode *,struct dentry *,int,int); + int (*rename) (struct inode *, struct dentry *, + struct inode *, struct dentry *); + int (*readlink) (struct dentry *, char *,int); + int (*follow_link) (struct dentry *, struct nameidata *); + void (*truncate) (struct inode *); + int (*permission) (struct inode *, int); + int (*revalidate) (struct dentry *); + int (*setattr) (struct dentry *, struct iattr *); + int (*getattr) (struct dentry *, struct iattr *); + +locking rules: + all may block + BKL i_sem(inode) i_zombie(inode) +lookup: yes yes no +create: yes yes yes +link: yes yes yes +mknod: yes yes yes +mkdir: yes yes yes +unlink: yes yes yes +rmdir: yes yes yes (see below) +rename: yes yes (both) yes (both) (see below) +readlink: no no no +follow_link: no no no +truncate: yes yes no (see below) +setattr: yes if ATTR_SIZE no +permssion: yes no no +getattr: (see below) +revalidate: no (see below) + Additionally, ->rmdir() has i_zombie on victim and so does ->rename() +in case when target exists and is a directory. + ->revalidate(), it may be called both with and without the i_sem +on dentry->d_inode. VFS never calls it with i_zombie on dentry->d_inode, +but watch for other methods directly calling this one... + ->truncate() is never called directly - it's a callback, not a +method. It's called by vmtruncate() - library function normally used by +->setattr(). Locking information above applies to that call (i.e. is +inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been +passed). + ->getattr() is currently unused. + +--------------------------- super_operations --------------------------- +prototypes: + void (*read_inode) (struct inode *); + void (*write_inode) (struct inode *, int); + void (*put_inode) (struct inode *); + void (*delete_inode) (struct inode *); + void (*put_super) (struct super_block *); + void (*write_super) (struct super_block *); + int (*statfs) (struct super_block *, struct statfs *); + int (*remount_fs) (struct super_block *, int *, char *); + void (*clear_inode) (struct inode *); + void (*umount_begin) (struct super_block *); + +locking rules: + All may block. + BKL s_lock mount_sem +read_inode: yes (see below) +write_inode: no +put_inode: no +delete_inode: no +clear_inode: no +put_super: yes yes maybe (see below) +write_super: yes yes maybe (see below) +statfs: yes no no +remount_fs: yes yes maybe (see below) +umount_begin: yes no maybe (see below) + +->read_inode() is not a method - it's a callback used in iget()/iget4(). +rules for mount_sem are not too nice - it is going to die and be replaced +by better scheme anyway. + +--------------------------- file_system_type --------------------------- +prototypes: + struct super_block *(*read_super) (struct super_block *, void *, int); +locking rules: +may block BKL ->s_lock mount_sem +yes yes yes maybe + +--------------------------- address_space_operations -------------------------- +prototypes: + int (*writepage)(struct file *, struct page *); + int (*readpage)(struct file *, struct page *); + int (*sync_page)(struct page *); + int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); + int (*commit_write)(struct file *, struct page *, unsigned, unsigned); + int (*bmap)(struct address_space *, long); +locking rules: + All may block + BKL PageLocked(page) +writepage: no yes +readpage: no yes +sync_page: no maybe +prepare_write: no yes +commit_write: no yes +bmap: yes + + ->prepare_write(), ->commit_write(), ->sync_page() and ->readpage() +may be called from the request handler (/dev/loop). + ->sync_page() locking rules are not well-defined - usually it is called +with lock on page, but that is not guaranteed. Considering the currently +existsing instances of this method ->sync_page() itself doesn't look +well-defined... + ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some +filesystems and by the swapper. The latter will eventually go away. All +instances do not actually need the BKL. Please, keep it that way and don't +breed new callers. + Note: currently almost all instances of address_space methods are +using BKL for internal serialization and that's one of the worst sources +of contention. Normally they are calling library functions (in fs/buffer.c) +and pass foo_get_block() as a callback (on local block-based filesystems, +indeed). BKL is not needed for library stuff and is usually taken by +foo_get_block(). It's an overkill, since block bitmaps can be protected by +internal fs locking and real critical areas are much smaller than the areas +filesystems protect now. + +--------------------------- file_lock ------------------------------------ +prototypes: + void (*fl_notify)(struct file_lock *); /* unblock callback */ + void (*fl_insert)(struct file_lock *); /* lock insertion callback */ + void (*fl_remove)(struct file_lock *); /* lock removal callback */ + +locking rules: + BKL may block +fl_notify: yes no +fl_insert: yes maybe +fl_remove: yes maybe + Currently only NLM provides instances of this class. None of the +them block. If you have out-of-tree instances - please, show up. Locking +in that area will change. + +--------------------------- buffer_head ----------------------------------- +prototypes: + void (*b_end_io)(struct buffer_head *bh, int uptodate); + +locking rules: + called from interrupts. In other words, extreme care is needed here. +bh is locked, but that's all warranties we have here. Currently only RAID1, +highmem and fs/buffer.c are providing these. Block devices call this method +upon the IO completion. + +--------------------------- block_device_operations ----------------------- +prototypes: + int (*open) (struct inode *, struct file *); + int (*release) (struct inode *, struct file *); + int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); + int (*check_media_change) (kdev_t); + int (*revalidate) (kdev_t); +locking rules: + BKL bd_sem +open: yes yes +release: yes yes +ioctl: yes no +check_media_change: yes no +revalidate: yes no + +The last two are called only from check_disk_change(). Prototypes are very +bad - as soon as we'll get disk_struct they will change (and methods will +become per-disk instead of per-partition). + +--------------------------- file_operations ------------------------------- +prototypes: + loff_t (*llseek) (struct file *, loff_t, int); + ssize_t (*read) (struct file *, char *, size_t, loff_t *); + ssize_t (*write) (struct file *, const char *, size_t, loff_t *); + int (*readdir) (struct file *, void *, filldir_t); + unsigned int (*poll) (struct file *, struct poll_table_struct *); + int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); + int (*mmap) (struct file *, struct vm_area_struct *); + int (*open) (struct inode *, struct file *); + int (*flush) (struct file *); + int (*release) (struct inode *, struct file *); + int (*fsync) (struct file *, struct dentry *, int datasync); + int (*fasync) (int, struct file *, int); + int (*lock) (struct file *, int, struct file_lock *); + ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); + ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); +}; + +locking rules: + All except ->poll() may block. + BKL +llseek: yes +read: no +write: no +readdir: yes (see below) +poll: no +ioctl: yes (see below) +mmap: no +open: maybe (see below) +flush: yes +release: yes +fsync: yes (see below) +fasync: yes (see below) +lock: yes +readv: no +writev: no + +->open() locking is in-transit: big lock partially moved into the methods. +The only exception is ->open() in the instances of file_operations that never +end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices +(chrdev_open() takes lock before replacing ->f_op and calling the secondary +method. As soon as we fix the handling of module reference counters all +instances of ->open() will be called without the BKL. At the same point +->release() will lose BKL. Currently ext2_release() is *the* source of +contention on fs-intensive loads and dropping BKL on ->release() will get +rid of that (we will still need some locking for cases when we close a file +that had been opened r/w, but that can be done using the internal locking with +smaller critical areas). sock_close() is also going to win from that change. + +->fasync() is a mess. This area needs a big cleanup and that will probably +affect locking. + +->readdir() and ->ioctl() on directories must be changed. Ideally we would +move ->readdir() to inode_operations and use a separate method for directory +->ioctl() or kill the latter completely. One of the problems is that for +anything that resembles union-mount we won't have a struct file for all +components. And there are other reasons why the current interface is a mess... + +->read on directories probably must go away - we should just enforce -EISDIR +in sys_read() and friends. + +->fsync() has i_sem on inode. + +--------------------------- dquot_operations ------------------------------- +prototypes: + void (*initialize) (struct inode *, short); + void (*drop) (struct inode *); + int (*alloc_block) (const struct inode *, unsigned long, char); + int (*alloc_inode) (const struct inode *, unsigned long); + void (*free_block) (const struct inode *, unsigned long); + void (*free_inode) (const struct inode *, unsigned long); + int (*transfer) (struct dentry *, struct iattr *); + +locking rules: + BKL +initialize: no +drop: no +alloc_block: yes +alloc_inode: yes +free_block: yes +free_inode: yes +transfer: no + +--------------------------- vm_operations_struct ----------------------------- +prototypes: + void (*open)(struct vm_area_struct*); + void (*close)(struct vm_area_struct*); + void (*unmap)(struct vm_area_struct*, unsigned long, size_t); + void (*protect)(struct vm_area_struct*, unsigned long, size_t, unsigned); + int (*sync)(struct vm_area_struct*, unsigned long, size_t, unsigned); + struct page *(*nopage)(struct vm_area_struct*, unsigned long, int); + struct page *(*wppage)(struct vm_area_struct*, unsigned long, struct page*); + int (*swapout)(struct page *, struct file *); + +locking rules: + BKL mmap_sem +open: no yes +close: no yes +sync: no yes +unmap: no yes +nopage: no yes +swapout: yes yes +wpppage: (see below) +protect: (see below) + +->wppage() and ->protect() have no instances and nothing calls them; looks like +they must die... + +================================================================================ + Dubious stuff + +(if you break something or notice that it is broken and do not fix it yourself +- at least put it here) + +ipc/shm.c::shm_delete() - may need BKL. +->read() and ->write() in many drivers are (probably) missing BKL. +drivers/sgi/char/graphics.c::sgi_graphics_nopage() - may need BKL. @@ -1,7 +1,8 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test3 +#EXTRAVERSION = -test3 +EXTRAVERSION = -test3-pre7 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index e1617fbaa..2c3cabadc 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -230,7 +230,6 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r int error; char * filename; - lock_kernel(); filename = getname(filenamei); error = PTR_ERR(filename); if (IS_ERR(filename)) @@ -238,7 +237,6 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r error = do_execve(filename, argv, envp, regs); putname(filename); out: - unlock_kernel(); return error; } diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 95f8b1f54..1e9876eb4 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -708,7 +708,6 @@ sys32_getdents (unsigned int fd, void * dirent, unsigned int count) buf.count = count; buf.error = 0; - lock_kernel(); error = vfs_readdir(file, filldir32, &buf); if (error < 0) goto out_putf; @@ -720,7 +719,6 @@ sys32_getdents (unsigned int fd, void * dirent, unsigned int count) } out_putf: - unlock_kernel(); fput(file); out: return error; @@ -759,12 +757,9 @@ sys32_readdir (unsigned int fd, void * dirent, unsigned int count) buf.count = 0; buf.dirent = dirent; - lock_kernel(); error = vfs_readdir(file, fillonedir32, &buf); if (error >= 0) error = buf.count; - unlock_kernel(); - fput(file); out: return error; @@ -1028,7 +1023,6 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count) struct file *file; long ret = -EBADF; - lock_kernel(); file = fget(fd); if(!file) goto bad_file; @@ -1041,7 +1035,6 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count) out: fput(file); bad_file: - unlock_kernel(); return ret; } @@ -1051,7 +1044,6 @@ sys32_writev(int fd, struct iovec32 *vector, u32 count) struct file *file; int ret = -EBADF; - lock_kernel(); file = fget(fd); if(!file) goto bad_file; @@ -1066,7 +1058,6 @@ sys32_writev(int fd, struct iovec32 *vector, u32 count) out: fput(file); bad_file: - unlock_kernel(); return ret; } @@ -1852,7 +1843,6 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { int version, err; - lock_kernel(); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -1904,7 +1894,6 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) break; } - unlock_kernel(); return err; } @@ -3719,7 +3708,6 @@ sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags) } kern_msg.msg_flags = user_flags; - lock_kernel(); sock = sockfd_lookup(fd, &err); if (sock != NULL) { if (sock->file->f_flags & O_NONBLOCK) @@ -3727,7 +3715,6 @@ sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags) err = sock_sendmsg(sock, &kern_msg, total_len); sockfd_put(sock); } - unlock_kernel(); /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ if(ctl_buf != ctl) @@ -3767,7 +3754,6 @@ sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags) cmsg_ptr = (unsigned long) kern_msg.msg_control; kern_msg.msg_flags = 0; - lock_kernel(); sock = sockfd_lookup(fd, &err); if (sock != NULL) { struct scm_cookie scm; @@ -3775,6 +3761,7 @@ sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags) if (sock->file->f_flags & O_NONBLOCK) user_flags |= MSG_DONTWAIT; memset(&scm, 0, sizeof(scm)); + lock_kernel(); err = sock->ops->recvmsg(sock, &kern_msg, total_len, user_flags, &scm); if(err >= 0) { @@ -3805,9 +3792,9 @@ sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags) scm_detach_fds32(&kern_msg, &scm); } } + unlock_kernel(); sockfd_put(sock); } - unlock_kernel(); if(uaddr != NULL && err >= 0) err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, @@ -4707,11 +4694,9 @@ asmlinkage long sys32_personality(unsigned long personality) { int ret; - lock_kernel(); if (current->personality == PER_LINUX32 && personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); - unlock_kernel(); if (ret == PER_LINUX32) ret = PER_LINUX; return ret; diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index c25193cdc..0ccbe24a6 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -180,27 +180,21 @@ sys_ioperm (unsigned long from, unsigned long num, int on) asmlinkage long sys_iopl (int level, long arg1, long arg2, long arg3) { - lock_kernel(); printk(KERN_ERR "sys_iopl(level=%d)!\n", level); - unlock_kernel(); return -ENOSYS; } asmlinkage long sys_vm86 (long arg0, long arg1, long arg2, long arg3) { - lock_kernel(); printk(KERN_ERR "sys_vm86(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3); - unlock_kernel(); return -ENOSYS; } asmlinkage long sys_modify_ldt (long arg0, long arg1, long arg2, long arg3) { - lock_kernel(); printk(KERN_ERR "sys_modify_ldt(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3); - unlock_kernel(); return -ENOSYS; } @@ -296,7 +290,6 @@ ia64_oldstat (char *filename, struct ia64_oldstat *statbuf) struct nameidata nd; int error; - lock_kernel(); error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -304,7 +297,6 @@ ia64_oldstat (char *filename, struct ia64_oldstat *statbuf) error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } - unlock_kernel(); return error; } @@ -314,7 +306,6 @@ ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) { struct nameidata nd; int error; - lock_kernel(); error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -322,7 +313,6 @@ ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) { error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf); path_release(&nd); } - unlock_kernel(); return error; } @@ -332,7 +322,6 @@ ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf) struct file * f; int err = -EBADF; - lock_kernel(); f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; @@ -342,7 +331,6 @@ ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf) err = cp_ia64_old_stat(dentry->d_inode, statbuf); fput(f); } - unlock_kernel(); return err; } diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c index 67383d84a..7d34f2d8c 100644 --- a/arch/mips/kernel/sysmips.c +++ b/arch/mips/kernel/sysmips.c @@ -49,7 +49,7 @@ sys_sysmips(int cmd, int arg1, int arg2, int arg3) { int *p; char *name; - int flags, tmp, len, retval; + int flags, tmp, len, retval, errno; switch(cmd) { case SETNAME: { diff --git a/arch/ppc/amiga/chipram.c b/arch/ppc/amiga/chipram.c index 31f91a794..259522584 100644 --- a/arch/ppc/amiga/chipram.c +++ b/arch/ppc/amiga/chipram.c @@ -1,15 +1,14 @@ /* ** linux/amiga/chipram.c ** -** Modified 03-May-94 by Geert Uytterhoeven -** (Geert.Uytterhoeven@cs.kuleuven.ac.be) +** Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org> ** - 64-bit aligned allocations for full AGA compatibility */ -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/zorro.h> #include <asm/amigahw.h> struct chip_desc { @@ -25,6 +24,8 @@ struct chip_desc { u_long amiga_chip_size; static unsigned long chipavail; +static struct resource chipram = { "Chip RAM", 0 }; + unsigned long amiga_chip_avail( void ) { #ifdef DEBUG @@ -34,8 +35,7 @@ unsigned long amiga_chip_avail( void ) } -__init -void amiga_chip_init (void) +void __init amiga_chip_init (void) { struct chip_desc *dp; @@ -49,6 +49,8 @@ void amiga_chip_init (void) */ amiga_chip_size -= 0x4000; #endif + chipram.end = amiga_chip_size-1; + request_resource(&iomem_resource, &chipram); /* initialize start boundary */ @@ -72,7 +74,7 @@ void amiga_chip_init (void) #endif } -void *amiga_chip_alloc (long size) +void *amiga_chip_alloc(long size, const char *name) { /* last chunk */ struct chip_desc *dp; @@ -82,7 +84,7 @@ void *amiga_chip_alloc (long size) size = (size + 7) & ~7; #ifdef DEBUG - printk("chip_alloc: allocate %ld bytes\n", size); + printk("amiga_chip_alloc: allocate %ld bytes\n", size); #endif /* @@ -108,14 +110,14 @@ void *amiga_chip_alloc (long size) dp = DP((unsigned long)ptr + dp->length); dp->alloced = 1; #ifdef DEBUG - printk ("chip_alloc: no split\n"); + printk ("amiga_chip_alloc: no split\n"); #endif } else { /* split the extent; use the end part */ long newsize = dp->length - (2*sizeof(*dp) + size); #ifdef DEBUG - printk ("chip_alloc: splitting %d to %ld\n", dp->length, + printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length, newsize); #endif dp->length = newsize; @@ -134,14 +136,18 @@ void *amiga_chip_alloc (long size) } #ifdef DEBUG - printk ("chip_alloc: returning %p\n", ptr); + printk ("amiga_chip_alloc: returning %p\n", ptr); #endif if ((unsigned long)ptr & 7) - panic("chip_alloc: alignment violation\n"); + panic("amiga_chip_alloc: alignment violation\n"); chipavail -= size + (2*sizeof(*dp)); /*MILAN*/ + if (!request_mem_region(ZTWO_PADDR(ptr), size, name)) + printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx " + "is busy\n", size, ZTWO_PADDR(ptr)); + return ptr; } @@ -156,6 +162,7 @@ void amiga_chip_free (void *ptr) #endif /* deallocate the chunk */ sdp->alloced = edp->alloced = 0; + release_mem_region(ZTWO_PADDR(ptr), sdp->length); /* check if we should merge with the previous chunk */ if (!sdp->first && !sdp[-1].alloced) { diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c index 08d0bc44b..11aa42cad 100644 --- a/arch/ppc/kernel/syscalls.c +++ b/arch/ppc/kernel/syscalls.c @@ -52,25 +52,19 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) int sys_iopl(int a1, int a2, int a3, int a4) { - lock_kernel(); printk(KERN_ERR "sys_iopl(%x, %x, %x, %x)!\n", a1, a2, a3, a4); - unlock_kernel(); return (-ENOSYS); } int sys_vm86(int a1, int a2, int a3, int a4) { - lock_kernel(); printk(KERN_ERR "sys_vm86(%x, %x, %x, %x)!\n", a1, a2, a3, a4); - unlock_kernel(); return (-ENOSYS); } int sys_modify_ldt(int a1, int a2, int a3, int a4) { - lock_kernel(); printk(KERN_ERR "sys_modify_ldt(%x, %x, %x, %x)!\n", a1, a2, a3, a4); - unlock_kernel(); return (-ENOSYS); } @@ -84,7 +78,6 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) { int version, ret; - lock_kernel(); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -171,7 +164,6 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) break; } - unlock_kernel(); return ret; } diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 66221c796..848dba72e 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -100,7 +100,6 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, { int version, err; - lock_kernel(); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -195,7 +194,6 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, else err = -EINVAL; out: - unlock_kernel(); return err; } diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 1ba500986..73cb4580c 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -521,7 +521,6 @@ asmlinkage int sunos_fpathconf(int fd, int name) { int ret; - lock_kernel(); switch(name) { case _PCONF_LINK: ret = LINK_MAX; @@ -552,7 +551,6 @@ asmlinkage int sunos_fpathconf(int fd, int name) ret = -EINVAL; break; } - unlock_kernel(); return ret; } @@ -560,9 +558,7 @@ asmlinkage int sunos_pathconf(char *path, int name) { int ret; - lock_kernel(); ret = sunos_fpathconf(0, name); /* XXX cheese XXX */ - unlock_kernel(); return ret; } @@ -575,7 +571,6 @@ asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, s int ret; /* SunOS binaries expect that select won't change the tvp contents */ - lock_kernel(); ret = sys_select (width, inp, outp, exp, tvp); if (ret == -EINTR && tvp) { time_t sec, usec; @@ -586,7 +581,6 @@ asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, s if (sec == 0 && usec == 0) ret = 0; } - unlock_kernel(); return ret; } @@ -829,7 +823,6 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) int ret; /* So stupid... */ - lock_kernel(); if((!pid || pid == current->pid) && !pgid) { sys_setsid(); @@ -837,7 +830,6 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) } else { ret = sys_setpgid(pid, pgid); } - unlock_kernel(); return ret; } @@ -847,9 +839,7 @@ asmlinkage int sunos_wait4(pid_t pid, unsigned int *stat_addr, int options, stru { int ret; - lock_kernel(); ret = sys_wait4((pid ? pid : -1), stat_addr, options, ru); - unlock_kernel(); return ret; } @@ -897,7 +887,6 @@ extern asmlinkage long sunos_sysconf (int name) { long ret; - lock_kernel(); switch (name){ case _SC_ARG_MAX: ret = ARG_MAX; @@ -930,7 +919,6 @@ extern asmlinkage long sunos_sysconf (int name) ret = -1; break; }; - unlock_kernel(); return ret; } @@ -940,7 +928,6 @@ asmlinkage int sunos_semsys(int op, unsigned long arg1, unsigned long arg2, union semun arg4; int ret; - lock_kernel(); switch (op) { case 0: /* Most arguments match on a 1:1 basis but cmd doesn't */ @@ -976,7 +963,6 @@ asmlinkage int sunos_semsys(int op, unsigned long arg1, unsigned long arg2, ret = -EINVAL; break; }; - unlock_kernel(); return ret; } @@ -987,7 +973,6 @@ asmlinkage int sunos_msgsys(int op, unsigned long arg1, unsigned long arg2, unsigned long arg5; int rval; - lock_kernel(); switch(op) { case 0: rval = sys_msgget((key_t)arg1, (int)arg2); @@ -997,8 +982,10 @@ asmlinkage int sunos_msgsys(int op, unsigned long arg1, unsigned long arg2, (struct msqid_ds *)arg3); break; case 2: + lock_kernel(); sp = (struct sparc_stackf *)current->thread.kregs->u_regs[UREG_FP]; arg5 = sp->xxargs[0]; + unlock_kernel(); rval = sys_msgrcv((int)arg1, (struct msgbuf *)arg2, (size_t)arg3, (long)arg4, (int)arg5); break; @@ -1010,7 +997,6 @@ asmlinkage int sunos_msgsys(int op, unsigned long arg1, unsigned long arg2, rval = -EINVAL; break; } - unlock_kernel(); return rval; } @@ -1020,7 +1006,6 @@ asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2, unsigned long raddr; int rval; - lock_kernel(); switch(op) { case 0: /* sys_shmat(): attach a shared memory area */ @@ -1044,7 +1029,6 @@ asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2, rval = -EINVAL; break; }; - unlock_kernel(); return rval; } @@ -1058,9 +1042,12 @@ asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2, static inline int check_nonblock(int ret, int fd) { if (ret == -EAGAIN) { - struct file * file = fcheck(fd); - if (file && (file->f_flags & O_NDELAY)) - ret = -SUNOS_EWOULDBLOCK; + struct file * file = fget(fd); + if (file) { + if (file->f_flags & O_NDELAY) + ret = -SUNOS_EWOULDBLOCK; + fput(file); + } } return ret; } @@ -1078,9 +1065,7 @@ asmlinkage int sunos_read(unsigned int fd,char *buf,int count) { int ret; - lock_kernel(); ret = check_nonblock(sys_read(fd,buf,count),fd); - unlock_kernel(); return ret; } @@ -1088,9 +1073,7 @@ asmlinkage int sunos_readv(unsigned long fd, const struct iovec * vector, long c { int ret; - lock_kernel(); ret = check_nonblock(sys_readv(fd,vector,count),fd); - unlock_kernel(); return ret; } @@ -1098,9 +1081,7 @@ asmlinkage int sunos_write(unsigned int fd,char *buf,int count) { int ret; - lock_kernel(); ret = check_nonblock(sys_write(fd,buf,count),fd); - unlock_kernel(); return ret; } @@ -1108,9 +1089,7 @@ asmlinkage int sunos_writev(unsigned long fd, const struct iovec * vector, long { int ret; - lock_kernel(); ret = check_nonblock(sys_writev(fd,vector,count),fd); - unlock_kernel(); return ret; } @@ -1118,9 +1097,7 @@ asmlinkage int sunos_recv(int fd, void * ubuf, int size, unsigned flags) { int ret; - lock_kernel(); ret = check_nonblock(sys_recv(fd,ubuf,size,flags),fd); - unlock_kernel(); return ret; } @@ -1128,9 +1105,7 @@ asmlinkage int sunos_send(int fd, void * buff, int len, unsigned flags) { int ret; - lock_kernel(); ret = check_nonblock(sys_send(fd,buff,len,flags),fd); - unlock_kernel(); return ret; } @@ -1141,7 +1116,6 @@ asmlinkage int sunos_socket(int family, int type, int protocol) { int ret, one = 1; - lock_kernel(); ret = sys_socket(family, type, protocol); if (ret < 0) goto out; @@ -1149,7 +1123,6 @@ asmlinkage int sunos_socket(int family, int type, int protocol) sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT, (char *)&one, sizeof(one)); out: - unlock_kernel(); return ret; } @@ -1157,7 +1130,6 @@ asmlinkage int sunos_accept(int fd, struct sockaddr *sa, int *addrlen) { int ret, one = 1; - lock_kernel(); while (1) { ret = check_nonblock(sys_accept(fd,sa,addrlen),fd); if (ret != -ENETUNREACH && ret != -EHOSTUNREACH) @@ -1169,7 +1141,6 @@ asmlinkage int sunos_accept(int fd, struct sockaddr *sa, int *addrlen) sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT, (char *)&one, sizeof(one)); out: - unlock_kernel(); return ret; } @@ -1226,14 +1197,12 @@ asmlinkage int sunos_setsockopt(int fd, int level, int optname, char *optval, int tr_opt = optname; int ret; - lock_kernel(); if (level == SOL_IP) { /* Multicast socketopts (ttl, membership) */ if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } ret = sys_setsockopt(fd, level, tr_opt, optval, optlen); - unlock_kernel(); return ret; } @@ -1243,13 +1212,11 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname, char *optval, int tr_opt = optname; int ret; - lock_kernel(); if (level == SOL_IP) { /* Multicast socketopts (ttl, membership) */ if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } ret = sys_getsockopt(fd, level, tr_opt, optval, optlen); - unlock_kernel(); return ret; } diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 48cf27f38..ec3042398 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -111,7 +111,6 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir { int err; - lock_kernel(); /* No need for backward compatibility. We can start fresh... */ if (call <= SEMCTL) @@ -177,7 +176,6 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir else err = -EINVAL; out: - unlock_kernel(); return err; } @@ -198,11 +196,9 @@ extern asmlinkage long sys_personality(unsigned long); asmlinkage int sparc64_personality(unsigned long personality) { int ret; - lock_kernel(); if (current->personality == PER_LINUX32 && personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); - unlock_kernel(); if (ret == PER_LINUX32) ret = PER_LINUX; return ret; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 8f3339bfa..8b917e303 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1184,8 +1184,6 @@ asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count) struct file *file; long ret = -EBADF; - lock_kernel(); - file = fget(fd); if(!file) goto bad_file; @@ -1195,7 +1193,6 @@ asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count) fput(file); bad_file: - unlock_kernel(); return ret; } @@ -1204,8 +1201,6 @@ asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count) struct file *file; int ret = -EBADF; - lock_kernel(); - file = fget(fd); if(!file) goto bad_file; @@ -1214,7 +1209,6 @@ asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count) fput(file); bad_file: - unlock_kernel(); return ret; } @@ -4132,10 +4126,7 @@ asmlinkage long sparc32_open(const char * filename, int flags, int mode) if (!IS_ERR(tmp)) { fd = get_unused_fd(); if (fd >= 0) { - struct file * f; - lock_kernel(); - f = filp_open(tmp, flags, mode); - unlock_kernel(); + struct file * f = filp_open(tmp, flags, mode); error = PTR_ERR(f); if (IS_ERR(f)) goto out_error; diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 4d2a9173d..624a6b971 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -481,7 +481,6 @@ asmlinkage int sunos_fpathconf(int fd, int name) { int ret; - lock_kernel(); switch(name) { case _PCONF_LINK: ret = LINK_MAX; @@ -512,7 +511,6 @@ asmlinkage int sunos_fpathconf(int fd, int name) ret = -EINVAL; break; } - unlock_kernel(); return ret; } @@ -520,9 +518,7 @@ asmlinkage int sunos_pathconf(u32 u_path, int name) { int ret; - lock_kernel(); ret = sunos_fpathconf(0, name); /* XXX cheese XXX */ - unlock_kernel(); return ret; } @@ -540,7 +536,6 @@ asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x) int ret; /* SunOS binaries expect that select won't change the tvp contents */ - lock_kernel(); ret = sys32_select (width, inp, outp, exp, tvp_x); if (ret == -EINTR && tvp_x) { struct timeval32 *tvp = (struct timeval32 *)A(tvp_x); @@ -551,7 +546,6 @@ asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x) if (sec == 0 && usec == 0) ret = 0; } - unlock_kernel(); return ret; } @@ -798,7 +792,6 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) int ret; /* So stupid... */ - lock_kernel(); if((!pid || pid == current->pid) && !pgid) { sys_setsid(); @@ -806,7 +799,6 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) } else { ret = sys_setpgid(pid, pgid); } - unlock_kernel(); return ret; } @@ -818,10 +810,8 @@ asmlinkage int sunos_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32 { int ret; - lock_kernel(); ret = sys32_wait4((pid ? pid : ((__kernel_pid_t32)-1)), stat_addr, options, ru); - unlock_kernel(); return ret; } @@ -838,9 +828,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig) asmlinkage int sunos_audit(void) { - lock_kernel(); printk ("sys_audit\n"); - unlock_kernel(); return -1; } @@ -868,7 +856,6 @@ extern asmlinkage s32 sunos_sysconf (int name) { s32 ret; - lock_kernel(); switch (name){ case _SC_ARG_MAX: ret = ARG_MAX; @@ -901,7 +888,6 @@ extern asmlinkage s32 sunos_sysconf (int name) ret = -1; break; }; - unlock_kernel(); return ret; } @@ -910,7 +896,6 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) union semun arg4; int ret; - lock_kernel(); switch (op) { case 0: /* Most arguments match on a 1:1 basis but cmd doesn't */ @@ -946,7 +931,6 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) ret = -EINVAL; break; }; - unlock_kernel(); return ret; } @@ -1048,7 +1032,6 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) u32 arg5; int rval; - lock_kernel(); switch(op) { case 0: rval = sys_msgget((key_t)arg1, (int)arg2); @@ -1102,7 +1085,6 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = -EINVAL; break; } - unlock_kernel(); return rval; } @@ -1162,7 +1144,6 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) mm_segment_t old_fs = get_fs(); int rval; - lock_kernel(); switch(op) { case 0: /* sys_shmat(): attach a shared memory area */ @@ -1194,7 +1175,6 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) rval = -EINVAL; break; }; - unlock_kernel(); return rval; } @@ -1217,9 +1197,12 @@ asmlinkage int sunos_open(u32 fname, int flags, int mode) static inline int check_nonblock(int ret, int fd) { if (ret == -EAGAIN) { - struct file * file = fcheck(fd); - if (file && (file->f_flags & O_NDELAY)) - ret = -SUNOS_EWOULDBLOCK; + struct file * file = fget(fd); + if (file) { + if (file->f_flags & O_NDELAY) + ret = -SUNOS_EWOULDBLOCK; + fput(file); + } } return ret; } @@ -1236,9 +1219,7 @@ asmlinkage int sunos_read(unsigned int fd, u32 buf, u32 count) { int ret; - lock_kernel(); ret = check_nonblock(sys_read(fd, (char *)A(buf), count), fd); - unlock_kernel(); return ret; } @@ -1246,9 +1227,7 @@ asmlinkage int sunos_readv(u32 fd, u32 vector, s32 count) { int ret; - lock_kernel(); ret = check_nonblock(sys32_readv(fd, vector, count), fd); - unlock_kernel(); return ret; } @@ -1256,9 +1235,7 @@ asmlinkage int sunos_write(unsigned int fd, u32 buf, u32 count) { int ret; - lock_kernel(); ret = check_nonblock(sys_write(fd, (char *)A(buf), count), fd); - unlock_kernel(); return ret; } @@ -1266,9 +1243,7 @@ asmlinkage int sunos_writev(u32 fd, u32 vector, s32 count) { int ret; - lock_kernel(); ret = check_nonblock(sys32_writev(fd, vector, count), fd); - unlock_kernel(); return ret; } @@ -1276,9 +1251,7 @@ asmlinkage int sunos_recv(int fd, u32 ubuf, int size, unsigned flags) { int ret; - lock_kernel(); ret = check_nonblock(sys_recv(fd, (void *)A(ubuf), size, flags), fd); - unlock_kernel(); return ret; } @@ -1286,9 +1259,7 @@ asmlinkage int sunos_send(int fd, u32 buff, int len, unsigned flags) { int ret; - lock_kernel(); ret = check_nonblock(sys_send(fd, (void *)A(buff), len, flags), fd); - unlock_kernel(); return ret; } @@ -1299,7 +1270,6 @@ asmlinkage int sunos_socket(int family, int type, int protocol) { int ret, one = 1; - lock_kernel(); ret = sys_socket(family, type, protocol); if (ret < 0) goto out; @@ -1307,7 +1277,6 @@ asmlinkage int sunos_socket(int family, int type, int protocol) sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT, (char *)&one, sizeof(one)); out: - unlock_kernel(); return ret; } @@ -1315,7 +1284,6 @@ asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) { int ret, one = 1; - lock_kernel(); while (1) { ret = check_nonblock(sys_accept(fd, (struct sockaddr *)A(sa), (int *)A(addrlen)), fd); @@ -1328,7 +1296,6 @@ asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT, (char *)&one, sizeof(one)); out: - unlock_kernel(); return ret; } @@ -1376,14 +1343,12 @@ asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, int tr_opt = optname; int ret; - lock_kernel(); if (level == SOL_IP) { /* Multicast socketopts (ttl, membership) */ if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } ret = sys_setsockopt(fd, level, tr_opt, (char *)A(optval), optlen); - unlock_kernel(); return ret; } @@ -1393,13 +1358,11 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname, int tr_opt = optname; int ret; - lock_kernel(); if (level == SOL_IP) { /* Multicast socketopts (ttl, membership) */ if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } ret = sys32_getsockopt(fd, level, tr_opt, optval, optlen); - unlock_kernel(); return ret; } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 97b8960c7..f0b95fd0f 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -168,6 +168,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,48)) proc_entry->proc_fops = &i2cproc_operations; + proc_entry->owner = THIS_MODULE; #else proc_entry->ops = &i2cproc_inode_operations; #endif diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index f8e7b418c..f7d7ee8d5 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -55,6 +55,7 @@ #include <linux/module.h> #include <linux/version.h> #include <linux/poll.h> +#include <linux/smp_lock.h> #ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> #else @@ -175,7 +176,7 @@ isdn_divert_open(struct inode *ino, struct file *filep) { int flags; - MOD_INC_USE_COUNT; + lock_kernel(); save_flags(flags); cli(); if_used++; @@ -185,6 +186,7 @@ isdn_divert_open(struct inode *ino, struct file *filep) (struct divert_info **) filep->private_data = &divert_info_head; restore_flags(flags); /* start_divert(); */ + unlock_kernel(); return (0); } /* isdn_divert_open */ @@ -212,7 +214,6 @@ isdn_divert_close(struct inode *ino, struct file *filep) divert_info_head = divert_info_head->next; kfree(inf); } - MOD_DEC_USE_COUNT; return (0); } /* isdn_divert_close */ @@ -345,6 +346,7 @@ divert_dev_init(void) return (-1); } isdn_divert_entry->proc_fops = &isdn_fops; + isdn_divert_entry->owner = THIS_MODULE; #endif /* CONFIG_PROC_FS */ return (0); diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index ac67610f7..c27c926a1 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -45,6 +45,7 @@ #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/pci.h> +#include <linux/smp_lock.h> #include "hysdn_defs.h" @@ -286,9 +287,8 @@ hysdn_conf_open(struct inode *ino, struct file *filep) struct conf_writedata *cnf; char *cp, *tmp; - MOD_INC_USE_COUNT; /* lock module */ - /* now search the addressed card */ + lock_kernel(); card = card_root; while (card) { pd = card->procconf; @@ -297,7 +297,7 @@ hysdn_conf_open(struct inode *ino, struct file *filep) card = card->next; /* search next entry */ } if (!card) { - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-ENODEV); /* device is unknown/invalid */ } if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) @@ -308,7 +308,7 @@ hysdn_conf_open(struct inode *ino, struct file *filep) /* write only access -> write boot file or conf line */ if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) { - MOD_DEC_USE_COUNT; + unlock_kernel(); return (-EFAULT); } cnf->card = card; @@ -320,7 +320,7 @@ hysdn_conf_open(struct inode *ino, struct file *filep) /* read access -> output card info data */ if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) { - MOD_DEC_USE_COUNT; + unlock_kernel(); return (-EFAULT); /* out of memory */ } filep->private_data = tmp; /* start of string */ @@ -354,9 +354,10 @@ hysdn_conf_open(struct inode *ino, struct file *filep) *cp++ = '\n'; *cp = 0; /* end of string */ } else { /* simultaneous read/write access forbidden ! */ - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-EPERM); /* no permission this time */ } + unlock_kernel(); return (0); } /* hysdn_conf_open */ @@ -402,7 +403,6 @@ hysdn_conf_close(struct inode *ino, struct file *filep) if (filep->private_data) kfree(filep->private_data); /* release memory */ } - MOD_DEC_USE_COUNT; /* reduce usage count */ return (retval); } /* hysdn_conf_close */ @@ -447,6 +447,7 @@ hysdn_procconf_init(void) S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) { ((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops; + ((struct proc_dir_entry *) card->procconf)->owner = THIS_MODULE; hysdn_proclog_init(card); /* init the log file entry */ } card = card->next; /* next entry */ diff --git a/drivers/isdn/hysdn/hysdn_procfs.c b/drivers/isdn/hysdn/hysdn_procfs.c index 867b22766..ae07f6597 100644 --- a/drivers/isdn/hysdn/hysdn_procfs.c +++ b/drivers/isdn/hysdn/hysdn_procfs.c @@ -33,6 +33,7 @@ #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/pci.h> +#include <linux/smp_lock.h> #include "hysdn_defs.h" @@ -198,7 +199,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) struct procdata *pd; ulong flags; - MOD_INC_USE_COUNT; /* lock module */ + lock_kernel(); card = card_root; while (card) { pd = card->procfs; @@ -207,7 +208,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) card = card->next; /* search next entry */ } if (!card) { - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-ENODEV); /* device is unknown/invalid */ } filep->private_data = card; /* remember our own card */ @@ -215,7 +216,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> boot pof data */ if (pof_boot_open(card)) { - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-EPERM); /* no permission this time */ } } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { @@ -231,9 +232,10 @@ hysdn_log_open(struct inode *ino, struct file *filep) restore_flags(flags); } else { /* simultaneous read/write access forbidden ! */ - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-EPERM); /* no permission this time */ } + unlock_kernel(); return (0); } /* hysdn_log_open */ @@ -295,7 +297,6 @@ hysdn_log_close(struct inode *ino, struct file *filep) } } /* read access */ - MOD_DEC_USE_COUNT; return (retval); } /* hysdn_log_close */ @@ -437,8 +438,10 @@ hysdn_procfs_init(void) memset(pd, 0, sizeof(struct procdata)); sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid); - if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) + if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) { pd->log->proc_fops = &log_fops; /* set new operations table */ + pd->log->owner = THIS_MODULE; + } init_waitqueue_head(&(pd->rd_queue)); diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index d93b59995..1a2980f02 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -45,6 +45,7 @@ #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/pci.h> +#include <linux/smp_lock.h> #include "hysdn_defs.h" @@ -293,7 +294,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) struct procdata *pd; ulong flags; - MOD_INC_USE_COUNT; /* lock module */ + lock_kernel(); card = card_root; while (card) { pd = card->proclog; @@ -302,7 +303,7 @@ hysdn_log_open(struct inode *ino, struct file *filep) card = card->next; /* search next entry */ } if (!card) { - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-ENODEV); /* device is unknown/invalid */ } filep->private_data = card; /* remember our own card */ @@ -321,9 +322,10 @@ hysdn_log_open(struct inode *ino, struct file *filep) (struct log_data **) filep->private_data = &(pd->log_head); restore_flags(flags); } else { /* simultaneous read/write access forbidden ! */ - MOD_DEC_USE_COUNT; /* unlock module */ + unlock_kernel(); return (-EPERM); /* no permission this time */ } + unlock_kernel(); return (0); } /* hysdn_log_open */ @@ -385,7 +387,6 @@ hysdn_log_close(struct inode *ino, struct file *filep) } } /* read access */ - MOD_DEC_USE_COUNT; return (retval); } /* hysdn_log_close */ @@ -451,8 +452,10 @@ hysdn_proclog_init(hysdn_card * card) if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { memset(pd, 0, sizeof(struct procdata)); sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid); - if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) + if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) { pd->log->proc_fops = &log_fops; + pd->log->owner = THIS_MODULE; + } init_waitqueue_head(&(pd->rd_queue)); diff --git a/drivers/mtd/nftl.c b/drivers/mtd/nftl.c index 95e851b2c..182ec5a96 100644 --- a/drivers/mtd/nftl.c +++ b/drivers/mtd/nftl.c @@ -1251,17 +1251,12 @@ static int nftl_release(struct inode *inode, struct file *fp) } #if LINUX_VERSION_CODE < 0x20326 static struct file_operations nftl_fops = { - NULL, /* lseek - default */ - block_read, /* read - block dev read */ - block_write, /* write - block dev write */ - NULL, /* readdir - not here! */ - NULL, /* select */ - nftl_ioctl, /* ioctl */ - NULL, /* mmap */ - nftl_open, /* open */ - NULL, /* flush */ - nftl_release, /* no special release code... */ - block_fsync /* fsync */ + read: block_read, + write: block_write, + ioctl: nftl_ioctl, + open: nftl_open, + release: nftl_release, + fsync: block_fsync, }; #else static struct block_device_operations nftl_fops = diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 881515b68..e2ed67aaa 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -229,7 +229,7 @@ static int __init ne_probe_pci(struct net_device *dev) for (i = 0; pci_clone_list[i].vendor != 0; i++) { struct pci_dev *pdev = NULL; - unsigned int pci_ioaddr; + unsigned int pci_ioaddr = 0; while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { if (pci_enable_device(pdev)) diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index e2f681c3a..065bcf8df 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c @@ -14,6 +14,10 @@ * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too. * 22-02-2000: Count devices that are actually detected. * + * The block comments above the functions in this file are + * licensed as part of the generated file + * Documentation/DocBook/parportbook.sgml under the GNU Free + * Documentation License. */ #include <linux/parport.h> diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 11f98bea0..c148a5b0c 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -8,6 +8,11 @@ * * This file is responsible for IEEE 1284 negotiation, and for handing * read/write requests to low-level drivers. + * + * The block comments above the functions in this file are + * licensed as part of the generated file + * Documentation/DocBook/parportbook.sgml under the GNU Free + * Documentation License. */ #include <linux/config.h> diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 5ada06a83..9fe0bb4be 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -9,6 +9,11 @@ * * based on work by Grant Guenther <grant@torque.net> * and Philip Blundell + * + * The block comments above the functions in this file are + * licensed as part of the generated file + * Documentation/DocBook/parportbook.sgml under the GNU Free + * Documentation License. */ #undef PARPORT_DEBUG_SHARING /* undef for production */ diff --git a/drivers/pnp/isapnp_proc.c b/drivers/pnp/isapnp_proc.c index 658fa2ede..3472225b8 100644 --- a/drivers/pnp/isapnp_proc.c +++ b/drivers/pnp/isapnp_proc.c @@ -28,6 +28,7 @@ #include <linux/poll.h> #include <linux/vmalloc.h> #include <asm/uaccess.h> +#include <linux/smp_lock.h> #include <linux/isapnp.h> struct isapnp_info_buffer { @@ -169,11 +170,12 @@ static int isapnp_info_entry_open(struct inode *inode, struct file *file) kfree(buffer); return -ENOMEM; } + lock_kernel(); buffer->curr = buffer->buffer; file->private_data = buffer; - MOD_INC_USE_COUNT; if (mode == O_RDONLY) isapnp_info_read(buffer); + unlock_kernel(); return 0; } @@ -189,7 +191,6 @@ static int isapnp_info_entry_release(struct inode *inode, struct file *file) isapnp_info_write(buffer); vfree(buffer->buffer); kfree(buffer); - MOD_DEC_USE_COUNT; return 0; } @@ -286,6 +287,7 @@ static int isapnp_proc_attach_device(struct pci_dev *dev) if (!e) return -ENOMEM; e->proc_fops = &isapnp_proc_bus_file_operations; + e->owner = THIS_MODULE; e->data = dev; e->size = 256; return 0; @@ -367,8 +369,10 @@ int __init isapnp_proc_init(void) isapnp_proc_entry = NULL; p = create_proc_entry("isapnp", S_IFREG | S_IRUGO | S_IWUSR, &proc_root); - if (p) + if (p) { p->proc_fops = &isapnp_info_entry_operations; + p->owner = THIS_MODULE; + } isapnp_proc_entry = p; isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus); isapnp_proc_devices_entry = create_proc_info_entry("devices", 0, diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bcdc4aab3..263fcd09e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1332,7 +1332,6 @@ void cleanup_module(void) } for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) { - blk_cleanup_queue(BLK_DEFAULT_QUEUE(SD_MAJOR(i))); blk_size[SD_MAJOR(i)] = NULL; hardsect_size[SD_MAJOR(i)] = NULL; read_ahead[SD_MAJOR(i)] = 0; diff --git a/drivers/usb/usb-uhci-debug.h b/drivers/usb/usb-uhci-debug.h index 4eedc4183..d1c0ca83d 100644 --- a/drivers/usb/usb-uhci-debug.h +++ b/drivers/usb/usb-uhci-debug.h @@ -1,5 +1,5 @@ #ifdef DEBUG -static void uhci_show_qh (puhci_desc_t qh) +static void __attribute__((__unused__)) uhci_show_qh (puhci_desc_t qh) { if (qh->type != QH_TYPE) { dbg("qh has not QH_TYPE"); @@ -75,7 +75,7 @@ static void uhci_show_td (puhci_desc_t td) (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : "Breadth first")); } #ifdef DEBUG -static void uhci_show_td_queue (puhci_desc_t td) +static void __attribute__((__unused__)) uhci_show_td_queue (puhci_desc_t td) { //dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td)); while (1) { @@ -91,7 +91,7 @@ static void uhci_show_td_queue (puhci_desc_t td) } } -static void uhci_show_queue (puhci_desc_t qh) +static void __attribute__((__unused__)) uhci_show_queue (puhci_desc_t qh) { uhci_desc_t *start_qh=qh; @@ -119,7 +119,7 @@ static void uhci_show_queue (puhci_desc_t qh) } } -static void uhci_show_sc (int port, unsigned short status) +static void __attribute__((__unused__)) uhci_show_sc (int port, unsigned short status) { dbg(" stat%d = %04x %s%s%s%s%s%s%s%s", port, diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 5dacc56d6..e55362eb7 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -12,6 +12,7 @@ #include <linux/string.h> #include <linux/locks.h> #include <linux/mm.h> +#include <linux/smp_lock.h> #include "adfs.h" @@ -354,6 +355,7 @@ void adfs_write_inode(struct inode *inode, int unused) struct super_block *sb = inode->i_sb; struct object_info obj; + lock_kernel(); obj.file_id = inode->i_ino; obj.name_len = 0; obj.parent_id = inode->u.adfs_i.parent_id; @@ -363,4 +365,5 @@ void adfs_write_inode(struct inode *inode, int unused) obj.size = inode->i_size; adfs_dir_update(sb, &obj); + unlock_kernel(); } diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 84ea2adf8..f98a2cd0b 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -27,6 +27,7 @@ #include <linux/major.h> #include <linux/blkdev.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -202,8 +203,10 @@ affs_write_inode(struct inode *inode, int unused) if (!inode->i_nlink) return; + lock_kernel(); if (!(bh = bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)))) { affs_error(inode->i_sb,"write_inode","Cannot read block %lu",inode->i_ino); + unlock_kernel(); return; } file_end = GET_END_PTR(struct file_end, bh->b_data,AFFS_I2BSIZE(inode)); @@ -231,6 +234,7 @@ affs_write_inode(struct inode *inode, int unused) affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5); mark_buffer_dirty(bh,1); brelse(bh); + unlock_kernel(); } int @@ -269,6 +273,7 @@ affs_put_inode(struct inode *inode) pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino,inode->i_nlink); + lock_kernel(); affs_free_prealloc(inode); if (atomic_read(&inode->i_count) == 1) { unsigned long cache_page = (unsigned long) inode->u.affs_i.i_ec; @@ -278,16 +283,19 @@ affs_put_inode(struct inode *inode) free_page(cache_page); } } + unlock_kernel(); } void affs_delete_inode(struct inode *inode) { pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink); + lock_kernel(); inode->i_size = 0; if (S_ISREG(inode->i_mode) && !inode->u.affs_i.i_hlink) affs_truncate(inode); affs_free_block(inode->i_sb,inode->i_ino); + unlock_kernel(); clear_inode(inode); } diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 5f41c53ac..9f53cbcd3 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/locks.h> #include <linux/bfs_fs.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -97,10 +98,12 @@ static void bfs_write_inode(struct inode * inode, int unused) return; } + lock_kernel(); block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; bh = bread(dev, block, BFS_BSIZE); if (!bh) { printf("Unable to read inode %s:%08lx\n", bdevname(dev), ino); + unlock_kernel(); return; } @@ -126,6 +129,7 @@ static void bfs_write_inode(struct inode * inode, int unused) mark_buffer_dirty(bh, 0); brelse(bh); + unlock_kernel(); } static void bfs_delete_inode(struct inode * inode) @@ -146,11 +150,13 @@ static void bfs_delete_inode(struct inode * inode) inode->i_size = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + lock_kernel(); mark_inode_dirty(inode); block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; bh = bread(dev, block, BFS_BSIZE); if (!bh) { printf("Unable to read inode %s:%08lx\n", bdevname(dev), ino); + unlock_kernel(); return; } off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; @@ -173,6 +179,7 @@ static void bfs_delete_inode(struct inode * inode) s->su_lf_eblk = inode->iu_sblock - 1; mark_buffer_dirty(s->su_sbh, 1); } + unlock_kernel(); clear_inode(inode); } diff --git a/fs/block_dev.c b/fs/block_dev.c index 02ae171c4..9a034ca60 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -11,6 +11,7 @@ #include <linux/malloc.h> #include <linux/kmod.h> #include <linux/devfs_fs_kernel.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -611,6 +612,7 @@ int blkdev_open(struct inode * inode, struct file * filp) int ret = -ENODEV; struct block_device *bdev = inode->i_bdev; down(&bdev->bd_sem); + lock_kernel(); if (!bdev->bd_op) bdev->bd_op = get_blkfops(MAJOR(inode->i_rdev)); if (bdev->bd_op) { @@ -622,6 +624,7 @@ int blkdev_open(struct inode * inode, struct file * filp) else if (!atomic_read(&bdev->bd_openers)) bdev->bd_op = NULL; } + unlock_kernel(); up(&bdev->bd_sem); return ret; } diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 66279990e..f5c53fac2 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -579,6 +579,7 @@ int coda_open(struct inode *i, struct file *f) unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_cred *cred; + lock_kernel(); ENTRY; coda_vfs_stat.open++; @@ -589,6 +590,7 @@ int coda_open(struct inode *i, struct file *f) if (error) { CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n", dev, (long)ino, error); + unlock_kernel(); return error; } @@ -600,6 +602,7 @@ int coda_open(struct inode *i, struct file *f) printk("coda_open: coda_inode_grab error %d.", error); if (cont_inode) iput(cont_inode); + unlock_kernel(); return error; } @@ -620,6 +623,7 @@ int coda_open(struct inode *i, struct file *f) cont_inode->i_ino, atomic_read(&cont_inode->i_count), cont_inode->i_op); EXIT; + unlock_kernel(); return 0; } diff --git a/fs/dcache.c b/fs/dcache.c index 1841eef97..3de8547ef 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -223,6 +223,24 @@ int d_invalidate(struct dentry * dentry) return 0; } +/* This should be called _only_ with dcache_lock held */ + +static inline struct dentry * __dget_locked(struct dentry *dentry) +{ + atomic_inc(&dentry->d_count); + if (atomic_read(&dentry->d_count) == 1) { + dentry_stat.nr_unused--; + list_del(&dentry->d_lru); + INIT_LIST_HEAD(&dentry->d_lru); /* make "list_empty()" work */ + } + return dentry; +} + +struct dentry * dget_locked(struct dentry *dentry) +{ + return __dget_locked(dentry); +} + /** * d_find_alias - grab a hashed alias of inode * @inode: inode in question @@ -246,7 +264,7 @@ struct dentry * d_find_alias(struct inode *inode) next = tmp->next; alias = list_entry(tmp, struct dentry, d_alias); if (!list_empty(&alias->d_hash)) { - dget(alias); + __dget_locked(alias); spin_unlock(&dcache_lock); return alias; } @@ -268,7 +286,7 @@ restart: while ((tmp = tmp->next) != head) { struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); if (!atomic_read(&dentry->d_count)) { - dget(dentry); + __dget_locked(dentry); spin_unlock(&dcache_lock); d_drop(dentry); dput(dentry); @@ -706,12 +724,7 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) if (memcmp(dentry->d_name.name, str, len)) continue; } - atomic_inc(&dentry->d_count); - if (atomic_read(&dentry->d_count) == 1) { - dentry_stat.nr_unused--; - list_del(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_lru); /* make "list_empty()" work */ - } + __dget_locked(dentry); spin_unlock(&dcache_lock); return dentry; } @@ -748,7 +761,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent, lhp = base; while ((lhp = lhp->next) != base) { if (dentry == list_entry(lhp, struct dentry, d_hash)) { - dget(dentry); + __dget_locked(dentry); goto out; } } @@ -764,7 +777,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent, if (!sb->s_dev) continue; if (sb->s_root == dentry) { - dget(dentry); + __dget_locked(dentry); goto out; } } diff --git a/fs/devfs/base.c b/fs/devfs/base.c index bacb67241..494cb270a 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -1075,16 +1075,19 @@ static void free_dentries (struct devfs_entry *de) { struct dentry *dentry; + spin_lock(&dcache_lock); dentry = de->inode.dentry; if (dentry != NULL) { - dget (dentry); + dget_locked (dentry); de->inode.dentry = NULL; + spin_unlock(&dcache_lock); /* Forcefully remove the inode */ if (dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0; d_drop (dentry); dput (dentry); - } + } else + spin_unlock(&dcache_lock); } /* End Function free_dentries */ @@ -2303,10 +2306,12 @@ static void devfs_write_inode (struct inode *inode, int wait) if (inode->i_ino < FIRST_INODE) return; index = inode->i_ino - FIRST_INODE; + lock_kernel(); if (index >= fs_info->num_inodes) { printk ("%s: writing inode: %lu for which there is no entry!\n", DEVFS_NAME, inode->i_ino); + unlock_kernel(); return; } de = fs_info->table[index]; @@ -2326,6 +2331,7 @@ static void devfs_write_inode (struct inode *inode, int wait) de->inode.atime = inode->i_atime; de->inode.mtime = inode->i_mtime; de->inode.ctime = inode->i_ctime; + unlock_kernel(); } /* End Function devfs_write_inode */ static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr) @@ -2476,11 +2482,18 @@ static int devfs_open (struct inode *inode, struct file *file) struct devfs_entry *de; struct fs_info *fs_info = inode->i_sb->u.generic_sbp; + lock_kernel(); de = get_devfs_entry_from_vfs_inode (inode); - if (de == NULL) return -ENODEV; - if ( S_ISDIR (de->mode) ) return 0; + err = -ENODEV; + if (de == NULL) + goto out; + err = 0; + if ( S_ISDIR (de->mode) ) + goto out; df = &de->u.fcb; - if (!de->registered) return -ENODEV; + err = -ENODEV; + if (!de->registered) + goto out; file->private_data = de->info; if ( S_ISBLK (inode->i_mode) ) { @@ -2496,9 +2509,10 @@ static int devfs_open (struct inode *inode, struct file *file) if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file); else err = -ENODEV; } - if (err < 0) return err; + if (err < 0) goto out; /* Open was successful */ - if (df->open) return 0; + err = 0; + if (df->open) goto out; df->open = TRUE; /* This is the first open */ if (df->auto_owner) { @@ -2513,7 +2527,9 @@ static int devfs_open (struct inode *inode, struct file *file) if (df->aopen_notify) devfsd_notify_one (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode, current->euid, current->egid, fs_info); - return 0; +out: + unlock_kernel(); + return err; } /* End Function devfs_open */ static struct file_operations devfs_fops = diff --git a/fs/devices.c b/fs/devices.c index 9e37e5c68..3023747da 100644 --- a/fs/devices.c +++ b/fs/devices.c @@ -18,6 +18,7 @@ #include <linux/fcntl.h> #include <linux/errno.h> #include <linux/module.h> +#include <linux/smp_lock.h> #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -143,6 +144,7 @@ int chrdev_open(struct inode * inode, struct file * filp) { int ret = -ENODEV; + lock_kernel(); filp->f_op = fops_get(get_chrfops(MAJOR(inode->i_rdev), MINOR(inode->i_rdev))); if (filp->f_op) { @@ -150,6 +152,7 @@ int chrdev_open(struct inode * inode, struct file * filp) if (filp->f_op->open != NULL) ret = filp->f_op->open(inode,filp); } + unlock_kernel(); return ret; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index d999b2b4f..5792d7b95 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -62,8 +62,8 @@ void ext2_delete_inode (struct inode * inode) unlock_kernel(); return; no_delete: - clear_inode(inode); /* We must guarantee clearing of inode... */ unlock_kernel(); + clear_inode(inode); /* We must guarantee clearing of inode... */ } #define inode_bmap(inode, nr) (le32_to_cpu((inode)->u.ext2_i.i_data[(nr)])) diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index 0b7793f07..3a665a18f 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -42,6 +42,7 @@ EXPORT_SYMBOL(fat_dir_ioctl); EXPORT_SYMBOL(fat_add_entries); EXPORT_SYMBOL(fat_dir_empty); EXPORT_SYMBOL(fat_truncate); +EXPORT_SYMBOL(fat_brelse); static int __init init_fat_fs(void) { diff --git a/fs/fat/inode.c b/fs/fat/inode.c index bd8d0ae26..046d384de 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -27,6 +27,7 @@ #include <linux/locks.h> #include <linux/fat_cvf.h> #include <linux/malloc.h> +#include <linux/smp_lock.h> #include "msbuffer.h" @@ -153,17 +154,21 @@ out: void fat_delete_inode(struct inode *inode) { + lock_kernel(); inode->i_size = 0; fat_truncate(inode); + unlock_kernel(); clear_inode(inode); } void fat_clear_inode(struct inode *inode) { + lock_kernel(); spin_lock(&fat_inode_lock); fat_cache_inval_inode(inode); list_del(&MSDOS_I(inode)->i_fat_hash); spin_unlock(&fat_inode_lock); + unlock_kernel(); } void fat_put_super(struct super_block *sb) @@ -846,16 +851,20 @@ void fat_write_inode(struct inode *inode, int wait) retry: i_pos = MSDOS_I(inode)->i_location; - if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) return; + if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) { + return; + } if (!(bh = fat_bread(sb, i_pos >> MSDOS_DPB_BITS))) { printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos); fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block"); + unlock_kernel(); return; } spin_lock(&fat_inode_lock); if (i_pos != MSDOS_I(inode)->i_location) { spin_unlock(&fat_inode_lock); fat_brelse(sb, bh); + unlock_kernel(); goto retry; } @@ -885,6 +894,7 @@ retry: spin_unlock(&fat_inode_lock); fat_mark_buffer_dirty(sb, bh, 1); fat_brelse(sb, bh); + unlock_kernel(); } @@ -11,6 +11,7 @@ #include <linux/mm.h> #include <linux/malloc.h> +#include <linux/smp_lock.h> static void wait_for_partner(struct inode* inode, unsigned int* cnt) { @@ -32,6 +33,7 @@ static int fifo_open(struct inode *inode, struct file *filp) int ret; ret = -ERESTARTSYS; + lock_kernel(); if (down_interruptible(PIPE_SEM(*inode))) goto err_nolock_nocleanup; @@ -114,6 +116,7 @@ static int fifo_open(struct inode *inode, struct file *filp) /* Ok! */ up(PIPE_SEM(*inode)); + unlock_kernel(); return 0; err_rd: @@ -140,6 +143,7 @@ err_nocleanup: up(PIPE_SEM(*inode)); err_nolock_nocleanup: + unlock_kernel(); return ret; } diff --git a/fs/filesystems.c b/fs/filesystems.c index ce64f4c8e..e57b7b3df 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -50,7 +50,7 @@ void __init filesystem_setup(void) #ifndef CONFIG_NFSD #ifdef CONFIG_NFSD_MODULE -int (*do_nfsservctl)(int, void *, void *); +long (*do_nfsservctl)(int, void *, void *); #endif long asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp) diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 371538b9d..56d1547e7 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -20,6 +20,7 @@ #include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_i.h> #include <linux/hfs_fs.h> +#include <linux/smp_lock.h> /*================ Variable-like macros ================*/ @@ -79,6 +80,7 @@ void hfs_put_inode(struct inode * inode) { struct hfs_cat_entry *entry = HFS_I(inode)->entry; + lock_kernel(); hfs_cat_put(entry); if (atomic_read(&inode->i_count) == 1) { struct hfs_hdr_layout *tmp = HFS_I(inode)->layout; @@ -88,6 +90,7 @@ void hfs_put_inode(struct inode * inode) HFS_DELETE(tmp); } } + unlock_kernel(); } /* diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 4a301f593..f284e3d42 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -7,12 +7,17 @@ */ #include <linux/string.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> #include "hpfs_fn.h" +/* HUH? */ int hpfs_open(struct inode *i, struct file *f) { + lock_kernel(); hpfs_lock_inode(i); hpfs_unlock_inode(i); /* make sure nobody is deleting the file */ + unlock_kernel(); if (!i->i_nlink) return -ENOENT; return 0; } diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 7938970c8..a9f085863 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -6,6 +6,8 @@ * inode VFS functions */ +#include <linux/sched.h> +#include <linux/smp_lock.h> #include "hpfs_fn.h" static struct file_operations hpfs_file_ops = @@ -313,6 +315,8 @@ void hpfs_write_if_changed(struct inode *inode) void hpfs_delete_inode(struct inode *inode) { + lock_kernel(); hpfs_remove_fnode(inode->i_sb, inode->i_ino); + unlock_kernel(); clear_inode(inode); } diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index fc9c7d0d2..e088d7fba 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1453,7 +1453,8 @@ static struct inode_operations jffs_file_inode_operations = static struct file_operations jffs_dir_operations = { - readdir: jffs_readdir, + read: generic_read_dir, + readdir: jffs_readdir, }; static struct inode_operations jffs_dir_inode_operations = @@ -1532,9 +1533,9 @@ jffs_delete_inode(struct inode *inode) inode->i_size = 0; + unlock_kernel(); clear_inode(inode); - unlock_kernel(); } void diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 3ea18c96d..8cb5a5c06 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -391,7 +391,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) dent = list_entry(next, struct dentry, d_child); if ((unsigned long)dent->d_fsdata == fpos) { if (dent->d_inode) - dget(dent); + dget_locked(dent); else dent = NULL; spin_unlock(&dcache_lock); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 0a6c2fd26..4ef5569fc 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -884,10 +884,14 @@ nfs_revalidate(struct dentry *dentry) */ int nfs_open(struct inode *inode, struct file *filp) { - struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; - struct rpc_cred *cred = rpcauth_lookupcred(auth, 0); + struct rpc_auth *auth; + struct rpc_cred *cred; + lock_kernel(); + auth = NFS_CLIENT(inode)->cl_auth; + cred = rpcauth_lookupcred(auth, 0); filp->private_data = cred; + unlock_kernel(); return 0; } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index cc3896c38..52a0348c1 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -155,7 +155,7 @@ static struct dentry *nfsd_iget(struct super_block *sb, unsigned long ino, __u32 for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) { result = list_entry(lp,struct dentry, d_alias); if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { - dget(result); + dget_locked(result); spin_unlock(&dcache_lock); iput(inode); return result; @@ -260,7 +260,7 @@ struct dentry *nfsd_findparent(struct dentry *child) pdentry = list_entry(aliases->prev, struct dentry, d_alias); if (pdentry == tdentry) pdentry = NULL; - if (pdentry) dget(pdentry); + if (pdentry) dget_locked(pdentry); } spin_unlock(&dcache_lock); if (pdentry == NULL) { @@ -305,7 +305,7 @@ static struct dentry *splice(struct dentry *child, struct dentry *parent) for (lp = child->d_inode->i_dentry.next; lp != &child->d_inode->i_dentry ; lp=lp->next) { tmp = list_entry(lp,struct dentry, d_alias); if (tmp->d_parent == parent) { - child = dget(tmp); + child = dget_locked(tmp); spin_unlock(&dcache_lock); goto out; } diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index 38ca56312..96178b4bb 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -29,6 +29,7 @@ #include <linux/nls.h> #include <linux/locks.h> #include <linux/init.h> +#include <linux/smp_lock.h> /* Forward declarations */ static struct inode_operations ntfs_dir_inode_operations; @@ -711,13 +712,16 @@ static void ntfs_read_inode(struct inode* inode) static void ntfs_write_inode (struct inode *ino, int unused) { + lock_kernel(); ntfs_debug (DEBUG_LINUX, "ntfs:write inode %x\n", ino->i_ino); ntfs_update_inode (NTFS_LINO2NINO (ino)); + unlock_kernel(); } #endif static void _ntfs_clear_inode(struct inode *ino) { + lock_kernel(); ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n",ino->i_ino); #ifdef NTFS_IN_LINUX_KERNEL if(ino->i_ino!=FILE_MFT) @@ -730,6 +734,7 @@ static void _ntfs_clear_inode(struct inode *ino) ino->u.generic_ip=0; } #endif + unlock_kernel(); return; } @@ -645,9 +645,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) if (inode->i_sb) file_move(f, &inode->i_sb->s_files); if (f->f_op && f->f_op->open) { - lock_kernel(); error = f->f_op->open(inode,f); - unlock_kernel(); if (error) goto cleanup_all; } @@ -366,12 +366,14 @@ pipe_write_open(struct inode *inode, struct file *filp) static int pipe_rdwr_open(struct inode *inode, struct file *filp) { + lock_kernel(); down(PIPE_SEM(*inode)); if (filp->f_mode & FMODE_READ) PIPE_READERS(*inode)++; if (filp->f_mode & FMODE_WRITE) PIPE_WRITERS(*inode)++; up(PIPE_SEM(*inode)); + unlock_kernel(); return 0; } diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 5937878c9..b20f0b7c4 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -626,7 +626,6 @@ void __init proc_misc_init(void) {"locks", locks_read_proc}, {"mounts", mounts_read_proc}, {"swaps", swaps_read_proc}, - {"slabinfo", slabinfo_read_proc}, {"iomem", memory_read_proc}, {"execdomains", execdomains_read_proc}, {NULL,NULL} diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 0785ee368..4e6dce60b 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -23,6 +23,7 @@ #include <linux/locks.h> #include <linux/init.h> #include <linux/highuid.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -62,9 +63,11 @@ int qnx4_sync_inode(struct inode *inode) static void qnx4_delete_inode(struct inode *inode) { QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino)); + lock_kernel(); inode->i_size = 0; qnx4_truncate(inode); qnx4_free_inode(inode); + unlock_kernel(); } static void qnx4_write_super(struct super_block *sb) @@ -91,9 +94,11 @@ static void qnx4_write_inode(struct inode *inode, int unused) } QNX4DEBUG(("qnx4: write inode 2.\n")); block = ino / QNX4_INODES_PER_BLOCK; + lock_kernel(); if (!(bh = bread(inode->i_dev, block, QNX4_BLOCK_SIZE))) { printk("qnx4: major problem: unable to read inode from dev " "%s\n", kdevname(inode->i_dev)); + unlock_kernel(); return; } raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + @@ -109,6 +114,7 @@ static void qnx4_write_inode(struct inode *inode, int unused) raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks); mark_buffer_dirty(bh, 1); brelse(bh); + unlock_kernel(); } #endif diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 00fefa101..7f08aa22d 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -141,7 +141,7 @@ static int smb_dir_open(struct inode *dir, struct file *file) { struct dentry *dentry = file->f_dentry; - struct smb_sb_info *server = server_from_dentry(dentry); + struct smb_sb_info *server; int error = 0; #ifdef SMBFS_DEBUG_VERBOSE printk("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name, @@ -151,6 +151,8 @@ file->f_dentry->d_name.name); * Directory timestamps in the core protocol aren't updated * when a file is added, so we give them a very short TTL. */ + lock_kernel(); + server = server_from_dentry(dentry); if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) { unsigned long age = jiffies - dir->u.smbfs_i.oldmtime; @@ -160,6 +162,7 @@ file->f_dentry->d_name.name); if (server->conn_pid) error = smb_revalidate_inode(dentry); + unlock_kernel(); return error; } diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index cbabee222..2c3b96638 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -334,7 +334,9 @@ out: static int smb_file_open(struct inode *inode, struct file * file) { + lock_kernel(); inode->u.smbfs_i.openers++; + unlock_kernel(); return 0; } diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 89ddfb22a..caa8cc533 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -281,9 +281,11 @@ static void smb_delete_inode(struct inode *ino) { pr_debug("smb_delete_inode\n"); + lock_kernel(); if (smb_close(ino)) printk("smb_delete_inode: could not close inode %ld\n", ino->i_ino); + unlock_kernel(); clear_inode(ino); } diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 9ac81643b..e1d594f0b 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -61,9 +61,11 @@ void sysv_print_inode(struct inode * inode) static void sysv_delete_inode(struct inode *inode) { + lock_kernel(); inode->i_size = 0; sysv_truncate(inode); sysv_free_inode(inode); + unlock_kernel(); } static void sysv_put_super(struct super_block *); @@ -1156,8 +1158,10 @@ static struct buffer_head * sysv_update_inode(struct inode * inode) void sysv_write_inode(struct inode * inode, int wait) { struct buffer_head *bh; + lock_kernel(); bh = sysv_update_inode(inode); brelse(bh); + unlock_kernel(); } int sysv_sync_inode(struct inode * inode) diff --git a/fs/udf/super.c b/fs/udf/super.c index f3f575d7e..e89a86e72 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -100,14 +100,14 @@ static DECLARE_FSTYPE_DEV(udf_fstype, "udf", udf_read_super); /* Superblock operations */ static struct super_operations udf_sb_ops = { - read_inode: udf_read_inode, + read_inode: udf_read_inode, write_inode: udf_write_inode, - put_inode: udf_put_inode, + put_inode: udf_put_inode, delete_inode: udf_delete_inode, - put_super: udf_put_super, + put_super: udf_put_super, write_super: udf_write_super, - statfs: udf_statfs, - remount_fs: udf_remount_fs, + statfs: udf_statfs, + remount_fs: udf_remount_fs, }; struct udf_options diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 3b7bf8410..f93a55c4e 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -101,6 +101,7 @@ void ufs_free_inode (struct inode * inode) is_directory = S_ISDIR(inode->i_mode); DQUOT_FREE_INODE(sb, inode); + DQUOT_DROP(inode); clear_inode (inode); diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index eb1d86d18..fffaa7d3e 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -747,7 +747,9 @@ static int ufs_update_inode(struct inode * inode, int do_sync) void ufs_write_inode (struct inode * inode, int wait) { + lock_kernel(); ufs_update_inode (inode, wait); + unlock_kernel(); } int ufs_sync_inode (struct inode *inode) @@ -755,18 +757,15 @@ int ufs_sync_inode (struct inode *inode) return ufs_update_inode (inode, 1); } -void ufs_put_inode (struct inode * inode) -{ - UFSD(("ENTER & EXIT\n")) -} - void ufs_delete_inode (struct inode * inode) { /*inode->u.ufs_i.i_dtime = CURRENT_TIME;*/ + lock_kernel(); mark_inode_dirty(inode); ufs_update_inode(inode, IS_SYNC(inode)); inode->i_size = 0; if (inode->i_blocks) ufs_truncate (inode); ufs_free_inode (inode); + unlock_kernel(); } diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 7784203e0..c41228adf 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -971,7 +971,6 @@ int ufs_statfs (struct super_block * sb, struct statfs * buf) static struct super_operations ufs_super_ops = { read_inode: ufs_read_inode, write_inode: ufs_write_inode, - put_inode: ufs_put_inode, delete_inode: ufs_delete_inode, put_super: ufs_put_super, write_super: ufs_write_super, diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7c0acf4bb..4c3f211cc 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -217,23 +217,30 @@ extern char * __d_path(struct dentry *, struct vfsmount *, struct dentry *, /* Allocation counts.. */ /** - * dget - get a reference to a dentry + * dget, dget_locked - get a reference to a dentry * @dentry: dentry to get a reference to * * Given a dentry or %NULL pointer increment the reference count * if appropriate and return the dentry. A dentry will not be - * destroyed when it has references. + * destroyed when it has references. dget() should never be + * called for dentries with zero reference counter. For these cases + * (preferably none, functions in dcache.c are sufficient for normal + * needs and they take necessary precautions) you should hold dcache_lock + * and call dget_locked() instead of dget(). */ static __inline__ struct dentry * dget(struct dentry *dentry) { - if (!atomic_read(&dentry->d_count)) - BUG(); - if (dentry) + if (dentry) { + if (!atomic_read(&dentry->d_count)) + BUG(); atomic_inc(&dentry->d_count); + } return dentry; } +extern struct dentry * dget_locked(struct dentry *); + /** * d_unhashed - is dentry hashed * @dentry: entry to check diff --git a/include/linux/parport.h b/include/linux/parport.h index 0597addd4..294464b65 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -1,5 +1,12 @@ /* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */ +/* + * The block comments above the functions in this file are + * licensed as part of the generated file + * Documentation/DocBook/parportbook.sgml under the GNU Free + * Documentation License. + */ + #ifndef _PARPORT_H_ #define _PARPORT_H_ @@ -52,7 +52,6 @@ static struct super_block *shm_read_super(struct super_block *,void *, int); static void shm_put_super (struct super_block *); static int shm_remount_fs (struct super_block *, int *, char *); static void shm_read_inode (struct inode *); -static void shm_write_inode(struct inode *, int); static int shm_statfs (struct super_block *, struct statfs *); static int shm_create (struct inode *,struct dentry *,int); static struct dentry *shm_lookup (struct inode *,struct dentry *); @@ -147,7 +146,6 @@ static DECLARE_FSTYPE(shm_fs_type, "shm", shm_read_super, FS_SINGLE); static struct super_operations shm_sops = { read_inode: shm_read_inode, - write_inode: shm_write_inode, delete_inode: shm_delete, put_super: shm_put_super, statfs: shm_statfs, @@ -371,10 +369,6 @@ static int shm_statfs(struct super_block *sb, struct statfs *buf) return 0; } -static void shm_write_inode(struct inode * inode, int sync) -{ -} - static void shm_read_inode(struct inode * inode) { int id; @@ -831,6 +825,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) return err; } +/* FIXME: maybe we need lock_kernel() here */ static void shm_delete (struct inode *ino) { int shmid = ino->i_ino; diff --git a/kernel/acct.c b/kernel/acct.c index 6eacd87b3..e2e8826fa 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -49,6 +49,7 @@ #ifdef CONFIG_BSD_PROCESS_ACCT #include <linux/mm.h> +#include <linux/slab.h> #include <linux/acct.h> #include <linux/smp_lock.h> #include <linux/file.h> diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 440aaf9f5..32ce9a7d6 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -56,7 +56,7 @@ extern int console_loglevel; extern void set_device_ro(kdev_t dev,int flag); #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) -extern int (*do_nfsservctl)(int, void *, void *); +extern long (*do_nfsservctl)(int, void *, void *); #endif extern void *sys_call_table; @@ -151,6 +151,7 @@ EXPORT_SYMBOL(sys_close); EXPORT_SYMBOL(dcache_lock); EXPORT_SYMBOL(d_alloc_root); EXPORT_SYMBOL(d_delete); +EXPORT_SYMBOL(dget_locked); EXPORT_SYMBOL(d_validate); EXPORT_SYMBOL(d_rehash); EXPORT_SYMBOL(d_invalidate); /* May be it will be better in dcache.h? */ diff --git a/mm/filemap.c b/mm/filemap.c index 7f226eef3..3b0078045 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1683,9 +1683,7 @@ int filemap_sync(struct vm_area_struct * vma, unsigned long address, */ static void filemap_unmap(struct vm_area_struct *vma, unsigned long start, size_t len) { - lock_kernel(); filemap_sync(vma, start, len, MS_ASYNC); - unlock_kernel(); } /* @@ -1741,14 +1739,17 @@ static int msync_interval(struct vm_area_struct * vma, { if (vma->vm_file && vma->vm_ops && vma->vm_ops->sync) { int error; - lock_kernel(); error = vma->vm_ops->sync(vma, start, end-start, flags); if (!error && (flags & MS_SYNC)) { struct file * file = vma->vm_file; - if (file && file->f_op && file->f_op->fsync) + if (file && file->f_op && file->f_op->fsync) { + down(&file->f_dentry->d_inode->i_sem); + lock_kernel(); error = file->f_op->fsync(file, file->f_dentry, 1); + unlock_kernel(); + up(&file->f_dentry->d_inode->i_sem); + } } - unlock_kernel(); return error; } return 0; @@ -354,7 +354,8 @@ static kmem_cache_t cache_cache = { flags: SLAB_NO_REAP, spinlock: SPIN_LOCK_UNLOCKED, colour_off: L1_CACHE_BYTES, - name: "kmem_cache" + name: "kmem_cache", + next: LIST_HEAD_INIT(cache_cache.next) }; /* Guard access to the cache-chain. */ diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index bb6eddfe6..69d8b726d 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -324,6 +324,7 @@ int mpc_proc_init(void) return -ENOMEM; } p->proc_fops = &mpc_file_operations; + p->owner = THIS_MODULE; return 0; } diff --git a/net/atm/proc.c b/net/atm/proc.c index b2b186ac4..4a016d08b 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -559,6 +559,7 @@ int atm_proc_dev_register(struct atm_dev *dev) goto fail0; dev->proc_entry->data = dev; dev->proc_entry->proc_fops = &proc_dev_atm_operations; + dev->proc_entry->owner = THIS_MODULE; return 0; kfree(dev->proc_entry); fail0: @@ -579,7 +580,8 @@ void atm_proc_dev_deregister(struct atm_dev *dev) name = create_proc_entry(#name,0,atm_proc_root); \ if (!name) goto cleanup; \ name->data = atm_##name##_info; \ - name->proc_fops = &proc_spec_atm_operations + name->proc_fops = &proc_spec_atm_operations; \ + name->owner = THIS_MODULE int __init atm_proc_init(void) diff --git a/net/netsyms.c b/net/netsyms.c index cd4a2bdb9..e1bfc3403 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -436,22 +436,6 @@ EXPORT_SYMBOL(arp_find); #endif /* CONFIG_INET */ -#if defined(CONFIG_ULTRA) || defined(CONFIG_WD80x3) || \ - defined(CONFIG_EL2) || defined(CONFIG_NE2000) || \ - defined(CONFIG_E2100) || defined(CONFIG_HPLAN_PLUS) || \ - defined(CONFIG_HPLAN) || defined(CONFIG_AC3200) || \ - defined(CONFIG_ES3210) || defined(CONFIG_ULTRA32) || \ - defined(CONFIG_LNE390) || defined(CONFIG_NE3210) || \ - defined(CONFIG_NE2K_PCI) || defined(CONFIG_APNE) || \ - defined(CONFIG_DAYNAPORT) -/* If 8390 NIC support is built in, we will need these. */ -EXPORT_SYMBOL(ei_open); -EXPORT_SYMBOL(ei_close); -EXPORT_SYMBOL(ei_interrupt); -EXPORT_SYMBOL(ethdev_init); -EXPORT_SYMBOL(NS8390_init); -#endif - #ifdef CONFIG_TR EXPORT_SYMBOL(tr_setup); EXPORT_SYMBOL(tr_type_trans); diff --git a/net/socket.c b/net/socket.c index 276940470..4cd725731 100644 --- a/net/socket.c +++ b/net/socket.c @@ -365,7 +365,7 @@ static int sock_map_fd(struct socket *sock) file->f_vfsmnt = mntget(sock_mnt); sock->file = file; - file->f_op = &socket_file_ops; + file->f_op = sock->inode->i_fop = &socket_file_ops; file->f_mode = 3; file->f_flags = O_RDWR; file->f_pos = 0; |