From: cvs2svn Date: Thu, 5 Dec 2002 08:42:55 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch 'unlabeled-1.8.10'. X-Git-Tag: v1_7_100~1^38~25 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=aef6340175f3c5c115843946ff6ce98a053710e4;p=fs%2Flustre-release.git This commit was manufactured by cvs2svn to create branch 'unlabeled-1.8.10'. --- aef6340175f3c5c115843946ff6ce98a053710e4 diff --cc lustre/.cvsignore index 953c699,111b232..0000000 deleted file mode 100644,100644 --- a/lustre/.cvsignore +++ /dev/null @@@ -1,12 -1,14 +1,0 @@@ --.Xrefs --aclocal.m4 --config.log --config.status --config.cache --configure --Makefile --Makefile.in --.deps --tags --TAGS --lustre*.tar.gz -cscope.files -cscope.out diff --cc lustre/BUGS index 9cf6fa2,9cf6fa2..0000000 deleted file mode 100644,100644 --- a/lustre/BUGS +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ --include /dev/obd in the documentation -- -- --attach: attaching ext2obd allows ext2 module to be unloaded. Unload, --then do cleanup, get Oops... -- --syncing: invalid IOCTL -- --create: more than one object -- --preallocate: IOCTL -- --statfs: -- --restoresnap: decrements directory count for ext2 diff --cc lustre/BUILDING index deaa5e8,deaa5e8..0000000 deleted file mode 100644,100644 --- a/lustre/BUILDING +++ /dev/null @@@ -1,25 -1,25 +1,0 @@@ --BUILDING LUSTRE ----------------- -- --To build the lustre obd module, you must first build portals. -- --Portals is available from the same CVS repository of the lustre --project module portals, see http://www.lustre.org -- --To build: -- sh autogen.sh -- ./configure --enable-linuxdir=/usr/src/linux --enable-portalsdir=/usr/src/portals -- make -- --To play with Lustre Lite: -- cd obd/tests -- sh llmount.sh -- --To clean up: -- sh llmountcleanup.sh -- --Feedback: -- lustre-devel@lists.sf.net -- lustre-discuss@lists.sf.net -- --- Peter - diff --cc lustre/COPYING index c69cfd8,c69cfd8..0000000 deleted file mode 100644,100644 --- a/lustre/COPYING +++ /dev/null @@@ -1,352 -1,352 +1,0 @@@ -- -- NOTE! This copyright does *not* cover user programs that use kernel -- services by normal system calls - this is merely considered normal use -- of the kernel, and does *not* fall under the heading of "derived work". -- Also note that the GPL below is copyrighted by the Free Software -- Foundation, but the instance of code that it refers to (the Linux -- kernel) is copyrighted by me and others who actually wrote it. -- -- Linus Torvalds -- ------------------------------------------ -- -- GNU GENERAL PUBLIC LICENSE -- Version 2, June 1991 -- -- Copyright (C) 1989, 1991 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. -- -- Preamble -- -- The licenses for most software are designed to take away your --freedom to share and change it. By contrast, the GNU General Public --License is intended to guarantee your freedom to share and change free --software--to make sure the software is free for all its users. This --General Public License applies to most of the Free Software --Foundation's software and to any other program whose authors commit to --using it. (Some other Free Software Foundation software is covered by --the GNU Library General Public License instead.) You can apply it to --your programs, too. -- -- When we speak of free software, we are referring to freedom, not --price. Our General Public Licenses are designed to make sure that you --have the freedom to distribute copies of free software (and charge for --this service if you wish), that you receive source code or can get it --if you want it, that you can change the software or use pieces of it --in new free programs; and that you know you can do these things. -- -- To protect your rights, we need to make restrictions that forbid --anyone to deny you these rights or to ask you to surrender the rights. --These restrictions translate to certain responsibilities for you if you --distribute copies of the software, or if you modify it. -- -- For example, if you distribute copies of such a program, whether --gratis or for a fee, you must give the recipients all the rights that --you have. You must make sure that they, too, receive or can get the --source code. And you must show them these terms so they know their --rights. -- -- We protect your rights with two steps: (1) copyright the software, and --(2) offer you this license which gives you legal permission to copy, --distribute and/or modify the software. -- -- Also, for each author's protection and ours, we want to make certain --that everyone understands that there is no warranty for this free --software. If the software is modified by someone else and passed on, we --want its recipients to know that what they have is not the original, so --that any problems introduced by others will not reflect on the original --authors' reputations. -- -- Finally, any free program is threatened constantly by software --patents. We wish to avoid the danger that redistributors of a free --program will individually obtain patent licenses, in effect making the --program proprietary. To prevent this, we have made it clear that any --patent must be licensed for everyone's free use or not licensed at all. -- -- The precise terms and conditions for copying, distribution and --modification follow. -- -- GNU GENERAL PUBLIC LICENSE -- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -- -- 0. This License applies to any program or other work which contains --a notice placed by the copyright holder saying it may be distributed --under the terms of this General Public License. The "Program", below, --refers to any such program or work, and a "work based on the Program" --means either the Program or any derivative work under copyright law: --that is to say, a work containing the Program or a portion of it, --either verbatim or with modifications and/or translated into another --language. (Hereinafter, translation is included without limitation in --the term "modification".) Each licensee is addressed as "you". -- --Activities other than copying, distribution and modification are not --covered by this License; they are outside its scope. The act of --running the Program is not restricted, and the output from the Program --is covered only if its contents constitute a work based on the --Program (independent of having been made by running the Program). --Whether that is true depends on what the Program does. -- -- 1. You may copy and distribute verbatim copies of the Program's --source code as you receive it, in any medium, provided that you --conspicuously and appropriately publish on each copy an appropriate --copyright notice and disclaimer of warranty; keep intact all the --notices that refer to this License and to the absence of any warranty; --and give any other recipients of the Program a copy of this License --along with the Program. -- --You may charge a fee for the physical act of transferring a copy, and --you may at your option offer warranty protection in exchange for a fee. -- -- 2. You may modify your copy or copies of the Program or any portion --of it, thus forming a work based on the Program, and copy and --distribute such modifications or work under the terms of Section 1 --above, provided that you also meet all of these conditions: -- -- a) You must cause the modified files to carry prominent notices -- stating that you changed the files and the date of any change. -- -- b) You must cause any work that you distribute or publish, that in -- whole or in part contains or is derived from the Program or any -- part thereof, to be licensed as a whole at no charge to all third -- parties under the terms of this License. -- -- c) If the modified program normally reads commands interactively -- when run, you must cause it, when started running for such -- interactive use in the most ordinary way, to print or display an -- announcement including an appropriate copyright notice and a -- notice that there is no warranty (or else, saying that you provide -- a warranty) and that users may redistribute the program under -- these conditions, and telling the user how to view a copy of this -- License. (Exception: if the Program itself is interactive but -- does not normally print such an announcement, your work based on -- the Program is not required to print an announcement.) -- --These requirements apply to the modified work as a whole. If --identifiable sections of that work are not derived from the Program, --and can be reasonably considered independent and separate works in --themselves, then this License, and its terms, do not apply to those --sections when you distribute them as separate works. But when you --distribute the same sections as part of a whole which is a work based --on the Program, the distribution of the whole must be on the terms of --this License, whose permissions for other licensees extend to the --entire whole, and thus to each and every part regardless of who wrote it. -- --Thus, it is not the intent of this section to claim rights or contest --your rights to work written entirely by you; rather, the intent is to --exercise the right to control the distribution of derivative or --collective works based on the Program. -- --In addition, mere aggregation of another work not based on the Program --with the Program (or with a work based on the Program) on a volume of --a storage or distribution medium does not bring the other work under --the scope of this License. -- -- 3. You may copy and distribute the Program (or a work based on it, --under Section 2) in object code or executable form under the terms of --Sections 1 and 2 above provided that you also do one of the following: -- -- a) Accompany it with the complete corresponding machine-readable -- source code, which must be distributed under the terms of Sections -- 1 and 2 above on a medium customarily used for software interchange; or, -- -- b) Accompany it with a written offer, valid for at least three -- years, to give any third party, for a charge no more than your -- cost of physically performing source distribution, a complete -- machine-readable copy of the corresponding source code, to be -- distributed under the terms of Sections 1 and 2 above on a medium -- customarily used for software interchange; or, -- -- c) Accompany it with the information you received as to the offer -- to distribute corresponding source code. (This alternative is -- allowed only for noncommercial distribution and only if you -- received the program in object code or executable form with such -- an offer, in accord with Subsection b above.) -- --The source code for a work means the preferred form of the work for --making modifications to it. For an executable work, complete source --code means all the source code for all modules it contains, plus any --associated interface definition files, plus the scripts used to --control compilation and installation of the executable. However, as a --special exception, the source code distributed need not include --anything that is normally distributed (in either source or binary --form) with the major components (compiler, kernel, and so on) of the --operating system on which the executable runs, unless that component --itself accompanies the executable. -- --If distribution of executable or object code is made by offering --access to copy from a designated place, then offering equivalent --access to copy the source code from the same place counts as --distribution of the source code, even though third parties are not --compelled to copy the source along with the object code. -- -- 4. You may not copy, modify, sublicense, or distribute the Program --except as expressly provided under this License. Any attempt --otherwise to copy, modify, sublicense or distribute the Program 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. -- -- 5. You are not required to accept this License, since you have not --signed it. However, nothing else grants you permission to modify or --distribute the Program or its derivative works. These actions are --prohibited by law if you do not accept this License. Therefore, by --modifying or distributing the Program (or any work based on the --Program), you indicate your acceptance of this License to do so, and --all its terms and conditions for copying, distributing or modifying --the Program or works based on it. -- -- 6. Each time you redistribute the Program (or any work based on the --Program), the recipient automatically receives a license from the --original licensor to copy, distribute or modify the Program subject to --these terms and conditions. You may not impose any further --restrictions on the recipients' exercise of the rights granted herein. --You are not responsible for enforcing compliance by third parties to --this License. -- -- 7. If, as a consequence of a court judgment or allegation of patent --infringement or for any other reason (not limited to patent issues), --conditions are imposed on you (whether by court order, agreement or --otherwise) that contradict the conditions of this License, they do not --excuse you from the conditions of this License. If you cannot --distribute so as to satisfy simultaneously your obligations under this --License and any other pertinent obligations, then as a consequence you --may not distribute the Program at all. For example, if a patent --license would not permit royalty-free redistribution of the Program by --all those who receive copies directly or indirectly through you, then --the only way you could satisfy both it and this License would be to --refrain entirely from distribution of the Program. -- --If any portion of this section is held invalid or unenforceable under --any particular circumstance, the balance of the section is intended to --apply and the section as a whole is intended to apply in other --circumstances. -- --It is not the purpose of this section to induce you to infringe any --patents or other property right claims or to contest validity of any --such claims; this section has the sole purpose of protecting the --integrity of the free software distribution system, which is --implemented by public license practices. Many people have made --generous contributions to the wide range of software distributed --through that system in reliance on consistent application of that --system; it is up to the author/donor to decide if he or she is willing --to distribute software through any other system and a licensee cannot --impose that choice. -- --This section is intended to make thoroughly clear what is believed to --be a consequence of the rest of this License. -- -- 8. If the distribution and/or use of the Program is restricted in --certain countries either by patents or by copyrighted interfaces, the --original copyright holder who places the Program under this License --may add an explicit geographical distribution limitation excluding --those countries, so that distribution is permitted only in or among --countries not thus excluded. In such case, this License incorporates --the limitation as if written in the body of this License. -- -- 9. The Free Software Foundation may publish revised and/or new versions --of the General Public 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. -- --Each version is given a distinguishing version number. If the Program --specifies a version number of this License which applies to it and "any --later version", you have the option of following the terms and conditions --either of that version or of any later version published by the Free --Software Foundation. If the Program does not specify a version number of --this License, you may choose any version ever published by the Free Software --Foundation. -- -- 10. If you wish to incorporate parts of the Program into other free --programs whose distribution conditions are different, write to the author --to ask for permission. For software which is copyrighted by the Free --Software Foundation, write to the Free Software Foundation; we sometimes --make exceptions for this. Our decision will be guided by the two goals --of preserving the free status of all derivatives of our free software and --of promoting the sharing and reuse of software generally. -- -- NO WARRANTY -- -- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY --FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN --OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES --PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED --OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF --MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS --TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE --PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, --REPAIR OR CORRECTION. -- -- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING --WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR --REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, --INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING --OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED --TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY --YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER --PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE --POSSIBILITY OF SUCH DAMAGES. -- -- END OF TERMS AND CONDITIONS -- -- How to Apply These Terms to Your New Programs -- -- If you develop a new program, and you want it to be of the greatest --possible use to the public, the best way to achieve this is to make it --free software which everyone can redistribute and change under these terms. -- -- To do so, attach the following notices to the program. It is safest --to attach them to the start of each source file to most effectively --convey the exclusion of warranty; and each file should have at least --the "copyright" line and a pointer to where the full notice is found. -- -- -- Copyright (C) 19yy -- -- This program 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. -- -- 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. -- -- 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 -- -- --Also add information on how to contact you by electronic and paper mail. -- --If the program is interactive, make it output a short notice like this --when it starts in an interactive mode: -- -- Gnomovision version 69, Copyright (C) 19yy name of author -- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -- This is free software, and you are welcome to redistribute it -- under certain conditions; type `show c' for details. -- --The hypothetical commands `show w' and `show c' should show the appropriate --parts of the General Public License. Of course, the commands you use may --be called something other than `show w' and `show c'; they could even be --mouse-clicks or menu items--whatever suits your program. -- --You should also get your employer (if you work as a programmer) or your --school, if any, to sign a "copyright disclaimer" for the program, if --necessary. Here is a sample; alter the names: -- -- Yoyodyne, Inc., hereby disclaims all copyright interest in the program -- `Gnomovision' (which makes passes at compilers) written by James Hacker. -- -- , 1 April 1989 -- Ty Coon, President of Vice -- --This General Public License does not permit incorporating your program into --proprietary programs. If your program is a subroutine library, you may --consider it more useful to permit linking proprietary applications with the --library. If this is what you want to do, use the GNU Library General --Public License instead of this License. diff --cc lustre/ChangeLog index d2ac804,45d39ab..0000000 deleted file mode 100644,100644 --- a/lustre/ChangeLog +++ /dev/null @@@ -1,210 -1,244 +1,0 @@@ - TBD - * version TBD -TBA - * bug fixes - - LRU counters were broken, causing constant lock purge (433, 432) - - garbage on read from stripes with failed OSTs (441) - - mark OSCs as active before reconnecting during recovery (438) - - lov_enqueue and lov_cancel need to handle inactive OSTs (403) - -2002-12-02 Andreas Dilger - * version v0_5_18 - * bug fixes - - fix many simultaneous client startup (392) - - fix dentry->d_it clobbering - - credentials weren't being shipped for readdir/getattr operations - - remove invalid assertions triggered during some concurrent MD - updates - - proper Lustre versions added (336, 389) - - fix memory leak for create error case (398) - - fix LOV locking bug that would get cli/srv out of sync - - fix echo client over LOV (409) - - fix dbench 2, extN refcount problem (170, 258, 356, 418) - - fix double-O_EXCL intent crash (424) - - avoid sending multiple lock CANCELs (352) - * Features - - MDS can do multi-client recovery (modulo bugs in new code) - * Documentation - - many updates, edits, cleanups - -2002-11-18 Phil Schwan - * version v0_5_17 -- * bug fixes -- - fix null d_it dereference (346) -- - fix full OST/dbench hang (333) -- - fix permission problem with file removal (286) -- - fix removal of OSCs from LOV when they fail -- - fix NULL deref during bulk timeout (214) -- - fix problems related to multiple filesystems on one MDS (241) -- - fixed serious subtle metadata locking bugs -- - free locks on clients when inodes are removed due to memory -- pressure (201) -- - fix inode pointer in lock data (285) - - partial support for multiple MDS on a single host (623279, 241) - - partial support for multiple MDS on a single host (241) -- - data locks weren't cancelled at clear_inode time (290, 311) -- - intent locks could lead to unbounded lock growth (205) -- - added a maximum lock count, an LRU list, and a flusher -- - fix multiple rename (365) - - properly abstracted the echo client - - OSC locked 1 byte too many; fixed - - rewrote brw callback code: - - fixed recovery bugs related to LOVs (306) - - fixed too-many-pages-in-one-write crash (191) - - fixed (again) crash in sync_io_timeout (214) - - probably fixed callback-related race (385) -- * protocol change -- - Add capability to MDS protocol -- - LDLM cancellations and callbacks on different portals -- --2002-10-28 Andreas Dilger -- * version v0_5_16 -- * bug fixes: -- - limit client IOV size to PTL_MD_MAX_IOV (611336, 191) -- - defer open object destruction to close time (601981, 138) -- - open/close OST file handle in obdo (OBD_MD_FLHANDLE) (601981, 138) -- - move LDLM_ENQUEUE/CONVERT back to MDS portal (625069) -- - abstract ll_lookup2, fix ll_revalidate2 to use abstraction (256) -- - don't call obd_setattr in ll_file_release for destroyed objects -- * protocol change to lustre_msg: move |version| and add |flags| -- * protocol change to osc_punch: "start" in "o_size", "end" in "o_blocks" -- * lock replay: for LDLM_FL_REPLAY trust client to do right thing -- * added replay of create, unlink, link and rename operations during -- MDS failover; recovery should be much more robust now -- * remove failed OSCs from LOVs (only lov_create uses this so far) -- * the lustre-HOWTO was brought (more) up to date (582544) -- --2002-10-23 Phil Schwan -- * version v0_5_15 -- * bug fixes: -- - in-use dentries weren't being reused properly (617851) -- - prevent multiple LDLM setup (599178) -- - fix LOV size calculations for truncate (617853) -- - fix client handling of MDS intent errors (POSIX) -- - fix permission bug in lovstripe.c test (624321) -- - fix MDS thread deadlock - move LDLM handler to DLM portal (625069) -- - truncate past end of file could corrupt data -- - proper cleanup after timeouts, crashes, etc (592524, 550815) -- - a race in recovery could return ETIMEDOUT to apps (623947) -- - building outside the source directory was fixed -- * the lustre-HOWTO was brought (more) up to date (582544) -- * major progress was made on recovery functionality -- --2002-10-10 Phil Schwan -- * version v0_5_14 -- * bug fixes: -- - recovery deadlock fix -- - rm -rf causes LBUG fix (617817) -- - file open by multiple tasks fix (618962) -- - directory permissions bugs (602707 and 620007) -- - journal_stop fixed with locking (611313) -- - O_APPEND failures resolved (618273, perhaps 614459) -- - lconf PATH fix (619770) -- - IA64 build fix (621450) -- - RPC buffer sizes scale with amount of memory -- --2002-10-01 Phil Schwan -- * version v0_5_13 -- * bug fixes: -- - locks would be cancelled without throwing away data pages, -- resulting in inconsistent data (605627) -- - inode attributes were not always being refreshed (605627, 612449) -- - lconf now continues to cleanup after lctl reports an error -- - MDS now enforces user permissions (602707) -- - lprocfs cleanup fixed, but not yet enabled (614157) -- - fixed infinite server hang, should a client not respond to an AST -- - avoid going into recovery if user calls readlink() with a buffer -- that's too small (613941) -- - AST RPCs no longer require replies (614867) -- this may be changed -- - don't crash server if client sends an IOV that's too big (611336) -- - fixed lock conversion deadlock (611892) -- - fixed the following of symlinks (614622) -- * recovery: the server can remove locks from a client that dies, other -- clients can make progress -- * more extN patch fixes -- * compile-time configurable ptlrpc buffer allocations -- * documentation -- - collaborative read cache document -- - Lustre Lite Performance CDR document-in-progress -- --2002-09-20 Andreas Dilger -- * version v0_5_12 -- * bug fix -- - fix typo in patch-2.4.18 -- --2002-09-20 Andreas Dilger -- * version v0_5_11 -- * bug fixes -- - clear ptlrpc request each time in handle_incoming_request() -- - unlink of files now destroys the object on the OST -- --2002-09-19 Peter Braam -- * version 0_5_10 -- * add hard link support -- * change obdfile creation method -- * kernel patch changed -- --2002-09-19 Peter Braam -- * version 0_5_9 -- * bug fix -- - stack overflow bug in extN fixed -- --2002-09-18 Andreas Dilger -- * version 0_5_8 -- * documentation updates -- - add man pages for config tools -- - update tests/README to describe testing with new config tools -- - finish metadata API descriptions -- * bug fixes and cleanups -- - statfs workaround for 16TB limit -- - LOV stripe allocation improved, can stripe on subset of OSTs -- - LOV file size/IO offset was wrong for files > 4GB in size -- - object EA data was being dropped, caused files to be unreadable -- - memory overflow with non-LOV OST caused memory corruption -- - fixed regression tests to work with new config tools, obdfilter -- - fixed bug when directory size became larger than 1 block -- - fixed bug (for single client case) when PWD was deleted -- - invalidate local directory pages when doing intent-based ops -- - avoid LDLM oops when lock callback contained bad data -- --2002-09-09 Andreas Dilger -- * version 0_5_7 -- * documentation updates -- * bug fixes and cleanups -- - configuration tools -- - LOV -- - imports/exports -- - 64-bit compile warnings -- - 64-bit internal statfs data -- - many more -- * test_brw on persistent OST devices -- * MDS recovery -- * lprocfs (disabled) -- --2002-09-04 Andreas Dilger -- * version 0_5_6 -- * documentation updates -- * bug fixes and cleanups -- * configuration tools -- --2002-08-30 Peter J. Braam -- -- * version v0_5_5 -- * many small fixes to 0_5_4 -- * io/network handling -- * thinkos in MDS operations -- --2002-08-24 Peter J. Braam -- -- * version v0_5_4 -- * crucial basic fixes to 0.5.3 -- * IOR, Iozone work over Elan -- * EOF locks added -- --2002-08-07 Phil Schwan -- * version 0_5_3, our first alpha -- * we use the new Portals iovs -- * documentation updates -- * bug fixes and cleanups -- * small changes in the DLM wire protocol -- --2002-07-25 Peter J. Braam -- * version 0_5_1 with some initial stability, -- * locking on MD and file I/O. -- * documentation updates -- * several bug fixes since 0.5.0 -- * small changes in wire protocol -- --2002-07-18 Phil Schwan -- * version v0_4_5 -- * delivered as Lustre Light Alpha -- * fixed a crash after handling invalid MDS requests -- * fixed directory pages for architectures with non-4k pages sizes -- --2002-07-11 Andreas Dilger -- * release version v0_4_4 -- * Moves TCP acceptor to be on port 2432 (unused Coda port) instead -- of 1234. -- * Fixes a number of interruption problems with OST operations. -- * Update documentation for portals header changes -- * Move all wire protocol structs/defines to lustre_idl.h -- * Fixes symlink length bug. -- * Add tcpdump to repository. -- --2002-07-05 Andreas Dilger -- * release version v0_4_3 -- * Fixes statfs for inodes on extN. -- * Fixes bug in runtests which would delete /etc/hosts. -- * Use 64-bit object IDs wherever possible (not into VFS though) -- Remove ost_get_info, which is unused by lustre, and out of date. -- --2002-07-03 Peter Braam -- * release version v0_4_2 Fixes a lookup error (type not passed) -- * move forward to head of Portals -- * move forward to latest Lustre kernel -- --2002-06-25 Peter Braam -- * release version v0_4_1. Hopefully stable on single node use. diff --cc lustre/FDL index b42936b,b42936b..0000000 deleted file mode 100644,100644 --- a/lustre/FDL +++ /dev/null @@@ -1,355 -1,355 +1,0 @@@ -- 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. diff --cc lustre/Makefile.am index 11194b3,6fcadf3..0000000 deleted file mode 100644,100644 --- a/lustre/Makefile.am +++ /dev/null @@@ -1,33 -1,31 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --AUTOMAKE_OPTIONS = foreign -- --if LINUX25 --DIRS24 = mds --else --DIRS24 = extN mds --endif -- - # NOTE: keep extN before mds - SUBDIRS = lov utils obdclass ldlm ptlrpc lib obdecho mdc osc ost llite - SUBDIRS+= $(DIRS24) obdfilter tests doc scripts -# NOTE: keep extN before mds and obdfilter -SUBDIRS = $(DIRS24) obdclass utils ptlrpc ldlm lib obdfilter mdc osc ost llite -SUBDIRS+= obdecho lov tests doc scripts -- --DIST_SUBDIRS = $(SUBDIRS) --EXTRA_DIST = BUGS FDL Rules include patches archdep.m4 -- --# We get the version from the spec file. --CONFIGURE_DEPENDENCIES = scripts/lustre.spec.in -- --dist-hook: -- find $(distdir) -name .deps | xargs rm -rf -- find $(distdir) -name CVS | xargs rm -rf -- --include $(top_srcdir)/Rules -- --rpms: dist Makefile -- rpm -ta $(distdir).tar.gz - - diff --cc lustre/README index a7b7240,a7b7240..0000000 deleted file mode 100644,100644 --- a/lustre/README +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --Instructions for building, configuring, and running Lustre can be found in --the file doc/lustre-HOWTO.txt. -- --If you have checked lustre directly out of CVS, then you either need to --get lyx to build the lustre-HOWTO.txt from the source file, get the PDF --version from the lustre.org website, or install the lustre-doc RPM for --the formatted text version (or read the somewhat cryptic lustre-HOWTO.lin --file if you are desperate). diff --cc lustre/Rules index cbcf51f,cbcf51f..0000000 deleted file mode 100644,100644 --- a/lustre/Rules +++ /dev/null @@@ -1,24 -1,24 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --# Build a kernel module, name.o, and install it in $(moduledir) by: --# MODULE = name --# module_DATA = name.o --# EXTRA_PROGRAMS = name --# name_SOURCES = my.c files.c --# include $(top_srcdir)/Rules -- --$(MODULE).o: $($(MODULE)_OBJECTS) -- $(LD) -m "`$(LD) --help | awk '/supported emulations/ {print $$4}'`" -r -o $(MODULE).o $($(MODULE)_OBJECTS) -- --tags: -- rm -f $(top_srcdir)/TAGS -- rm -f $(top_srcdir)/tags -- find $(top_srcdir)/../portals/ -name '*.[hc]' | xargs etags -a -- find $(top_srcdir) -name '*.[hc]' | xargs etags -a -- find $(top_srcdir)/../portals/ -name '*.[hc]' | xargs ctags -a -- find $(top_srcdir) -name '*.[hc]' | xargs ctags -a -- --AM_CPPFLAGS="-I$(top_builddir)/include" diff --cc lustre/archdep.m4 index b11266c,b11266c..0000000 deleted file mode 100644,100644 --- a/lustre/archdep.m4 +++ /dev/null @@@ -1,97 -1,97 +1,0 @@@ --AC_MSG_CHECKING(if you are running user mode linux for $host_cpu ...) --if test -e $LINUX/include/asm-um ; then --if test X`ls -id $LINUX/include/asm/ | awk '{print $1}'` = X`ls -id $LINUX/include/asm-um | awk '{print $1}'` ; then -- host_cpu="um"; -- AC_MSG_RESULT(yes) --else -- AC_MSG_RESULT(no (asm doesn't point at asm-um)) --fi -- --else -- AC_MSG_RESULT(no (asm-um missing)) --fi -- --AC_MSG_CHECKING(setting make flags system architecture: ) --case ${host_cpu} in -- um ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -Wall -pipe -Wno-trigraphs -Wstrict-prototypes -fno-strict-aliasing -fno-common ' -- KCPPFLAGS='-D__KERNEL__ -U__i386__ -Ui386 -DUM_FASTCALL -D__arch_um__ -DSUBARCH="i386" -DNESTING=0 -D_LARGEFILE64_SOURCE -Derrno=kernel_errno -DPATCHLEVEL=4 -DMODULE -I$(LINUX)/arch/um/include ' -- MOD_LINK=elf_i386 --;; -- i*86 ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -pipe' -- KCPPFLAGS='-D__KERNEL__ -DMODULE ' -- MOD_LINK=elf_i386 --;; -- -- alphaev6 ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev6' -- KCPPFLAGS='-D__KERNEL__ -DMODULE ' -- MOD_LINK=elf64alpha --;; -- -- alphaev67 ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev6' -- KCPPFLAGS='-D__KERNEL__ -DMODULE ' -- MOD_LINK=elf64alpha --;; -- -- alpha* ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mno-fp-regs -ffixed-8 -mcpu=ev5 -Wa,-mev5' -- KCPPFLAGS='-D__KERNEL__ -DMODULE ' -- MOD_LINK=elf64alpha --;; -- -- ia64 ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -pipe -ffixed-r13 -mfixed-range=f10-f15,f32-f127 -falign-functions=32 -mb-step' -- KCPPFLAGS='-D__KERNEL__ -DMODULE' -- MOD_LINK=elf64_ia64 --;; -- -- sparc64 ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -Wno-unused -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare -Wa,--undeclared-regs' -- KCPPFLAGS='-D__KERNEL__' -- MOD_LINK=elf64_sparc -- --;; -- -- powerpc ) -- AC_MSG_RESULT($host_cpu) -- KCFLAGS='-O2 -Wall -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing -fno-common -D__powerpc__ -fsigned-char -msoft-float -pipe -ffixed-r2 -Wno-uninitialized -mmultiple -mstring' -- KCPPFLAGS='-D__KERNEL__' -- MOD_LINK=elf32ppclinux --;; -- -- *) -- AC_ERROR("Unknown Linux Platform: $host_cpu") --;; --esac -- --AC_MSG_CHECKING(for MODVERSIONS) --if egrep -e 'MODVERSIONS.*1' $LINUX/include/linux/autoconf.h >/dev/null 2>&1; --then -- MFLAGS="-DMODULE -DMODVERSIONS -include $LINUX/include/linux/modversions.h -DEXPORT_SYMTAB" -- AC_MSG_RESULT(yes) --else -- MFLAGS= -- AC_MSG_RESULT(no) --fi -- --AC_MSG_CHECKING(for SMP) --if egrep -e SMP=y $LINUX/.config >/dev/null 2>&1; then -- SMPFLAG= -- AC_MSG_RESULT(yes) --else -- SMPFLAG= -- AC_MSG_RESULT(no) --fi -- --CFLAGS="$KCFLAGS $MFLAGS" --ARCHCPPFLAGS="$KCPPFLAGS" diff --cc lustre/autogen.sh index 9accad4,9accad4..0000000 deleted file mode 100644,100644 --- a/lustre/autogen.sh +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh -- --find . -type d -name .deps | xargs rm -rf --aclocal && --automake --add-missing && --${AUTOCONF:-autoconf} diff --cc lustre/configure.in index c40124e,c40124e..0000000 deleted file mode 100644,100644 --- a/lustre/configure.in +++ /dev/null @@@ -1,125 -1,125 +1,0 @@@ --AC_INIT --AC_CANONICAL_SYSTEM -- --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --# Automake variables. Steal the version number from lustre.spec.in. --AM_INIT_AUTOMAKE(lustre, builtin([esyscmd], [sed -ne '/^%define version /{ s/.*version //; p; q; }' scripts/lustre.spec.in])) --#AM_MAINTAINER_MODE --AC_PROG_CC --AC_PROG_RANLIB -- --# --# Check for required packages -- --# this doesn't seem to work on older autoconf --# AC_CHECK_LIB(readline, readline,,) -- --AC_ARG_ENABLE(readline, [ --enable-readline use readline library],, -- enable_readline="yes") -- --if test "$enable_readline" = "yes" ; then -- LIBREADLINE="-lreadline -lncurses" -- HAVE_LIBREADLINE="-DHAVE_LIBREADLINE=1" --else -- LIBREADLINE="" -- HAVE_LIBREADLINE="" --fi --AC_SUBST(LIBREADLINE) --AC_SUBST(HAVE_LIBREADLINE) -- --# Kernel build environment. --ac_default_prefix= --bindir='${exec_prefix}/usr/bin' --sbindir='${exec_prefix}/usr/sbin' -- --linuxdir_def=/usr/src/linux --AC_ARG_WITH(linux, [ --with-linux=[path] set path to Linux source (default=/usr/src/linux)], enable_linuxdir=$withval) --AC_ARG_ENABLE(linuxdir, [ --enable-linuxdir=[path] (deprecated) set path to Linux source (default=/usr/src/linux)],, enable_linuxdir=$linuxdir_def) -- --LINUX=$enable_linuxdir --AC_SUBST(LINUX) -- --sinclude(archdep.m4) -- --AC_MSG_CHECKING(if you are running linux 2.5...) --if test -e $LINUX/include/linux/namei.h ; then -- linux25=yes -- AC_MSG_RESULT(yes) --else -- linux25=no -- AC_MSG_RESULT(no) --fi --AM_CONDITIONAL(LINUX25, test x$linux25 = xyes) -- --KINCFLAGS='-I. -I$(top_srcdir)/include -I$(PORTALS)/include -I$(LINUX)/include' --CPPFLAGS="$KINCFLAGS $ARCHCPPFLAGS" -- --portalsdir_def='$(top_srcdir)/../portals' --AC_ARG_WITH(portals, [ --with-portals=[path] set path to Portals source (default=../portals)], enable_portalsdir=$withval) --AC_ARG_ENABLE(portalsdir, [ --enable-portalsdir=[path] (deprecated) set path to Portals source (default=$(top_srcdir)/../portals)],, enable_portalsdir=$portalsdir_def) --PORTALS=$enable_portalsdir --AC_SUBST(PORTALS) -- --portalslib_def=$enable_portalsdir/linux/utils --AC_ARG_WITH(portalslib, [ --with-portalslib=[path] set path to Portals library (default=../portals/linux/utils)], enable_portalslib=$withval) --AC_ARG_ENABLE(portalslib, [ --enable-portalslib=[path] (deprecated) set path to Portals lib (default=../portals/linux/utils)],, enable_portalslib=$portalslib_def) -- -- --if ! test -z "$enable_portalslib"; then -- PORTALSLIB=${enable_portalslib} --fi -- -- --AC_SUBST(PORTALSLIB) -- --AC_MSG_CHECKING(if make dep has been run in kernel source) --if test -f $LINUX/include/linux/config.h ; then -- AC_MSG_RESULT(yes) --else -- AC_MSG_ERROR(** cannot find $LINUX/include/linux/config.h. Run make dep in $LINUX.) --fi -- --AC_MSG_CHECKING(if autoconf.h is in kernel source) --if test -f $LINUX/include/linux/autoconf.h ; then -- AC_MSG_RESULT(yes) --else -- AC_MSG_ERROR(** cannot find $LINUX/include/linux/autoconf.h. Run make config in $LINUX.) --fi -- -- --AC_MSG_CHECKING(for Linux release) -- --dnl We need to rid ourselves of the nasty [ ] quotes. --changequote(, ) --dnl Get release from version.h --RELEASE="`sed -ne 's/.*UTS_RELEASE[ \"]*\([0-9.a-zA-Z-]*\).*/\1/p' $LINUX/include/linux/version.h`" --changequote([, ]) -- --moduledir='$(libdir)/modules/'$RELEASE/kernel --AC_SUBST(moduledir) -- --modulefsdir='$(moduledir)/fs/$(PACKAGE)' --AC_SUBST(modulefsdir) -- --AC_MSG_RESULT($RELEASE) --AC_SUBST(RELEASE) -- --# Directories for documentation and demos. --docdir='${prefix}/usr/share/doc/$(PACKAGE)' --AC_SUBST(docdir) -- --demodir='$(docdir)/demo' --AC_SUBST(demodir) -- --# not needed until the AC_CHECK_LIB(readline) above works --# AM_CONFIG_HEADER(include/config.h) -- --AC_OUTPUT(Makefile lib/Makefile ldlm/Makefile obdecho/Makefile ptlrpc/Makefile \ -- lov/Makefile osc/Makefile mdc/Makefile mds/Makefile ost/Makefile \ -- utils/Makefile tests/Makefile obdfilter/Makefile obdclass/Makefile \ -- llite/Makefile doc/Makefile scripts/Makefile \ -- scripts/lustre.spec extN/Makefile) diff --cc lustre/doc/.cvsignore index fdf1642,fdf1642..0000000 deleted file mode 100644,100644 --- a/lustre/doc/.cvsignore +++ /dev/null @@@ -1,23 -1,23 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --tags --TAGS --OBD-HOWTO.html --OBD-HOWTO.txt --lustre-HOWTO.lyx --lustre-HOWTO.txt --lustre-pdf.bbl --lustre-pdf.blg --lustre-pdf.log --lustre-pdf.out --lustre-pdf.toc --*.eps --lustre.lyx --*.tex --*.pdf --*.aux diff --cc lustre/doc/Makefile.am index d261050,d261050..0000000 deleted file mode 100644,100644 --- a/lustre/doc/Makefile.am +++ /dev/null @@@ -1,124 -1,124 +1,0 @@@ --# Copyright (C) 2001, 2002 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution --LYX2PDF = GS_OPTIONS=-dCompatibilityLevel=1.1 $(srcdir)/tex2pdf -overwrite --TEX2PDF = GS_OPTIONS=-dCompatibilityLevel=1.1 $(srcdir)/tex2pdf -overwrite --LYX2PS = lyx --export ps --LYX2TEX = lyx --export latex --LYX2TXT = lyx --export text --LYX2HTML = lyx --export html --LATEX = latex --DVIPS = dvips --PS2PDF = ps2pdf --TEXEXPAND = texexpand --SUFFIXES = .lin .lyx .pdf .ps .sgml .html .txt .tex .fig .eps .dvi -- --DOCS = lustre.pdf lustre-HOWTO.txt --HOWTODOC = lustre-HOWTO.txt --IMAGES := $(patsubst %.fig,%.eps,$(wildcard *.fig)) --LYXFILES= $(filter-out $(patsubst %.lin,%.lyx,$(wildcard *.lin)),\ -- $(wildcard *.lin *.lyx)) -- --MAINTAINERCLEANFILES = $(IMAGES) $(DOCS) $(VERSIONED) --CLEANFILES = *.aux *.tex doc.old/*.aux doc.old/*.tex *.eps *.log *.pdf --VERSIONED = lustre-HOWTO.lyx lustre.lyx doc.old/lustre-HOWTO.lyx doc.old/lustre.lyx --GENERATED = $(VERSIONED) lustre-full.tex lustre-chbar.tex -- --EXTRA_DIST = chbar.sh postbar tex2pdf $(DOCS) $(IMAGES) $(LYXFILES) lustre.bib -- --all: $(HOWTODOC) --docs: $(DOCS) -- --# These variables are set by lbuild/check-build. --RPMRELEASE ?= RELEASE --KERNTYPE ?= chaos --KERNRPM ?= kernel-2.4.18lustre13-RELEASE.i386.rpm -- --# update date and version in document --date := $(shell date +%x) --tag := $(shell echo '$$Name: $$' | sed -e 's/^\$$Na''me: *\$$$$/HEAD/; s/^\$$Na''me: \(.*\) \$$$$/\1/') --addversion = sed -e 's|@T''AG@|$(tag)|g; s|@VER''SION@|$(VERSION)|g; s|@DA''TE@|$(date)|g; s|@RPM''RELEASE@|$(RPMRELEASE)|g; s|@KERN''TYPE@|$(KERNTYPE)|g; s|@KERN''RPM@|$(KERNRPM)|g' -- --# Regenerate when the $(VERSION) or $Name: $ changes. --.INTERMEDIATE: $(GENERATED) --$(VERSIONED) : %.lyx: %.lin Makefile -- $(addversion) $< > $@ -- --.lyx.pdf: -- @echo $(LYX2PDF) $< && $(LYX2PDF) $< || printf "\n*** Warning: not creating PDF docs; install lyx to rectify this\n" -- --.lyx.ps: -- @echo $(LYX2PS) $< && $(LYX2PS) $< || printf "\n*** Warning: not creating PostScript docs; install lyx to rectify this\n" -- --.lyx.tex: -- @echo $(LYX2TEX) $< && $(LYX2TEX) $< || printf "\n*** Warning: not creating LaTeX docs; install lyx to rectify this\n" -- --.lyx.txt: -- @echo $(LYX2TXT) $< && $(LYX2TXT) $< || printf "\n*** Warning: not creating text docs; install lyx to rectify this\n" -- --.lyx.html: -- @echo $(LYX2HTML) $< && $(LYX2HTML) $< || printf "\n*** Warning: not creating HTML docs; install lyx to rectify this\n" -- --.tex.pdf: -- $(TEX2PDF) $< -- --.tex.dvi: -- $(LATEX) $< -- $(LATEX) $< -- --.dvi.ps: -- $(DVIPS) $< -o $@ -- --.ps.pdf: -- $(PS2PDF) $< $@ -- --lustre.tex lustre.pdf lustre.txt lustre.html: $(IMAGES) $(LYXFILES) lustre-HOWTO.lyx --.fig.eps: -- -fig2dev -L eps $< > $@ -- --syncweb: lustre.pdf -- cp lustre.pdf /usr/src/www/content/lustre/docs/lustre.pdf -- ( cd /usr/src/www ; make lustre ; make synclustre ) --.PHONY: syncweb chbar -- --# Build a changebar document from the files in doc.old and this directory. --chbar: lustre-chbar.pdf -- --# FIXME: Temporary rules until pdftex displays changebars correctly. --lustre-chbar.pdf: lustre-chbar-nopdf.ps -- $(PS2PDF) $< $@ --lustre-chbar-nopdf.ps: lustre-chbar-nopdf.dvi -- $(DVIPS) $< -o $@ --lustre-chbar-nopdf.dvi: lustre-chbar-nopdf.tex -- $(LATEX) $< -- $(LATEX) $< --lustre-chbar-nopdf.tex: lustre-chbar.tex -- sed -e 's/^\(.*usepackage.*pdftex\)/%\1/' $< > $@ -- --%-chbar.tex: chbar.sh postbar doc.old/%-full.tex %-full.tex -- $(SHELL) $(srcdir)/chbar.sh doc.old/$*-full.tex $*-full.tex | $(srcdir)/postbar > $@ -- --# This rule needs to come before the next %-full.tex rule. --doc.old/lustre.tex: doc.old/lustre-HOWTO.lyx --doc.old/%-full.tex: doc.old/%.tex -- cd doc.old && $(TEXEXPAND) -texinputs=. -output=$*-full.tex $*.tex -- --# This rule needs to come after the more specific doc.old rule. --%-full.tex: %.tex -- $(TEXEXPAND) -texinputs=. -texinputs=$(srcdir) -output=$@ $< -- --# Check out the old directory if it doesn't exist. --doc.old/lustre.lin doc.old/lustre-HOWTO.lin: -- @if test "X$(OLD)" = X; then \ -- echo "You must populate doc.old or specify a CVS tag like OLD=v0_5_1"; \ -- exit 1; \ -- fi -- rm -rf doc.old -- mkdir doc.old -- cvs checkout -r $(OLD) -d doc.old lustre/doc -- --dist-hook: -- rm -rf $(distdir)/figs/CVS -- --include $(top_srcdir)/Rules diff --cc lustre/doc/VERSIONING index a1a8b62,839c746..0000000 deleted file mode 100644,100644 --- a/lustre/doc/VERSIONING +++ /dev/null @@@ -1,97 -1,91 +1,0 @@@ --Lustre versioning --================= -- --0.0.1 2/19/2002 --0.0.2 3/14/2002 describe branches / stable tag --0.0.3 6/10/2002 describe release mechanisms -- --This document describes versioning of source and binaries for Lustre. -- --Packages --======== -- --RPM's that you build should get 3 figure versions, CVS versions will --be 4 digits, and can correspond to test RPM's, and lead up to the --package version. So let's plan on releasing -- - So you'd build 2 sets of test rpms this week: -So you'd build 2 sets of test rpms this week: -- --0.0.9.1 --0.0.9.2 -- - we decide it's fine then and we release -we decide it's fine then and we release -- --0.1.0 -- - We go on developing with -We go on developing with -- - 0.1.0.{1,2,3,4,...} -0.1.0.{1,2,3,4,...} -- - as test releases and then we release: -as test releases and then we release: -- --0.1.1 -- --The 0.1 sequence is an unstable sequence, like 2.5 for the kernel is. --So we expect lots of 0.1.X releases leading up to a stable 0.2 (or --1.0) at the time of deployment. -- --CVS --=== -- --Versions will have 4 digits: -- major.minor.patch.test -- - Such versions will be tagged in CVS as: -Such versions will be tagged in CVS as: -- v1_2_11_7 --and referred to as: -- 1.2.11.7 --encoded as: -- 0x01021107 -- - Usage: -Usage: -------- -- - New numbers are used as follows: -New numbers are used as follows: -- - 1. major: -1. major: -- - increased when major new functionality becomes available - 2. minor: -2. minor: -- - even: for each new release with new functionality -- - odd : when a new development cycle starts after a release --3. patch: -- - when a development snapshot or release update becomes available -- - all these are announced on lustre-devel@lists.sf.net - 4. test: -4. test: -- - when developers feel it is time to exchange a named version -- - What will run, what won't ? -What will run, what won't ? ----------------------------- -- --1. If the test level is non-zero, i.e. there are 4 digits in the -- version, no guarantees of any kind are made. -- - 2. For three digit releases/tags the code should perform -2. For three digit releases/tags the code should perform -- according to the announcement. -- --Moving tags ------------- -- --The last stable release will be tagged: CVS tag "t_last_stable" --The last operational development snapshot will be CVS tag "dstable" -- --Branches ---------- - - For even minor releases a branch tag will be created. The branch tag - will be of the form: - - bmajor_minor - - Note that the CVS head is where development is going. If developers - use a branch they must eventually merge that back into the head. - Typically this is done by importing changes into the branch and - removing the sticky tags: -- - cvs update -A -Any and all development must be done on branches, and can only merge to the -HEAD if _at_least_ tests/acceptance-small.sh and IOR with 5 SMP nodes and -2 clients/node with 1GB file/client pass without any errors or cleanup -problems. Additional tests may be added in the future, so the tests in the -current CVS head must pass before a branch can be merged back to the trunk. -- - fixing any conflicts and then committing. -See http://lustre.org/docs/branches.html for details on CVS branch usage. diff --cc lustre/doc/chbar.sh index 7825241,7825241..0000000 deleted file mode 100755,100755 --- a/lustre/doc/chbar.sh +++ /dev/null @@@ -1,243 -1,243 +1,0 @@@ --#!/bin/sh --# Gadget to take two LaTeX files and produce a third which --# has changebars highlighting the difference between them. --# --# Version 1.2 --# Author: --# Don Ward, Careful Computing (don@careful.co.uk) --# v1.0 April 1989 --# v1.1 Feb 93 Amended to use changebar.sty (v3.0) and dvips --# v1.2 Aug 95 Added support for LaTeX209/LaTeX2e --# Added RCS support to retrive old files -- --CMD=`basename $0` -- --SED=sed --RM="rm -f" --DIFF=diff --ED=ed --AWK=awk --GREP=grep --MV=mv --CAT=cat --MKDIR=mkdir --CO="co" -- --TMPDIR=${TMP-/tmp}/$CMD.$$ --trap 'test $DEBUG = NO && rm -rf $TMPDIR' 0 1 2 3 6 7 13 15 --mkdir $TMPDIR || { echo "cannot create directory \`$TMPDIR'." >&2; exit 1; } --TMPFILE=${TMPDIR}/$CMD.$$ --SED_CMD_FILE=$TMPFILE.sed -- --usage() --{ --$CAT << _END_ --Usage: -- $CMD [-hgG] [-d dir] old new [output] -- default output is stdout -- -- $CMD [-hgG] [-d dir] old -- new file on stdin, output on stdout -- -- $CMD [-hgG] -d dir -r rev files -- old file retrieved using RCS -- -- Gadget to take two LaTeX files and produce a third which -- has changebars highlighting the difference between them. -- Changebars are inserted for differences after '\begin{document}'. -- -- Feature: \`new' can not be named \`-'. -- -- Options are: -- -d dir : Write the output to file \`dir/new', if \`new' is given or -- to file \`dir/old'. -- If \`dir' does not exist, it is created. -- If \`output' is given, it is discarded. -- -- -r rev : If the LaTeX \`files' are kept under control of the -- Revision Control System RCS, the old files of -- the revision \`rev' can be retrived. -- \`rev' is specified using the RCS conventions. -- This option must be used together with the \`-d dir' option. -- \`files' must be a nonempty list of files. -- -- -h : Print this info text. -- -g : Print some debugging info. -- -G : Even more debug info. -- -- Version 1.2: August 3. 1995 --_END_ --exit 1 --} -- --# parse options and arguments --DEBUG="NO" --DIR= --REV= --# process options --while getopts d:r:gGh i $* --do -- case $i in -- d ) DIR=$OPTARG;; -- r ) REV=$OPTARG;; -- g ) DEBUG="YES" ;; -- G ) set -x; DEBUG="YES";; -- h | \ -- * ) usage ;; -- esac --done -- --shift `expr $OPTIND - 1` -- --case $# in -- 1 ) OLD=$1; NEW="-"; OUT="" ;; -- 2 ) OLD=$1; NEW=$2; OUT="" ;; -- 3 ) OLD=$1; NEW=$2; OUT="$3" ;; -- * ) usage ;; --esac -- --# check correct options --if [ ! -z "$DIR" ] --then -- [ -d $DIR ] || $MKDIR $DIR --fi -- --if [ ! -z "$REV" ] --then -- [ -z "$DIR" ] && usage -- FILES=$* --else -- FILES=$NEW --fi -- --# do the work --for NEW in $FILES --do -- if [ ! -z "$DIR" ] -- then -- if [ $NEW = "-" ] -- then -- OUT=$DIR/$OLD -- else -- OUT=$DIR/$NEW -- fi -- fi -- if [ ! -z "$REV" ] -- then -- OLD=${TMPFILE}.old -- $CO -p"$REV" -q $NEW > $OLD -- fi -- -- [ $DEBUG = "YES" ] && echo "OLD=\`$OLD' NEW=\`$NEW' OUT=\`$OUT'" -- -- # gather some info about the file -- # Since we have for sure only the name of the OLD file, ... -- $GREP "^\\\\begin{document}" $OLD > /dev/null -- if [ $? -eq 0 ] -- then -- [ $DEBUG = "YES" ] && echo "contains a \\begin{document}" -- HAS_BEGIN_DOC="YES" -- else -- [ $DEBUG = "YES" ] && echo "contains no \\begin{document}" -- HAS_BEGIN_DOC="NO" -- fi -- -- # Method to do the work: -- # 1 Use diff to get an ed script to go from file1 to file2. -- # 2 Breath on it a bit (with sed) to insert changebar commands. -- # 3 Apply modified ed script to produce (nearly) the output. -- # 4 Use awk to insert the changebars option into the \documentstyle -- # and to handle changebar commands inside verbatim environments. -- # 5 Remove changebars before \begin{document} with sed -- -- # SED commands to edit ED commands to edit old file -- $CAT > $SED_CMD_FILE <<\_END_ --/^\.$/i\ --\\cbend{}% --/^[0-9][0-9]*[ac]$/a\ --\\cbstart{}% --/^[0-9][0-9]*,[0-9][0-9]*[ac]$/a\ --\\cbstart{}% --/^[0-9][0-9]*d$/a\ --i\ --\\cbdelete{}%\ --. --/^[0-9][0-9]*,[0-9][0-9]*d$/a\ --i\ --\\cbdelete{}%\ --. --_END_ -- -- # note DIFF accepts `-' as stdin -- $DIFF -b -e $OLD $NEW | \ -- ( $SED -f $SED_CMD_FILE ; echo w ${TMPFILE}.1 ; echo q ) | \ -- $ED - $OLD -- -- # AWK commands to insert Changebars style and to protect -- # changebar commands in verbatim environments -- # and to tell what driver is in use; we assume the `dvips' driver -- -- $AWK ' -- BEGIN {kind=""; # we saw now \documentXXX[]{} -- } -- /^\\documentstyle/{ -- kind = "209"; -- if (index($0, "changebar") == 0 ) { -- opts = index($0, "[") -- if (opts > 0) -- printf "%schangebar,%s\n",substr($0,1,opts),substr($0,opts+1) -- else -- printf "\\documentstyle[changebar]%s\n", substr($0,15) -- next -- } -- } -- /^\\documentclass/{ -- kind = "2e"; -- printf "%s\n", $0 -- printf "\\usepackage[dvips]{changebar}\n" -- next -- } -- /\\begin{document}/ {if (kind == "209" ) {print "\\driver{dvips}"}} -- /\\begin{verbatim}/{++nesting} -- /\\end{verbatim}/{--nesting} -- /\\cbstart{}%|\\cbend{}%|\cbdelete{}%/ { -- if ( nesting > 0) { -- # changebar command in a verbatim environment: Temporarily exit, -- # do the changebar command and reenter. -- # -- # The obvious ( printf "\\end{verbatim}%s\\begin{verbatim} , $0 ) -- # leaves too much vertical space around the changed line(s). -- # The following magic seeems to work -- # -- print "\\end{verbatim}\\nointerlineskip" -- print "\\vskip -\\ht\\strutbox\\vskip -\\ht\\strutbox" -- printf "\\vbox to 0pt{\\vskip \\ht\\strutbox%s\\vss}\n", $0 -- print "\\begin{verbatim}" -- next -- } -- } -- { print $0 } -- ' ${TMPFILE}.1 > ${TMPFILE}.2 -- -- # if a \begin{document} is contained in the file, -- # remove the changebar commands before them -- -- if [ $HAS_BEGIN_DOC = "YES" ] -- then -- SED_CMD="1,/\\\\begin{document}/s/\(\\\\cb[sed][tne][adl][^{}]*{}%\)$/%%\1/" -- $SED "$SED_CMD" ${TMPFILE}.2 > ${TMPFILE}.3 -- else -- $CAT ${TMPFILE}.2 > ${TMPFILE}.3 -- fi -- if [ -z "$OUT" ] -- then -- $CAT ${TMPFILE}.3 -- else -- $MV ${TMPFILE}.3 $OUT -- fi -- --done -- --[ $DEBUG = "NO" ] && $RM ${TMPFILE}.* -- --############################################################### diff --cc lustre/doc/lconf.lyx index 0095c6f,0095c6f..0000000 deleted file mode 100644,100644 --- a/lustre/doc/lconf.lyx +++ /dev/null @@@ -1,133 -1,133 +1,0 @@@ --#LyX 1.2 created this file. For more info see http://www.lyx.org/ --\lyxformat 220 --\textclass amsart --\language english --\inputencoding auto --\fontscheme times --\graphics default --\paperfontsize default --\spacing single --\papersize letterpaper --\paperpackage a4 --\use_geometry 0 --\use_amsmath 0 --\use_natbib 0 --\use_numerical_citations 0 --\paperorientation portrait --\secnumdepth 3 --\tocdepth 3 --\paragraph_separation skip --\defskip medskip --\quotes_language english --\quotes_times 2 --\papercolumns 1 --\papersides 1 --\paperpagestyle default -- --\layout Section -- --lconf --\layout Subsection -- --NAME --\layout Standard -- --lconf- Lustre file system configuration utility --\layout Subsection -- --SYNOPSIS --\layout Standard -- -- --\series bold --lconf\SpecialChar ~ --[--node ] [-d,--cleanup] [--noexec] [--gdb] [--nosetup] -- [--nomod] [-n,--noexec] [-v,--verbose] [-h,--help] --\layout Subsection -- --DESCRIPTION --\layout Standard -- --This program configures a node following directives in the --\layout Description -- ----node\SpecialChar ~ --node_name Specifiy a specific node to configure. -- By default, LCONF will search for nodes with the local hostname and 'localhost'. -- When --node is used, only node_name is searched for. -- If a matching node is not found in the config, then LCONF exits with an -- error. --\layout Description -- ----cleanup Unconfigure a node. -- The same config and --node argument used for configuration needs to be -- used for cleanup as well. -- This will attempt to undo all of the configuration steps done by LCONF, -- including unloading the kernel modules. --\layout Description -- ----noexec Print, but don't execute, the steps lconf will perform. -- This is useful for debugging a configuration, and when used with --node, -- can be run on any host. --\layout Description -- ----gdb Causes LCONF to print a message and pause for 5 seconds after creating -- a gdb module script and before doing any lustre configuration. -- (The gdb module script is always created, however.) --\layout Description -- ----nosetup Only load modules, do not configure devices or services --\layout Description -- ----nomod Only setup devices and services, do not load modules --\layout Description -- ----noexec,-n Don't do anything, but print what would happen. --\layout Description -- ----verbose,-v Be verbose and show actions while going along --\layout Description -- ---h,--help Print help. --\layout Description -- ----maxlevel\SpecialChar ~ -- [NOT IMPLEMENTED] Perform configuration of devices and -- services up to level given. -- --\emph on --level --\emph default -- can take the values --\series bold --net, dev, svc, fs. -- --\series default --When used in conjunction with cleanup services are torn down up to a certain -- level. --\layout Subsection -- --EXAMPLES --\layout Standard -- --On client nodes this is typically invoked as --\layout LyX-Code -- --lconf --node client config.xml --\layout Standard -- --in order to give clients, regardless of hostname a single configuration. --\layout Subsection -- --BUGS --\layout Standard -- --None are known. --\layout Subsection -- --AUTHOR --\layout Standard -- --Cluster File Systems, Inc. -- 2002 - created --\the_end diff --cc lustre/doc/lctl.lyx index 154b646,154b646..0000000 deleted file mode 100644,100644 --- a/lustre/doc/lctl.lyx +++ /dev/null @@@ -1,540 -1,540 +1,0 @@@ --#LyX 1.2 created this file. For more info see http://www.lyx.org/ --\lyxformat 220 --\textclass amsart-plain --\language english --\inputencoding auto --\fontscheme times --\graphics default --\paperfontsize default --\spacing single --\papersize letterpaper --\paperpackage a4 --\use_geometry 0 --\use_amsmath 0 --\use_natbib 0 --\use_numerical_citations 0 --\paperorientation portrait --\secnumdepth 3 --\tocdepth 3 --\paragraph_separation skip --\defskip medskip --\quotes_language english --\quotes_times 2 --\papercolumns 1 --\papersides 1 --\paperpagestyle default -- --\layout Section -- --LCTL --\layout Subsection -- --NAME --\layout Standard -- --lctl - low level Lustre file system configuration utility --\layout Subsection -- --SYNOPSIS --\layout Standard -- -- --\series bold --lctl --\layout Standard -- -- --\series bold --lctl\SpecialChar ~ ----device\SpecialChar ~ -- --\layout Standard -- -- --\series bold --lctl\SpecialChar ~ ----threads\SpecialChar ~ --\SpecialChar ~ --\SpecialChar ~ --\SpecialChar ~ -- --\layout Subsection -- --DESCRIPTION --\layout Standard -- --The program can be invoked in interactive mode by issuing --\series bold --lctl. -- --\series default -- After that commands are issued as below. -- The most common commands in lctl are (in matching pairs) --\family typewriter --device --\family default --, --\family typewriter --attach --\family default -- and --\family typewriter --detach --\family default --, --\family typewriter --setup --\family default -- and --\family typewriter --cleanup --\family default --, --\family typewriter --connect --\family default -- and --\family typewriter --disconnect --\family default --, --\family typewriter --help --\family default --, and --\family typewriter --quit --\family default --. -- To get a complete listing of available commands, type --\family typewriter --help --\family default -- at the lctl prompt. -- To get basic help on the meaning and syntax of a command, type --\family typewriter --help command --\family default --. -- Command completion is activated with the --\family typewriter --TAB --\family default -- key, and command history is available via the up- and down-arrow keys. -- --\layout Standard -- --For non-interactive single threaded use, one uses the second invocation -- which runs --\emph on --command --\emph default -- after connecting to the --\emph on --device. -- --\emph default -- --\layout Description -- ----device The device number to be used for the operation. -- The value of devno is an integer, normally found by calling --\emph on --lctl name2dev --\emph default --on a device name. -- --\layout Description -- ----threads How many threads should be forked doing the command specified. -- The numthreads variable is a strictly positivie integer indicating how -- many threads should be started. -- Verbose can take values , --\emph on --devno --\emph default --is used as above. --\layout LyX-Code -- --\layout LyX-Code -- --\layout Description -- --network\SpecialChar ~ --config --\begin_deeper --\layout Description -- --network\SpecialChar ~ -- Indicate what kind of network applies for the -- configuration commands that follow --\layout Description -- --connect\SpecialChar ~ --[[\SpecialChar ~ --]\SpecialChar ~ --|\SpecialChar ~ --] This will establish a connection to -- a remote network network id given by the hostname/port combination or the -- elan id --\layout Description -- --disconnect\SpecialChar ~ -- Disconnect from a remote nid --\layout Description -- --mynid\SpecialChar ~ --[nid] Informs the socknal of the local nid. -- It defaults to hostname for tcp networks and is automatically setup for -- elan/myrinet networks --\layout Description -- --add_uuid\SpecialChar ~ --\SpecialChar ~ -- Associate a given UUID with an --\emph on --nid --\emph default -- --\layout Description -- --close_uuid\SpecialChar ~ -- Disconnect a UUID --\layout Description -- --del_uuid\SpecialChar ~ -- Delete a UUID association --\layout Description -- --add_route\SpecialChar ~ --\SpecialChar ~ --\SpecialChar ~ --[target] Add an entry to the routing table for -- the given target --\layout Description -- --del_route\SpecialChar ~ -- Delete an entry for the target from the routing table --\layout Description -- --route_list Print the complete routing table --\layout Description -- --recv_mem\SpecialChar ~ --[size] Set the socket receive buffer size, if the size is omited -- the default size for the buffer is printed --\layout Description -- --send_mem\SpecialChar ~ --[size] Set send buffer size for the socket, if size is omited the -- default size for the buffer is printed --\layout Description -- --nagle\SpecialChar ~ --[on/off] Enable/disable nagle, omiting the arguement will cause the -- default value to be printed --\end_deeper --\layout Description -- --device\SpecialChar ~ --selection --\begin_deeper --\layout Description -- --newdev Create a new device --\layout Description -- --name2dev This command can be used to determine a device number for the given -- device name. --\layout Description -- --device This will select the specified OBD device. -- All other commands depend on the device being set. -- --\layout Description -- --device_list Show all the devices --\end_deeper --\layout Description -- --device\SpecialChar ~ --config --\begin_deeper --\layout Description -- --attach\SpecialChar ~ --type\SpecialChar ~ --[name\SpecialChar ~ --[uuid]] --\shape italic --Attach --\shape default -- a type to the current device (which you need to set using the --\family typewriter --device --\family default -- command) and give that device a name and UUID. -- This allows us to identify the device for use later, and also tells us -- what type of device we will have. --\layout Description -- --setup\SpecialChar ~ -- Type specific device setup commands. -- For obdfilter a setup command tells the driver which block device it should -- use for storage and what type of filesystem is on that device. -- --\layout Description -- --cleanup Cleanup a previously setup device --\layout Description -- --detach Remove driver (and name and uuid) from the current device --\layout Description -- --lov_setconfig\SpecialChar ~ --lov-uuid\SpecialChar ~ --default-stripe-count\SpecialChar ~ --default-stripe-size\SpecialChar ~ --offset\SpecialChar ~ --pattern\SpecialChar ~ --UUID1\SpecialChar ~ --[U --UID2...] Write LOV configuration to an MDS device --\layout Description -- --lov_getconfig\SpecialChar ~ --lov-uuid Read LOV configuration from an MDS device. -- Returns default-stripe-count, default-stripe-size, offset, pattern, and -- a list of OST UUIDs. --\end_deeper --\layout Description -- --device\SpecialChar ~ --operations --\begin_deeper --\layout Description -- --probe\SpecialChar ~ --[timeout] Build a connection handle to a device. -- This command is used to suspend configuration till the lctl command has -- ensured that the mds and osc services are available. -- This is to avoid mount failures in a reebooting cluster --\layout Description -- --close --\layout Description -- --getattr\SpecialChar ~ -- Get attributes for an OST object --\layout Description -- --setattr\SpecialChar ~ --\SpecialChar ~ -- Set mode attribute for OST object --\layout Description -- --create\SpecialChar ~ --[num\SpecialChar ~ --[mode\SpecialChar ~ --[verbose]]] Create the specified number of OST objects -- with the given --\layout Description -- --destroy\SpecialChar ~ -- Destroy an OST object --\layout Description -- --test_getattr\SpecialChar ~ --\SpecialChar ~ --[verbose\SpecialChar ~ --[[t]objid]] Do getattrs on OST object -- (objectid+1 on each thread) --\layout Description -- --test_brw\SpecialChar ~ --[t]\SpecialChar ~ --[write\SpecialChar ~ --[verbose\SpecialChar ~ --[npages\SpecialChar ~ --[[t]objid]]]] Do bulk read/writes -- on OST object ( per I/O) --\layout Description -- --test_ldlm Perform lock manager test --\layout Description -- --ldlm_regress_start\SpecialChar ~ --%s\SpecialChar ~ --[numthreads\SpecialChar ~ --[refheld\SpecialChar ~ --[numres\SpecialChar ~ --[numext]]]] Start lock manager -- stress test --\layout Description -- --ldlm_regress_stop Stop lock manager stress test --\layout Description -- --dump_ldlm Dump all lock manager state, this is very useful for debugging --\layout Description -- --newconn\SpecialChar ~ --\SpecialChar ~ --[newuuid] --\end_deeper --\layout Description -- --debug --\begin_deeper --\layout Description -- --debug_kernel\SpecialChar ~ --[file]\SpecialChar ~ --[raw] Get debug buffer and dump to a fileusage --\layout Description -- --debug_file\SpecialChar ~ --\SpecialChar ~ --[output]\SpecialChar ~ --[raw] Read debug buffer from input and dump to -- outputusage --\layout Description -- --clear Clear kernel debug buffer --\layout Description -- --mark\SpecialChar ~ -- Insert marker text in kernel debug buffer --\layout Description -- --filter\SpecialChar ~ -- Filter message type from the kernel debug -- buffer --\layout Description -- --show\SpecialChar ~ -- Show specific type of messages --\layout Description -- --debug_list\SpecialChar ~ -- List all the subsystem and debug types --\layout Description -- --panic Force the kernel to panic --\end_deeper --\layout Description -- --control --\begin_deeper --\layout Description -- --help Show a complete list of commands, help can be used to -- get help on specific command --\layout Description -- --exit Close the lctl session --\layout Description -- --quit Close the lctl session --\end_deeper --\layout Subsection -- --EXAMPLES --\layout Description -- --attach --\layout LyX-Code -- --# lctl --\newline --lctl > newdev --\newline --lctl > attach obdfilter OBDDEV OBDUUID --\layout Description -- --connect --\layout LyX-Code -- --lctl > name2dev OSCDEV --\newline --2 --\newline --lctl > device 2 --\newline --lctl > connect --\newline -- --\layout Description -- --getattr --\layout LyX-Code -- --lctl > getattr 12 --\newline --id: 12 --\newline --grp: 0 --\newline --atime: 1002663714 --\newline --mtime: 1002663535 --\newline --ctime: 1002663535 --\newline --size: 10 --\newline --blocks: 8 --\newline --blksize: 4096 --\newline --mode: 100644 --\newline --uid: 0 --\newline --gid: 0 --\newline --flags: 0 --\newline --obdflags: 0 --\newline --nlink: 1 --\newline --valid: ffffffff --\newline --inline: --\newline --obdmd: --\newline --lctl > disconnect --\newline --Finished (success) --\layout Description -- --setup --\layout LyX-Code -- --lctl > setup /dev/loop0 extN --\newline --lctl > quit --\layout LyX-Code -- --\layout Subsection -- --BUGS --\layout Standard -- --None are known. --\layout Subsection -- --AUTHOR --\layout Standard -- --Cluster File Systems, Inc. -- 2002 - created --\the_end diff --cc lustre/doc/lmc.lyx index 39e602f,39e602f..0000000 deleted file mode 100644,100644 --- a/lustre/doc/lmc.lyx +++ /dev/null @@@ -1,310 -1,310 +1,0 @@@ --#LyX 1.2 created this file. For more info see http://www.lyx.org/ --\lyxformat 220 --\textclass amsart --\language english --\inputencoding auto --\fontscheme times --\graphics default --\paperfontsize default --\spacing single --\papersize letterpaper --\paperpackage a4 --\use_geometry 0 --\use_amsmath 0 --\use_natbib 0 --\use_numerical_citations 0 --\paperorientation portrait --\secnumdepth 3 --\tocdepth 3 --\paragraph_separation skip --\defskip medskip --\quotes_language english --\quotes_times 2 --\papercolumns 1 --\papersides 1 --\paperpagestyle default -- --\layout Section -- --lmc --\layout Subsection -- --NAME --\layout Standard -- --lmc - lustre configuration maker. --\layout Subsection -- --SYNOPSIS --\layout Standard -- -- --\series bold --lmc [options] --add [args] --\layout Standard -- -- --\series bold --NOT IMPLEMENTED -- lmc [options] --remove [args] --\layout Standard -- -- --\series bold --NOT IMPLEMENTED -- lmc [options] --convert [args] --\layout Subsection -- --DESCRIPTION --\layout Standard -- --At present lmc when invoked adds configuration data to the config file. -- lmc will also be able to remove configuration data or convert its forma. -- One generates a single config file for the cluster at present including -- at the minimum mds's, mtpt's and ost's and whatever those reference (e.g. -- net's and profiles) --\layout Standard -- --The objecttype refers to a collection of related configuration entities -- and can be one of --\series bold --net, mds, lov, ost, mtpt, route, oscref. -- --\series default --We describe the arguments required for the addition of each objecttype. -- [NOT implemented] Lmc can also remove items from or convert the format -- of configuration data. --\layout Standard -- --to generate configuration data associated with systems in a Lustre cluster. -- --\layout Description -- ----add\SpecialChar ~ --net Adds a network device descriptor for the given node, with parameters -- as indicated. --\begin_deeper --\layout Standard -- --The arguments required are --\layout Description -- ----node\SpecialChar ~ --''node_name'' If not present this will create a new node with the -- given name. -- This is also used to specify a specific node for other elements, and the --\layout Description -- ----nettype\SpecialChar ~ -- this can be --\series bold --tcp, elan, gm --\layout Description -- ----nid\SpecialChar ~ --nid the network id, e.g. -- ElanID or IP address as used by portals. -- If host_name is '*', then the local address while be substituted when the -- node is configured with lconf. --\layout Description -- ----router optional flag to mark this node as a router --\layout Description -- ----profile optional flag to mark this node as a profile node. -- This is automatically true if the the --nid argument contains a '*'. --\layout Description -- ----port\SpecialChar ~ --[port] optional argument to indicate the tcp port. -- The default is 988. -- --\layout Description -- ----tcpbuf\SpecialChar ~ -- optional argument --\end_deeper --\layout Description -- ----add\SpecialChar ~ --mds --\begin_deeper --\layout Description -- ----mds\SpecialChar ~ -- --\layout Description -- ----device\SpecialChar ~ -- --\layout Description -- ----size\SpecialChar ~ -- optional argument indicating the size of the device to be created -- (used typically for loop devices). --\layout Description -- ----node\SpecialChar ~ -- Adds an MDS to the specified node. -- This requires a --node argument, and it must not be a profile node. --\end_deeper --\layout Description -- ----add\SpecialChar ~ --lov Creates an LOV with the specified parameters. -- The mds_name must already exist in the descriptor. --\begin_deeper --\layout Description -- ----lov_ --\layout Description -- ----mds_ --\layout Description -- ----stripesize\SpecialChar ~ -- --\layout Description -- ----stripecount\SpecialChar ~ -- --\layout Description -- ----pattern\SpecialChar ~ -- Pattern can be 0. --\end_deeper --\layout Description -- ----add\SpecialChar ~ --ost Creates an OBD, OST, and OSC. -- The OST and OBD are created on the specified node. --\begin_deeper --\layout Description -- ----ost\SpecialChar ~ -- [NOT IMPLEMENTED] Name to give to this OST target. --\layout Description -- ----node\SpecialChar ~ -- Node on which the OST service is run, can not be a profile -- node. --\layout Description -- ----device\SpecialChar ~ -- --\layout Description -- ----size\SpecialChar ~ --[size] --\layout Description -- ----lov\SpecialChar ~ -- Name of LOV to which this OSC will be attached. -- --\layout Description -- ----obduuid\SpecialChar ~ --UUID specify the UUID of the OBD device. -- The default value is OBD_nodename_UUID. --\end_deeper --\layout Description -- ----add\SpecialChar ~ --mtpt Creates a mount point on the specified node. -- Either an LOV or OSC name can be used. --\begin_deeper --\layout Description -- ----node\SpecialChar ~ --node node or profile node that will use the mtpt --\layout Description -- ----path\SpecialChar ~ --/mnt/path\SpecialChar ~ -- --\layout Description -- ----mds\SpecialChar ~ --mds_name --\layout Description -- ----mdc\SpecialChar ~ --lov_name|osc_name --\end_deeper --\layout Description -- ----add\SpecialChar ~ --route Creates a static route through a gateway to a specific nid or -- a range of nids. --\begin_deeper --\layout Description -- ----node\SpecialChar ~ --node node or profile node to add the route to --\layout Description -- ----gw\SpecialChar ~ --nid the nid of the gateway (must be a local interface or a peer) --\layout Description -- ----tgt\SpecialChar ~ --nid for a specific route, this is the target nid --\layout Description -- ----lo\SpecialChar ~ --nid for a range route, this is the lo value nid --\layout Description -- ----hi\SpecialChar ~ --nid for a range route, this is the hi value nid --\end_deeper --\layout Description -- ----add\SpecialChar ~ --oscref Adds an OSC reference to a node. -- This is only necessary when the the OSC will be used without a mountpoint. --\begin_deeper --\layout Description -- ----node\SpecialChar ~ --node node or profile node to add the OSC ref to --\layout Description -- ----osc\SpecialChar ~ --osc_name Name of the OSC to add a reference to. -- The --add ost command automatically creates the OSC, and the name will -- be OSC_, where node is the name of node the OST is on. --\end_deeper --\layout Description -- --Options: --\begin_deeper --\layout Description -- ----output\SpecialChar ~ --filename Sends output to the file. -- If the file exists, it will be overwritten. --\layout Description -- ----merge\SpecialChar ~ --filename Add the new element to an existing file. -- --\end_deeper --\layout Subsection -- --EXAMPLES --\layout Standard -- --Real life examples are given in the lustre-conf man page. --\layout Subsection -- --BUGS --\layout Standard -- --None are known. --\layout Subsection -- --AUTHOR --\layout Standard -- --Cluster File Systems, Inc. -- 2002 - created --\the_end diff --cc lustre/doc/postbar index 349d41c,349d41c..0000000 deleted file mode 100755,100755 --- a/lustre/doc/postbar +++ /dev/null @@@ -1,151 -1,151 +1,0 @@@ --#! /usr/bin/perl --# postbar - Massage chbar.sh output into valid LaTeX --# Copyright (C) 2002 Cluster File Systems, Inc. --# Gord Eagle , 2002-08-10 -- --my $progname = $0; --$progname =~ s|^.*/||; --my $CHANGE_ENVIRONMENT = '\\\\(begin|end)\\{([^\\}]+)\\}'; --my (@envname, @envdepth, @envbuf); --my $phony_preamble = 0; --my $cbdepth = 0; --my $cbfound = 0; -- --# Tell whether an environment cannot have arbitrary changebars. --sub fragile_environment --{ -- my ($env) = @_; -- return $env ne 'document'; --} -- -- --# Tell whether we can hava arbitrary stuff. --sub toplevel --{ -- my ($env) = @_; -- return $env eq 'document'; --} -- -- --sub out --{ -- my (@msg) = @_; -- if ($#envbuf < 0 || toplevel($envname[0])) { -- print @msg; -- } else { -- $envbuf[0] .= join('', @msg); -- } --} -- -- --# Leave an environment. --sub end_environment --{ -- my ($env) = @_; -- -- #out("%$progname end $env\n"); -- if ($envname[0] ne $env) { -- die "Expecting \\end{$envname[0]} but got \\end{$env}\n"; -- } -- -- if ($cbfound) { -- # Did we find a changebar? -- $cbfound = !toplevel($envname[1]); -- if (!$cbfound) { -- # We found one, and the parent environment is the top level. -- if ($cbdepth == $envdepth[0]) { -- # There was no change in depth, so mark the environment. -- $envbuf[0] = "\\cbstart{}%$progname\n" . $envbuf[0]; -- out("\\cbend{}%$progname\n"); -- } elsif ($envdepth[0] > $cbdepth) { -- # There were more ends in the environment, so append them. -- for (my $i = 0; $i < $envdepth[0] - $cbdepth; $i ++) { -- out("\\cbend{}%$progname\n"); -- } -- } else { -- # There were more starts, so prepend them. -- my $starts; -- for (my $i = 0; $i < $cbdepth - $envdepth[0]; $i ++) { -- $starts .= "\\cbstart{}%$progname\n"; -- } -- $envbuf[0] = $starts . $envbuf[0]; -- } -- } -- } -- -- # Drop the environment from the list. -- shift(@envname); -- shift(@envdepth); -- out(shift(@envbuf)); --} -- -- --while ($_ = ) { -- chomp; -- my $env; -- if (!/\\begin.*\\end/ && /$CHANGE_ENVIRONMENT/o) { -- $env = $2; -- if ($1 eq 'begin') { -- # Enter the new environment. -- unshift(@envname, $env); -- unshift(@envdepth, $cbdepth); -- unshift(@envbuf, ''); -- #out("%$progname depth=$cbdepth, $#envname ($env)\n"); -- } elsif (!$phony_preamble) { -- out("$_\n"); -- end_environment($env); -- next; -- } -- } -- -- if ($#envname >= 0 && /^\\documentclass/) { -- $phony_preamble = 1; -- } -- -- if ($phony_preamble) { -- # Comment out and ignore the redundant preambles. -- out("%$progname $_\n"); -- $phony_preamble = 0 if ($env eq 'document'); -- next; -- } elsif ($#envname >= 0) { -- # Track the current changebar depth. -- if (/^\\cbstart/) { -- $cbdepth ++; -- if (!toplevel($envname[0])) { -- $cbfound = 1; -- out("%$progname $_\n"); -- next; -- } -- } elsif (/^\\cbend/) { -- if ($cbdepth == 0) { -- die "$progname: Too many \\cbend{}s\n"; -- } -- $cbdepth --; -- if (!toplevel($envname[0])) { -- $cbfound = 1; -- out("%$progname $_\n"); -- next; -- } -- } elsif (/^\\cbdelete/ && fragile_environment($envname[0])) { -- # What to do with delete bars? -- out("%$progname $_\n"); -- next; -- } -- out("$_\n"); -- } else { -- out("$_\n"); -- # Add the options to the usepackage. -- if (/^\\usepackage.*\{changebar\}$/) { -- # Prevent PostScript dictionary overflow errors. -- out("\\def\\cb\@maxpoint{15}\n"); -- -- # Show the bars. -- out("\\outerbarstrue\n"); -- } -- } -- -- if (defined($env)) { -- } --} -- --exit(0); diff --cc lustre/doc/tex2pdf index d9a7176,d9a7176..0000000 deleted file mode 100755,100755 --- a/lustre/doc/tex2pdf +++ /dev/null @@@ -1,3043 -1,3043 +1,0 @@@ --#!/usr/bin/perl -w -- --# tex2pdf - script for translating latex docs to pdf --# --# Copyright (C) 2000-2002 by Steffen Evers and others --# --# This program is free software; you can redistribute it and/or modify --# it under the terms of the GNU General Public License version 2 as --# published by the Free Software Foundation. --# --# 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. --# --# 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., 675 Mass Ave, Cambridge, MA 02139, USA. --# --# The GNU General Public License is also available online: --# http://www.gnu.org/licenses/gpl.html --# --# Thanks a lot to all the people that have already contributed to this project! --# --# The changelog including the credits has become too long. So, I have removed it --# from the script, but it is still available online (see below). --# --# Special thanks to the following people for their contribution --# (see the changelog for details): --# Matej Cepl, Herbert Voss, Nicolas Marsgui, Bruce Foster, Mark van Rossum, --# Matt Bandy, Garrick Chien Welsh, Stacy J. Prowell, Pavel Sedivy, --# Holger Daszler, Olaf Gabler, Ahmet Sekercioglui, Richard, Steffen Macke, --# Rainer Dorsch & friends, Jean-Pierre Chretien, Fernando Perez, --# Ha Duong Minh, Oscar Lopez --# --# Project Homepage: http://tex2pdf.berlios.de --# Developer Homepage: http://developer.berlios.de/projects/tex2pdf --# Mailing lists: http://developer.berlios.de/mail/?group_id=57 --# Changelog: http://tex2pdf.berlios.de/changelog.html --# --# Anyone is invited to help to improve tex2pdf. Therefore any kind of feedback --# is welcome. Maybe you even would like to hack the code and send us your --# changes. This would help a lot and is highly appreciated. Think about it :-) --# Subscribing to the developer mailing list might be a first step (see above). --# --# Send feedback to: tex2pdf-devel@lists.berlios.de --# -- --######## Imports -- --use File::Basename; --use File::Copy; --use Getopt::Long; --use Sys::Hostname; --use Cwd; --use strict; -- --####### global variables -- --my $MYRELEASE="3.0.21"; --my $MYHOSTNAME=hostname; --my $MYNAME=basename $0; --my $MYUSER=$ENV{'USER'}; --my $USER_HOME=$ENV{'HOME'}; --if (not $MYUSER) { $MYUSER = 'nobody'; } --if (not $USER_HOME) { $USER_HOME = '/tmp'; } -- --my @TMPFILES=(); --my @TMP_TEX_FILES=(); --my $NUM_PARAM_MIN=0; --my $NUM_PARAM_MAX=9; --my @REF_DOCS; --my $MTP_PREAMBLE_FILENAME="preamble.cfg"; --my $MTP_TMP_BASESUFFIX="-mp"; --my @EPS_SUFFIXES=('eps','ps','ps.gz','eps.gz' ); --my $PDF_ORIG_SUFFIX='pdf.orig'; --my @BITMAP_SUFFIXES=( 'jpg', 'png', 'tif' ); -- --# (initial) log file of this script --# this log file will be moved to the specified log_dir after configuration --# and the variable will be updated to the new name --my $MYLOGFILE="$USER_HOME/tex2pdf-$$.log"; --my $LOGFILE_VERBOSITY=9; -- --### text token for no value --my $NIL="NOVALUE"; --my $UNDEF="undefined"; -- --### token for boolean 'false', 'no' --my $NO="no"; --my $FALSE=0; -- --### token for boolean 'true', 'yes' --my $YES="yes"; --my $TRUE=1; -- --### file to store private parameters --# If you only want to change your private parameters change them there --# default: $HOME/.tex2pdf3rc --my $RC_FILENAME="$USER_HOME/.tex2pdf3rc"; --my $MYRCFILE_VERSION=7; --my $RCVERSION_STRING="rcfile_version"; -- --## set global variable configured to prevent access to configuration --# parameters before configuration process is finished --my $CONFIGURED=$FALSE; --my $PRE_CONFIG_VERBOSITY=4; -- --########################## NEW PERL CONFIGURATON -- --my %CONFIGURATION = (); --my %PARAMETER_LIST = (); --my @PARAMETER_ORDER = (); --my %PARAMETER_TYPES = (); -- --## Array index for the various information in each parameter specifcation --## referenced by %PARAMETER_LIST --my $TYPE=0; --my $OPT_ALIAS=1; --my $OPT_SPEC=2; --my $DEF_VALUE=3; --my $DESCRIPTION=4; --my $QUESTION=5; --my $EXPLANATION=6; -- --&add_param_type('paper', -- [ ['a4paper' , 'a4 paper' ], -- [ 'letterpaper', 'letter paper' ], -- [ 'legalpaper', 'legal paper' ], -- [ 'executivepaper', 'executive paper' ], -- [ $NIL, 'do not set value - leave it to hyperref' ] -- ] ); -- --&add_param_type('color', -- [ [ 'yellow', 'LaTeX color yellow' ], -- [ 'red', 'LaTeX color red' ], -- [ 'green', 'LaTeX color green' ], -- [ 'cyan', 'LaTeX color cyan' ], -- [ 'blue', 'LaTeX color blue' ], -- [ 'magenta', 'LaTeX color magenta' ], -- [ 'black', 'LaTeX color black' ], -- [ $NIL , 'do not set this value - leave it to hyperref' ] -- ] ); -- --&add_param_type('destination', -- [ [ 'source', 'directory of the LaTeX source document' ] , -- [ 'input', 'root directory of referenced material' ], -- [ 'custom', 'custom directory as specified' ] -- ] ); -- --### Option parameters: these parameters have no default value and can not --# be configured interactively, but only as a command line option --# an option parameter is not allowed to have a default value, question or --# explanation --# and all parameter of type action are treated as option parameters --# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation -- --&add_param('help', 'action', undef, '|h', '', -- 'print a short help text and exit'); -- --&add_param('version', 'action', undef, '|v', '', -- 'print the version of this script and exit'); -- --&add_param('print_config', 'action', undef, '|o', '', -- 'print the current configuration and exit'); -- --&add_param('configure', 'action', undef, '|c', '', -- 'configure all parameters interactivly, store them and exit'); -- --&add_param('title', 'text', undef, '|t', '=s', -- 'set PDF info title for specified document'); -- --&add_param('author', 'text', undef, '|a', '=s', -- 'set PDF info author for specified document'); -- --&add_param('input_path', 'directory', undef, '', '=s', -- 'set path for referenced material in main document'); -- --### Full parameters --# parameter type action is not allowed --# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation -- --&add_param('logdir', 'directory',"$USER_HOME/tex2pdf-log/", '', '=s', -- 'set directory for saving log files', -- 'What log directory should be used?', -- "The log directory is used to store information about the generation\n" -- ."process for later review, e.g. for debugging."); -- --&add_param('lyxrc_path', 'directory', "$USER_HOME/.lyx/", '', '=s', -- 'set the configuration directory of LyX', -- 'What is the directory for your LyX configuration data?', -- "If I have to generate a LateX file from a LyX file I need to clear two " -- ."temporary\nfiles in your LyX configuration directory. They will " -- ."be backuped and normally\ndo not contain any valuable data anyway. If " -- ."you do not use LyX, simply leave\nthe default."); -- --&add_param('lyx_exec', 'text', "lyx", '', '=s', -- 'specify the LyX executable for converting lyx to latex', -- 'Which executable should I use for converting LyX docs to LaTeX?', -- "I use LyX to generate a LateX file from a LyX file. As you might use\n" -- ."several versions of LyX at the same time or do not have it in your path" -- ."\nyou can give me the apropriate executable here (e.g. '/usr/bin/lyx')." -- ."\nIn most cases the default 'lyx' should be fine."); -- --&add_param('debug', 'bool', $NO, '', '!', --'do not delete temporary files after execution and be as verbose as possible', -- 'Do you want to debug this script?', -- "I will not remove any temporary files. This could cause problems on a " -- ."second\nexecution as I might refuse to overwrite these files for security " -- ."reasons.\nYou have to remove them manually in this case. Additionally, I " -- ."will provide\nas much information during execution as possible."); -- --&add_param('delete_pdf_images', 'bool', $NO, '', '!', -- 'delete generated PDF image files after execution', -- 'Should generated PDF image files be deleted after execution?', -- "Pdflatex cannot handle EPS images. Therefore all such images need to be\n" -- ."translated to PDF in advance. After a successful generation of the final " -- ."PDF \ndocument or after encountering an error I could leave this PDF " -- ."images for\n later executions or simply delete them."); -- --&add_param('clean_on_abort', 'bool', $YES, '', '!', -- 'also delete temporary files after abort', -- 'Should temporary files be deleted when aborting?', -- "When the generation of the PDF file fails for some reason you might still " -- ."want\nto keep already generated temporary files for some reason, e.g. " -- ."debugging.\nIf you do not want to keep them set this parameter to 'yes'."); -- --&add_param('tmp_base_suffix', 'text', '-pdf', '', '=s', -- 'specify the extension of the basename for temporary TeX files', -- 'What string should be used as basename suffix for temporary files?', -- "I have to find names for my temporary files. Therefore I construct a new " -- ."name\nfrom the original filename and this string. Me and various called " -- ."applications\nwill then create several files with this constructed " -- ."basename and different\nextensions. When cleaning up I will simple " -- ."delete all files with the\nconstructed basenames I have used."); -- --&add_param('overwrite', 'bool', $NO, '', '!', -- 'ignore existence of files with same basename as temporary TeX files', -- 'Should I overwrite existing (temporary) files?', -- "In spite of the precaution with the appended base suffix, there still " -- ."might\nexist files with an identical basename. If you set this option I " -- ."will consider\nsuch files as old temporary files and overwrite them " -- ."during generation.\nHowever, I will not remove any files with this " -- ."constructed basename on the\nclean up. You have to remove them manually."); -- --&add_param('clean_logs', 'bool', $YES, '|l', '!', -- 'delete all log files in log directory before execution', -- 'Should the old log files be removed before execution?', -- "I can remove old log files prior to execution. However, you might " -- ."experience\nproblems if you run the script on several documents at the " -- ."same time. If you\nwant to be on the safe side, answer '$NO'. Than you " -- ."have to remove the logs\nmanually from time to time."); -- --&add_param('check_commands', 'bool', $YES, '', '!', -- 'make sure that required shell commands does exist before start', -- 'Should I look for required executables?', -- "As I use several different applications for PDF generation you might want " -- ."to \nmake sure that they are available before the real work starts."); -- --&add_param('destination', 'destination', 'source', '', '=s', -- 'specifiy final location of generated PDF document', -- 'Where should I store the resulting PDF document?', -- "Depending on the application that starts this script (or you if you call " -- ."it\ndirectly) you might want to have the resulting PDF document located " -- ."at\ndifferent places."); -- --&add_param('custom_path', 'directory', $USER_HOME.'/', '|d', '=s', -- "specify custom path for 'destination' parameter", -- 'What custom directory should be used?', -- "When ever you specifiy to store the generated PDF document (command line " -- ."or\nconfiguration) in a custom directory I will put it here."); -- --&add_param('colorlinks', 'three', $YES, '', '!', -- 'activate colored links in PDF doc (hyperref)', -- 'Should colors be used for links?', -- "I can use different colors for links inside the PDF document.\nYou can " -- ."use '$UNDEF' to tell me that you would like to leave this up to\n" -- ."independent hyperref configuration."); -- --&add_param('paper', 'paper', 'a4paper', '|p', '=s', -- 'specify papersize of the PDF doc (hyperref)', -- 'What papersize should be used?', -- "I can set the papersize of the resulting PDF document"); -- --&add_param('citecolor', 'color', 'blue', '', '=s', -- 'specify color of citations in PDF doc (hyperref)', -- 'What color should be used for citation?', ""); -- --&add_param('urlcolor', 'color', 'blue', '', '=s', -- 'specify color of URLs in PDF doc (hyperref)', -- 'What color should be used for URLs?', ""); -- --&add_param('linkcolor', 'color', 'blue', '', '=s', -- 'specify color of internal links in PDF doc (hyperref)', -- 'What color should be used for normal internal links?', ""); -- --&add_param('pagecolor', 'color', 'blue', '', '=s', -- 'specify color of links to other pages in PDF doc (hyperref)', -- 'What color should be used for page links?', ""); -- --&add_param('link_toc_page', 'bool', $YES, '', '!', -- 'link table of contents to pages instead of sections (hyperref)', -- 'Should TOC be linked to pages?', -- "The table of contents of the resulting PDF document is normally linked to " -- ."the\ncorresponding section. However, you can also link it to the " -- ."corresponding page\ninstead."); -- --&add_param('default_title', 'text', $NIL, '', '=s', -- 'set default PDF info title', -- 'What is the default title?', -- "A PDF document contains meta data about itself: the document info.\nOne " -- ."of the info fields is the document title. You can set a default value\n" -- ."which will be used in the case the script cannot determine a proper " -- ."title from\nthe LaTeX document and you have not set one on the command " -- ."line.\nYou can use '$NIL' to tell me that you would like to leave this " -- ."up to\nindependent hyperref configuration."); -- --&add_param('default_author', 'text', $NIL, '', '=s', -- 'set default PDF info author', -- 'What is the default author?', -- "A PDF document contains meta data about itself: the document info.\nOne " -- ."of the info fields is the document author. You can set a default value\n" -- ."which will be used in the case the script cannot determine a proper " -- ."author\nfrom the LaTeX document and you have not set one on the command " -- ."line.\nYou can use '$NIL' to tell me that you would like to leave this " -- ."up to\nindependent hyperref configuration."); -- --&add_param('force_index', 'bool', $NO, '|i', '!', -- 'force explicit inclusion of (existing) index in PDF doc', -- 'Should the call of makeindex be forced?', -- "Older versions of pdflatex have not included the index of a document\n" -- ."automatically. If you are missing the index in your document you can " -- ."force the\ncall of makeindex on the condition that an index file was " -- ."generated."); -- --&add_param('makeindex_opts', 'text', '', '', '=s', -- 'specify extra options for shell execution of makeindex', -- 'What additional options for makeindex should be used?', -- "Sometimes, people would like to pass some extra options over to makeindex. " -- ."This\nis the right place to do that. Everyone else can leave this empty."); -- --&add_param('bibtex', 'three', $NIL, '|b', '!', -- 'set bibtex behavior', -- 'How should bibtex be used?', -- "The bibtex usage can be specified.\nPossible values are: '$YES' (always " -- ."run bibtex), '$NO' (never run bibtex)\nand '$UNDEF' (scan tex file for " -- ."a bibtex entry and run it if required)."); -- --&add_param('gloss', 'three', $NIL, '', '!', -- 'set gloss behavior', -- 'How should gloss be used?', -- "The gloss usage can be specified.\nPossible values are: '$YES' (always " -- ."run bibtex on file.gls), '$NO' (never run bibtex on file.gls)\nand '$UNDEF' (scan tex file for " -- ."a gloss entry and run it if required)."); -- --&add_param('thumbpdf', 'bool', $NO, '|n', '!', -- 'generate thumbnails for PDF document', -- 'Should PNG thumbnails be created?', -- "I can use thumbpdf to include thumbnails of the document pages in the PDF " -- ."file.\nThis requires Ghostscript 5.50 or higher."); -- --&add_param('ppower', 'bool', $NO, '|w', '!', -- 'postprocess PDF document with ppower', -- 'Should ppower postprocess the PDF document?', -- "I can use ppower to postprocess the PDF " -- ."file.\nThis requires ppower 4.0 or higher."); -- --&add_param('authorindex', 'bool', $NO, '', '!', -- 'generate author index for PDF document', -- 'Should authorindex process the PDF document?', -- "I can use authorindex to process to include an author index in the PDF " -- ."file.\nThis requires authorindex."); -- -- --&add_param('mtp_preamble', 'bool', $NO, '|r', '!', -- "add the file $MTP_PREAMBLE_FILENAME at the current dir to metapost files", -- "Should the $MTP_PREAMBLE_FILENAME file be added to the metapost files?", -- "I can add $MTP_PREAMBLE_FILENAME to metapost " -- ."files.\nThis requires an existing $MTP_PREAMBLE_FILENAME file."); -- --&add_param('maxrun', 'integer', 6, '', '=i', -- 'specify maximal number of pdflatex runs if problems are detected', -- 'What should be the maximum number of runs for pdflatex (1-6)?', ""); -- --&add_param('minrun', 'integer', 2, '', '=i', -- 'specify minimal number of pdflatex runs if no problems are detected', -- 'What should be the minimum number of runs for pdflatex (1-6)?', ""); -- --&add_param('verbosity', 'integer', 5, '', '=i', -- 'set the level of verbosity', -- 'Which level of verbosity do you want (0-9)', -- "Different people want different amounts of information about what the " -- ."script\nactually does. Therefore you can adjust the verbosity to your " -- ."personal needs\nby setting this parameter to a value from 0 to 9. 0 " -- ."means no output at all\nand 9 means maximal output."); -- --&add_param('pdftex_opts', 'text', '', '', '=s', -- 'specify extra options for shell execution of pdflatex', -- 'What additional options for pdflatex should be used?', -- "Sometimes, people would like to pass some extra options over to pdflatex. " -- ."This\nis the right place to do that. Everyone else can leave this empty."); -- --&add_param('hyperref_args', 'text', '', '', '=s', -- 'specify extra arguments for the hyperref package', -- 'What additional arguments should be passed to the hyperref package?', -- "Sometimes, people would like to pass some extra options over to hyperref. " -- ."This\nis the right place to do that. Everyone else can leave this empty."); -- --# the following parameter types should be set now: --# 'color' => \@VALUES, --# 'destination' => \@VALUES, --# 'paper' => \@VALUES, --# 'action' => undef, --# 'three' => undef, --# 'bool' => undef, --# 'integer' => undef, --# 'text' => undef, --# 'directory' => undef -- --##### Functions ########################################### -- --### handle a status report with a given priority level --# write it to the log file if log file if configuration is done --# write it to stdout if verbosity is set lower or equal --# --# The following priority levels exist: --# 1: minimal fatal error messages --# 2: additional information about fatal error --# 3: non-fatal error message --# 4: warning --# 5: major step of the process --# 6: minor step of the process --# 7: progress report of minor step --# 8: long status report from called applications --# 9: debug info --# --# parameter 1: priority level --# parameter 2: list of output strings --# return value: none -- --sub report { -- my $level; -- my $verbosity; -- my $log_verbosity; -- my @output; -- -- if (@_ < 2 ) { -- @output = ( "Oppss! Report function got only 1 argument!" ); -- $level = 9; -- } else { -- ($level, @output) = @_; -- } -- -- if($CONFIGURED) { -- if( ¶m_value('debug') eq $NO ) { -- $verbosity = ¶m_value('verbosity'); -- $log_verbosity = $LOGFILE_VERBOSITY; -- } else { -- $verbosity = 9; -- $log_verbosity = 9; -- } -- } else { -- $verbosity = $PRE_CONFIG_VERBOSITY; -- $log_verbosity = $LOGFILE_VERBOSITY; -- } -- -- if ( $level <= $log_verbosity ) { -- open LOGFILE, ">> $MYLOGFILE"; -- print LOGFILE @output,"\n"; -- close LOGFILE; -- } -- -- if( $level <= $verbosity ) { -- print @output,"\n"; -- } --} -- --### process system command and do the appropriate reports --# parameter 1: the system command to process --# parameter 2: flag - TRUE: abort on failure, FALSE: continue on failures --# parameter 3: priority level for output of system command --# parameter 4: specific failure message --# return value: TRUE - success, FALSE - failure -- --sub system_command { -- my $command = $_[0]; -- my $fatal_failure= $_[1]; -- my $output_priority = $_[2]; -- my $fail_message = $_[3]; -- my $system_out; -- -- $system_out = `$command 2>&1`; -- -- if ($?) { -- if ($fatal_failure) { -- &report(2, $system_out) if ($system_out); -- &abort($fail_message.": $!"); -- } else { -- &report($output_priority, $system_out) if ($system_out); -- &report(3, $fail_message.": $!"); -- } -- return $FALSE; -- } -- -- return $TRUE; --} -- --### Index of the first occurence of a string in an array --# parameter 1: text --# parameter 2: list --# return value: index or -1 if not element of the array -- --sub array_index { -- my ($text, @list) = @_; -- -- if(!defined($text)) { -- &report(9, "Oppss! Cannot compare nothing."); -- return -1; -- } -- -- foreach (0..$#list) { -- if ( $list[$_] eq $text ) { return $_; } -- } -- -- return -1; --} -- --### extract the last N lines of a text file --# abort on failures --# parameter 1: file to read --# parameter 2: N - number of lines to print (undef/0: all lines) --# return value: last N lines -- --sub file_tail { -- my $file_name = $_[0]; -- my $no_of_lines = defined($_[1]) ? $_[1] : 0; -- my @cache=(); -- -- &check_file($file_name); -- open(TAIL_SOURCE, "<$file_name") -- or &abort("Could not read file $file_name: $!"); -- -- if($no_of_lines == 0) { -- # use entire file -- while() { -- if(!$_) { $_="\n"; } -- push(@cache, $_); -- } -- } else { -- # only last N lines -- -- # fill up cache -- while(@cache < $no_of_lines and ) { -- if(!$_) { $_="\n"; } -- push(@cache, $_); -- } -- -- # always cache the last N lines up to the end of the file -- while() { -- if(!$_) { $_="\n"; } -- shift(@cache); -- push(@cache, $_); -- } -- } -- -- close TAIL_SOURCE; -- -- return @cache; --} -- --### return all lines of FILE which match match regexp EXPR --# parameter 1: FILE - file to read --# parameter 2: EXPR - regular expression to match --# parameter 3: true: exit on first occurence, otherwise get all (default: false) --# return value: array of matching lines -- --sub grep_file { -- my $file_name = $_[0]; -- my $regexp = $_[1]; -- my $first_only = $_[2] ? $TRUE : $FALSE; -- my @result=(); -- -- ### open file and abort if not possible -- &check_file($file_name); -- open(GREP_SOURCE, "<$file_name") -- or &abort("Could not read file $file_name: $!"); -- -- while() { -- if(m#$regexp#) { -- push(@result, $_); -- if($first_only) { last; } -- } -- } -- -- close GREP_SOURCE; -- return @result; --} -- --### Removing all temporary files -- --sub clean_up { -- &report(6, "Removing temporary files ..."); -- foreach (@TMPFILES) { -- unlink($_) if(-f $_); -- } -- -- foreach (@TMP_TEX_FILES) { -- # make sure that we have a good tex file name in order -- # to avoid unintended removals -- if( $_ ne "" and -f $_.'.tex' ) { -- unlink glob($_.".???"); -- } else { -- &report(3, "Bad file in temp tex files list: $_"); -- } -- } --} -- --### Output of all temp files -- --sub print_temp_files { -- if (scalar @TMPFILES > 0) { -- print "Stored the following explicit temporary files:\n"; -- foreach (@TMPFILES) { -- if (-f $_) { -- print "> ".$_."\n"; -- } else { -- print "> ".$_." (does not exist)\n"; -- } -- } -- print "\n"; -- } -- -- if (scalar @TMP_TEX_FILES > 0) { -- print "Stored the following temporary TeX base names:\n"; -- foreach (@TMP_TEX_FILES) { -- if( $_ ne "" and -f $_.'.tex' ) { -- print "> ".$_.": "; -- foreach my $file (glob($_.".???")) { -- print basename($file)." "; -- } -- print "\n"; -- } else { -- print "> ".$_.": bad file for temp TeX file\n"; -- } -- } -- print "\n"; -- } --} -- --### exit with an error message -- --sub abort { -- &report(1, @_); -- if ( $CONFIGURED and ¶m_value('clean_on_abort') eq $YES -- and ¶m_value('debug') eq $NO) { -- &clean_up; -- } else { -- &print_temp_files; -- } -- &report(2, "Aborting ..."); -- exit 1; --} -- --### Check for required command with 'which'; abort if not found --# parameter $1: command to check --# parameter $2: remark if specified command is not found -- --sub checkCommand { -- my $command = $_[0]; -- my $message = $_[1]; -- my $which_output; -- -- $which_output = `which $command 2>&1`; -- chomp $which_output; -- $_ = $which_output; -- s|^(.*/)?([^/]+)$|$2|; -- -- if ( $_ ne $command ) { -- &report(2, "\n$which_output"); -- &report(1, "\nRequired command '$command' seems not to be in your path."); -- if ( defined($message) ) { -- &report(2, "$message"); -- } -- &report(2, "Aborting ..."); -- exit 1; -- } --} -- --###################### Generic configuration functions -- --### interactively answer a question with yes or no --# parameter 1: question --# parameter 2: default value (not set means $NIL) --# parameter 3: yes: allow undefined as third value --# no : only yes/no allowed (default) --# return value: the given answer -- --sub question_ynu { -- my $user_input; -- my $question = $_[0]; -- my $default = defined($_[1]) ? $_[1] : $NIL; -- my $undef_allowed = $_[2]; -- my $response = undef; -- -- if (defined($undef_allowed) and $undef_allowed eq $YES) { -- $undef_allowed = $TRUE; -- } else { -- $undef_allowed = $FALSE; -- } -- -- if( $default =~ /^y(es)?/i ) { -- $question .= ' [y]: '; -- $default = $YES; -- } elsif ( $default eq $NIL and $undef_allowed ) { -- $question .= ' [u]: '; -- $default = $NIL; -- } else { -- $question .= ' [n]: '; -- $default = $NO; -- } -- while (! defined($response)) { -- print $question; -- $user_input = ; -- chomp($user_input); -- -- if( $user_input =~ /^y(es)?/i ) { -- $response=$YES; -- } elsif ( $user_input =~ /^no?/i ) { -- $response=$NO; -- } elsif ( $user_input =~ /^u(ndef(ined)?)?/i and $undef_allowed ) { -- $response=$NIL; -- } elsif ( $user_input eq "" ) { -- $response=$default; -- } else { -- print "Please respond with y(es)"; -- print ", u(ndefined)" if($undef_allowed); -- print " or n(o).\n"; -- } -- } -- return $response; --} -- --### interactively input a positive integer number --# parameter 1: question --# parameter 2: default value --# parameter 3: min value --# parameter 4: max value --# return value: the input number -- --sub input_number { -- my $question = $_[0]; -- my $default = $_[1]; -- my $min_limit = $_[2]; -- my $max_limit = $_[3]; -- my $response= undef; -- -- while (! defined($response)) { -- print "$question [$default]: "; -- my $user_input = ; -- chomp($user_input); -- -- if ($user_input eq "") { -- $response=$default; -- } else { -- $_ = $user_input; -- if (s/^([0-9]+)$/$1/ and $_ >= $min_limit and $_ <= $max_limit ) { -- $response = $_; -- } else { -- print "Invalid input. Please enter a positve integer from $min_limit to $max_limit.\n"; -- } -- } -- } -- return $response; --} -- --### interactively choose between several given values --# parameter 1: question --# parameter 2: default value --# parameter 3: reference to an array of possible values arrays --# return value: the chosen value -- --sub choose_value { -- my ($question, $default, $enum_array_ref)=@_; -- my $default_no=1; -- my $chosen_no; -- my @possible_values = @$enum_array_ref; -- my @value_array; -- my $value_key; -- my $value_output; -- -- print "$question\n"; -- foreach (0..$#possible_values) { -- my $no = $_ + 1; -- @value_array = @{$possible_values[$_]}; -- $value_key = $value_array[0]; -- $value_output = $value_array[1]; -- -- print "$no) " . $value_output . "\n"; -- if ( $default eq $value_key ) { $default_no=$no; } -- } -- -- $chosen_no=&input_number("Please enter the corresponding number", $default_no, 1, $#possible_values); -- -- @value_array = @{$possible_values[$chosen_no - 1]}; -- $value_key = $value_array[0]; -- return $value_key; --} -- --### interactively answer a question --# parameter 1: question --# parameter 2: current value --# return value: the new value -- --sub input_text { -- my $question=$_[0]; -- my $default=$_[1]; -- my $response= undef; -- -- print "Suggested value: $default\n"; -- if ( &question_ynu("Do you want to keep this value?", $YES) eq $YES ) { -- $response= $default; -- } else { -- print "$question "; -- my $user_input = ; -- chomp($user_input); -- -- $response = $user_input; -- } -- return $response; --} -- --##### Make sure that specified file exists and is readable; abort if missing --# parameter 1: file to check --# parameter 2: remark if check fails on specified file -- --sub check_file { -- my $file = $_[0]; -- my $message = defined($_[1]) ? $_[1] : "Required file cannot be accessed!"; -- -- if ( ! -f $file ) { -- &report(2, "\nSorry. I cannot find '$file'."); -- &abort($message); -- } elsif ( ! -r $file ) { -- &report(2, "\nSorry. File '$file' exists, but is not readable."); -- &abort($message); -- } --} -- --##### Make sure that specified directory exists and is writable --# parameter 1: directory to check --# parameter 2: remark if check fails on specified directory --# parameter 3: if yes, creation is allowed --# return value: $TRUE - ok; $FALSE - error -- --sub check_dir { -- my $directory = $_[0]; -- my $message = defined($_[1]) ? $_[1] : "Not a valid path!"; -- my $allow_creation = defined($_[2]) ? $_[2] : $NO; -- -- if ( index($directory, "/") != 0 ) { -- &report(3, "\nSorry. '$directory' is not an absolute path."); -- &report(3, $message); -- return $FALSE; -- } elsif ( ! -d $directory ) { -- # dir does not exist -- if ( $allow_creation eq $YES ) { -- # creation allowed -- &report(4, "\nI cannot find '$directory'. Try to create it."); -- if ( mkdir($directory, 0755) ) { -- &report(7, "Creation of '$directory' was successful."); -- return $TRUE; -- } else { -- &report(3, "Creation of '$directory' failed."); -- &report(3, $message); -- return $FALSE; -- } -- } else { -- # creation not allowed -- &report(3, "\nSorry. Directory '$directory' does not exist."); -- &report(3, $message); -- return $FALSE; -- } -- } elsif ( ! -w $directory ) { -- # dir not writable -- &report(3, "\nSorry. Directory '$directory' exists, but is not writable."); -- &report(3, $message); -- return $FALSE; -- } -- return $TRUE; --} -- --### interactively input a directory for data storage (absolute path) --# parameter 1: question --# parameter 2: default dir --# parameter 3: if 'yes' allow creation of directory --# return value: the specified directory -- --sub input_dir { -- my $question = $_[0]; -- my $default_dir = $_[1]; -- my $allow_creation = defined($_[2]) ? $_[2] : $NO; -- my $user_input; -- my $response = undef; -- -- if ( defined($default_dir) and index($default_dir, "/") == 0 -- and ( (! -d $default_dir and $allow_creation eq $YES) -- or (-d $default_dir and -w $default_dir) ) ) { -- $question .= " [$default_dir]: "; -- } else { -- $default_dir = undef; -- $question .= ": "; -- } -- -- while (! defined($response)) { -- print "$question"; -- $user_input = ; -- chomp($user_input); -- -- if( $user_input eq "" and defined($default_dir) ) { -- # user has only pressed and thereby confirmed default value -- if( ! &check_dir($default_dir,"Default value was not valid. Please, give different directory.", $allow_creation ) ) { -- # default dir does not exist and cannot be created -- $default_dir = undef; -- $question = "$_[0]: "; -- } else { -- # valid default dir has already existed or has been created -- $response = $default_dir; -- } -- } else { -- # user has given a directory -- if( &check_dir($user_input,"This is not a valid directory!", $allow_creation) ) { -- $response = $user_input; -- } -- } -- } -- return $response; --} -- --#### add a new parameter type with corresponding additional data argument --#### parameters types --# parameter 1: type key --# parameter 2: additonal data for the type --# e.g. for enum type: reference to list of arrays --# return value: none -- --sub add_param_type { -- -- my ($type, $scalar_argument) = @_; -- -- $PARAMETER_TYPES{$type} = $scalar_argument; --} -- --#### add a new parameter to the adminstrated parameters --#### --# parameter 1: key --# parameter 2: type --# parameter 3: default value --# parameter 4: alias for command line options --# parameter 5: specification for command line options --# parameter 6: short description for help --# parameter 7: question --# parameter 8: explanation --# return value: none -- --sub add_param { -- -- my ($key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation) = @_; -- -- $CONFIGURATION{$key} = $def_value; -- -- $PARAMETER_LIST{$key} = [ $type, $opt_alias, $opt_spec, $def_value, $description, $question, $explanation ]; -- -- push(@PARAMETER_ORDER, $key); -- -- if (! exists $PARAMETER_TYPES{$type}) { -- $PARAMETER_TYPES{$type} = undef; -- } --} -- --### get the value of an existing parameter --# parameter 1: a parameter key --# return value: reference to the array of possible value entries --# (undef if not valid) -- --sub type_enum_array { -- my $key = $_[0]; -- my $values_ref; -- -- if(! exists($PARAMETER_TYPES{$key})) { -- &abort("unknown type: $key"); -- } -- -- $values_ref = $PARAMETER_TYPES{$key}; -- -- if(ref $values_ref ne 'ARRAY') { -- $values_ref = undef; -- } -- -- return $values_ref; --} -- --### get the value of an existing parameter --# parameter 1: a parameter key --# return value: parameter value -- --sub param_value { -- my $key = $_[0]; -- my $current_value; -- -- exists($CONFIGURATION{$key}) -- or &abort("unknown parameter: $key"); -- $current_value = $CONFIGURATION{$key}; -- -- return $current_value; --} -- --### get the type of an existing parameter --# parameter 1: a parameter key --# return value: parameter value -- --sub param_type { -- my $key = $_[0]; -- my $def_ref; -- my $type; -- -- exists($PARAMETER_LIST{$key}) -- or &abort("unknown parameter: $key"); -- $def_ref = $PARAMETER_LIST{$key}; -- $type = @{$def_ref}[$TYPE]; -- -- exists($PARAMETER_TYPES{$type}) -- or &abort("parameter has unknown type: $key (type: $type)"); -- -- return $type; --} -- --### determine if the given parameter is a full one (instead of option only) --# parameter 1: a parameter key --# return value: $TRUE - full parameter; $FALSE otherwise -- --sub full_param { -- my $key = $_[0]; -- my @param_def; -- -- exists($PARAMETER_LIST{$key}) -- or &abort("unknown parameter: $key"); -- @param_def = @{$PARAMETER_LIST{$key}}; -- -- if ($param_def[$TYPE] ne 'action' and defined ($param_def[$QUESTION])) { -- return $TRUE; -- } else { -- return $FALSE; -- } --} -- --### get the output needed for configuration of this parameter --# parameter 1: a parameter key --# return value: array - (description, explanation, question) -- --sub param_config_output { -- my $key = $_[0]; -- my @param_def; -- my $description; -- my $explanation; -- my $question; -- -- exists($PARAMETER_LIST{$key}) -- or &abort("unknown parameter: $key"); -- @param_def = @{$PARAMETER_LIST{$key}}; -- $description = $param_def[$DESCRIPTION]; -- $explanation = $param_def[$EXPLANATION]; -- $question = $param_def[$QUESTION]; -- -- return ($description, $explanation, $question); --} -- --### set the value of an existing parameter --# parameter 1: a parameter key --# parameter 2: the new value --# return value: none -- --sub set_param_value { -- my $key = $_[0]; -- my $new_value = $_[1]; -- -- exists($CONFIGURATION{$key}) -- or &abort("unknown parameter: $key"); -- $CONFIGURATION{$key}=$new_value; --} -- --### get option specifier for getopts --# parameter 1: option key --# return value: string - option specifier -- --sub option_specifier { -- my $key = $_[0]; -- my $spec; -- my $def_ref; -- -- exists($PARAMETER_LIST{$key}) -- or &abort("unknown parameter: $key"); -- $def_ref = $PARAMETER_LIST{$key}; -- $spec = $key . ${$def_ref}[$OPT_ALIAS] . ${$def_ref}[$OPT_SPEC]; -- -- return $spec; --} -- --### handle an option --# parameter 1: a parameter/option key --# parameter 2: the option value --# return value: none -- --sub handle_option { -- my $key = $_[0]; -- my $value = $_[1]; -- my $type; -- -- $type = ¶m_type($key); -- -- if ($type eq 'action') { -- &handle_action_opt($key, $value); -- } elsif ( $type eq 'bool' or $type eq 'three') { -- my $bool_value = $value ? $YES : $NO; -- &set_param_value($key, $bool_value); -- } elsif ( $type eq 'directory') { -- if (! &check_dir($value)) { -- &report(2, "$key requires an existing writable directory as an absolute path."); -- &abort("Illegal value: $value"); -- } -- &set_param_value($key, $value); -- } elsif (defined(&type_enum_array($type))){ -- &set_enum_param($key, $value); -- } else { -- &set_param_value($key, $value); -- } --} -- --### handle all action options --# parameter 1: a option key --# parameter 2: the option value --# return value: none -- --sub handle_action_opt { -- my $key = $_[0]; -- my $value = $_[1]; -- -- if ($key eq 'help') { -- &print_help; -- -- } elsif ($key eq 'version') { -- &print_version; -- -- } elsif ($key eq 'configure') { -- if ( -f $RC_FILENAME ) { -- &read_configuration($RC_FILENAME); -- } -- &configure; -- &write_configuration($RC_FILENAME); -- &print_configuration; -- -- } elsif ($key eq 'print_config') { -- if ( -f $RC_FILENAME ) { -- &read_configuration($RC_FILENAME); -- } -- &print_configuration; -- -- } else { -- &print_usage; -- exit 1; -- } -- exit 0; --} -- --### set a variable by a command line option to a possible values; abort on error --# parameter 1: parameter key --# parameter 2: value -- --sub set_enum_value { -- my ($key, $value) = @_; -- my $type; -- my $enum_array_ref; -- my @allowed_values=(); -- -- $type = ¶m_type($key); -- $enum_array_ref = &type_enum_array($type); -- &abort("Internal error: No value array for parameter $key.") -- if(!defined($enum_array_ref)); -- -- ### find out if the given value is allowed -- foreach my $value_array_ref (${$enum_array_ref}) { -- if(${$value_array_ref}[0] eq $value) { -- ### found it, so it is okay! -- &set_param_value($key, $value); -- return; -- } -- } -- -- ### value is not listed, so not allowed -- ### make a list of all allowed values -- foreach my $value_array_ref (${$enum_array_ref}) { -- push(@allowed_values, ${$value_array_ref}[0]); -- } -- -- &report(2, "\n$key allows: " . @allowed_values . ".\n"); -- &abort("Illegal value: $value"); --} -- --### configure an existing parameter interactively --# parameter 1: a parameter key --# return value: none -- --sub config_param { -- my $key = $_[0]; -- my $type; -- my $new_value; -- my $current_value; -- my $description; -- my $explanation; -- my $question; -- -- ### get required information about this parameter -- $type = ¶m_type($key); -- $current_value = ¶m_value($key); -- ($description, $explanation, $question) = ¶m_config_output($key); -- -- ### tell the user the facts -- print "\n\n--------------------------------------------\n"; -- print "Parameter: ".$key."\n"; -- print $description."\n\n"; -- print $explanation."\n\n" if($explanation ne ""); -- -- ### ask him what he wants -- if ($type eq 'bool') { -- $new_value=&question_ynu($question, $current_value, $NO); -- } elsif ($type eq 'three') { -- $new_value=&question_ynu($question, $current_value, $YES); -- } elsif ($type eq 'directory') { -- $new_value=&input_dir($question, $current_value, $YES); -- } elsif ($type eq 'text') { -- $new_value=&input_text($question, $current_value); -- } elsif ($type eq 'integer') { -- $new_value=&input_number($question, $current_value, -- $NUM_PARAM_MIN, $NUM_PARAM_MAX); -- } else { -- my $enum_array_ref; -- -- $enum_array_ref=&type_enum_array($type); -- if (! defined($enum_array_ref)) { -- &abort("Do not know how to configure this parameter: $key (type: $type)"); -- } -- -- $new_value=&choose_value($question,$current_value,$enum_array_ref); -- } -- -- ### store his choice -- &set_param_value($key, $new_value); --} -- --### save configuration in rc file --# parameter 1: file name --# return value: none -- --sub write_configuration { -- my $file_name = $_[0]; -- my $date; -- -- open(RCFILE, ">$file_name") or -- &abort("Could not open configuration file for writing ($file_name)"); -- select RCFILE; -- -- $date = `date`; -- chomp($date); -- -- print "# Configuration file for $MYNAME V$MYRELEASE\n"; -- print "# Generated $date by $MYUSER on $MYHOSTNAME\n"; -- print "$RCVERSION_STRING=$MYRCFILE_VERSION\n"; -- -- foreach my $key (@PARAMETER_ORDER) { -- my $value = $CONFIGURATION{$key}; -- if(&full_param($key)) { -- print $key.'='.$value."\n"; -- } -- } -- -- print "# EOF\n"; -- select STDOUT; -- close RCFILE; --} -- --### print the configuration parameters -- --sub print_configuration { -- print "\nConfiguration for $MYNAME V$MYRELEASE\n"; -- -- foreach my $key (@PARAMETER_ORDER) { -- my $value = $CONFIGURATION{$key}; -- if(&full_param($key)) { -- print $key.'='.$value."\n"; -- } -- } -- -- print "\n"; --} -- --### load parameters from rc file --# parameter 1: file name --# return value: version of read rc file or 0 if no version given -- --sub read_configuration { -- my $file_name = $_[0]; -- my $file_version= 0; -- -- &check_file($file_name, "Could not access configuration file"); -- open(RCFILE, "<$file_name") or -- &abort("Could not open configuration file for reading ($file_name)"); -- -- while () { -- chomp; -- if( /^([^#=]+)=(.*)$/ ) { -- if( exists $CONFIGURATION{$1} ) { -- $CONFIGURATION{$1} = $2; -- } elsif ( $1 eq $RCVERSION_STRING ) { -- $file_version = $2; -- } else { -- print "Ignoring unknown parameter in RC file: $1=$2\n"; -- } -- } -- } -- close RCFILE; -- -- return $file_version; --} -- --### print script version -- --sub print_version { -- print "\n$MYNAME Version $MYRELEASE\n"; --} -- --###################### Specific functions (for use with this script only) -- --### print usage of command -- --sub print_usage { -- print "\nUsage: $MYNAME [OPTIONS] DOCUMENT.lyx\n"; -- print " $MYNAME [OPTIONS] DOCUMENT[.tex]\n\n"; -- print " $MYNAME -c | --configure modify/set up configuration\n"; -- print " $MYNAME -h | --help give a short help\n"; -- print " $MYNAME -o | --print_config print current configuration\n"; -- print " $MYNAME -v | --version print my version\n\n"; --} -- --### print command help -- --sub print_help { -- &print_version; -- &print_usage; -- -- foreach my $key (@PARAMETER_ORDER) { -- my @param_def = @{$PARAMETER_LIST{$key}}; -- my $description = $param_def[$DESCRIPTION]; -- my $takes_value = $param_def[$OPT_SPEC] =~ /[=:]/ ? $TRUE : $FALSE; -- my $negation = $param_def[$OPT_SPEC] eq '!' ? $TRUE : $FALSE; -- my $alias = $param_def[$OPT_ALIAS]; -- -- $alias =~ s/\|(([a-zA-Z])(\||$))/ | -$1/g; -- $alias =~ s/\|(([a-zA-Z][a-zA-Z0-9_]+)(\||$))/ | --$1/g; -- -- print "--"; -- print "[no]" if($negation); -- print $key.$alias; -- print " VALUE" if ($takes_value); -- print ":\n ".$description."\n\n"; -- } -- print "\n"; --} -- --### configure all tex2pdf parameters interactively --# parameters: none --# return value: none -- --sub configure { -- -- print "\n--------------------------------------------------------\n"; -- print "\n***** Configuration for $MYNAME *****\n\n"; -- print "The following answers are considered as defaults in later "; -- print "executions\n"; -- print "of $MYNAME. You can change these values by using the option "; -- print "--configure \nagain."; -- print "Additionally, all command-line options override these settings.\n"; -- print "Many parameters can be set to '$NIL' or '$UNDEF'. This means that NO"; -- print "\nvalue at all (not even an empty value) is passed over to the "; -- print "called\napplication (e.g. latex package hyperref).\n"; -- -- $NUM_PARAM_MIN=1; -- $NUM_PARAM_MAX=9; -- -- foreach my $key (@PARAMETER_ORDER) { -- if(&full_param($key)) { -- &config_param($key); -- } -- } -- -- print "\nConfiguration for $MYNAME finished.\n\n"; --} -- --### check if the most important executables are installed on the system --# parameters: none -- --sub check_commands { -- my $exec_epstopdf; -- ### check for which command -- &checkCommand("which","You can switch off all command checks to fix this."); -- -- ### pdftex executables -- # Homepage: http://tug.org/applications/pdftex -- &checkCommand("pdflatex","See pdftex homepage for details: http://tug.org/applications/pdftex"); -- &checkCommand("epstopdf","See pdftex homepage for details: http://tug.org/applications/pdftex"); -- $exec_epstopdf = `which epstopdf`; -- chomp $exec_epstopdf; -- my $compat = "-dCompatibilityLevel=1\\.1"; -- if (defined($ENV{'GS_OPTIONS'}) && $ENV{'GS_OPTIONS'} =~ /$compat/o) { -- &report(9, "Good: ghostscript option '-dCompatibilityLevel=1.1' detected " -- ."in\n'\$GS_OPTIONS'."); -- } elsif (&grep_file($exec_epstopdf, $compat, $TRUE) > 0) { -- &report(9, "Good: ghostscript option '-dCompatibilityLevel=1.1' detected " -- ."in\n'$exec_epstopdf'."); -- } else { -- &report(4, "\nWARNING: no ghostscript option '-dCompatibilityLevel=1.1' " -- ."in\n'$exec_epstopdf'.\n" -- ."You might run into trouble with the conversions of bitmaps.\n" -- ."Adjusting epstopdf or setting the environment variable GS_OPTIONS " -- ."to \n".'"$GS_OPTIONS -dCompatibilityLevel=1.1" before calling this ' -- ."script\nmight help in this case.\n"); -- } -- -- if ( ¶m_value('thumbpdf') eq $YES ) { -- &checkCommand("thumbpdf","You can switch off thumbpdf support to fix this."); -- } -- -- if ( ¶m_value('ppower') eq $YES ) { -- &checkCommand("ppower","You can switch off ppower support to fix this."); -- } -- -- ### authorindex perl script -- if ( ¶m_value('authorindex') eq $YES ) { -- &checkCommand("authorindex","You can switch off authorindex support to fix this."); -- } -- -- ### bibtex executable -- if ( ¶m_value('bibtex') ne $NO or ¶m_value('gloss') ne $NO) { -- &checkCommand("bibtex","You can switch off BibTeX support to fix this."); -- } --} -- --#### generate the tmp file name from the original tex filename --#### and make sure that they are not the same --# parameter 1: orignal filename (with or without a path or .tex) --# parameter 2: path for the tmp file (default: doc path) --# return value: tmp name -- --sub reserve_tmp_texname { -- my $original_name = $_[0]; -- my $tmp_path = $_[1]; -- my $tmp_base_suffix = ¶m_value('tmp_base_suffix'); -- my $overwrite = ¶m_value('overwrite'); -- my $original_path; -- my $original_base; -- my $suffix; -- my $pathed_tmp_base; -- my @existing_files; -- -- # separate path, base and suffix -- ($original_base,$original_path,$suffix) = fileparse($original_name, '\.tex'); -- -- # set the path of the tmp file -- if(!$tmp_path) { -- $tmp_path=$original_path; -- } else { -- $tmp_path .= '/' if( $tmp_path ne "" and ! ($tmp_path =~ m#/$#) ); -- } -- -- # abort if no absolute path is given -- if( index($tmp_path, "/") != 0 ) { -- &abort("Internal error: Illegal argument for reserve_tmp_texname:". -- "Given file has no absolute path: $original_name"); -- } -- -- # make sure that tmp_base_suffix is set correctly -- if($tmp_base_suffix eq "") { -- &abort("Temporary filename base suffix is empty."); -- } -- -- $pathed_tmp_base = $tmp_path.$original_base.$tmp_base_suffix; -- -- # make sure no file with this base exists in this directory -- @existing_files = glob "$pathed_tmp_base.*"; -- if (@existing_files != 0) { -- &report(3, "Problems detected while reserving temporay file name!\n", -- "In this directory are already files with this basename.\n", -- "A list of the conflicting, existing files:\n", -- join("\n", @existing_files), "\n"); -- if ($overwrite eq $YES) { -- &report(4, "As you have activated the parameter 'overwrite' I will " -- ."continue.\n", -- "However, in order to protect the existing files I will not\n", -- "delete any files with this basename at the final clean-up."); -- } else { -- &report(2, "You could activate the parameter 'overwrite' or remove ", -- "the\n corresponding files in order to avoid these problems."); -- &abort("No temporary name found for $original_name."); -- } -- } else { -- push(@TMP_TEX_FILES, $pathed_tmp_base); -- } -- -- return $pathed_tmp_base.$suffix; --} -- --### generate LaTeX file from LyX document with LyX itself --# parameter ($1): Lyx document --# parameter ($2): Latex document -- --sub generate_tex_file { -- my $lyx_doc = $_[0]; -- my $tex_doc = $_[1]; -- my $lyx_dir; -- my $lyx_output; -- my $lyx_exec=¶m_value('lyx_exec'); -- -- $lyx_dir = ¶m_value('lyxrc_path'); -- $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) ); -- $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) ); -- -- ### Check if LyX file can be accessed -- &check_file($lyx_doc,"Cannot read the specified LyX document!"); -- -- ### Check if LaTeX file exists and is newer than the LyX file -- if ( -f $tex_doc and -M $tex_doc < -M $lyx_doc ) { -- &report(4, "\nLaTeX file is newer than LyX document ($lyx_doc).\n", -- "Using existing TeX file: $tex_doc\n", -- "Remove it to force its new generation."); -- } else { -- ### export LaTeX file with LyX (needs a display!) -- &checkCommand($lyx_exec, "Cannot generate LaTeX document without LyX!"); -- &report(6, "\nExporting LaTeX file"); -- -- ### move some files out of the way that stop LyX from exporting -- foreach my $file ($lyx_dir."lyxpipe.out",$lyx_dir."lyxpipe.in",$tex_doc) { -- if ( -f $file ) { rename($file, $file.'~'); } -- } -- -- $lyx_output = `$lyx_exec --export latex $lyx_doc 2>&1`; -- -- ### check if LaTeX file now really exists -- if ( ! -f $tex_doc ) { -- &report(2, "Lyx Output:\n$lyx_output"); -- &report(2, "\nSorry. I cannot find '$tex_doc'."); -- &abort("The LaTeX document was not generated by LyX!"); -- } else { -- &report(8, "Lyx Output:\n$lyx_output"); -- } -- } --} -- --#### search TeX document for a certain text tag (e.g. author, title) --# parameter 1: file to parse --# parameter 2: full TeX tag name --# return value: list of the contents strings of all matching tags -- --sub extract_tag_contents { -- my $source=$_[0]; -- my $tag_name=$_[1]; -- my $contents; -- my @results=(); -- my $error_message="Could not read TeX document to extract $tag_name"; -- -- &check_file($source, $error_message.'.'); -- open(EXTRACT_SOURCE, "<$source") or -- &abort($error_message." ($source)."); -- -- -- while() { -- ### ignore comments -- s/(^|[^\\])%.*/$1/; -- # ignore \thanks{} -- s/\\thanks\{.*?\}//g; -- # change \and to and -- s/\\and/ and/g; -- -- $contents .= $_; -- } -- -- close EXTRACT_SOURCE; -- -- $_ = $contents; -- -- # add contents of all occurences of this tag in a line to result list -- while ( /\\($tag_name)(\[[^]]*?\])*?{+([^{}]*?)}/s ) { -- my $text = $3; -- $_ = $'; -- # remove newlines -- $text =~ s/\n//g; -- $text="" if (!defined($text)); -- push(@results, $text); -- } -- -- return @results; --} -- --#### search for filenames in given TeX Tag in entire document --### skip all comments and duplicates while parsing --# parameter 1: file to parse --# parameter 2: full TeX tag name --# parameter 3: reference to a list of possible filename suffixes (without '.') --# parameter 4: regexp for suffix to ignore when specified in TeX file --# (undef if not used) --# return value: list of identified files -- --sub identify_files { -- my $source=$_[0]; -- my $tag_name=$_[1]; -- my @suffixes=@{$_[2]}; -- my $ignore_suffix=$_[3]; -- my @matched_tags; -- my @found_files=(); -- my $regexp_suffixes; -- -- # create one large regexp from given suffixes and escape dots in them -- $regexp_suffixes= '.('.join('|', @suffixes).')'; -- $regexp_suffixes =~ s/\./\\./g; -- -- @matched_tags = &extract_tag_contents($source, $tag_name); -- -- foreach my $tag_contents (@matched_tags) { -- my $path; -- my $base; -- my $suffix; -- my $kpse_result; -- my $working_dir = cwd."/"; -- -- ($base,$path,$suffix) = fileparse($tag_contents, $regexp_suffixes); -- -- # if a suffix is specified in the tag_contents handle it as requested -- # -- # 1. $suffix: TRUE if $suffix is defined and not of zero length -- # means: a valid suffix has been found in the filename -- # 2. defined($ignore_suffix): TRUE if $ignore_suffix is defined -- # means: a regexp for suffixes to be ignored has been specified as -- # parameter4 -- # 3. $suffix =~ /$ignore_suffix/: TRUE if $suffix matches the regexp -- # means: the suffix in the filename is wanted to be ignored -- # -- # The IF statement will be executed when: -- # a valid suffix has been found in the filename (1) -- # AND regexp for suffixes to be ignored has NOT been specified (not 2) -- # OR -- # a valid suffix has been found in the filename (1) -- # AND regexp for suffixes to be ignored has been specified (2) -- # AND the suffix in the filename is NOT wanted to be ignored (not 3) -- # -- # The stuff that is executed if the entire IF statement is TRUE does the -- # following: accept the found suffix and consider it as the only possible -- # file name. -- if($suffix and not (defined($ignore_suffix) and $suffix =~ /$ignore_suffix/)){ -- $kpse_result=`kpsewhich $tag_contents`; -- # print warning and skip this tag if kpsewhich could not find it -- if (!$kpse_result) { -- &report(4, "WARNING - Could not identify referenced file:\n", -- " Ignoring '$tag_contents'."); -- next; -- } -- } else { -- # if there is a '.' in the basename assume that this is a reference -- # to a file of another type and skip it -- if( $base =~ /\./ ) { -- &report(9, "Found an unknown extension. Ignoring '$tag_contents'."); -- next; -- } -- -- # search for all possible files with allowed suffixes -- foreach my $allowed_suffix (@suffixes) { -- if (not $allowed_suffix =~ /[\]\)\(\|\[\\]/ ) { -- # suffix is not a regexp, but a real extension -- my $possible_file= $path.$base.'.'.$allowed_suffix; -- $kpse_result=`kpsewhich $possible_file`; -- if ($kpse_result) { -- last; -- } -- } -- } -- } -- -- # if kpsewhich could not find any file with an allowed suffix -- # assume that this reference is of a different type and skip it -- # quietly -- if (!$kpse_result) { -- &report(9, "No suitable file found. Ignoring '$tag_contents'."); -- next; -- } -- -- # expand '.' in kpsewhich output to the current path -- $kpse_result =~ s#^\./#$working_dir#; -- -- # remove trailing newline -- chomp($kpse_result); -- -- # add file to the found file list if it is not already on it -- if( &array_index($kpse_result, @found_files) < 0 ) { -- push(@found_files, $kpse_result); -- } -- } -- -- return @found_files; --} -- --### Build a list of all files which are included from the root file. --# This function recurses, and is maybe smart enough to detect cycles. --# Be sure to set REF_DOCS to the empty string prior to calling this. --# parameter 1: tex file to start with --# no return value --# result is appended to global variable @REF_DOCS -- --sub get_file_list { -- my $source = $_[0]; -- my @imports = (); -- -- # This is the cycle avoidance logic. -- if ( &array_index($source, @REF_DOCS) < 0 ) { -- # Make sure the file can be accessed -- &check_file($source, "Included TeX file seems not to be available. Path problem?"); -- -- # Save the argument in the list of files. -- push(@REF_DOCS, $source); -- -- # Get the list of files included by the argument. -- @imports=&identify_files($source, 'include|input', ['tex']); -- -- # Recurse. -- foreach my $file (@imports) { -- if( ! ($file =~ /\.tex$/) ) { $file .= '.tex'; } -- &get_file_list($file); -- } -- } --} -- --### do the required modifications in the LaTeX preamble --# parameter 1: original preamble from the source file --# lines before \begin{document} tag (without this tag) --# parameter 2: reference to hyperref parameter list --# return value: adjusted preamble -- --sub adjust_preamble { -- my $preamble = $_[0]; -- my $hyperref_params_ref = $_[1]; -- my $extra_code; -- my $result; -- -- $_ = $preamble; -- -- # protect pdflatex execution mode -- s/^(\\batchmode)$/% $1/m; -- -- # insert a4paper in the documentclass when a4wide is used -- # fixes problem that hyperref defaults to letter otherwise -- if ( /^[^%]*\\usepackage(\[widemargins\])?\{(a4|a4wide)\}/m ) { -- # check if package parameters with [] brackets are present -- if ( not s/^(\\documentclass\[.*?)\]/$1,a4paper]/m ) { -- s/^\\documentclass/$&\[a4paper\]/m; -- } -- } -- -- ### collect additional LaTeX code -- -- $extra_code = "\n" . '\usepackage{pslatex}' . "\n"; -- -- if ( ¶m_value('thumbpdf') eq $YES ) { -- $extra_code .= '\usepackage{thumbpdf}' . "\n"; -- } else { -- $extra_code .= "% no thumbpdf support\n"; -- } -- --# if ( ¶m_value('ppower') eq $YES ) { --# $extra_code .= '\usepackage{mpmulti}' . "\n"; --# } else { --# $extra_code .= "% no ppower support\n"; --# } -- -- if ( ¶m_value('authorindex') eq $YES ) { -- $extra_code .= '\usepackage[pages]{authorindex}' . "\n"; -- $extra_code .= '\let\cite=\aicite' . "\n"; -- } else { -- $extra_code .= "% no authorindex support\n"; -- } -- -- $extra_code .= '\makeatletter' . "\n"; -- $extra_code .= '\usepackage[' . join(',', @$hyperref_params_ref) -- . ']{hyperref}' . "\n"; -- $extra_code .= '\makeatother' . "\n"; -- -- ### insert the extra LaTeX code directly after documentclass -- m/^(\\documentclass)(\[[^]]*\])?(\{.*\})/m; -- return $` . $& . $extra_code . $'; --} -- --### adjust all filenames in the LaTeX code to the tmp files --# parameter 1: original LaTeX code from the source file --# return value: adjusted code -- --sub adjust_filenames { -- my $code = $_[0]; -- my $tmp_suffix = ¶m_value('tmp_base_suffix'); -- my $result; -- -- $_ = $code; -- -- # cut off the suffix of eps, ps, *.gz and pstex graphics -- s/((\\includegraphics)(\[[^]]*?\])?(\{[^}]+?))\.(e?ps|pstex|e?ps\.gz)\n?\}/$1}/sg; -- -- # replace the suffix 'pstex_t' with 'pdf_t' -- s/(\\input\{[^}]+?\.)pstex_t\n?\}/$1pdf_t}/sg; -- -- if ( ¶m_value('mtp_preamble') eq $NO ) { -- # cut off the suffix of mmp graphics -- s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)\.mmp\n?\}/$1}/sg; -- } else { -- # replace the suffix '.#' with '-mp.#' -- s/(\\includegraphics(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg; -- -- # replace the suffix '.#' with '-mp.#' -- s/(\\convertMPtoPDF(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg; -- -- # cut off optional suffix '.mmp' and append '-mp' in any case -- s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)(\.mmp)?\n?\}/$1$MTP_TMP_BASESUFFIX}/sg; -- } -- -- # insert the tmp_suffix in tex filenames -- # I assume that files with no extension are TeX files as well; correct? -- s#(\\(input|include)\{([^}]*?/)?[^}/.]+?)((\.tex)?\n?\})#$1$tmp_suffix$4#sg; -- -- return $_; --} -- --### Convert given tex file to the temp tex file we need for pdftex --### major task is to change the reference in the tex files to the --### corresponding tmp files --# parameter 1: tex source file --# parameter 2: tex tmp file --# parameter 3: reference to hyperref parameter list or --# 'undef' if preamble should not be changed -- --sub convert_tex2tmp { -- my $source = $_[0]; -- my $target = $_[1]; -- my $hyperref_params_ref = $_[2]; -- my $contents; -- my $preamble; -- my $body; -- my $adjust_preamble = defined($hyperref_params_ref) ? $YES : $NO; -- my $read_err_msg = "Could not read original TeX document to generate temporary document"; -- -- ### open source and target file -- &check_file($source, $read_err_msg . '.'); -- open(SOURCE_FILE, "<$source") or -- &abort($read_err_msg . " ($source)."); -- -- ### read in the LaTeX source file -- $contents = ""; -- while() { -- $contents .= $_; -- } -- -- close SOURCE_FILE; -- -- ### prepare the LaTeX code for PDF generation -- if ( $adjust_preamble eq $YES ) { -- $contents =~ m/^ *\\begin\{document\} *$/m; -- $preamble = $`; -- $body = $&.$'; -- $preamble = &adjust_preamble($preamble, $hyperref_params_ref); -- $preamble = &adjust_filenames($preamble); -- } else { -- $preamble = ""; -- $body = $contents; -- } -- -- $body = &adjust_filenames($body); -- -- ### write the new LaTeX target file -- open(TARGET_FILE, ">$target") or -- &abort("Could not open file to write temporary TeX document ($target)."); -- -- print TARGET_FILE $preamble.$body; -- -- close TARGET_FILE; --} -- --### Convert the given EPS image to PDF --# parameters $1: EPS image filename with absolute path --# return value: none -- --sub convert_eps2pdf { -- my $image = $_[0]; -- my $image_path; -- my $image_base; -- my $image_name; -- my $suffix; -- my $image_target; -- my $zipped = 0; -- my $dummy; -- -- ($image_base,$image_path,$suffix) = fileparse($image, '\.eps', '\.ps', '\.pstex', '\.gz'); -- if ($suffix eq "\.gz") { -- $zipped = 1; -- ($image_base,$dummy,$suffix) = fileparse($image_base, '\.eps', '\.ps', '\.pstex'); -- } -- $image_name = $image_base . $suffix; -- $image_target = $image_path . $image_base . '.pdf'; -- -- #### check if image file really exists -- #&check_file($image, "Could not convert referenced image."); -- -- ### return if image directory is not writeable -- if (! -w $image_path) { -- &report(4, "WARNING - Image directory not writable: $image_path\n", -- " Skipping '$image_name', assume you have converted it manually."); -- return; -- } -- -- if ( ! -f $image_target or -M $image_target > -M $image ) { -- &report(7, "Converting image $image_name to $image_target ...\n"); -- if ($zipped > 0) { -- &system_command("gunzip -c $image | epstopdf -f -outfile=$image_target", -- $TRUE, 8, "epstopdf failed on $image_name"); -- } else { -- &system_command("epstopdf -outfile=$image_target $image", -- $TRUE, 8, "epstopdf failed on $image_name"); -- } -- if (¶m_value('delete_pdf_images') eq $YES) { -- push(@TMPFILES, $image_target); -- } -- } else { -- &report(7, "$image_base.pdf newer than $image_name, conversion skipped..."); -- } --} -- --### Convert the given PSTEX_T file to PDF_T --# parameters 1: PSTEX_T filename with absolute path --# return value: none -- --sub convert_pstex2pdf { -- my $pstex_file = $_[0]; -- my $pstex_path; -- my $pstex_base; -- my $pstex_name; -- my $suffix; -- my $pstex_target; -- my @eps_images; -- -- ($pstex_base,$pstex_path,$suffix) = fileparse($pstex_file, ('\.pstex_t')); -- $pstex_name = $pstex_base . $suffix; -- $pstex_target = $pstex_path . $pstex_base . '.pdf_t'; -- -- #### check if image file really exists -- #&check_file($pstex_file, "Could not convert referenced file."); -- -- ### return if directory is not writeable -- if (! -w $pstex_path) { -- &report(4, "WARNING - Directory not writable: $pstex_path\n", -- " Skipping '$pstex_name', assume you have converted it manually."); -- return; -- } -- -- # descend into file -- &report(7, "Converting file $pstex_name ...\n"); -- -- # find included EPS image(s) -- @eps_images=&identify_files($pstex_file, 'includegraphics', -- ['pstex', 'pstex\.gz']); -- -- # create .pdf_t file -- &convert_tex2tmp($pstex_file, $pstex_target, undef); -- -- # put tmp file in the tmp file list -- push(@TMPFILES, $pstex_target); -- -- # convert image(s) to pdf -- foreach my $image (@eps_images) { -- &convert_eps2pdf($image); -- } --} -- --### Convert the given MP image to PDF --# parameters $1: MP image filename with absolute path --# return value: none -- --sub convert_mp2pdf { -- my $image = $_[0]; -- my $image_path; -- my $image_base; -- my $image_name; -- my $suffix; -- my $image_target; -- my $image_src; -- my @mps_fig=(); -- my $mp_fig; -- -- ($image_base,$image_path,$suffix) = fileparse($image, '\.mp|\.mmp'); -- $image_name = $image_base . $suffix; -- $image_src=$image_path . $image_base . $suffix; -- -- @mps_fig= &grep_file($image_path.$image_name,'beginfig',$TRUE); -- $_=$mps_fig[0]; -- /(\d)/; -- $mp_fig=$1; -- if (¶m_value('mtp_preamble') eq $YES) { -- $image_target = $image_path . $image_base . $MTP_TMP_BASESUFFIX . '.' . $mp_fig; -- $image_name=$image_base.$MTP_TMP_BASESUFFIX.$suffix; -- } else { -- $image_target = $image_path . $image_base . '.' . $mp_fig; -- } -- -- #### check if image file really exists -- #&check_file($image, "Could not convert referenced image."); -- -- ### return if image directory is not writeable -- if (! -w $image_path) { -- &report(4, "$MYNAME: WARNING - Image directory not writable: $image_path\n", -- " Skipping '$image_name', assume you have converted it manually."); -- return; -- } -- -- if ( ! -f $image_target -- or (-M $image_target > -M $image_src) -- or ( ( ¶m_value('mtp_preamble') eq $YES) -- and (-M $image_target > -M $image_path.$MTP_PREAMBLE_FILENAME) ) ) { -- &report(7, "Converting image $image_name ...\n"); -- my $working_dir = cwd."/"; -- chdir("$image_path") or &abort("cannot cd to $image_path($!)"); -- if ( ¶m_value('mtp_preamble') eq $YES ) { -- &modify_mp_file($image_base,$suffix); -- } -- &system_command("mpost $image_name", -- $TRUE, 8, "mpost failed on $image_name"); -- chdir("$working_dir") or &abort("cannot cd to $working_dir($!)"); -- if (¶m_value('delete_pdf_images') eq $YES) { -- push(@TMPFILES, $image_target); -- } -- } else { -- if ( ¶m_value('mtp_preamble') eq $YES ) { -- &report(7, "$image_base$MTP_TMP_BASESUFFIX.$mp_fig newer than $image_base$suffix, conversion skipped..."); -- } else { -- &report(7, "$image_base.$mp_fig newer than $image_base$suffix, conversion skipped..."); -- } -- } --} -- --### Convert the given MP image to PDF --# parameters $1: MP image filename with absolute path --# return value: none -- --sub modify_mp_file { -- my $base=$_[0]; -- my $suffix=$_[1]; -- my $preamble_file=$MTP_PREAMBLE_FILENAME; -- -- my $mp_source=$base.$suffix; -- my $mp_target=$base.$MTP_TMP_BASESUFFIX.$suffix; -- -- ### open source and target file -- open(SOURCE_FILE, "<$mp_source") or -- &abort("Could not open $mp_source to add $preamble_file ($mp_source)."); -- -- open(TARGET_FILE, ">$mp_target") or -- &abort("Could not open $mp_target to add $preamble_file ($mp_source)."); -- -- open(PREAMBLE_FILE, "<$preamble_file") or -- &abort("Could not open $preamble_file to be added to metapost files ($mp_source)."); -- -- ### set target file as stdout -- select TARGET_FILE; -- print 'verbatimtex' . "\n"; -- print '%&latex' . "\n"; # This forces metapost to use latex in the compilation -- print '\documentclass[english]{article}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here -- # english must be added -- # to preamble in order to -- # make work mpost, why ??? -- while() { -- print $_ -- } -- print '\begin{document}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here -- print 'etex' . "\n"; -- while() { -- print $_ -- } -- print 'verbatimtex' . "\n"; -- print '\end{document}' . "\n"; -- print 'etex' . "\n"; -- -- ### set STDOUT as stdout again -- select STDOUT; -- -- ### close files -- close SOURCE_FILE; -- close TARGET_FILE; -- close PREAMBLE_FILE; -- --} -- -- --### Convert included images to pdf --# parameter 1: tex source file --# no return value -- --sub convert_images { -- my $tex_source=$_[0]; -- my @pstex_file_list; -- my @image_list; -- my @mp_image_list; -- my @mmp_image_list; -- my @major_suffixes; -- my $ignore_regexp; -- -- &report(6, "\nConverting images referenced in $tex_source."); -- -- ##### Get images of major type from the source file -- @major_suffixes = (@BITMAP_SUFFIXES, $PDF_ORIG_SUFFIX, @EPS_SUFFIXES); -- $ignore_regexp = '.('.join('|',@EPS_SUFFIXES).')'; -- $ignore_regexp =~ s/\./\\./g; -- -- &report(6, "\nScanning for major image types (".join(', ',@major_suffixes)."):"); -- @image_list = &identify_files($tex_source,'includegraphics', -- \@major_suffixes, $ignore_regexp ); -- -- if ( @image_list > 0 ) { -- &report(7, join("\n", @image_list)); -- } else { -- &report(7, "None."); -- } -- -- ##### Get PSTEX_T files from the source file -- &report(6, "\nScanning for PSTEX_T files (.pstex_t):"); -- @pstex_file_list=&identify_files($tex_source, 'input', ['pstex_t']); -- if ( @pstex_file_list > 0 ) { -- &report(7, join("\n", @pstex_file_list)); -- } else { -- &report(7, "None."); -- } -- -- ##### Get MP images from the source file -- &report(6, "\nScanning for MP images (.mp):"); -- @mp_image_list=&identify_files($tex_source, -- 'convertMPtoPDF|includegraphics',['mp','(\d+)'],'\.(\d+)'); -- # FIXME -- # fixed for now by ignoring strange extension in identify_files -- # -- # the above could cause problems as identify_files is expecting a list of -- # real extensions and not of regexps -- # maybe the only way to fix this is to adjust identify_files to ignore -- # invalid extension when testing them with kpsewhich -- # ALTERNATIVE: design identify_files to use preffered_suffixes instead -- # of ignore_suffixes -- -- if ( @mp_image_list > 0 ) { -- &report(7, join("\n", @mp_image_list)); -- } else { -- &report(7, "None."); -- } -- -- ##### Get MMP images from the source file -- &report(6, "\nScanning for MMP images (.mmp):"); -- @mmp_image_list=&identify_files($tex_source,'multiinclude',['mmp']); -- if ( @mmp_image_list > 0 ) { -- &report(7, join("\n", @mmp_image_list)); -- } else { -- &report(7, "None."); -- } -- -- ### Convert EPS images to PDF, copy pdf.orig image files to pdf, -- ### and simply ignore all other -- if ( @image_list > 0) { -- my $handled_suffixes; -- -- &report(6, "\nProcessing images of major types:"); -- -- # create one large regexp from suffixes and escape dots in them -- $handled_suffixes = '.('.join('|',(@EPS_SUFFIXES, $PDF_ORIG_SUFFIX)).')'; -- $handled_suffixes =~ s/\./\\./g; -- -- foreach my $image (@image_list) { -- my $path; -- my $base; -- my $suffix; -- ($base,$path,$suffix) = fileparse($image, $handled_suffixes); -- if (not $suffix) { -- &report(7, "No special handling required for image: $base$suffix"); -- } elsif ($suffix eq ('.'.$PDF_ORIG_SUFFIX) ) { -- my $image_target = $path.$base.'.pdf'; -- -- if ( ! -f $image_target or -M $image_target > -M $image ) { -- &report(7, "Create temporary PDF file from original: $base$suffix"); -- copy($image, $image_target) -- or &abort("Could not create tmp file: $!"); -- if (¶m_value('delete_pdf_images') eq $YES) { -- push(@TMPFILES, $image_target); -- } -- } else { -- &report(7, "$base.pdf newer than $base$suffix, copy skipped ..."); -- } -- } else { -- &convert_eps2pdf($image); -- } -- } -- } -- -- ### Convert all PSTEX_T files to PDF_T -- if ( @pstex_file_list > 0 ) { -- &report(6, "\nConverting pstex_t docs to pdf_t docs"); -- foreach my $image (@pstex_file_list) { -- &convert_pstex2pdf($image); -- } -- } -- -- ### Convert all MP images to PDF -- if ( @mp_image_list > 0) { -- &report(6, "\nConverting MP images to PDF"); -- foreach my $image (@mp_image_list) { -- &convert_mp2pdf($image); -- } -- } -- -- ### Convert all MMP images to PDF -- if ( @mmp_image_list > 0) { -- &report(6, "\nConverting MMP images to PDF"); -- foreach my $image (@mmp_image_list) { -- &convert_mp2pdf($image); -- } -- } -- -- &report(6, "\nFinished converting for ${tex_source}."); --} -- --### run pdflatex --# parameter 1: LaTeX file without extension --# parameter 2: log-file where the full out put is stored --# return value: 0 - no errors (no rerun); 1 - errors (rerun required) -- --sub run_pdflatex { -- my $texfile=$_[0]; -- my $logfile=$_[1]; -- my @errors=(); -- my $exit_status=0; -- my $extra_options=¶m_value('pdftex_opts'); -- -- if( !defined($extra_options) or $extra_options eq $NIL ) { -- $extra_options = ""; -- } -- -- &report(7, "Running pdflatex. This may take a while.\n"); -- system("pdflatex --interaction nonstopmode $extra_options $texfile > $logfile 2>&1"); -- $exit_status=$?; -- &report(7, "Pdflatex finished. Errors:"); -- -- ### extract all errors and warnings from the log file -- @errors = &grep_file($logfile, '(Emergency stop|Error|Warning).*:'); -- -- ### make sure thumbpdf package does not spoil rerun detection -- ### as it will be processed very last -- if(grep(/Package thumbpdf/, @errors) == @errors) { @errors=(); } -- -- if ( @errors != 0 or $exit_status != 0 ) { -- if ( grep(/Emergency stop/, @errors) != 0 ) { -- &report(2, &file_tail($logfile,10)); -- &report(2, "\nSee $logfile for details."); -- &abort("Fatal error occured. I am lost."); -- } -- if( @errors != 0 ) { -- &report(8, @errors); -- } else { -- &report(8, &file_tail($logfile,10)); -- } -- &report(7, "\nSee $logfile for details."); -- return $FALSE; -- } else { -- &report(7, "None detected (log file: $logfile)."); -- return $TRUE; -- } --} -- --#### run bibtex if BIBTEX=$YES or a bibliography tag is found --# included tex files are not parsed for a bibliography --# parameter 1: filename of the aux file without .aux suffix --# parameter 2: log-file where the full out put is stored -- --sub handle_bibtex { -- my $auxfile=$_[0]; -- my $logfile=$_[1]; -- my $run_bibtex=$FALSE; -- my $bibtex_param=¶m_value('bibtex'); -- -- if ( $bibtex_param eq $YES ) { -- $run_bibtex=$TRUE; -- &report(7, "BibTeX parameter set to '$YES':"); -- } else { -- &report(7, "Checking for BibTeX bibliography in main document: "); -- if( &grep_file($auxfile.'.tex', '^[^%]*\\\\bibliography{') != 0) { -- $run_bibtex=$TRUE; -- &report(7, "Bibliography detected."); -- } else { -- if ( @REF_DOCS > 0 ) { -- &report(7, "Checking for BibTeX bibliography in included documents:"); -- foreach my $file (@REF_DOCS) { -- if( &grep_file($file, '^[^%]*\\\\bibliography{') != 0) { -- $run_bibtex=$TRUE; -- &report(7, "Bibliography detected."); -- } else { -- &report(7, "No bibliography detected in $file."); -- } -- } -- } else { -- &report(7, "No bibliography detected."); -- } -- } -- } -- -- if ( $run_bibtex ) { -- my @errors=(); -- my $exit_status=0; -- -- &report(7, "Running bibtex. This may take a while.\n"); -- system "bibtex $auxfile > $logfile"; -- $exit_status=$?; -- &report(7, "Bibtex finished. Errors:"); -- -- ### extract all errors and warnings from the log file -- @errors=&grep_file($logfile, 'error message'); -- -- if ( @errors != 0 or $exit_status != 0 ) { -- &report(4, &file_tail($logfile)); -- &report(4, "\nYou can switch off BibTeX support by setting the bibtex parameter accordingly."); -- } else { -- &report(7, "None detected (log file: $logfile)."); -- } -- } --} -- --#### run bibtex on file.gls if BIBTEX=$YES or a bibliography tag is found --# included tex files are not parsed for a bibliography --# parameter 1: filename of the aux file without .aux suffix --# parameter 2: log-file where the full out put is stored -- --sub handle_gloss { -- my $auxfile=$_[0]; -- my $logfile=$_[1]; -- my $run_gloss=$FALSE; -- my $gloss_param=¶m_value('gloss'); -- my $glsfile=$auxfile.'.gls'; -- -- if ( $gloss_param eq $YES ) { -- $run_gloss=$TRUE; -- &report(7, "Gloss parameter set to '$YES':"); -- } else { -- &report(7, "Checking for Gloss bibliography in main document: "); -- if( &grep_file($auxfile.'.tex', '^[^%]*\\\\printgloss{') != 0) { -- $run_gloss=$TRUE; -- &report(7, "Gloss bibliography detected."); -- } else { -- if ( @REF_DOCS > 0 ) { -- &report(7, "Checking for Gloss bibliography in included documents:"); -- foreach my $file (@REF_DOCS) { -- if( &grep_file($file, '^[^%]*\\\\printgloss') != 0) { -- $run_gloss=$TRUE; -- &report(7, "Gloss bibliography detected."); -- } else { -- &report(7, "No gloss database detected in $file."); -- } -- } -- } else { -- &report(7, "No gloss database detected."); -- } -- } -- } -- if ( $run_gloss ) { -- my @errors=(); -- my $exit_status=0; -- -- &report(7, "Running bibtex on $glsfile. This may take a while.\n"); -- system "bibtex $glsfile > $logfile 2>&1"; -- $exit_status=$?; -- &report(7, "Bibtex finished. Errors:"); -- -- ### extract all errors and warnings from the log file -- @errors=&grep_file($logfile, 'error message'); -- -- if ( @errors != 0 or $exit_status != 0 ) { -- &report(4, &file_tail($logfile)); -- &report(4, "\nYou can switch off Gloss support by setting the gloss parameter accordingly."); -- } else { -- &report(7, "None detected (log file: $logfile)."); -- } -- } --} -- --#### run thumbpdf command to make thumbnails --# more informations: /usr/share/texmf/doc/pdftex/thumbpdf/readme.txt --# parameter 1: LaTeX file without extension --# parameter 2: log-file where the full out put is stored -- --sub run_thumbpdf { -- my $texfile=$_[0]; -- my $logfile=$_[1]; -- my $exit_status=0; -- -- &report(7, "\nCreating thumbnails with 'thumbpdf'\n"); -- &system_command("thumbpdf $texfile", $FALSE, 8, -- "thumbpdf failed.\n" -- ."I will continue, but maybe there will not be thumbs in the PDF doc."); -- -- if ( -f 'thumbpdf.log' ) { -- move('thumbpdf.log', $logfile); -- &report(7, "\nSee $logfile for details."); -- } -- -- ### store possible tmp files -- push(@TMPFILES, glob 'thumb???.png'); -- push(@TMPFILES, 'thumbpdf.pdf'); -- push(@TMPFILES, 'thumbdta.tex'); -- push(@TMPFILES, $texfile.'.tpt'); --} -- -- --#### run ppower command to make presentations --# more informations: --# parameter 1: LaTeX file without extension --# parameter 2: log-file where the full out put is stored -- --sub run_ppower { -- my $texfile=$_[0]; -- my $logfile=$_[1]; -- my $exit_status=0; -- my $infile; -- my $outfile; -- my $texfile_base; -- my $texfile_path; -- my $texfile_suffix; -- -- ##### Getting document name, suffix and path -- ($texfile_base,$texfile_path,$texfile_suffix) = fileparse($texfile,¶m_value('tmp_base_suffix')); -- -- $infile=$texfile_base.'.pdf'; -- $outfile=$texfile_base.'_p4.pdf'; -- -- &report(7, "\nPostprocessing PDF file with 'ppower'\n"); -- if(&system_command("ppower $infile $outfile", $FALSE, 8, -- "ppower failed.\nI will continue, " -- ."but maybe there will not be pause effects in the PDF doc.")) { -- &report(7, "\nThe postprocessed pdf file is: $outfile\n"); -- } -- -- if ( -f 'ppower.log' ) { -- move('ppower.log', $logfile); -- &report(7, "See $logfile for details."); -- } --} -- --#### run authorindex command to obtain an author index --# more informations: --# parameter 1: LaTeX file without extension --# parameter 2: log-file where the full out put is stored -- --sub run_authorindex { -- my $texfile=$_[0]; -- my $logfile=$_[1]; -- my $exit_status=0; -- -- &report(7, "\nProcessing file with 'authorindex'\n"); -- &system_command("authorindex $texfile", $FALSE, 8, -- "authorindex failed.\nI will continue, " -- ."but maybe there will not be an author index in the PDF doc."); -- -- if ( -f 'authorindex.log' ) { -- move('authorindex.log', $logfile); -- &report(7, "\nSee $logfile for details."); -- } -- --} -- -- --##### read and analyse configuration and options and adjust basic variables --##### accordingly --#### The following sources are considered (last value overrides previous) --## 1. general configuration (global variables in the script) --## 2. private configuration (in user's RC file) --## 3. command line options --# parameters: none --# return value: given document argument -- --sub adjust_configuration { -- my $valid_rcfile = $FALSE; -- my %opt_specs =(); -- -- ### Check number of arguments -- if ( @ARGV == 0 ) { -- &report(1, "\nI need at least one argument!"); -- &print_usage; -- exit 1; -- } -- -- ##### command line options and private configuration files handling -- -- ### set parameters from rc file -- if ( -f $RC_FILENAME ) { -- my $rcfile_version; -- $rcfile_version = &read_configuration($RC_FILENAME); -- if( $rcfile_version == $MYRCFILE_VERSION ) { -- $valid_rcfile = $TRUE; -- } elsif ( $rcfile_version == 0 ) { -- &report(4, "Could not determine version of read RC file."); -- } else { -- &report(4, "Version of read RC file ($rcfile_version) and ", -- "this script ($MYRCFILE_VERSION) differs."); -- } -- } -- -- ### scan parameters -- foreach (keys %PARAMETER_LIST) { -- $opt_specs{&option_specifier($_)} = \&handle_option; -- } -- if(! GetOptions(%opt_specs)) { -- &print_usage; -- &abort("An error occured while processing command line options"); -- } -- -- if( ! $valid_rcfile ) { -- &report(3,"No valid configuration file found. Please run '$MYNAME " -- ."--configure'.\nUsing default values for missing parameters in this " -- ."session."); -- } -- -- ### As the configuration process is done now, it is time to set the -- # global configuration flag -- $CONFIGURED = $TRUE; -- -- #### do some test in order to secure as good as possible that we will -- #### succeed before to much work was done and maybe some data as damaged -- -- ### make sure that tmp_base_suffix is not empty -- if ( ¶m_value('tmp_base_suffix') eq "" ) { -- &report(2, "\nCAUTION: Empty tmp_base_suffix would destroy the original files!"); -- &abort("Parameter tmp_base_suffix is not set."); -- } -- -- ##### check for required commands -- if (¶m_value('check_commands') ne $NO ) { -- &check_commands; -- } -- -- ### Check number of arguments -- if ( @ARGV != 1 ) { -- &report(1, "\nWrong number of arguments. I need exactly one file."); -- &print_usage; -- exit 1; -- } -- -- return $ARGV[0]; --} -- --#### prepare the logdir for the log files of the various called appplications -- --sub prepare_logdir { -- my $log_dir= ¶m_value('logdir'); -- my $my_new_log; -- -- ##### Preparing the LOGDIR -- if (! &check_dir($log_dir, "Could not create log directory", $YES)) { -- &abort("Please, set a different path and restart"); -- } -- -- # make sure there is a slash at the end of the path -- $log_dir .= '/' if( ! ($log_dir =~ m#/$#) ); -- -- if( <$log_dir/*.log> and ¶m_value('clean_logs') eq $YES ) { -- &report(6, "\nRemoving old log files ($log_dir)."); -- unlink (<$log_dir/pdflatex-*.log>, <$log_dir/bibtex-*.log>, -- <$log_dir/gloss-*.log>, <$log_dir/thumbpdf-*.log>, -- <$log_dir/ppower-*.log>, <$log_dir/authorindex-*.log>, -- <$log_dir/tex2pdf-*.log>); -- } else { -- &report(6, "\nAll log files will be stored in ($log_dir)."); -- } -- -- ### move my pre-configuration log file to specified log directory -- $my_new_log = "$log_dir/tex2pdf-$$.log"; -- if ( move($MYLOGFILE, $my_new_log) ) { -- $MYLOGFILE = $my_new_log; -- } else { -- &report(3, "Could not move '$MYLOGFILE' to logdir: $!"); -- } --} -- --##### analyse document argument --#### process the one and only argument (besides the options) which specifies --#### which LaTeX document the user wants to translate to PDF --#### a lyx file will be translated to LaTeX first --# parameter 1: argument -- --sub process_doc_argument { -- my $argument = $_[0]; -- my $doc_base; -- my $doc_path; -- my $arg_suffix; -- -- ##### Getting document name, suffix and path -- ($doc_base,$doc_path,$arg_suffix) = fileparse($argument, ('\.tex', '\.lyx')); -- -- if (! defined($arg_suffix) or $arg_suffix eq "") { -- $arg_suffix = '.tex'; -- } -- -- ###### change working directory to document directory -- if ( $doc_path ne "" ) { -- chdir $doc_path; -- } -- -- ###### make DOCPATH an absolute path -- $doc_path = cwd.'/'; -- -- ###### Cut off suffix and do lyx or tex specific stuff -- if ( $arg_suffix eq '.lyx' ) { -- # Lyx document argument: generate Latex document if required -- &generate_tex_file($doc_base.'.lyx', $doc_base.'.tex'); -- } else { -- # LaTeX document argument: check access to given LaTeX document -- &check_file($doc_base.'.tex', "Cannot read the specified LaTeX document!"); -- } -- -- return $doc_path.$doc_base.'.tex'; --} -- --#### handle the dir of the input path if the document has one and --# parameter 1: main tex doc --# return value: absolute input path -- --sub process_inputpath { -- my $texdoc = $_[0]; -- my $doc_base; -- my $doc_path; -- my $doc_suffix; -- my $input_path; -- my @matches; -- -- ### Maybe the user has given us a different inputpath -- $input_path = ¶m_value('input_path'); -- if(defined($input_path) and $input_path ne "") { -- &report(6, "Setting input path to specified directory: $input_path"); -- -- &report(7, "Change working directory to input path."); -- chdir $input_path; -- -- return $input_path; -- } -- -- ##### Getting document name, suffix and path -- ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex')); -- -- ###### change working directory to input_path if set -- # When the files' path (images, included documents, etc.) in your document is -- # relative to another directory than the PASSED document's directory. -- # This is useful when the calling application (e.g. LyX) generates a -- # temporary -- # TeX file and calls the tex2pdf with it instead of the original file. -- -- @matches=&extract_tag_contents($texdoc, 'def\\\\input@path'); -- $input_path=$matches[0]; -- -- ## check if input_path is ok -- if ($input_path) { -- &report(7, "Found an input path in the latex document: $input_path"); -- if( &check_dir($input_path, 'The retrieved input@path seems not to be valid.', $NO)) { -- &set_param_value('input_path', $input_path); -- &report(7, "Change working directory to input path."); -- chdir $input_path; -- } else { -- &abort ('I am lost.'); -- } -- } else { -- &report(4, "No input path in the latex document found."); -- &report(7, "Resources are expected to be relative to document's location: $doc_path"); -- $input_path=$doc_path; -- } -- -- return $input_path; --} -- --#### set the working dir to the input path if the document has one and --#### and determine the path for the result --# parameter 1: main tex doc --# parameter 2: absolute input path --# return value: absolute path were the resulting pdf doc should be stored -- --sub get_target_name { -- my $texdoc = $_[0]; -- my $input_path=$_[1]; -- -- my $doc_base; -- my $doc_path; -- my $doc_suffix; -- my $destination; -- my $pdf_path; -- -- ##### Getting document name, suffix and path -- ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex')); -- -- ##### set the directory where the final pdf will be stored -- $destination=¶m_value('destination'); -- $pdf_path=undef; -- -- if ($destination eq 'custom' ) { -- $pdf_path=¶m_value('custom_path'); -- } elsif ($destination eq 'input') { -- $pdf_path=$input_path; -- } else { -- $pdf_path=$doc_path; -- } -- -- if( ! defined($pdf_path) or $pdf_path eq "" or ! &check_dir($pdf_path, -- 'The specified destination directory for the final PDF documents is not valid.', $NO)) { -- &report(7, "Using document's instead of destination path: $doc_path"); -- $pdf_path=$doc_path; -- } -- -- # make sure there is a slash at the end of the path -- $pdf_path .= '/' if( ! ($pdf_path =~ m#/$#) ); -- -- return $pdf_path.$doc_base.'.pdf'; --} -- --### generate hyperref parameters from given settings --# parameter 1: main tex doc --# return_value: result -- --sub generate_hyperref_params { -- my $texdoc = $_[0]; -- my $para; -- my @params = ('pdftex'); -- -- ##### Set title and author from main LaTeX document or parameters -- foreach my $info (('title', 'author')) { -- my $value; -- -- $value=¶m_value("$info"); -- if (! defined($value) ) { -- my @matches=&extract_tag_contents($texdoc, $info); -- $value= $matches[0]; -- if (! defined($value) ) { -- &report(4, "\nWARNING: Could not identify document's $info correctly."); -- &report(7, "Maybe you have used a LaTeX tag inside the $info which confuses me.\n", -- "Adjust the $info of the LaTeX file in order to avoid the problem or\n", -- "you could set the $info parameter manually."); -- $value= ¶m_value("default_$info"); -- &report(7, "Using default-$info: $value"); -- } -- } -- if (! defined($value) or $value eq $NIL ) { -- &report(7, "$info field set to $NIL - no value will be passed."); -- } else { -- &report(7, "Document's $info: $value"); -- push(@params, "pdf$info={$value}"); -- } -- } -- -- $para=¶m_value('paper'); -- if ( $para ne $NIL ) { push(@params, $para); } -- -- $para=¶m_value('link_toc_page'); -- if ( $para eq $YES ) { push(@params, 'linktocpage'); } -- -- $para=¶m_value('colorlinks'); -- if ( $para ne $NIL ) { -- $para= $para eq $YES ? 'true' : 'false'; -- push(@params, "colorlinks=$para"); -- } -- -- if ( $para ne 'false' ) { -- foreach (('linkcolor', 'pagecolor', 'urlcolor', 'citecolor')) { -- $para=¶m_value($_); -- if ( $para ne $NIL ) { push(@params, "$_={$para}"); } -- } -- } -- -- $para=¶m_value('hyperref_args'); -- if(defined($para) and $para ne "" and $para ne $NIL) { -- push(@params, $para); -- } -- -- return @params; --} -- --#### Prepare the main document and all referenced ones for the generation --#### of the PDF document (including referenced images) --# parameter 1: top level tex document --# parameter 2: parameter list of hyperref parameters -- --sub prepare_documents { -- my ($main_tex_doc, $input_path, @hyperref_params) = @_; -- @REF_DOCS=(); -- -- ## get a name for the tmp tex file -- my $main_tmp_doc = &reserve_tmp_texname($main_tex_doc, $input_path); -- -- ## Get the list of imported files from the tex file -- &get_file_list($main_tex_doc); -- -- ## remove main file from list (first element; needs special handling) -- shift @REF_DOCS; -- -- ## tell user about the identified refereneced docs -- if ( @REF_DOCS > 0 ) { -- &report(7, "\nFound the following referenced TeX files:"); -- foreach my $file (@REF_DOCS) { -- &report(7, ">>>>> $file"); -- } -- } else { -- &report(7, "\nFound no referenced TeX files."); -- } -- -- ##### Generate adjusted temp tex files and convert all their images -- ## main doc -- &report(6, "\nGenerating main temporary LaTeX document: $main_tmp_doc"); -- &convert_tex2tmp($main_tex_doc, $main_tmp_doc, \@hyperref_params); -- &convert_images($main_tex_doc); -- -- ## referenced docs -- foreach my $file (@REF_DOCS) { -- my $tmp_file = &reserve_tmp_texname($file); -- -- ### Insert pdf conversation tags in tex file and write it to tmp_file -- &report(7, "\nGenerating temporary LaTeX document: $tmp_file"); -- &convert_tex2tmp($file, $tmp_file, undef); -- &convert_images($file); -- } -- -- return $main_tmp_doc; --} -- --##### Generate the final PDF document --# parameter 1: filename of the source LaTeX document (with extension) -- --sub generate_pdf_doc { -- my $source = $_[0]; -- my $runno=1; -- my $rerun=$TRUE; -- my $doc; -- my $pdf_doc; -- my $base; -- my $path; -- my $suffix; -- -- my $max_run_no= ¶m_value('maxrun'); -- my $min_run_no= ¶m_value('minrun'); -- my $log_dir= ¶m_value('logdir'); -- $log_dir .= '/' if( ! ($log_dir =~ m#/$#) ); -- my $makeindex_options=¶m_value('makeindex_opts'); -- -- # setting the log files for the output of pdflatex, bibtex, gloss, -- # thumbpdf, ppower and authorindex -- my $pdflog_base = $log_dir."pdflatex-$$-"; -- my $bibtex_log = $log_dir."bibtex-$$.log"; -- my $gloss_log = $log_dir."gloss-$$.log"; -- my $thumbpdf_log = $log_dir."thumbpdf-$$.log"; -- my $ppower_log = $log_dir."ppower-$$.log"; -- my $authorindex_log = $log_dir."authorindex-$$.log"; -- -- ##### Getting document name, suffix and path -- ($base,$path,$suffix) = fileparse($source, ('\.tex')); -- $doc = $path.$base; -- $pdf_doc = $base.'.pdf'; -- -- ### run pdflatex until no more errors are reported (max MAXRUNNO) -- while ( $rerun and $runno <= $max_run_no ) -- { -- &report(6, "\n************ Pdflatex run no. $runno *************"); -- if ( &run_pdflatex($doc, $pdflog_base.$runno.'.log') == $TRUE -- and ( $min_run_no <= $runno )) { -- # no errors detected and min. no. of runs are done -- $rerun=$FALSE; -- } else { -- # errors appeared or max run no. has not been reached -- $rerun=$TRUE; -- } -- -- ### Execute BibTeX after first run if set (and required) -- if ( $runno == 1 and ¶m_value('bibtex') ne $NO ) { -- &report(6, "\n****************** BibTeX handling ***********************"); -- &handle_bibtex($doc, $bibtex_log); -- } -- -- ### Execute BibTeX on file.gls after first run if set (and required) -- if ( $runno == 1 and ¶m_value('gloss') ne $NO ) { -- &report(6, "\n****************** Gloss handling ***********************"); -- &handle_gloss($doc, $gloss_log); -- } -- -- ### generated index file exists -- if ( $runno == 1 and -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) { -- if( !defined($makeindex_options) or $makeindex_options eq $NIL ) { -- $makeindex_options = ""; -- } -- &report(6, "\n****************** Extra index generation ***************"); -- &report(7, "Document seems to have an index. Generating ...\n"); -- &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8, -- "makeindex failed.\nI will continue, " -- ."but maybe there will not be an index in the PDF doc."); -- } -- -- $runno += 1; -- } -- -- $rerun = $FALSE; -- -- ### if the authorindex option is switched on then run authorindex -- if ( ¶m_value('authorindex') eq $YES ) { -- &report(6, "\n****************** authorindex generation *****************"); -- &run_authorindex($doc, $authorindex_log); -- } -- -- ### generated index file exists -- if ( -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) { -- if( !defined($makeindex_options) or $makeindex_options eq $NIL ) { -- $makeindex_options = ""; -- } -- &report(6, "\n****************** Extra index generation ***************"); -- &report(7, "Document seems to have an index. Generating ...\n"); -- &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8, -- "makeindex failed.\nI will continue, " -- ."but maybe there will not be an index in the PDF doc."); -- $rerun=$TRUE; -- } -- -- ### if the thumbpdf option is switched on then make thumbnails -- if ( ¶m_value('thumbpdf') eq $YES ) { -- &report(6, "\n****************** Thumbnail generation *****************"); -- &run_thumbpdf($doc, $thumbpdf_log); -- $rerun=$TRUE; -- } -- -- ### One final pdflatex run if requested -- if ( $rerun ) { -- &report(6, "\n************ One final pdflatex run no. $runno *************"); -- &run_pdflatex($doc, $pdflog_base.$runno.'.log'); -- } -- -- ### if the ppower option is switched on then run ppower -- if ( ¶m_value('ppower') eq $YES ) { -- &report(6, "\n****************** ppower postprocess *****************"); -- &run_ppower($doc, $ppower_log); -- } -- -- if ( ! -f $pdf_doc ) { -- &abort("\nThe new PDF file could not be generated: ".$pdf_doc); -- } -- -- return $pdf_doc; --} -- --################## Lift off !!!! (main part) ################## -- --my $texdoc; --my $doc_argument; --my $input_path; --my $target_name; --my @hyperref_params; --my $new_pdf_doc; --my $tmp_tex_doc; -- --&report(5, "\nScript starts ($MYRELEASE)"); -- --##### read and analyse configuration and options and adjust basic variables --##### accordingly --##### write RC file on config request --#### use the finished configuration to get all further settings before we --#### actually start doing something -- --&report(5, "\nProcessing given parameters and arguments."); --$doc_argument = &adjust_configuration; -- --#### prepare the script to write some information to specified log files -- --&report(5, "\nPreparing directory for log files."); --&prepare_logdir; -- --#### process the one and only argument (besides the options) which specifies --#### which LaTeX document the user wants to translate to PDF --#### a lyx file will be translated to LaTeX first -- --&report(5, "\nAnalysing your document argument."); --$texdoc = &process_doc_argument($doc_argument); -- --#### we would like to get some more information from the actual --#### main LaTeX document before we really start --#### parse the document and try to get the info -- --## translate hyperref settings to the actual package parameters -- --&report(5, "\nSetting up parameters for hyperref."); --@hyperref_params = &generate_hyperref_params($texdoc); -- --## set the working dir to the input path if the document has one and -- --&report(5, "\nProcessing input path for main tex document."); --$input_path = &process_inputpath($texdoc); -- --## determine the name for the result -- --&report(5, "\nSetting the correct name for the result."); --$target_name = &get_target_name($texdoc, $input_path); -- --## as much as possible is prepared in advance at this point --## so hopefully we will succeed in generating the PDF document -- --##### real work starts NOW -- --##### Generate adjusted temp tex files and convert all their images -- --&report(5, "\nPreparing all documents and images."); --$tmp_tex_doc = &prepare_documents($texdoc, $input_path, @hyperref_params); -- --##### Generate the final PDF document -- --&report(5, "\nProcessing the actual generation of the PDF document."); --$new_pdf_doc = &generate_pdf_doc($tmp_tex_doc); -- --##### Finalize --move($new_pdf_doc, $target_name) or &abort("Could not move PDF file to final destination: $!"); -- --if ( ¶m_value('debug') eq $NO ) { -- &clean_up; --} else { -- &print_temp_files; --} -- --&report(5, "\nThe new pdf file is: $target_name\n"); -- diff --cc lustre/extN/.cvsignore index 8a8af37,8a8af37..0000000 deleted file mode 100644,100644 --- a/lustre/extN/.cvsignore +++ /dev/null @@@ -1,19 -1,19 +1,0 @@@ --.Xrefs --Makefile --Makefile.in --.deps --TAGS --balloc.c --bitmap.c --dir.c --file.c --fsync.c --ialloc.c --inode.c --ioctl.c --namei.c --super.c --symlink.c --xattr.c --patch-stamp --sed-stamp diff --cc lustre/extN/Makefile.am index 2ff23b0,2ff23b0..0000000 deleted file mode 100644,100644 --- a/lustre/extN/Makefile.am +++ /dev/null @@@ -1,146 -1,146 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS=-DEXPORT_SYMTAB --MODULE = extN --modulefs_DATA = extN.o --EXTRA_PROGRAMS = extN -- --# NOTE: If you are not using a RedHat 12.5 or later kernel, then you need to --# apply the "fixes" patch first, as it fixes a number of bugs in ext3. --# It will be applied automatically by the extN build process, or you --# can apply it to the source kernel tree and fix ext3 also. For chaos22 --# (or other RH < 12.5 kernels) use the "chaos22" patch instead. --EXTN_FIXES = ../patches/patch-2.4.18-chaos22 --#EXTN_FIXES = ext3-2.4.18-fixes.diff --EXTNP = htree-ext3-2.4.18.diff linux-2.4.18ea-0.8.26.diff --EXTNP+= ext3-2.4.18-ino_sb_macro.diff extN-misc-fixup.diff --EXTNC = balloc.c bitmap.c dir.c file.c fsync.c ialloc.c inode.c ioctl.c --EXTNC+= namei.c super.c symlink.c --EXTNI = extN_fs.h extN_fs_i.h extN_fs_sb.h extN_jbd.h quotaops.h --EXTN_EXTRA = include/linux/xattr.h include/linux/extN_xattr.h fs/extN/xattr.c --EXTN_EXTRA += include/linux/quotaops.h --extN_SOURCES = $(EXTNC) xattr.c # punch.c --extN_DEPENDENCIES = patch-stamp --EXTRA_DIST = $(EXTNP) $(EXTN_FIXES) \ -- extN-2.4.18-ino_sb_fixup.diff extN-2.4.18-exports.diff \ -- $(wildcard extN.patch-*) --DISTCLEANFILES = -r $(extN_SOURCES) sed-stamp patch-stamp *.orig *.rej --SUB=-e "s/ext3/extN/g" -e "s/EXT3/EXTN/g" -e "s/extern __inline__/static inline/" -- --distclean: -- cd .. && rm -f $(EXTN_EXTRA) -- --include $(top_srcdir)/Rules -- --# Following 2 vars are for buildind outside the source tree. --extN_orig = $(top_builddir)/$(subdir)/extN.orig --extN_include_orig = $(top_builddir)/$(subdir)/extN-include.orig -- --# Create a fresh extN patch. --# This is for when the patch-stamp target fails for your kernel. --# Just edit the files until you like them, then do `make diff', and --# it will create a specialized patch for your particular kernel. --# Check it in, and the build should work for you without disrupting --# the other developers. --# Of course, the ideal is to merge changes so that the default patch --# set works for nearly everybody. This is mainly for damage control. -- --diff: -- $(RM) extN.patchT -- l='$(EXTNC)'; for f in $$l; do \ -- echo "$$f"; \ -- (diff -u $(extN_orig)/$$f extN/$$f) >> extN.patchT; \ -- test $$? -le 1 || exit 1; -- done -- l='$(EXTNI)'; for f in $$l; do \ -- echo "$$f"; \ -- (diff -u $(extN_include_orig)/$$f $(top_srcdir)/include/linux/$$f)>>extN.patchT;\ -- test $$? -le 1 || exit 1; -- done -- l='$(EXTN_EXTRA)'; for f in $$l; do \ -- f=`echo "$$f" | sed 's%^fs/%%'`; \ -- echo "$$f"; \ -- (cd $(top_srcdir) && \ -- diff -u /dev/null $$f) >> extN.patchT; \ -- test $$? -le 1 || exit 1; -- done -- mv -f extN.patchT $(top_builddir)/$(subdir)/extN.patch-$(RELEASE) -- echo "Don't forget to add $(srcdir)/extN.patch-$(RELEASE) to CVS!" -- -- -- --.PHONY: diff -- --# Just do the SUB transformation on all our source files. -- -- --sed-stamp: -- $(RM) $@ -- rm -rf $(extN_orig) $(extN_include_orig) -- mkdir $(extN_orig) $(extN_include_orig) -- list='$(EXTNC)'; for f in $$list; do \ -- echo "creating $(extN_orig)/$$f"; \ -- sed $(SUB) $(LINUX)/fs/ext3/$$f > $(extN_orig)/$$f; \ -- done -- list='$(EXTNI)'; for i in $$list; do \ -- s=`echo $$i | sed "s/extN/ext3/"`; \ -- echo "creating $(extN_include_orig)/$$i"; \ -- sed $(SUB) $(LINUX)/include/linux/$$s > $(extN_include_orig)/$$i; \ -- done -- echo timestamp > $@ -- -- --# Patch the kernel files with our ext3 patches. We need to go through some --# extra hoops because the include files are in a different tree and because --# patch likes to make local copies of files with (sym)links when it is patching --# them. To avoid this, we copy/patch in the source dir instead of the build --# dir (if they are different). --# We also want to preserve the pristine transformed files for the diff target. -- -- -- --patch-stamp: sed-stamp $(EXTNP) -- test -e $(top_builddir)/include/linux || mkdir -p $(top_builddir)/include/linux -- cp -a $(extN_orig)/* $(top_builddir)/$(subdir) -- cp -a $(extN_include_orig)/* $(top_builddir)/include/linux -- test -e $(top_builddir)/fs || ln -s . $(top_builddir)/fs -- list='$(EXTN_EXTRA)'; for f in $$list; do $(RM) $(top_builddir)/$$f; done -- if [ -f $(srcdir)/extN.patch-$(RELEASE) ]; then \ -- echo "applying patch $(srcdir)/extN.patch-$(RELEASE)"; \ -- (cd $(top_builddir) && patch -p0) < $(srcdir)/extN.patch-$(RELEASE); \ -- else \ -- echo "If first patch fails, read NOTE in extN/Makefile.am"; \ -- list='$(EXTNP)'; \ -- sed '/i_version/q' $(extN_orig)/namei.c | tail -2 | \ -- grep extN_mark_inode_dirty >/dev/null && list="$(EXTN_FIXES) $$list"; \ -- for p in $$list; do \ -- echo "applying patch $$p"; \ -- sed $(SUB) $(srcdir)/$$p | \ -- (cd $(top_builddir) && patch -p1) || exit $$?; \ -- done; \ -- echo "It is OK if the next patch says it is already applied"; \ -- echo "applying patch $(srcdir)/extN-2.4.18-exports.diff"; \ -- (cd $(top_builddir) && \ -- patch -N -p1) < $(srcdir)/extN-2.4.18-exports.diff; \ -- echo "applying patch $(srcdir)/extN-2.4.18-ino_sb_fix.diff"; \ -- (cd $(top_builddir) && \ -- patch -p1) < $(srcdir)/extN-2.4.18-ino_sb_fixup.diff || exit $$?; \ -- fi -- echo timestamp > $@ -- -- -- -- --$(extN_SOURCES) $(EXTNI) $(EXTN_EXTRA): patch-stamp -- --# Don't distribute any patched files. --dist-hook: -- $(RM) $(top_srcdir)/fs -- list='$(EXTNC)'; for f in $$list; do $(RM) $(distdir)/$$f; done -- list='$(EXTNI)'; for i in $$list; do \ -- $(RM) $(distdir)/../include/linux/$$i; \ -- done -- list='$(EXTN_EXTRA)'; for f in $$list; do $(RM) $(distdir)/../$$f; done diff --cc lustre/extN/ext3-2.4.18-fixes.diff index 56e841e,56e841e..0000000 deleted file mode 100644,100644 --- a/lustre/extN/ext3-2.4.18-fixes.diff +++ /dev/null @@@ -1,353 -1,353 +1,0 @@@ --diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c ----- lum-2.4.18-um30/fs/ext3/balloc.c Mon Feb 25 12:38:08 2002 --+++ uml-2.4.18-12.5/fs/ext3/balloc.c Thu Sep 19 13:40:11 2002 --@@ -276,7 +276,8 @@ -- } -- lock_super (sb); -- es = sb->u.ext3_sb.s_es; --- if (block < le32_to_cpu(es->s_first_data_block) || --+ if (block < le32_to_cpu(es->s_first_data_block) || --+ block + count < block || -- (block + count) > le32_to_cpu(es->s_blocks_count)) { -- ext3_error (sb, "ext3_free_blocks", -- "Freeing blocks not in datazone - " --@@ -309,17 +310,6 @@ -- if (!gdp) -- goto error_return; -- --- if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) || --- in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) || --- in_range (block, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group) || --- in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group)) --- ext3_error (sb, "ext3_free_blocks", --- "Freeing blocks in system zones - " --- "Block = %lu, count = %lu", --- block, count); --- -- /* -- * We are about to start releasing blocks in the bitmap, -- * so we need undo access. --@@ -345,14 +335,24 @@ -- if (err) -- goto error_return; -- --- for (i = 0; i < count; i++) { --+ for (i = 0; i < count; i++, block++) { --+ if (block == le32_to_cpu(gdp->bg_block_bitmap) || --+ block == le32_to_cpu(gdp->bg_inode_bitmap) || --+ in_range(block, le32_to_cpu(gdp->bg_inode_table), --+ sb->u.ext2_sb.s_itb_per_group)) { --+ ext3_error(sb, __FUNCTION__, --+ "Freeing block in system zone - block = %lu", --+ block); --+ continue; --+ } --+ -- /* -- * An HJ special. This is expensive... -- */ -- #ifdef CONFIG_JBD_DEBUG -- { -- struct buffer_head *debug_bh; --- debug_bh = sb_get_hash_table(sb, block + i); --+ debug_bh = sb_get_hash_table(sb, block); -- if (debug_bh) { -- BUFFER_TRACE(debug_bh, "Deleted!"); -- if (!bh2jh(bitmap_bh)->b_committed_data) --@@ -365,9 +365,8 @@ -- #endif -- BUFFER_TRACE(bitmap_bh, "clear bit"); -- if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) { --- ext3_error (sb, __FUNCTION__, --- "bit already cleared for block %lu", --- block + i); --+ ext3_error(sb, __FUNCTION__, --+ "bit already cleared for block %lu", block); -- BUFFER_TRACE(bitmap_bh, "bit already cleared"); -- } else { -- dquot_freed_blocks++; --@@ -415,7 +417,6 @@ -- if (!err) err = ret; -- -- if (overflow && !err) { --- block += count; -- count = overflow; -- goto do_more; -- } --@@ -542,6 +543,7 @@ -- int i, j, k, tmp, alloctmp; -- int bitmap_nr; -- int fatal = 0, err; --+ int performed_allocation = 0; -- struct super_block * sb; -- struct ext3_group_desc * gdp; -- struct ext3_super_block * es; --@@ -575,6 +577,7 @@ -- -- ext3_debug ("goal=%lu.\n", goal); -- --+repeat: -- /* -- * First, test whether the goal block is free. -- */ --@@ -644,8 +647,7 @@ -- } -- -- /* No space left on the device */ --- unlock_super (sb); --- return 0; --+ goto out; -- -- search_back: -- /* --@@ -684,16 +686,28 @@ -- if (tmp == le32_to_cpu(gdp->bg_block_bitmap) || -- tmp == le32_to_cpu(gdp->bg_inode_bitmap) || -- in_range (tmp, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group)) --- ext3_error (sb, "ext3_new_block", --- "Allocating block in system zone - " --- "block = %u", tmp); --+ EXT3_SB(sb)->s_itb_per_group)) { --+ ext3_error(sb, __FUNCTION__, --+ "Allocating block in system zone - block = %u", tmp); --+ --+ /* Note: This will potentially use up one of the handle's --+ * buffer credits. Normally we have way too many credits, --+ * so that is OK. In _very_ rare cases it might not be OK. --+ * We will trigger an assertion if we run out of credits, --+ * and we will have to do a full fsck of the filesystem - --+ * better than randomly corrupting filesystem metadata. --+ */ --+ ext3_set_bit(j, bh->b_data); --+ goto repeat; --+ } --+ -- -- /* The superblock lock should guard against anybody else beating -- * us to this point! */ -- J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data)); -- BUFFER_TRACE(bh, "setting bitmap bit"); -- ext3_set_bit(j, bh->b_data); --+ performed_allocation = 1; -- -- #ifdef CONFIG_JBD_DEBUG -- { --@@ -815,6 +829,11 @@ -- ext3_std_error(sb, fatal); -- } -- unlock_super (sb); --+ /* --+ * Undo the block allocation --+ */ --+ if (!performed_allocation) --+ DQUOT_FREE_BLOCK(inode, 1); -- return 0; -- -- } --diff -ru lum-2.4.18-um30/fs/ext3/file.c uml-2.4.18-12.5/fs/ext3/file.c ----- lum-2.4.18-um30/fs/ext3/file.c Thu Nov 15 14:37:55 2001 --+++ uml-2.4.18-12.5/fs/ext3/file.c Thu Sep 19 13:40:11 2002 --@@ -61,19 +61,52 @@ -- static ssize_t -- ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -- { --+ int ret, err; -- struct inode *inode = file->f_dentry->d_inode; -- --- /* --- * Nasty: if the file is subject to synchronous writes then we need --- * to force generic_osync_inode() to call ext3_write_inode(). --- * We do that by marking the inode dirty. This adds much more --- * computational expense than we need, but we're going to sync --- * anyway. --- */ --- if (IS_SYNC(inode) || (file->f_flags & O_SYNC)) --- mark_inode_dirty(inode); --+ ret = generic_file_write(file, buf, count, ppos); -- --- return generic_file_write(file, buf, count, ppos); --+ /* Skip file flushing code if there was an error, or if nothing --+ was written. */ --+ if (ret <= 0) --+ return ret; --+ --+ /* If the inode is IS_SYNC, or is O_SYNC and we are doing --+ data-journaling, then we need to make sure that we force the --+ transaction to disk to keep all metadata uptodate --+ synchronously. */ --+ --+ if (file->f_flags & O_SYNC) { --+ /* If we are non-data-journaled, then the dirty data has --+ already been flushed to backing store by --+ generic_osync_inode, and the inode has been flushed --+ too if there have been any modifications other than --+ mere timestamp updates. --+ --+ Open question --- do we care about flushing --+ timestamps too if the inode is IS_SYNC? */ --+ if (!ext3_should_journal_data(inode)) --+ return ret; --+ --+ goto force_commit; --+ } --+ --+ /* So we know that there has been no forced data flush. If the --+ inode is marked IS_SYNC, we need to force one ourselves. */ --+ if (!IS_SYNC(inode)) --+ return ret; --+ --+ /* Open question #2 --- should we force data to disk here too? --+ If we don't, the only impact is that data=writeback --+ filesystems won't flush data to disk automatically on --+ IS_SYNC, only metadata (but historically, that is what ext2 --+ has done.) */ --+ --+force_commit: --+ err = ext3_force_commit(inode->i_sb); --+ if (err) --+ return err; --+ return ret; -- } -- -- struct file_operations ext3_file_operations = { --diff -ru lum-2.4.18-um30/fs/ext3/fsync.c uml-2.4.18-12.5/fs/ext3/fsync.c ----- lum-2.4.18-um30/fs/ext3/fsync.c Tue Nov 20 22:34:13 2001 --+++ uml-2.4.18-12.5/fs/ext3/fsync.c Thu Sep 19 13:40:11 2002 --@@ -62,7 +62,12 @@ -- * we'll end up waiting on them in commit. -- */ -- ret = fsync_inode_buffers(inode); --- ret |= fsync_inode_data_buffers(inode); --+ --+ /* In writeback mode, we need to force out data buffers too. In --+ * the other modes, ext3_force_commit takes care of forcing out --+ * just the right data blocks. */ --+ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) --+ ret |= fsync_inode_data_buffers(inode); -- -- ext3_force_commit(inode->i_sb); -- --diff -ru lum-2.4.18-um30/fs/ext3/ialloc.c uml-2.4.18-12.5/fs/ext3/ialloc.c ----- lum-2.4.18-um30/fs/ext3/ialloc.c Mon Feb 25 12:38:08 2002 --+++ uml-2.4.18-12.5/fs/ext3/ialloc.c Thu Sep 19 13:40:11 2002 --@@ -392,7 +392,7 @@ -- -- err = -ENOSPC; -- if (!gdp) --- goto fail; --+ goto out; -- -- err = -EIO; -- bitmap_nr = load_inode_bitmap (sb, i); --@@ -523,9 +523,10 @@ -- return inode; -- -- fail: --+ ext3_std_error(sb, err); --+out: -- unlock_super(sb); -- iput(inode); --- ext3_std_error(sb, err); -- return ERR_PTR(err); -- } -- --diff -ru lum-2.4.18-um30/fs/ext3/inode.c uml-2.4.18-12.5/fs/ext3/inode.c ----- lum-2.4.18-um30/fs/ext3/inode.c Mon Feb 25 12:38:08 2002 --+++ uml-2.4.18-12.5/fs/ext3/inode.c Thu Sep 19 13:40:11 2002 --@@ -412,6 +412,7 @@ -- return NULL; -- -- changed: --+ brelse(bh); -- *err = -EAGAIN; -- goto no_block; -- failure: --@@ -581,8 +582,6 @@ -- -- parent = nr; -- } --- if (IS_SYNC(inode)) --- handle->h_sync = 1; -- } -- if (n == num) -- return 0; --@@ -1015,8 +1018,8 @@ -- unsigned from, unsigned to) -- { -- struct inode *inode = page->mapping->host; --- handle_t *handle = ext3_journal_current_handle(); -- int ret, needed_blocks = ext3_writepage_trans_blocks(inode); --+ handle_t *handle; -- -- lock_kernel(); -- handle = ext3_journal_start(inode, needed_blocks); --diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c ----- lum-2.4.18-um30/fs/ext3/namei.c Fri Nov 9 15:25:04 2001 --+++ uml-2.4.18-12.5/fs/ext3/namei.c Thu Sep 19 13:40:11 2002 --@@ -354,8 +355,8 @@ -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --- ext3_mark_inode_dirty(handle, dir); -- dir->i_version = ++event; --+ ext3_mark_inode_dirty(handle, dir); -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -- brelse(bh); --@@ -464,8 +465,8 @@ -- inode->i_op = &ext3_file_inode_operations; -- inode->i_fop = &ext3_file_operations; -- inode->i_mapping->a_ops = &ext3_aops; --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); -- return err; --@@ -489,8 +490,8 @@ -- err = PTR_ERR(inode); -- if (!IS_ERR(inode)) { -- init_special_inode(inode, mode, rdev); --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); -- return err; --@@ -933,8 +934,8 @@ -- inode->i_size = l-1; -- } -- inode->u.ext3_i.i_disksize = inode->i_size; --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- out_stop: -- ext3_journal_stop(handle, dir); -- return err; --@@ -970,8 +971,8 @@ -- ext3_inc_count(handle, inode); -- atomic_inc(&inode->i_count); -- --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- ext3_journal_stop(handle, dir); -- return err; -- } --diff -ru lum-2.4.18-um30/fs/ext3/super.c uml-2.4.18-12.5/fs/ext3/super.c ----- lum-2.4.18-um30/fs/ext3/super.c Fri Jul 12 17:59:37 2002 --+++ uml-2.4.18-12.5/fs/ext3/super.c Thu Sep 19 13:40:11 2002 --@@ -1589,8 +1589,10 @@ -- journal_t *journal = EXT3_SB(sb)->s_journal; -- -- /* Now we set up the journal barrier. */ --+ unlock_super(sb); -- journal_lock_updates(journal); -- journal_flush(journal); --+ lock_super(sb); -- -- /* Journal blocked and flushed, clear needs_recovery flag. */ -- EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); diff --cc lustre/extN/ext3-2.4.18-ino_sb_macro.diff index a49d5da,a49d5da..0000000 deleted file mode 100644,100644 --- a/lustre/extN/ext3-2.4.18-ino_sb_macro.diff +++ /dev/null @@@ -1,1556 -1,1556 +1,0 @@@ ----- ./fs/ext3/balloc.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/balloc.c Tue May 7 15:35:59 2002 --@@ -46,18 +46,18 @@ struct ext3_group_desc * ext3_get_group_ -- unsigned long desc; -- struct ext3_group_desc * gdp; -- --- if (block_group >= sb->u.ext3_sb.s_groups_count) { --+ if (block_group >= EXT3_SB(sb)->s_groups_count) { -- ext3_error (sb, "ext3_get_group_desc", -- "block_group >= groups_count - " -- "block_group = %d, groups_count = %lu", --- block_group, sb->u.ext3_sb.s_groups_count); --+ block_group, EXT3_SB(sb)->s_groups_count); -- -- return NULL; -- } -- -- group_desc = block_group / EXT3_DESC_PER_BLOCK(sb); -- desc = block_group % EXT3_DESC_PER_BLOCK(sb); --- if (!sb->u.ext3_sb.s_group_desc[group_desc]) { --+ if (!EXT3_SB(sb)->s_group_desc[group_desc]) { -- ext3_error (sb, "ext3_get_group_desc", -- "Group descriptor not loaded - " -- "block_group = %d, group_desc = %lu, desc = %lu", --@@ -66,9 +66,9 @@ struct ext3_group_desc * ext3_get_group_ -- } -- -- gdp = (struct ext3_group_desc *) --- sb->u.ext3_sb.s_group_desc[group_desc]->b_data; --+ EXT3_SB(sb)->s_group_desc[group_desc]->b_data; -- if (bh) --- *bh = sb->u.ext3_sb.s_group_desc[group_desc]; --+ *bh = EXT3_SB(sb)->s_group_desc[group_desc]; -- return gdp + desc; -- } -- --@@ -104,8 +104,8 @@ static int read_block_bitmap (struct sup -- * this group. The IO will be retried next time. -- */ -- error_out: --- sb->u.ext3_sb.s_block_bitmap_number[bitmap_nr] = block_group; --- sb->u.ext3_sb.s_block_bitmap[bitmap_nr] = bh; --+ EXT3_SB(sb)->s_block_bitmap_number[bitmap_nr] = block_group; --+ EXT3_SB(sb)->s_block_bitmap[bitmap_nr] = bh; -- return retval; -- } -- --@@ -128,16 +128,17 @@ static int __load_block_bitmap (struct s -- int i, j, retval = 0; -- unsigned long block_bitmap_number; -- struct buffer_head * block_bitmap; --+ struct ext3_sb_info *sbi = EXT3_SB(sb); -- --- if (block_group >= sb->u.ext3_sb.s_groups_count) --+ if (block_group >= sbi->s_groups_count) -- ext3_panic (sb, "load_block_bitmap", -- "block_group >= groups_count - " -- "block_group = %d, groups_count = %lu", --- block_group, sb->u.ext3_sb.s_groups_count); --+ block_group, EXT3_SB(sb)->s_groups_count); -- --- if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED) { --- if (sb->u.ext3_sb.s_block_bitmap[block_group]) { --- if (sb->u.ext3_sb.s_block_bitmap_number[block_group] == --+ if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED) { --+ if (sbi->s_block_bitmap[block_group]) { --+ if (sbi->s_block_bitmap_number[block_group] == -- block_group) -- return block_group; -- ext3_error (sb, "__load_block_bitmap", --@@ -149,21 +150,20 @@ static int __load_block_bitmap (struct s -- return block_group; -- } -- --- for (i = 0; i < sb->u.ext3_sb.s_loaded_block_bitmaps && --- sb->u.ext3_sb.s_block_bitmap_number[i] != block_group; i++) --+ for (i = 0; i < sbi->s_loaded_block_bitmaps && --+ sbi->s_block_bitmap_number[i] != block_group; i++) -- ; --- if (i < sb->u.ext3_sb.s_loaded_block_bitmaps && --- sb->u.ext3_sb.s_block_bitmap_number[i] == block_group) { --- block_bitmap_number = sb->u.ext3_sb.s_block_bitmap_number[i]; --- block_bitmap = sb->u.ext3_sb.s_block_bitmap[i]; --+ if (i < sbi->s_loaded_block_bitmaps && --+ sbi->s_block_bitmap_number[i] == block_group) { --+ block_bitmap_number = sbi->s_block_bitmap_number[i]; --+ block_bitmap = sbi->s_block_bitmap[i]; -- for (j = i; j > 0; j--) { --- sb->u.ext3_sb.s_block_bitmap_number[j] = --- sb->u.ext3_sb.s_block_bitmap_number[j - 1]; --- sb->u.ext3_sb.s_block_bitmap[j] = --- sb->u.ext3_sb.s_block_bitmap[j - 1]; --+ sbi->s_block_bitmap_number[j] = --+ sbi->s_block_bitmap_number[j - 1]; --+ sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1]; -- } --- sb->u.ext3_sb.s_block_bitmap_number[0] = block_bitmap_number; --- sb->u.ext3_sb.s_block_bitmap[0] = block_bitmap; --+ sbi->s_block_bitmap_number[0] = block_bitmap_number; --+ sbi->s_block_bitmap[0] = block_bitmap; -- -- /* -- * There's still one special case here --- if block_bitmap == 0 --@@ -173,17 +173,14 @@ static int __load_block_bitmap (struct s -- if (!block_bitmap) -- retval = read_block_bitmap (sb, block_group, 0); -- } else { --- if (sb->u.ext3_sb.s_loaded_block_bitmapsu.ext3_sb.s_loaded_block_bitmaps++; --+ if (sbi->s_loaded_block_bitmapss_loaded_block_bitmaps++; -- else --- brelse (sb->u.ext3_sb.s_block_bitmap --- [EXT3_MAX_GROUP_LOADED - 1]); --- for (j = sb->u.ext3_sb.s_loaded_block_bitmaps - 1; --- j > 0; j--) { --- sb->u.ext3_sb.s_block_bitmap_number[j] = --- sb->u.ext3_sb.s_block_bitmap_number[j - 1]; --- sb->u.ext3_sb.s_block_bitmap[j] = --- sb->u.ext3_sb.s_block_bitmap[j - 1]; --+ brelse(sbi->s_block_bitmap[EXT3_MAX_GROUP_LOADED - 1]); --+ for (j = sbi->s_loaded_block_bitmaps - 1; j > 0; j--) { --+ sbi->s_block_bitmap_number[j] = --+ sbi->s_block_bitmap_number[j - 1]; --+ sbi->s_block_bitmap[j] = sbi->s_block_bitmap[j - 1]; -- } -- retval = read_block_bitmap (sb, block_group, 0); -- } --@@ -206,24 +203,25 @@ static int __load_block_bitmap (struct s -- static inline int load_block_bitmap (struct super_block * sb, -- unsigned int block_group) -- { --+ struct ext3_sb_info *sbi = EXT3_SB(sb); -- int slot; --- --+ -- /* -- * Do the lookup for the slot. First of all, check if we're asking -- * for the same slot as last time, and did we succeed that last time? -- */ --- if (sb->u.ext3_sb.s_loaded_block_bitmaps > 0 && --- sb->u.ext3_sb.s_block_bitmap_number[0] == block_group && --- sb->u.ext3_sb.s_block_bitmap[0]) { --+ if (sbi->s_loaded_block_bitmaps > 0 && --+ sbi->s_block_bitmap_number[0] == block_group && --+ sbi->s_block_bitmap[0]) { -- return 0; -- } -- /* -- * Or can we do a fast lookup based on a loaded group on a filesystem -- * small enough to be mapped directly into the superblock? -- */ --- else if (sb->u.ext3_sb.s_groups_count <= EXT3_MAX_GROUP_LOADED && --- sb->u.ext3_sb.s_block_bitmap_number[block_group]==block_group --- && sb->u.ext3_sb.s_block_bitmap[block_group]) { --+ else if (sbi->s_groups_count <= EXT3_MAX_GROUP_LOADED && --+ sbi->s_block_bitmap_number[block_group] == block_group --+ && sbi->s_block_bitmap[block_group]) { -- slot = block_group; -- } -- /* --@@ -243,7 +241,7 @@ static inline int load_block_bitmap (str -- * If it's a valid slot, we may still have cached a previous IO error, -- * in which case the bh in the superblock cache will be zero. -- */ --- if (!sb->u.ext3_sb.s_block_bitmap[slot]) --+ if (!sbi->s_block_bitmap[slot]) -- return -EIO; -- -- /* --@@ -275,7 +273,7 @@ void ext3_free_blocks (handle_t *handle, -- return; -- } -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; --+ es = EXT3_SB(sb)->s_es; -- if (block < le32_to_cpu(es->s_first_data_block) || -- block + count < block || -- (block + count) > le32_to_cpu(es->s_blocks_count)) { --@@ -304,7 +302,7 @@ do_more: -- if (bitmap_nr < 0) -- goto error_return; -- --- bitmap_bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; --+ bitmap_bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -- gdp = ext3_get_group_desc (sb, block_group, &gd_bh); -- if (!gdp) -- goto error_return; --@@ -330,8 +328,8 @@ do_more: -- if (err) -- goto error_return; -- --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); --- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); --+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -- if (err) -- goto error_return; -- --@@ -341,7 +339,7 @@ -- if (block == le32_to_cpu(gdp->bg_block_bitmap) || -- block == le32_to_cpu(gdp->bg_inode_bitmap) || -- in_range(block, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext2_sb.s_itb_per_group)) { --+ EXT3_SB(sb)->s_itb_per_group)) { -- ext3_error(sb, __FUNCTION__, -- "Freeing block in system zone - block = %lu", -- block); --@@ -410,8 +407,8 @@ do_more: -- if (!err) err = ret; -- -- /* And the superblock */ --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "dirtied superblock"); --- ret = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "dirtied superblock"); --+ ret = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -- if (!err) err = ret; -- -- if (overflow && !err) { --@@ -564,12 +560,12 @@ int ext3_new_block (handle_t *handle, st -- } -- -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; --+ es = EXT3_SB(sb)->s_es; -- if (le32_to_cpu(es->s_free_blocks_count) <= -- le32_to_cpu(es->s_r_blocks_count) && --- ((sb->u.ext3_sb.s_resuid != current->fsuid) && --- (sb->u.ext3_sb.s_resgid == 0 || --- !in_group_p (sb->u.ext3_sb.s_resgid)) && --+ ((EXT3_SB(sb)->s_resuid != current->fsuid) && --+ (EXT3_SB(sb)->s_resgid == 0 || --+ !in_group_p (EXT3_SB(sb)->s_resgid)) && -- !capable(CAP_SYS_RESOURCE))) -- goto out; -- --@@ -598,7 +595,7 @@ int ext3_new_block (handle_t *handle, st -- if (bitmap_nr < 0) -- goto io_error; -- --- bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; --+ bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -- -- ext3_debug ("goal is at %d:%d.\n", i, j); -- --@@ -621,9 +618,9 @@ int ext3_new_block (handle_t *handle, st -- * Now search the rest of the groups. We assume that -- * i and gdp correctly point to the last group visited. -- */ --- for (k = 0; k < sb->u.ext3_sb.s_groups_count; k++) { --+ for (k = 0; k < EXT3_SB(sb)->s_groups_count; k++) { -- i++; --- if (i >= sb->u.ext3_sb.s_groups_count) --+ if (i >= EXT3_SB(sb)->s_groups_count) -- i = 0; -- gdp = ext3_get_group_desc (sb, i, &bh2); -- if (!gdp) { --@@ -635,7 +632,7 @@ int ext3_new_block (handle_t *handle, st -- if (bitmap_nr < 0) -- goto io_error; -- --- bh = sb->u.ext3_sb.s_block_bitmap[bitmap_nr]; --+ bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -- j = find_next_usable_block(-1, bh, -- EXT3_BLOCKS_PER_GROUP(sb)); -- if (j >= 0) --@@ -674,8 +671,8 @@ got_block: -- fatal = ext3_journal_get_write_access(handle, bh2); -- if (fatal) goto out; -- --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); --- fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); --+ fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -- if (fatal) goto out; -- -- tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb) --@@ -796,7 +804,7 @@ got_block: -- if (!fatal) fatal = err; -- -- BUFFER_TRACE(bh, "journal_dirty_metadata for superblock"); --- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); --+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -- if (!fatal) fatal = err; -- -- sb->s_dirt = 1; --@@ -829,11 +837,11 @@ unsigned long ext3_count_free_blocks (st -- int i; -- -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; --+ es = EXT3_SB(sb)->s_es; -- desc_count = 0; -- bitmap_count = 0; -- gdp = NULL; --- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { --+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { -- gdp = ext3_get_group_desc (sb, i, NULL); -- if (!gdp) -- continue; --@@ -842,7 +850,7 @@ unsigned long ext3_count_free_blocks (st -- if (bitmap_nr < 0) -- continue; -- --- x = ext3_count_free (sb->u.ext3_sb.s_block_bitmap[bitmap_nr], --+ x = ext3_count_free (EXT3_SB(sb)->s_block_bitmap[bitmap_nr], -- sb->s_blocksize); -- printk ("group %d: stored = %d, counted = %lu\n", -- i, le16_to_cpu(gdp->bg_free_blocks_count), x); --@@ -853,7 +861,7 @@ unsigned long ext3_count_free_blocks (st -- unlock_super (sb); -- return bitmap_count; -- #else --- return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_blocks_count); --+ return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count); -- #endif -- } -- --@@ -862,7 +870,7 @@ static inline int block_in_use (unsigned -- unsigned char * map) -- { -- return ext3_test_bit ((block - --- le32_to_cpu(sb->u.ext3_sb.s_es->s_first_data_block)) % --+ le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) % -- EXT3_BLOCKS_PER_GROUP(sb), map); -- } -- --@@ -930,11 +938,11 @@ void ext3_check_blocks_bitmap (struct su -- struct ext3_group_desc * gdp; -- int i; -- --- es = sb->u.ext3_sb.s_es; --+ es = EXT3_SB(sb)->s_es; -- desc_count = 0; -- bitmap_count = 0; -- gdp = NULL; --- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { --+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { -- gdp = ext3_get_group_desc (sb, i, NULL); -- if (!gdp) -- continue; --@@ -968,7 +976,7 @@ void ext3_check_blocks_bitmap (struct su -- "Inode bitmap for group %d is marked free", -- i); -- --- for (j = 0; j < sb->u.ext3_sb.s_itb_per_group; j++) --+ for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++) -- if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j, -- sb, bh->b_data)) -- ext3_error (sb, "ext3_check_blocks_bitmap", ----- ./fs/ext3/dir.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/dir.c Tue May 7 14:54:13 2002 --@@ -52,7 +52,7 @@ int ext3_check_dir_entry (const char * f -- else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) -- error_msg = "directory entry across blocks"; -- else if (le32_to_cpu(de->inode) > --- le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) --+ le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count)) -- error_msg = "inode out of bounds"; -- -- if (error_msg != NULL) ----- ./fs/ext3/ialloc.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/ialloc.c Tue May 7 15:39:26 2002 --@@ -73,8 +73,8 @@ static int read_inode_bitmap (struct sup -- * this group. The IO will be retried next time. -- */ -- error_out: --- sb->u.ext3_sb.s_inode_bitmap_number[bitmap_nr] = block_group; --- sb->u.ext3_sb.s_inode_bitmap[bitmap_nr] = bh; --+ EXT3_SB(sb)->s_inode_bitmap_number[bitmap_nr] = block_group; --+ EXT3_SB(sb)->s_inode_bitmap[bitmap_nr] = bh; -- return retval; -- } -- --@@ -225,7 +225,7 @@ void ext3_free_inode (handle_t *handle, -- clear_inode (inode); -- -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; --+ es = EXT3_SB(sb)->s_es; -- if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { -- ext3_error (sb, "ext3_free_inode", -- "reserved or nonexistent inode %lu", ino); --@@ -237,7 +237,7 @@ void ext3_free_inode (handle_t *handle, -- if (bitmap_nr < 0) -- goto error_return; -- --- bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; --+ bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]; -- -- BUFFER_TRACE(bh, "get_write_access"); -- fatal = ext3_journal_get_write_access(handle, bh); --@@ -255,8 +255,8 @@ void ext3_free_inode (handle_t *handle, -- fatal = ext3_journal_get_write_access(handle, bh2); -- if (fatal) goto error_return; -- --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get write access"); --- fatal = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get write access"); --+ fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -- if (fatal) goto error_return; -- -- if (gdp) { --@@ -271,9 +271,9 @@ void ext3_free_inode (handle_t *handle, -- if (!fatal) fatal = err; -- es->s_free_inodes_count = -- cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1); --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, -- "call ext3_journal_dirty_metadata"); --- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); --+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -- if (!fatal) fatal = err; -- } -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); --@@ -305,6 +305,8 @@ struct inode * ext3_new_inode (handle_t -- int i, j, avefreei; -- struct inode * inode; -- int bitmap_nr; --+ struct ext3_inode_info *ei; --+ struct ext3_sb_info *sbi; -- struct ext3_group_desc * gdp; -- struct ext3_group_desc * tmp; -- struct ext3_super_block * es; --@@ -318,19 +320,21 @@ struct inode * ext3_new_inode (handle_t -- inode = new_inode(sb); -- if (!inode) -- return ERR_PTR(-ENOMEM); --- init_rwsem(&inode->u.ext3_i.truncate_sem); --+ sbi = EXT3_SB(sb); --+ ei = EXT3_I(inode); --+ init_rwsem(&ei->truncate_sem); -- -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; --+ es = sbi->s_es; -- repeat: -- gdp = NULL; -- i = 0; -- -- if (S_ISDIR(mode)) { -- avefreei = le32_to_cpu(es->s_free_inodes_count) / --- sb->u.ext3_sb.s_groups_count; --+ sbi->s_groups_count; -- if (!gdp) { --- for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) { --+ for (j = 0; j < sbi->s_groups_count; j++) { -- struct buffer_head *temp_buffer; -- tmp = ext3_get_group_desc (sb, j, &temp_buffer); -- if (tmp && --@@ -350,7 +354,7 @@ repeat: -- /* -- * Try to place the inode in its parent directory -- */ --- i = dir->u.ext3_i.i_block_group; --+ i = EXT3_I(dir)->i_block_group; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) -- gdp = tmp; --@@ -360,10 +364,10 @@ repeat: -- * Use a quadratic hash to find a group with a -- * free inode -- */ --- for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) { --+ for (j = 1; j < sbi->s_groups_count; j <<= 1) { -- i += j; --- if (i >= sb->u.ext3_sb.s_groups_count) --- i -= sb->u.ext3_sb.s_groups_count; --+ if (i >= sbi->s_groups_count) --+ i -= sbi->s_groups_count; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && -- le16_to_cpu(tmp->bg_free_inodes_count)) { --@@ -376,9 +380,9 @@ repeat: -- /* -- * That failed: try linear search for a free inode -- */ --- i = dir->u.ext3_i.i_block_group + 1; --- for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) { --- if (++i >= sb->u.ext3_sb.s_groups_count) --+ i = EXT3_I(dir)->i_block_group + 1; --+ for (j = 2; j < sbi->s_groups_count; j++) { --+ if (++i >= sbi->s_groups_count) -- i = 0; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && --@@ -399,11 +403,11 @@ repeat: -- if (bitmap_nr < 0) -- goto fail; -- --- bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; --+ bh = sbi->s_inode_bitmap[bitmap_nr]; -- -- if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data, --- EXT3_INODES_PER_GROUP(sb))) < --- EXT3_INODES_PER_GROUP(sb)) { --+ sbi->s_inodes_per_group)) < --+ sbi->s_inodes_per_group) { -- BUFFER_TRACE(bh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, bh); -- if (err) goto fail; --@@ -436,8 +440,8 @@ repeat: -- } -- goto repeat; -- } --- j += i * EXT3_INODES_PER_GROUP(sb) + 1; --- if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) { --+ j += i * sbi->s_inodes_per_group + 1; --+ if (j < sbi->s_first_ino || j > le32_to_cpu(es->s_inodes_count)) { -- ext3_error (sb, "ext3_new_inode", -- "reserved inode or inode > inodes count - " -- "block_group = %d,inode=%d", i, j); --@@ -457,13 +461,13 @@ repeat: -- err = ext3_journal_dirty_metadata(handle, bh2); -- if (err) goto fail; -- --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); --- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(sbi->s_sbh, "get_write_access"); --+ err = ext3_journal_get_write_access(handle, sbi->s_sbh); -- if (err) goto fail; -- es->s_free_inodes_count = -- cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1); --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "call ext3_journal_dirty_metadata"); --- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(sbi->s_sbh, "call ext3_journal_dirty_metadata"); --+ err = ext3_journal_dirty_metadata(handle, sbi->s_sbh); -- sb->s_dirt = 1; -- if (err) goto fail; -- --@@ -483,31 +487,31 @@ repeat: -- inode->i_blksize = PAGE_SIZE; -- inode->i_blocks = 0; -- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; --- inode->u.ext3_i.i_flags = dir->u.ext3_i.i_flags & ~EXT3_INDEX_FL; --+ ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL; -- if (S_ISLNK(mode)) --- inode->u.ext3_i.i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL); --+ ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL); -- #ifdef EXT3_FRAGMENTS --- inode->u.ext3_i.i_faddr = 0; --- inode->u.ext3_i.i_frag_no = 0; --- inode->u.ext3_i.i_frag_size = 0; --+ ei->i_faddr = 0; --+ ei->i_frag_no = 0; --+ ei->i_frag_size = 0; -- #endif --- inode->u.ext3_i.i_file_acl = 0; --- inode->u.ext3_i.i_dir_acl = 0; --- inode->u.ext3_i.i_dtime = 0; --- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); --+ ei->i_file_acl = 0; --+ ei->i_dir_acl = 0; --+ ei->i_dtime = 0; --+ INIT_LIST_HEAD(&ei->i_orphan); -- #ifdef EXT3_PREALLOCATE --- inode->u.ext3_i.i_prealloc_count = 0; --+ ei->i_prealloc_count = 0; -- #endif --- inode->u.ext3_i.i_block_group = i; --+ ei->i_block_group = i; -- --- if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) --+ if (ei->i_flags & EXT3_SYNC_FL) -- inode->i_flags |= S_SYNC; -- if (IS_SYNC(inode)) -- handle->h_sync = 1; -- insert_inode_hash(inode); --- inode->i_generation = sb->u.ext3_sb.s_next_generation++; --+ inode->i_generation = sbi->s_next_generation++; -- --- inode->u.ext3_i.i_state = EXT3_STATE_NEW; --+ ei->i_state = EXT3_STATE_NEW; -- err = ext3_mark_inode_dirty(handle, inode); -- if (err) goto fail; -- --@@ -585,19 +589,19 @@ struct inode *ext3_orphan_get (struct su -- -- unsigned long ext3_count_free_inodes (struct super_block * sb) -- { --+ struct ext3_sb_info *sbi = EXT3_SB(sb); --+ struct ext3_super_block *es = sbi->s_es; -- #ifdef EXT3FS_DEBUG --- struct ext3_super_block * es; -- unsigned long desc_count, bitmap_count, x; -- int bitmap_nr; -- struct ext3_group_desc * gdp; -- int i; -- -- lock_super (sb); --- es = sb->u.ext3_sb.s_es; -- desc_count = 0; -- bitmap_count = 0; -- gdp = NULL; --- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { --+ for (i = 0; i < sbi->s_groups_count; i++) { -- gdp = ext3_get_group_desc (sb, i, NULL); -- if (!gdp) -- continue; --@@ -606,8 +610,8 @@ unsigned long ext3_count_free_inodes (st -- if (bitmap_nr < 0) -- continue; -- --- x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr], --- EXT3_INODES_PER_GROUP(sb) / 8); --+ x = ext3_count_free(sbi->s_inode_bitmap[bitmap_nr], --+ sbi->s_inodes_per_group / 8); -- printk ("group %d: stored = %d, counted = %lu\n", -- i, le16_to_cpu(gdp->bg_free_inodes_count), x); -- bitmap_count += x; --@@ -617,7 +621,7 @@ unsigned long ext3_count_free_inodes (st -- unlock_super (sb); -- return desc_count; -- #else --- return le32_to_cpu(sb->u.ext3_sb.s_es->s_free_inodes_count); --+ return le32_to_cpu(es->s_free_inodes_count); -- #endif -- } -- --@@ -626,16 +630,18 @@ unsigned long ext3_count_free_inodes (st -- void ext3_check_inodes_bitmap (struct super_block * sb) -- { -- struct ext3_super_block * es; --+ struct ext3_sb_info *sbi; -- unsigned long desc_count, bitmap_count, x; -- int bitmap_nr; -- struct ext3_group_desc * gdp; -- int i; -- --- es = sb->u.ext3_sb.s_es; --+ sbi = EXT3_SB(sb); --+ es = sbi->s_es; -- desc_count = 0; -- bitmap_count = 0; -- gdp = NULL; --- for (i = 0; i < sb->u.ext3_sb.s_groups_count; i++) { --+ for (i = 0; i < sbi->s_groups_count; i++) { -- gdp = ext3_get_group_desc (sb, i, NULL); -- if (!gdp) -- continue; --@@ -644,7 +650,7 @@ void ext3_check_inodes_bitmap (struct su -- if (bitmap_nr < 0) -- continue; -- --- x = ext3_count_free (sb->u.ext3_sb.s_inode_bitmap[bitmap_nr], --+ x = ext3_count_free (sbi->s_inode_bitmap[bitmap_nr], -- EXT3_INODES_PER_GROUP(sb) / 8); -- if (le16_to_cpu(gdp->bg_free_inodes_count) != x) -- ext3_error (sb, "ext3_check_inodes_bitmap", ----- ./fs/ext3/inode.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/inode.c Tue May 7 15:41:23 2002 --@@ -196,7 +196,7 @@ void ext3_delete_inode (struct inode * i -- * (Well, we could do this if we need to, but heck - it works) -- */ -- ext3_orphan_del(handle, inode); --- inode->u.ext3_i.i_dtime = CURRENT_TIME; --+ EXT3_I(inode)->i_dtime = CURRENT_TIME; -- -- /* -- * One subtle ordering requirement: if anything has gone wrong --@@ -220,13 +220,14 @@ no_delete: -- void ext3_discard_prealloc (struct inode * inode) -- { -- #ifdef EXT3_PREALLOCATE --+ struct ext3_inode_info *ei = EXT3_I(inode); -- lock_kernel(); -- /* Writer: ->i_prealloc* */ --- if (inode->u.ext3_i.i_prealloc_count) { --- unsigned short total = inode->u.ext3_i.i_prealloc_count; --- unsigned long block = inode->u.ext3_i.i_prealloc_block; --- inode->u.ext3_i.i_prealloc_count = 0; --- inode->u.ext3_i.i_prealloc_block = 0; --+ if (ei->i_prealloc_count) { --+ unsigned short total = ei->i_prealloc_count; --+ unsigned long block = ei->i_prealloc_block; --+ ei->i_prealloc_count = 0; --+ ei->i_prealloc_block = 0; -- /* Writer: end */ -- ext3_free_blocks (inode, block, total); -- } --@@ -243,13 +244,15 @@ static int ext3_alloc_block (handle_t *h -- unsigned long result; -- -- #ifdef EXT3_PREALLOCATE --+ struct ext3_inode_info *ei = EXT3_I(inode); --+ -- /* Writer: ->i_prealloc* */ --- if (inode->u.ext3_i.i_prealloc_count && --- (goal == inode->u.ext3_i.i_prealloc_block || --- goal + 1 == inode->u.ext3_i.i_prealloc_block)) --+ if (ei->i_prealloc_count && --+ (goal == ei->i_prealloc_block || --+ goal + 1 == ei->i_prealloc_block)) -- { --- result = inode->u.ext3_i.i_prealloc_block++; --- inode->u.ext3_i.i_prealloc_count--; --+ result = ei->i_prealloc_block++; --+ ei->i_prealloc_count--; -- /* Writer: end */ -- ext3_debug ("preallocation hit (%lu/%lu).\n", -- ++alloc_hits, ++alloc_attempts); --@@ -259,8 +262,8 @@ static int ext3_alloc_block (handle_t *h -- alloc_hits, ++alloc_attempts); -- if (S_ISREG(inode->i_mode)) -- result = ext3_new_block (inode, goal, --- &inode->u.ext3_i.i_prealloc_count, --- &inode->u.ext3_i.i_prealloc_block, err); --+ &ei->i_prealloc_count, --+ &ei->i_prealloc_block, err); -- else -- result = ext3_new_block (inode, goal, 0, 0, err); -- /* --@@ -394,7 +397,7 @@ static Indirect *ext3_get_branch(struct -- -- *err = 0; -- /* i_data is not going away, no lock needed */ --- add_chain (chain, NULL, inode->u.ext3_i.i_data + *offsets); --+ add_chain (chain, NULL, EXT3_I(inode)->i_data + *offsets); -- if (!p->key) -- goto no_block; -- while (--depth) { --@@ -437,7 +440,8 @@ no_block: -- -- static inline unsigned long ext3_find_near(struct inode *inode, Indirect *ind) -- { --- u32 *start = ind->bh ? (u32*) ind->bh->b_data : inode->u.ext3_i.i_data; --+ struct ext3_inode_info *ei = EXT3_I(inode); --+ u32 *start = ind->bh ? (u32*) ind->bh->b_data : ei->i_data; -- u32 *p; -- -- /* Try to find previous block */ --@@ -453,9 +456,8 @@ static inline unsigned long ext3_find_ne -- * It is going to be refered from inode itself? OK, just put it into -- * the same cylinder group then. -- */ --- return (inode->u.ext3_i.i_block_group * --- EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + --- le32_to_cpu(inode->i_sb->u.ext3_sb.s_es->s_first_data_block); --+ return (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + --+ le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); -- } -- -- /** --@@ -474,14 +477,15 @@ -- static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4], -- Indirect *partial, unsigned long *goal) -- { --+ struct ext3_inode_info *ei = EXT3_I(inode); -- /* Writer: ->i_next_alloc* */ --- if (block == inode->u.ext3_i.i_next_alloc_block + 1) { --- inode->u.ext3_i.i_next_alloc_block++; --- inode->u.ext3_i.i_next_alloc_goal++; --+ if (block == ei->i_next_alloc_block + 1) { --+ ei->i_next_alloc_block++; --+ ei->i_next_alloc_goal++; -- } -- #ifdef SEARCH_FROM_ZERO --- inode->u.ext3_i.i_next_alloc_block = 0; --- inode->u.ext3_i.i_next_alloc_goal = 0; --+ ei->i_next_alloc_block = 0; --+ ei->i_next_alloc_goal = 0; -- #endif -- /* Writer: end */ -- /* Reader: pointers, ->i_next_alloc* */ --@@ -490,8 +493,8 @@ static int ext3_find_goal(struct inode * -- * try the heuristic for sequential allocation, -- * failing that at least try to get decent locality. -- */ --- if (block == inode->u.ext3_i.i_next_alloc_block) --- *goal = inode->u.ext3_i.i_next_alloc_goal; --+ if (block == ei->i_next_alloc_block) --+ *goal = ei->i_next_alloc_goal; -- if (!*goal) -- *goal = ext3_find_near(inode, partial); -- #ifdef SEARCH_FROM_ZERO --@@ -619,6 +621,7 @@ -- { -- int i; -- int err = 0; --+ struct ext3_inode_info *ei = EXT3_I(inode); -- -- /* -- * If we're splicing into a [td]indirect block (as opposed to the --@@ -641,11 +644,11 @@ static int ext3_splice_branch(handle_t * -- /* That's it */ -- -- *where->p = where->key; --- inode->u.ext3_i.i_next_alloc_block = block; --- inode->u.ext3_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key); --+ ei->i_next_alloc_block = block; --+ ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key); -- #ifdef SEARCH_FROM_ZERO --- inode->u.ext3_i.i_next_alloc_block = 0; --- inode->u.ext3_i.i_next_alloc_goal = 0; --+ ei->i_next_alloc_block = 0; --+ ei->i_next_alloc_goal = 0; -- #endif -- /* Writer: end */ -- --@@ -729,6 +732,7 @@ -- unsigned long goal; -- int left; -- int depth = ext3_block_to_path(inode, iblock, offsets); --+ struct ext3_inode_info *ei = EXT3_I(inode); -- loff_t new_size; -- -- J_ASSERT(handle != NULL || create == 0); --@@ -782,7 +785,7 @@ out: -- /* -- * Block out ext3_truncate while we alter the tree -- */ --- down_read(&inode->u.ext3_i.truncate_sem); --+ down_read(&ei->truncate_sem); -- err = ext3_alloc_branch(handle, inode, left, goal, -- offsets+(partial-chain), partial); -- --@@ -794,7 +797,7 @@ out: -- if (!err) -- err = ext3_splice_branch(handle, inode, iblock, chain, -- partial, left); --- up_read(&inode->u.ext3_i.truncate_sem); --+ up_read(&ei->truncate_sem); -- if (err == -EAGAIN) -- goto changed; -- if (err) --@@ -807,8 +810,8 @@ out: -- * truncate is in progress. It is racy between multiple parallel -- * instances of get_block, but we have the BKL. -- */ --- if (new_size > inode->u.ext3_i.i_disksize) --- inode->u.ext3_i.i_disksize = new_size; --+ if (new_size > ei->i_disksize) --+ ei->i_disksize = new_size; -- -- bh_result->b_state |= (1UL << BH_New); -- goto got_it; --@@ -921,7 +924,7 @@ struct buffer_head *ext3_bread(handle_t -- struct buffer_head *tmp_bh; -- -- for (i = 1; --- inode->u.ext3_i.i_prealloc_count && --+ EXT3_I(inode)->i_prealloc_count && -- i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks; -- i++) { -- /* --@@ -1131,8 +1134,8 @@ static int ext3_commit_write(struct file -- kunmap(page); -- } -- } --- if (inode->i_size > inode->u.ext3_i.i_disksize) { --- inode->u.ext3_i.i_disksize = inode->i_size; --+ if (inode->i_size > EXT3_I(inode)->i_disksize) { --+ EXT3_I(inode)->i_disksize = inode->i_size; -- ret2 = ext3_mark_inode_dirty(handle, inode); -- if (!ret) -- ret = ret2; --@@ -1832,7 +1835,8 @@ static void ext3_free_branches(handle_t -- void ext3_truncate(struct inode * inode) -- { -- handle_t *handle; --- u32 *i_data = inode->u.ext3_i.i_data; --+ struct ext3_inode_info *ei = EXT3_I(inode); --+ u32 *i_data = EXT3_I(inode)->i_data; -- int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb); -- int offsets[4]; -- Indirect chain[4]; --@@ -1884,13 +1887,13 @@ void ext3_truncate(struct inode * inode) -- * on-disk inode. We do this via i_disksize, which is the value which -- * ext3 *really* writes onto the disk inode. -- */ --- inode->u.ext3_i.i_disksize = inode->i_size; --+ ei->i_disksize = inode->i_size; -- -- /* -- * From here we block out all ext3_get_block() callers who want to -- * modify the block allocation tree. -- */ --- down_write(&inode->u.ext3_i.truncate_sem); --+ down_write(&ei->truncate_sem); -- -- if (n == 1) { /* direct blocks */ -- ext3_free_data(handle, inode, NULL, i_data+offsets[0], --@@ -1954,7 +1957,7 @@ do_indirects: -- case EXT3_TIND_BLOCK: -- ; -- } --- up_write(&inode->u.ext3_i.truncate_sem); --+ up_write(&ei->truncate_sem); -- inode->i_mtime = inode->i_ctime = CURRENT_TIME; -- ext3_mark_inode_dirty(handle, inode); -- --@@ -1983,6 +1986,8 @@ out_stop: -- -- int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) -- { --+ struct super_block *sb = inode->i_sb; --+ struct ext3_sb_info *sbi = EXT3_SB(sb); -- struct buffer_head *bh = 0; -- unsigned long block; -- unsigned long block_group; --@@ -1997,23 +2010,19 @@ int ext3_get_inode_loc (struct inode *in -- inode->i_ino != EXT3_JOURNAL_INO && --- inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || --- inode->i_ino > le32_to_cpu( --- inode->i_sb->u.ext3_sb.s_es->s_inodes_count)) { --- ext3_error (inode->i_sb, "ext3_get_inode_loc", --- "bad inode number: %lu", inode->i_ino); --+ inode->i_ino < EXT3_FIRST_INO(sb)) || --+ inode->i_ino > le32_to_cpu(sbi->s_es->s_inodes_count)) { --+ ext3_error (sb, __FUNCTION__, "bad inode #%lu", inode->i_ino); -- goto bad_inode; -- } --- block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb); --- if (block_group >= inode->i_sb->u.ext3_sb.s_groups_count) { --- ext3_error (inode->i_sb, "ext3_get_inode_loc", --- "group >= groups count"); --+ block_group = (inode->i_ino - 1) / sbi->s_inodes_per_group; --+ if (block_group >= sbi->s_groups_count) { --+ ext3_error(sb, __FUNCTION__, "group >= groups count"); -- goto bad_inode; -- } --- group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb); --- desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1); --- bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc]; --+ group_desc = block_group >> sbi->s_desc_per_block_bits; --+ desc = block_group & (sbi->s_desc_per_block - 1); --+ bh = sbi->s_group_desc[group_desc]; -- if (!bh) { --- ext3_error (inode->i_sb, "ext3_get_inode_loc", --- "Descriptor not loaded"); --+ ext3_error(sb, __FUNCTION__, "Descriptor not loaded"); -- goto bad_inode; -- } -- --@@ -2021,17 +2022,17 @@ int ext3_get_inode_loc (struct inode *in -- /* -- * Figure out the offset within the block group inode table -- */ --- offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) * --- EXT3_INODE_SIZE(inode->i_sb); --+ offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) * --+ sbi->s_inode_size; -- block = le32_to_cpu(gdp[desc].bg_inode_table) + --- (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); --- if (!(bh = sb_bread(inode->i_sb, block))) { --- ext3_error (inode->i_sb, "ext3_get_inode_loc", --+ (offset >> EXT3_BLOCK_SIZE_BITS(sb)); --+ if (!(bh = sb_bread(sb, block))) { --+ ext3_error (sb, __FUNCTION__, -- "unable to read inode block - " -- "inode=%lu, block=%lu", inode->i_ino, block); -- goto bad_inode; -- } --- offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1); --+ offset &= (EXT3_BLOCK_SIZE(sb) - 1); -- -- iloc->bh = bh; -- iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); --@@ -2047,6 +2048,7 @@ void ext3_read_inode(struct inode * inod -- { -- struct ext3_iloc iloc; -- struct ext3_inode *raw_inode; --+ struct ext3_inode_info *ei = EXT3_I(inode); -- struct buffer_head *bh; -- int block; -- --@@ -2054,7 +2056,7 @@ void ext3_read_inode(struct inode * inod -- goto bad_inode; -- bh = iloc.bh; -- raw_inode = iloc.raw_inode; --- init_rwsem(&inode->u.ext3_i.truncate_sem); --+ init_rwsem(&ei->truncate_sem); -- inode->i_mode = le16_to_cpu(raw_inode->i_mode); -- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); -- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); --@@ -2067,7 +2069,7 @@ void ext3_read_inode(struct inode * inod -- inode->i_atime = le32_to_cpu(raw_inode->i_atime); -- inode->i_ctime = le32_to_cpu(raw_inode->i_ctime); -- inode->i_mtime = le32_to_cpu(raw_inode->i_mtime); --- inode->u.ext3_i.i_dtime = le32_to_cpu(raw_inode->i_dtime); --+ ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); -- /* We now have enough fields to check if the inode was active or not. -- * This is needed because nfsd might try to access dead inodes -- * the test is that same one that e2fsck uses --@@ -2075,7 +2077,7 @@ void ext3_read_inode(struct inode * inod -- */ -- if (inode->i_nlink == 0) { -- if (inode->i_mode == 0 || --- !(inode->i_sb->u.ext3_sb.s_mount_state & EXT3_ORPHAN_FS)) { --+ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) { -- /* this inode is deleted */ -- brelse (bh); -- goto bad_inode; --@@ -2090,33 +2092,33 @@ void ext3_read_inode(struct inode * inod -- * size */ -- inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); -- inode->i_version = ++event; --- inode->u.ext3_i.i_flags = le32_to_cpu(raw_inode->i_flags); --+ ei->i_flags = le32_to_cpu(raw_inode->i_flags); -- #ifdef EXT3_FRAGMENTS --- inode->u.ext3_i.i_faddr = le32_to_cpu(raw_inode->i_faddr); --- inode->u.ext3_i.i_frag_no = raw_inode->i_frag; --- inode->u.ext3_i.i_frag_size = raw_inode->i_fsize; --+ ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); --+ ei->i_frag_no = raw_inode->i_frag; --+ ei->i_frag_size = raw_inode->i_fsize; -- #endif --- inode->u.ext3_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl); --+ ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); -- if (!S_ISREG(inode->i_mode)) { --- inode->u.ext3_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl); --+ ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl); -- } else { -- inode->i_size |= -- ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32; -- } --- inode->u.ext3_i.i_disksize = inode->i_size; --+ ei->i_disksize = inode->i_size; -- inode->i_generation = le32_to_cpu(raw_inode->i_generation); -- #ifdef EXT3_PREALLOCATE --- inode->u.ext3_i.i_prealloc_count = 0; --+ ei->i_prealloc_count = 0; -- #endif --- inode->u.ext3_i.i_block_group = iloc.block_group; --+ ei->i_block_group = iloc.block_group; -- -- /* -- * NOTE! The in-memory inode i_data array is in little-endian order -- * even on big-endian machines: we do NOT byteswap the block numbers! -- */ -- for (block = 0; block < EXT3_N_BLOCKS; block++) --- inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; --- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); --+ ei->i_data[block] = iloc.raw_inode->i_block[block]; --+ INIT_LIST_HEAD(&ei->i_orphan); -- -- brelse (iloc.bh); -- --@@ -2143,17 +2145,17 @@ void ext3_read_inode(struct inode * inod -- /* inode->i_attr_flags = 0; unused */ --- if (inode->u.ext3_i.i_flags & EXT3_SYNC_FL) { --+ if (ei->i_flags & EXT3_SYNC_FL) { -- /* inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS; unused */ -- inode->i_flags |= S_SYNC; -- } --- if (inode->u.ext3_i.i_flags & EXT3_APPEND_FL) { --+ if (ei->i_flags & EXT3_APPEND_FL) { -- /* inode->i_attr_flags |= ATTR_FLAG_APPEND; unused */ -- inode->i_flags |= S_APPEND; -- } --- if (inode->u.ext3_i.i_flags & EXT3_IMMUTABLE_FL) { --+ if (ei->i_flags & EXT3_IMMUTABLE_FL) { -- /* inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE; unused */ -- inode->i_flags |= S_IMMUTABLE; -- } --- if (inode->u.ext3_i.i_flags & EXT3_NOATIME_FL) { --+ if (ei->i_flags & EXT3_NOATIME_FL) { -- /* inode->i_attr_flags |= ATTR_FLAG_NOATIME; unused */ -- inode->i_flags |= S_NOATIME; -- } --@@ -2175,6 +2177,7 @@ static int ext3_do_update_inode(handle_t -- struct ext3_iloc *iloc) -- { -- struct ext3_inode *raw_inode = iloc->raw_inode; --+ struct ext3_inode_info *ei = EXT3_I(inode); -- struct buffer_head *bh = iloc->bh; -- int err = 0, rc, block; -- --@@ -2192,7 +2195,7 @@ static int ext3_do_update_inode(handle_t -- * Fix up interoperability with old kernels. Otherwise, old inodes get -- * re-used with the upper 16 bits of the uid/gid intact -- */ --- if(!inode->u.ext3_i.i_dtime) { --+ if(!ei->i_dtime) { -- raw_inode->i_uid_high = -- cpu_to_le16(high_16_bits(inode->i_uid)); -- raw_inode->i_gid_high = --@@ -2210,34 +2213,33 @@ static int ext3_do_update_inode(handle_t -- raw_inode->i_gid_high = 0; -- } -- raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); --- raw_inode->i_size = cpu_to_le32(inode->u.ext3_i.i_disksize); --+ raw_inode->i_size = cpu_to_le32(ei->i_disksize); -- raw_inode->i_atime = cpu_to_le32(inode->i_atime); -- raw_inode->i_ctime = cpu_to_le32(inode->i_ctime); -- raw_inode->i_mtime = cpu_to_le32(inode->i_mtime); -- raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); --- raw_inode->i_dtime = cpu_to_le32(inode->u.ext3_i.i_dtime); --- raw_inode->i_flags = cpu_to_le32(inode->u.ext3_i.i_flags); --+ raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); --+ raw_inode->i_flags = cpu_to_le32(ei->i_flags); -- #ifdef EXT3_FRAGMENTS --- raw_inode->i_faddr = cpu_to_le32(inode->u.ext3_i.i_faddr); --- raw_inode->i_frag = inode->u.ext3_i.i_frag_no; --- raw_inode->i_fsize = inode->u.ext3_i.i_frag_size; --+ raw_inode->i_faddr = cpu_to_le32(ei->i_faddr); --+ raw_inode->i_frag = ei->i_frag_no; --+ raw_inode->i_fsize = ei->i_frag_size; -- #else -- /* If we are not tracking these fields in the in-memory inode, -- * then preserve them on disk, but still initialise them to zero -- * for new inodes. */ --- if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) { --+ if (ei->i_state & EXT3_STATE_NEW) { -- raw_inode->i_faddr = 0; -- raw_inode->i_frag = 0; -- raw_inode->i_fsize = 0; -- } -- #endif --- raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl); --+ raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl); -- if (!S_ISREG(inode->i_mode)) { --- raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext3_i.i_dir_acl); --+ raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); -- } else { --- raw_inode->i_size_high = --- cpu_to_le32(inode->u.ext3_i.i_disksize >> 32); --- if (inode->u.ext3_i.i_disksize > 0x7fffffffULL) { --+ raw_inode->i_size_high = cpu_to_le32(ei->i_disksize >> 32); --+ if (ei->i_disksize > MAX_NON_LFS) { -- struct super_block *sb = inode->i_sb; -- if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, -- EXT3_FEATURE_RO_COMPAT_LARGE_FILE) || --@@ -2247,7 +2249,7 @@ static int ext3_do_update_inode(handle_t -- * created, add a flag to the superblock. -- */ -- err = ext3_journal_get_write_access(handle, --- sb->u.ext3_sb.s_sbh); --+ EXT3_SB(sb)->s_sbh); -- if (err) -- goto out_brelse; -- ext3_update_dynamic_rev(sb); --@@ -2256,7 +2258,7 @@ static int ext3_do_update_inode(handle_t -- sb->s_dirt = 1; -- handle->h_sync = 1; -- err = ext3_journal_dirty_metadata(handle, --- sb->u.ext3_sb.s_sbh); --+ EXT3_SB(sb)->s_sbh); -- } -- } -- } --@@ -2265,13 +2267,13 @@ static int ext3_do_update_inode(handle_t -- raw_inode->i_block[0] = -- cpu_to_le32(kdev_t_to_nr(inode->i_rdev)); -- else for (block = 0; block < EXT3_N_BLOCKS; block++) --- raw_inode->i_block[block] = inode->u.ext3_i.i_data[block]; --+ raw_inode->i_block[block] = ei->i_data[block]; -- -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- rc = ext3_journal_dirty_metadata(handle, bh); -- if (!err) -- err = rc; --- EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW; --+ ei->i_state &= ~EXT3_STATE_NEW; -- -- out_brelse: -- brelse (bh); --@@ -2379,7 +2381,7 @@ int ext3_setattr(struct dentry *dentry, -- } -- -- error = ext3_orphan_add(handle, inode); --- inode->u.ext3_i.i_disksize = attr->ia_size; --+ EXT3_I(inode)->i_disksize = attr->ia_size; -- rc = ext3_mark_inode_dirty(handle, inode); -- if (!error) -- error = rc; --@@ -2622,9 +2624,9 @@ int ext3_change_inode_journal_flag(struc -- */ -- -- if (val) --- inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL; --+ EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL; -- else --- inode->u.ext3_i.i_flags &= ~EXT3_JOURNAL_DATA_FL; --+ EXT3_I(inode)->i_flags &= ~EXT3_JOURNAL_DATA_FL; -- -- journal_unlock_updates(journal); -- ----- ./fs/ext3/ioctl.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/ioctl.c Tue May 7 15:20:52 2002 --@@ -18,13 +18,14 @@ -- int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, -- unsigned long arg) -- { --+ struct ext3_inode_info *ei = EXT3_I(inode); -- unsigned int flags; -- -- ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg); -- -- switch (cmd) { -- case EXT3_IOC_GETFLAGS: --- flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE; --+ flags = ei->i_flags & EXT3_FL_USER_VISIBLE; -- return put_user(flags, (int *) arg); -- case EXT3_IOC_SETFLAGS: { -- handle_t *handle = NULL; --@@ -42,7 +42,7 @@ int ext3_ioctl (struct inode * inode, st -- if (get_user(flags, (int *) arg)) -- return -EFAULT; -- --- oldflags = inode->u.ext3_i.i_flags; --+ oldflags = ei->i_flags; -- -- /* The JOURNAL_DATA flag is modifiable only by root */ -- jflag = flags & EXT3_JOURNAL_DATA_FL; --@@ -79,7 +79,7 @@ int ext3_ioctl (struct inode * inode, st -- -- flags = flags & EXT3_FL_USER_MODIFIABLE; -- flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE; --- inode->u.ext3_i.i_flags = flags; --+ ei->i_flags = flags; -- -- if (flags & EXT3_SYNC_FL) -- inode->i_flags |= S_SYNC; --@@ -155,12 +155,12 @@ flags_err: -- int ret = 0; -- -- set_current_state(TASK_INTERRUPTIBLE); --- add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait); --- if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) { --+ add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); --+ if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) { -- schedule(); -- ret = 1; -- } --- remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait); --+ remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait); -- return ret; -- } -- #endif ----- ./fs/ext3/namei.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/namei.c Tue May 7 16:05:51 2002 --@@ -636,7 +636,7 @@ static struct buffer_head * ext3_find_en -- } -- -- nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); --- start = dir->u.ext3_i.i_dir_start_lookup; --+ start = EXT3_I(dir)->i_dir_start_lookup; -- if (start >= nblocks) -- start = 0; -- block = start; --@@ -677,7 +677,7 @@ restart: -- i = search_dirblock(bh, dir, dentry, -- block << EXT3_BLOCK_SIZE_BITS(sb), res_dir); -- if (i == 1) { --- dir->u.ext3_i.i_dir_start_lookup = block; --+ EXT3_I(dir)->i_dir_start_lookup = block; -- ret = bh; -- goto cleanup_and_exit; -- } else { --@@ -1419,7 +1419,7 @@ int ext3_orphan_add(handle_t *handle, st -- int err = 0, rc; -- -- lock_super(sb); --- if (!list_empty(&inode->u.ext3_i.i_orphan)) --+ if (!list_empty(&EXT3_I(inode)->i_orphan)) -- goto out_unlock; -- -- /* Orphan handling is only valid for files with data blocks --@@ -1430,8 +1430,8 @@ int ext3_orphan_add(handle_t *handle, st -- J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || -- S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); -- --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "get_write_access"); --- err = ext3_journal_get_write_access(handle, sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access"); --+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -- if (err) -- goto out_unlock; -- --@@ -1442,7 +1442,7 @@ int ext3_orphan_add(handle_t *handle, st -- /* Insert this inode at the head of the on-disk orphan list... */ -- NEXT_ORPHAN(inode) = le32_to_cpu(EXT3_SB(sb)->s_es->s_last_orphan); -- EXT3_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); --- err = ext3_journal_dirty_metadata(handle, sb->u.ext3_sb.s_sbh); --+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -- rc = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (!err) -- err = rc; --@@ -1456,7 +1456,7 @@ int ext3_orphan_add(handle_t *handle, st -- * This is safe: on error we're going to ignore the orphan list -- * anyway on the next recovery. */ -- if (!err) --- list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan); --+ list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); -- -- jbd_debug(4, "superblock will point to %ld\n", inode->i_ino); -- jbd_debug(4, "orphan inode %ld will point to %d\n", --@@ -714,25 +770,25 @@ -- int ext3_orphan_del(handle_t *handle, struct inode *inode) -- { -- struct list_head *prev; --+ struct ext3_inode_info *ei = EXT3_I(inode); -- struct ext3_sb_info *sbi; -- ino_t ino_next; -- struct ext3_iloc iloc; -- int err = 0; -- -- lock_super(inode->i_sb); --- if (list_empty(&inode->u.ext3_i.i_orphan)) { --+ if (list_empty(&ei->i_orphan)) { -- unlock_super(inode->i_sb); -- return 0; -- } -- -- ino_next = NEXT_ORPHAN(inode); --- prev = inode->u.ext3_i.i_orphan.prev; --+ prev = ei->i_orphan.prev; -- sbi = EXT3_SB(inode->i_sb); -- -- jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino); -- --- list_del(&inode->u.ext3_i.i_orphan); --- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); --+ list_del_init(&ei->i_orphan); -- -- /* If we're on an error path, we may not have a valid -- * transaction handle with which to update the orphan list on --@@ -1520,9 +1520,8 @@ int ext3_orphan_del(handle_t *handle, st -- err = ext3_journal_dirty_metadata(handle, sbi->s_sbh); -- } else { -- struct ext3_iloc iloc2; --- struct inode *i_prev = --- list_entry(prev, struct inode, u.ext3_i.i_orphan); --- --+ struct inode *i_prev = orphan_list_entry(prev); --+ -- jbd_debug(4, "orphan inode %ld will point to %ld\n", -- i_prev->i_ino, ino_next); -- err = ext3_reserve_inode_write(handle, i_prev, &iloc2); --@@ -1695,10 +1695,10 @@ static int ext3_symlink (struct inode * -- goto out_no_entry; -- } else { -- inode->i_op = &ext3_fast_symlink_inode_operations; --- memcpy((char*)&inode->u.ext3_i.i_data,symname,l); --+ memcpy((char*)&EXT3_I(inode)->i_data,symname,l); -- inode->i_size = l-1; -- } --- inode->u.ext3_i.i_disksize = inode->i_size; --+ EXT3_I(inode)->i_disksize = inode->i_size; -- err = ext3_add_nondir(handle, dentry, inode); -- ext3_mark_inode_dirty(handle, inode); -- out_stop: ----- ./fs/ext3/super.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/super.c Tue May 7 16:05:44 2002 --@@ -121,7 +121,7 @@ static int ext3_error_behaviour(struct s -- /* If no overrides were specified on the mount, then fall back -- * to the default behaviour set in the filesystem's superblock -- * on disk. */ --- switch (le16_to_cpu(sb->u.ext3_sb.s_es->s_errors)) { --+ switch (le16_to_cpu(EXT3_SB(sb)->s_es->s_errors)) { -- case EXT3_ERRORS_PANIC: -- return EXT3_ERRORS_PANIC; -- case EXT3_ERRORS_RO: --@@ -269,9 +269,9 @@ void ext3_abort (struct super_block * sb -- return; -- -- printk (KERN_CRIT "Remounting filesystem read-only\n"); --- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; --+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; -- sb->s_flags |= MS_RDONLY; --- sb->u.ext3_sb.s_mount_opt |= EXT3_MOUNT_ABORT; --+ EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; -- journal_abort(EXT3_SB(sb)->s_journal, -EIO); -- } -- --@@ -377,8 +377,6 @@ static int ext3_blkdev_remove(struct ext3 -- return ret; -- } -- ---#define orphan_list_entry(l) list_entry((l), struct inode, u.ext3_i.i_orphan) --- -- static void dump_orphan_list(struct super_block *sb, struct ext3_sb_info *sbi) -- { -- struct list_head *l; --@@ -818,7 +818,7 @@ static void ext3_orphan_cleanup (struct -- sb->s_flags &= ~MS_RDONLY; -- } -- --- if (sb->u.ext3_sb.s_mount_state & EXT3_ERROR_FS) { --+ if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { -- if (es->s_last_orphan) -- jbd_debug(1, "Errors on filesystem, " -- "clearing orphan list.\n"); --@@ -1463,12 +1463,14 @@ static void ext3_commit_super (struct su -- struct ext3_super_block * es, -- int sync) -- { --+ struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; --+ -- es->s_wtime = cpu_to_le32(CURRENT_TIME); --- BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty"); --- mark_buffer_dirty(sb->u.ext3_sb.s_sbh); --+ BUFFER_TRACE(sbh, "marking dirty"); --+ mark_buffer_dirty(sbh); -- if (sync) { --- ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh); --- wait_on_buffer(sb->u.ext3_sb.s_sbh); --+ ll_rw_block(WRITE, 1, &sbh); --+ wait_on_buffer(sbh); -- } -- } -- --@@ -1519,7 +1521,7 @@ static void ext3_clear_journal_err(struc -- ext3_warning(sb, __FUNCTION__, "Marking fs in need of " -- "filesystem check."); -- --- sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS; --+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; -- es->s_state |= cpu_to_le16(EXT3_ERROR_FS); -- ext3_commit_super (sb, es, 1); -- ----- ./fs/ext3/symlink.c.orig Fri Apr 12 10:27:49 2002 --+++ ./fs/ext3/symlink.c Tue May 7 15:25:39 2002 --@@ -23,13 +23,13 @@ -- -- static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) -- { --- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; --- return vfs_readlink(dentry, buffer, buflen, s); --+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); --+ return vfs_readlink(dentry, buffer, buflen, (char *)ei->i_data); -- } -- -- static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd) -- { --- char *s = (char *)dentry->d_inode->u.ext3_i.i_data; --- return vfs_follow_link(nd, s); --+ struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); --+ return vfs_follow_link(nd, (char*)ei->i_data); -- } -- ----- ./include/linux/ext3_fs.h.orig Tue Apr 16 14:27:25 2002 --+++ ./include/linux/ext3_fs.h Tue May 7 16:47:36 2002 --@@ -84,22 +84,25 @@ -- #define EXT3_MIN_BLOCK_SIZE 1024 -- #define EXT3_MAX_BLOCK_SIZE 4096 -- #define EXT3_MIN_BLOCK_LOG_SIZE 10 --+ -- #ifdef __KERNEL__ ---# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) ---#else ---# define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) ---#endif ---#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) ---#ifdef __KERNEL__ ---# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) ---#else ---# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) ---#endif ---#ifdef __KERNEL__ ---#define EXT3_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_addr_per_block_bits) ---#define EXT3_INODE_SIZE(s) ((s)->u.ext3_sb.s_inode_size) ---#define EXT3_FIRST_INO(s) ((s)->u.ext3_sb.s_first_ino) --+#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) --+#define EXT3_I(inode) (&((inode)->u.ext3_i)) --+ --+#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) --+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) --+#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) --+#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) --+#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) -- #else --+ --+/* Assume that user mode programs are passing in an ext3fs superblock, not --+ * a kernel struct super_block. This will allow us to call the feature-test --+ * macros from user land. */ --+#define EXT3_SB(sb) (sb) --+ --+#define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) --+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) -- #define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \ -- EXT3_GOOD_OLD_INODE_SIZE : \ -- (s)->s_inode_size) --@@ -108,6 +110,7 @@ -- EXT3_GOOD_OLD_FIRST_INO : \ -- (s)->s_first_ino) -- #endif --+#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) -- -- /* -- * Macro-instructions used to manage fragments --@@ -116,8 +120,8 @@ -- #define EXT3_MAX_FRAG_SIZE 4096 -- #define EXT3_MIN_FRAG_LOG_SIZE 10 -- #ifdef __KERNEL__ ---# define EXT3_FRAG_SIZE(s) ((s)->u.ext3_sb.s_frag_size) ---# define EXT3_FRAGS_PER_BLOCK(s) ((s)->u.ext3_sb.s_frags_per_block) --+# define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) --+# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) -- #else -- # define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size) -- # define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s)) --@@ -163,15 +167,13 @@ -- /* -- * Macro-instructions used to manage group descriptors -- */ --+# define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) --+# define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) -- #ifdef __KERNEL__ ---# define EXT3_BLOCKS_PER_GROUP(s) ((s)->u.ext3_sb.s_blocks_per_group) ---# define EXT3_DESC_PER_BLOCK(s) ((s)->u.ext3_sb.s_desc_per_block) ---# define EXT3_INODES_PER_GROUP(s) ((s)->u.ext3_sb.s_inodes_per_group) ---# define EXT3_DESC_PER_BLOCK_BITS(s) ((s)->u.ext3_sb.s_desc_per_block_bits) --+# define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) --+# define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) -- #else ---# define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) -- # define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc)) ---# define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) -- #endif -- -- /* --@@ -344,7 +347,7 @@ -- #ifndef _LINUX_EXT2_FS_H -- #define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt -- #define set_opt(o, opt) o |= EXT3_MOUNT_##opt ---#define test_opt(sb, opt) ((sb)->u.ext3_sb.s_mount_opt & \ --+#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ -- EXT3_MOUNT_##opt) -- #else -- #define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD --@@ -441,17 +443,11 @@ -- /*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */ -- }; -- ---#ifdef __KERNEL__ ---#define EXT3_SB(sb) (&((sb)->u.ext3_sb)) ---#define EXT3_I(inode) (&((inode)->u.ext3_i)) ---#else ---/* Assume that user mode programs are passing in an ext3fs superblock, not --- * a kernel struct super_block. This will allow us to call the feature-test --- * macros from user land. */ ---#define EXT3_SB(sb) (sb) ---#endif --- ---#define NEXT_ORPHAN(inode) (inode)->u.ext3_i.i_dtime --+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime --+static inline struct inode *orphan_list_entry(struct list_head *l) --+{ --+ return list_entry(l, struct inode, u.ext3_i.i_orphan); --+} -- -- /* -- * Codes for operating systems ----- ./include/linux/ext3_jbd.h.orig Tue May 7 14:44:08 2002 --+++ ./include/linux/ext3_jbd.h Tue May 7 14:44:43 2002 --@@ -291,7 +291,7 @@ -- return 1; -- if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) -- return 1; --- if (inode->u.ext3_i.i_flags & EXT3_JOURNAL_DATA_FL) --+ if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) -- return 1; -- return 0; -- } diff --cc lustre/extN/extN-2.4.18-exports.diff index 8780209,8780209..0000000 deleted file mode 100644,100644 --- a/lustre/extN/extN-2.4.18-exports.diff +++ /dev/null @@@ -1,11 -1,11 +1,0 @@@ ----- linux-2.4.17/fs/extN/super.c.orig Fri Dec 21 10:41:55 2001 --+++ linux-2.4.17/fs/extN/super.c Fri Mar 22 11:00:41 2002 --@@ -1742,7 +1742,7 @@ -- unregister_filesystem(&extN_fs_type); -- } -- ---EXPORT_NO_SYMBOLS; --+EXPORT_SYMBOL(extN_bread); -- -- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); diff --cc lustre/extN/extN-2.4.18-ino_sb_fixup.diff index 37fd692,37fd692..0000000 deleted file mode 100644,100644 --- a/lustre/extN/extN-2.4.18-ino_sb_fixup.diff +++ /dev/null @@@ -1,33 -1,33 +1,0 @@@ ----- ./include/linux/extN_fs.h.orig Tue May 7 17:06:03 2002 --+++ ./include/linux/extN_fs.h Tue May 7 17:07:11 2002 --@@ -17,6 +17,8 @@ -- #define _LINUX_EXTN_FS_H -- -- #include --+#include --+#include -- -- /* -- * The second extended filesystem constants/structures --@@ -86,8 +88,8 @@ -- #define EXTN_MIN_BLOCK_LOG_SIZE 10 -- -- #ifdef __KERNEL__ ---#define EXTN_SB(sb) (&((sb)->u.extN_sb)) ---#define EXTN_I(inode) (&((inode)->u.extN_i)) --+#define EXTN_SB(sb) ((struct extN_sb_info *)&((sb)->u.generic_sbp)) --+#define EXTN_I(inode) ((struct extN_inode_info *)&((inode)->u.generic_ip)) -- -- #define EXTN_BLOCK_SIZE(s) ((s)->s_blocksize) -- #define EXTN_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) --@@ -447,7 +447,9 @@ -- #define NEXT_ORPHAN(inode) EXTN_I(inode)->i_dtime -- static inline struct inode *orphan_list_entry(struct list_head *l) -- { --- return list_entry(l, struct inode, u.extN_i.i_orphan); --+ return ((struct inode *)((char *)l - --+ (unsigned long)(offsetof(struct inode, u.generic_ip) + --+ offsetof(struct extN_inode_info, i_orphan)))); -- } -- -- /* diff --cc lustre/extN/extN-misc-fixup.diff index 29b36fb,29b36fb..0000000 deleted file mode 100644,100644 --- a/lustre/extN/extN-misc-fixup.diff +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ ----- linux-2.4.17/fs/extN/super.c.orig Fri Dec 21 10:41:55 2001 --+++ linux-2.4.17/fs/extN/super.c Fri Mar 22 11:00:41 2002 --@@ -1344,10 +1342,10 @@ -- printk(KERN_ERR "EXTN-fs: I/O error on journal device\n"); -- goto out_journal; -- } --- if (ntohl(journal->j_superblock->s_nr_users) != 1) { --+ if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { -- printk(KERN_ERR "EXTN-fs: External journal has more than one " -- "user (unsupported) - %d\n", --- ntohl(journal->j_superblock->s_nr_users)); --+ be32_to_cpu(journal->j_superblock->s_nr_users)); -- goto out_journal; -- } -- EXTN_SB(sb)->journal_bdev = bdev; diff --cc lustre/extN/htree-ext3-2.4.18.diff index de8bc8a,de8bc8a..0000000 deleted file mode 100644,100644 --- a/lustre/extN/htree-ext3-2.4.18.diff +++ /dev/null @@@ -1,1213 -1,1213 +1,0 @@@ ----- ./fs/ext3/super.c 2002/03/05 06:18:59 2.1 --+++ ./fs/ext3/super.c 2002/03/05 06:26:56 --@@ -529,6 +529,12 @@ -- "EXT3 Check option not supported\n"); -- #endif -- } --+ else if (!strcmp (this_char, "index")) --+#ifdef CONFIG_EXT3_INDEX --+ set_opt (*mount_options, INDEX); --+#else --+ printk("EXT3 index option not supported\n"); --+#endif -- else if (!strcmp (this_char, "debug")) -- set_opt (*mount_options, DEBUG); -- else if (!strcmp (this_char, "errors")) { --@@ -702,6 +708,12 @@ static int ext3_setup_super(struct super -- es->s_mtime = cpu_to_le32(CURRENT_TIME); -- ext3_update_dynamic_rev(sb); -- EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); --+ --+ if (test_opt(sb, INDEX)) --+ EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX); --+ else if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) --+ set_opt (EXT3_SB(sb)->s_mount_opt, INDEX); --+ -- ext3_commit_super (sb, es, 1); -- if (test_opt (sb, DEBUG)) -- printk (KERN_INFO ----- ./fs/ext3/namei.c 2002/03/05 06:18:59 2.1 --+++ ./fs/ext3/namei.c 2002/03/06 00:13:18 --@@ -16,6 +16,10 @@ -- * David S. Miller (davem@caip.rutgers.edu), 1995 -- * Directory entry file type support and forward compatibility hooks -- * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 --+ * Hash Tree Directory indexing (c) --+ * Daniel Phillips, 2001 --+ * Hash Tree Directory indexing porting --+ * Christopher Li, 2002 -- */ -- -- #include --@@ -33,7 +33,7 @@ -- #include -- #include -- #include --- --+#include -- -- /* -- * define how far ahead to read directories while searching them. --@@ -38,6 +42,433 @@ -- #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) -- #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) -- --+static struct buffer_head *ext3_append(handle_t *handle, --+ struct inode *inode, --+ u32 *block, int *err) --+{ --+ struct buffer_head *bh; --+ --+ *block = inode->i_size >> inode->i_sb->s_blocksize_bits; --+ --+ if ((bh = ext3_bread(handle, inode, *block, 1, err))) { --+ inode->i_size += inode->i_sb->s_blocksize; --+ EXT3_I(inode)->i_disksize = inode->i_size; --+ ext3_journal_get_write_access(handle,bh); --+ } --+ return bh; --+} --+ --+#ifndef assert --+#define assert(test) J_ASSERT(test) --+#endif --+ --+#ifndef swap --+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) --+#endif --+ --+typedef struct { u32 v; } le_u32; --+typedef struct { u16 v; } le_u16; --+ --+#define dxtrace_on(command) command --+#define dxtrace_off(command) --+#define dxtrace dxtrace_off --+ --+struct fake_dirent --+{ --+ /*le*/u32 inode; --+ /*le*/u16 rec_len; --+ u8 name_len; --+ u8 file_type; --+}; --+ --+struct dx_countlimit --+{ --+ le_u16 limit; --+ le_u16 count; --+}; --+ --+struct dx_entry --+{ --+ le_u32 hash; --+ le_u32 block; --+}; --+ --+/* --+ * dx_root_info is laid out so that if it should somehow get overlaid by a --+ * dirent the two low bits of the hash version will be zero. Therefore, the --+ * hash version mod 4 should never be 0. Sincerely, the paranoia department. --+ */ --+ --+struct dx_root --+{ --+ struct fake_dirent dot; --+ char dot_name[4]; --+ struct fake_dirent dotdot; --+ char dotdot_name[4]; --+ struct dx_root_info --+ { --+ le_u32 reserved_zero; --+ u8 hash_version; /* 0 now, 1 at release */ --+ u8 info_length; /* 8 */ --+ u8 indirect_levels; --+ u8 unused_flags; --+ } --+ info; --+ struct dx_entry entries[0]; --+}; --+ --+struct dx_node --+{ --+ struct fake_dirent fake; --+ struct dx_entry entries[0]; --+}; --+ --+ --+struct dx_frame --+{ --+ struct buffer_head *bh; --+ struct dx_entry *entries; --+ struct dx_entry *at; --+}; --+ --+struct dx_map_entry --+{ --+ u32 hash; --+ u32 offs; --+}; --+ --+typedef struct ext3_dir_entry_2 ext3_dirent; --+static inline unsigned dx_get_block (struct dx_entry *entry); --+static void dx_set_block (struct dx_entry *entry, unsigned value); --+static inline unsigned dx_get_hash (struct dx_entry *entry); --+static void dx_set_hash (struct dx_entry *entry, unsigned value); --+static unsigned dx_get_count (struct dx_entry *entries); --+static unsigned dx_get_limit (struct dx_entry *entries); --+static void dx_set_count (struct dx_entry *entries, unsigned value); --+static void dx_set_limit (struct dx_entry *entries, unsigned value); --+static unsigned dx_root_limit (struct inode *dir, unsigned infosize); --+static unsigned dx_node_limit (struct inode *dir); --+static unsigned dx_hack_hash (const u8 *name, int len); --+static struct dx_frame *dx_probe (struct inode *dir, u32 hash, struct dx_frame *frame); --+static void dx_release (struct dx_frame *frames); --+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]); --+static void dx_sort_map(struct dx_map_entry *map, unsigned count); --+static ext3_dirent *dx_copy_dirents (char *from, char *to, --+ struct dx_map_entry *map, int count); --+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); --+ --+ --+#ifdef CONFIG_EXT3_INDEX --+/* --+ * Future: use high four bits of block for coalesce-on-delete flags --+ * Mask them off for now. --+ */ --+ --+static inline unsigned dx_get_block (struct dx_entry *entry) --+{ --+ return le32_to_cpu(entry->block.v) & 0x00ffffff; --+} --+ --+static inline void dx_set_block (struct dx_entry *entry, unsigned value) --+{ --+ entry->block.v = cpu_to_le32(value); --+} --+ --+static inline unsigned dx_get_hash (struct dx_entry *entry) --+{ --+ return le32_to_cpu(entry->hash.v); --+} --+ --+static inline void dx_set_hash (struct dx_entry *entry, unsigned value) --+{ --+ entry->hash.v = cpu_to_le32(value); --+} --+ --+static inline unsigned dx_get_count (struct dx_entry *entries) --+{ --+ return le16_to_cpu(((struct dx_countlimit *) entries)->count.v); --+} --+ --+static inline unsigned dx_get_limit (struct dx_entry *entries) --+{ --+ return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v); --+} --+ --+static inline void dx_set_count (struct dx_entry *entries, unsigned value) --+{ --+ ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value); --+} --+ --+static inline void dx_set_limit (struct dx_entry *entries, unsigned value) --+{ --+ ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value); --+} --+ --+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) --+{ --+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - --+ EXT3_DIR_REC_LEN(2) - infosize; --+ return 0? 20: entry_space / sizeof(struct dx_entry); --+} --+ --+static inline unsigned dx_node_limit (struct inode *dir) --+{ --+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); --+ return 0? 22: entry_space / sizeof(struct dx_entry); --+} --+ --+/* Hash function - not bad, but still looking for an ideal default */ --+ --+static unsigned dx_hack_hash (const u8 *name, int len) --+{ --+ u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; --+ while (len--) --+ { --+ u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); --+ if (hash & 0x80000000) hash -= 0x7fffffff; --+ hash1 = hash0; --+ hash0 = hash; --+ } --+ return hash0; --+} --+ --+#define dx_hash(s,n) (dx_hack_hash(s,n) << 1) --+ --+/* --+ * Debug --+ */ --+static void dx_show_index (char * label, struct dx_entry *entries) --+{ --+ int i, n = dx_get_count (entries); --+ printk("%s index ", label); --+ for (i = 0; i < n; i++) --+ { --+ printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i)); --+ } --+ printk("\n"); --+} --+ --+struct stats --+{ --+ unsigned names; --+ unsigned space; --+ unsigned bcount; --+}; --+ --+static struct stats dx_show_leaf (ext3_dirent *de, int size, int show_names) --+{ --+ unsigned names = 0, space = 0; --+ char *base = (char *) de; --+ printk("names: "); --+ while ((char *) de < base + size) --+ { --+ if (de->inode) --+ { --+ if (show_names) --+ { --+ int len = de->name_len; --+ char *name = de->name; --+ while (len--) printk("%c", *name++); --+ printk(":%x.%u ", dx_hash (de->name, de->name_len), ((char *) de - base)); --+ } --+ space += EXT3_DIR_REC_LEN(de->name_len); --+ names++; --+ } --+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); --+ } --+ printk("(%i)\n", names); --+ return (struct stats) { names, space, 1 }; --+} --+ --+struct stats dx_show_entries (struct inode *dir, struct dx_entry *entries, int levels) --+{ --+ unsigned blocksize = dir->i_sb->s_blocksize; --+ unsigned count = dx_get_count (entries), names = 0, space = 0, i; --+ unsigned bcount = 0; --+ struct buffer_head *bh; --+ int err; --+ printk("%i indexed blocks...\n", count); --+ for (i = 0; i < count; i++, entries++) --+ { --+ u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; --+ u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; --+ struct stats stats; --+ printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); --+ if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue; --+ stats = levels? --+ dx_show_entries (dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): --+ dx_show_leaf ((ext3_dirent *) bh->b_data, blocksize, 0); --+ names += stats.names; --+ space += stats.space; --+ bcount += stats.bcount; --+ brelse (bh); --+ } --+ if (bcount) --+ printk("%snames %u, fullness %u (%u%%)\n", levels?"":" ", --+ names, space/bcount,(space/bcount)*100/blocksize); --+ return (struct stats) { names, space, bcount}; --+} --+ --+/* --+ * Probe for a directory leaf block to search --+ */ --+ --+static struct dx_frame * --+dx_probe(struct inode *dir, u32 hash, struct dx_frame *frame_in) --+{ --+ unsigned count, indirect; --+ struct dx_entry *at, *entries, *p, *q, *m; --+ struct dx_root *root; --+ struct buffer_head *bh; --+ struct dx_frame *frame = frame_in; --+ int err; --+ --+ frame->bh = NULL; --+ if (!(bh = ext3_bread(NULL, dir, 0, 0, &err))) --+ goto fail; --+ root = (struct dx_root *) bh->b_data; --+ if (root->info.hash_version > 0 || root->info.unused_flags & 1) { --+ brelse(bh); --+ goto fail; --+ } --+ if ((indirect = root->info.indirect_levels) > 1) { --+ brelse(bh); --+ goto fail; --+ } --+ entries = (struct dx_entry *) (((char *) &root->info) + root->info.info_length); --+ assert (dx_get_limit(entries) == dx_root_limit(dir, root->info.info_length)); --+ dxtrace (printk("Look up %x", hash)); --+ while (1) --+ { --+ count = dx_get_count(entries); --+ assert (count && count <= dx_get_limit(entries)); --+ p = entries + 1; --+ q = entries + count - 1; --+ while (p <= q) --+ { --+ m = p + (q - p)/2; --+ dxtrace(printk(".")); --+ if (dx_get_hash(m) > hash) --+ q = m - 1; --+ else --+ p = m + 1; --+ } --+ --+ if (0) // linear search cross check --+ { --+ unsigned n = count - 1; --+ at = entries; --+ while (n--) --+ { --+ dxtrace(printk(",")); --+ if (dx_get_hash(++at) > hash) --+ { --+ at--; --+ break; --+ } --+ } --+ assert (at == p - 1); --+ } --+ --+ at = p - 1; --+ dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); --+ frame->bh = bh; --+ frame->entries = entries; --+ frame->at = at; --+ if (!indirect--) return frame; --+ if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0,&err))) --+ goto fail2; --+ at = entries = ((struct dx_node *) bh->b_data)->entries; --+ assert (dx_get_limit(entries) == dx_node_limit (dir)); --+ frame++; --+ } --+fail2: --+ while (frame >= frame_in) { --+ brelse(frame->bh); --+ frame--; --+ } --+fail: --+ return NULL; --+} --+ --+static void dx_release (struct dx_frame *frames) --+{ --+ if (frames[0].bh == NULL) --+ return; --+ --+ if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels) --+ brelse (frames[1].bh); --+ brelse (frames[0].bh); --+} --+ --+/* --+ * Directory block splitting, compacting --+ */ --+ --+static int dx_make_map (ext3_dirent *de, int size, struct dx_map_entry map[]) --+{ --+ int count = 0; --+ char *base = (char *) de; --+ while ((char *) de < base + size) { --+ if (de->name_len && de->inode) { --+ map[count].hash = dx_hash (de->name, de->name_len); --+ map[count].offs = (u32) ((char *) de - base); --+ count++; --+ } --+ de = (ext3_dirent *) ((char *) de + le16_to_cpu(de->rec_len)); --+ } --+ return count; --+} --+ --+static void dx_sort_map (struct dx_map_entry *map, unsigned count) --+{ --+ struct dx_map_entry *p, *q, *top = map + count - 1; --+ int more; --+ /* Combsort until bubble sort doesn't suck */ --+ while (count > 2) --+ { --+ count = count*10/13; --+ if (count - 9 < 2) /* 9, 10 -> 11 */ --+ count = 11; --+ for (p = top, q = p - count; q >= map; p--, q--) --+ if (p->hash < q->hash) --+ swap(*p, *q); --+ } --+ /* Garden variety bubble sort */ --+ do { --+ more = 0; --+ q = top; --+ while (q-- > map) --+ { --+ if (q[1].hash >= q[0].hash) --+ continue; --+ swap(*(q+1), *q); --+ more = 1; --+ } --+ } while(more); --+} --+ --+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) --+{ --+ struct dx_entry *entries = frame->entries; --+ struct dx_entry *old = frame->at, *new = old + 1; --+ int count = dx_get_count(entries); --+ --+ assert(count < dx_get_limit(entries)); --+ assert(old < entries + count); --+ memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); --+ dx_set_hash(new, hash); --+ dx_set_block(new, block); --+ dx_set_count(entries, count + 1); --+} --+#endif --+ --+static void ext3_update_dx_flag(struct inode *inode) --+{ --+ if (!test_opt(inode->i_sb, INDEX)) --+ EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; --+} --+ -- /* -- * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure. -- * --@@ -95,6 +529,15 @@ -- } -- -- /* --+ * p is at least 6 bytes before the end of page --+ */ --+static inline ext3_dirent *ext3_next_entry(ext3_dirent *p) --+{ --+ return (ext3_dirent *)((char*)p + le16_to_cpu(p->rec_len)); --+} --+ --+ --+/* -- * ext3_find_entry() -- * -- * finds an entry in the specified directory with the wanted name. It --@@ -105,6 +548,8 @@ -- * The returned buffer_head has ->b_count elevated. The caller is expected -- * to brelse() it when appropriate. -- */ --+ --+ -- static struct buffer_head * ext3_find_entry (struct dentry *dentry, -- struct ext3_dir_entry_2 ** res_dir) -- { --@@ -119,10 +564,76 @@ -- int num = 0; -- int nblocks, i, err; -- struct inode *dir = dentry->d_parent->d_inode; --+ int namelen; --+ const u8 *name; --+ unsigned blocksize; --+ ext3_dirent *de, *top; -- -- *res_dir = NULL; -- sb = dir->i_sb; --+ blocksize = sb->s_blocksize; --+ namelen = dentry->d_name.len; --+ name = dentry->d_name.name; --+ if (namelen > EXT3_NAME_LEN) --+ return NULL; --+ if (ext3_dx && is_dx(dir)) { --+ u32 hash = dx_hash (name, namelen); --+ struct dx_frame frames[2], *frame; --+ if (!(frame = dx_probe (dir, hash, frames))) --+ return NULL; --+dxnext: --+ block = dx_get_block(frame->at); --+ if (!(bh = ext3_bread (NULL,dir, block, 0, &err))) --+ goto dxfail; --+ de = (ext3_dirent *) bh->b_data; --+ top = (ext3_dirent *) ((char *) de + blocksize - --+ EXT3_DIR_REC_LEN(0)); --+ for (; de < top; de = ext3_next_entry(de)) --+ if (ext3_match (namelen, name, de)) { --+ if (!ext3_check_dir_entry("ext3_find_entry", --+ dir, de, bh, --+ (block<b_data))) { --+ brelse (bh); --+ goto dxfail; --+ } --+ *res_dir = de; --+ goto dxfound; --+ } --+ brelse (bh); --+ /* Same hash continues in next block? Search on. */ --+ if (++(frame->at) == frame->entries + dx_get_count(frame->entries)) --+ { --+ struct buffer_head *bh2; --+ if (frame == frames) --+ goto dxfail; --+ if (++(frames->at) == frames->entries + dx_get_count(frames->entries)) --+ goto dxfail; --+ /* should omit read if not continued */ --+ if (!(bh2 = ext3_bread (NULL, dir, --+ dx_get_block(frames->at), --+ 0, &err))) --+ goto dxfail; --+ brelse (frame->bh); --+ frame->bh = bh2; --+ frame->at = frame->entries = ((struct dx_node *) bh2->b_data)->entries; --+ /* Subtle: the 0th entry has the count, find the hash in frame above */ --+ if ((dx_get_hash(frames->at) & -2) == hash) --+ goto dxnext; --+ goto dxfail; --+ } --+ if ((dx_get_hash(frame->at) & -2) == hash) --+ goto dxnext; --+dxfail: --+ dxtrace(printk("%s not found\n", name)); --+ dx_release (frames); --+ return NULL; --+dxfound: --+ dx_release (frames); --+ return bh; -- --+ } --+ -- nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); -- start = dir->u.ext3_i.i_dir_start_lookup; -- if (start >= nblocks) --@@ -237,6 +748,92 @@ -- de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; -- } -- --+static ext3_dirent * --+dx_copy_dirents (char *from, char *to, struct dx_map_entry *map, int count) --+{ --+ unsigned rec_len = 0; --+ --+ while (count--) { --+ ext3_dirent *de = (ext3_dirent *) (from + map->offs); --+ rec_len = EXT3_DIR_REC_LEN(de->name_len); --+ memcpy (to, de, rec_len); --+ ((ext3_dirent *) to)->rec_len = rec_len; --+ to += rec_len; --+ map++; --+ } --+ return (ext3_dirent *) (to - rec_len); --+} --+ --+#ifdef CONFIG_EXT3_INDEX --+static ext3_dirent *do_split(handle_t *handle, struct inode *dir, --+ struct buffer_head **bh,struct dx_frame *frame, --+ u32 hash, int *error) --+{ --+ unsigned blocksize = dir->i_sb->s_blocksize; --+ unsigned count, continued; --+ struct buffer_head *bh2; --+ u32 newblock; --+ unsigned MAX_DX_MAP = PAGE_CACHE_SIZE/EXT3_DIR_REC_LEN(1) + 1; --+ u32 hash2; --+ struct dx_map_entry *map; --+ char *data1 = (*bh)->b_data, *data2, *data3; --+ unsigned split; --+ ext3_dirent *de, *de2; --+ --+ bh2 = ext3_append (handle, dir, &newblock, error); --+ if (!(bh2)) --+ { --+ brelse(*bh); --+ *bh = NULL; --+ return (ext3_dirent *)bh2; --+ } --+ --+ BUFFER_TRACE(*bh, "get_write_access"); --+ ext3_journal_get_write_access(handle, *bh); --+ BUFFER_TRACE(frame->bh, "get_write_access"); --+ ext3_journal_get_write_access(handle, frame->bh); --+ --+ data2 = bh2->b_data; --+ --+ map = kmalloc(sizeof(*map) * MAX_DX_MAP, GFP_KERNEL); --+ if (!map) --+ panic("no memory for do_split\n"); --+ count = dx_make_map ((ext3_dirent *) data1, blocksize, map); --+ split = count/2; // need to adjust to actual middle --+ dx_sort_map (map, count); --+ hash2 = map[split].hash; --+ continued = hash2 == map[split - 1].hash; --+ dxtrace(printk("Split block %i at %x, %i/%i\n", --+ dx_get_block(frame->at), hash2, split, count-split)); --+ --+ /* Fancy dance to stay within two buffers */ --+ de2 = dx_copy_dirents (data1, data2, map + split, count - split); --+ data3 = (char *) de2 + de2->rec_len; --+ de = dx_copy_dirents (data1, data3, map, split); --+ memcpy(data1, data3, (char *) de + de->rec_len - data3); --+ de = (ext3_dirent *) ((char *) de - data3 + data1); // relocate de --+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); --+ de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); --+ dxtrace(dx_show_leaf ((ext3_dirent *) data1, blocksize, 1)); --+ dxtrace(dx_show_leaf ((ext3_dirent *) data2, blocksize, 1)); --+ --+ /* Which block gets the new entry? */ --+ if (hash >= hash2) --+ { --+ swap(*bh, bh2); --+ de = de2; --+ } --+ dx_insert_block (frame, hash2 + continued, newblock); --+ ext3_journal_dirty_metadata (handle, bh2); --+ brelse (bh2); --+ ext3_journal_dirty_metadata (handle, frame->bh); --+ dxtrace(dx_show_index ("frame", frame->entries)); --+ kfree(map); --+ return de; --+} --+#endif --+ --+ -- /* -- * ext3_add_entry() -- * --@@ -251,6 +844,7 @@ -- /* -- * AKPM: the journalling code here looks wrong on the error paths -- */ --+ -- static int ext3_add_entry (handle_t *handle, struct dentry *dentry, -- struct inode *inode) -- { --@@ -258,117 +852,281 @@ -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; -- unsigned long offset; --- unsigned short rec_len; -- struct buffer_head * bh; --- struct ext3_dir_entry_2 * de, * de1; --- struct super_block * sb; --+ ext3_dirent *de; --+ struct super_block * sb = dir->i_sb; -- int retval; --+ unsigned short reclen = EXT3_DIR_REC_LEN(namelen); -- --- sb = dir->i_sb; --+ unsigned blocksize = sb->s_blocksize; --+ unsigned nlen, rlen; --+ u32 block, blocks; --+ char *top; -- -- if (!namelen) -- return -EINVAL; --- bh = ext3_bread (handle, dir, 0, 0, &retval); --- if (!bh) --- return retval; --- rec_len = EXT3_DIR_REC_LEN(namelen); --- offset = 0; --- de = (struct ext3_dir_entry_2 *) bh->b_data; --- while (1) { --- if ((char *)de >= sb->s_blocksize + bh->b_data) { --- brelse (bh); --- bh = NULL; --- bh = ext3_bread (handle, dir, --- offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval); --- if (!bh) --- return retval; --- if (dir->i_size <= offset) { --- if (dir->i_size == 0) { --- brelse(bh); --- return -ENOENT; --+ if (ext3_dx && is_dx(dir)) { --+ struct dx_frame frames[2], *frame; --+ struct dx_entry *entries, *at; --+ u32 hash; --+ char *data1; --+ --+ hash = dx_hash(name, namelen); --+ /* FIXME: do something if dx_probe() fails here */ --+ frame = dx_probe(dir, hash, frames); --+ entries = frame->entries; --+ at = frame->at; --+ --+ if (!(bh = ext3_bread(handle,dir, dx_get_block(at), 0,&retval))) --+ goto dxfail1; --+ --+ BUFFER_TRACE(bh, "get_write_access"); --+ ext3_journal_get_write_access(handle, bh); --+ --+ data1 = bh->b_data; --+ de = (ext3_dirent *) data1; --+ top = data1 + (0? 200: blocksize); --+ while ((char *) de < top) --+ { --+ /* FIXME: check EEXIST and dir */ --+ nlen = EXT3_DIR_REC_LEN(de->name_len); --+ rlen = le16_to_cpu(de->rec_len); --+ if ((de->inode? rlen - nlen: rlen) >= reclen) --+ goto dx_add; --+ de = (ext3_dirent *) ((char *) de + rlen); --+ } --+ /* Block full, should compress but for now just split */ --+ dxtrace(printk("using %u of %u node entries\n", --+ dx_get_count(entries), dx_get_limit(entries))); --+ /* Need to split index? */ --+ if (dx_get_count(entries) == dx_get_limit(entries)) --+ { --+ u32 newblock; --+ unsigned icount = dx_get_count(entries); --+ int levels = frame - frames; --+ struct dx_entry *entries2; --+ struct dx_node *node2; --+ struct buffer_head *bh2; --+ if (levels && dx_get_count(frames->entries) == dx_get_limit(frames->entries)) --+ goto dxfull; --+ bh2 = ext3_append (handle, dir, &newblock, &retval); --+ if (!(bh2)) --+ goto dxfail2; --+ node2 = (struct dx_node *)(bh2->b_data); --+ entries2 = node2->entries; --+ node2->fake.rec_len = cpu_to_le16(blocksize); --+ node2->fake.inode = 0; --+ BUFFER_TRACE(frame->bh, "get_write_access"); --+ ext3_journal_get_write_access(handle, frame->bh); --+ if (levels) --+ { --+ unsigned icount1 = icount/2, icount2 = icount - icount1; --+ unsigned hash2 = dx_get_hash(entries + icount1); --+ dxtrace(printk("Split index %i/%i\n", icount1, icount2)); --+ --+ BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ --+ ext3_journal_get_write_access(handle, frames[0].bh); --+ --+ memcpy ((char *) entries2, (char *) (entries + icount1), --+ icount2 * sizeof(struct dx_entry)); --+ dx_set_count (entries, icount1); --+ dx_set_count (entries2, icount2); --+ dx_set_limit (entries2, dx_node_limit(dir)); --+ --+ /* Which index block gets the new entry? */ --+ if (at - entries >= icount1) { --+ frame->at = at = at - entries - icount1 + entries2; --+ frame->entries = entries = entries2; --+ swap(frame->bh, bh2); -- } --- --- ext3_debug ("creating next block\n"); --- --- BUFFER_TRACE(bh, "get_write_access"); --- ext3_journal_get_write_access(handle, bh); --- de = (struct ext3_dir_entry_2 *) bh->b_data; --- de->inode = 0; --- de->rec_len = le16_to_cpu(sb->s_blocksize); --- dir->u.ext3_i.i_disksize = --- dir->i_size = offset + sb->s_blocksize; --- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --- ext3_mark_inode_dirty(handle, dir); --+ dx_insert_block (frames + 0, hash2, newblock); --+ dxtrace(dx_show_index ("node", frames[1].entries)); --+ dxtrace(dx_show_index ("node", --+ ((struct dx_node *) bh2->b_data)->entries)); --+ ext3_journal_dirty_metadata(handle, bh2); --+ brelse (bh2); -- } else { --- --- ext3_debug ("skipping to next block\n"); --- --- de = (struct ext3_dir_entry_2 *) bh->b_data; --+ dxtrace(printk("Creating second level index...\n")); --+ memcpy((char *) entries2, (char *) entries, --+ icount * sizeof(struct dx_entry)); --+ dx_set_limit(entries2, dx_node_limit(dir)); --+ --+ /* Set up root */ --+ dx_set_count(entries, 1); --+ dx_set_block(entries + 0, newblock); --+ ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; --+ --+ /* Add new access path frame */ --+ frame = frames + 1; --+ frame->at = at = at - entries + entries2; --+ frame->entries = entries = entries2; --+ frame->bh = bh2; --+ ext3_journal_get_write_access(handle, frame->bh); -- } --+ ext3_journal_dirty_metadata(handle, frames[0].bh); -- } --- if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh, --- offset)) { --- brelse (bh); --- return -ENOENT; --- } --- if (ext3_match (namelen, name, de)) { --+ de = do_split(handle, dir, &bh, frame, hash, &retval); --+ dx_release (frames); --+ if (!(de)) --+ goto fail; --+ nlen = EXT3_DIR_REC_LEN(de->name_len); --+ rlen = le16_to_cpu(de->rec_len); --+ goto add; --+ --+dx_add: --+ dx_release (frames); --+ goto add; --+ --+dxfull: --+ ext3_warning(sb, __FUNCTION__, "Directory index full!\n"); --+ retval = -ENOSPC; --+dxfail2: --+ brelse(bh); --+dxfail1: --+ dx_release (frames); --+ goto fail1; --+ } --+ --+ blocks = dir->i_size >> sb->s_blocksize_bits; --+ for (block = 0, offset = 0; block < blocks; block++) { --+ bh = ext3_bread(handle, dir, block, 0, &retval); --+ if(!bh) --+ return retval; --+ de = (ext3_dirent *)bh->b_data; --+ top = bh->b_data + blocksize - reclen; --+ while ((char *) de <= top) { --+ if (!ext3_check_dir_entry("ext3_add_entry", dir, de, --+ bh, offset)) { --+ brelse (bh); --+ return -EIO; --+ } --+ if (ext3_match (namelen, name, de)) { -- brelse (bh); -- return -EEXIST; --- } --- if ((le32_to_cpu(de->inode) == 0 && --- le16_to_cpu(de->rec_len) >= rec_len) || --- (le16_to_cpu(de->rec_len) >= --- EXT3_DIR_REC_LEN(de->name_len) + rec_len)) { --- BUFFER_TRACE(bh, "get_write_access"); --- ext3_journal_get_write_access(handle, bh); --- /* By now the buffer is marked for journaling */ --- offset += le16_to_cpu(de->rec_len); --- if (le32_to_cpu(de->inode)) { --- de1 = (struct ext3_dir_entry_2 *) ((char *) de + --- EXT3_DIR_REC_LEN(de->name_len)); --- de1->rec_len = --- cpu_to_le16(le16_to_cpu(de->rec_len) - --- EXT3_DIR_REC_LEN(de->name_len)); --- de->rec_len = cpu_to_le16( --- EXT3_DIR_REC_LEN(de->name_len)); --- de = de1; -- } --- de->file_type = EXT3_FT_UNKNOWN; --- if (inode) { --- de->inode = cpu_to_le32(inode->i_ino); --- ext3_set_de_type(dir->i_sb, de, inode->i_mode); --- } else --- de->inode = 0; --- de->name_len = namelen; --- memcpy (de->name, name, namelen); --- /* --- * XXX shouldn't update any times until successful --- * completion of syscall, but too many callers depend --- * on this. --- * --- * XXX similarly, too many callers depend on --- * ext3_new_inode() setting the times, but error --- * recovery deletes the inode, so the worst that can --- * happen is that the times are slightly out of date --- * and/or different from the directory change time. --- */ --- dir->i_mtime = dir->i_ctime = CURRENT_TIME; --- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --- dir->i_version = ++event; --- ext3_mark_inode_dirty(handle, dir); --- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); --- ext3_journal_dirty_metadata(handle, bh); --+ nlen = EXT3_DIR_REC_LEN(de->name_len); --+ rlen = le16_to_cpu(de->rec_len); --+ if ((de->inode? rlen - nlen: rlen) >= reclen) --+ goto add; --+ de = (ext3_dirent *)((char *)de + rlen); --+ offset += rlen; --+ } --+ if (ext3_dx && blocks == 1 && test_opt(sb, INDEX)) --+ goto dx_make_index; --+ brelse(bh); --+ } --+ bh = ext3_append(handle, dir, &block, &retval); --+ if (!bh) --+ return retval; --+ de = (ext3_dirent *) bh->b_data; --+ de->inode = 0; --+ de->rec_len = cpu_to_le16(rlen = blocksize); --+ nlen = 0; --+ goto add; --+ --+add: --+ BUFFER_TRACE(bh, "get_write_access"); --+ ext3_journal_get_write_access(handle, bh); --+ /* By now the buffer is marked for journaling */ --+ if (de->inode) { --+ ext3_dirent *de1 = (ext3_dirent *)((char *)de + nlen); --+ de1->rec_len = cpu_to_le16(rlen - nlen); --+ de->rec_len = cpu_to_le16(nlen); --+ de = de1; --+ } --+ de->file_type = EXT3_FT_UNKNOWN; --+ if (inode) { --+ de->inode = cpu_to_le32(inode->i_ino); --+ ext3_set_de_type(dir->i_sb, de, inode->i_mode); --+ } else --+ de->inode = 0; --+ de->name_len = namelen; --+ memcpy (de->name, name, namelen); --+ /* --+ * XXX shouldn't update any times until successful --+ * completion of syscall, but too many callers depend --+ * on this. --+ * --+ * XXX similarly, too many callers depend on --+ * ext3_new_inode() setting the times, but error --+ * recovery deletes the inode, so the worst that can --+ * happen is that the times are slightly out of date --+ * and/or different from the directory change time. --+ */ --+ dir->i_mtime = dir->i_ctime = CURRENT_TIME; --+ ext3_update_dx_flag(dir); --+ dir->i_version = ++event; --+ ext3_mark_inode_dirty(handle, dir); --+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); --+ ext3_journal_dirty_metadata(handle, bh); --+ brelse(bh); --+ return 0; --+ --+dx_make_index: --+ { --+ struct buffer_head *bh2; --+ struct dx_root *root; --+ struct dx_frame frames[2], *frame; --+ struct dx_entry *entries; --+ ext3_dirent *de2; --+ char *data1; --+ unsigned len; --+ u32 hash; --+ --+ dxtrace(printk("Creating index\n")); --+ ext3_journal_get_write_access(handle, bh); --+ root = (struct dx_root *) bh->b_data; --+ --+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; --+ bh2 = ext3_append (handle, dir, &block, &retval); --+ if (!(bh2)) --+ { -- brelse(bh); --- return 0; --+ return retval; -- } --- offset += le16_to_cpu(de->rec_len); --- de = (struct ext3_dir_entry_2 *) --- ((char *) de + le16_to_cpu(de->rec_len)); --+ data1 = bh2->b_data; --+ --+ /* The 0th block becomes the root, move the dirents out */ --+ de = (ext3_dirent *) &root->info; --+ len = ((char *) root) + blocksize - (char *) de; --+ memcpy (data1, de, len); --+ de = (ext3_dirent *) data1; --+ top = data1 + len; --+ while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top) --+ de = de2; --+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); --+ /* Initialize the root; the dot dirents already exist */ --+ de = (ext3_dirent *) (&root->dotdot); --+ de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2)); --+ memset (&root->info, 0, sizeof(root->info)); --+ root->info.info_length = sizeof(root->info); --+ entries = root->entries; --+ dx_set_block (entries, 1); --+ dx_set_count (entries, 1); --+ dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info))); --+ --+ /* Initialize as for dx_probe */ --+ hash = dx_hash (name, namelen); --+ frame = frames; --+ frame->entries = entries; --+ frame->at = entries; --+ frame->bh = bh; --+ bh = bh2; --+ de = do_split(handle,dir, &bh, frame, hash, &retval); --+ dx_release (frames); --+ if (!(de)) --+ return retval; --+ nlen = EXT3_DIR_REC_LEN(de->name_len); --+ rlen = le16_to_cpu(de->rec_len); --+ goto add; -- } --- brelse (bh); --- return -ENOSPC; --+fail1: --+ return retval; --+fail: --+ return -ENOENT; -- } -- --+ -- /* -- * ext3_delete_entry deletes a directory entry by merging it with the -- * previous entry --@@ -451,7 +1212,8 @@ -- struct inode * inode; -- int err; -- --- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); --+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -478,7 +1240,8 @@ -- struct inode *inode; -- int err; -- --- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); --+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -507,7 +1270,8 @@ -- if (dir->i_nlink >= EXT3_LINK_MAX) -- return -EMLINK; -- --- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); --+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -550,7 +1320,7 @@ -- if (err) -- goto out_no_entry; -- dir->i_nlink++; --- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --+ ext3_update_dx_flag(dir); -- ext3_mark_inode_dirty(handle, dir); -- d_instantiate(dentry, inode); -- out_stop: --@@ -832,7 +1596,7 @@ -- ext3_mark_inode_dirty(handle, inode); -- dir->i_nlink--; -- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; --- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --+ ext3_update_dx_flag(dir); -- ext3_mark_inode_dirty(handle, dir); -- -- end_rmdir: --@@ -878,7 +1642,7 @@ -- if (retval) -- goto end_unlink; -- dir->i_ctime = dir->i_mtime = CURRENT_TIME; --- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --+ ext3_update_dx_flag(dir); -- ext3_mark_inode_dirty(handle, dir); -- inode->i_nlink--; -- if (!inode->i_nlink) --@@ -904,7 +1668,8 @@ -- if (l > dir->i_sb->s_blocksize) -- return -ENAMETOOLONG; -- --- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5); --+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -959,7 +1724,8 @@ -- if (inode->i_nlink >= EXT3_LINK_MAX) -- return -EMLINK; -- --- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS); --+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -995,7 +1761,8 @@ -- -- old_bh = new_bh = dir_bh = NULL; -- --- handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2); --+ handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + --+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); -- if (IS_ERR(handle)) -- return PTR_ERR(handle); -- --@@ -1077,7 +1844,7 @@ -- new_inode->i_ctime = CURRENT_TIME; -- } -- old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; --- old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --+ ext3_update_dx_flag(old_dir); -- if (dir_bh) { -- BUFFER_TRACE(dir_bh, "get_write_access"); -- ext3_journal_get_write_access(handle, dir_bh); --@@ -1089,7 +1856,7 @@ -- new_inode->i_nlink--; -- } else { -- new_dir->i_nlink++; --- new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --+ ext3_update_dx_flag(new_dir); -- ext3_mark_inode_dirty(handle, new_dir); -- } -- } ----- ./include/linux/ext3_fs.h 2002/03/05 06:18:59 2.1 --+++ ./include/linux/ext3_fs.h 2002/03/05 06:26:56 --@@ -339,6 +339,7 @@ -- #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ -- #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ -- #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ --+#define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */ -- -- /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ -- #ifndef _LINUX_EXT2_FS_H --@@ -575,6 +576,24 @@ -- #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) -- #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ -- ~EXT3_DIR_ROUND) --+/* --+ * Hash Tree Directory indexing --+ * (c) Daniel Phillips, 2001 --+ */ --+ --+#define CONFIG_EXT3_INDEX --+ --+#ifdef CONFIG_EXT3_INDEX --+ enum {ext3_dx = 1}; --+ #define is_dx(dir) (EXT3_I(dir)->i_flags & EXT3_INDEX_FL) --+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) --+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) --+#else --+ enum {ext3_dx = 0}; --+ #define is_dx(dir) 0 --+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) --+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) --+#endif -- -- #ifdef __KERNEL__ -- /* ----- ./include/linux/ext3_jbd.h 2002/03/05 06:18:59 2.1 --+++ ./include/linux/ext3_jbd.h 2002/03/05 06:33:54 --@@ -63,6 +63,8 @@ -- -- #define EXT3_RESERVE_TRANS_BLOCKS 12 -- --+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 --+ -- int -- ext3_mark_iloc_dirty(handle_t *handle, -- struct inode *inode, diff --cc lustre/extN/linux-2.4.18ea-0.8.26.diff index 15df90c,15df90c..0000000 deleted file mode 100644,100644 --- a/lustre/extN/linux-2.4.18ea-0.8.26.diff +++ /dev/null @@@ -1,1787 -1,1787 +1,0 @@@ --Linux Extended Attributes -- Kernel Patch --24 April 2002, 11:31:18 -- -- --This patch 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. -- --This patch 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. -- --You should have received a copy of the GNU General Public License --along with this patch; if not, write to the Free Software Foundation, --Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- --After extracting the linux-2.4.18.tar.gz package, apply this patch as follows: -- -- cd linux -- patch -p1 < ../linux-2.4.18ea-0.8.26.patch -- --diff -Nur linux-2.4.18/fs/ext3/ialloc.c linux-2.4.18ea/fs/ext3/ialloc.c ----- linux-2.4.18/fs/ext3/ialloc.c Sun Feb 24 04:42:59 2002 --+++ linux-2.4.18ea/fs/ext3/ialloc.c Sun Feb 24 04:34:43 2002 --@@ -17,6 +17,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include --@@ -216,6 +217,7 @@ -- * as writing the quota to disk may need the lock as well. -- */ -- DQUOT_INIT(inode); --+ ext3_xattr_drop_inode(handle, inode); -- DQUOT_FREE_INODE(inode); -- DQUOT_DROP(inode); -- --diff -Nur linux-2.4.18/fs/ext3/inode.c linux-2.4.18ea/fs/ext3/inode.c ----- linux-2.4.18/fs/ext3/inode.c Sun Feb 24 04:42:59 2002 --+++ linux-2.4.18ea/fs/ext3/inode.c Thu Mar 14 21:51:59 2002 --@@ -39,6 +39,18 @@ -- */ -- #undef SEARCH_FROM_ZERO -- --+/* --+ * Test whether an inode is a fast symlink. --+ */ --+static inline int ext3_inode_is_fast_symlink(struct inode *inode) --+{ --+ int ea_blocks = EXT3_I(inode)->i_file_acl ? --+ (inode->i_sb->s_blocksize >> 9) : 0; --+ --+ return (S_ISLNK(inode->i_mode) && --+ inode->i_blocks - ea_blocks == 0); --+} --+ -- /* The ext3 forget function must perform a revoke if we are freeing data -- * which has been journaled. Metadata (eg. indirect blocks) must be -- * revoked in all cases. --@@ -48,7 +60,7 @@ -- * still needs to be revoked. -- */ -- ---static int ext3_forget(handle_t *handle, int is_metadata, --+int ext3_forget(handle_t *handle, int is_metadata, -- struct inode *inode, struct buffer_head *bh, -- int blocknr) -- { --@@ -164,9 +176,7 @@ -- { -- handle_t *handle; -- --- if (is_bad_inode(inode) || --- inode->i_ino == EXT3_ACL_IDX_INO || --- inode->i_ino == EXT3_ACL_DATA_INO) --+ if (is_bad_inode(inode)) -- goto no_delete; -- -- lock_kernel(); --@@ -1845,6 +1855,8 @@ -- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || -- S_ISLNK(inode->i_mode))) -- return; --+ if (ext3_inode_is_fast_symlink(inode)) --+ return; -- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) -- return; -- --@@ -1992,8 +2004,6 @@ -- struct ext3_group_desc * gdp; -- -- if ((inode->i_ino != EXT3_ROOT_INO && --- inode->i_ino != EXT3_ACL_IDX_INO && --- inode->i_ino != EXT3_ACL_DATA_INO && -- inode->i_ino != EXT3_JOURNAL_INO && -- inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || -- inode->i_ino > le32_to_cpu( --@@ -2120,10 +2130,7 @@ -- -- brelse (iloc.bh); -- --- if (inode->i_ino == EXT3_ACL_IDX_INO || --- inode->i_ino == EXT3_ACL_DATA_INO) --- /* Nothing to do */ ; --- else if (S_ISREG(inode->i_mode)) { --+ if (S_ISREG(inode->i_mode)) { -- inode->i_op = &ext3_file_inode_operations; -- inode->i_fop = &ext3_file_operations; -- inode->i_mapping->a_ops = &ext3_aops; --@@ -2131,7 +2138,7 @@ -- inode->i_op = &ext3_dir_inode_operations; -- inode->i_fop = &ext3_dir_operations; -- } else if (S_ISLNK(inode->i_mode)) { --- if (!inode->i_blocks) --+ if (ext3_inode_is_fast_symlink(inode)) -- inode->i_op = &ext3_fast_symlink_inode_operations; -- else { -- inode->i_op = &page_symlink_inode_operations; --diff -Nur linux-2.4.18/fs/ext3/namei.c linux-2.4.18ea/fs/ext3/namei.c ----- linux-2.4.18/fs/ext3/namei.c Fri Nov 9 23:25:04 2001 --+++ linux-2.4.18ea/fs/ext3/namei.c Mon Mar 11 03:27:00 2002 --@@ -23,6 +23,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include --@@ -465,6 +466,8 @@ -- inode->i_fop = &extN_file_operations; -- inode->i_mapping->a_ops = &ext3_aops; -- err = ext3_add_nondir(handle, dentry, inode); --+ if (err) --+ ext3_xattr_drop_inode(handle, inode); -- ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); --@@ -490,6 +493,8 @@ -- if (!IS_ERR(inode)) { -- init_special_inode(inode, mode, rdev); -- err = ext3_add_nondir(handle, dentry, inode); --+ if (err) --+ ext3_xattr_drop_inode(handle, inode); -- ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); --@@ -514,7 +519,7 @@ -- if (IS_SYNC(dir)) -- handle->h_sync = 1; -- --- inode = ext3_new_inode (handle, dir, S_IFDIR); --+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); -- err = PTR_ERR(inode); -- if (IS_ERR(inode)) -- goto out_stop; --@@ -522,7 +527,6 @@ -- inode->i_op = &ext3_dir_inode_operations; -- inode->i_fop = &ext3_dir_operations; --- inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize; --- inode->i_blocks = 0; --+ inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; -- dir_block = ext3_bread (handle, inode, 0, 1, &err); -- if (!dir_block) { -- inode->i_nlink--; /* is this nlink == 0? */ --@@ -549,9 +553,6 @@ -- BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, dir_block); -- brelse (dir_block); --- inode->i_mode = S_IFDIR | mode; --- if (dir->i_mode & S_ISGID) --- inode->i_mode |= S_ISGID; -- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_entry (handle, dentry, inode); -- if (err) --@@ -565,6 +566,7 @@ -- return err; -- -- out_no_entry: --+ ext3_xattr_drop_inode(handle, inode); -- inode->i_nlink = 0; -- ext3_mark_inode_dirty(handle, inode); -- iput (inode); --@@ -917,5 +919,5 @@ -- goto out_stop; -- --- if (l > sizeof (inode->u.ext3_i.i_data)) { --+ if (l > sizeof(EXT3_I(inode)->i_data)) { -- inode->i_op = &page_symlink_inode_operations; -- inode->i_mapping->a_ops = &ext3_aops; --diff -Nur linux-2.4.18/fs/ext3/super.c linux-2.4.18ea/fs/ext3/super.c ----- linux-2.4.18/fs/ext3/super.c Sun Feb 24 04:42:59 2002 --+++ linux-2.4.18ea/fs/ext3/super.c Thu Apr 4 21:41:05 2002 --@@ -24,6 +24,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include --@@ -404,6 +405,7 @@ -- kdev_t j_dev = sbi->s_journal->j_dev; -- int i; -- --+ ext3_xattr_put_super(sb); -- journal_destroy(sbi->s_journal); -- if (!(sb->s_flags & MS_RDONLY)) { -- EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); --@@ -1734,14 +1772,25 @@ -- -- static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super); -- ---static int __init init_ext3_fs(void) --+static void exit_ext3_fs(void) -- { --- return register_filesystem(&ext3_fs_type); --+ unregister_filesystem(&ext3_fs_type); --+ exit_ext3_xattr_user(); --+ exit_ext3_xattr(); -- } -- ---static void __exit exit_ext3_fs(void) --+static int __init init_ext3_fs(void) -- { --- unregister_filesystem(&ext3_fs_type); --+ int error = init_ext3_xattr(); --+ if (!error) --+ error = init_ext3_xattr_user(); --+ if (!error) --+ error = register_filesystem(&ext3_fs_type); --+ if (!error) --+ return 0; --+ --+ exit_ext3_fs(); --+ return error; -- } -- -- EXPORT_NO_SYMBOLS; --diff -Nur linux-2.4.18/fs/ext3/xattr.c linux-2.4.18ea/fs/ext3/xattr.c ----- linux-2.4.18/fs/ext3/xattr.c Thu Jan 1 01:00:00 1970 --+++ linux-2.4.18ea/fs/ext3/xattr.c Wed Apr 3 13:19:05 2002 --@@ -0,0 +1,1247 @@ --+/* --+ * linux/fs/ext3/xattr.c --+ * --+ * Copyright (C) 2001 by Andreas Gruenbacher, --+ * --+ * Fix by Harrison Xing . --+ * Ext3 code with a lot of help from Eric Jarman . --+ * Extended attributes for symlinks and special files added per --+ * suggestion of Luka Renko . --+ */ --+ --+/* --+ * Extended attributes are stored on disk blocks allocated outside of --+ * any inode. The i_file_acl field is then made to point to this allocated --+ * block. If all extended attributes of an inode are identical, these --+ * inodes may share the same extended attribute block. Such situations --+ * are automatically detected by keeping a cache of recent attribute block --+ * numbers and hashes over the block's contents in memory. --+ * --+ * --+ * Extended attribute block layout: --+ * --+ * +------------------+ --+ * | header | --+ * ¦ entry 1 | | --+ * | entry 2 | | growing downwards --+ * | entry 3 | v --+ * | four null bytes | --+ * | . . . | --+ * | value 1 | ^ --+ * | value 3 | | growing upwards --+ * | value 2 | | --+ * +------------------+ --+ * --+ * The block header is followed by multiple entry descriptors. These entry --+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD --+ * byte boundaries. The entry descriptors are sorted by attribute name, --+ * so that two extended attribute blocks can be compared efficiently. --+ * --+ * Attribute values are aligned to the end of the block, stored in --+ * no specific order. They are also padded to EXT3_XATTR_PAD byte --+ * boundaries. No additional gaps are left between them. --+ * --+ * Locking strategy --+ * ---------------- --+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of --+ * the xattr inode operations are called, so we are guaranteed that only one --+ * processes accesses extended attributes of an inode at any time. --+ * --+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that --+ * only a single process is modifying an extended attribute block, even --+ * if the block is shared among inodes. --+ * --+ * Note for porting to 2.5 --+ * ----------------------- --+ * The BKL will no longer be held in the xattr inode operations. --+ */ --+ --+#include --+#include --+#include --+#include --+#include --+#include --+#ifdef CONFIG_EXT3_FS_XATTR_SHARING --+#include --+#endif --+#include --+#include --+#include --+#include --+ --+/* These symbols may be needed by a module. */ --+EXPORT_SYMBOL(extN_xattr_register); --+EXPORT_SYMBOL(extN_xattr_unregister); --+EXPORT_SYMBOL(extN_xattr_get); --+EXPORT_SYMBOL(extN_xattr_list); --+EXPORT_SYMBOL(extN_xattr_set); --+ --+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) --+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1) --+#endif --+ --+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) --+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) --+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) --+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) --+ --+#ifdef EXT3_XATTR_DEBUG --+# define ea_idebug(inode, f...) do { \ --+ printk(KERN_DEBUG "inode %s:%ld: ", \ --+ kdevname(inode->i_dev), inode->i_ino); \ --+ printk(f); \ --+ printk("\n"); \ --+ } while (0) --+# define ea_bdebug(bh, f...) do { \ --+ printk(KERN_DEBUG "block %s:%ld: ", \ --+ kdevname(bh->b_dev), bh->b_blocknr); \ --+ printk(f); \ --+ printk("\n"); \ --+ } while (0) --+#else --+# define ea_idebug(f...) --+# define ea_bdebug(f...) --+#endif --+ --+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, --+ struct ext3_xattr_header *); --+ --+#ifdef CONFIG_EXT3_FS_XATTR_SHARING --+ --+static int ext3_xattr_cache_insert(struct buffer_head *); --+static struct buffer_head *ext3_xattr_cache_find(struct inode *, --+ struct ext3_xattr_header *); --+static void ext3_xattr_cache_remove(struct buffer_head *); --+static void ext3_xattr_rehash(struct ext3_xattr_header *, --+ struct ext3_xattr_entry *); --+ --+static struct mb_cache *ext3_xattr_cache; --+ --+#else --+# define ext3_xattr_cache_insert(bh) 0 --+# define ext3_xattr_cache_find(inode, header) NULL --+# define ext3_xattr_cache_remove(bh) do {} while(0) --+# define ext3_xattr_rehash(header, entry) do {} while(0) --+#endif --+ --+/* --+ * If a file system does not share extended attributes among inodes, --+ * we should not need the ext3_xattr_sem semaphore. However, the --+ * filesystem may still contain shared blocks, so we always take --+ * the lock. --+ */ --+ --+DECLARE_MUTEX(ext3_xattr_sem); --+ --+static inline void --+ext3_xattr_lock(void) --+{ --+ down(&ext3_xattr_sem); --+} --+ --+static inline void --+ext3_xattr_unlock(void) --+{ --+ up(&ext3_xattr_sem); --+} --+ --+static inline int --+ext3_xattr_new_block(handle_t *handle, struct inode *inode, --+ int * errp, int force) --+{ --+ struct super_block *sb = inode->i_sb; --+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + --+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); --+ --+ /* How can we enforce the allocation? */ --+ int block = ext3_new_block(handle, inode, goal, 0, 0, errp); --+#ifdef OLD_QUOTAS --+ if (!*errp) --+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; --+#endif --+ return block; --+} --+ --+static inline int --+ext3_xattr_quota_alloc(struct inode *inode, int force) --+{ --+ /* How can we enforce the allocation? */ --+#ifdef OLD_QUOTAS --+ int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1); --+ if (!error) --+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; --+#else --+ int error = DQUOT_ALLOC_BLOCK(inode, 1); --+#endif --+ return error; --+} --+ --+#ifdef OLD_QUOTAS --+ --+static inline void --+ext3_xattr_quota_free(struct inode *inode) --+{ --+ DQUOT_FREE_BLOCK(inode->i_sb, inode, 1); --+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; --+} --+ --+static inline void --+ext3_xattr_free_block(handle_t *handle, struct inode * inode, --+ unsigned long block) --+{ --+ ext3_free_blocks(handle, inode, block, 1); --+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; --+} --+ --+#else --+# define ext3_xattr_quota_free(inode) \ --+ DQUOT_FREE_BLOCK(inode, 1) --+# define ext3_xattr_free_block(handle, inode, block) \ --+ ext3_free_blocks(handle, inode, block, 1) --+#endif --+ --+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) --+ --+static inline struct buffer_head * --+sb_bread(struct super_block *sb, int block) --+{ --+ return bread(sb->s_dev, block, sb->s_blocksize); --+} --+ --+static inline struct buffer_head * --+sb_getblk(struct super_block *sb, int block) --+{ --+ return getblk(sb->s_dev, block, sb->s_blocksize); --+} --+ --+#endif --+ --+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; --+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; --+ --+int --+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) --+{ --+ int error = -EINVAL; --+ --+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { --+ write_lock(&ext3_handler_lock); --+ if (!ext3_xattr_handlers[name_index-1]) { --+ ext3_xattr_handlers[name_index-1] = handler; --+ error = 0; --+ } --+ write_unlock(&ext3_handler_lock); --+ } --+ return error; --+} --+ --+void --+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) --+{ --+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { --+ write_lock(&ext3_handler_lock); --+ ext3_xattr_handlers[name_index-1] = NULL; --+ write_unlock(&ext3_handler_lock); --+ } --+} --+ --+static inline const char * --+strcmp_prefix(const char *a, const char *a_prefix) --+{ --+ while (*a_prefix && *a == *a_prefix) { --+ a++; --+ a_prefix++; --+ } --+ return *a_prefix ? NULL : a; --+} --+ --+/* --+ * Decode the extended attribute name, and translate it into --+ * the name_index and name suffix. --+ */ --+static inline struct ext3_xattr_handler * --+ext3_xattr_resolve_name(const char **name) --+{ --+ struct ext3_xattr_handler *handler = NULL; --+ int i; --+ --+ if (!*name) --+ return NULL; --+ read_lock(&ext3_handler_lock); --+ for (i=0; iprefix); --+ if (n) { --+ handler = ext3_xattr_handlers[i]; --+ *name = n; --+ break; --+ } --+ } --+ } --+ read_unlock(&ext3_handler_lock); --+ return handler; --+} --+ --+static inline struct ext3_xattr_handler * --+ext3_xattr_handler(int name_index) --+{ --+ struct ext3_xattr_handler *handler = NULL; --+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { --+ read_lock(&ext3_handler_lock); --+ handler = ext3_xattr_handlers[name_index-1]; --+ read_unlock(&ext3_handler_lock); --+ } --+ return handler; --+} --+ --+/* --+ * Inode operation getxattr() --+ * --+ * dentry->d_inode->i_sem down --+ * BKL held [before 2.5.x] --+ */ --+ssize_t --+ext3_getxattr(struct dentry *dentry, const char *name, --+ void *buffer, size_t size) --+{ --+ struct ext3_xattr_handler *handler; --+ struct inode *inode = dentry->d_inode; --+ --+ handler = ext3_xattr_resolve_name(&name); --+ if (!handler) --+ return -ENOTSUP; --+ return handler->get(inode, name, buffer, size); --+} --+ --+/* --+ * Inode operation listxattr() --+ * --+ * dentry->d_inode->i_sem down --+ * BKL held [before 2.5.x] --+ */ --+ssize_t --+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) --+{ --+ return ext3_xattr_list(dentry->d_inode, buffer, size); --+} --+ --+/* --+ * Inode operation setxattr() --+ * --+ * dentry->d_inode->i_sem down --+ * BKL held [before 2.5.x] --+ */ --+int --+ext3_setxattr(struct dentry *dentry, const char *name, --+ void *value, size_t size, int flags) --+{ --+ struct ext3_xattr_handler *handler; --+ struct inode *inode = dentry->d_inode; --+ --+ if (size == 0) --+ value = ""; /* empty EA, do not remove */ --+ handler = ext3_xattr_resolve_name(&name); --+ if (!handler) --+ return -ENOTSUP; --+ return handler->set(inode, name, value, size, flags); --+} --+ --+/* --+ * Inode operation removexattr() --+ * --+ * dentry->d_inode->i_sem down --+ * BKL held [before 2.5.x] --+ */ --+int --+ext3_removexattr(struct dentry *dentry, const char *name) --+{ --+ struct ext3_xattr_handler *handler; --+ struct inode *inode = dentry->d_inode; --+ --+ handler = ext3_xattr_resolve_name(&name); --+ if (!handler) --+ return -ENOTSUP; --+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); --+} --+ --+/* --+ * ext3_xattr_get() --+ * --+ * Copy an extended attribute into the buffer --+ * provided, or compute the buffer size required. --+ * Buffer is NULL to compute the size of the buffer required. --+ * --+ * Returns a negative error number on failure, or the number of bytes --+ * used / required on success. --+ */ --+int --+ext3_xattr_get(struct inode *inode, int name_index, const char *name, --+ void *buffer, size_t buffer_size) --+{ --+ struct buffer_head *bh = NULL; --+ struct ext3_xattr_entry *entry; --+ unsigned int block, size; --+ char *end; --+ int name_len, error; --+ --+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", --+ name_index, name, buffer, (long)buffer_size); --+ --+ if (name == NULL) --+ return -EINVAL; --+ if (!EXT3_I(inode)->i_file_acl) --+ return -ENOATTR; --+ block = EXT3_I(inode)->i_file_acl; --+ ea_idebug(inode, "reading block %d", block); --+ bh = sb_bread(inode->i_sb, block); --+ if (!bh) --+ return -EIO; --+ ea_bdebug(bh, "b_count=%d, refcount=%d", --+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); --+ end = bh->b_data + bh->b_size; --+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || --+ HDR(bh)->h_blocks != cpu_to_le32(1)) { --+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", --+ "inode %ld: bad block %d", inode->i_ino, block); --+ error = -EIO; --+ goto cleanup; --+ } --+ /* find named attribute */ --+ name_len = strlen(name); --+ --+ error = -ERANGE; --+ if (name_len > 255) --+ goto cleanup; --+ entry = FIRST_ENTRY(bh); --+ while (!IS_LAST_ENTRY(entry)) { --+ struct ext3_xattr_entry *next = --+ EXT3_XATTR_NEXT(entry); --+ if ((char *)next >= end) --+ goto bad_block; --+ if (name_index == entry->e_name_index && --+ name_len == entry->e_name_len && --+ memcmp(name, entry->e_name, name_len) == 0) --+ goto found; --+ entry = next; --+ } --+ /* Check the remaining name entries */ --+ while (!IS_LAST_ENTRY(entry)) { --+ struct ext3_xattr_entry *next = --+ EXT3_XATTR_NEXT(entry); --+ if ((char *)next >= end) --+ goto bad_block; --+ entry = next; --+ } --+ if (ext3_xattr_cache_insert(bh)) --+ ea_idebug(inode, "cache insert failed"); --+ error = -ENOATTR; --+ goto cleanup; --+found: --+ /* check the buffer size */ --+ if (entry->e_value_block != 0) --+ goto bad_block; --+ size = le32_to_cpu(entry->e_value_size); --+ if (size > inode->i_sb->s_blocksize || --+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) --+ goto bad_block; --+ --+ if (ext3_xattr_cache_insert(bh)) --+ ea_idebug(inode, "cache insert failed"); --+ if (buffer) { --+ error = -ERANGE; --+ if (size > buffer_size) --+ goto cleanup; --+ /* return value of attribute */ --+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), --+ size); --+ } --+ error = size; --+ --+cleanup: --+ brelse(bh); --+ --+ return error; --+} --+ --+/* --+ * ext3_xattr_list() --+ * --+ * Copy a list of attribute names into the buffer --+ * provided, or compute the buffer size required. --+ * Buffer is NULL to compute the size of the buffer required. --+ * --+ * Returns a negative error number on failure, or the number of bytes --+ * used / required on success. --+ */ --+int --+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) --+{ --+ struct buffer_head *bh = NULL; --+ struct ext3_xattr_entry *entry; --+ unsigned int block, size = 0; --+ char *buf, *end; --+ int error; --+ --+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", --+ buffer, (long)buffer_size); --+ --+ if (!EXT3_I(inode)->i_file_acl) --+ return 0; --+ block = EXT3_I(inode)->i_file_acl; --+ ea_idebug(inode, "reading block %d", block); --+ bh = sb_bread(inode->i_sb, block); --+ if (!bh) --+ return -EIO; --+ ea_bdebug(bh, "b_count=%d, refcount=%d", --+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); --+ end = bh->b_data + bh->b_size; --+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || --+ HDR(bh)->h_blocks != cpu_to_le32(1)) { --+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", --+ "inode %ld: bad block %d", inode->i_ino, block); --+ error = -EIO; --+ goto cleanup; --+ } --+ /* compute the size required for the list of attribute names */ --+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); --+ entry = EXT3_XATTR_NEXT(entry)) { --+ struct ext3_xattr_handler *handler; --+ struct ext3_xattr_entry *next = --+ EXT3_XATTR_NEXT(entry); --+ if ((char *)next >= end) --+ goto bad_block; --+ --+ handler = ext3_xattr_handler(entry->e_name_index); --+ if (handler) { --+ size += handler->list(NULL, inode, entry->e_name, --+ entry->e_name_len) + 1; --+ } --+ } --+ --+ if (ext3_xattr_cache_insert(bh)) --+ ea_idebug(inode, "cache insert failed"); --+ if (!buffer) { --+ error = size; --+ goto cleanup; --+ } else { --+ error = -ERANGE; --+ if (size > buffer_size) --+ goto cleanup; --+ } --+ --+ /* list the attribute names */ --+ buf = buffer; --+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); --+ entry = EXT3_XATTR_NEXT(entry)) { --+ struct ext3_xattr_handler *handler; --+ --+ handler = ext3_xattr_handler(entry->e_name_index); --+ if (handler) { --+ buf += handler->list(buf, inode, entry->e_name, --+ entry->e_name_len); --+ *buf++ = '\0'; --+ } --+ } --+ error = size; --+ --+cleanup: --+ brelse(bh); --+ --+ return error; --+} --+ --+/* --+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is --+ * not set, set it. --+ */ --+static void ext3_xattr_update_super_block(handle_t *handle, --+ struct super_block *sb) --+{ --+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) --+ return; --+ --+ lock_super(sb); --+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); --+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) --+ EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR; --+#endif --+ EXT3_SB(sb)->s_es->s_feature_compat |= --+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); --+ sb->s_dirt = 1; --+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); --+ unlock_super(sb); --+} --+ --+/* --+ * ext3_xattr_set() --+ * --+ * Create, replace or remove an extended attribute for this inode. Buffer --+ * is NULL to remove an existing extended attribute, and non-NULL to --+ * either replace an existing extended attribute, or create a new extended --+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE --+ * specify that an extended attribute must exist and must not exist --+ * previous to the call, respectively. --+ * --+ * Returns 0, or a negative error number on failure. --+ */ --+int --+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, --+ const char *name, void *value, size_t value_len, int flags) --+{ --+ struct super_block *sb = inode->i_sb; --+ struct buffer_head *bh = NULL; --+ struct ext3_xattr_header *header = NULL; --+ struct ext3_xattr_entry *here, *last; --+ unsigned int name_len; --+ int min_offs = sb->s_blocksize, not_found = 1, free, error; --+ char *end; --+ --+ /* --+ * header -- Points either into bh, or to a temporarily --+ * allocated buffer. --+ * here -- The named entry found, or the place for inserting, within --+ * the block pointed to by header. --+ * last -- Points right after the last named entry within the block --+ * pointed to by header. --+ * min_offs -- The offset of the first value (values are aligned --+ * towards the end of the block). --+ * end -- Points right after the block pointed to by header. --+ */ --+ --+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", --+ name_index, name, value, (long)value_len); --+ --+ if (IS_RDONLY(inode)) --+ return -EROFS; --+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) --+ return -EPERM; --+ if (value == NULL) --+ value_len = 0; --+ if (name == NULL) --+ return -EINVAL; --+ name_len = strlen(name); --+ if (name_len > 255 || value_len > sb->s_blocksize) --+ return -ERANGE; --+ ext3_xattr_lock(); --+ --+ if (EXT3_I(inode)->i_file_acl) { --+ /* The inode already has an extended attribute block. */ --+ int block = EXT3_I(inode)->i_file_acl; --+ --+ bh = sb_bread(sb, block); --+ error = -EIO; --+ if (!bh) --+ goto cleanup; --+ ea_bdebug(bh, "b_count=%d, refcount=%d", --+ atomic_read(&(bh->b_count)), --+ le32_to_cpu(HDR(bh)->h_refcount)); --+ header = HDR(bh); --+ end = bh->b_data + bh->b_size; --+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || --+ header->h_blocks != cpu_to_le32(1)) { --+bad_block: ext3_error(sb, "ext3_xattr_set", --+ "inode %ld: bad block %d", inode->i_ino, block); --+ error = -EIO; --+ goto cleanup; --+ } --+ /* Find the named attribute. */ --+ here = FIRST_ENTRY(bh); --+ while (!IS_LAST_ENTRY(here)) { --+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); --+ if ((char *)next >= end) --+ goto bad_block; --+ if (!here->e_value_block && here->e_value_size) { --+ int offs = le16_to_cpu(here->e_value_offs); --+ if (offs < min_offs) --+ min_offs = offs; --+ } --+ not_found = name_index - here->e_name_index; --+ if (!not_found) --+ not_found = name_len - here->e_name_len; --+ if (!not_found) --+ not_found = memcmp(name, here->e_name,name_len); --+ if (not_found <= 0) --+ break; --+ here = next; --+ } --+ last = here; --+ /* We still need to compute min_offs and last. */ --+ while (!IS_LAST_ENTRY(last)) { --+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); --+ if ((char *)next >= end) --+ goto bad_block; --+ if (!last->e_value_block && last->e_value_size) { --+ int offs = le16_to_cpu(last->e_value_offs); --+ if (offs < min_offs) --+ min_offs = offs; --+ } --+ last = next; --+ } --+ --+ /* Check whether we have enough space left. */ --+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); --+ } else { --+ /* We will use a new extended attribute block. */ --+ free = sb->s_blocksize - --+ sizeof(struct ext3_xattr_header) - sizeof(__u32); --+ here = last = NULL; /* avoid gcc uninitialized warning. */ --+ } --+ --+ if (not_found) { --+ /* Request to remove a nonexistent attribute? */ --+ error = -ENOATTR; --+ if (flags & XATTR_REPLACE) --+ goto cleanup; --+ error = 0; --+ if (value == NULL) --+ goto cleanup; --+ else --+ free -= EXT3_XATTR_LEN(name_len); --+ } else { --+ /* Request to create an existing attribute? */ --+ error = -EEXIST; --+ if (flags & XATTR_CREATE) --+ goto cleanup; --+ if (!here->e_value_block && here->e_value_size) { --+ unsigned int size = le32_to_cpu(here->e_value_size); --+ --+ if (le16_to_cpu(here->e_value_offs) + size > --+ sb->s_blocksize || size > sb->s_blocksize) --+ goto bad_block; --+ free += EXT3_XATTR_SIZE(size); --+ } --+ } --+ free -= EXT3_XATTR_SIZE(value_len); --+ error = -ENOSPC; --+ if (free < 0) --+ goto cleanup; --+ --+ /* Here we know that we can set the new attribute. */ --+ --+ if (header) { --+ if (header->h_refcount == cpu_to_le32(1)) { --+ ea_bdebug(bh, "modifying in-place"); --+ ext3_xattr_cache_remove(bh); --+ error = ext3_journal_get_write_access(handle, bh); --+ if (error) --+ goto cleanup; --+ } else { --+ int offset; --+ --+ ea_bdebug(bh, "cloning"); --+ header = kmalloc(bh->b_size, GFP_KERNEL); --+ error = -ENOMEM; --+ if (header == NULL) --+ goto cleanup; --+ memcpy(header, HDR(bh), bh->b_size); --+ header->h_refcount = cpu_to_le32(1); --+ offset = (char *)header - bh->b_data; --+ here = ENTRY((char *)here + offset); --+ last = ENTRY((char *)last + offset); --+ } --+ } else { --+ /* Allocate a buffer where we construct the new block. */ --+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); --+ error = -ENOMEM; --+ if (header == NULL) --+ goto cleanup; --+ memset(header, 0, sb->s_blocksize); --+ end = (char *)header + sb->s_blocksize; --+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); --+ header->h_blocks = header->h_refcount = cpu_to_le32(1); --+ last = here = ENTRY(header+1); --+ } --+ --+ if (not_found) { --+ /* Insert the new name. */ --+ int size = EXT3_XATTR_LEN(name_len); --+ int rest = (char *)last - (char *)here; --+ memmove((char *)here + size, here, rest); --+ memset(here, 0, size); --+ here->e_name_index = name_index; --+ here->e_name_len = name_len; --+ memcpy(here->e_name, name, name_len); --+ } else { --+ /* Remove the old value. */ --+ if (!here->e_value_block && here->e_value_size) { --+ char *first_val = (char *)header + min_offs; --+ int offs = le16_to_cpu(here->e_value_offs); --+ char *val = (char *)header + offs; --+ size_t size = EXT3_XATTR_SIZE( --+ le32_to_cpu(here->e_value_size)); --+ memmove(first_val + size, first_val, val - first_val); --+ memset(first_val, 0, size); --+ here->e_value_offs = 0; --+ min_offs += size; --+ --+ /* Adjust all value offsets. */ --+ last = ENTRY(header+1); --+ while (!IS_LAST_ENTRY(last)) { --+ int o = le16_to_cpu(last->e_value_offs); --+ if (!last->e_value_block && o < offs) --+ last->e_value_offs = --+ cpu_to_le16(o + size); --+ last = EXT3_XATTR_NEXT(last); --+ } --+ } --+ if (value == NULL) { --+ /* Remove this attribute. */ --+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { --+ /* This block is now empty. */ --+ error = ext3_xattr_set2(handle, inode, bh,NULL); --+ goto cleanup; --+ } else { --+ /* Remove the old name. */ --+ int size = EXT3_XATTR_LEN(name_len); --+ last = ENTRY((char *)last - size); --+ memmove(here, (char*)here + size, --+ (char*)last - (char*)here); --+ memset(last, 0, size); --+ } --+ } --+ } --+ --+ if (value != NULL) { --+ /* Insert the new value. */ --+ here->e_value_size = cpu_to_le32(value_len); --+ if (value_len) { --+ size_t size = EXT3_XATTR_SIZE(value_len); --+ char *val = (char *)header + min_offs - size; --+ here->e_value_offs = --+ cpu_to_le16((char *)val - (char *)header); --+ memset(val + size - EXT3_XATTR_PAD, 0, --+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ --+ memcpy(val, value, value_len); --+ } --+ } --+ ext3_xattr_rehash(header, here); --+ --+ error = ext3_xattr_set2(handle, inode, bh, header); --+ --+cleanup: --+ brelse(bh); --+ if (!(bh && header == HDR(bh))) --+ kfree(header); --+ ext3_xattr_unlock(); --+ --+ return error; --+} --+ --+/* --+ * Second half of ext3_xattr_set(): Update the file system. --+ */ --+static int --+ext3_xattr_set2(handle_t *handle, struct inode *inode, --+ struct buffer_head *old_bh, struct ext3_xattr_header *header) --+{ --+ struct super_block *sb = inode->i_sb; --+ struct buffer_head *new_bh = NULL; --+ int error; --+ --+ if (header) { --+ new_bh = ext3_xattr_cache_find(inode, header); --+ if (new_bh) { --+ /* --+ * We found an identical block in the cache. --+ * The old block will be released after updating --+ * the inode. --+ */ --+ ea_bdebug(old_bh, "reusing block %ld", --+ new_bh->b_blocknr); --+ --+ error = -EDQUOT; --+ if (ext3_xattr_quota_alloc(inode, 1)) --+ goto cleanup; --+ --+ error = ext3_journal_get_write_access(handle, new_bh); --+ if (error) --+ goto cleanup; --+ HDR(new_bh)->h_refcount = cpu_to_le32( --+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); --+ ea_bdebug(new_bh, "refcount now=%d", --+ le32_to_cpu(HDR(new_bh)->h_refcount)); --+ } else if (old_bh && header == HDR(old_bh)) { --+ /* Keep this block. */ --+ new_bh = old_bh; --+ (void)ext3_xattr_cache_insert(new_bh); --+ } else { --+ /* We need to allocate a new block */ --+ int force = EXT3_I(inode)->i_file_acl != 0; --+ int block = ext3_xattr_new_block(handle, inode, --+ &error, force); --+ if (error) --+ goto cleanup; --+ ea_idebug(inode, "creating block %d", block); --+ --+ new_bh = sb_getblk(sb, block); --+ if (!new_bh) { --+getblk_failed: ext3_xattr_free_block(handle, inode, block); --+ error = -EIO; --+ goto cleanup; --+ } --+ lock_buffer(new_bh); --+ error = ext3_journal_get_create_access(handle, new_bh); --+ if (error) { --+ unlock_buffer(new_bh); --+ goto getblk_failed; --+ } --+ memcpy(new_bh->b_data, header, new_bh->b_size); --+ mark_buffer_uptodate(new_bh, 1); --+ unlock_buffer(new_bh); --+ (void)ext3_xattr_cache_insert(new_bh); --+ ext3_xattr_update_super_block(handle, sb); --+ } --+ error = ext3_journal_dirty_metadata(handle, new_bh); --+ if (error) --+ goto cleanup; --+ } --+ --+ /* Update the inode. */ --+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; --+ inode->i_ctime = CURRENT_TIME; --+ ext3_mark_inode_dirty(handle, inode); --+ if (IS_SYNC(inode)) --+ handle->h_sync = 1; --+ --+ error = 0; --+ if (old_bh && old_bh != new_bh) { --+ /* --+ * If there was an old block, and we are not still using it, --+ * we now release the old block. --+ */ --+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); --+ --+ error = ext3_journal_get_write_access(handle, old_bh); --+ if (error) --+ goto cleanup; --+ if (refcount == 1) { --+ /* Free the old block. */ --+ ea_bdebug(old_bh, "freeing"); --+ ext3_xattr_free_block(handle, inode, old_bh->b_blocknr); --+ --+ /* ext3_forget() calls bforget() for us, but we --+ let our caller release old_bh, so we need to --+ duplicate the handle before. */ --+ get_bh(old_bh); --+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); --+ } else { --+ /* Decrement the refcount only. */ --+ refcount--; --+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); --+ ext3_xattr_quota_free(inode); --+ ext3_journal_dirty_metadata(handle, old_bh); --+ ea_bdebug(old_bh, "refcount now=%d", refcount); --+ } --+ } --+ --+cleanup: --+ if (old_bh != new_bh) --+ brelse(new_bh); --+ --+ return error; --+} --+ --+/* --+ * ext3_xattr_drop_inode() --+ * --+ * Free extended attribute resources associated with this inode. This --+ * is called immediately before an inode is freed. --+ */ --+void --+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode) --+{ --+ struct buffer_head *bh; --+ unsigned int block = EXT3_I(inode)->i_file_acl; --+ --+ if (!block) --+ return; --+ ext3_xattr_lock(); --+ --+ bh = sb_bread(inode->i_sb, block); --+ if (!bh) { --+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", --+ "inode %ld: block %d read error", inode->i_ino, block); --+ goto cleanup; --+ } --+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); --+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || --+ HDR(bh)->h_blocks != cpu_to_le32(1)) { --+ ext3_error(inode->i_sb, "ext3_xattr_drop_inode", --+ "inode %ld: bad block %d", inode->i_ino, block); --+ goto cleanup; --+ } --+ ext3_journal_get_write_access(handle, bh); --+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); --+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { --+ ext3_xattr_cache_remove(bh); --+ ext3_xattr_free_block(handle, inode, block); --+ ext3_forget(handle, 1, inode, bh, block); --+ bh = NULL; --+ } else { --+ HDR(bh)->h_refcount = cpu_to_le32( --+ le32_to_cpu(HDR(bh)->h_refcount) - 1); --+ ext3_journal_dirty_metadata(handle, bh); --+ if (IS_SYNC(inode)) --+ handle->h_sync = 1; --+ ext3_xattr_quota_free(inode); --+ } --+ EXT3_I(inode)->i_file_acl = 0; --+ --+cleanup: --+ brelse(bh); --+ ext3_xattr_unlock(); --+} --+ --+/* --+ * ext3_xattr_put_super() --+ * --+ * This is called when a file system is unmounted. --+ */ --+void --+ext3_xattr_put_super(struct super_block *sb) --+{ --+#ifdef CONFIG_EXT3_FS_XATTR_SHARING --+ mb_cache_shrink(ext3_xattr_cache, sb->s_dev); --+#endif --+} --+ --+#ifdef CONFIG_EXT3_FS_XATTR_SHARING --+ --+/* --+ * ext3_xattr_cache_insert() --+ * --+ * Create a new entry in the extended attribute cache, and insert --+ * it unless such an entry is already in the cache. --+ * --+ * Returns 0, or a negative error number on failure. --+ */ --+static int --+ext3_xattr_cache_insert(struct buffer_head *bh) --+{ --+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); --+ struct mb_cache_entry *ce; --+ int error; --+ --+ ce = mb_cache_entry_alloc(ext3_xattr_cache); --+ if (!ce) --+ return -ENOMEM; --+ error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash); --+ if (error) { --+ mb_cache_entry_free(ce); --+ if (error == -EBUSY) { --+ ea_bdebug(bh, "already in cache (%d cache entries)", --+ atomic_read(&ext3_xattr_cache->c_entry_count)); --+ error = 0; --+ } --+ } else { --+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, --+ atomic_read(&ext3_xattr_cache->c_entry_count)); --+ mb_cache_entry_release(ce); --+ } --+ return error; --+} --+ --+/* --+ * ext3_xattr_cmp() --+ * --+ * Compare two extended attribute blocks for equality. --+ * --+ * Returns 0 if the blocks are equal, 1 if they differ, and --+ * a negative error number on errors. --+ */ --+static int --+ext3_xattr_cmp(struct ext3_xattr_header *header1, --+ struct ext3_xattr_header *header2) --+{ --+ struct ext3_xattr_entry *entry1, *entry2; --+ --+ entry1 = ENTRY(header1+1); --+ entry2 = ENTRY(header2+1); --+ while (!IS_LAST_ENTRY(entry1)) { --+ if (IS_LAST_ENTRY(entry2)) --+ return 1; --+ if (entry1->e_hash != entry2->e_hash || --+ entry1->e_name_len != entry2->e_name_len || --+ entry1->e_value_size != entry2->e_value_size || --+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) --+ return 1; --+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) --+ return -EIO; --+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), --+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), --+ le32_to_cpu(entry1->e_value_size))) --+ return 1; --+ --+ entry1 = EXT3_XATTR_NEXT(entry1); --+ entry2 = EXT3_XATTR_NEXT(entry2); --+ } --+ if (!IS_LAST_ENTRY(entry2)) --+ return 1; --+ return 0; --+} --+ --+/* --+ * ext3_xattr_cache_find() --+ * --+ * Find an identical extended attribute block. --+ * --+ * Returns a pointer to the block found, or NULL if such a block was --+ * not found or an error occurred. --+ */ --+static struct buffer_head * --+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) --+{ --+ __u32 hash = le32_to_cpu(header->h_hash); --+ struct mb_cache_entry *ce; --+ --+ if (!header->h_hash) --+ return NULL; /* never share */ --+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); --+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash); --+ while (ce) { --+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); --+ --+ if (!bh) { --+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", --+ "inode %ld: block %ld read error", --+ inode->i_ino, ce->e_block); --+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > --+ EXT3_XATTR_REFCOUNT_MAX) { --+ ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block, --+ le32_to_cpu(HDR(bh)->h_refcount), --+ EXT3_XATTR_REFCOUNT_MAX); --+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { --+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); --+ mb_cache_entry_release(ce); --+ return bh; --+ } --+ brelse(bh); --+ ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash); --+ } --+ return NULL; --+} --+ --+/* --+ * ext3_xattr_cache_remove() --+ * --+ * Remove the cache entry of a block from the cache. Called when a --+ * block becomes invalid. --+ */ --+static void --+ext3_xattr_cache_remove(struct buffer_head *bh) --+{ --+ struct mb_cache_entry *ce; --+ --+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr); --+ if (ce) { --+ ea_bdebug(bh, "removing (%d cache entries remaining)", --+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); --+ mb_cache_entry_free(ce); --+ } else --+ ea_bdebug(bh, "no cache entry"); --+} --+ --+#define NAME_HASH_SHIFT 5 --+#define VALUE_HASH_SHIFT 16 --+ --+/* --+ * ext3_xattr_hash_entry() --+ * --+ * Compute the hash of an extended attribute. --+ */ --+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, --+ struct ext3_xattr_entry *entry) --+{ --+ __u32 hash = 0; --+ char *name = entry->e_name; --+ int n; --+ --+ for (n=0; n < entry->e_name_len; n++) { --+ hash = (hash << NAME_HASH_SHIFT) ^ --+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ --+ *name++; --+ } --+ --+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { --+ __u32 *value = (__u32 *)((char *)header + --+ le16_to_cpu(entry->e_value_offs)); --+ for (n = (le32_to_cpu(entry->e_value_size) + --+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { --+ hash = (hash << VALUE_HASH_SHIFT) ^ --+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ --+ le32_to_cpu(*value++); --+ } --+ } --+ entry->e_hash = cpu_to_le32(hash); --+} --+ --+#undef NAME_HASH_SHIFT --+#undef VALUE_HASH_SHIFT --+ --+#define BLOCK_HASH_SHIFT 16 --+ --+/* --+ * ext3_xattr_rehash() --+ * --+ * Re-compute the extended attribute hash value after an entry has changed. --+ */ --+static void ext3_xattr_rehash(struct ext3_xattr_header *header, --+ struct ext3_xattr_entry *entry) --+{ --+ struct ext3_xattr_entry *here; --+ __u32 hash = 0; --+ --+ ext3_xattr_hash_entry(header, entry); --+ here = ENTRY(header+1); --+ while (!IS_LAST_ENTRY(here)) { --+ if (!here->e_hash) { --+ /* Block is not shared if an entry's hash value == 0 */ --+ hash = 0; --+ break; --+ } --+ hash = (hash << BLOCK_HASH_SHIFT) ^ --+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ --+ le32_to_cpu(here->e_hash); --+ here = EXT3_XATTR_NEXT(here); --+ } --+ header->h_hash = cpu_to_le32(hash); --+} --+ --+#undef BLOCK_HASH_SHIFT --+ --+int __init --+init_ext3_xattr(void) --+{ --+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, --+ sizeof(struct mb_cache_entry) + --+ sizeof(struct mb_cache_entry_index), 1, 61); --+ if (!ext3_xattr_cache) --+ return -ENOMEM; --+ --+ return 0; --+} --+ --+void --+exit_ext3_xattr(void) --+{ --+ if (ext3_xattr_cache) --+ mb_cache_destroy(ext3_xattr_cache); --+ ext3_xattr_cache = NULL; --+} --+ --+#else /* CONFIG_EXT3_FS_XATTR_SHARING */ --+ --+int __init --+init_ext3_xattr(void) --+{ --+ return 0; --+} --+ --+void --+exit_ext3_xattr(void) --+{ --+} --+ --+#endif /* CONFIG_EXT3_FS_XATTR_SHARING */ --diff -Nur linux-2.4.18/include/linux/ext3_fs.h linux-2.4.18ea/include/linux/ext3_fs.h ----- linux-2.4.18/include/linux/ext3_fs.h Sun Feb 24 04:42:59 2002 --+++ linux-2.4.18ea/include/linux/ext3_fs.h Mon Mar 11 03:27:00 2002 --@@ -58,8 +58,6 @@ -- */ -- #define EXT3_BAD_INO 1 /* Bad blocks inode */ -- #define EXT3_ROOT_INO 2 /* Root inode */ ---#define EXT3_ACL_IDX_INO 3 /* ACL inode */ ---#define EXT3_ACL_DATA_INO 4 /* ACL inode */ -- #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ -- #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ -- #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ --@@ -89,7 +87,6 @@ -- #else -- # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) -- #endif ---#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) -- #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) -- #ifdef __KERNEL__ -- # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) --@@ -124,28 +121,6 @@ -- #endif -- -- /* --- * ACL structures --- */ ---struct ext3_acl_header /* Header of Access Control Lists */ ---{ --- __u32 aclh_size; --- __u32 aclh_file_count; --- __u32 aclh_acle_count; --- __u32 aclh_first_acle; ---}; --- ---struct ext3_acl_entry /* Access Control List Entry */ ---{ --- __u32 acle_size; --- __u16 acle_perms; /* Access permissions */ --- __u16 acle_type; /* Type of entry */ --- __u16 acle_tag; /* User or group identity */ --- __u16 acle_pad1; --- __u32 acle_next; /* Pointer on next entry for the */ --- /* same inode or on next free entry */ ---}; --- ---/* -- * Structure of a blocks group descriptor -- */ -- struct ext3_group_desc --@@ -512,7 +487,7 @@ -- #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ -- #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -- ---#define EXT3_FEATURE_COMPAT_SUPP 0 --+#define EXT3_FEATURE_COMPAT_SUPP EXT3_FEATURE_COMPAT_EXT_ATTR -- #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ -- EXT3_FEATURE_INCOMPAT_RECOVER) -- #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ --@@ -603,4 +578,22 @@ -- */ -- --+/* Defined for extended attributes */ --+#define CONFIG_EXT3_FS_XATTR y --+#ifndef ENOATTR --+#define ENOATTR ENODATA /* No such attribute */ --+#endif --+#ifndef ENOTSUP --+#define ENOTSUP EOPNOTSUPP /* Operation not supported */ --+#endif --+#ifndef XATTR_NAME_MAX --+#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */ --+#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */ --+#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */ --+#endif --+#ifndef XATTR_CREATE --+#define XATTR_CREATE 1 /* set value, fail if attr already exists */ --+#define XATTR_REPLACE 2 /* set value, fail if attr does not exist */ --+#endif --+ -- /* -- * Ok, these declarations are also in but none of the --@@ -628,6 +603,7 @@ -- extern unsigned long ext3_count_free (struct buffer_head *, unsigned); -- -- /* inode.c */ --+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); -- extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); -- extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); -- --diff -Nur linux-2.4.18/include/linux/ext3_jbd.h linux-2.4.18ea/include/linux/ext3_jbd.h ----- linux-2.4.18/include/linux/ext3_jbd.h Fri Dec 21 18:42:03 2001 --+++ linux-2.4.18ea/include/linux/ext3_jbd.h Mon Mar 25 00:11:36 2002 --@@ -30,13 +30,19 @@ -- -- #define EXT3_SINGLEDATA_TRANS_BLOCKS 8 -- --+/* Extended attributes may touch two data buffers, two bitmap buffers, --+ * and two group and summaries. */ --+ --+#define EXT3_XATTR_TRANS_BLOCKS 8 --+ -- /* Define the minimum size for a transaction which modifies data. This -- * needs to take into account the fact that we may end up modifying two -- * quota files too (one for the group, one for the user quota). The -- * superblock only gets updated once, of course, so don't bother -- * counting that again for the quota updates. */ -- ---#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) --+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ --+ EXT3_XATTR_TRANS_BLOCKS - 2) -- -- extern int ext3_writepage_trans_blocks(struct inode *inode); -- --diff -Nur linux-2.4.18/include/linux/ext3_xattr.h linux-2.4.18ea/include/linux/ext3_xattr.h ----- linux-2.4.18/include/linux/ext3_xattr.h Thu Jan 1 01:00:00 1970 --+++ linux-2.4.18ea/include/linux/ext3_xattr.h Fri Apr 5 10:08:01 2002 --@@ -0,0 +1,155 @@ --+/* --+ File: linux/ext3_xattr.h --+ --+ On-disk format of extended attributes for the ext3 filesystem. --+ --+ (C) 2001 Andreas Gruenbacher, --+*/ --+ --+#include --+#include --+#include --+ --+/* Magic value in attribute blocks */ --+#define EXT3_XATTR_MAGIC 0xEA020000 --+ --+/* Maximum number of references to one attribute block */ --+#define EXT3_XATTR_REFCOUNT_MAX 1024 --+ --+/* Name indexes */ --+#define EXT3_XATTR_INDEX_MAX 10 --+#define EXT3_XATTR_INDEX_USER 1 --+ --+struct ext3_xattr_header { --+ __u32 h_magic; /* magic number for identification */ --+ __u32 h_refcount; /* reference count */ --+ __u32 h_blocks; /* number of disk blocks used */ --+ __u32 h_hash; /* hash value of all attributes */ --+ __u32 h_reserved[4]; /* zero right now */ --+}; --+ --+struct ext3_xattr_entry { --+ __u8 e_name_len; /* length of name */ --+ __u8 e_name_index; /* attribute name index */ --+ __u16 e_value_offs; /* offset in disk block of value */ --+ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ --+ __u32 e_value_size; /* size of attribute value */ --+ __u32 e_hash; /* hash value of name and value */ --+ char e_name[0]; /* attribute name */ --+}; --+ --+#define EXT3_XATTR_PAD_BITS 2 --+#define EXT3_XATTR_PAD (1<e_name_len)) ) --+#define EXT3_XATTR_SIZE(size) \ --+ (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND) --+ --+#ifdef __KERNEL__ --+ --+# ifdef CONFIG_EXT3_FS_XATTR --+ --+struct ext3_xattr_handler { --+ char *prefix; --+ size_t (*list)(char *list, struct inode *inode, const char *name, --+ int name_len); --+ int (*get)(struct inode *inode, const char *name, void *buffer, --+ size_t size); --+ int (*set)(struct inode *inode, const char *name, void *buffer, --+ size_t size, int flags); --+}; --+ --+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); --+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); --+ --+extern int ext3_setxattr(struct dentry *, const char *, void *, size_t, int); --+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); --+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); --+extern int ext3_removexattr(struct dentry *, const char *); --+ --+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); --+extern int ext3_xattr_list(struct inode *, char *, size_t); --+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, void *, size_t, int); --+ --+extern void ext3_xattr_drop_inode(handle_t *, struct inode *); --+extern void ext3_xattr_put_super(struct super_block *); --+ --+extern int init_ext3_xattr(void) __init; --+extern void exit_ext3_xattr(void); --+ --+# else /* CONFIG_EXT3_FS_XATTR */ --+# define ext3_setxattr NULL --+# define ext3_getxattr NULL --+# define ext3_listxattr NULL --+# define ext3_removexattr NULL --+ --+static inline int --+ext3_xattr_get(struct inode *inode, int name_index, const char *name, --+ void *buffer, size_t size, int flags) --+{ --+ return -ENOTSUP; --+} --+ --+static inline int --+ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags) --+{ --+ return -ENOTSUP; --+} --+ --+static inline int --+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, --+ const char *name, void *value, size_t size, int flags) --+{ --+ return -ENOTSUP; --+} --+ --+static inline void --+ext3_xattr_drop_inode(handle_t *handle, struct inode *inode) --+{ --+} --+ --+static inline void --+ext3_xattr_put_super(struct super_block *sb) --+{ --+} --+ --+static inline int --+init_ext3_xattr(void) --+{ --+ return 0; --+} --+ --+static inline void --+exit_ext3_xattr(void) --+{ --+} --+ --+# endif /* CONFIG_EXT3_FS_XATTR */ --+ --+# ifdef CONFIG_EXT3_FS_XATTR_USER --+ --+extern int init_ext3_xattr_user(void) __init; --+extern void exit_ext3_xattr_user(void); --+ --+# else /* CONFIG_EXT3_FS_XATTR_USER */ --+ --+static inline int --+init_ext3_xattr_user(void) --+{ --+ return 0; --+} --+ --+static inline void --+exit_ext3_xattr_user(void) --+{ --+} --+ --+#endif /* CONFIG_EXT3_FS_XATTR_USER */ --+ --+#endif /* __KERNEL__ */ --+ --diff -Nur linux-2.4.18/include/linux/xattr.h linux-2.4.18ea/include/linux/xattr.h ----- linux-2.4.18/include/linux/xattr.h Thu Jan 1 01:00:00 1970 --+++ linux-2.4.18ea/include/linux/xattr.h Sun Mar 24 23:42:21 2002 --@@ -0,0 +1,15 @@ --+/* --+ File: linux/xattr.h --+ --+ Extended attributes handling. --+ --+ Copyright (C) 2001 by Andreas Gruenbacher --+ Copyright (C) 2001 SGI - Silicon Graphics, Inc --+*/ --+#ifndef _LINUX_XATTR_H --+#define _LINUX_XATTR_H --+ --+#define XATTR_CREATE 1 /* set value, fail if attr already exists */ --+#define XATTR_REPLACE 2 /* set value, fail if attr does not exist */ --+ --+#endif /* _LINUX_XATTR_H */ diff --cc lustre/include/.cvsignore index 864df96,864df96..0000000 deleted file mode 100644,100644 --- a/lustre/include/.cvsignore +++ /dev/null @@@ -1,11 -1,11 +1,0 @@@ --.Xrefs --config.log --config.status --configure --config.h --stamp-h --stamp-h.in --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/include/config.h.in index 14f0f3b,14f0f3b..0000000 deleted file mode 100644,100644 --- a/lustre/include/config.h.in +++ /dev/null @@@ -1,10 -1,10 +1,0 @@@ --/* include/config.h.in. Generated automatically from configure.in by autoheader. */ -- --/* Define if you have the `readline' library (-lreadline). */ --#undef HAVE_LIBREADLINE -- --/* Name of package */ --#undef PACKAGE -- --/* Version number of package */ --#undef VERSION diff --cc lustre/include/linux/.cvsignore index ce9b313,b731c89..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/.cvsignore +++ /dev/null @@@ -1,14 -1,15 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS --extN_fs.h --extN_fs_i.h --extN_fs_sb.h --extN_jbd.h --extN_xattr.h --xattr.h -lustre_build_version.h diff --cc lustre/include/linux/Makefile index c263b40,c263b40..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/Makefile +++ /dev/null @@@ -1,7 -1,7 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --all .DEFAULT: -- $(MAKE) -C ../.. $@ diff --cc lustre/include/linux/lprocfs_status.h index e769f43,e769f43..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lprocfs_status.h +++ /dev/null @@@ -1,132 -1,132 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Top level header file for LProc SNMP -- * Author: Hariharan Thantry thantry@users.sourceforge.net -- */ --#ifndef _LPROCFS_SNMP_H --#define _LPROCFS_SNMP_H -- -- --#ifndef LPROC_SNMP --#define LPROC_SNMP --#endif -- --#include -- --typedef enum { -- E_LPROC_OK = 0 --} lproc_error_t; -- --struct lprocfs_vars{ -- -- char* name; -- read_proc_t* read_fptr; -- write_proc_t* write_fptr; -- void* data; --}; -- --#ifdef LPROC_SNMP -- --struct proc_dir_entry* lprocfs_mkdir(const char *dname, -- struct proc_dir_entry *parent); --struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry *head, -- const char *name); --void lprocfs_remove_all(struct proc_dir_entry *root); --struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry *root, -- const char *string, -- const char *tok); --int lprocfs_new_vars(struct proc_dir_entry *root, struct lprocfs_vars *list, -- const char *tok, void *data); -- --int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var, -- void *data); --int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list, -- void *data); --int lprocfs_dereg_obd(struct obd_device *device); --struct proc_dir_entry* lprocfs_reg_mnt(char *mnt_name); --int lprocfs_dereg_mnt(struct proc_dir_entry *root); -- --int lprocfs_reg_class(struct obd_type *type, struct lprocfs_vars *list, -- void *data); --int lprocfs_dereg_class(struct obd_type *class); --int lprocfs_reg_main(void); --int lprocfs_dereg_main(void); --int lprocfs_ll_rd(char *page, char **start, off_t off, int count, int *eof, -- void *data); --#else -- -- --static inline int lprocfs_add_vars(struct proc_dir_entry *root, -- struct lprocfs_vars *var, void *data) --{ -- return 0; --} -- --static inline int lprocfs_reg_obd(struct obd_device* device, -- struct lprocfs_vars* list, void* data) --{ -- return 0; --} -- --static inline int lprocfs_dereg_obd(struct obd_device* device) --{ -- return 0; --} -- --static inline struct proc_dir_entry* lprocfs_reg_mnt(char *name) --{ -- return NULL; --} -- --static inline int lprocfs_dereg_mnt(struct proc_dir_entry* root) --{ -- return 0; --} -- --static inline int lprocfs_reg_class(struct obd_type* type, -- struct lprocfs_vars* list, void* data) --{ -- return 0; --} -- --static inline int lprocfs_dereg_class(struct obd_type* class) --{ -- return 0; --} -- --static inline int lprocfs_reg_main(void) --{ -- return 0; --} -- --static inline int lprocfs_dereg_main(void) --{ -- return 0; --} -- --static inline int lprocfs_ll_rd(char *page, char **start, off_t off, -- int count, int *eof, void *data) --{ -- return 0; --} --#endif /* LPROC_SNMP */ -- --#endif /* LPROCFS_SNMP_H */ diff --cc lustre/include/linux/lustre_debug.h index 756d32e,756d32e..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_debug.h +++ /dev/null @@@ -1,53 -1,53 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#ifndef _LUSTRE_DEBUG_H --#define _LUSTRE_DEBUG_H -- --#include -- --#define ASSERT_MAX_SIZE_MB 60000ULL --#define ASSERT_PAGE_INDEX(index, OP) \ --do { if (index > ASSERT_MAX_SIZE_MB << (20 - PAGE_SHIFT)) { \ -- CERROR("bad page index %lu > %Lu\n", index, \ -- ASSERT_MAX_SIZE_MB << (20 - PAGE_SHIFT)); \ -- portal_debug = ~0UL; \ -- OP; \ --}} while(0) -- --#define ASSERT_FILE_OFFSET(offset, OP) \ --do { if (offset > ASSERT_MAX_SIZE_MB << 20) { \ -- CERROR("bad file offset %Lu > %Lu\n", offset, \ -- ASSERT_MAX_SIZE_MB << 20); \ -- portal_debug = ~0UL; \ -- OP; \ --}} while(0) -- --/* lib/debug.c */ --int dump_lniobuf(struct niobuf_local *lnb); --int dump_rniobuf(struct niobuf_remote *rnb); --int dump_ioo(struct obd_ioobj *nb); --int dump_req(struct ptlrpc_request *req); --int dump_obdo(struct obdo *oa); --int page_debug_setup(void *addr, int len, __u64 off, __u64 id); --int page_debug_check(char *who, void *addr, int len, __u64 off, __u64 id); --#endif diff --cc lustre/include/linux/lustre_dlm.h index f8a6715,916db86..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_dlm.h +++ /dev/null @@@ -1,434 -1,463 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * (visit-tags-table FILE) -- * vim:expandtab:shiftwidth=8:tabstop=8: -- */ -- --#ifndef _LUSTRE_DLM_H__ --#define _LUSTRE_DLM_H__ -- --#ifdef __KERNEL__ -- --#include --#include --#include --#include -- --struct obd_ops; --struct obd_device; -- --#define OBD_LDLM_DEVICENAME "ldlm" -- --typedef enum { -- ELDLM_OK = 0, -- -- ELDLM_LOCK_CHANGED = 300, -- ELDLM_LOCK_ABORTED = 301, -- -- ELDLM_NAMESPACE_EXISTS = 400, -- ELDLM_BAD_NAMESPACE = 401 --} ldlm_error_t; -- --#define LDLM_NAMESPACE_SERVER 0 --#define LDLM_NAMESPACE_CLIENT 1 -- - #define LDLM_FL_LOCK_CHANGED (1 << 0) -#define LDLM_FL_LOCK_CHANGED (1 << 0) /* extent, mode, or resource changed */ - -/* If the server returns one of these flags, then the lock was put on that list. - * If the client sends one of these flags (during recovery ONLY!), it wants the - * lock added to the specified list, no questions asked. -p */ --#define LDLM_FL_BLOCK_GRANTED (1 << 1) --#define LDLM_FL_BLOCK_CONV (1 << 2) --#define LDLM_FL_BLOCK_WAIT (1 << 3) - #define LDLM_FL_CBPENDING (1 << 4) - #define LDLM_FL_AST_SENT (1 << 5) - #define LDLM_FL_DESTROYED (1 << 6) - #define LDLM_FL_WAIT_NOREPROC (1 << 7) - #define LDLM_FL_CANCEL (1 << 8) - #define LDLM_FL_REPLAY (1 << 9) - #define LDLM_FL_INTENT_ONLY (1 << 10) /* don't grant lock, just do intent */ - #define LDLM_FL_LOCAL_ONLY (1 << 11) /* see ldlm_cli_cancel_unused */ - #define LDLM_FL_NO_CALLBACK (1 << 12) /* see ldlm_cli_cancel_unused */ - #define LDLM_FL_HAS_INTENT (1 << 13) /* lock request has intent */ - #define LDLM_FL_REDUCE (1 << 14) /* throw away unused locks */ - -#define LDLM_FL_CBPENDING (1 << 4) // this lock is being destroyed -#define LDLM_FL_AST_SENT (1 << 5) // blocking or cancel packet was sent -#define LDLM_FL_WAIT_NOREPROC (1 << 6)// not a real lock flag,not saved in lock -#define LDLM_FL_CANCEL (1 << 7) // cancellation callback already run - -/* Lock is being replayed. This could probably be implied by the fact that one - * of BLOCK_{GRANTED,CONV,WAIT} is set, but that is pretty dangerous. */ -#define LDLM_FL_REPLAY (1 << 8) - -#define LDLM_FL_INTENT_ONLY (1 << 9) /* don't grant lock, just do intent */ -#define LDLM_FL_LOCAL_ONLY (1 << 10) /* see ldlm_cli_cancel_unused */ -#define LDLM_FL_NO_CALLBACK (1 << 11) /* see ldlm_cli_cancel_unused */ -#define LDLM_FL_HAS_INTENT (1 << 12) /* lock request has intent */ -#define LDLM_FL_CANCELING (1 << 13) /* lock cancel has already been sent */ -- -/* The blocking callback is overloaded to perform two functions. These flags - * indicate which operation should be performed. */ --#define LDLM_CB_BLOCKING 1 --#define LDLM_CB_CANCELING 2 -- --#define L2B(c) (1 << c) -- --/* compatibility matrix */ --#define LCK_COMPAT_EX L2B(LCK_NL) --#define LCK_COMPAT_PW (LCK_COMPAT_EX | L2B(LCK_CR)) --#define LCK_COMPAT_PR (LCK_COMPAT_PW | L2B(LCK_PR)) --#define LCK_COMPAT_CW (LCK_COMPAT_PW | L2B(LCK_CW)) --#define LCK_COMPAT_CR (LCK_COMPAT_CW | L2B(LCK_PR) | L2B(LCK_PW)) --#define LCK_COMPAT_NL (LCK_COMPAT_CR | L2B(LCK_EX)) -- --static ldlm_mode_t lck_compat_array[] = { -- [LCK_EX] LCK_COMPAT_EX, -- [LCK_PW] LCK_COMPAT_PW, -- [LCK_PR] LCK_COMPAT_PR, -- [LCK_CW] LCK_COMPAT_CW, -- [LCK_CR] LCK_COMPAT_CR, -- [LCK_NL] LCK_COMPAT_NL --}; -- --static inline int lockmode_compat(ldlm_mode_t exist, ldlm_mode_t new) --{ -- if (exist < LCK_EX || exist > LCK_NL) -- LBUG(); -- if (new < LCK_EX || new > LCK_NL) -- LBUG(); -- -- return (lck_compat_array[exist] & L2B(new)); --} -- --/* -- * -- * cluster name spaces -- * -- */ -- --#define DLM_OST_NAMESPACE 1 --#define DLM_MDS_NAMESPACE 2 -- --/* XXX -- - do we just separate this by security domains and use a prefix for -- multiple namespaces in the same domain? -- - --*/ -- --struct ldlm_namespace { -- char *ns_name; -- __u32 ns_client; /* is this a client-side lock tree? */ -- struct list_head *ns_hash; /* hash table for ns */ -- __u32 ns_refcount; /* count of resources in the hash */ -- struct list_head ns_root_list; /* all root resources in ns */ -- struct lustre_lock ns_lock; /* protects hash, refcount, list */ -- struct list_head ns_list_chain; /* position in global NS list */ -- /* -- struct proc_dir_entry *ns_proc_dir; -- */ -- -- struct list_head ns_unused_list; /* all root resources in ns */ -- unsigned int ns_nr_unused; -- unsigned int ns_max_unused; -- -- spinlock_t ns_counter_lock; -- __u64 ns_locks; -- __u64 ns_resources; --}; -- --/* -- * -- * Resource hash table -- * -- */ -- --#define RES_HASH_BITS 14 --#define RES_HASH_SIZE (1UL << RES_HASH_BITS) --#define RES_HASH_MASK (RES_HASH_SIZE - 1) -- --struct ldlm_lock; -- --typedef int (*ldlm_blocking_callback)(struct ldlm_lock *lock, -- struct ldlm_lock_desc *new, void *data, -- __u32 data_len, int flag); -- --typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, int flags); -- --struct ldlm_lock { -- __u64 l_random; - int l_refc; - atomic_t l_refc; -- struct ldlm_resource *l_resource; -- struct ldlm_lock *l_parent; -- struct list_head l_children; -- struct list_head l_childof; -- struct list_head l_lru; -- struct list_head l_res_link; /*position in one of three res lists*/ -- struct list_head l_export_chain; /* per-export chain of locks */ -- struct list_head l_pending_chain; /* locks with callbacks pending*/ -- unsigned long l_callback_timeout; -- -- ldlm_mode_t l_req_mode; -- ldlm_mode_t l_granted_mode; -- - ldlm_completion_callback l_completion_ast; - ldlm_blocking_callback l_blocking_ast; - ldlm_completion_callback l_completion_ast; - ldlm_blocking_callback l_blocking_ast; -- -- struct obd_export *l_export; -- struct lustre_handle *l_connh; -- __u32 l_flags; - struct lustre_handle l_remote_handle; - struct lustre_handle l_remote_handle; -- void *l_data; -- __u32 l_data_len; -- struct ldlm_extent l_extent; -- __u32 l_version[RES_VERSION_SIZE]; -- -- __u32 l_readers; -- __u32 l_writers; - __u8 l_destroyed; -- -- /* If the lock is granted, a process sleeps on this waitq to learn when -- * it's no longer in use. If the lock is not granted, a process sleeps -- * on this waitq to learn when it becomes granted. */ -- wait_queue_head_t l_waitq; --}; -- --typedef int (*ldlm_res_compat)(struct ldlm_lock *child, struct ldlm_lock *new); --typedef int (*ldlm_res_policy)(struct ldlm_lock *lock, void *req_cookie, -- ldlm_mode_t mode, int flags, void *data); -- --#define LDLM_PLAIN 10 --#define LDLM_EXTENT 11 -- --#define LDLM_MIN_TYPE 10 --#define LDLM_MAX_TYPE 11 -- --extern ldlm_res_compat ldlm_res_compat_table []; --extern ldlm_res_policy ldlm_res_policy_table []; -- --struct ldlm_resource { -- struct ldlm_namespace *lr_namespace; -- struct list_head lr_hash; -- struct ldlm_resource *lr_parent; /* 0 for a root resource */ -- struct list_head lr_children; /* list head for child resources */ -- struct list_head lr_childof; /* part of ns_root_list if root res, -- * part of lr_children if child */ -- -- struct list_head lr_granted; -- struct list_head lr_converting; -- struct list_head lr_waiting; -- ldlm_mode_t lr_most_restr; -- __u32 lr_type; /* LDLM_PLAIN or LDLM_EXTENT */ -- struct ldlm_resource *lr_root; -- __u64 lr_name[RES_NAME_SIZE]; -- __u32 lr_version[RES_VERSION_SIZE]; -- atomic_t lr_refcount; -- void *lr_tmp; --}; -- --struct ldlm_ast_work { -- struct ldlm_lock *w_lock; -- int w_blocking; -- struct ldlm_lock_desc w_desc; -- struct list_head w_list; -- int w_flags; -- void *w_data; -- int w_datalen; --}; -- --/* Per-export ldlm state. */ --struct ldlm_export_data { -- struct list_head led_held_locks; -- struct obd_import led_import; --}; -- --static inline struct ldlm_extent *ldlm_res2extent(struct ldlm_resource *res) --{ -- return (struct ldlm_extent *)(res->lr_name); --} -- --extern struct obd_ops ldlm_obd_ops; -- --extern char *ldlm_lockname[]; --extern char *ldlm_typename[]; --extern char *ldlm_it2str(int it); -- --#define LDLM_DEBUG(lock, format, a...) \ --do { \ -- if (lock->l_resource == NULL) { \ -- CDEBUG(D_DLMTRACE, "### " format \ - " (UNKNOWN: lock %p(rc=%d/%d,%d) mode %s/%s on " \ - "res \?\? (rc=\?\?) type \?\?\? remote "LPX64")\n" \ - " ns: \?\? lock: %p lrc: %d/%d,%d mode: %s/%s " \ - "res: \?\? rrc=\?\? type: \?\?\? remote: "LPX64")\n" \ -- , ## a, lock, lock->l_refc, lock->l_readers, \ -- lock->l_writers, \ -- ldlm_lockname[lock->l_granted_mode], \ -- ldlm_lockname[lock->l_req_mode], \ -- lock->l_remote_handle.addr); \ -- break; \ -- } \ -- if (lock->l_resource->lr_type == LDLM_EXTENT) { \ -- CDEBUG(D_DLMTRACE, "### " format \ - " (%s: lock %p(rc=%d/%d,%d) mode %s/%s on res "LPU64 \ - "/"LPU64" (rc=%d) type %s ["LPU64"->"LPU64"] remote " \ - LPX64")\n" , ## a, \ - " ns: %s lock: %p lrc: %d/%d,%d mode: %s/%s res: "LPU64 \ - "/"LPU64" rrc: %d type: %s ["LPU64"->"LPU64"] remote: " \ - LPX64"\n" , ## a, \ -- lock->l_resource->lr_namespace->ns_name, lock, \ -- lock->l_refc, lock->l_readers, lock->l_writers, \ -- ldlm_lockname[lock->l_granted_mode], \ -- ldlm_lockname[lock->l_req_mode], \ -- lock->l_resource->lr_name[0], \ -- lock->l_resource->lr_name[1], \ -- atomic_read(&lock->l_resource->lr_refcount), \ -- ldlm_typename[lock->l_resource->lr_type], \ -- lock->l_extent.start, lock->l_extent.end, \ -- lock->l_remote_handle.addr); \ -- break; \ -- } \ -- { \ -- CDEBUG(D_DLMTRACE, "### " format \ - " (%s: lock %p(rc=%d/%d,%d) mode %s/%s on res "LPU64 \ - "/"LPU64" (rc=%d) type %s remote "LPX64")\n" , ## a, \ - " ns: %s lock: %p lrc: %d/%d,%d mode: %s/%s res: "LPU64 \ - "/"LPU64" rrc: %d type: %s remote: "LPX64"\n" , ## a, \ -- lock->l_resource->lr_namespace->ns_name, lock, \ -- lock->l_refc, lock->l_readers, lock->l_writers, \ -- ldlm_lockname[lock->l_granted_mode], \ -- ldlm_lockname[lock->l_req_mode], \ -- lock->l_resource->lr_name[0], \ -- lock->l_resource->lr_name[1], \ -- atomic_read(&lock->l_resource->lr_refcount), \ -- ldlm_typename[lock->l_resource->lr_type], \ -- lock->l_remote_handle.addr); \ -- } \ --} while (0) -- --#define LDLM_DEBUG_NOLOCK(format, a...) \ -- CDEBUG(D_DLMTRACE, "### " format "\n" , ## a) - -/* - * Iterators. - */ - -#define LDLM_ITER_CONTINUE 0 /* keep iterating */ -#define LDLM_ITER_STOP 1 /* stop iterating */ - -typedef int (*ldlm_iterator_t)(struct ldlm_lock *, void *); - -int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter, - void *closure); -int ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter, - void *closure); - -int ldlm_replay_locks(struct obd_import *imp); -- --/* ldlm_extent.c */ --int ldlm_extent_compat(struct ldlm_lock *, struct ldlm_lock *); --int ldlm_extent_policy(struct ldlm_lock *, void *, ldlm_mode_t, int flags, -- void *); -- --/* ldlm_lockd.c */ --int ldlm_handle_enqueue(struct ptlrpc_request *req); --int ldlm_handle_convert(struct ptlrpc_request *req); --int ldlm_handle_cancel(struct ptlrpc_request *req); --int ldlm_del_waiting_lock(struct ldlm_lock *lock); -- --/* ldlm_lock.c */ --void ldlm_register_intent(int (*arg)(struct ldlm_lock *lock, void *req_cookie, -- ldlm_mode_t mode, int flags, void *data)); --void ldlm_unregister_intent(void); - void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh); - struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *, int strict); --void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh); -struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *, int strict, - int flags); --void ldlm_cancel_callback(struct ldlm_lock *); --int ldlm_lock_set_data(struct lustre_handle *, void *data, int datalen); -void ldlm_lock_remove_from_lru(struct ldlm_lock *); -- --static inline struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *h) --{ - return __ldlm_handle2lock(h, 1); - return __ldlm_handle2lock(h, 1, 0); --} -- --#define LDLM_LOCK_PUT(lock) \ --do { \ -- /*LDLM_DEBUG(lock, "put");*/ \ -- ldlm_lock_put(lock); \ --} while (0) -- --#define LDLM_LOCK_GET(lock) \ --({ \ -- ldlm_lock_get(lock); \ -- /*LDLM_DEBUG(lock, "get");*/ \ -- lock; \ --}) -- --struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); --void ldlm_lock_put(struct ldlm_lock *lock); --void ldlm_lock_destroy(struct ldlm_lock *lock); --void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc); --void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode); --void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode); --void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode); --void ldlm_grant_lock(struct ldlm_lock *lock); --int ldlm_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type, -- void *cookie, int cookielen, ldlm_mode_t mode, -- struct lustre_handle *lockh); --struct ldlm_lock * --ldlm_lock_create(struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 *res_id, __u32 type, ldlm_mode_t mode, void *data, -- __u32 data_len); --ldlm_error_t ldlm_lock_enqueue(struct ldlm_lock *lock, void *cookie, -- int cookie_len, int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback blocking); --struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, -- int *flags); --void ldlm_lock_cancel(struct ldlm_lock *lock); --void ldlm_cancel_locks_for_export(struct obd_export *export); --void ldlm_run_ast_work(struct list_head *rpc_list); --void ldlm_reprocess_all(struct ldlm_resource *res); --void ldlm_lock_dump(struct ldlm_lock *lock); -- --/* ldlm_test.c */ --int ldlm_test(struct obd_device *device, struct lustre_handle *connh); --int ldlm_regression_start(struct obd_device *obddev, -- struct lustre_handle *connh, -- unsigned int threads, unsigned int max_locks_in, -- unsigned int num_resources_in, -- unsigned int num_extents_in); --int ldlm_regression_stop(void); -- -- --/* resource.c */ --struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 local); --int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only); --int ldlm_namespace_free(struct ldlm_namespace *ns); --int ldlm_proc_setup(struct obd_device *obd); --void ldlm_proc_cleanup(struct obd_device *obd); -- --/* resource.c - internal */ --struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, -- struct ldlm_resource *parent, -- __u64 *name, __u32 type, int create); --struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res); - int ldlm_resource_put(struct ldlm_resource *res); -int ldlm_resource_putref(struct ldlm_resource *res); --void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head, -- struct ldlm_lock *lock); --void ldlm_resource_unlink_lock(struct ldlm_lock *lock); --void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc); --void ldlm_dump_all_namespaces(void); --void ldlm_namespace_dump(struct ldlm_namespace *); --void ldlm_resource_dump(struct ldlm_resource *); --int ldlm_lock_change_resource(struct ldlm_lock *, __u64 new_resid[3]); -- --/* ldlm_request.c */ --int ldlm_completion_ast(struct ldlm_lock *lock, int flags); --int ldlm_cli_enqueue(struct lustre_handle *conn, -- struct ptlrpc_request *req, -- struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 *res_id, -- __u32 type, -- void *cookie, int cookielen, -- ldlm_mode_t mode, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback callback, -- void *data, -- __u32 data_len, -- struct lustre_handle *lockh); --int ldlm_match_or_enqueue(struct lustre_handle *connh, -- struct ptlrpc_request *req, -- struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 *res_id, -- __u32 type, -- void *cookie, int cookielen, -- ldlm_mode_t mode, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback callback, -- void *data, -- __u32 data_len, -- struct lustre_handle *lockh); --int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new, -- void *data, __u32 data_len); --int ldlm_cli_convert(struct lustre_handle *, int new_mode, int *flags); --int ldlm_cli_cancel(struct lustre_handle *lockh); --int ldlm_cli_cancel_unused(struct ldlm_namespace *, __u64 *, int flags); --int ldlm_cancel_lru(struct ldlm_namespace *ns); -- --/* mds/handler.c */ --/* This has to be here because recurisve inclusion sucks. */ --int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, -- void *data, __u32 data_len, int flag); -- --#endif /* __KERNEL__ */ -- --/* ioctls for trying requests */ --#define IOC_LDLM_TYPE 'f' --#define IOC_LDLM_MIN_NR 40 -- --#define IOC_LDLM_TEST _IOWR('f', 40, long) --#define IOC_LDLM_DUMP _IOWR('f', 41, long) --#define IOC_LDLM_REGRESS_START _IOWR('f', 42, long) --#define IOC_LDLM_REGRESS_STOP _IOWR('f', 43, long) --#define IOC_LDLM_MAX_NR 43 -- --#endif diff --cc lustre/include/linux/lustre_export.h index 38551ac,dc2c0b5..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_export.h +++ /dev/null @@@ -1,50 -1,45 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#ifndef __EXPORT_H --#define __EXPORT_H -- --#ifdef __KERNEL__ -- --#include --#include --#include -- --struct lov_export_data { -- struct list_head led_open_head; --}; -- --struct obd_export { -- __u64 exp_cookie; - struct lustre_handle exp_impconnh; -- struct list_head exp_obd_chain; -- struct list_head exp_conn_chain; -- struct obd_device *exp_obd; -- struct ptlrpc_connection *exp_connection; - struct ldlm_export_data exp_ldlm_data; /* can this go inside u? */ - struct ldlm_export_data exp_ldlm_data; -- union { -- struct mds_export_data eu_mds_data; -- struct filter_export_data eu_filter_data; -- struct lov_export_data eu_lov_data; -- } u; - void *exp_data; /* device specific data */ - int exp_desclen; - char *exp_desc; - obd_uuid_t exp_uuid; --}; -- --#define exp_mds_data u.eu_mds_data --#define exp_lov_data u.eu_lov_data --#define exp_filter_data u.eu_filter_data -- --extern struct obd_export *class_conn2export(struct lustre_handle *conn); --extern struct obd_device *class_conn2obd(struct lustre_handle *conn); --#endif /* __KERNEL__ */ -- --#endif /* __EXPORT_H */ diff --cc lustre/include/linux/lustre_ha.h index f989e6d,1e6596b..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_ha.h +++ /dev/null @@@ -1,59 -1,61 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- */ -- --#ifndef _LUSTRE_HA_H --#define _LUSTRE_HA_H -- --#define LUSTRE_HA_NAME "ptlrpc" -- --struct recovd_data; --struct recovd_obd; --struct obd_import; --struct ptlrpc_connection; -- --/* rd_phase/rd_next_phase values */ --#define RD_IDLE 0 --#define RD_TROUBLED 1 --#define RD_PREPARING 2 --#define RD_PREPARED 3 --#define RD_RECOVERING 4 --#define RD_RECOVERED 5 --#define RD_FAILED 6 -- --/* recovd_state values */ --#define RECOVD_READY 1 --#define RECOVD_STOPPING 2 /* how cleanup tells recovd to quit */ --#define RECOVD_STOPPED 4 /* after recovd has stopped */ -- --#define PTLRPC_RECOVD_PHASE_PREPARE 1 --#define PTLRPC_RECOVD_PHASE_RECOVER 2 --#define PTLRPC_RECOVD_PHASE_FAILURE 3 -- --typedef int (*ptlrpc_recovery_cb_t)(struct recovd_data *, int); -- --struct recovd_data { -- /* you must hold recovd->recovd_lock when touching rd_managed_chain */ -- struct list_head rd_managed_chain; -- ptlrpc_recovery_cb_t rd_recover; -- struct recovd_obd *rd_recovd; -- __u32 rd_phase; -- __u32 rd_next_phase; -- __u32 rd_flags; --}; -- --void recovd_conn_fail(struct ptlrpc_connection *conn); --void recovd_conn_manage(struct ptlrpc_connection *conn, struct recovd_obd *mgr, -- ptlrpc_recovery_cb_t recover); --void recovd_conn_unmanage(struct ptlrpc_connection *conn); --void recovd_conn_fixed(struct ptlrpc_connection *conn); --int recovd_setup(struct recovd_obd *mgr); --int recovd_cleanup(struct recovd_obd *mgr); -- --extern struct recovd_obd *ptlrpc_recovd; -- --int ptlrpc_run_recovery_upcall(struct ptlrpc_connection *conn); --int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc); - int ptlrpc_replay(struct ptlrpc_connection *conn); - -int ptlrpc_replay(struct obd_import *imp, int send_last_flag); -int ptlrpc_resend(struct obd_import *imp); -void ptlrpc_free_committed(struct obd_import *imp); -void ptlrpc_wake_delayed(struct obd_import *imp); --#endif diff --cc lustre/include/linux/lustre_idl.h index 0a412e7f,ea75f08..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_idl.h +++ /dev/null @@@ -1,544 -1,547 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * (Un)packing of OST requests -- */ -- --#ifndef _LUSTRE_IDL_H_ --#define _LUSTRE_IDL_H_ -- --#ifdef __KERNEL__ --# include --# include --# include --# include --#else --# define __KERNEL__ --# include --# include --# undef __KERNEL__ --# include --#endif --/* -- * this file contains all data structures used in Lustre interfaces: -- * - obdo and obd_request records -- * - mds_request records -- * - ldlm data -- * - ioctl's -- */ -- --/* -- * GENERAL STUFF -- */ --typedef __u8 obd_uuid_t[37]; -- --/* FOO_REQUEST_PORTAL is for incoming requests on the FOO -- * FOO_REPLY_PORTAL is for incoming replies on the FOO -- * FOO_BULK_PORTAL is for incoming bulk on the FOO -- */ -- --#define CONNMGR_REQUEST_PORTAL 1 --#define CONNMGR_REPLY_PORTAL 2 --#define OSC_REQUEST_PORTAL 3 --#define OSC_REPLY_PORTAL 4 --#define OSC_BULK_PORTAL 5 --#define OST_REQUEST_PORTAL 6 --#define OST_REPLY_PORTAL 7 --#define OST_BULK_PORTAL 8 --#define MDC_REQUEST_PORTAL 9 --#define MDC_REPLY_PORTAL 10 --#define MDC_BULK_PORTAL 11 --#define MDS_REQUEST_PORTAL 12 --#define MDS_REPLY_PORTAL 13 --#define MDS_BULK_PORTAL 14 --#define LDLM_CB_REQUEST_PORTAL 15 --#define LDLM_CB_REPLY_PORTAL 16 --#define LDLM_CANCEL_REQUEST_PORTAL 17 --#define LDLM_CANCEL_REPLY_PORTAL 18 -- --#define SVC_KILLED 1 --#define SVC_EVENT 2 --#define SVC_SIGNAL 4 --#define SVC_RUNNING 8 --#define SVC_STOPPING 16 --#define SVC_STOPPED 32 -- --#define LUSTRE_CONN_NEW 1 --#define LUSTRE_CONN_CON 2 --#define LUSTRE_CONN_RECOVD 3 --#define LUSTRE_CONN_FULL 4 -- --/* packet types */ --#define PTL_RPC_MSG_REQUEST 4711 --#define PTL_RPC_MSG_ERR 4712 --#define PTL_RPC_MSG_REPLY 4713 -- --#define PTLRPC_MSG_MAGIC (cpu_to_le32(0x0BD00BD0)) --#define PTLRPC_MSG_VERSION (cpu_to_le32(0x00040001)) -- --struct lustre_handle { -- __u64 addr; -- __u64 cookie; --}; --#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabe -- --static inline void ptlrpc_invalidate_handle(struct lustre_handle *hdl) --{ -- hdl->addr = hdl->cookie = 0; /* XXX invalid enough? */ --} -- --/* we depend on this structure to be 8-byte aligned */ --struct lustre_msg { -- __u64 addr; -- __u64 cookie; /* security token */ -- __u32 magic; -- __u32 type; -- __u32 version; -- __u32 opc; -- __u64 last_xid; -- __u64 last_committed; -- __u64 transno; -- __u32 status; -- __u32 bufcount; -- __u32 flags; -- __u32 buflens[0]; --}; -- --/* Flags that are operation-specific go in the top 16 bits. */ --#define MSG_OP_FLAG_MASK 0xffff0000 --#define MSG_OP_FLAG_SHIFT 16 -- --/* Flags that apply to all requests are in the bottom 16 bits */ --#define MSG_GEN_FLAG_MASK 0x0000ffff -#define MSG_LAST_REPLAY 1 -- --static inline int lustre_msg_get_flags(struct lustre_msg *msg) --{ -- return (msg->flags & MSG_GEN_FLAG_MASK); --} -- --static inline void lustre_msg_set_flags(struct lustre_msg *msg, int flags) --{ -- msg->flags &= ~MSG_GEN_FLAG_MASK; -- msg->flags |= MSG_GEN_FLAG_MASK & flags; --} -- --static inline int lustre_msg_get_op_flags(struct lustre_msg *msg) --{ -- return (msg->flags >> MSG_OP_FLAG_SHIFT); --} -- --static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) --{ -- msg->flags &= ~MSG_OP_FLAG_MASK; -- msg->flags |= ((flags & MSG_GEN_FLAG_MASK) << MSG_OP_FLAG_SHIFT); --} -- --#define CONNMGR_REPLY 0 --#define CONNMGR_CONNECT 1 -- --/* -- * OST requests: OBDO & OBD request records -- */ -- --/* opcodes */ --#define OST_REPLY 0 /* reply ? */ --#define OST_GETATTR 1 --#define OST_SETATTR 2 --#define OST_READ 3 --#define OST_WRITE 4 --#define OST_CREATE 5 --#define OST_DESTROY 6 --#define OST_GET_INFO 7 --#define OST_CONNECT 8 --#define OST_DISCONNECT 9 --#define OST_PUNCH 10 --#define OST_OPEN 11 --#define OST_CLOSE 12 --#define OST_STATFS 13 -- -- --typedef uint64_t obd_id; --typedef uint64_t obd_gr; --typedef uint64_t obd_time; --typedef uint64_t obd_size; --typedef uint64_t obd_off; --typedef uint64_t obd_blocks; --typedef uint32_t obd_blksize; --typedef uint32_t obd_mode; --typedef uint32_t obd_uid; --typedef uint32_t obd_gid; --typedef uint64_t obd_rdev; --typedef uint32_t obd_flag; --typedef uint32_t obd_count; -- --#define OBD_FL_INLINEDATA (0x00000001) --#define OBD_FL_OBDMDEXISTS (0x00000002) -- --#define OBD_INLINESZ 60 -- --/* Note: 64-bit types are 64-bit aligned in structure */ --struct obdo { -- obd_id o_id; -- obd_gr o_gr; -- obd_time o_atime; -- obd_time o_mtime; -- obd_time o_ctime; -- obd_size o_size; -- obd_blocks o_blocks; -- obd_rdev o_rdev; -- obd_blksize o_blksize; -- obd_mode o_mode; -- obd_uid o_uid; -- obd_gid o_gid; -- obd_flag o_flags; -- obd_count o_nlink; -- obd_count o_generation; -- obd_flag o_valid; /* hot fields in this obdo */ -- obd_flag o_obdflags; -- __u32 o_easize; -- char o_inline[OBD_INLINESZ]; --}; -- --struct lov_object_id { /* per-child structure */ -- __u64 l_object_id; --}; -- --#define LOV_MAGIC 0x0BD00BD0 -- --struct lov_mds_md { -- __u32 lmm_magic; - __u32 lmm_easize; /* packed size of extended */ - __u32 lmm_unused; /* was packed size of extended attribute */ -- __u64 lmm_object_id; /* lov object id */ -- __u32 lmm_stripe_offset; /* starting stripe offset in lmd_objects */ -- __u32 lmm_stripe_count; /* number of stipes in use for this object */ -- __u64 lmm_stripe_size; /* size of the stripe */ -- __u32 lmm_ost_count; /* how many OST idx are in this LOV md */ -- __u32 lmm_stripe_pattern; /* per-lov object stripe pattern */ -- struct lov_object_id lmm_objects[0]; --}; -- --#define OBD_MD_FLALL (0xffffffff) --#define OBD_MD_FLID (0x00000001) /* object ID */ --#define OBD_MD_FLATIME (0x00000002) /* access time */ --#define OBD_MD_FLMTIME (0x00000004) /* data modification time */ --#define OBD_MD_FLCTIME (0x00000008) /* change time */ --#define OBD_MD_FLSIZE (0x00000010) /* size */ --#define OBD_MD_FLBLOCKS (0x00000020) /* allocated blocks count */ --#define OBD_MD_FLBLKSZ (0x00000040) /* block size */ --#define OBD_MD_FLMODE (0x00000080) /* access bits (mode & ~S_IFMT) */ --#define OBD_MD_FLTYPE (0x00000100) /* object type (mode & S_IFMT) */ --#define OBD_MD_FLUID (0x00000200) /* user ID */ --#define OBD_MD_FLGID (0x00000400) /* group ID */ --#define OBD_MD_FLFLAGS (0x00000800) /* flags word */ --#define OBD_MD_FLOBDFLG (0x00001000) --#define OBD_MD_FLNLINK (0x00002000) /* link count */ --#define OBD_MD_FLGENER (0x00004000) /* generation number */ --#define OBD_MD_FLINLINE (0x00008000) /* inline data */ --#define OBD_MD_FLRDEV (0x00010000) /* device number */ --#define OBD_MD_FLEASIZE (0x00020000) /* extended attribute data */ --#define OBD_MD_LINKNAME (0x00040000) /* symbolic link target */ --#define OBD_MD_FLHANDLE (0x00080000) /* file handle */ - #define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS | OBD_MD_LINKNAME)) -#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS | OBD_MD_LINKNAME|\ - OBD_MD_FLEASIZE | OBD_MD_FLHANDLE)) -- --struct obd_statfs { -- __u64 os_type; -- __u64 os_blocks; -- __u64 os_bfree; -- __u64 os_bavail; -- __u64 os_files; -- __u64 os_ffree; -- __u8 os_fsid[40]; -- __u32 os_bsize; -- __u32 os_namelen; -- __u32 os_spare[12]; --}; -- --/* ost_body.data values for OST_BRW */ -- --#define OBD_BRW_READ 0x1 --#define OBD_BRW_WRITE 0x2 --#define OBD_BRW_RWMASK (OBD_BRW_READ | OBD_BRW_WRITE) --#define OBD_BRW_CREATE 0x4 -- --#define OBD_OBJECT_EOF 0xffffffffffffffffULL -- --struct obd_ioobj { -- obd_id ioo_id; -- obd_gr ioo_gr; -- /* struct lustre_handle ioo_handle; XXX in the future */ -- __u32 ioo_type; -- __u32 ioo_bufcnt; --}; -- --struct niobuf_remote { -- __u64 offset; -- __u32 len; -- __u32 xid; -- __u32 flags; --}; -- --#define CONNMGR_REPLY 0 --#define CONNMGR_CONNECT 1 -- --struct connmgr_body { -- __u64 conn; -- __u64 conn_token; -- __u32 generation; -- obd_uuid_t conn_uuid; --}; -- --/* request structure for OST's */ -- --#define OST_REQ_HAS_OA1 0x1 -- --struct ost_body { -- struct obdo oa; --}; -- --/* -- * MDS REQ RECORDS -- */ -- --/* opcodes */ --#define MDS_GETATTR 1 --#define MDS_OPEN 2 --#define MDS_CLOSE 3 --#define MDS_REINT 4 --#define MDS_READPAGE 6 --#define MDS_CONNECT 7 --#define MDS_DISCONNECT 8 --#define MDS_GETSTATUS 9 --#define MDS_STATFS 10 --#define MDS_GETLOVINFO 11 -- --#define REINT_SETATTR 1 --#define REINT_CREATE 2 --#define REINT_LINK 3 --#define REINT_UNLINK 4 --#define REINT_RENAME 5 --#define REINT_MAX 5 -- --#define REINT_OPCODE_MASK 0xff /* opcodes must fit into this mask */ --#define REINT_REPLAYING 0x1000 /* masked into the opcode to indicate replay */ -- --struct ll_fid { -- __u64 id; -- __u32 generation; -- __u32 f_type; --}; -- -- --#define MDS_STATUS_CONN 1 --#define MDS_STATUS_LOV 2 -- --struct mds_status_req { -- __u32 flags; -- __u32 repbuf; --}; -- --struct mds_fileh_body { -- struct ll_fid f_fid; -- struct lustre_handle f_handle; --}; -- --struct mds_conn_status { -- struct ll_fid rootfid; -- __u64 xid; -- __u64 last_committed; -- __u64 last_rcvd; -- /* XXX preallocated quota & obj fields here */ --}; -- --struct mds_body { -- struct ll_fid fid1; -- struct ll_fid fid2; -- struct lustre_handle handle; -- __u64 size; -- __u32 ino; /* make this a __u64 */ -- __u32 valid; -- __u32 fsuid; -- __u32 fsgid; -- __u32 capability; -- __u32 mode; -- __u32 uid; -- __u32 gid; -- __u32 mtime; -- __u32 ctime; -- __u32 atime; -- __u32 flags; -- __u32 rdev; -- __u32 nlink; -- __u32 generation; --}; -- -/* This is probably redundant with OBD_MD_FLEASIZE, but we need an audit */ --#define MDS_OPEN_HAS_EA 1 /* this open has an EA, for a delayed create*/ -- --/* MDS update records */ -- -- --//struct mds_update_record_hdr { --// __u32 ur_opcode; --//}; -- --struct mds_rec_setattr { -- __u32 sa_opcode; -- __u32 sa_fsuid; -- __u32 sa_fsgid; -- __u32 sa_cap; -- __u32 sa_reserved; -- __u32 sa_valid; -- struct ll_fid sa_fid; -- __u32 sa_mode; -- __u32 sa_uid; -- __u32 sa_gid; -- __u32 sa_attr_flags; -- __u64 sa_size; -- __u64 sa_atime; -- __u64 sa_mtime; -- __u64 sa_ctime; --}; -- --struct mds_rec_create { -- __u32 cr_opcode; -- __u32 cr_fsuid; -- __u32 cr_fsgid; -- __u32 cr_cap; -- __u32 cr_reserved; -- __u32 cr_mode; -- struct ll_fid cr_fid; -- struct ll_fid cr_replayfid; -- __u32 cr_uid; -- __u32 cr_gid; -- __u64 cr_time; -- __u64 cr_rdev; --}; -- --struct mds_rec_link { -- __u32 lk_opcode; -- __u32 lk_fsuid; -- __u32 lk_fsgid; -- __u32 lk_cap; -- struct ll_fid lk_fid1; -- struct ll_fid lk_fid2; --}; -- --struct mds_rec_unlink { -- __u32 ul_opcode; -- __u32 ul_fsuid; -- __u32 ul_fsgid; -- __u32 ul_cap; -- __u32 ul_reserved; -- __u32 ul_mode; -- struct ll_fid ul_fid1; -- struct ll_fid ul_fid2; --}; -- --struct mds_rec_rename { -- __u32 rn_opcode; -- __u32 rn_fsuid; -- __u32 rn_fsgid; -- __u32 rn_cap; -- struct ll_fid rn_fid1; -- struct ll_fid rn_fid2; --}; -- -- --/* -- * LOV data structures -- */ -- --#define LOV_RAID0 0 --#define LOV_RAIDRR 1 -- --struct lov_desc { -- __u32 ld_tgt_count; /* how many OBD's */ -- __u32 ld_active_tgt_count; /* how many active */ -- __u32 ld_default_stripe_count; /* how many objects are used */ -- __u64 ld_default_stripe_size; /* in bytes */ -- __u64 ld_default_stripe_offset; /* in bytes */ -- __u32 ld_pattern; /* RAID 0,1 etc */ -- obd_uuid_t ld_uuid; --}; -- --/* -- * LDLM requests: -- */ --/* opcodes -- MUST be distinct from OST/MDS opcodes */ --#define LDLM_ENQUEUE 101 --#define LDLM_CONVERT 102 --#define LDLM_CANCEL 103 --#define LDLM_BL_CALLBACK 104 --#define LDLM_CP_CALLBACK 105 -- --#define RES_NAME_SIZE 3 --#define RES_VERSION_SIZE 4 -- --/* lock types */ --typedef enum { -- LCK_EX = 1, -- LCK_PW, -- LCK_PR, -- LCK_CW, -- LCK_CR, -- LCK_NL --} ldlm_mode_t; -- --struct ldlm_extent { -- __u64 start; -- __u64 end; --}; -- --struct ldlm_intent { -- __u64 opc; --}; -- --/* Note this unaligned structure; as long as it's only used in ldlm_request -- * below, we're probably fine. */ --struct ldlm_resource_desc { -- __u32 lr_type; -- __u64 lr_name[RES_NAME_SIZE]; -- __u32 lr_version[RES_VERSION_SIZE]; --}; -- --struct ldlm_lock_desc { -- struct ldlm_resource_desc l_resource; -- ldlm_mode_t l_req_mode; -- ldlm_mode_t l_granted_mode; -- struct ldlm_extent l_extent; -- __u32 l_version[RES_VERSION_SIZE]; --}; -- --struct ldlm_request { -- __u32 lock_flags; -- struct ldlm_lock_desc lock_desc; -- struct lustre_handle lock_handle1; -- struct lustre_handle lock_handle2; --}; -- --struct ldlm_reply { -- __u32 lock_flags; -- __u32 lock_mode; -- __u64 lock_resource_name[RES_NAME_SIZE]; -- struct lustre_handle lock_handle; -- struct ldlm_extent lock_extent; /* XXX make this policy 1 &2 */ -- __u64 lock_policy_res1; -- __u64 lock_policy_res2; --}; --#endif diff --cc lustre/include/linux/lustre_import.h index 13b39b7,0f0d67d..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_import.h +++ /dev/null @@@ -1,34 -1,52 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#ifndef __IMPORT_H --#define __IMPORT_H -- --#ifdef __KERNEL__ -- --#define IMP_INVALID 1 --#define IMP_REPLAYABLE 2 - -typedef int (*import_recover_t)(struct obd_import *imp, int phase); -- --#include --struct obd_import { - import_recover_t imp_recover; -- struct ptlrpc_connection *imp_connection; -- struct ptlrpc_client *imp_client; -- struct lustre_handle imp_handle; -- struct list_head imp_chain; - - /* Lists of requests that are retained for replay, waiting for a reply, - * or waiting for recovery to complete, respectively. - */ - struct list_head imp_replay_list; - struct list_head imp_sending_list; - struct list_head imp_delayed_list; - -- struct obd_device *imp_obd; -- int imp_flags; - /* XXX need a UUID here, I think, unless we just use the OBD's UUID */ - int imp_level; - __u64 imp_last_xid; - __u64 imp_max_transno; - __u64 imp_peer_last_xid; - __u64 imp_peer_committed_transno; - - /* Protects flags, level, *_xid, *_list */ - spinlock_t imp_lock; --}; -- --extern struct obd_import *class_conn2cliimp(struct lustre_handle *); --extern struct obd_import *class_conn2ldlmimp(struct lustre_handle *); -- --#endif /* __KERNEL__ */ -- --#endif /* __IMPORT_H */ diff --cc lustre/include/linux/lustre_lib.h index 7cfac66,da5cc81..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_lib.h +++ /dev/null @@@ -1,607 -1,587 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Basic Lustre library routines. -- * -- */ -- --#ifndef _LUSTRE_LIB_H --#define _LUSTRE_LIB_H -- --#ifndef __KERNEL__ --# include --#else --# include - #include /* XXX just for LASSERT! */ --#endif -#include /* XXX just for LASSERT! */ --#include --#include - - #if BITS_PER_LONG > 32 - #define LPU64 "%lu" - #define LPD64 "%ld" - #define LPX64 "%#lx" - #else - #define LPU64 "%Lu" - #define LPD64 "%Ld" - #define LPX64 "%#Lx" - #endif -- --#ifdef __KERNEL__ --/* l_net.c */ --struct ptlrpc_request; --struct obd_device; --struct recovd_data; --struct recovd_obd; --#include -- --int target_handle_connect(struct ptlrpc_request *req); --int target_handle_disconnect(struct ptlrpc_request *req); --int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover); --int client_obd_disconnect(struct lustre_handle *conn); --int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf); --int client_obd_cleanup(struct obd_device * obddev); --struct client_obd *client_conn2cli(struct lustre_handle *conn); -- --int target_revoke_connection(struct recovd_data *rd, int phase); -- --/* l_lock.c */ --struct lustre_lock { -- int l_depth; -- struct task_struct *l_owner; -- struct semaphore l_sem; -- spinlock_t l_spin; --}; -- --void l_lock_init(struct lustre_lock *); --void l_lock(struct lustre_lock *); --void l_unlock(struct lustre_lock *); - -int l_has_lock(struct lustre_lock *); -- - /* page.c */ --#define CB_PHASE_START 12 --#define CB_PHASE_FINISH 13 - - /* - * io_cb_data: io callback data merged into one struct to simplify - * memory managment. This may be turn out to be too simple. - */ - struct brw_cb_data; - typedef int (*brw_cb_t)(struct brw_cb_data *, int err, int phase); -- - struct brw_cb_data { -/* This list head doesn't need to be locked, because it's only manipulated by - * one thread at a time. */ -struct obd_brw_set { - struct list_head brw_desc_head; /* list of ptlrpc_bulk_desc */ -- wait_queue_head_t brw_waitq; -- atomic_t brw_refcount; - int brw_complete; - int brw_err; - struct ptlrpc_bulk_desc *brw_desc; - brw_cb_t brw_cb; - void *brw_data; - }; - int brw_flags; -- - int ll_sync_brw_cb(struct brw_cb_data *brw_cbd, int err, int phase); - struct brw_cb_data *ll_init_brw_cb_data(void); - int (*brw_callback)(struct obd_brw_set *, int phase); -}; -- --/* simple.c */ --struct obd_run_ctxt; --struct obd_ucred; - void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new, -void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, -- struct obd_ucred *cred); - void pop_ctxt(struct obd_run_ctxt *saved); -void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, - struct obd_ucred *cred); --struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode); --struct dentry *simple_mknod(struct dentry *dir, char *name, int mode); --int lustre_fread(struct file *file, char *str, int len, loff_t *off); --int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off); --int lustre_fsync(struct file *file); -- --static inline void l_dput(struct dentry *de) --{ -- if (!de || IS_ERR(de)) -- return; -- shrink_dcache_parent(de); -- LASSERT(atomic_read(&de->d_count) > 0); -- dput(de); --} -- --static inline void ll_sleep(int t) --{ -- set_current_state(TASK_INTERRUPTIBLE); -- schedule_timeout(t * HZ); -- set_current_state(TASK_RUNNING); --} --#endif -- --/* FIXME: This needs to validate pointers and cookies */ --static inline void *lustre_handle2object(struct lustre_handle *handle) --{ -- if (handle) -- return (void *)(unsigned long)(handle->addr); -- return NULL; --} -- --static inline void ldlm_object2handle(void *object, struct lustre_handle *handle) --{ -- handle->addr = (__u64)(unsigned long)object; --} -- --struct obd_statfs; --struct statfs; --void statfs_pack(struct obd_statfs *osfs, struct statfs *sfs); --void statfs_unpack(struct statfs *sfs, struct obd_statfs *osfs); --void obd_statfs_pack(struct obd_statfs *tgt, struct obd_statfs *src); --static inline void --obd_statfs_unpack(struct obd_statfs *tgt, struct obd_statfs *src) --{ -- obd_statfs_pack(tgt, src); --} -- --#include -- --/* -- * OBD IOCTLS -- */ --#define OBD_IOCTL_VERSION 0x00010001 -- --struct obd_ioctl_data { -- uint32_t ioc_len; -- uint32_t ioc_version; -- -- uint64_t ioc_addr; -- uint64_t ioc_cookie; -- uint32_t ioc_conn1; -- uint32_t ioc_conn2; -- -- struct obdo ioc_obdo1; -- struct obdo ioc_obdo2; -- -- obd_size ioc_count; -- obd_off ioc_offset; -- uint32_t ioc_dev; -- uint32_t ____padding; -- -- /* buffers the kernel will treat as user pointers */ -- uint32_t ioc_plen1; -- char *ioc_pbuf1; -- uint32_t ioc_plen2; -- char *ioc_pbuf2; -- -- /* two inline buffers */ -- uint32_t ioc_inllen1; -- char *ioc_inlbuf1; -- uint32_t ioc_inllen2; -- char *ioc_inlbuf2; -- uint32_t ioc_inllen3; -- char *ioc_inlbuf3; -- -- char ioc_bulk[0]; --}; -- --struct obd_ioctl_hdr { -- uint32_t ioc_len; -- uint32_t ioc_version; --}; -- --static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) --{ -- int len = size_round(sizeof(struct obd_ioctl_data)); -- len += size_round(data->ioc_inllen1); -- len += size_round(data->ioc_inllen2); -- len += size_round(data->ioc_inllen3); -- return len; --} -- -- --static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) --{ -- if (data->ioc_len > (1<<30)) { -- printk("OBD ioctl: ioc_len larger than 1<<30\n"); -- return 1; -- } -- if (data->ioc_inllen1 > (1<<30)) { -- printk("OBD ioctl: ioc_inllen1 larger than 1<<30\n"); -- return 1; -- } -- if (data->ioc_inllen2 > (1<<30)) { -- printk("OBD ioctl: ioc_inllen2 larger than 1<<30\n"); -- return 1; -- } -- -- if (data->ioc_inllen3 > (1<<30)) { -- printk("OBD ioctl: ioc_inllen3 larger than 1<<30\n"); -- return 1; -- } -- if (data->ioc_inlbuf1 && !data->ioc_inllen1) { -- printk("OBD ioctl: inlbuf1 pointer but 0 length\n"); -- return 1; -- } -- if (data->ioc_inlbuf2 && !data->ioc_inllen2) { -- printk("OBD ioctl: inlbuf2 pointer but 0 length\n"); -- return 1; -- } -- if (data->ioc_inlbuf3 && !data->ioc_inllen3) { -- printk("OBD ioctl: inlbuf3 pointer but 0 length\n"); -- return 1; -- } -- if (data->ioc_pbuf1 && !data->ioc_plen1) { -- printk("OBD ioctl: pbuf1 pointer but 0 length\n"); -- return 1; -- } -- if (data->ioc_pbuf2 && !data->ioc_plen2) { -- printk("OBD ioctl: pbuf2 pointer but 0 length\n"); -- return 1; -- } -- /* -- if (data->ioc_inllen1 && !data->ioc_inlbuf1) { -- printk("OBD ioctl: inllen1 set but NULL pointer\n"); -- return 1; -- } -- if (data->ioc_inllen2 && !data->ioc_inlbuf2) { -- printk("OBD ioctl: inllen2 set but NULL pointer\n"); -- return 1; -- } -- if (data->ioc_inllen3 && !data->ioc_inlbuf3) { -- printk("OBD ioctl: inllen3 set but NULL pointer\n"); -- return 1; -- } -- */ -- if (data->ioc_plen1 && !data->ioc_pbuf1) { -- printk("OBD ioctl: plen1 set but NULL pointer\n"); -- return 1; -- } -- if (data->ioc_plen2 && !data->ioc_pbuf2) { -- printk("OBD ioctl: plen2 set but NULL pointer\n"); -- return 1; -- } -- if (obd_ioctl_packlen(data) != data->ioc_len ) { -- printk("OBD ioctl: packlen exceeds ioc_len\n"); -- return 1; -- } --#if 0 -- if (data->ioc_inllen1 && -- data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') { -- printk("OBD ioctl: inlbuf1 not 0 terminated\n"); -- return 1; -- } -- if (data->ioc_inllen2 && -- data->ioc_bulk[size_round(data->ioc_inllen1) + data->ioc_inllen2 - 1] != '\0') { -- printk("OBD ioctl: inlbuf2 not 0 terminated\n"); -- return 1; -- } -- if (data->ioc_inllen3 && -- data->ioc_bulk[size_round(data->ioc_inllen1) + size_round(data->ioc_inllen2) -- + data->ioc_inllen3 - 1] != '\0') { -- printk("OBD ioctl: inlbuf3 not 0 terminated\n"); -- return 1; -- } --#endif -- return 0; --} -- --#ifndef __KERNEL__ --static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, -- int max) --{ -- char *ptr; -- struct obd_ioctl_data *overlay; -- data->ioc_len = obd_ioctl_packlen(data); -- data->ioc_version = OBD_IOCTL_VERSION; -- -- if (*pbuf && data->ioc_len > max) -- return 1; -- if (*pbuf == NULL) { -- *pbuf = malloc(data->ioc_len); -- } -- if (!*pbuf) -- return 1; -- overlay = (struct obd_ioctl_data *)*pbuf; -- memcpy(*pbuf, data, sizeof(*data)); -- -- ptr = overlay->ioc_bulk; -- if (data->ioc_inlbuf1) -- LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr); -- if (data->ioc_inlbuf2) -- LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr); -- if (data->ioc_inlbuf3) -- LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr); -- if (obd_ioctl_is_invalid(overlay)) -- return 1; -- -- return 0; --} -- --static inline int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, -- int max) --{ -- char *ptr; -- struct obd_ioctl_data *overlay; -- -- if (!pbuf) -- return 1; -- overlay = (struct obd_ioctl_data *)pbuf; -- -- /* Preserve the caller's buffer pointers */ -- overlay->ioc_inlbuf1 = data->ioc_inlbuf1; -- overlay->ioc_inlbuf2 = data->ioc_inlbuf2; -- overlay->ioc_inlbuf3 = data->ioc_inlbuf3; -- -- memcpy(data, pbuf, sizeof(*data)); -- -- ptr = overlay->ioc_bulk; -- if (data->ioc_inlbuf1) -- LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr); -- if (data->ioc_inlbuf2) -- LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr); -- if (data->ioc_inlbuf3) -- LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr); -- -- return 0; --} --#else -- --#include -- --/* buffer MUST be at least the size of obd_ioctl_hdr */ --static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) --{ -- struct obd_ioctl_hdr hdr; -- struct obd_ioctl_data *data; -- int err; -- ENTRY; -- -- err = copy_from_user(&hdr, (void *)arg, sizeof(hdr)); -- if ( err ) { -- EXIT; -- return err; -- } -- -- if (hdr.ioc_version != OBD_IOCTL_VERSION) { -- printk("OBD: version mismatch kernel vs application\n"); -- return -EINVAL; -- } -- -- if (hdr.ioc_len > 8192) { -- printk("OBD: user buffer exceeds 8192 max buffer\n"); -- return -EINVAL; -- } -- -- if (hdr.ioc_len < sizeof(struct obd_ioctl_data)) { -- printk("OBD: user buffer too small for ioctl\n"); -- return -EINVAL; -- } -- -- OBD_ALLOC(*buf, hdr.ioc_len); -- if (!*buf) { -- CERROR("Cannot allocate control buffer of len %d\n", -- hdr.ioc_len); -- RETURN(-EINVAL); -- } -- *len = hdr.ioc_len; -- data = (struct obd_ioctl_data *)*buf; -- -- err = copy_from_user(*buf, (void *)arg, hdr.ioc_len); -- if ( err ) { -- EXIT; -- return err; -- } -- -- if (obd_ioctl_is_invalid(data)) { -- printk("OBD: ioctl not correctly formatted\n"); -- return -EINVAL; -- } -- -- if (data->ioc_inllen1) { -- data->ioc_inlbuf1 = &data->ioc_bulk[0]; -- } -- -- if (data->ioc_inllen2) { -- data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1); -- } -- -- if (data->ioc_inllen3) { -- data->ioc_inlbuf3 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1) + -- size_round(data->ioc_inllen2); -- } -- -- EXIT; -- return 0; --} --#endif -- --#define OBD_IOC_CREATE _IOR ('f', 101, long) --#define OBD_IOC_SETUP _IOW ('f', 102, long) --#define OBD_IOC_CLEANUP _IO ('f', 103 ) --#define OBD_IOC_DESTROY _IOW ('f', 104, long) --#define OBD_IOC_PREALLOCATE _IOWR('f', 105, long) --#define OBD_IOC_DEC_USE_COUNT _IO ('f', 106 ) --#define OBD_IOC_SETATTR _IOW ('f', 107, long) --#define OBD_IOC_GETATTR _IOR ('f', 108, long) --#define OBD_IOC_READ _IOWR('f', 109, long) --#define OBD_IOC_WRITE _IOWR('f', 110, long) --#define OBD_IOC_CONNECT _IOR ('f', 111, long) --#define OBD_IOC_DISCONNECT _IOW ('f', 112, long) --#define OBD_IOC_STATFS _IOWR('f', 113, long) --#define OBD_IOC_SYNC _IOR ('f', 114, long) --#define OBD_IOC_READ2 _IOWR('f', 115, long) --#define OBD_IOC_FORMAT _IOWR('f', 116, long) --#define OBD_IOC_PARTITION _IOWR('f', 117, long) --#define OBD_IOC_ATTACH _IOWR('f', 118, long) --#define OBD_IOC_DETACH _IOWR('f', 119, long) --#define OBD_IOC_COPY _IOWR('f', 120, long) --#define OBD_IOC_MIGR _IOWR('f', 121, long) --#define OBD_IOC_PUNCH _IOWR('f', 122, long) --#define OBD_IOC_DEVICE _IOWR('f', 123, long) --#define OBD_IOC_MODULE_DEBUG _IOWR('f', 124, long) --#define OBD_IOC_BRW_READ _IOWR('f', 125, long) --#define OBD_IOC_BRW_WRITE _IOWR('f', 126, long) --#define OBD_IOC_NAME2DEV _IOWR('f', 127, long) --#define OBD_IOC_NEWDEV _IOWR('f', 128, long) --#define OBD_IOC_LIST _IOWR('f', 129, long) --#define OBD_IOC_UUID2DEV _IOWR('f', 130, long) -- --#define OBD_IOC_RECOVD_NEWCONN _IOWR('f', 131, long) --#define OBD_IOC_LOV_SET_CONFIG _IOWR('f', 132, long) --#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 133, long) --#define OBD_IOC_LOV_CONFIG OBD_IOC_LOV_SET_CONFIG -- --#define OBD_IOC_OPEN _IOWR('f', 134, long) --#define OBD_IOC_CLOSE _IOWR('f', 135, long) -- --#define OBD_IOC_RECOVD_FAILCONN _IOWR('f', 136, long) -- --#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139 ) - -#define OBD_GET_VERSION _IOWR ('f', 144, long) -- --/* -- * l_wait_event is a flexible sleeping function, permitting simple caller -- * configuration of interrupt and timeout sensitivity along with actions to -- * be performed in the event of either exception. -- * -- * Common usage looks like this: -- * -- * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler, -- * intr_handler, callback_data); -- * rc = l_wait_event(waitq, condition, &lwi); -- * -- * (LWI_TIMEOUT and LWI_INTR macros are available for timeout- and -- * interrupt-only variants, respectively.) -- * -- * If a timeout is specified, the timeout_handler will be invoked in the event -- * that the timeout expires before the process is awakened. (Note that any -- * waking of the process will restart the timeout, even if the condition is -- * not satisfied and the process immediately returns to sleep. This might be -- * considered a bug.) If the timeout_handler returns non-zero, l_wait_event -- * will return -ETIMEDOUT and the caller will continue. If the handler returns -- * zero instead, the process will go back to sleep until it is awakened by the -- * waitq or some similar mechanism, or an interrupt occurs (if the caller has -- * asked for interrupts to be detected). The timeout will only fire once, so -- * callers should take care that a timeout_handler which returns zero will take -- * future steps to awaken the process. N.B. that these steps must include -- * making the provided condition become true. -- * -- * If the interrupt flag (lwi_signals) is non-zero, then the process will be -- * interruptible, and will be awakened by any "killable" signal (SIGTERM, -- * SIGKILL or SIGINT). If a timeout is also specified, then the process will -- * only become interruptible _after_ the timeout has expired, though it can be -- * awakened by a signal that was delivered before the timeout and is still -- * pending when the timeout expires. If a timeout is not specified, the process -- * will be interruptible at all times during l_wait_event. -- */ -- --struct l_wait_info { -- long lwi_timeout; -- int (*lwi_on_timeout)(void *); -- long lwi_signals; -- int (*lwi_on_signal)(void *); /* XXX return is ignored for now */ -- void *lwi_cb_data; --}; -- --#define LWI_TIMEOUT(time, cb, data) \ --((struct l_wait_info) { \ -- lwi_timeout: time, \ -- lwi_on_timeout: cb, \ -- lwi_cb_data: data \ --}) -- --#define LWI_INTR(cb, data) \ --((struct l_wait_info) { \ -- lwi_signals: 1, \ -- lwi_on_signal: cb, \ -- lwi_cb_data: data \ --}) -- --#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data) \ --((struct l_wait_info) { \ -- lwi_timeout: time, \ -- lwi_on_timeout: time_cb, \ -- lwi_signals: 1, \ -- lwi_on_signal: sig_cb, \ -- lwi_cb_data: data \ --}) -- --/* XXX this should be one mask-check */ --#define l_killable_pending(task) \ --(sigismember(&(task->pending.signal), SIGKILL) || \ -- sigismember(&(task->pending.signal), SIGINT) || \ -- sigismember(&(task->pending.signal), SIGTERM)) -- --#define __l_wait_event(wq, condition, info, ret) \ --do { \ -- wait_queue_t __wait; \ -- long __state; \ -- int __timed_out = 0; \ -- init_waitqueue_entry(&__wait, current); \ -- \ -- add_wait_queue(&wq, &__wait); \ -- if (info->lwi_signals && !info->lwi_timeout) \ -- __state = TASK_INTERRUPTIBLE; \ -- else \ -- __state = TASK_UNINTERRUPTIBLE; \ -- for (;;) { \ -- set_current_state(__state); \ -- if (condition) \ -- break; \ -- if (__state == TASK_INTERRUPTIBLE && l_killable_pending(current)) {\ - CERROR("lwe: interrupt\n"); \ -- if (info->lwi_on_signal) \ -- info->lwi_on_signal(info->lwi_cb_data); \ -- ret = -EINTR; \ -- break; \ -- } \ -- if (info->lwi_timeout && !__timed_out) { \ -- if (schedule_timeout(info->lwi_timeout) == 0) { \ - CERROR("lwe: timeout\n"); \ -- __timed_out = 1; \ -- if (!info->lwi_on_timeout || \ -- info->lwi_on_timeout(info->lwi_cb_data)) { \ -- ret = -ETIMEDOUT; \ -- break; \ -- } \ -- /* We'll take signals after a timeout. */ \ -- if (info->lwi_signals) { \ -- __state = TASK_INTERRUPTIBLE; \ -- /* Check for a pending interrupt. */ \ -- if (info->lwi_signals && l_killable_pending(current)) {\ - CERROR("lwe: pending interrupt\n"); \ -- if (info->lwi_on_signal) \ -- info->lwi_on_signal(info->lwi_cb_data); \ -- ret = -EINTR; \ -- break; \ -- } \ -- } \ -- } \ -- } else { \ -- schedule(); \ -- } \ -- } \ -- current->state = TASK_RUNNING; \ -- remove_wait_queue(&wq, &__wait); \ --} while(0) -- --#define l_wait_event(wq, condition, info) \ --({ \ -- int __ret = 0; \ -- struct l_wait_info *__info = (info); \ -- if (!(condition)) \ -- __l_wait_event(wq, condition, __info, __ret); \ -- __ret; \ --}) -- --#endif /* _LUSTRE_LIB_H */ diff --cc lustre/include/linux/lustre_lite.h index 93b92cc,4da319d..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_lite.h +++ /dev/null @@@ -1,281 -1,262 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lustre lite cluster file system -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- */ -- -- -- --#ifndef _LL_H --#define _LL_H -- --#ifdef __KERNEL__ -- --#include --#include --#include -- --#include --#include --#include --#include -- --extern kmem_cache_t *ll_file_data_slab; --struct ll_file_data { -- struct lustre_handle fd_mdshandle; -- struct lustre_handle fd_osthandle; -- struct ptlrpc_request *fd_req; -- __u32 fd_flags; --}; -- - struct lustre_intent_data { - __u64 it_lock_handle[2]; - __u32 it_disposition; - __u32 it_status; - __u32 it_lock_mode; -struct lustre_intent_data { - __u64 it_lock_handle[2]; - __u32 it_disposition; - __u32 it_status; - __u32 it_lock_mode; --}; -- --struct ll_dentry_data { -- struct semaphore lld_it_sem; --}; -- --#define ll_d2d(dentry) ((struct ll_dentry_data*) dentry->d_fsdata) -- --struct ll_read_inode2_cookie { -- struct mds_body *lic_body; -- struct lov_mds_md *lic_lmm; --}; -- --#define LL_INLINESZ 60 --struct ll_inode_info { -- struct lov_stripe_md *lli_smd; -- char *lli_symlink_name; - struct lustre_handle lli_intent_lock_handle; -- struct semaphore lli_open_sem; -- atomic_t lli_open_count; /* see ll_file_release */ --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -- struct inode lli_vfs_inode; --#endif --}; -- -- -- --#define LL_SUPER_MAGIC 0x0BD00BD0 -- --#define LL_COMMITCBD_STOPPING 0x1 --#define LL_COMMITCBD_STOPPED 0x2 --#define LL_COMMITCBD_RUNNING 0x4 -- --#define LL_SBI_NOLCK 0x1 -- --struct ll_sb_info { -- obd_uuid_t ll_sb_uuid; -- struct lustre_handle ll_mdc_conn; -- struct lustre_handle ll_osc_conn; -- struct proc_dir_entry* ll_proc_root; -- obd_id ll_rootino; /* number of root inode */ -- -- int ll_flags; -- wait_queue_head_t ll_commitcbd_waitq; -- wait_queue_head_t ll_commitcbd_ctl_waitq; -- int ll_commitcbd_flags; -- struct task_struct *ll_commitcbd_thread; -- time_t ll_commitcbd_waketime; -- time_t ll_commitcbd_timeout; -- spinlock_t ll_commitcbd_lock; -- struct list_head ll_conn_chain; /* per-conn chain of SBs */ -- -- struct list_head ll_orphan_dentry_list; /*please don't ask -p*/ --}; -- --static inline struct ll_sb_info *ll_s2sbi(struct super_block *sb) --{ --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -- return (struct ll_sb_info *)(sb->s_fs_info); --#else -- return (struct ll_sb_info *)(sb->u.generic_sbp); --#endif --} -- --static inline struct lustre_handle *ll_s2obdconn(struct super_block *sb) --{ -- return &(ll_s2sbi(sb))->ll_osc_conn; --} -- --static inline struct client_obd *sbi2mdc(struct ll_sb_info *sbi) --{ -- struct obd_device *obd = class_conn2obd(&sbi->ll_mdc_conn); -- if (obd == NULL) -- LBUG(); -- return &obd->u.cli; --} -- --// FIXME: replace the name of this with LL_SB to conform to kernel stuff --static inline struct ll_sb_info *ll_i2sbi(struct inode *inode) --{ -- return ll_s2sbi(inode->i_sb); --} -- -- --// FIXME: replace the name of this with LL_I to conform to kernel stuff --// static inline struct ll_inode_info *LL_I(struct inode *inode) --static inline struct ll_inode_info *ll_i2info(struct inode *inode) --{ --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) - return container_of(inode, struct ll_inode_info, lli_vfs_inode); - return container_of(inode, struct ll_inode_info, lli_vfs_inode); --#else -- return (struct ll_inode_info *)&(inode->u.generic_ip); --#endif --} -- --static inline struct lustre_handle *ll_i2obdconn(struct inode *inode) --{ -- return ll_s2obdconn(inode->i_sb); --} -- --static inline void ll_ino2fid(struct ll_fid *fid, obd_id ino, __u32 generation, -- int type) --{ -- fid->id = ino; -- fid->generation = generation; -- fid->f_type = type; --} -- --static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode) --{ -- ll_ino2fid(fid, inode->i_ino, inode->i_generation, -- inode->i_mode & S_IFMT); --} -- - static inline int ll_mds_easize(struct super_block *sb) -static inline int ll_mds_max_easize(struct super_block *sb) --{ -- return sbi2mdc(ll_s2sbi(sb))->cl_max_mds_easize; - } - - static inline int ll_ost_easize(struct super_block *sb) - { - return sbi2mdc(ll_s2sbi(sb))->cl_max_ost_easize; --} -- --/* namei.c */ --int ll_lock(struct inode *dir, struct dentry *dentry, -- struct lookup_intent *it, struct lustre_handle *lockh); --int ll_unlock(__u32 mode, struct lustre_handle *lockh); -- --typedef int (*intent_finish_cb)(int flag, struct ptlrpc_request *, -- struct dentry **, struct lookup_intent *, -- int offset, obd_id ino); --int ll_intent_lock(struct inode *parent, struct dentry **, -- struct lookup_intent *, intent_finish_cb); -- --/* dcache.c */ --void ll_intent_release(struct dentry *, struct lookup_intent *); --int ll_set_dd(struct dentry *de); -- --/**** -- --I originally implmented these as functions, then realized a macro --would be more helpful for debugging, so the CDEBUG messages show --the current calling function. The orignal functions are in llite/dcache.c -- --int ll_save_intent(struct dentry * de, struct lookup_intent * it); --struct lookup_intent * ll_get_intent(struct dentry * de); --****/ -- --#define IT_RELEASED_MAGIC 0xDEADCAFE -- --#define LL_SAVE_INTENT(de, it) \ --do { \ -- LASSERT(ll_d2d(de) != NULL); \ -- \ -- down(&ll_d2d(de)->lld_it_sem); \ - LASSERT(de->d_it == NULL); \ - LASSERT(de->d_it == NULL); \ -- de->d_it = it; \ -- CDEBUG(D_DENTRY, "D_IT DOWN dentry %p fsdata %p intent: %s sem %d\n", \ -- de, ll_d2d(de), ldlm_it2str(de->d_it->it_op), \ -- atomic_read(&(ll_d2d(de)->lld_it_sem.count))); \ --} while(0) -- --#define LL_GET_INTENT(de, it) \ --do { \ -- it = de->d_it; \ -- \ -- LASSERT(ll_d2d(de) != NULL); \ -- LASSERT(it); \ -- LASSERT(it->it_op != IT_RELEASED_MAGIC); \ -- \ -- CDEBUG(D_DENTRY, "D_IT UP dentry %p fsdata %p intent: %s\n", \ -- de, ll_d2d(de), ldlm_it2str(de->d_it->it_op)); \ -- de->d_it = NULL; \ -- it->it_op = IT_RELEASED_MAGIC; \ -- up(&ll_d2d(de)->lld_it_sem); \ --} while(0) - -- --/* dir.c */ --extern struct file_operations ll_dir_operations; --extern struct inode_operations ll_dir_inode_operations; -- --/* file.c */ --extern struct file_operations ll_file_operations; --extern struct inode_operations ll_file_inode_operations; --struct ldlm_lock; --int ll_lock_callback(struct ldlm_lock *, struct ldlm_lock_desc *, void *data, -- __u32 data_len, int flag); --int ll_size_lock(struct inode *, struct lov_stripe_md *, obd_off start, -- int mode, struct lustre_handle **); --int ll_size_unlock(struct inode *, struct lov_stripe_md *, int mode, -- struct lustre_handle *); --int ll_file_size(struct inode *inode, struct lov_stripe_md *md); --int ll_create_objects(struct super_block *sb, obd_id id, uid_t uid, -- gid_t gid, struct lov_stripe_md **lsmp); -- --/* rw.c */ --struct page *ll_getpage(struct inode *inode, unsigned long offset, -- int create, int locked); --void ll_truncate(struct inode *inode); -- --/* super.c */ --void ll_update_inode(struct inode *, struct mds_body *); -- --/* symlink.c */ --extern struct inode_operations ll_fast_symlink_inode_operations; --extern struct inode_operations ll_symlink_inode_operations; -- --/* sysctl.c */ --void ll_sysctl_init(void); --void ll_sysctl_clean(void); -- --#endif /* __KERNEL__ */ -- --#include -- --#define LL_IOC_GETFLAGS _IOR ('f', 151, long) --#define LL_IOC_SETFLAGS _IOW ('f', 152, long) --#define LL_IOC_CLRFLAGS _IOW ('f', 153, long) --#define LL_IOC_LOV_SETSTRIPE _IOW ('f', 154, long) --#define LL_IOC_LOV_GETSTRIPE _IOW ('f', 155, long) - - struct lov_user_oinfo { - __u64 luo_id; /* object ID on the target OBD */ - __u32 luo_idx; /* OBD stripe index in lmd_objects array */ - __u32 luo_pad; - }; - - struct lov_user_md { - __u64 lum_stripe_size; - __u32 lum_stripe_pattern; - __u32 lum_stripe_offset; - __u32 lum_stripe_count; - struct lov_user_oinfo lum_luoinfo[0]; - }; -- --#define O_LOV_DELAY_CREATE 0100000000 /* hopefully this does not conflict */ -- --#define LL_FILE_IGNORE_LOCK 0x00000001 -- --#endif diff --cc lustre/include/linux/lustre_mds.h index 7e0005b,0260ac8..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_mds.h +++ /dev/null @@@ -1,247 -1,250 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * MDS data structures. -- * See also lustre_idl.h for wire formats of requests. -- * -- */ -- --#ifndef _LUSTRE_MDS_H --#define _LUSTRE_MDS_H -- --#ifdef __KERNEL__ -- --#include --#include -- --struct ldlm_lock_desc; - struct lov_stripe_md; --struct mds_obd; --struct ptlrpc_connection; --struct ptlrpc_client; --struct obd_export; --struct ptlrpc_request; --struct obd_device; -- --#define LUSTRE_MDS_NAME "mds" --#define LUSTRE_MDT_NAME "mdt" --#define LUSTRE_MDC_NAME "mdc" -- --struct mds_update_record { -- __u32 ur_fsuid; -- __u32 ur_fsgid; -- __u32 ur_cap; -- __u32 ur_opcode; -- struct ll_fid *ur_fid1; -- struct ll_fid *ur_fid2; -- int ur_namelen; -- char *ur_name; -- int ur_tgtlen; -- char *ur_tgt; -- struct iattr ur_iattr; -- __u64 ur_rdev; -- __u32 ur_mode; -- __u32 ur_uid; -- __u32 ur_gid; -- __u64 ur_time; --}; -- --#define MDS_LR_CLIENT 8192 --#define MDS_LR_SIZE 128 -- --#define MDS_CLIENT_SLOTS 17 -- --#define MDS_MOUNT_RECOV 2 -- --/* Data stored per server at the head of the last_rcvd file. In le32 order. */ --struct mds_server_data { -- __u8 msd_uuid[37]; /* server UUID */ -- __u8 uuid_padding[3]; /* unused */ -- __u64 msd_last_rcvd; /* last completed transaction ID */ -- __u64 msd_mount_count; /* MDS incarnation number */ -- __u8 padding[512 - 56]; --}; -- --/* Data stored per client in the last_rcvd file. In le32 order. */ --struct mds_client_data { -- __u8 mcd_uuid[37]; /* client UUID */ -- __u8 uuid_padding[3]; /* unused */ -- __u64 mcd_last_rcvd; /* last completed transaction ID */ -- __u64 mcd_mount_count; /* MDS incarnation number */ -- __u64 mcd_last_xid; /* client RPC xid for the last transaction */ -- __u8 padding[MDS_LR_SIZE - 64]; --}; -- --/* In-memory access to client data from MDS struct */ --struct mds_export_data { -- struct list_head med_open_head; -- spinlock_t med_open_lock; -- struct mds_client_data *med_mcd; -- int med_off; --}; -- --/* file data for open files on MDS */ --struct mds_file_data { -- struct list_head mfd_list; -- struct lustre_handle mfd_clienthandle; -- __u64 mfd_servercookie; -- struct file *mfd_file; --}; -- --/* mds/mds_reint.c */ --int mds_reint_rec(struct mds_update_record *r, int offset, -- struct ptlrpc_request *req); -- --/* lib/mds_updates.c */ --void mds_unpack_body(struct mds_body *b); --void mds_unpack_fid(struct ll_fid *fid); --void mds_pack_fid(struct ll_fid *fid); --void mds_pack_req_body(struct ptlrpc_request *); --void mds_pack_rep_body(struct ptlrpc_request *); --int mds_update_unpack(struct ptlrpc_request *, int offset, -- struct mds_update_record *); -- -void mds_readdir_pack(struct ptlrpc_request *req, __u64 offset, - obd_id ino, int type); --void mds_getattr_pack(struct ptlrpc_request *req, int offset, -- struct inode *inode, const char *name, int namelen); --void mds_setattr_pack(struct ptlrpc_request *, int offset, struct inode *, -- struct iattr *, const char *name, int namelen); - void mds_create_pack(struct ptlrpc_request *, int offset, struct inode *, - __u32 mode, __u64 id, __u32 uid, __u32 gid, __u64 time, - const char *name, int namelen, const char *tgt, - int tgtlen); -void mds_create_pack(struct ptlrpc_request *, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - const char *name, int namelen, const void *data, - int datalen); --void mds_unlink_pack(struct ptlrpc_request *, int offset, struct inode *inode, -- struct inode *child, __u32 mode, const char *name, -- int namelen); --void mds_link_pack(struct ptlrpc_request *, int offset, struct inode *ino, -- struct inode *dir, const char *name, int namelen); --void mds_rename_pack(struct ptlrpc_request *, int offset, struct inode *srcdir, -- struct inode *tgtdir, const char *name, int namelen, -- const char *tgt, int tgtlen); --void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode); --void mds_pack_inode2body(struct mds_body *body, struct inode *inode); -- --/* mds/handler.c */ --struct dentry *mds_name2locked_dentry(struct obd_device *, struct dentry *dir, -- struct vfsmount **mnt, char *name, -- int namelen, int lock_mode, -- struct lustre_handle *lockh, -- int dir_lock_mode); --struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid, -- struct vfsmount **mnt, int lock_mode, -- struct lustre_handle *lockh); --struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, -- struct vfsmount **mnt); - int mds_reint(int offset, struct ptlrpc_request *req); -int mds_reint(struct ptlrpc_request *req, int offset); -int mds_pack_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode); -- --/* mdc/mdc_request.c */ --int mdc_enqueue(struct lustre_handle *conn, int lock_type, -- struct lookup_intent *it, int lock_mode, struct inode *dir, -- struct dentry *de, struct lustre_handle *lockh, char *tgt, -- int tgtlen, void *data, int datalen); --int mdc_cancel_unused(struct lustre_handle *conn, struct inode *, int flags); --int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh, -- struct ptlrpc_request **request); --int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid); --int mdc_getattr(struct lustre_handle *conn, -- obd_id ino, int type, unsigned long valid, size_t ea_size, -- struct ptlrpc_request **request); --int mdc_setattr(struct lustre_handle *conn, -- struct inode *, struct iattr *iattr, struct ptlrpc_request **); --int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags, - struct lov_stripe_md *, struct lustre_handle *fh, - struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, -- struct ptlrpc_request **); --int mdc_close(struct lustre_handle *conn, obd_id ino, int type, -- struct lustre_handle *fh, struct ptlrpc_request **req); --int mdc_readpage(struct lustre_handle *conn, obd_id ino, -- int type, __u64 offset, char *addr, struct ptlrpc_request **); --int mdc_create(struct lustre_handle *conn, -- struct inode *dir, const char *name, int namelen, - const char *tgt, int tgtlen, int mode, __u32 uid, __u32 gid, - __u64 time, __u64 rdev, struct lov_stripe_md *md, - struct ptlrpc_request **); - const void *data, int datalen, int mode, __u32 uid, __u32 gid, - __u64 time, __u64 rdev, struct ptlrpc_request **); --int mdc_unlink(struct lustre_handle *, struct inode *dir, struct inode *child, -- __u32 mode, const char *name, int namelen, -- struct ptlrpc_request **); --int mdc_link(struct lustre_handle *conn, -- struct dentry *src, struct inode *dir, const char *name, -- int namelen, struct ptlrpc_request **); --int mdc_rename(struct lustre_handle *conn, -- struct inode *src, struct inode *tgt, const char *old, -- int oldlen, const char *new, int newlen, -- struct ptlrpc_request **); --int mdc_create_client(obd_uuid_t uuid, struct ptlrpc_client *cl); -- --/* Store the generation of a newly-created inode in |req| for replay. */ --void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff, -- int repoff); -- - extern int mds_client_add(struct mds_export_data *med, int cl_off); - extern int mds_client_free(struct obd_export *exp); -int mds_client_add(struct mds_obd *mds, struct mds_export_data *med, - int cl_off); -int mds_client_free(struct obd_export *exp); -- --/* mds/mds_fs.c */ --struct mds_fs_operations { -- struct module *fs_owner; -- void *(* fs_start)(struct inode *inode, int op); -- int (* fs_commit)(struct inode *inode, void *handle); -- int (* fs_setattr)(struct dentry *dentry, void *handle, -- struct iattr *iattr); -- int (* fs_set_md)(struct inode *inode, void *handle, - struct lov_mds_md *md); - int (* fs_get_md)(struct inode *inode, - struct lov_mds_md *md); - struct lov_mds_md *md, int size); - int (* fs_get_md)(struct inode *inode, struct lov_mds_md *md, - int size); -- ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count, -- loff_t *offset); -- void (* fs_delete_inode)(struct inode *inode); -- void (* cl_delete_inode)(struct inode *inode); -- int (* fs_journal_data)(struct file *file); -- int (* fs_set_last_rcvd)(struct mds_obd *mds, void *handle); -- int (* fs_statfs)(struct super_block *sb, struct statfs *sfs); --}; -- --extern int mds_register_fs_type(struct mds_fs_operations *op, const char *name); --extern void mds_unregister_fs_type(const char *name); --extern int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt); --extern void mds_fs_cleanup(struct obd_device *obddev); -- --#define MDS_FSOP_UNLINK 1 --#define MDS_FSOP_RMDIR 2 --#define MDS_FSOP_RENAME 3 --#define MDS_FSOP_CREATE 4 --#define MDS_FSOP_MKDIR 5 --#define MDS_FSOP_SYMLINK 6 --#define MDS_FSOP_MKNOD 7 --#define MDS_FSOP_SETATTR 8 --#define MDS_FSOP_LINK 9 -- --#endif /* __KERNEL__ */ -- --/* ioctls for trying requests */ --#define IOC_REQUEST_TYPE 'f' --#define IOC_REQUEST_MIN_NR 30 -- --#define IOC_REQUEST_GETATTR _IOWR('f', 30, long) --#define IOC_REQUEST_READPAGE _IOWR('f', 31, long) --#define IOC_REQUEST_SETATTR _IOWR('f', 32, long) --#define IOC_REQUEST_CREATE _IOWR('f', 33, long) --#define IOC_REQUEST_OPEN _IOWR('f', 34, long) --#define IOC_REQUEST_CLOSE _IOWR('f', 35, long) --#define IOC_REQUEST_MAX_NR 35 -- --#endif diff --cc lustre/include/linux/lustre_net.h index 5e2fc03,5c2ba75..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/lustre_net.h +++ /dev/null @@@ -1,365 -1,363 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#ifndef _LUSTRE_NET_H --#define _LUSTRE_NET_H -- --#include --#include --// #include --#include --#include --#include --#include -- --/* The following constants determine how much memory is devoted to -- * buffering in the lustre services. -- * -- * ?_NEVENTS # event queue entries -- * - * ?_NBUFS # request buffers - * ?_BUFSIZE # bytes in a single request buffer - * ?_NBUFS # request buffers - * ?_BUFSIZE # bytes in a single request buffer -- * total memory = ?_NBUFS * ?_BUFSIZE -- * -- * ?_MAXREQSIZE # maximum request service will receive -- * larger messages will get dropped. -- * request buffers are auto-unlinked when less than ?_MAXREQSIZE -- * is left in them. -- */ -- --#define LDLM_NUM_THREADS 4 - #define LDLM_NEVENTS 1024 - #define LDLM_NBUFS 10 - #define LDLM_BUFSIZE (64 * 1024) - #define LDLM_MAXREQSIZE 1024 -#define LDLM_NEVENTS 1024 -#define LDLM_NBUFS 10 -#define LDLM_BUFSIZE (64 * 1024) -#define LDLM_MAXREQSIZE 1024 -- --#define MDT_NUM_THREADS 8 - #define MDS_NEVENTS 1024 - #define MDS_NBUFS 10 - #define MDS_BUFSIZE (64 * 1024) - #define MDS_MAXREQSIZE 1024 -#define MDS_NEVENTS 1024 -#define MDS_NBUFS 10 -#define MDS_BUFSIZE (64 * 1024) -#define MDS_MAXREQSIZE 1024 -- --#define OST_NUM_THREADS 6 - #define OST_NEVENTS min(num_physpages / 16, 32768UL) - #define OST_NBUFS min(OST_NEVENTS / 128, 256UL) - #define OST_BUFSIZE ((OST_NEVENTS > 4096UL ? 128 : 64) * 1024) - #define OST_MAXREQSIZE (8 * 1024) -#define OST_NEVENTS min(num_physpages / 16, 32768UL) -#define OST_NBUFS min(OST_NEVENTS / 128, 256UL) -#define OST_BUFSIZE ((OST_NEVENTS > 4096UL ? 128 : 64) * 1024) -#define OST_MAXREQSIZE (8 * 1024) -- --#define CONN_INVALID 1 -- --struct ptlrpc_connection { -- struct list_head c_link; -- struct lustre_peer c_peer; -- __u8 c_local_uuid[37]; /* XXX do we need this? */ -- __u8 c_remote_uuid[37]; -- - int c_level; -- __u32 c_generation; /* changes upon new connection */ -- __u32 c_epoch; /* changes when peer changes */ -- __u32 c_bootcount; /* peer's boot count */ -- -- spinlock_t c_lock; /* also protects req->rq_list */ - __u32 c_xid_in; - __u32 c_xid_out; -- -- atomic_t c_refcount; -- __u64 c_token; -- __u64 c_remote_conn; -- __u64 c_remote_token; -- - __u64 c_last_xid; /* protected by c_lock */ - __u64 c_last_committed;/* protected by c_lock */ - struct list_head c_delayed_head;/* delayed until post-recovery */ - struct list_head c_sending_head;/* protected by c_lock */ - struct list_head c_dying_head; /* protected by c_lock */ - struct list_head c_delayed_head;/* delayed until post-recovery XXX imp? */ -- struct recovd_data c_recovd_data; -- -- struct list_head c_imports; -- struct list_head c_exports; -- struct list_head c_sb_chain; - __u32 c_flags; /* can we indicate INVALID elsewhere? */ - __u32 c_flags; // can we indicate INVALID elsewhere? --}; -- --struct ptlrpc_client { -- __u32 cli_request_portal; -- __u32 cli_reply_portal; -- -- __u32 cli_target_devno; -- -- void *cli_data; - // struct semaphore cli_rpc_sem; /* limits outstanding requests */ - -- char *cli_name; --}; -- --/* state flags of requests */ --#define PTL_RPC_FL_INTR (1 << 0) --#define PTL_RPC_FL_REPLIED (1 << 1) /* reply was received */ --#define PTL_RPC_FL_SENT (1 << 2) --#define PTL_BULK_FL_SENT (1 << 3) --#define PTL_BULK_FL_RCVD (1 << 4) --#define PTL_RPC_FL_ERR (1 << 5) --#define PTL_RPC_FL_TIMEOUT (1 << 6) --#define PTL_RPC_FL_RESEND (1 << 7) - #define PTL_RPC_FL_RECOVERY (1 << 8) /* retransmission for recovery */ -#define PTL_RPC_FL_RESTART (1 << 8) /* operation must be restarted */ --#define PTL_RPC_FL_FINISHED (1 << 9) --#define PTL_RPC_FL_RETAIN (1 << 10) /* retain for replay after reply */ --#define PTL_RPC_FL_REPLAY (1 << 11) /* replay upon recovery */ --#define PTL_RPC_FL_ALLOCREP (1 << 12) /* reply buffer allocated */ -- - struct ptlrpc_request { -struct ptlrpc_request { -- int rq_type; /* one of PTL_RPC_MSG_* */ -- struct list_head rq_list; -- struct obd_device *rq_obd; -- int rq_status; - int rq_flags; - int rq_flags; -- atomic_t rq_refcount; -- - int rq_request_portal; /* XXX FIXME bug 625069 */ - int rq_reply_portal; /* XXX FIXME bug 625069 */ - int rq_request_portal; /* XXX FIXME bug 249 */ - int rq_reply_portal; /* XXX FIXME bug 249 */ -- -- int rq_reqlen; -- struct lustre_msg *rq_reqmsg; -- -- int rq_replen; -- struct lustre_msg *rq_repmsg; -- __u64 rq_transno; -- __u64 rq_xid; -- -- int rq_level; -- time_t rq_timeout; -- // void * rq_reply_handle; -- wait_queue_head_t rq_wait_for_rep; -- -- /* incoming reply */ -- ptl_md_t rq_reply_md; -- ptl_handle_me_t rq_reply_me_h; -- -- /* outgoing req/rep */ -- ptl_md_t rq_req_md; -- -- struct lustre_peer rq_peer; /* XXX see service.c can this be factored away? */ -- struct obd_export *rq_export; -- struct ptlrpc_connection *rq_connection; -- struct obd_import *rq_import; -- struct ptlrpc_service *rq_svc; -- -- void (*rq_replay_cb)(struct ptlrpc_request *); --}; -- --#define DEBUG_REQ(level, req, fmt, args...) \ --do { \ --CDEBUG(level, \ - "@@@ " fmt " req x"LPD64"/t"LPD64" o%d->%s:%d lens %d/%d fl %x\n" , ## args, \ - req->rq_xid, req->rq_transno, \ - "@@@ " fmt " req x"LPD64"/t"LPD64" o%d->%s:%d lens %d/%d ref %d fl " \ - "%x\n" , ## args, req->rq_xid, req->rq_transno, \ -- req->rq_reqmsg ? req->rq_reqmsg->opc : -1, \ -- req->rq_connection ? (char *)req->rq_connection->c_remote_uuid : "", \ -- (req->rq_import && req->rq_import->imp_client) ? \ -- req->rq_import->imp_client->cli_request_portal : -1, \ - req->rq_reqlen, req->rq_replen, req->rq_flags); \ - req->rq_reqlen, req->rq_replen, req->rq_refcount, req->rq_flags); \ --} while (0) -- --struct ptlrpc_bulk_page { -- struct ptlrpc_bulk_desc *bp_desc; -- struct list_head bp_link; -- void *bp_buf; -- int bp_buflen; -- struct page *bp_page; -- __u32 bp_xid; -- __u32 bp_flags; -- struct dentry *bp_dentry; -- int (*bp_cb)(struct ptlrpc_bulk_page *); --}; -- -- --struct ptlrpc_bulk_desc { - struct list_head bd_set_chain; /* entry in obd_brw_set */ - struct obd_brw_set *bd_brw_set; -- int bd_flags; -- struct ptlrpc_connection *bd_connection; -- struct ptlrpc_client *bd_client; -- __u32 bd_portal; -- struct lustre_handle bd_conn; - void (*bd_ptl_ev_hdlr)(struct ptlrpc_bulk_desc *, void *); - void *bd_ptl_ev_data; - void (*bd_ptl_ev_hdlr)(struct ptlrpc_bulk_desc *); -- -- wait_queue_head_t bd_waitq; -- struct list_head bd_page_list; -- __u32 bd_page_count; -- atomic_t bd_refcount; -- void *bd_desc_private; -- --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -- struct work_struct bd_queue; --#else -- struct tq_struct bd_queue; --#endif -- -- ptl_md_t bd_md; -- ptl_handle_md_t bd_md_h; -- ptl_handle_me_t bd_me_h; -- - atomic_t bd_source_callback_count; - atomic_t bd_source_callback_count; -- -- struct iovec bd_iov[16]; /* self-sized pre-allocated iov */ --}; -- --struct ptlrpc_thread { -- struct list_head t_link; -- - __u32 t_flags; - __u32 t_flags; -- wait_queue_head_t t_ctl_waitq; --}; -- --struct ptlrpc_request_buffer_desc { -- struct list_head rqbd_list; -- struct ptlrpc_service *rqbd_service; -- ptl_handle_me_t rqbd_me_h; -- atomic_t rqbd_refcount; -- char *rqbd_buffer; --}; -- --struct ptlrpc_service { -- time_t srv_time; -- time_t srv_timeout; -- -- /* incoming request buffers */ -- /* FIXME: perhaps a list of EQs, if multiple NIs are used? */ -- - __u32 srv_max_req_size; /* biggest request to receive */ - __u32 srv_buf_size; /* # bytes in a request buffer */ - struct list_head srv_rqbds; /* all the request buffer descriptors */ - __u32 srv_nrqbds; /* # request buffers */ - atomic_t srv_nrqbds_receiving; /* # request buffers posted for input */ - __u32 srv_max_req_size; /* biggest request to receive */ - __u32 srv_buf_size; /* # bytes in a request buffer */ - struct list_head srv_rqbds; /* all the request buffer descriptors */ - __u32 srv_nrqbds; /* # request buffers */ - atomic_t srv_nrqbds_receiving; /* # request buffers posted for input */ -- -- __u32 srv_req_portal; -- __u32 srv_rep_portal; -- -- __u32 srv_xid; -- -- /* event queue */ -- ptl_handle_eq_t srv_eq_h; -- -- struct lustre_peer srv_self; -- -- wait_queue_head_t srv_waitq; /* all threads sleep on this */ -- -- spinlock_t srv_lock; -- struct list_head srv_threads; -- int (*srv_handler)(struct ptlrpc_request *req); -- char *srv_name; /* only statically allocated strings here; we don't clean them */ --}; -- - static inline void ptlrpc_hdl2req(struct ptlrpc_request *req, struct lustre_handle *h) -static inline void ptlrpc_hdl2req(struct ptlrpc_request *req, - struct lustre_handle *h) --{ -- req->rq_reqmsg->addr = h->addr; -- req->rq_reqmsg->cookie = h->cookie; --} -- --typedef void (*bulk_callback_t)(struct ptlrpc_bulk_desc *, void *); -- --typedef int (*svc_handler_t)(struct ptlrpc_request *req); -- --/* rpc/connection.c */ - void ptlrpc_readdress_connection(struct ptlrpc_connection *conn, obd_uuid_t uuid); -void ptlrpc_readdress_connection(struct ptlrpc_connection *, obd_uuid_t uuid); --struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer, -- obd_uuid_t uuid); --int ptlrpc_put_connection(struct ptlrpc_connection *c); --struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *); --void ptlrpc_init_connection(void); --void ptlrpc_cleanup_connection(void); -- --/* rpc/niobuf.c */ --int ptlrpc_check_bulk_sent(struct ptlrpc_bulk_desc *bulk); --int ptlrpc_check_bulk_received(struct ptlrpc_bulk_desc *bulk); --int ptlrpc_send_bulk(struct ptlrpc_bulk_desc *); --int ptlrpc_register_bulk(struct ptlrpc_bulk_desc *); --int ptlrpc_abort_bulk(struct ptlrpc_bulk_desc *bulk); -struct obd_brw_set *obd_brw_set_new(void); -void obd_brw_set_add(struct obd_brw_set *, struct ptlrpc_bulk_desc *); -void obd_brw_set_free(struct obd_brw_set *); - --int ptlrpc_reply(struct ptlrpc_service *svc, struct ptlrpc_request *req); --int ptlrpc_error(struct ptlrpc_service *svc, struct ptlrpc_request *req); --void ptlrpc_resend_req(struct ptlrpc_request *request); --int ptl_send_rpc(struct ptlrpc_request *request); --void ptlrpc_link_svc_me(struct ptlrpc_request_buffer_desc *rqbd); -- --/* rpc/client.c */ --void ptlrpc_init_client(int req_portal, int rep_portal, char *name, -- struct ptlrpc_client *); --void ptlrpc_cleanup_client(struct obd_import *imp); --__u8 *ptlrpc_req_to_uuid(struct ptlrpc_request *req); --struct ptlrpc_connection *ptlrpc_uuid_to_connection(obd_uuid_t uuid); - -int ll_brw_sync_wait(struct obd_brw_set *, int phase); -- --int ptlrpc_queue_wait(struct ptlrpc_request *req); --void ptlrpc_continue_req(struct ptlrpc_request *req); --int ptlrpc_replay_req(struct ptlrpc_request *req); --void ptlrpc_restart_req(struct ptlrpc_request *req); -- --struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode, -- int count, int *lengths, char **bufs); --void ptlrpc_free_req(struct ptlrpc_request *request); --void ptlrpc_req_finished(struct ptlrpc_request *request); --struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct ptlrpc_connection *); --void ptlrpc_free_bulk(struct ptlrpc_bulk_desc *bulk); --struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc); --void ptlrpc_free_bulk_page(struct ptlrpc_bulk_page *page); - int ptlrpc_check_status(struct ptlrpc_request *req, int err); -- --/* rpc/service.c */ --struct ptlrpc_service * - ptlrpc_init_svc(__u32 nevents, __u32 nbufs, __u32 bufsize, __u32 max_req_size, -ptlrpc_init_svc(__u32 nevents, __u32 nbufs, __u32 bufsize, __u32 max_req_size, -- int req_portal, int rep_portal, -- obd_uuid_t uuid, svc_handler_t, char *name); --void ptlrpc_stop_all_threads(struct ptlrpc_service *svc); --int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, -- char *name); --int ptlrpc_unregister_service(struct ptlrpc_service *service); -- - struct ptlrpc_svc_data { -struct ptlrpc_svc_data { -- char *name; - struct ptlrpc_service *svc; - struct ptlrpc_service *svc; -- struct ptlrpc_thread *thread; -- struct obd_device *dev; - }; -}; -- --/* rpc/pack_generic.c */ --int lustre_pack_msg(int count, int *lens, char **bufs, int *len, -- struct lustre_msg **msg); --int lustre_msg_size(int count, int *lengths); --int lustre_unpack_msg(struct lustre_msg *m, int len); --void *lustre_msg_buf(struct lustre_msg *m, int n); -- --static inline void ptlrpc_bulk_decref(struct ptlrpc_bulk_desc *desc) --{ -- if (atomic_dec_and_test(&desc->bd_refcount)) { -- CDEBUG(D_PAGE, "Released last ref on %p, freeing\n", desc); -- ptlrpc_free_bulk(desc); -- } else { -- CDEBUG(D_PAGE, "%p -> %d\n", desc, -- atomic_read(&desc->bd_refcount)); -- } --} -- --static inline void ptlrpc_bulk_addref(struct ptlrpc_bulk_desc *desc) --{ -- atomic_inc(&desc->bd_refcount); -- CDEBUG(D_PAGE, "Set refcount of %p to %d\n", desc, -- atomic_read(&desc->bd_refcount)); --} -- --#endif diff --cc lustre/include/linux/obd.h index 89624fb,cb72b5b..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd.h +++ /dev/null @@@ -1,404 -1,420 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#ifndef __OBD_H --#define __OBD_H - #include - #include - #include - #include - - #include - #include - #include - #include - - struct obd_type { - struct list_head typ_chain; - struct obd_ops *typ_ops; - struct proc_dir_entry *typ_procroot; - char *typ_name; - int typ_refcnt; - }; - - struct brw_page { - struct page *pg; - obd_size count; - obd_off off; - obd_flag flag; - }; -- --struct lov_oinfo { /* per-child structure */ -- __u64 loi_id; /* object ID on the target OST */ - __u64 loi_size; /* size of this object on the target OST */ -- struct lustre_handle *loi_handle; /* handle for object on OST */ -- int loi_ost_idx; /* OST stripe index in lmd_objects array */ --}; -- --struct lov_stripe_md { -- __u32 lsm_magic; - __u32 lsm_mds_easize; /* packed size for MDS of ea - KILL ME*/ -- __u64 lsm_object_id; /* lov object id */ -- __u64 lsm_stripe_size; /* size of the stripe */ -- __u32 lsm_stripe_pattern; /* per-lov object stripe pattern */ -- int lsm_stripe_offset; /* offset of first stripe in lmd_objects */ -- int lsm_stripe_count; /* how many objects are being striped on */ - int lsm_ost_count; /* how many OSTs are in this LOV - KILL ME */ -- struct lov_oinfo lsm_oinfo[0]; -}; - -#ifdef __KERNEL__ -# include -# include -# include -# include - -# include -# include -# include -# include - -struct obd_type { - struct list_head typ_chain; - struct obd_ops *typ_ops; - struct proc_dir_entry *typ_procroot; - char *typ_name; - int typ_refcnt; -}; - -struct brw_page { - struct page *pg; - obd_size count; - obd_off off; - obd_flag flag; --}; -- --/* Individual type definitions */ -- --struct ext2_obd { -- struct super_block *e2_sb; -- struct vfsmount *e2_vfsmnt; --}; -- --struct obd_ucred { -- __u32 ouc_fsuid; -- __u32 ouc_fsgid; -- __u32 ouc_cap; --}; -- --#define OBD_RUN_CTXT_MAGIC 0xC0FFEEAA --#define OBD_CTXT_DEBUG /* development-only debugging */ --struct obd_run_ctxt { -- struct vfsmount *pwdmnt; -- struct dentry *pwd; -- mm_segment_t fs; -- __u32 fsuid; -- __u32 fsgid; -- __u32 cap; --#ifdef OBD_CTXT_DEBUG -- __u32 magic; --#endif --}; -- -- --#ifdef OBD_CTXT_DEBUG --#define OBD_SET_CTXT_MAGIC(ctxt) (ctxt)->magic = OBD_RUN_CTXT_MAGIC --#else --#define OBD_SET_CTXT_MAGIC(ctxt) do {} while(0) --#endif -- --struct filter_obd { -- char *fo_fstype; -- struct super_block *fo_sb; -- struct vfsmount *fo_vfsmnt; -- struct obd_run_ctxt fo_ctxt; -- struct dentry *fo_dentry_O; -- struct dentry *fo_dentry_O_mode[16]; -- spinlock_t fo_objidlock; /* protects fo_lastobjid increment */ -- __u64 fo_lastobjid; -- struct file_operations *fo_fop; -- struct inode_operations *fo_iop; -- struct address_space_operations *fo_aops; -- struct list_head fo_export_list; -- spinlock_t fo_fddlock; /* protects setting dentry->d_fsdata */ --}; -- --struct mds_server_data; -- --struct client_obd { -- struct obd_import cl_import; -- struct semaphore cl_sem; -- int cl_conn_count; -- obd_uuid_t cl_target_uuid; /* XXX -> lustre_name */ - /* max_mds_easize is purely a performance thing so we don't have to - * call obd_size_wiremd() all the time. */ -- int cl_max_mds_easize; - int cl_max_ost_easize; -- struct obd_device *cl_containing_lov; --}; -- --#define IOC_OSC_TYPE 'h' --#define IOC_OSC_MIN_NR 20 --#define IOC_OSC_REGISTER_LOV _IOWR('h', 20, struct obd_device *) --#define IOC_OSC_MAX_NR 50 -- --struct mds_obd { - struct ptlrpc_service *mds_service; - struct ptlrpc_service *mds_service; -- - char *mds_fstype; - struct super_block *mds_sb; - struct super_operations *mds_sop; - struct vfsmount *mds_vfsmnt; - struct obd_run_ctxt mds_ctxt; - struct file_operations *mds_fop; - struct inode_operations *mds_iop; - char *mds_fstype; - struct super_block *mds_sb; - struct super_operations *mds_sop; - struct vfsmount *mds_vfsmnt; - struct obd_run_ctxt mds_ctxt; - struct file_operations *mds_fop; - struct inode_operations *mds_iop; -- struct address_space_operations *mds_aops; - struct mds_fs_operations *mds_fsops; - int mds_max_mdsize; - struct file *mds_rcvd_filp; - spinlock_t mds_last_lock; - __u64 mds_last_committed; - __u64 mds_last_rcvd; - __u64 mds_mount_count; - struct ll_fid mds_rootfid; - struct mds_server_data *mds_server_data; - struct mds_fs_operations *mds_fsops; - - int mds_max_mdsize; - struct file *mds_rcvd_filp; - struct semaphore mds_transno_sem; - __u64 mds_last_committed; - __u64 mds_last_rcvd; - __u64 mds_mount_count; - struct ll_fid mds_rootfid; - struct mds_server_data *mds_server_data; - - wait_queue_head_t mds_next_transno_waitq; - __u64 mds_next_recovery_transno; - int mds_recoverable_clients; - struct list_head mds_recovery_queue; - struct list_head mds_delayed_reply_queue; - spinlock_t mds_processing_task_lock; - pid_t mds_processing_task; --}; -- --struct ldlm_obd { -- struct ptlrpc_service *ldlm_cb_service; -- struct ptlrpc_service *ldlm_cancel_service; -- struct ptlrpc_client *ldlm_client; -- struct ptlrpc_connection *ldlm_server_conn; --}; -- --struct echo_obd { -- char *eo_fstype; -- struct obdo oa; -- spinlock_t eo_lock; -- __u64 eo_lastino; -- atomic_t eo_getattr; -- atomic_t eo_setattr; -- atomic_t eo_create; -- atomic_t eo_destroy; -- atomic_t eo_prep; -- atomic_t eo_read; -- atomic_t eo_write; --}; -- --struct recovd_obd { -- spinlock_t recovd_lock; -- struct list_head recovd_managed_items; /* items managed */ -- struct list_head recovd_troubled_items; /* items in recovery */ -- -- wait_queue_head_t recovd_recovery_waitq; -- wait_queue_head_t recovd_ctl_waitq; -- wait_queue_head_t recovd_waitq; -- struct task_struct *recovd_thread; -- __u32 recovd_state; --}; -- --struct trace_obd { -- struct obdtrace_opstats *stats; --}; -- --#if 0 --struct snap_obd { -- unsigned int snap_index; /* which snapshot index are we accessing */ -- int snap_tableno; --}; -- --#endif -- --struct ost_obd { -- struct ptlrpc_service *ost_service; -- struct lustre_handle ost_conn; /* the local connection to the OBD */ --}; -- -struct echo_client_obd { - struct lustre_handle conn; /* the local connection to osc/lov */ -}; -- --struct lov_tgt_desc { -- obd_uuid_t uuid; -- struct lustre_handle conn; -- int active; /* is this target available for requests, etc */ --}; -- --struct lov_obd { -- spinlock_t lov_lock; -- struct obd_device *mdcobd; -- struct lov_desc desc; -- int bufsize; -- int refcount; -- struct lov_tgt_desc *tgts; --}; -- --struct niobuf_local { -- __u64 offset; -- __u32 len; -- __u32 xid; -- __u32 flags; -- void *addr; -- struct page *page; -- void *target_private; -- struct dentry *dentry; --}; -- --#define N_LOCAL_TEMP_PAGE 0x00000001 -- --/* corresponds to one of the obd's */ --struct obd_device { -- struct obd_type *obd_type; -- -- /* common and UUID name of this device */ -- char *obd_name; -- obd_uuid_t obd_uuid; -- -- int obd_minor; -- int obd_flags; -- struct proc_dir_entry *obd_proc_entry; -- struct list_head obd_exports; -- struct list_head obd_imports; -- struct ldlm_namespace *obd_namespace; -- struct ptlrpc_client obd_ldlm_client; /* XXX OST/MDS only */ -- /* a spinlock is OK for what we do now, may need a semaphore later */ -- spinlock_t obd_dev_lock; -- union { -- struct ext2_obd ext2; -- struct filter_obd filter; -- struct mds_obd mds; -- struct client_obd cli; -- struct ost_obd ost; - struct echo_client_obd echo_client;; -- // struct osc_obd osc; -- struct ldlm_obd ldlm; -- struct echo_obd echo; -- struct recovd_obd recovd; -- struct trace_obd trace; -- struct lov_obd lov; --#if 0 -- struct snap_obd snap; --#endif -- } u; -- /* Fields used by LProcFS */ -- unsigned int cntr_mem_size; -- void* counters; --}; - - struct brw_cb_data; -- --struct obd_ops { - int (*o_iocontrol)(long cmd, struct lustre_handle *, int len, - int (*o_iocontrol)(unsigned int cmd, struct lustre_handle *, int len, -- void *karg, void *uarg); -- int (*o_get_info)(struct lustre_handle *, obd_count keylen, void *key, -- obd_count *vallen, void **val); -- int (*o_set_info)(struct lustre_handle *, obd_count keylen, void *key, -- obd_count vallen, void *val); -- int (*o_attach)(struct obd_device *dev, obd_count len, void *data); -- int (*o_detach)(struct obd_device *dev); -- int (*o_setup) (struct obd_device *dev, obd_count len, void *data); -- int (*o_cleanup)(struct obd_device *dev); -- int (*o_connect)(struct lustre_handle *conn, struct obd_device *src, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover); -- int (*o_disconnect)(struct lustre_handle *conn); -- -- -- int (*o_statfs)(struct lustre_handle *conn, struct obd_statfs *osfs); - int (*o_packmd)(struct lustre_handle *, struct lov_mds_md **wire_tgt, - struct lov_stripe_md *mem_src); - int (*o_unpackmd)(struct lustre_handle *, - struct lov_stripe_md **mem_tgt, - struct lov_mds_md *wire_src); -- int (*o_preallocate)(struct lustre_handle *, obd_count *req, -- obd_id *ids); -- int (*o_create)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md **ea); -- int (*o_destroy)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea); -- int (*o_setattr)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea); -- int (*o_getattr)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea); -- int (*o_open)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea); -- int (*o_close)(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea); -- int (*o_brw)(int rw, struct lustre_handle *conn, -- struct lov_stripe_md *ea, obd_count oa_bufs, - struct brw_page *pgarr, brw_cb_t callback, - struct brw_cb_data *data); - struct brw_page *pgarr, struct obd_brw_set *); -- int (*o_punch)(struct lustre_handle *conn, struct obdo *tgt, -- struct lov_stripe_md *ea, obd_size count, -- obd_off offset); -- int (*o_sync)(struct lustre_handle *conn, struct obdo *tgt, -- obd_size count, obd_off offset); -- int (*o_migrate)(struct lustre_handle *conn, struct obdo *dst, -- struct obdo *src, obd_size count, obd_off offset); -- int (*o_copy)(struct lustre_handle *dstconn, struct obdo *dst, -- struct lustre_handle *srconn, struct obdo *src, -- obd_size count, obd_off offset); -- int (*o_iterate)(struct lustre_handle *conn, -- int (*)(obd_id, obd_gr, void *), -- obd_id *startid, obd_gr group, void *data); -- int (*o_preprw)(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_remote *remote, -- struct niobuf_local *local, void **desc_private); -- int (*o_commitrw)(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_local *local, -- void *desc_private); -- int (*o_enqueue)(struct lustre_handle *conn, struct lov_stripe_md *md, -- struct lustre_handle *parent_lock, -- __u32 type, void *cookie, int cookielen, __u32 mode, -- int *flags, void *cb, void *data, int datalen, -- struct lustre_handle *lockh); -- int (*o_cancel)(struct lustre_handle *, struct lov_stripe_md *md, -- __u32 mode, struct lustre_handle *); -- int (*o_cancel_unused)(struct lustre_handle *, struct lov_stripe_md *, -- int local_only); -- --}; -- --static inline void *mds_fs_start(struct mds_obd *mds, struct inode *inode, -- int op) --{ -- return mds->mds_fsops->fs_start(inode, op); --} -- --static inline int mds_fs_commit(struct mds_obd *mds, struct inode *inode, -- void *handle) --{ -- return mds->mds_fsops->fs_commit(inode, handle); --} -- --static inline int mds_fs_setattr(struct mds_obd *mds, struct dentry *dentry, -- void *handle, struct iattr *iattr) --{ -- int rc; -- /* -- * NOTE: we probably don't need to take i_sem here when changing -- * ATTR_SIZE because the MDS never needs to truncate a file. -- * The ext2/ext3 code never truncates a directory, and files -- * stored on the MDS are entirely sparse (no data blocks). -- * If we do need to get it, we can do it here. -- */ -- lock_kernel(); -- rc = mds->mds_fsops->fs_setattr(dentry, handle, iattr); -- unlock_kernel(); -- -- return rc; --} -- --static inline int mds_fs_set_md(struct mds_obd *mds, struct inode *inode, - void *handle, struct lov_mds_md *md) - void *handle, struct lov_mds_md *md, - int size) --{ - return mds->mds_fsops->fs_set_md(inode, handle, md); - return mds->mds_fsops->fs_set_md(inode, handle, md, size); --} -- --static inline int mds_fs_get_md(struct mds_obd *mds, struct inode *inode, - struct lov_mds_md *md) - struct lov_mds_md *md, int size) --{ - return mds->mds_fsops->fs_get_md(inode, md); - return mds->mds_fsops->fs_get_md(inode, md, size); --} -- --static inline ssize_t mds_fs_readpage(struct mds_obd *mds, struct file *file, -- char *buf, size_t count, loff_t *offset) --{ -- return mds->mds_fsops->fs_readpage(file, buf, count, offset); --} -- --/* Set up callback to update mds->mds_last_committed with the current -- * value of mds->mds_last_recieved when this transaction is on disk. -- */ --static inline int mds_fs_set_last_rcvd(struct mds_obd *mds, void *handle) --{ -- return mds->mds_fsops->fs_set_last_rcvd(mds, handle); --} -- --/* Enable data journaling on the given file */ --static inline ssize_t mds_fs_journal_data(struct mds_obd *mds, -- struct file *file) --{ -- return mds->mds_fsops->fs_journal_data(file); --} -- --static inline int mds_fs_statfs(struct mds_obd *mds, struct statfs *sfs) --{ -- if (mds->mds_fsops->fs_statfs) -- return mds->mds_fsops->fs_statfs(mds->mds_sb, sfs); -- -- return vfs_statfs(mds->mds_sb, sfs); --} - - #endif -#endif /* __KERNEL */ -#endif /* __OBD_H */ diff --cc lustre/include/linux/obd_class.h index 8b4833c,197de84..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_class.h +++ /dev/null @@@ -1,785 -1,879 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#ifndef __LINUX_CLASS_OBD_H --#define __LINUX_CLASS_OBD_H -- --#ifndef __KERNEL__ --# include --# define __KERNEL__ --# include --# undef __KERNEL__ --#else --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include --#endif -- -- - /* - * ======== OBD Device Declarations =========== - */ -/* OBD Device Declarations */ --#define MAX_OBD_DEVICES 128 --extern struct obd_device obd_dev[MAX_OBD_DEVICES]; -- --#define OBD_ATTACHED 0x1 --#define OBD_SET_UP 0x2 - - extern struct proc_dir_entry * - proc_lustre_register_obd_device(struct obd_device *obd); - extern void proc_lustre_release_obd_device(struct obd_device *obd); - extern void proc_lustre_remove_obd_entry(const char* name, - struct obd_device *obd); -- - /* - * ======== OBD Operations Declarations =========== - */ -/* OBD Operations Declarations */ -- --#ifdef __KERNEL__ --static inline int obd_check_conn(struct lustre_handle *conn) --{ -- struct obd_device *obd; -- if (!conn) { -- CERROR("NULL conn\n"); -- RETURN(-ENOTCONN); -- } -- obd = class_conn2obd(conn); -- if (!obd) { -- CERROR("NULL obd\n"); -- RETURN(-ENODEV); -- } -- -- if (!obd->obd_flags & OBD_ATTACHED ) { -- CERROR("obd %d not attached\n", obd->obd_minor); -- RETURN(-ENODEV); -- } -- -- if (!obd->obd_flags & OBD_SET_UP) { -- CERROR("obd %d not setup\n", obd->obd_minor); -- RETURN(-ENODEV); -- } -- -- if (!obd->obd_type) { -- CERROR("obd %d not typed\n", obd->obd_minor); -- RETURN(-ENODEV); -- } -- -- if (!obd->obd_type->typ_ops) { -- CERROR("obd_check_conn: obd %d no operations\n", -- obd->obd_minor); -- RETURN(-EOPNOTSUPP); -- } -- return 0; --} -- -- --#define OBT(dev) (dev)->obd_type --#define OBP(dev, op) (dev)->obd_type->typ_ops->o_ ## op -- --#define OBD_CHECK_SETUP(conn, exp) \ --do { \ -- if (!(conn)) { \ -- CERROR("NULL connection\n"); \ -- RETURN(-EINVAL); \ -- } \ -- \ -- exp = class_conn2export(conn); \ -- if (!(exp)) { \ -- CERROR("No export\n"); \ -- RETURN(-EINVAL); \ -- } \ -- \ -- if (!((exp)->exp_obd->obd_flags & OBD_SET_UP)) { \ -- CERROR("Device %d not setup\n", \ -- (exp)->exp_obd->obd_minor); \ -- RETURN(-EINVAL); \ -- } \ --} while (0) -- --#define OBD_CHECK_DEVSETUP(obd) \ --do { \ -- if (!(obd)) { \ -- CERROR("NULL device\n"); \ -- RETURN(-EINVAL); \ -- } \ -- \ -- if (!((obd)->obd_flags & OBD_SET_UP)) { \ -- CERROR("Device %d not setup\n", \ -- (obd)->obd_minor); \ -- RETURN(-EINVAL); \ -- } \ --} while (0) -- --#define OBD_CHECK_OP(obd, op) \ --do { \ -- if (!OBP((obd), op)) { \ -- CERROR("obd_" #op ": dev %d no operation\n", \ -- obd->obd_minor); \ -- RETURN(-EOPNOTSUPP); \ -- } \ --} while (0) -- --static inline int obd_get_info(struct lustre_handle *conn, obd_count keylen, -- void *key, obd_count *vallen, void **val) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, get_info); -- -- rc = OBP(exp->exp_obd, get_info)(conn, keylen, key, vallen, val); -- RETURN(rc); --} -- --static inline int obd_set_info(struct lustre_handle *conn, obd_count keylen, -- void *key, obd_count vallen, void *val) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, set_info); -- -- rc = OBP(exp->exp_obd, set_info)(conn, keylen, key, vallen, val); -- RETURN(rc); --} -- --static inline int obd_setup(struct obd_device *obd, int datalen, void *data) --{ -- int rc; - ENTRY; -- -- OBD_CHECK_OP(obd, setup); -- -- rc = OBP(obd, setup)(obd, datalen, data); -- RETURN(rc); --} -- --static inline int obd_cleanup(struct obd_device *obd) --{ -- int rc; - ENTRY; -- -- OBD_CHECK_DEVSETUP(obd); -- OBD_CHECK_OP(obd, cleanup); -- -- rc = OBP(obd, cleanup)(obd); -- RETURN(rc); -} - -/* Pack an in-memory MD struct for sending to the MDS and/or disk. - * Returns +ve size of packed MD (0 for free), or -ve error. - * - * If @wire_tgt == NULL, MD size is returned (max size if @mem_src == NULL). - * If @*wire_tgt != NULL and @mem_src == NULL, @*wire_tgt will be freed. - * If @*wire_tgt == NULL, it will be allocated - */ -static inline int obd_packmd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt, - struct lov_stripe_md *mem_src) -{ - struct obd_export *exp; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, packmd); - - RETURN(OBP(exp->exp_obd, packmd)(conn, wire_tgt, mem_src)); -} - -static inline int obd_size_wiremd(struct lustre_handle *conn, - struct lov_stripe_md *mem_src) -{ - return obd_packmd(conn, NULL, mem_src); -} - -/* helper functions */ -static inline int obd_alloc_wiremd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt) -{ - LASSERT(wire_tgt); - LASSERT(*wire_tgt == NULL); - return obd_packmd(conn, wire_tgt, NULL); -} - -static inline int obd_free_wiremd(struct lustre_handle *conn, - struct lov_mds_md **wire_tgt) -{ - LASSERT(wire_tgt); - LASSERT(*wire_tgt); - return obd_packmd(conn, wire_tgt, NULL); -} - -/* Unpack an MD struct from the MDS and/or disk to in-memory format. - * Returns +ve size of unpacked MD (0 for free), or -ve error. - * - * If @mem_tgt == NULL, MD size is returned (max size if @wire_src == NULL). - * If @*mem_tgt != NULL and @wire_src == NULL, @*mem_tgt will be freed. - * If @*mem_tgt == NULL, it will be allocated - */ -static inline int obd_unpackmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt, - struct lov_mds_md *wire_src) -{ - struct obd_export *exp; - ENTRY; - - OBD_CHECK_SETUP(conn, exp); - OBD_CHECK_OP(exp->exp_obd, unpackmd); - - RETURN(OBP(exp->exp_obd, unpackmd)(conn, mem_tgt, wire_src)); -} - -static inline int obd_size_memmd(struct lustre_handle *conn, - struct lov_mds_md *wire_src) -{ - return obd_unpackmd(conn, NULL, wire_src); -} - -/* helper functions */ -static inline int obd_alloc_memmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt) -{ - LASSERT(mem_tgt); - LASSERT(*mem_tgt == NULL); - return obd_unpackmd(conn, mem_tgt, NULL); -} - -static inline int obd_free_memmd(struct lustre_handle *conn, - struct lov_stripe_md **mem_tgt) -{ - LASSERT(mem_tgt); - LASSERT(*mem_tgt); - return obd_unpackmd(conn, mem_tgt, NULL); --} -- --static inline int obd_create(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md **ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, create); -- -- rc = OBP(exp->exp_obd, create)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_destroy(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, destroy); -- -- rc = OBP(exp->exp_obd, destroy)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_getattr(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, getattr); -- -- rc = OBP(exp->exp_obd, getattr)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_close(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, close); -- -- rc = OBP(exp->exp_obd, close)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_open(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, open); -- -- rc = OBP(exp->exp_obd, open)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_setattr(struct lustre_handle *conn, struct obdo *obdo, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, setattr); -- -- rc = OBP(exp->exp_obd, setattr)(conn, obdo, ea); -- RETURN(rc); --} -- --static inline int obd_connect(struct lustre_handle *conn, -- struct obd_device *obd, obd_uuid_t cluuid, -- struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- int rc; - ENTRY; -- -- OBD_CHECK_DEVSETUP(obd); -- OBD_CHECK_OP(obd, connect); -- -- rc = OBP(obd, connect)(conn, obd, cluuid, recovd, recover); -- RETURN(rc); --} -- --static inline int obd_disconnect(struct lustre_handle *conn) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, disconnect); -- -- rc = OBP(exp->exp_obd, disconnect)(conn); -- RETURN(rc); --} -- --static inline int obd_statfs(struct lustre_handle *conn,struct obd_statfs *osfs) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, statfs); -- -- rc = OBP(exp->exp_obd, statfs)(conn, osfs); -- RETURN(rc); --} -- --static inline int obd_punch(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea, -- obd_size start, obd_size end) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, punch); -- -- rc = OBP(exp->exp_obd, punch)(conn, oa, ea, start, end); -- RETURN(rc); --} -- --static inline int obd_brw(int cmd, struct lustre_handle *conn, -- struct lov_stripe_md *ea, obd_count oa_bufs, - struct brw_page *pg, - brw_cb_t callback, struct brw_cb_data *data) - struct brw_page *pg, struct obd_brw_set *set) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, brw); -- -- if (!(cmd & OBD_BRW_RWMASK)) { -- CERROR("obd_brw: cmd must be OBD_BRW_READ or OBD_BRW_WRITE\n"); -- LBUG(); -- } -- - rc = OBP(exp->exp_obd, brw)(cmd, conn, ea, oa_bufs, pg, callback, data); - rc = OBP(exp->exp_obd, brw)(cmd, conn, ea, oa_bufs, pg, set); -- RETURN(rc); --} -- --static inline int obd_preprw(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_remote *remote, -- struct niobuf_local *local, void **desc_private) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, preprw); -- -- rc = OBP(exp->exp_obd, preprw)(cmd, conn, objcount, obj, niocount, -- remote, local, desc_private); -- RETURN(rc); --} -- --static inline int obd_commitrw(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_local *local, -- void *desc_private) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, commitrw); -- -- rc = OBP(exp->exp_obd, commitrw)(cmd, conn, objcount, obj, niocount, -- local, desc_private); -- RETURN(rc); --} -- - static inline int obd_iocontrol(int cmd, struct lustre_handle *conn, -static inline int obd_iocontrol(unsigned int cmd, struct lustre_handle *conn, -- int len, void *karg, void *uarg) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, iocontrol); -- -- rc = OBP(exp->exp_obd, iocontrol)(cmd, conn, len, karg, uarg); -- RETURN(rc); --} -- --static inline int obd_enqueue(struct lustre_handle *conn, -- struct lov_stripe_md *ea, -- struct lustre_handle *parent_lock, -- __u32 type, void *cookie, int cookielen, -- __u32 mode, int *flags, void *cb, void *data, -- int datalen, struct lustre_handle *lockh) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, enqueue); -- -- rc = OBP(exp->exp_obd, enqueue)(conn, ea, parent_lock, type, -- cookie, cookielen, mode, flags, cb, -- data, datalen, lockh); -- RETURN(rc); --} -- --static inline int obd_cancel(struct lustre_handle *conn, -- struct lov_stripe_md *ea, __u32 mode, -- struct lustre_handle *lockh) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, cancel); -- -- rc = OBP(exp->exp_obd, cancel)(conn, ea, mode, lockh); -- RETURN(rc); --} -- --static inline int obd_cancel_unused(struct lustre_handle *conn, -- struct lov_stripe_md *ea, int local) --{ -- struct obd_export *exp; -- int rc; - ENTRY; -- -- OBD_CHECK_SETUP(conn, exp); -- OBD_CHECK_OP(exp->exp_obd, cancel_unused); -- -- rc = OBP(exp->exp_obd, cancel_unused)(conn, ea, local); -- RETURN(rc); --} -- --#endif -- - /* - * ======== OBD Metadata Support =========== - */ -/* OBD Metadata Support */ -- --extern int obd_init_caches(void); --extern void obd_cleanup_caches(void); -- --static inline struct lustre_handle *obdo_handle(struct obdo *oa) --{ -- return (struct lustre_handle *)&oa->o_inline; --} -- --static inline void obd_oa2handle(struct lustre_handle *handle, struct obdo *oa) --{ -- if (oa->o_valid |= OBD_MD_FLHANDLE) { -- struct lustre_handle *oa_handle = obdo_handle(oa); -- memcpy(handle, oa_handle, sizeof(*handle)); -- } --} -- --static inline void obd_handle2oa(struct obdo *oa, struct lustre_handle *handle) --{ -- if (handle->addr) { -- struct lustre_handle *oa_handle = obdo_handle(oa); -- memcpy(oa_handle, handle, sizeof(*handle)); -- oa->o_valid |= OBD_MD_FLHANDLE; -- } --} -- --#ifdef __KERNEL__ --/* support routines */ --extern kmem_cache_t *obdo_cachep; --static inline struct obdo *obdo_alloc(void) --{ -- struct obdo *oa; -- -- oa = kmem_cache_alloc(obdo_cachep, SLAB_KERNEL); -- if (oa == NULL) -- LBUG(); -- memset(oa, 0, sizeof (*oa)); -- -- return oa; --} -- --static inline void obdo_free(struct obdo *oa) --{ -- if (!oa) -- return; -- kmem_cache_free(obdo_cachep, oa); --} -- --static inline void obdo_from_iattr(struct obdo *oa, struct iattr *attr) --{ -- unsigned int ia_valid = attr->ia_valid; -- -- if (ia_valid & ATTR_ATIME) { -- oa->o_atime = attr->ia_atime; -- oa->o_valid |= OBD_MD_FLATIME; -- } -- if (ia_valid & ATTR_MTIME) { -- oa->o_mtime = attr->ia_mtime; -- oa->o_valid |= OBD_MD_FLMTIME; -- } -- if (ia_valid & ATTR_CTIME) { -- oa->o_ctime = attr->ia_ctime; -- oa->o_valid |= OBD_MD_FLCTIME; -- } -- if (ia_valid & ATTR_SIZE) { -- oa->o_size = attr->ia_size; -- oa->o_valid |= OBD_MD_FLSIZE; -- } -- if (ia_valid & ATTR_MODE) { -- oa->o_mode = attr->ia_mode; -- oa->o_valid |= OBD_MD_FLTYPE | OBD_MD_FLMODE; -- if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID)) -- oa->o_mode &= ~S_ISGID; -- } -- if (ia_valid & ATTR_UID) { -- oa->o_uid = attr->ia_uid; -- oa->o_valid |= OBD_MD_FLUID; -- } -- if (ia_valid & ATTR_GID) { -- oa->o_gid = attr->ia_gid; -- oa->o_valid |= OBD_MD_FLGID; -- } --} -- -- --static inline void iattr_from_obdo(struct iattr *attr, struct obdo *oa, -- obd_flag valid) --{ -- memset(attr, 0, sizeof(*attr)); -- if (valid & OBD_MD_FLATIME) { -- attr->ia_atime = oa->o_atime; -- attr->ia_valid |= ATTR_ATIME; -- } -- if (valid & OBD_MD_FLMTIME) { -- attr->ia_mtime = oa->o_mtime; -- attr->ia_valid |= ATTR_MTIME; -- } -- if (valid & OBD_MD_FLCTIME) { -- attr->ia_ctime = oa->o_ctime; -- attr->ia_valid |= ATTR_CTIME; -- } -- if (valid & OBD_MD_FLSIZE) { -- attr->ia_size = oa->o_size; -- attr->ia_valid |= ATTR_SIZE; -- } -- if (valid & OBD_MD_FLTYPE) { -- attr->ia_mode = (attr->ia_mode & ~S_IFMT)|(oa->o_mode & S_IFMT); -- attr->ia_valid |= ATTR_MODE; -- } -- if (valid & OBD_MD_FLMODE) { -- attr->ia_mode = (attr->ia_mode & S_IFMT)|(oa->o_mode & ~S_IFMT); -- attr->ia_valid |= ATTR_MODE; -- if (!in_group_p(oa->o_gid) && !capable(CAP_FSETID)) -- attr->ia_mode &= ~S_ISGID; -- } -- if (valid & OBD_MD_FLUID) -- { -- attr->ia_uid = oa->o_uid; -- attr->ia_valid |= ATTR_UID; -- } -- if (valid & OBD_MD_FLGID) { -- attr->ia_gid = oa->o_gid; -- attr->ia_valid |= ATTR_GID; -- } --} -- -- --/* WARNING: the file systems must take care not to tinker with -- attributes they don't manage (such as blocks). */ -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --#define to_kdev_t(dev) dev --#define kdev_t_to_nr(dev) dev --#endif -- --static inline void obdo_from_inode(struct obdo *dst, struct inode *src, -- obd_flag valid) --{ --// if (valid & OBD_MD_FLID) --// dst->o_id = src->i_ino; -- if (valid & OBD_MD_FLATIME) -- dst->o_atime = src->i_atime; -- if (valid & OBD_MD_FLMTIME) -- dst->o_mtime = src->i_mtime; -- if (valid & OBD_MD_FLCTIME) -- dst->o_ctime = src->i_ctime; -- if (valid & OBD_MD_FLSIZE) -- dst->o_size = src->i_size; -- if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ -- dst->o_blocks = src->i_blocks; -- if (valid & OBD_MD_FLBLKSZ) -- dst->o_blksize = src->i_blksize; -- if (valid & OBD_MD_FLTYPE) -- dst->o_mode = (dst->o_mode & ~S_IFMT) | (src->i_mode & S_IFMT); -- if (valid & OBD_MD_FLMODE) -- dst->o_mode = (dst->o_mode & S_IFMT) | (src->i_mode & ~S_IFMT); -- if (valid & OBD_MD_FLUID) -- dst->o_uid = src->i_uid; -- if (valid & OBD_MD_FLGID) -- dst->o_gid = src->i_gid; -- if (valid & OBD_MD_FLFLAGS) -- dst->o_flags = src->i_flags; -- if (valid & OBD_MD_FLNLINK) -- dst->o_nlink = src->i_nlink; -- if (valid & OBD_MD_FLGENER) -- dst->o_generation = src->i_generation; -- if (valid & OBD_MD_FLRDEV) -- dst->o_rdev = (__u32)kdev_t_to_nr(src->i_rdev); -- -- dst->o_valid |= (valid & ~OBD_MD_FLID); --} -- --static inline void obdo_to_inode(struct inode *dst, struct obdo *src, -- obd_flag valid) --{ --// if (valid & OBD_MD_FLID) --// dst->i_ino = src->o_id; -- if (valid & OBD_MD_FLATIME) -- dst->i_atime = src->o_atime; -- if (valid & OBD_MD_FLMTIME) -- dst->i_mtime = src->o_mtime; -- if (valid & OBD_MD_FLCTIME) -- dst->i_ctime = src->o_ctime; -- if (valid & OBD_MD_FLSIZE) -- dst->i_size = src->o_size; -- if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ -- dst->i_blocks = src->o_blocks; -- if (valid & OBD_MD_FLBLKSZ) -- dst->i_blksize = src->o_blksize; -- if (valid & OBD_MD_FLTYPE) -- dst->i_mode = (dst->i_mode & ~S_IFMT) | (src->o_mode & S_IFMT); -- if (valid & OBD_MD_FLMODE) -- dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT); -- if (valid & OBD_MD_FLUID) -- dst->i_uid = src->o_uid; -- if (valid & OBD_MD_FLGID) -- dst->i_gid = src->o_gid; -- if (valid & OBD_MD_FLFLAGS) -- dst->i_flags = src->o_flags; -- if (valid & OBD_MD_FLNLINK) -- dst->i_nlink = src->o_nlink; -- if (valid & OBD_MD_FLGENER) -- dst->i_generation = src->o_generation; -- if (valid & OBD_MD_FLRDEV) -- dst->i_rdev = to_kdev_t(src->o_rdev); --} --#endif -- --static inline void obdo_cpy_md(struct obdo *dst, struct obdo *src, -- obd_flag valid) --{ --#ifdef __KERNEL__ -- CDEBUG(D_INODE, "src obdo %Ld valid 0x%x, dst obdo %Ld\n", -- (unsigned long long)src->o_id, src->o_valid, -- (unsigned long long)dst->o_id); --#endif -- if (valid & OBD_MD_FLATIME) -- dst->o_atime = src->o_atime; -- if (valid & OBD_MD_FLMTIME) -- dst->o_mtime = src->o_mtime; -- if (valid & OBD_MD_FLCTIME) -- dst->o_ctime = src->o_ctime; -- if (valid & OBD_MD_FLSIZE) -- dst->o_size = src->o_size; -- if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ -- dst->o_blocks = src->o_blocks; -- if (valid & OBD_MD_FLBLKSZ) -- dst->o_blksize = src->o_blksize; -- if (valid & OBD_MD_FLTYPE) -- dst->o_mode = (dst->o_mode & ~S_IFMT) | (src->o_mode & S_IFMT); -- if (valid & OBD_MD_FLMODE) -- dst->o_mode = (dst->o_mode & S_IFMT) | (src->o_mode & ~S_IFMT); -- if (valid & OBD_MD_FLUID) -- dst->o_uid = src->o_uid; -- if (valid & OBD_MD_FLGID) -- dst->o_gid = src->o_gid; -- if (valid & OBD_MD_FLFLAGS) -- dst->o_flags = src->o_flags; -- /* -- if (valid & OBD_MD_FLOBDFLG) -- dst->o_obdflags = src->o_obdflags; -- */ -- if (valid & OBD_MD_FLNLINK) -- dst->o_nlink = src->o_nlink; -- if (valid & OBD_MD_FLGENER) -- dst->o_generation = src->o_generation; -- if (valid & OBD_MD_FLRDEV) -- dst->o_rdev = src->o_rdev; -- if (valid & OBD_MD_FLINLINE && -- src->o_obdflags & OBD_FL_INLINEDATA) { -- memcpy(dst->o_inline, src->o_inline, sizeof(src->o_inline)); -- dst->o_obdflags |= OBD_FL_INLINEDATA; -- } -- -- dst->o_valid |= valid; --} -- -- --/* returns FALSE if comparison (by flags) is same, TRUE if changed */ --static inline int obdo_cmp_md(struct obdo *dst, struct obdo *src, -- obd_flag compare) --{ -- int res = 0; -- -- if ( compare & OBD_MD_FLATIME ) -- res = (res || (dst->o_atime != src->o_atime)); -- if ( compare & OBD_MD_FLMTIME ) -- res = (res || (dst->o_mtime != src->o_mtime)); -- if ( compare & OBD_MD_FLCTIME ) -- res = (res || (dst->o_ctime != src->o_ctime)); -- if ( compare & OBD_MD_FLSIZE ) -- res = (res || (dst->o_size != src->o_size)); -- if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */ -- res = (res || (dst->o_blocks != src->o_blocks)); -- if ( compare & OBD_MD_FLBLKSZ ) -- res = (res || (dst->o_blksize != src->o_blksize)); -- if ( compare & OBD_MD_FLTYPE ) -- res = (res || (((dst->o_mode ^ src->o_mode) & S_IFMT) != 0)); -- if ( compare & OBD_MD_FLMODE ) -- res = (res || (((dst->o_mode ^ src->o_mode) & ~S_IFMT) != 0)); -- if ( compare & OBD_MD_FLUID ) -- res = (res || (dst->o_uid != src->o_uid)); -- if ( compare & OBD_MD_FLGID ) -- res = (res || (dst->o_gid != src->o_gid)); -- if ( compare & OBD_MD_FLFLAGS ) -- res = (res || (dst->o_flags != src->o_flags)); -- if ( compare & OBD_MD_FLNLINK ) -- res = (res || (dst->o_nlink != src->o_nlink)); -- if ( compare & OBD_MD_FLGENER ) -- res = (res || (dst->o_generation != src->o_generation)); -- /* XXX Don't know if thses should be included here - wasn't previously -- if ( compare & OBD_MD_FLINLINE ) -- res = (res || memcmp(dst->o_inline, src->o_inline)); -- */ -- return res; --} -- -- --#ifdef __KERNEL__ --/* I'm as embarrassed about this as you are. -- * -- * // XXX do not look into _superhack with remaining eye -- * // XXX if this were any uglier, I'd get my own show on MTV */ --extern int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c); -- --int class_register_type(struct obd_ops *ops, struct lprocfs_vars* vars, -- char *nm); --int class_unregister_type(char *nm); --int class_name2dev(char *name); --int class_uuid2dev(char *uuid); --struct obd_device *class_uuid2obd(char *uuid); --struct obd_export *class_new_export(struct obd_device *obddev); --struct obd_type *class_nm_to_type(char* name); --void class_destroy_export(struct obd_export *exp); --int class_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid); --int class_disconnect(struct lustre_handle *conn); --void class_disconnect_all(struct obd_device *obddev); -- --/* generic operations shared by various OBD types */ --int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data); --int class_multi_cleanup(struct obd_device *obddev); -- --extern void (*class_signal_connection_failure)(struct ptlrpc_connection *); -- --static inline struct ptlrpc_connection *class_rd2conn(struct recovd_data *rd) --{ -- /* reuse list_entry's member-pointer offset stuff */ -- return list_entry(rd, struct ptlrpc_connection, c_recovd_data); --} -- --#endif -- --/* sysctl.c */ --extern void obd_sysctl_init (void); --extern void obd_sysctl_clean (void); -- --/* uuid.c */ --typedef __u8 class_uuid_t[16]; --//int class_uuid_parse(obd_uuid_t in, class_uuid_t out); --void class_uuid_unparse(class_uuid_t in, obd_uuid_t out); --#endif /* __LINUX_CLASS_OBD_H */ diff --cc lustre/include/linux/obd_echo.h index 67ccf6a,6bc32f2..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_echo.h +++ /dev/null @@@ -1,18 -1,13 +1,0 @@@ --#ifndef _OBD_ECHO_H --#define _OBD_ECHO_H --/* -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ - -- - #ifndef OBD_ECHO_DEVICENAME --#define OBD_ECHO_DEVICENAME "obdecho" - #endif - - extern struct obd_ops echo_obd_ops; -#define OBD_ECHO_CLIENT_DEVICENAME "echo_client" -- --#endif - diff --cc lustre/include/linux/obd_ext2.h index 73b4b0b,73b4b0b..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_ext2.h +++ /dev/null @@@ -1,49 -1,49 +1,0 @@@ --#ifndef _OBD_EXT2 --#define _OBD_EXT2 --/* -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#define OBD_EXT2_RUNIT _IOWR('f', 61, long) -- --#ifndef OBD_EXT2_DEVICENAME --#define OBD_EXT2_DEVICENAME "obdext2" --#endif -- --/* development definitions */ --extern struct obdfs_sb_info *obd_sbi; --extern struct file_operations *obd_fso; -- --/* ext2_obd.c */ --extern struct obd_ops ext2_obd_ops; -- --#include --#include -- --/* super.c */ --#ifdef EXT2_OBD_DEBUG --# undef ext2_debug --# define ext2_debug(format, a...) CDEBUG(D_EXT2, format, ## a) --# define ext2_error ext2_warning --# define ext2_panic ext2_warning --# define ext2_warning(sb, func, format, a...) CDEBUG(D_WARNING, format, ## a) --#else --# undef ext2_debug --# define ext2_debug(format, a...) {} --# define ext2_error(sb, func, format, a...) printk(KERN_ERR "%s: " format, func, ## a) --# define ext2_panic(sb, func, format, a...) printk(KERN_CRIT "%s: " format, func, ## a) --# define ext2_warning(sb, func, format, a...) printk(KERN_WARNING "%s: " format, func, ## a) --#endif -- --extern struct super_operations ext2_sops; --int obd_remount (struct super_block * sb, int * flags, char * data); --struct super_block * ext2_read_super (struct super_block * sb, void * data, -- int silent); --/* punch.c */ --void ext2_truncate (struct inode * inode); --int ext2_punch (struct inode * inode, loff_t start, size_t count); -- --#endif diff --cc lustre/include/linux/obd_filter.h index fb3d1ff,fb3d1ff..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_filter.h +++ /dev/null @@@ -1,50 -1,50 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#ifndef _OBD_FILTER_H --#define _OBD_FILTER_H -- --#ifndef OBD_FILTER_DEVICENAME --#define OBD_FILTER_DEVICENAME "obdfilter" --#endif -- --/* In-memory access to client data from OST struct */ --struct filter_export_data { -- struct list_head fed_open_head; /* files to close on disconnect */ -- spinlock_t fed_lock; /* protects fed_open_head */ --}; -- --/* file data for open files on OST */ --struct filter_file_data { -- struct list_head ffd_export_list; /* export open list - fed_lock */ -- struct file *ffd_file; /* file handle */ -- __u64 ffd_servercookie; /* cookie for lustre handle */ --}; -- --struct filter_dentry_data { -- atomic_t fdd_open_count; -- int fdd_flags; --}; -- --#define FILTER_FLAG_DESTROY 0x0001 /* destroy dentry on last file close */ -- --#endif diff --cc lustre/include/linux/obd_lov.h index b8285f3,acdac151..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_lov.h +++ /dev/null @@@ -1,34 -1,31 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- */ -- --#ifndef _OBD_LOV_H__ --#define _OBD_LOV_H__ -- --#ifdef __KERNEL__ -- --#define OBD_LOV_DEVICENAME "lov" -- --void lov_unpackdesc(struct lov_desc *ld); --void lov_packdesc(struct lov_desc *ld); - void lov_packmd(struct lov_mds_md *mdsmd, struct lov_stripe_md *md); - void lov_unpackmd(struct lov_stripe_md *md, struct lov_mds_md *mdsmd); -- --static inline int lov_stripe_md_size(int stripes) --{ -- return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo); --} -#endif -- --static inline int lov_mds_md_size(int stripes) --{ -- return sizeof(struct lov_mds_md) + stripes*sizeof(struct lov_object_id); --} - - #endif -- --#define IOC_LOV_TYPE 'g' --#define IOC_LOV_MIN_NR 50 --#define IOC_LOV_SET_OSC_ACTIVE _IOWR('g', 50, long) --#define IOC_LOV_MAX_NR 50 -- --#endif diff --cc lustre/include/linux/obd_ost.h index e999451,e999451..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_ost.h +++ /dev/null @@@ -1,42 -1,42 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Data structures for object storage targets and client: OST & OSC's -- * -- * See also lustre_idl.h for wire formats of requests. -- * -- */ -- --#ifndef _LUSTRE_OST_H --#define _LUSTRE_OST_H -- --#include -- --#define LUSTRE_OST_NAME "ost" --#define LUSTRE_OSC_NAME "osc" -- --/* ost/ost_pack.c */ --void ost_pack_niobuf(void **tmp, __u64 offset, __u32 len, __u32 flags, -- __u32 xid); --void ost_unpack_niobuf(void **tmp, struct niobuf_remote **nbp); --void ost_pack_ioo(void **tmp, struct lov_stripe_md *oa, int bufcnt); --void ost_unpack_ioo(void **tmp, struct obd_ioobj **ioop); -- --#endif diff --cc lustre/include/linux/obd_snap.h index b7641d4,b7641d4..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_snap.h +++ /dev/null @@@ -1,29 -1,29 +1,0 @@@ --#ifndef _OBD_SNAP --#define _OBD_SNAP --/* -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#include -- --#define OBD_SNAP_MAGIC 0xfffffff3 /* an unlikely block number */ -- --#ifndef OBD_SNAP_DEVICENAME --#define OBD_SNAP_DEVICENAME "obdsnap" --#endif -- --/* ioctls for manipulating snapshots 40 - 60 */ --#define OBD_SNAP_SETTABLE _IOWR('f', 40, long) --#define OBD_SNAP_PRINTTABLE _IOWR('f', 41, long) --#define OBD_SNAP_DELETE _IOWR('f', 42, long) --#define OBD_SNAP_RESTORE _IOWR('f', 43, long) -- --void snap_use(int table_no, int snap_index) ; --void snap_unuse(int table_no, int snap_index) ; --int snap_is_used(int table_no, int snap_index) ; --int snap_table_attach(int tableno, int snap_index); -- --#endif diff --cc lustre/include/linux/obd_support.h index a6eb4c2,b95b266..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_support.h +++ /dev/null @@@ -1,186 -1,195 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#ifndef _OBD_SUPPORT --#define _OBD_SUPPORT -- --#include --#include --#include --#include --#include -- --/* global variables */ --extern unsigned long obd_memory; --extern unsigned long obd_fail_loc; --extern unsigned long obd_timeout; --extern char obd_recovery_upcall[128]; -- --#define OBD_FAIL_MDS 0x100 --#define OBD_FAIL_MDS_HANDLE_UNPACK 0x101 --#define OBD_FAIL_MDS_GETATTR_NET 0x102 --#define OBD_FAIL_MDS_GETATTR_PACK 0x103 --#define OBD_FAIL_MDS_READPAGE_NET 0x104 --#define OBD_FAIL_MDS_READPAGE_PACK 0x105 --#define OBD_FAIL_MDS_SENDPAGE 0x106 --#define OBD_FAIL_MDS_REINT_NET 0x107 --#define OBD_FAIL_MDS_REINT_UNPACK 0x108 --#define OBD_FAIL_MDS_REINT_SETATTR 0x109 --#define OBD_FAIL_MDS_REINT_SETATTR_WRITE 0x10a --#define OBD_FAIL_MDS_REINT_CREATE 0x10b --#define OBD_FAIL_MDS_REINT_CREATE_WRITE 0x10c --#define OBD_FAIL_MDS_REINT_UNLINK 0x10d --#define OBD_FAIL_MDS_REINT_UNLINK_WRITE 0x10e --#define OBD_FAIL_MDS_REINT_LINK 0x10f --#define OBD_FAIL_MDS_REINT_LINK_WRITE 0x110 --#define OBD_FAIL_MDS_REINT_RENAME 0x111 --#define OBD_FAIL_MDS_REINT_RENAME_WRITE 0x112 --#define OBD_FAIL_MDS_OPEN_NET 0x113 --#define OBD_FAIL_MDS_OPEN_PACK 0x114 --#define OBD_FAIL_MDS_CLOSE_NET 0x115 --#define OBD_FAIL_MDS_CLOSE_PACK 0x116 --#define OBD_FAIL_MDS_CONNECT_NET 0x117 --#define OBD_FAIL_MDS_CONNECT_PACK 0x118 --#define OBD_FAIL_MDS_REINT_NET_REP 0x119 --#define OBD_FAIL_MDS_DISCONNECT_NET 0x11a --#define OBD_FAIL_MDS_GETSTATUS_NET 0x11b --#define OBD_FAIL_MDS_GETSTATUS_PACK 0x11c --#define OBD_FAIL_MDS_STATFS_PACK 0x11d --#define OBD_FAIL_MDS_STATFS_NET 0x11e -- --#define OBD_FAIL_OST 0x200 --#define OBD_FAIL_OST_CONNECT_NET 0x201 --#define OBD_FAIL_OST_DISCONNECT_NET 0x202 --#define OBD_FAIL_OST_GET_INFO_NET 0x203 --#define OBD_FAIL_OST_CREATE_NET 0x204 --#define OBD_FAIL_OST_DESTROY_NET 0x205 --#define OBD_FAIL_OST_GETATTR_NET 0x206 --#define OBD_FAIL_OST_SETATTR_NET 0x207 --#define OBD_FAIL_OST_OPEN_NET 0x208 --#define OBD_FAIL_OST_CLOSE_NET 0x209 --#define OBD_FAIL_OST_BRW_NET 0x20a --#define OBD_FAIL_OST_PUNCH_NET 0x20b --#define OBD_FAIL_OST_STATFS_NET 0x20c --#define OBD_FAIL_OST_HANDLE_UNPACK 0x20d --#define OBD_FAIL_OST_BRW_WRITE_BULK 0x20e --#define OBD_FAIL_OST_BRW_READ_BULK 0x20f -- --#define OBD_FAIL_LDLM 0x300 --#define OBD_FAIL_LDLM_NAMESPACE_NEW 0x301 --#define OBD_FAIL_LDLM_ENQUEUE 0x302 --#define OBD_FAIL_LDLM_CONVERT 0x303 --#define OBD_FAIL_LDLM_CANCEL 0x304 --#define OBD_FAIL_LDLM_BL_CALLBACK 0x305 --#define OBD_FAIL_LDLM_CP_CALLBACK 0x306 -- --#define OBD_FAIL_OSC 0x400 --#define OBD_FAIL_OSC_BRW_READ_BULK 0x401 --#define OBD_FAIL_OSC_BRW_WRITE_BULK 0x402 --#define OBD_FAIL_OSC_LOCK_BL_AST 0x403 --#define OBD_FAIL_OSC_LOCK_CP_AST 0x404 -- --/* preparation for a more advanced failure testbed (not functional yet) */ --#define OBD_FAIL_MASK_SYS 0x0000FF00 --#define OBD_FAIL_MASK_LOC (0x000000FF | OBD_FAIL_MASK_SYS) --#define OBD_FAIL_ONCE 0x80000000 --#define OBD_FAILED 0x40000000 --#define OBD_FAIL_MDS_ALL_NET 0x01000000 --#define OBD_FAIL_OST_ALL_NET 0x02000000 -- --#define OBD_FAIL_CHECK(id) ((obd_fail_loc & OBD_FAIL_MASK_LOC) == (id) && \ -- ((obd_fail_loc & (OBD_FAILED | OBD_FAIL_ONCE))!=\ -- (OBD_FAILED | OBD_FAIL_ONCE))) -- --#define OBD_FAIL_RETURN(id, ret) \ --do { \ -- if (OBD_FAIL_CHECK(id)) { \ -- CERROR("obd_fail_loc=%x, fail operation rc=%d\n", id, ret); \ -- obd_fail_loc |= OBD_FAILED; \ -- if ((id) & OBD_FAIL_ONCE) \ -- obd_fail_loc |= OBD_FAIL_ONCE; \ -- RETURN(ret); \ -- } \ --} while(0) -- --#include --#include -- --#define fixme() CDEBUG(D_OTHER, "FIXME\n"); -- --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) --#define ll_bdevname(a) __bdevname((a)) --#define ll_lock_kernel lock_kernel() --#else --#define ll_lock_kernel --#define ll_bdevname(a) bdevname((a)) --#endif -- --static inline void OBD_FAIL_WRITE(int id, kdev_t dev) --{ -- if (OBD_FAIL_CHECK(id)) { --#ifdef CONFIG_DEV_RDONLY -- CERROR("obd_fail_loc=%x, fail write operation on %s\n", -- id, ll_bdevname(dev)); -- dev_set_rdonly(dev, 2); --#else -- CERROR("obd_fail_loc=%x, can't fail write operation on %s\n", -- id, ll_bdevname(dev)); --#endif -- /* We set FAIL_ONCE because we never "un-fail" a device */ -- obd_fail_loc |= OBD_FAILED | OBD_FAIL_ONCE; -- } --} -- --#define OBD_ALLOC(ptr, size) \ --do { \ - void *lptr; \ -- long s = (size); \ - (ptr) = kmalloc(s, GFP_KERNEL); \ - if ((ptr) == NULL) { \ - (ptr) = lptr = kmalloc(s, GFP_KERNEL); \ - if (lptr == NULL) { \ -- CERROR("kmalloc of '" #ptr "' (%ld bytes) failed " \ -- "at %s:%d\n", s, __FILE__, __LINE__); \ -- } else { \ - memset((ptr), 0, s); \ - memset(lptr, 0, s); \ -- obd_memory += s; \ -- CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %ld at " \ - "%p (tot %ld).\n", s, (ptr), obd_memory); \ - "%p (tot %ld).\n", s, lptr, obd_memory); \ -- } \ --} while (0) - -#ifdef CONFIG_DEBUG_SLAB -#define POISON(lptr, s) do {} while (0) -#else -#define POISON(lptr, s) memset(lptr, 0xb6, s) -#endif -- --#define OBD_FREE(ptr, size) \ --do { \ - void *lptr = (ptr); \ -- int s = (size); \ - LASSERT(ptr); \ - kfree((ptr)); \ - LASSERT(lptr); \ - POISON(lptr, s); \ - kfree(lptr); \ -- obd_memory -= s; \ -- CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %ld).\n", \ - s, (ptr), obd_memory); \ - s, lptr, obd_memory); \ -- (ptr) = (void *)0xdeadbeef; \ --} while (0) -- --#ifdef CONFIG_HIGHMEM --extern void obd_kmap_get(int count, int server); --extern void obd_kmap_put(int count); --#else --#define obd_kmap_get(count, server) do {} while (0) --#define obd_kmap_put(count) do {} while (0) --#endif --#endif diff --cc lustre/include/linux/obd_trace.h index 524889d,524889d..0000000 deleted file mode 100644,100644 --- a/lustre/include/linux/obd_trace.h +++ /dev/null @@@ -1,20 -1,20 +1,0 @@@ --/* -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * obdtrace (header file) - is useful for tracing and performance -- * debug of the Lustre obd protocol stack. obdtrace is a transparent -- * logical obd driver that prints commands their in- and outbound -- * parameters. obdtrace maintains statistics about number and latency -- * of the obd commands that pass through it. As such it is also use -- * for performance analysis. -- * -- * Copyright (c) 2001 Rumi Zahir -- */ -- --#ifndef __OBD_TRACE_H --#define __OBD_TRACE_H -- --#include -- --#endif diff --cc lustre/install-sh index e9de238,e9de238..0000000 deleted file mode 100755,100755 --- a/lustre/install-sh +++ /dev/null @@@ -1,251 -1,251 +1,0 @@@ --#!/bin/sh --# --# install - install a program, script, or datafile --# This comes from X11R5 (mit/util/scripts/install.sh). --# --# Copyright 1991 by the Massachusetts Institute of Technology --# --# Permission to use, copy, modify, distribute, and sell this software and its --# documentation for any purpose is hereby granted without fee, provided that --# the above copyright notice appear in all copies and that both that --# copyright notice and this permission notice appear in supporting --# documentation, and that the name of M.I.T. not be used in advertising or --# publicity pertaining to distribution of the software without specific, --# written prior permission. M.I.T. makes no representations about the --# suitability of this software for any purpose. It is provided "as is" --# without express or implied warranty. --# --# Calling this script install-sh is preferred over install.sh, to prevent --# `make' implicit rules from creating a file called install from it --# when there is no Makefile. --# --# This script is compatible with the BSD install script, but was written --# from scratch. It can only install one file at a time, a restriction --# shared with many OS's install programs. -- -- --# set DOITPROG to echo to test this script -- --# Don't use :- since 4.3BSD and earlier shells don't like it. --doit="${DOITPROG-}" -- -- --# put in absolute paths if you don't have them in your path; or use env. vars. -- --mvprog="${MVPROG-mv}" --cpprog="${CPPROG-cp}" --chmodprog="${CHMODPROG-chmod}" --chownprog="${CHOWNPROG-chown}" --chgrpprog="${CHGRPPROG-chgrp}" --stripprog="${STRIPPROG-strip}" --rmprog="${RMPROG-rm}" --mkdirprog="${MKDIRPROG-mkdir}" -- --transformbasename="" --transform_arg="" --instcmd="$mvprog" --chmodcmd="$chmodprog 0755" --chowncmd="" --chgrpcmd="" --stripcmd="" --rmcmd="$rmprog -f" --mvcmd="$mvprog" --src="" --dst="" --dir_arg="" -- --while [ x"$1" != x ]; do -- case $1 in -- -c) instcmd="$cpprog" -- shift -- continue;; -- -- -d) dir_arg=true -- shift -- continue;; -- -- -m) chmodcmd="$chmodprog $2" -- shift -- shift -- continue;; -- -- -o) chowncmd="$chownprog $2" -- shift -- shift -- continue;; -- -- -g) chgrpcmd="$chgrpprog $2" -- shift -- shift -- continue;; -- -- -s) stripcmd="$stripprog" -- shift -- continue;; -- -- -t=*) transformarg=`echo $1 | sed 's/-t=//'` -- shift -- continue;; -- -- -b=*) transformbasename=`echo $1 | sed 's/-b=//'` -- shift -- continue;; -- -- *) if [ x"$src" = x ] -- then -- src=$1 -- else -- # this colon is to work around a 386BSD /bin/sh bug -- : -- dst=$1 -- fi -- shift -- continue;; -- esac --done -- --if [ x"$src" = x ] --then -- echo "install: no input file specified" -- exit 1 --else -- true --fi -- --if [ x"$dir_arg" != x ]; then -- dst=$src -- src="" -- -- if [ -d $dst ]; then -- instcmd=: -- chmodcmd="" -- else -- instcmd=mkdir -- fi --else -- --# Waiting for this to be detected by the "$instcmd $src $dsttmp" command --# might cause directories to be created, which would be especially bad --# if $src (and thus $dsttmp) contains '*'. -- -- if [ -f $src -o -d $src ] -- then -- true -- else -- echo "install: $src does not exist" -- exit 1 -- fi -- -- if [ x"$dst" = x ] -- then -- echo "install: no destination specified" -- exit 1 -- else -- true -- fi -- --# If destination is a directory, append the input filename; if your system --# does not like double slashes in filenames, you may need to add some logic -- -- if [ -d $dst ] -- then -- dst="$dst"/`basename $src` -- else -- true -- fi --fi -- --## this sed command emulates the dirname command --dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` -- --# Make sure that the destination directory exists. --# this part is taken from Noah Friedman's mkinstalldirs script -- --# Skip lots of stat calls in the usual case. --if [ ! -d "$dstdir" ]; then --defaultIFS=' --' --IFS="${IFS-${defaultIFS}}" -- --oIFS="${IFS}" --# Some sh's can't handle IFS=/ for some reason. --IFS='%' --set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` --IFS="${oIFS}" -- --pathcomp='' -- --while [ $# -ne 0 ] ; do -- pathcomp="${pathcomp}${1}" -- shift -- -- if [ ! -d "${pathcomp}" ] ; -- then -- $mkdirprog "${pathcomp}" -- else -- true -- fi -- -- pathcomp="${pathcomp}/" --done --fi -- --if [ x"$dir_arg" != x ] --then -- $doit $instcmd $dst && -- -- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && -- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && -- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && -- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi --else -- --# If we're going to rename the final executable, determine the name now. -- -- if [ x"$transformarg" = x ] -- then -- dstfile=`basename $dst` -- else -- dstfile=`basename $dst $transformbasename | -- sed $transformarg`$transformbasename -- fi -- --# don't allow the sed command to completely eliminate the filename -- -- if [ x"$dstfile" = x ] -- then -- dstfile=`basename $dst` -- else -- true -- fi -- --# Make a temp file name in the proper directory. -- -- dsttmp=$dstdir/#inst.$$# -- --# Move or copy the file name to the temp name -- -- $doit $instcmd $src $dsttmp && -- -- trap "rm -f ${dsttmp}" 0 && -- --# and set any options; do chmod last to preserve setuid bits -- --# If any of these fail, we abort the whole thing. If we want to --# ignore errors from any of these, just make sure not to ignore --# errors from the above "$doit $instcmd $src $dsttmp" command. -- -- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && -- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && -- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && -- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && -- --# Now rename the file to the real destination. -- -- $doit $rmcmd -f $dstdir/$dstfile && -- $doit $mvcmd $dsttmp $dstdir/$dstfile -- --fi && -- -- --exit 0 diff --cc lustre/ldlm/.cvsignore index e995588,e995588..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/.cvsignore +++ /dev/null @@@ -1,3 -1,3 +1,0 @@@ --.deps --Makefile --Makefile.in diff --cc lustre/ldlm/Makefile.am index ed5051a,ed5051a..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/Makefile.am +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= --MODULE = ldlm --modulefs_DATA = ldlm.o --EXTRA_PROGRAMS = ldlm -- --ldlm_SOURCES = l_lock.c ldlm_lock.c ldlm_resource.c ldlm_test.c ldlm_lockd.c \ --ldlm_extent.c ldlm_request.c -- --include $(top_srcdir)/Rules -- diff --cc lustre/ldlm/l_lock.c index 2566280,680d4f0..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/l_lock.c +++ /dev/null @@@ -1,95 -1,108 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ - - -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include -- --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include -- --/* invariants: -- - only the owner of the lock changes l_owner/l_depth -- - if a non-owner changes or checks the variables a spin lock is taken --*/ -- --void l_lock_init(struct lustre_lock *lock) --{ -- sema_init(&lock->l_sem, 1); -- spin_lock_init(&lock->l_spin); --} -- --void l_lock(struct lustre_lock *lock) --{ -- int owner = 0; - -- spin_lock(&lock->l_spin); - if (lock->l_owner == current) { - if (lock->l_owner == current) -- owner = 1; - } -- spin_unlock(&lock->l_spin); - if (owner) - ++lock->l_depth; - else { - - if (owner) { - ++lock->l_depth; - } else { -- down(&lock->l_sem); -- spin_lock(&lock->l_spin); -- lock->l_owner = current; -- lock->l_depth = 0; -- spin_unlock(&lock->l_spin); -- } --} -- --void l_unlock(struct lustre_lock *lock) --{ - if (lock->l_owner != current) - LBUG(); - if (lock->l_depth < 0) - LBUG(); - LASSERT(lock->l_owner == current); - LASSERT(lock->l_depth >= 0); -- - spin_lock(&lock->l_spin); - if (--lock->l_depth < 0) { - spin_lock(&lock->l_spin); - if (--lock->l_depth < 0) { -- lock->l_owner = NULL; -- spin_unlock(&lock->l_spin); -- up(&lock->l_sem); - return ; - return; - } - spin_unlock(&lock->l_spin); -} - -int l_has_lock(struct lustre_lock *lock) -{ - int depth = -1, owner = 0; - - spin_lock(&lock->l_spin); - if (lock->l_owner == current) { - depth = lock->l_depth; - owner = 1; -- } -- spin_unlock(&lock->l_spin); - - if (depth >= 0) - CDEBUG(D_INFO, "lock_depth: %d\n", depth); - return owner; --} diff --cc lustre/ldlm/ldlm_extent.c index 468eb2b,468eb2b..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_extent.c +++ /dev/null @@@ -1,97 -1,97 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Cluster File Systems, Inc. -- * authors, Peter Braam & -- * Phil Schwan -- */ -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include -- --/* This function will be called to judge if the granted queue of another child -- * (read: another extent) is conflicting and needs its granted queue walked to -- * issue callbacks. -- * -- * This helps to find conflicts between read and write locks on overlapping -- * extents. */ --int ldlm_extent_compat(struct ldlm_lock *a, struct ldlm_lock *b) --{ -- if (MAX(a->l_extent.start, b->l_extent.start) <= -- MIN(a->l_extent.end, b->l_extent.end)) -- RETURN(0); -- -- RETURN(1); --} -- --/* The purpose of this function is to return: -- * - the maximum extent -- * - containing the requested extent -- * - and not overlapping existing extents outside the requested one -- * -- * An alternative policy is to not shrink the new extent when conflicts exist. -- * -- * To reconstruct our formulas, take a deep breath. */ --static void policy_internal(struct list_head *queue, struct ldlm_extent *req_ex, -- struct ldlm_extent *new_ex, ldlm_mode_t mode) --{ -- struct list_head *tmp; -- -- list_for_each(tmp, queue) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- -- if (lock->l_extent.end < req_ex->start) -- new_ex->start = MIN(lock->l_extent.end, new_ex->start); -- else { -- if (lock->l_extent.start < req_ex->start && -- !lockmode_compat(lock->l_req_mode, mode)) -- /* Policy: minimize conflict overlap */ -- new_ex->start = req_ex->start; -- } -- if (lock->l_extent.start > req_ex->end) -- new_ex->end = MAX(lock->l_extent.start, new_ex->end); -- else { -- if (lock->l_extent.end > req_ex->end && -- !lockmode_compat(lock->l_req_mode, mode)) -- /* Policy: minimize conflict overlap */ -- new_ex->end = req_ex->end; -- } -- } --} -- --/* apply the internal policy by walking all the lists */ --int ldlm_extent_policy(struct ldlm_lock *lock, void *req_cookie, -- ldlm_mode_t mode, int flags, void *data) --{ -- struct ldlm_resource *res = lock->l_resource; -- struct ldlm_extent *req_ex = req_cookie; -- struct ldlm_extent new_ex; -- new_ex.start = 0; -- new_ex.end = ~0; -- -- if (!res) -- LBUG(); -- -- l_lock(&res->lr_namespace->ns_lock); -- policy_internal(&res->lr_granted, req_ex, &new_ex, mode); -- policy_internal(&res->lr_converting, req_ex, &new_ex, mode); -- policy_internal(&res->lr_waiting, req_ex, &new_ex, mode); -- l_unlock(&res->lr_namespace->ns_lock); -- -- memcpy(&lock->l_extent, &new_ex, sizeof(new_ex)); -- -- LDLM_DEBUG(lock, "new extent "LPU64" -> "LPU64, new_ex.start, -- new_ex.end); -- -- if (new_ex.end != req_ex->end || new_ex.start != req_ex->start) -- return ELDLM_LOCK_CHANGED; -- else -- return 0; --} diff --cc lustre/ldlm/ldlm_lock.c index abb2a70,83a6661..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_lock.c +++ /dev/null @@@ -1,1038 -1,1061 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (c) 2002 Cluster File Systems, Inc. -- * Author: Peter Braam -- * Author: Phil Schwan -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include --#include --#include --#include --#include -- --//struct lustre_lock ldlm_everything_lock; -- --/* lock types */ --char *ldlm_lockname[] = { -- [0] "--", -- [LCK_EX] "EX", -- [LCK_PW] "PW", -- [LCK_PR] "PR", -- [LCK_CW] "CW", -- [LCK_CR] "CR", -- [LCK_NL] "NL" --}; --char *ldlm_typename[] = { -- [LDLM_PLAIN] "PLN", -- [LDLM_EXTENT] "EXT", --}; -- --char *ldlm_it2str(int it) --{ -- switch (it) { -- case IT_OPEN: -- return "open"; -- case IT_CREAT: -- return "creat"; -- case (IT_OPEN | IT_CREAT): -- return "open|creat"; -- case IT_MKDIR: -- return "mkdir"; -- case IT_LINK: -- return "link"; -- case IT_LINK2: -- return "link2"; -- case IT_SYMLINK: -- return "symlink"; -- case IT_UNLINK: -- return "unlink"; -- case IT_RMDIR: -- return "rmdir"; -- case IT_RENAME: -- return "rename"; -- case IT_RENAME2: -- return "rename2"; -- case IT_READDIR: -- return "readdir"; -- case IT_GETATTR: -- return "getattr"; -- case IT_SETATTR: -- return "setattr"; -- case IT_READLINK: -- return "readlink"; -- case IT_MKNOD: -- return "mknod"; -- case IT_LOOKUP: -- return "lookup"; -- default: -- CERROR("Unknown intent %d\n", it); -- return "UNKNOWN"; -- } --} -- --extern kmem_cache_t *ldlm_lock_slab; -struct lustre_lock ldlm_handle_lock; -- --static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b); -- --ldlm_res_compat ldlm_res_compat_table[] = { -- [LDLM_PLAIN] ldlm_plain_compat, -- [LDLM_EXTENT] ldlm_extent_compat, --}; -- --static ldlm_res_policy ldlm_intent_policy_func; -- --static int ldlm_plain_policy(struct ldlm_lock *lock, void *req_cookie, -- ldlm_mode_t mode, int flags, void *data) --{ -- if ((flags & LDLM_FL_HAS_INTENT) && ldlm_intent_policy_func) { -- return ldlm_intent_policy_func(lock, req_cookie, mode, flags, -- data); -- } -- -- return ELDLM_OK; --} -- --ldlm_res_policy ldlm_res_policy_table[] = { -- [LDLM_PLAIN] ldlm_plain_policy, -- [LDLM_EXTENT] ldlm_extent_policy, --}; -- --void ldlm_register_intent(ldlm_res_policy arg) --{ -- ldlm_intent_policy_func = arg; --} -- --void ldlm_unregister_intent(void) --{ -- ldlm_intent_policy_func = NULL; --} -- --/* -- * REFCOUNTED LOCK OBJECTS -- */ -- -- --/* -- * Lock refcounts, during creation: -- * - one special one for allocation, dec'd only once in destroy -- * - one for being a lock that's in-use -- * - one for the addref associated with a new lock -- */ --struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock) --{ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); - lock->l_refc++; - atomic_inc(&lock->l_refc); -- ldlm_resource_getref(lock->l_resource); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- return lock; --} -- --void ldlm_lock_put(struct ldlm_lock *lock) --{ -- struct ldlm_namespace *ns = lock->l_resource->lr_namespace; -- ENTRY; -- -- l_lock(&ns->ns_lock); - lock->l_refc--; - //LDLM_DEBUG(lock, "after refc--"); - if (lock->l_refc < 0) - LBUG(); - atomic_dec(&lock->l_refc); - LASSERT(atomic_read(&lock->l_refc) >= 0); -- - if (ldlm_resource_put(lock->l_resource)) { - LASSERT(lock->l_refc == 0); - if (ldlm_resource_putref(lock->l_resource)) { - LASSERT(atomic_read(&lock->l_refc) == 0); -- lock->l_resource = NULL; -- } -- if (lock->l_parent) -- LDLM_LOCK_PUT(lock->l_parent); -- - if (lock->l_refc == 0 && (lock->l_flags & LDLM_FL_DESTROYED)) { - if (atomic_read(&lock->l_refc) == 0) { - LASSERT(lock->l_destroyed); -- l_unlock(&ns->ns_lock); -- LDLM_DEBUG(lock, "final lock_put on destroyed lock, freeing"); -- - //spin_lock(&ldlm_handle_lock); -- spin_lock(&ns->ns_counter_lock); -- ns->ns_locks--; -- spin_unlock(&ns->ns_counter_lock); -- -- lock->l_resource = NULL; -- lock->l_random = DEAD_HANDLE_MAGIC; -- if (lock->l_export && lock->l_export->exp_connection) -- ptlrpc_put_connection(lock->l_export->exp_connection); - memset(lock, 0x5a, sizeof(*lock)); -- kmem_cache_free(ldlm_lock_slab, lock); - //spin_unlock(&ldlm_handle_lock); -- CDEBUG(D_MALLOC, "kfreed 'lock': %d at %p (tot 0).\n", -- sizeof(*lock), lock); -- } else -- l_unlock(&ns->ns_lock); - - EXIT; -} -- -void ldlm_lock_remove_from_lru(struct ldlm_lock *lock) -{ - ENTRY; - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (!list_empty(&lock->l_lru)) { - list_del_init(&lock->l_lru); - lock->l_resource->lr_namespace->ns_nr_unused--; - LASSERT(lock->l_resource->lr_namespace->ns_nr_unused >= 0); - } - l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- EXIT; --} -- --void ldlm_lock_destroy(struct ldlm_lock *lock) --{ -- ENTRY; -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- -- if (!list_empty(&lock->l_children)) { -- LDLM_DEBUG(lock, "still has children (%p)!", -- lock->l_children.next); -- ldlm_lock_dump(lock); -- LBUG(); -- } -- if (lock->l_readers || lock->l_writers) { -- LDLM_DEBUG(lock, "lock still has references"); -- ldlm_lock_dump(lock); -- } -- -- if (!list_empty(&lock->l_res_link)) { -- ldlm_lock_dump(lock); -- LBUG(); -- } -- - if (lock->l_flags & LDLM_FL_DESTROYED) { - if (lock->l_destroyed) { -- LASSERT(list_empty(&lock->l_lru)); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- EXIT; -- return; -- } - lock->l_destroyed = 1; -- - list_del_init(&lock->l_lru); -- list_del(&lock->l_export_chain); -- lock->l_export = NULL; - lock->l_flags |= LDLM_FL_DESTROYED; - ldlm_lock_remove_from_lru(lock); -- -- /* Wake anyone waiting for this lock */ -- /* FIXME: I should probably add yet another flag, instead of using -- * l_export to only call this on clients */ -- if (lock->l_export && lock->l_completion_ast) -- lock->l_completion_ast(lock, 0); -- -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- LDLM_LOCK_PUT(lock); -- EXIT; --} -- --/* -- usage: pass in a resource on which you have done get -- pass in a parent lock on which you have done a get -- do not put the resource or the parent -- returns: lock with refcount 1 --*/ --static struct ldlm_lock *ldlm_lock_new(struct ldlm_lock *parent, -- struct ldlm_resource *resource) --{ -- struct ldlm_lock *lock; -- ENTRY; -- -- if (resource == NULL) -- LBUG(); -- -- lock = kmem_cache_alloc(ldlm_lock_slab, SLAB_KERNEL); -- if (lock == NULL) -- RETURN(NULL); -- -- memset(lock, 0, sizeof(*lock)); -- get_random_bytes(&lock->l_random, sizeof(__u64)); -- -- lock->l_resource = resource; -- /* this refcount matches the one of the resource passed -- in which is not being put away */ - lock->l_refc = 1; - atomic_set(&lock->l_refc, 1); -- INIT_LIST_HEAD(&lock->l_children); -- INIT_LIST_HEAD(&lock->l_res_link); -- INIT_LIST_HEAD(&lock->l_lru); -- INIT_LIST_HEAD(&lock->l_export_chain); -- INIT_LIST_HEAD(&lock->l_pending_chain); -- init_waitqueue_head(&lock->l_waitq); -- -- spin_lock(&resource->lr_namespace->ns_counter_lock); -- resource->lr_namespace->ns_locks++; -- spin_unlock(&resource->lr_namespace->ns_counter_lock); -- -- if (parent != NULL) { -- l_lock(&parent->l_resource->lr_namespace->ns_lock); -- lock->l_parent = parent; -- list_add(&lock->l_childof, &parent->l_children); -- l_unlock(&parent->l_resource->lr_namespace->ns_lock); -- } -- -- CDEBUG(D_MALLOC, "kmalloced 'lock': %d at " -- "%p (tot %d).\n", sizeof(*lock), lock, 1); -- /* this is the extra refcount, to prevent the lock from evaporating */ -- LDLM_LOCK_GET(lock); -- RETURN(lock); --} -- --int ldlm_lock_change_resource(struct ldlm_lock *lock, __u64 new_resid[3]) --{ -- struct ldlm_namespace *ns = lock->l_resource->lr_namespace; -- struct ldlm_resource *oldres = lock->l_resource; - int i; - int i, refc; -- ENTRY; -- -- l_lock(&ns->ns_lock); -- if (memcmp(new_resid, lock->l_resource->lr_name, -- sizeof(lock->l_resource->lr_name)) == 0) { -- /* Nothing to do */ -- l_unlock(&ns->ns_lock); -- RETURN(0); -- } -- -- LASSERT(new_resid[0] != 0); -- -- /* This function assumes that the lock isn't on any lists */ -- LASSERT(list_empty(&lock->l_res_link)); -- -- lock->l_resource = ldlm_resource_get(ns, NULL, new_resid, -- lock->l_resource->lr_type, 1); -- if (lock->l_resource == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- -- /* move references over */ - for (i = 0; i < lock->l_refc; i++) { - refc = atomic_read(&lock->l_refc); - for (i = 0; i < refc; i++) { -- int rc; -- ldlm_resource_getref(lock->l_resource); - rc = ldlm_resource_put(oldres); - if (rc == 1 && i != lock->l_refc - 1) - rc = ldlm_resource_putref(oldres); - if (rc == 1 && i != refc - 1) -- LBUG(); -- } -- /* compensate for the initial get above.. */ - ldlm_resource_put(lock->l_resource); - ldlm_resource_putref(lock->l_resource); -- -- l_unlock(&ns->ns_lock); -- RETURN(0); --} -- --/* -- * HANDLES -- */ -- --void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh) --{ -- lockh->addr = (__u64) (unsigned long)lock; -- lockh->cookie = lock->l_random; --} -- - struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *handle, - int strict) -/* - * if flags: atomically get the lock and set the flags. - * Return NULL if flag already set - */ - -struct ldlm_lock *__ldlm_handle2lock(struct lustre_handle *handle, int strict, - int flags) --{ -- struct ldlm_lock *lock = NULL, *retval = NULL; -- ENTRY; -- - if (!handle || !handle->addr) - LASSERT(handle); - - if (!handle->addr) -- RETURN(NULL); -- - //spin_lock(&ldlm_handle_lock); -- lock = (struct ldlm_lock *)(unsigned long)(handle->addr); -- if (!kmem_cache_validate(ldlm_lock_slab, (void *)lock)) { -- //CERROR("bogus lock %p\n", lock); -- GOTO(out2, retval); -- } -- -- if (lock->l_random != handle->cookie) { - CERROR("bogus cookie: lock %p has "LPX64" vs. handle "LPX64"\n", - lock, lock->l_random, handle->cookie); - //CERROR("bogus cookie: lock %p has "LPX64" vs. handle "LPX64 - // "\n", lock, lock->l_random, handle->cookie); -- GOTO(out2, NULL); -- } -- if (!lock->l_resource) { -- CERROR("trying to lock bogus resource: lock %p\n", lock); - LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); -- GOTO(out2, retval); -- } -- if (!lock->l_resource->lr_namespace) { -- CERROR("trying to lock bogus namespace: lock %p\n", lock); - LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); -- GOTO(out2, retval); -- } -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (strict && lock->l_flags & LDLM_FL_DESTROYED) { - if (strict && lock->l_destroyed) { -- CERROR("lock already destroyed: lock %p\n", lock); - LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); - //LDLM_DEBUG(lock, "ldlm_handle2lock(%p)", lock); -- GOTO(out, NULL); -- } - - if (flags && (lock->l_flags & flags)) - GOTO(out, NULL); - - if (flags) - lock->l_flags |= flags; -- -- retval = LDLM_LOCK_GET(lock); -- if (!retval) -- CERROR("lock disappeared below us!!! %p\n", lock); -- EXIT; -- out: -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- out2: - //spin_unlock(&ldlm_handle_lock); -- return retval; --} -- --static int ldlm_plain_compat(struct ldlm_lock *a, struct ldlm_lock *b) --{ -- return lockmode_compat(a->l_req_mode, b->l_req_mode); --} -- --void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc) --{ -- ldlm_res2desc(lock->l_resource, &desc->l_resource); -- desc->l_req_mode = lock->l_req_mode; -- desc->l_granted_mode = lock->l_granted_mode; -- memcpy(&desc->l_extent, &lock->l_extent, sizeof(desc->l_extent)); -- memcpy(desc->l_version, lock->l_version, sizeof(desc->l_version)); --} -- --static void ldlm_add_ast_work_item(struct ldlm_lock *lock, -- struct ldlm_lock *new) --{ -- struct ldlm_ast_work *w; -- ENTRY; -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- if (new && (lock->l_flags & LDLM_FL_AST_SENT)) -- GOTO(out, 0); -- -- OBD_ALLOC(w, sizeof(*w)); -- if (!w) { -- LBUG(); -- GOTO(out, 0); -- } -- -- if (new) { -- lock->l_flags |= LDLM_FL_AST_SENT; -- w->w_blocking = 1; -- ldlm_lock2desc(new, &w->w_desc); -- } -- -- w->w_lock = LDLM_LOCK_GET(lock); -- list_add(&w->w_list, lock->l_resource->lr_tmp); -- out: -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- return; --} -- --void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode) --{ -- struct ldlm_lock *lock; -- -- lock = ldlm_handle2lock(lockh); -- ldlm_lock_addref_internal(lock, mode); -- LDLM_LOCK_PUT(lock); --} -- --/* only called for local locks */ --void ldlm_lock_addref_internal(struct ldlm_lock *lock, __u32 mode) --{ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); - - if (!list_empty(&lock->l_lru)) { - list_del_init(&lock->l_lru); - lock->l_resource->lr_namespace->ns_nr_unused--; - LASSERT(lock->l_resource->lr_namespace->ns_nr_unused >= 0); - } - - ldlm_lock_remove_from_lru(lock); -- if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR) -- lock->l_readers++; -- else -- lock->l_writers++; -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- LDLM_LOCK_GET(lock); -- LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]); --} -- --/* Args: unlocked lock */ --int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns, -- __u64 *res_id, int flags); -- --void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode) --{ - struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0); - struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0, 0); -- struct ldlm_namespace *ns; -- ENTRY; -- -- if (lock == NULL) -- LBUG(); -- -- LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]); -- ns = lock->l_resource->lr_namespace; -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- if (mode == LCK_NL || mode == LCK_CR || mode == LCK_PR) -- lock->l_readers--; -- else -- lock->l_writers--; -- -- /* If we received a blocked AST and this was the last reference, -- * run the callback. */ -- if (!lock->l_readers && !lock->l_writers && -- (lock->l_flags & LDLM_FL_CBPENDING)) { -- if (!lock->l_resource->lr_namespace->ns_client && -- lock->l_export) -- CERROR("FL_CBPENDING set on non-local lock--just a " -- "warning\n"); -- -- LDLM_DEBUG(lock, "final decref done on cbpending lock"); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- -- /* FIXME: need a real 'desc' here */ -- lock->l_blocking_ast(lock, NULL, lock->l_data, -- lock->l_data_len, LDLM_CB_BLOCKING); -- } else if (ns->ns_client && !lock->l_readers && !lock->l_writers) { -- LASSERT(list_empty(&lock->l_lru)); -- LASSERT(ns->ns_nr_unused >= 0); -- list_add_tail(&lock->l_lru, &ns->ns_unused_list); -- ns->ns_nr_unused++; -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- ldlm_cancel_lru(ns); -- } else -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- -- LDLM_LOCK_PUT(lock); /* matches the ldlm_lock_get in addref */ -- LDLM_LOCK_PUT(lock); /* matches the handle2lock above */ -- -- EXIT; --} -- --static int ldlm_lock_compat_list(struct ldlm_lock *lock, int send_cbs, -- struct list_head *queue) --{ -- struct list_head *tmp, *pos; -- int rc = 1; -- -- list_for_each_safe(tmp, pos, queue) { -- struct ldlm_lock *child; -- ldlm_res_compat compat; -- -- child = list_entry(tmp, struct ldlm_lock, l_res_link); -- if (lock == child) -- continue; -- -- compat = ldlm_res_compat_table[child->l_resource->lr_type]; -- if (compat && compat(child, lock)) { -- CDEBUG(D_OTHER, "compat function succeded, next.\n"); -- continue; -- } -- if (lockmode_compat(child->l_granted_mode, lock->l_req_mode)) { -- CDEBUG(D_OTHER, "lock modes are compatible, next.\n"); -- continue; -- } -- -- rc = 0; -- -- if (send_cbs && child->l_blocking_ast != NULL) { -- CDEBUG(D_OTHER, "lock %p incompatible; sending " -- "blocking AST.\n", child); -- ldlm_add_ast_work_item(child, lock); -- } -- } -- -- return rc; --} -- --static int ldlm_lock_compat(struct ldlm_lock *lock, int send_cbs) --{ -- int rc; -- ENTRY; -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- rc = ldlm_lock_compat_list(lock, send_cbs, -- &lock->l_resource->lr_granted); -- /* FIXME: should we be sending ASTs to converting? */ -- if (rc) -- rc = ldlm_lock_compat_list -- (lock, send_cbs, &lock->l_resource->lr_converting); -- -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- RETURN(rc); --} -- --/* NOTE: called by -- - ldlm_handle_enqueuque - resource --*/ --void ldlm_grant_lock(struct ldlm_lock *lock) --{ -- struct ldlm_resource *res = lock->l_resource; -- ENTRY; -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- ldlm_resource_add_lock(res, &res->lr_granted, lock); -- lock->l_granted_mode = lock->l_req_mode; -- -- if (lock->l_granted_mode < res->lr_most_restr) -- res->lr_most_restr = lock->l_granted_mode; -- -- if (lock->l_completion_ast) { -- ldlm_add_ast_work_item(lock, NULL); -- } -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- EXIT; --} -- --/* returns a referenced lock or NULL */ --static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode, -- struct ldlm_extent *extent, -- struct ldlm_lock *old_lock) --{ -- struct ldlm_lock *lock; -- struct list_head *tmp; -- -- list_for_each(tmp, queue) { -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- -- if (lock == old_lock) -- continue; -- - if (lock->l_flags & (LDLM_FL_CBPENDING | LDLM_FL_DESTROYED)) - if (lock->l_flags & LDLM_FL_CBPENDING) -- continue; -- -- if (lock->l_req_mode != mode) -- continue; -- -- if (lock->l_resource->lr_type == LDLM_EXTENT && -- (lock->l_extent.start > extent->start || -- lock->l_extent.end < extent->end)) - continue; - - if (lock->l_destroyed) -- continue; -- -- ldlm_lock_addref_internal(lock, mode); -- return lock; -- } -- -- return NULL; --} -- --/* Can be called in two ways: -- * -- * If 'ns' is NULL, then lockh describes an existing lock that we want to look -- * for a duplicate of. -- * -- * Otherwise, all of the fields must be filled in, to match against. -- * -- * Returns 1 if it finds an already-existing lock that is compatible; in this -- * case, lockh is filled in with a addref()ed lock -- */ --int ldlm_lock_match(struct ldlm_namespace *ns, __u64 *res_id, __u32 type, -- void *cookie, int cookielen, ldlm_mode_t mode, -- struct lustre_handle *lockh) --{ -- struct ldlm_resource *res; -- struct ldlm_lock *lock, *old_lock = NULL; -- int rc = 0; -- ENTRY; -- -- if (ns == NULL) { -- old_lock = ldlm_handle2lock(lockh); -- LASSERT(old_lock); -- -- ns = old_lock->l_resource->lr_namespace; -- res_id = old_lock->l_resource->lr_name; -- type = old_lock->l_resource->lr_type; -- mode = old_lock->l_req_mode; -- } -- -- res = ldlm_resource_get(ns, NULL, res_id, type, 0); -- if (res == NULL) { -- LASSERT(old_lock == NULL); -- RETURN(0); -- } -- -- l_lock(&ns->ns_lock); -- -- if ((lock = search_queue(&res->lr_granted, mode, cookie, old_lock))) -- GOTO(out, rc = 1); -- if ((lock = search_queue(&res->lr_converting, mode, cookie, old_lock))) -- GOTO(out, rc = 1); -- if ((lock = search_queue(&res->lr_waiting, mode, cookie, old_lock))) -- GOTO(out, rc = 1); -- -- EXIT; -- out: - ldlm_resource_put(res); - ldlm_resource_putref(res); -- l_unlock(&ns->ns_lock); -- -- if (lock) { -- ldlm_lock2handle(lock, lockh); -- if (lock->l_completion_ast) -- lock->l_completion_ast(lock, LDLM_FL_WAIT_NOREPROC); -- } -- if (rc) -- LDLM_DEBUG(lock, "matched"); -- else -- LDLM_DEBUG_NOLOCK("not matched"); -- -- if (old_lock) -- LDLM_LOCK_PUT(old_lock); -- -- return rc; --} -- --/* Returns a referenced lock */ --struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 * res_id, __u32 type, -- ldlm_mode_t mode, void *data, __u32 data_len) --{ -- struct ldlm_resource *res, *parent_res = NULL; - struct ldlm_lock *lock, *parent_lock; - struct ldlm_lock *lock, *parent_lock = NULL; -- - parent_lock = ldlm_handle2lock(parent_lock_handle); - if (parent_lock) - parent_res = parent_lock->l_resource; - if (parent_lock_handle) { - parent_lock = ldlm_handle2lock(parent_lock_handle); - if (parent_lock) - parent_res = parent_lock->l_resource; - } -- -- res = ldlm_resource_get(ns, parent_res, res_id, type, 1); -- if (res == NULL) -- RETURN(NULL); -- -- lock = ldlm_lock_new(parent_lock, res); -- if (lock == NULL) { - ldlm_resource_put(res); - ldlm_resource_putref(res); -- RETURN(NULL); -- } -- -- lock->l_req_mode = mode; -- lock->l_data = data; -- lock->l_data_len = data_len; -- -- return lock; --} -- --/* Must be called with lock->l_lock and lock->l_resource->lr_lock not held */ --ldlm_error_t ldlm_lock_enqueue(struct ldlm_lock * lock, -- void *cookie, int cookie_len, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback blocking) --{ -- struct ldlm_resource *res; -- int local; -- ldlm_res_policy policy; -- ENTRY; -- -- res = lock->l_resource; -- lock->l_blocking_ast = blocking; -- -- if (res->lr_type == LDLM_EXTENT) -- memcpy(&lock->l_extent, cookie, sizeof(lock->l_extent)); -- -- /* policies are not executed on the client or during replay */ -- local = res->lr_namespace->ns_client; -- if (!local && !(*flags & LDLM_FL_REPLAY) && -- (policy = ldlm_res_policy_table[res->lr_type])) { -- int rc; -- rc = policy(lock, cookie, lock->l_req_mode, *flags, NULL); -- -- if (rc == ELDLM_LOCK_CHANGED) { -- res = lock->l_resource; -- *flags |= LDLM_FL_LOCK_CHANGED; -- } else if (rc == ELDLM_LOCK_ABORTED) { -- ldlm_lock_destroy(lock); -- RETURN(rc); -- } -- } -- -- l_lock(&res->lr_namespace->ns_lock); -- if (local && lock->l_req_mode == lock->l_granted_mode) { -- /* The server returned a blocked lock, but it was granted before -- * we got a chance to actually enqueue it. We don't need to do -- * anything else. */ -- *flags &= ~(LDLM_FL_BLOCK_GRANTED | -- LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_WAIT); -- GOTO(out, ELDLM_OK); -- } -- -- /* This distinction between local lock trees is very important; a client -- * namespace only has information about locks taken by that client, and -- * thus doesn't have enough information to decide for itself if it can -- * be granted (below). In this case, we do exactly what the server -- * tells us to do, as dictated by the 'flags'. -- * -- * We do exactly the same thing during recovery, when the server is -- * more or less trusting the clients not to lie. -- * -- * FIXME (bug 629283): Detect obvious lies by checking compatibility in -- * granted/converting queues. */ -- ldlm_resource_unlink_lock(lock); -- if (local || (*flags & LDLM_FL_REPLAY)) { -- if (*flags & LDLM_FL_BLOCK_CONV) -- ldlm_resource_add_lock(res, res->lr_converting.prev, -- lock); -- else if (*flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED)) -- ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); -- else -- ldlm_grant_lock(lock); -- GOTO(out, ELDLM_OK); -- } -- -- /* FIXME: We may want to optimize by checking lr_most_restr */ -- if (!list_empty(&res->lr_converting)) { -- ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); -- *flags |= LDLM_FL_BLOCK_CONV; -- GOTO(out, ELDLM_OK); -- } -- if (!list_empty(&res->lr_waiting)) { -- ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); -- *flags |= LDLM_FL_BLOCK_WAIT; -- GOTO(out, ELDLM_OK); -- } -- if (!ldlm_lock_compat(lock, 0)) { -- ldlm_resource_add_lock(res, res->lr_waiting.prev, lock); -- *flags |= LDLM_FL_BLOCK_GRANTED; -- GOTO(out, ELDLM_OK); -- } -- -- ldlm_grant_lock(lock); -- EXIT; -- out: -- l_unlock(&res->lr_namespace->ns_lock); -- /* Don't set 'completion_ast' until here so that if the lock is granted -- * immediately we don't do an unnecessary completion call. */ -- lock->l_completion_ast = completion; -- return ELDLM_OK; --} -- --/* Must be called with namespace taken: queue is waiting or converting. */ --static int ldlm_reprocess_queue(struct ldlm_resource *res, -- struct list_head *queue) --{ -- struct list_head *tmp, *pos; -- ENTRY; -- -- list_for_each_safe(tmp, pos, queue) { -- struct ldlm_lock *pending; -- pending = list_entry(tmp, struct ldlm_lock, l_res_link); -- -- CDEBUG(D_INFO, "Reprocessing lock %p\n", pending); -- -- if (!ldlm_lock_compat(pending, 1)) -- RETURN(1); -- -- list_del_init(&pending->l_res_link); -- ldlm_grant_lock(pending); -- } -- -- RETURN(0); --} -- --void ldlm_run_ast_work(struct list_head *rpc_list) --{ -- struct list_head *tmp, *pos; -- int rc; -- ENTRY; -- -- list_for_each_safe(tmp, pos, rpc_list) { -- struct ldlm_ast_work *w = -- list_entry(tmp, struct ldlm_ast_work, w_list); -- -- if (w->w_blocking) -- rc = w->w_lock->l_blocking_ast -- (w->w_lock, &w->w_desc, w->w_data, -- w->w_datalen, LDLM_CB_BLOCKING); -- else -- rc = w->w_lock->l_completion_ast(w->w_lock, w->w_flags); -- if (rc) -- CERROR("Failed AST - should clean & disconnect " -- "client\n"); -- LDLM_LOCK_PUT(w->w_lock); -- list_del(&w->w_list); -- OBD_FREE(w, sizeof(*w)); -- } -- EXIT; --} -- --/* Must be called with resource->lr_lock not taken. */ --void ldlm_reprocess_all(struct ldlm_resource *res) --{ -- struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); -- ENTRY; -- -- /* Local lock trees don't get reprocessed. */ -- if (res->lr_namespace->ns_client) { -- EXIT; -- return; -- } -- -- l_lock(&res->lr_namespace->ns_lock); -- res->lr_tmp = &rpc_list; -- -- ldlm_reprocess_queue(res, &res->lr_converting); -- if (list_empty(&res->lr_converting)) -- ldlm_reprocess_queue(res, &res->lr_waiting); -- -- res->lr_tmp = NULL; -- l_unlock(&res->lr_namespace->ns_lock); -- -- ldlm_run_ast_work(&rpc_list); -- EXIT; --} -- --void ldlm_cancel_callback(struct ldlm_lock *lock) --{ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- if (!(lock->l_flags & LDLM_FL_CANCEL)) { -- lock->l_flags |= LDLM_FL_CANCEL; -- if (lock->l_blocking_ast) -- lock->l_blocking_ast(lock, NULL, lock->l_data, -- lock->l_data_len, -- LDLM_CB_CANCELING); -- else -- LDLM_DEBUG(lock, "no blocking ast"); -- } -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); --} -- --void ldlm_lock_cancel(struct ldlm_lock *lock) --{ -- struct ldlm_resource *res; -- struct ldlm_namespace *ns; -- ENTRY; -- -- res = lock->l_resource; -- ns = res->lr_namespace; -- -- l_lock(&ns->ns_lock); -- if (lock->l_readers || lock->l_writers) -- LDLM_DEBUG(lock, "lock still has references"); -- -- ldlm_cancel_callback(lock); -- -- ldlm_del_waiting_lock(lock); -- ldlm_resource_unlink_lock(lock); -- ldlm_lock_destroy(lock); -- l_unlock(&ns->ns_lock); -- EXIT; --} -- --int ldlm_lock_set_data(struct lustre_handle *lockh, void *data, int datalen) --{ -- struct ldlm_lock *lock = ldlm_handle2lock(lockh); -- ENTRY; -- -- if (lock == NULL) -- RETURN(-EINVAL); -- -- lock->l_data = data; -- lock->l_data_len = datalen; -- -- LDLM_LOCK_PUT(lock); -- -- RETURN(0); --} -- --void ldlm_cancel_locks_for_export(struct obd_export *exp) --{ -- struct list_head *iter, *n; /* MUST BE CALLED "n"! */ -- -- list_for_each_safe(iter, n, &exp->exp_ldlm_data.led_held_locks) { -- struct ldlm_lock *lock; -- struct ldlm_resource *res; -- lock = list_entry(iter, struct ldlm_lock, l_export_chain); -- res = ldlm_resource_getref(lock->l_resource); -- LDLM_DEBUG(lock, "export %p", exp); -- ldlm_lock_cancel(lock); -- ldlm_reprocess_all(res); - ldlm_resource_put(res); - ldlm_resource_putref(res); -- } --} -- --struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, -- int *flags) --{ -- struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); -- struct ldlm_resource *res; -- struct ldlm_namespace *ns; -- int granted = 0; -- ENTRY; -- -- res = lock->l_resource; -- ns = res->lr_namespace; -- -- l_lock(&ns->ns_lock); -- -- lock->l_req_mode = new_mode; -- ldlm_resource_unlink_lock(lock); -- -- /* If this is a local resource, put it on the appropriate list. */ -- if (res->lr_namespace->ns_client) { -- if (*flags & (LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_GRANTED)) -- ldlm_resource_add_lock(res, res->lr_converting.prev, -- lock); -- else { -- /* This should never happen, because of the way the -- * server handles conversions. */ -- LBUG(); -- -- res->lr_tmp = &rpc_list; -- ldlm_grant_lock(lock); -- res->lr_tmp = NULL; -- granted = 1; -- /* FIXME: completion handling not with ns_lock held ! */ -- if (lock->l_completion_ast) -- lock->l_completion_ast(lock, 0); -- } -- } else { -- /* FIXME: We should try the conversion right away and possibly -- * return success without the need for an extra AST */ -- ldlm_resource_add_lock(res, res->lr_converting.prev, lock); -- *flags |= LDLM_FL_BLOCK_CONV; -- } -- -- l_unlock(&ns->ns_lock); -- -- if (granted) -- ldlm_run_ast_work(&rpc_list); -- RETURN(res); --} -- --void ldlm_lock_dump(struct ldlm_lock *lock) --{ -- char ver[128]; -- -- if (!(portal_debug & D_OTHER)) -- return; -- -- if (RES_VERSION_SIZE != 4) -- LBUG(); -- -- if (!lock) { -- CDEBUG(D_OTHER, " NULL LDLM lock\n"); -- return; -- } -- -- snprintf(ver, sizeof(ver), "%x %x %x %x", -- lock->l_version[0], lock->l_version[1], -- lock->l_version[2], lock->l_version[3]); -- -- CDEBUG(D_OTHER, " -- Lock dump: %p (%s)\n", lock, ver); -- if (lock->l_export && lock->l_export->exp_connection) -- CDEBUG(D_OTHER, " Node: NID %x (rhandle: "LPX64")\n", -- lock->l_export->exp_connection->c_peer.peer_nid, -- lock->l_remote_handle.addr); -- else -- CDEBUG(D_OTHER, " Node: local\n"); -- CDEBUG(D_OTHER, " Parent: %p\n", lock->l_parent); -- CDEBUG(D_OTHER, " Resource: %p ("LPD64")\n", lock->l_resource, -- lock->l_resource->lr_name[0]); -- CDEBUG(D_OTHER, " Requested mode: %d, granted mode: %d\n", -- (int)lock->l_req_mode, (int)lock->l_granted_mode); -- CDEBUG(D_OTHER, " Readers: %u ; Writers; %u\n", -- lock->l_readers, lock->l_writers); -- if (lock->l_resource->lr_type == LDLM_EXTENT) -- CDEBUG(D_OTHER, " Extent: %Lu -> %Lu\n", -- (unsigned long long)lock->l_extent.start, -- (unsigned long long)lock->l_extent.end); --} diff --cc lustre/ldlm/ldlm_lockd.c index 973d565,bd2dd09..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_lockd.c +++ /dev/null @@@ -1,779 -1,794 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Peter Braam -- * Author: Phil Schwan -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include --#include --#include --#include -- --extern kmem_cache_t *ldlm_resource_slab; --extern kmem_cache_t *ldlm_lock_slab; -extern struct lustre_lock ldlm_handle_lock; --extern struct list_head ldlm_namespace_list; --extern int (*mds_reint_p)(int offset, struct ptlrpc_request *req); --extern int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req); -- --inline unsigned long round_timeout(unsigned long timeout) --{ -- return ((timeout / HZ) + 1) * HZ; --} -- --static struct list_head waiting_locks_list; --static spinlock_t waiting_locks_spinlock; --static struct timer_list waiting_locks_timer; --static int ldlm_already_setup = 0; -- --static void waiting_locks_callback(unsigned long unused) --{ -- struct list_head *liter, *n; -- -- spin_lock_bh(&waiting_locks_spinlock); -- list_for_each_safe(liter, n, &waiting_locks_list) { -- struct ldlm_lock *l = list_entry(liter, struct ldlm_lock, -- l_pending_chain); -- if (l->l_callback_timeout > jiffies) -- break; -- LDLM_DEBUG(l, "timer expired, recovering exp %p on conn %p", -- l->l_export, l->l_export->exp_connection); -- recovd_conn_fail(l->l_export->exp_connection); -- } -- spin_unlock_bh(&waiting_locks_spinlock); --} -- --/* -- * Indicate that we're waiting for a client to call us back cancelling a given -- * lock. We add it to the pending-callback chain, and schedule the lock-timeout -- * timer to fire appropriately. (We round up to the next second, to avoid -- * floods of timer firings during periods of high lock contention and traffic). -- */ --static int ldlm_add_waiting_lock(struct ldlm_lock *lock) --{ -- unsigned long timeout_rounded; -- ENTRY; -- -- LASSERT(list_empty(&lock->l_pending_chain)); -- -- spin_lock_bh(&waiting_locks_spinlock); - lock->l_callback_timeout = jiffies + (obd_timeout * HZ); - lock->l_callback_timeout = jiffies + (obd_timeout * HZ / 2); -- -- timeout_rounded = round_timeout(lock->l_callback_timeout); -- -- if (timeout_rounded < waiting_locks_timer.expires || -- !timer_pending(&waiting_locks_timer)) { -- mod_timer(&waiting_locks_timer, timeout_rounded); -- } -- list_add_tail(&lock->l_pending_chain, &waiting_locks_list); /* FIFO */ -- spin_unlock_bh(&waiting_locks_spinlock); -- RETURN(1); --} -- --/* -- * Remove a lock from the pending list, likely because it had its cancellation -- * callback arrive without incident. This adjusts the lock-timeout timer if -- * needed. Returns 0 if the lock wasn't pending after all, 1 if it was. -- */ --int ldlm_del_waiting_lock(struct ldlm_lock *lock) --{ -- struct list_head *list_next; -- -- ENTRY; -- -- spin_lock_bh(&waiting_locks_spinlock); -- -- if (list_empty(&lock->l_pending_chain)) { -- spin_unlock_bh(&waiting_locks_spinlock); -- RETURN(0); -- } -- -- list_next = lock->l_pending_chain.next; -- if (lock->l_pending_chain.prev == &waiting_locks_list) { -- /* Removing the head of the list, adjust timer. */ -- if (list_next == &waiting_locks_list) { -- /* No more, just cancel. */ -- del_timer(&waiting_locks_timer); -- } else { -- struct ldlm_lock *next; -- next = list_entry(list_next, struct ldlm_lock, -- l_pending_chain); -- mod_timer(&waiting_locks_timer, -- round_timeout(next->l_callback_timeout)); -- } -- } -- list_del_init(&lock->l_pending_chain); -- spin_unlock_bh(&waiting_locks_spinlock); -- RETURN(1); --} -- --static int ldlm_server_blocking_ast(struct ldlm_lock *lock, -- struct ldlm_lock_desc *desc, -- void *data, __u32 data_len, int flag) --{ -- struct ldlm_request *body; -- struct ptlrpc_request *req; -- int rc = 0, size = sizeof(*body); -- ENTRY; -- -- if (flag == LDLM_CB_CANCELING) { -- /* Don't need to do anything here. */ -- RETURN(0); -- } -- -- req = ptlrpc_prep_req(&lock->l_export->exp_ldlm_data.led_import, -- LDLM_BL_CALLBACK, 1, &size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- memcpy(&body->lock_handle1, &lock->l_remote_handle, -- sizeof(body->lock_handle1)); -- memcpy(&body->lock_desc, desc, sizeof(*desc)); -- -- LDLM_DEBUG(lock, "server preparing blocking AST"); -- req->rq_replen = 0; /* no reply needed */ -- -- ldlm_add_waiting_lock(lock); -- (void)ptl_send_rpc(req); -- - /* no commit, and no waiting for reply, so 2x decref now */ - ptlrpc_req_finished(req); - /* not waiting for reply */ -- ptlrpc_req_finished(req); -- -- RETURN(rc); --} -- --static int ldlm_server_completion_ast(struct ldlm_lock *lock, int flags) --{ -- struct ldlm_request *body; -- struct ptlrpc_request *req; -- int rc = 0, size = sizeof(*body); -- ENTRY; -- -- if (lock == NULL) { -- LBUG(); -- RETURN(-EINVAL); -- } -- -- req = ptlrpc_prep_req(&lock->l_export->exp_ldlm_data.led_import, -- LDLM_CP_CALLBACK, 1, &size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- memcpy(&body->lock_handle1, &lock->l_remote_handle, -- sizeof(body->lock_handle1)); -- body->lock_flags = flags; -- ldlm_lock2desc(lock, &body->lock_desc); -- -- LDLM_DEBUG(lock, "server preparing completion AST"); -- req->rq_replen = 0; /* no reply needed */ -- -- (void)ptl_send_rpc(req); - /* no commit, and no waiting for reply, so 2x decref now */ - ptlrpc_req_finished(req); - - /* not waiting for reply */ -- ptlrpc_req_finished(req); -- -- RETURN(rc); --} -- --int ldlm_handle_enqueue(struct ptlrpc_request *req) --{ -- struct obd_device *obddev = req->rq_export->exp_obd; -- struct ldlm_reply *dlm_rep; -- struct ldlm_request *dlm_req; -- int rc, size = sizeof(*dlm_rep), cookielen = 0; -- __u32 flags; -- ldlm_error_t err; -- struct ldlm_lock *lock = NULL; -- void *cookie = NULL; -- ENTRY; -- -- LDLM_DEBUG_NOLOCK("server-side enqueue handler START"); -- -- dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); -- flags = dlm_req->lock_flags; -- if (dlm_req->lock_desc.l_resource.lr_type == LDLM_PLAIN && -- (flags & LDLM_FL_HAS_INTENT)) { -- /* In this case, the reply buffer is allocated deep in -- * local_lock_enqueue by the policy function. */ -- cookie = req; -- cookielen = sizeof(*req); -- } else { -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, -- &req->rq_repmsg); -- if (rc) { -- CERROR("out of memory\n"); -- RETURN(-ENOMEM); -- } -- if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) { -- cookie = &dlm_req->lock_desc.l_extent; -- cookielen = sizeof(struct ldlm_extent); -- } -- } -- -- /* XXX notice that this lock has no callback data: of course the -- export would be exactly what we may want to use here... */ -- lock = ldlm_lock_create(obddev->obd_namespace, -- &dlm_req->lock_handle2, -- dlm_req->lock_desc.l_resource.lr_name, -- dlm_req->lock_desc.l_resource.lr_type, -- dlm_req->lock_desc.l_req_mode, NULL, 0); -- if (!lock) -- GOTO(out, err = -ENOMEM); -- -- memcpy(&lock->l_remote_handle, &dlm_req->lock_handle1, -- sizeof(lock->l_remote_handle)); -- LDLM_DEBUG(lock, "server-side enqueue handler, new lock created"); -- -- err = ldlm_lock_enqueue(lock, cookie, cookielen, &flags, -- ldlm_server_completion_ast, -- ldlm_server_blocking_ast); -- if (err != ELDLM_OK) -- GOTO(out, err); -- -- dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); -- dlm_rep->lock_flags = flags; -- -- ldlm_lock2handle(lock, &dlm_rep->lock_handle); -- if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) -- memcpy(&dlm_rep->lock_extent, &lock->l_extent, -- sizeof(lock->l_extent)); -- if (dlm_rep->lock_flags & LDLM_FL_LOCK_CHANGED) { -- memcpy(dlm_rep->lock_resource_name, lock->l_resource->lr_name, -- sizeof(dlm_rep->lock_resource_name)); -- dlm_rep->lock_mode = lock->l_req_mode; -- } -- -- lock->l_export = req->rq_export; -- if (lock->l_export) { -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- list_add(&lock->l_export_chain, -- &lock->l_export->exp_ldlm_data.led_held_locks); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- } -- -- EXIT; -- out: -- if (lock) -- LDLM_DEBUG(lock, "server-side enqueue handler, sending reply" -- "(err=%d)", err); -- req->rq_status = err; -- -- if (lock) { -- if (!err) -- ldlm_reprocess_all(lock->l_resource); -- LDLM_LOCK_PUT(lock); -- } -- LDLM_DEBUG_NOLOCK("server-side enqueue handler END (lock %p)", lock); -- -- return 0; --} -- --int ldlm_handle_convert(struct ptlrpc_request *req) --{ -- struct ldlm_request *dlm_req; -- struct ldlm_reply *dlm_rep; -- struct ldlm_lock *lock; -- int rc, size = sizeof(*dlm_rep); -- ENTRY; -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) { -- CERROR("out of memory\n"); -- RETURN(-ENOMEM); -- } -- dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); -- dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); -- dlm_rep->lock_flags = dlm_req->lock_flags; -- -- lock = ldlm_handle2lock(&dlm_req->lock_handle1); -- if (!lock) { -- req->rq_status = EINVAL; -- } else { -- LDLM_DEBUG(lock, "server-side convert handler START"); -- ldlm_lock_convert(lock, dlm_req->lock_desc.l_req_mode, -- &dlm_rep->lock_flags); -- if (ldlm_del_waiting_lock(lock)) -- CDEBUG(D_DLMTRACE, "converted waiting lock %p\n", lock); -- req->rq_status = 0; -- } -- -- if (lock) { -- ldlm_reprocess_all(lock->l_resource); -- LDLM_DEBUG(lock, "server-side convert handler END"); -- LDLM_LOCK_PUT(lock); -- } else -- LDLM_DEBUG_NOLOCK("server-side convert handler END"); -- -- RETURN(0); --} -- --int ldlm_handle_cancel(struct ptlrpc_request *req) --{ -- struct ldlm_request *dlm_req; -- struct ldlm_lock *lock; -- int rc; -- ENTRY; -- -- rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) { -- CERROR("out of memory\n"); -- RETURN(-ENOMEM); -- } -- dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); -- if (!dlm_req) { -- CERROR("bad request buffer for cancel\n"); -- RETURN(-EINVAL); -- } -- -- lock = ldlm_handle2lock(&dlm_req->lock_handle1); -- if (!lock) { -- LDLM_DEBUG_NOLOCK("server-side cancel handler stale lock (lock " -- "%p)", (void *)(unsigned long) -- dlm_req->lock_handle1.addr); -- req->rq_status = ESTALE; -- } else { -- LDLM_DEBUG(lock, "server-side cancel handler START"); -- ldlm_lock_cancel(lock); -- if (ldlm_del_waiting_lock(lock)) -- CDEBUG(D_DLMTRACE, "cancelled waiting lock %p\n", lock); -- req->rq_status = 0; -- } -- -- if (ptlrpc_reply(req->rq_svc, req) != 0) -- LBUG(); -- -- if (lock) { -- ldlm_reprocess_all(lock->l_resource); -- LDLM_DEBUG(lock, "server-side cancel handler END"); -- LDLM_LOCK_PUT(lock); -- } -- -- RETURN(0); --} -- --static int ldlm_handle_bl_callback(struct ptlrpc_request *req) --{ -- struct ldlm_request *dlm_req; -- struct ldlm_lock *lock; -- int do_ast; -- ENTRY; -- -- OBD_FAIL_RETURN(OBD_FAIL_OSC_LOCK_BL_AST, 0); -- -- dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); -- -- lock = ldlm_handle2lock(&dlm_req->lock_handle1); -- if (!lock) { -- CERROR("blocking callback on lock "LPX64" - lock disappeared\n", -- dlm_req->lock_handle1.addr); -- RETURN(0); -- } -- -- LDLM_DEBUG(lock, "client blocking AST callback handler START"); -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- lock->l_flags |= LDLM_FL_CBPENDING; -- do_ast = (!lock->l_readers && !lock->l_writers); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- -- if (do_ast) { -- LDLM_DEBUG(lock, "already unused, calling " -- "callback (%p)", lock->l_blocking_ast); -- if (lock->l_blocking_ast != NULL) { -- lock->l_blocking_ast(lock, &dlm_req->lock_desc, -- lock->l_data, lock->l_data_len, -- LDLM_CB_BLOCKING); -- } -- } else -- LDLM_DEBUG(lock, "Lock still has references, will be" -- " cancelled later"); -- -- LDLM_DEBUG(lock, "client blocking callback handler END"); -- LDLM_LOCK_PUT(lock); -- RETURN(0); --} -- --static int ldlm_handle_cp_callback(struct ptlrpc_request *req) --{ -- struct list_head ast_list = LIST_HEAD_INIT(ast_list); -- struct ldlm_request *dlm_req; -- struct ldlm_lock *lock; -- ENTRY; -- -- OBD_FAIL_RETURN(OBD_FAIL_OSC_LOCK_CP_AST, 0); -- -- dlm_req = lustre_msg_buf(req->rq_reqmsg, 0); -- -- lock = ldlm_handle2lock(&dlm_req->lock_handle1); -- if (!lock) { -- CERROR("completion callback on lock "LPX64" - lock " -- "disappeared\n", dlm_req->lock_handle1.addr); -- RETURN(0); -- } -- -- LDLM_DEBUG(lock, "client completion callback handler START"); -- -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- -- /* If we receive the completion AST before the actual enqueue returned, -- * then we might need to switch lock modes, resources, or extents. */ -- if (dlm_req->lock_desc.l_granted_mode != lock->l_req_mode) { -- lock->l_req_mode = dlm_req->lock_desc.l_granted_mode; -- LDLM_DEBUG(lock, "completion AST, new lock mode"); -- } -- if (lock->l_resource->lr_type == LDLM_EXTENT) -- memcpy(&lock->l_extent, &dlm_req->lock_desc.l_extent, -- sizeof(lock->l_extent)); -- ldlm_resource_unlink_lock(lock); -- if (memcmp(dlm_req->lock_desc.l_resource.lr_name, -- lock->l_resource->lr_name, -- sizeof(__u64) * RES_NAME_SIZE) != 0) { -- ldlm_lock_change_resource(lock, -- dlm_req->lock_desc.l_resource.lr_name); -- LDLM_DEBUG(lock, "completion AST, new resource"); -- } -- lock->l_resource->lr_tmp = &ast_list; -- ldlm_grant_lock(lock); -- lock->l_resource->lr_tmp = NULL; -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- LDLM_DEBUG(lock, "callback handler finished, about to run_ast_work"); -- LDLM_LOCK_PUT(lock); -- -- ldlm_run_ast_work(&ast_list); -- -- LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)", -- lock); -- RETURN(0); --} -- --static int ldlm_callback_handler(struct ptlrpc_request *req) --{ -- int rc; -- ENTRY; -- -- rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); -- if (rc) { -- CERROR("lustre_ldlm: Invalid request: %d\n", rc); -- RETURN(rc); -- } -- -- if (req->rq_export == NULL) { - CERROR("lustre_dlm: operation %d with missing/invalid export\n", - req->rq_reqmsg->opc); - RETURN(-ENOTCONN); - CERROR("operation %d with bad export (ptl req %d/rep %d)\n", - req->rq_reqmsg->opc, req->rq_request_portal, - req->rq_reply_portal); - CERROR("--> export addr: "LPX64", cookie: "LPX64"\n", - req->rq_reqmsg->addr, req->rq_reqmsg->cookie); - CERROR("--> ignoring this error as a temporary workaround! " - "beware!\n"); - //RETURN(-ENOTCONN); -- } -- -- switch (req->rq_reqmsg->opc) { -- case LDLM_BL_CALLBACK: -- CDEBUG(D_INODE, "blocking ast\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); -- rc = ldlm_handle_bl_callback(req); -- RETURN(rc); -- case LDLM_CP_CALLBACK: -- CDEBUG(D_INODE, "completion ast\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_CP_CALLBACK, 0); -- rc = ldlm_handle_cp_callback(req); -- RETURN(rc); -- -- default: -- CERROR("invalid opcode %d\n", req->rq_reqmsg->opc); -- RETURN(-EINVAL); -- } -- -- RETURN(0); --} -- -- --static int ldlm_cancel_handler(struct ptlrpc_request *req) --{ -- int rc; -- ENTRY; -- -- rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); -- if (rc) { -- CERROR("lustre_ldlm: Invalid request: %d\n", rc); -- RETURN(rc); -- } -- -- if (req->rq_export == NULL) { - CERROR("lustre_dlm: operation %d with missing/invalid export\n", - req->rq_reqmsg->opc); - RETURN(-ENOTCONN); - CERROR("operation %d with bad export (ptl req %d/rep %d)\n", - req->rq_reqmsg->opc, req->rq_request_portal, - req->rq_reply_portal); - CERROR("--> export addr: "LPX64", cookie: "LPX64"\n", - req->rq_reqmsg->addr, req->rq_reqmsg->cookie); - CERROR("--> ignoring this error as a temporary workaround! " - "beware!\n"); - //RETURN(-ENOTCONN); -- } -- -- switch (req->rq_reqmsg->opc) { -- -- /* XXX FIXME move this back to mds/handler.c, bug 625069 */ -- case LDLM_CANCEL: -- CDEBUG(D_INODE, "cancel\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_CANCEL, 0); -- rc = ldlm_handle_cancel(req); -- if (rc) -- break; -- RETURN(0); -- -- default: -- CERROR("invalid opcode %d\n", req->rq_reqmsg->opc); -- RETURN(-EINVAL); -- } -- -- RETURN(0); --} -- -- --static int ldlm_iocontrol(long cmd, struct lustre_handle *conn, int len, -- void *karg, void *uarg) --{ -- struct obd_device *obddev = class_conn2obd(conn); -- struct ptlrpc_connection *connection; -- int err = 0; -- ENTRY; -- -- if (_IOC_TYPE(cmd) != IOC_LDLM_TYPE || _IOC_NR(cmd) < IOC_LDLM_MIN_NR || -- _IOC_NR(cmd) > IOC_LDLM_MAX_NR) { -- CDEBUG(D_IOCTL, "invalid ioctl (type %ld, nr %ld, size %ld)\n", -- _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); -- RETURN(-EINVAL); -- } -- -- OBD_ALLOC(obddev->u.ldlm.ldlm_client, -- sizeof(*obddev->u.ldlm.ldlm_client)); -- connection = ptlrpc_uuid_to_connection("ldlm"); -- if (!connection) -- CERROR("No LDLM UUID found: assuming ldlm is local.\n"); -- -- switch (cmd) { -- case IOC_LDLM_TEST: -- err = ldlm_test(obddev, conn); -- CERROR("-- done err %d\n", err); -- GOTO(out, err); -- case IOC_LDLM_DUMP: -- ldlm_dump_all_namespaces(); -- GOTO(out, err); -- default: -- GOTO(out, err = -EINVAL); -- } -- -- out: -- if (connection) -- ptlrpc_put_connection(connection); -- OBD_FREE(obddev->u.ldlm.ldlm_client, -- sizeof(*obddev->u.ldlm.ldlm_client)); -- return err; --} -- --static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- struct ldlm_obd *ldlm = &obddev->u.ldlm; -- int rc, i; -- ENTRY; -- -- if (ldlm_already_setup) -- RETURN(-EALREADY); -- -- MOD_INC_USE_COUNT; -- -- rc = ldlm_proc_setup(obddev); -- if (rc != 0) -- GOTO(out_dec, rc); -- -- ldlm->ldlm_cb_service = -- ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE, -- LDLM_MAXREQSIZE, LDLM_CB_REQUEST_PORTAL, -- LDLM_CB_REPLY_PORTAL, "self", -- ldlm_callback_handler, "ldlm_cbd"); -- -- if (!ldlm->ldlm_cb_service) { -- CERROR("failed to start service\n"); -- GOTO(out_proc, rc = -ENOMEM); -- } -- -- ldlm->ldlm_cancel_service = -- ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE, -- LDLM_MAXREQSIZE, LDLM_CANCEL_REQUEST_PORTAL, -- LDLM_CANCEL_REPLY_PORTAL, "self", -- ldlm_cancel_handler, "ldlm_canceld"); -- -- if (!ldlm->ldlm_cancel_service) { -- CERROR("failed to start service\n"); -- GOTO(out_proc, rc = -ENOMEM); -- } -- -- for (i = 0; i < LDLM_NUM_THREADS; i++) { -- char name[32]; - sprintf(name, "ldlm_%02d", i); - sprintf(name, "ldlm_cn_%02d", i); -- rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cancel_service, -- name); -- if (rc) { -- CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc); -- LBUG(); -- GOTO(out_thread, rc); -- } -- } -- -- for (i = 0; i < LDLM_NUM_THREADS; i++) { -- char name[32]; - sprintf(name, "ldlm_%02d", i); - sprintf(name, "ldlm_cb_%02d", i); -- rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cb_service, name); -- if (rc) { -- CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc); -- LBUG(); -- GOTO(out_thread, rc); -- } -- } -- -- INIT_LIST_HEAD(&waiting_locks_list); -- spin_lock_init(&waiting_locks_spinlock); -- waiting_locks_timer.function = waiting_locks_callback; -- waiting_locks_timer.data = 0; -- init_timer(&waiting_locks_timer); -- -- ldlm_already_setup = 1; -- -- RETURN(0); -- -- out_thread: -- ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service); -- ptlrpc_unregister_service(ldlm->ldlm_cancel_service); -- ptlrpc_stop_all_threads(ldlm->ldlm_cb_service); -- ptlrpc_unregister_service(ldlm->ldlm_cb_service); -- -- out_proc: -- ldlm_proc_cleanup(obddev); -- -- out_dec: -- MOD_DEC_USE_COUNT; -- return rc; --} -- --static int ldlm_cleanup(struct obd_device *obddev) --{ -- struct ldlm_obd *ldlm = &obddev->u.ldlm; -- ENTRY; -- -- if (!list_empty(&ldlm_namespace_list)) { -- CERROR("ldlm still has namespaces; clean these up first.\n"); -- RETURN(-EBUSY); -- } -- -- ptlrpc_stop_all_threads(ldlm->ldlm_cb_service); -- ptlrpc_unregister_service(ldlm->ldlm_cb_service); -- ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service); -- ptlrpc_unregister_service(ldlm->ldlm_cancel_service); -- ldlm_proc_cleanup(obddev); -- -- ldlm_already_setup = 0; -- MOD_DEC_USE_COUNT; -- RETURN(0); --} -- --static int ldlm_connect(struct lustre_handle *conn, struct obd_device *src, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- return class_connect(conn, src, cluuid); --} -- --struct obd_ops ldlm_obd_ops = { -- o_iocontrol: ldlm_iocontrol, -- o_setup: ldlm_setup, -- o_cleanup: ldlm_cleanup, -- o_connect: ldlm_connect, -- o_disconnect: class_disconnect --}; -- --static int __init ldlm_init(void) --{ -- int rc = class_register_type(&ldlm_obd_ops, 0, OBD_LDLM_DEVICENAME); -- if (rc != 0) -- return rc; -- -- ldlm_resource_slab = kmem_cache_create("ldlm_resources", -- sizeof(struct ldlm_resource), 0, -- SLAB_HWCACHE_ALIGN, NULL, NULL); -- if (ldlm_resource_slab == NULL) -- return -ENOMEM; -- -- ldlm_lock_slab = kmem_cache_create("ldlm_locks", -- sizeof(struct ldlm_lock), 0, -- SLAB_HWCACHE_ALIGN, NULL, NULL); -- if (ldlm_lock_slab == NULL) { -- kmem_cache_destroy(ldlm_resource_slab); -- return -ENOMEM; -- } - - l_lock_init(&ldlm_handle_lock); -- -- return 0; --} -- --static void __exit ldlm_exit(void) --{ -- class_unregister_type(OBD_LDLM_DEVICENAME); -- if (kmem_cache_destroy(ldlm_resource_slab) != 0) -- CERROR("couldn't free ldlm resource slab\n"); -- if (kmem_cache_destroy(ldlm_lock_slab) != 0) -- CERROR("couldn't free ldlm lock slab\n"); --} -- --EXPORT_SYMBOL(ldlm_completion_ast); --EXPORT_SYMBOL(ldlm_handle_enqueue); --EXPORT_SYMBOL(ldlm_handle_cancel); --EXPORT_SYMBOL(ldlm_handle_convert); --EXPORT_SYMBOL(ldlm_register_intent); --EXPORT_SYMBOL(ldlm_unregister_intent); --EXPORT_SYMBOL(ldlm_lockname); --EXPORT_SYMBOL(ldlm_typename); --EXPORT_SYMBOL(__ldlm_handle2lock); --EXPORT_SYMBOL(ldlm_lock2handle); --EXPORT_SYMBOL(ldlm_lock_put); --EXPORT_SYMBOL(ldlm_lock_match); --EXPORT_SYMBOL(ldlm_lock_addref); --EXPORT_SYMBOL(ldlm_lock_decref); --EXPORT_SYMBOL(ldlm_lock_change_resource); --EXPORT_SYMBOL(ldlm_lock_set_data); --EXPORT_SYMBOL(ldlm_cli_convert); --EXPORT_SYMBOL(ldlm_cli_enqueue); --EXPORT_SYMBOL(ldlm_cli_cancel); --EXPORT_SYMBOL(ldlm_cli_cancel_unused); --EXPORT_SYMBOL(ldlm_match_or_enqueue); --EXPORT_SYMBOL(ldlm_it2str); --EXPORT_SYMBOL(ldlm_test); --EXPORT_SYMBOL(ldlm_regression_start); --EXPORT_SYMBOL(ldlm_regression_stop); --EXPORT_SYMBOL(ldlm_lock_dump); --EXPORT_SYMBOL(ldlm_namespace_new); --EXPORT_SYMBOL(ldlm_namespace_cleanup); --EXPORT_SYMBOL(ldlm_namespace_free); --EXPORT_SYMBOL(ldlm_namespace_dump); --EXPORT_SYMBOL(ldlm_cancel_locks_for_export); -EXPORT_SYMBOL(ldlm_replay_locks); -EXPORT_SYMBOL(ldlm_resource_foreach); -EXPORT_SYMBOL(ldlm_namespace_foreach); --EXPORT_SYMBOL(l_lock); --EXPORT_SYMBOL(l_unlock); -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Lock Management Module v0.1"); --MODULE_LICENSE("GPL"); -- --module_init(ldlm_init); --module_exit(ldlm_exit); diff --cc lustre/ldlm/ldlm_request.c index 778e505,7d449ef..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_request.c +++ /dev/null @@@ -1,656 -1,797 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include --#include -- --static int interrupted_completion_wait(void *data) --{ -- RETURN(1); --} -- --static int expired_completion_wait(void *data) --{ -- struct ldlm_lock *lock = data; -- struct ptlrpc_connection *conn; -- struct obd_device *obd; -- -- if (!lock) -- CERROR("NULL lock\n"); -- else if (!lock->l_connh) -- CERROR("lock %p has NULL connh\n", lock); -- else if (!(obd = class_conn2obd(lock->l_connh))) -- CERROR("lock %p has NULL obd\n", lock); -- else if (!(conn = obd->u.cli.cl_import.imp_connection)) -- CERROR("lock %p has NULL connection\n", lock); -- else -- class_signal_connection_failure(conn); -- RETURN(0); --} -- --int ldlm_completion_ast(struct ldlm_lock *lock, int flags) --{ -- struct l_wait_info lwi = -- LWI_TIMEOUT_INTR(obd_timeout * HZ, expired_completion_wait, -- interrupted_completion_wait, lock); -- int rc = 0; -- ENTRY; -- -- if (flags == LDLM_FL_WAIT_NOREPROC) -- goto noreproc; -- -- if (flags == 0) { -- wake_up(&lock->l_waitq); -- RETURN(0); -- } -- -- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | -- LDLM_FL_BLOCK_CONV))) -- RETURN(0); -- -- LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " -- "sleeping"); -- ldlm_lock_dump(lock); -- ldlm_reprocess_all(lock->l_resource); -- -- noreproc: -- /* Go to sleep until the lock is granted or cancelled. */ -- rc = l_wait_event(lock->l_waitq, -- ((lock->l_req_mode == lock->l_granted_mode) || - (lock->l_flags & LDLM_FL_DESTROYED)), &lwi); - lock->l_destroyed), &lwi); -- - if (lock->l_flags & LDLM_FL_DESTROYED) { - if (lock->l_destroyed) { -- LDLM_DEBUG(lock, "client-side enqueue waking up: destroyed"); -- RETURN(-EIO); -- } -- -- if (rc) { -- LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)", -- rc); -- RETURN(rc); -- } -- -- LDLM_DEBUG(lock, "client-side enqueue waking up: granted"); -- RETURN(0); --} -- --static int ldlm_cli_enqueue_local(struct ldlm_namespace *ns, -- struct lustre_handle *parent_lockh, -- __u64 *res_id, -- __u32 type, -- void *cookie, int cookielen, -- ldlm_mode_t mode, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback blocking, -- void *data, -- __u32 data_len, -- struct lustre_handle *lockh) --{ -- struct ldlm_lock *lock; -- int err; -- ENTRY; -- -- if (ns->ns_client) { -- CERROR("Trying to enqueue local lock in a shadow namespace\n"); -- LBUG(); -- } -- -- lock = ldlm_lock_create(ns, parent_lockh, res_id, type, mode, data, -- data_len); -- if (!lock) -- GOTO(out_nolock, err = -ENOMEM); -- LDLM_DEBUG(lock, "client-side local enqueue handler, new lock created"); -- -- ldlm_lock_addref_internal(lock, mode); -- ldlm_lock2handle(lock, lockh); -- lock->l_connh = NULL; -- -- err = ldlm_lock_enqueue(lock, cookie, cookielen, flags, completion, -- blocking); -- if (err != ELDLM_OK) -- GOTO(out, err); -- -- if (type == LDLM_EXTENT) -- memcpy(cookie, &lock->l_extent, sizeof(lock->l_extent)); -- if ((*flags) & LDLM_FL_LOCK_CHANGED) -- memcpy(res_id, lock->l_resource->lr_name, sizeof(*res_id)); -- -- LDLM_DEBUG_NOLOCK("client-side local enqueue handler END (lock %p)", -- lock); -- -- if (lock->l_completion_ast) -- lock->l_completion_ast(lock, *flags); -- -- LDLM_DEBUG(lock, "client-side local enqueue END"); -- EXIT; -- out: -- LDLM_LOCK_PUT(lock); -- out_nolock: -- return err; --} -- --int ldlm_cli_enqueue(struct lustre_handle *connh, -- struct ptlrpc_request *req, -- struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 *res_id, -- __u32 type, -- void *cookie, int cookielen, -- ldlm_mode_t mode, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback blocking, -- void *data, -- __u32 data_len, -- struct lustre_handle *lockh) --{ -- struct ldlm_lock *lock; -- struct ldlm_request *body; -- struct ldlm_reply *reply; -- int rc, size = sizeof(*body), req_passed_in = 1, is_replay; -- ENTRY; -- -- is_replay = *flags & LDLM_FL_REPLAY; -- LASSERT(connh != NULL || !is_replay); -- -- if (connh == NULL) -- return ldlm_cli_enqueue_local(ns, parent_lock_handle, res_id, -- type, cookie, cookielen, mode, -- flags, completion, blocking, data, -- data_len, lockh); -- -- /* If we're replaying this lock, just check some invariants. -- * If we're creating a new lock, get everything all setup nice. */ -- if (is_replay) { -- lock = ldlm_handle2lock(lockh); -- LDLM_DEBUG(lock, "client-side enqueue START"); -- LASSERT(connh == lock->l_connh); -- } else { -- lock = ldlm_lock_create(ns, parent_lock_handle, res_id, type, -- mode, data, data_len); -- if (lock == NULL) -- GOTO(out_nolock, rc = -ENOMEM); -- LDLM_DEBUG(lock, "client-side enqueue START"); -- /* for the local lock, add the reference */ -- ldlm_lock_addref_internal(lock, mode); -- ldlm_lock2handle(lock, lockh); -- if (type == LDLM_EXTENT) -- memcpy(&lock->l_extent, cookie, -- sizeof(body->lock_desc.l_extent)); -- } -- -- if (req == NULL) { -- req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_ENQUEUE, 1, -- &size, NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- req_passed_in = 0; -- } else if (req->rq_reqmsg->buflens[0] != sizeof(*body)) -- LBUG(); -- -- /* Dump lock data into the request buffer */ -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- ldlm_lock2desc(lock, &body->lock_desc); -- body->lock_flags = *flags; -- -- memcpy(&body->lock_handle1, lockh, sizeof(*lockh)); -- if (parent_lock_handle) -- memcpy(&body->lock_handle2, parent_lock_handle, -- sizeof(body->lock_handle2)); -- -- /* Continue as normal. */ -- if (!req_passed_in) { -- size = sizeof(*reply); -- req->rq_replen = lustre_msg_size(1, &size); -- } -- lock->l_connh = connh; -- lock->l_export = NULL; -- -- LDLM_DEBUG(lock, "sending request"); -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- if (rc != ELDLM_OK) { -- LASSERT(!is_replay); -- LDLM_DEBUG(lock, "client-side enqueue END (%s)", -- rc == ELDLM_LOCK_ABORTED ? "ABORTED" : "FAILED"); -- ldlm_lock_decref(lockh, mode); -- /* FIXME: if we've already received a completion AST, this will -- * LBUG! */ -- ldlm_lock_destroy(lock); -- GOTO(out, rc); -- } -- -- reply = lustre_msg_buf(req->rq_repmsg, 0); -- memcpy(&lock->l_remote_handle, &reply->lock_handle, -- sizeof(lock->l_remote_handle)); -- *flags = reply->lock_flags; -- - CDEBUG(D_INFO, "remote handle: %p, flags: %d\n", - CDEBUG(D_INFO, "local: %p, remote: %p, flags: %d\n", lock, -- (void *)(unsigned long)reply->lock_handle.addr, *flags); -- if (type == LDLM_EXTENT) { -- CDEBUG(D_INFO, "requested extent: "LPU64" -> "LPU64", got " -- "extent "LPU64" -> "LPU64"\n", -- body->lock_desc.l_extent.start, -- body->lock_desc.l_extent.end, -- reply->lock_extent.start, reply->lock_extent.end); -- cookie = &reply->lock_extent; /* FIXME bug 267 */ -- cookielen = sizeof(reply->lock_extent); -- } -- -- /* If enqueue returned a blocked lock but the completion handler has -- * already run, then it fixed up the resource and we don't need to do it -- * again. */ -- if ((*flags) & LDLM_FL_LOCK_CHANGED) { -- int newmode = reply->lock_mode; -- LASSERT(!is_replay); -- if (newmode && newmode != lock->l_req_mode) { -- LDLM_DEBUG(lock, "server returned different mode %s", -- ldlm_lockname[newmode]); -- lock->l_req_mode = newmode; -- } -- -- if (reply->lock_resource_name[0] != -- lock->l_resource->lr_name[0]) { -- CDEBUG(D_INFO, "remote intent success, locking %ld " -- "instead of %ld\n", -- (long)reply->lock_resource_name[0], -- (long)lock->l_resource->lr_name[0]); -- -- ldlm_lock_change_resource(lock, -- reply->lock_resource_name); -- if (lock->l_resource == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- LDLM_DEBUG(lock, "client-side enqueue, new resource"); -- } -- } - - if (!req_passed_in) - ptlrpc_req_finished(req); -- -- if (!is_replay) { -- rc = ldlm_lock_enqueue(lock, cookie, cookielen, flags, -- completion, blocking); -- if (lock->l_completion_ast) -- lock->l_completion_ast(lock, *flags); -- } - - if (!req_passed_in) - ptlrpc_req_finished(req); -- -- LDLM_DEBUG(lock, "client-side enqueue END"); -- EXIT; -- out: -- LDLM_LOCK_PUT(lock); -- out_nolock: -- return rc; --} -- --int ldlm_match_or_enqueue(struct lustre_handle *connh, -- struct ptlrpc_request *req, -- struct ldlm_namespace *ns, -- struct lustre_handle *parent_lock_handle, -- __u64 *res_id, -- __u32 type, -- void *cookie, int cookielen, -- ldlm_mode_t mode, -- int *flags, -- ldlm_completion_callback completion, -- ldlm_blocking_callback blocking, -- void *data, -- __u32 data_len, -- struct lustre_handle *lockh) --{ -- int rc; -- ENTRY; -- rc = ldlm_lock_match(ns, res_id, type, cookie, cookielen, mode, lockh); -- if (rc == 0) { -- rc = ldlm_cli_enqueue(connh, req, ns, -- parent_lock_handle, res_id, type, cookie, -- cookielen, mode, flags, completion, -- blocking, data, data_len, lockh); -- if (rc != ELDLM_OK) -- CERROR("ldlm_cli_enqueue: err: %d\n", rc); -- RETURN(rc); -- } else -- RETURN(0); --} -- --int ldlm_cli_replay_enqueue(struct ldlm_lock *lock) --{ -- struct lustre_handle lockh; -- int flags = LDLM_FL_REPLAY; -- ldlm_lock2handle(lock, &lockh); -- return ldlm_cli_enqueue(lock->l_connh, NULL, NULL, NULL, NULL, -- lock->l_resource->lr_type, NULL, 0, -1, &flags, -- NULL, NULL, NULL, 0, &lockh); --} -- --static int ldlm_cli_convert_local(struct ldlm_lock *lock, int new_mode, -- int *flags) --{ -- ENTRY; -- if (lock->l_resource->lr_namespace->ns_client) { -- CERROR("Trying to cancel local lock\n"); -- LBUG(); -- } -- LDLM_DEBUG(lock, "client-side local convert"); -- -- ldlm_lock_convert(lock, new_mode, flags); -- ldlm_reprocess_all(lock->l_resource); -- -- LDLM_DEBUG(lock, "client-side local convert handler END"); -- LDLM_LOCK_PUT(lock); -- RETURN(0); --} -- --/* FIXME: one of ldlm_cli_convert or the server side should reject attempted -- * conversion of locks which are on the waiting or converting queue */ --int ldlm_cli_convert(struct lustre_handle *lockh, int new_mode, int *flags) --{ -- struct ldlm_request *body; -- struct lustre_handle *connh; -- struct ldlm_reply *reply; -- struct ldlm_lock *lock; -- struct ldlm_resource *res; -- struct ptlrpc_request *req; -- int rc, size = sizeof(*body); -- ENTRY; -- -- lock = ldlm_handle2lock(lockh); -- if (!lock) { -- LBUG(); -- RETURN(-EINVAL); -- } -- *flags = 0; -- connh = lock->l_connh; -- -- if (!connh) -- RETURN(ldlm_cli_convert_local(lock, new_mode, flags)); -- -- LDLM_DEBUG(lock, "client-side convert"); -- -- req = ptlrpc_prep_req(class_conn2cliimp(connh), LDLM_CONVERT, 1, &size, -- NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- memcpy(&body->lock_handle1, &lock->l_remote_handle, -- sizeof(body->lock_handle1)); -- -- body->lock_desc.l_req_mode = new_mode; -- body->lock_flags = *flags; -- -- size = sizeof(*reply); -- req->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- if (rc != ELDLM_OK) -- GOTO(out, rc); -- -- reply = lustre_msg_buf(req->rq_repmsg, 0); -- res = ldlm_lock_convert(lock, new_mode, &reply->lock_flags); -- if (res != NULL) -- ldlm_reprocess_all(res); -- /* Go to sleep until the lock is granted. */ -- /* FIXME: or cancelled. */ -- if (lock->l_completion_ast) -- lock->l_completion_ast(lock, LDLM_FL_WAIT_NOREPROC); -- EXIT; -- out: -- LDLM_LOCK_PUT(lock); -- ptlrpc_req_finished(req); -- return rc; --} -- --int ldlm_cli_cancel(struct lustre_handle *lockh) --{ -- struct ptlrpc_request *req; -- struct ldlm_lock *lock; -- struct ldlm_request *body; -- int rc = 0, size = sizeof(*body); -- ENTRY; -- - lock = ldlm_handle2lock(lockh); - if (!lock) { - /* It's possible that the decref that we did just before this - * cancel was the last reader/writer, and caused a cancel before - * we could call this function. If we want to make this - * impossible (by adding a dec_and_cancel() or similar), then - * we can put the LBUG back. */ - //LBUG(); - /* concurrent cancels on the same handle can happen */ - lock = __ldlm_handle2lock(lockh, 0, LDLM_FL_CANCELING); - if (lock == NULL) -- RETURN(0); - } -- -- if (lock->l_connh) { -- LDLM_DEBUG(lock, "client-side cancel"); -- /* Set this flag to prevent others from getting new references*/ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- lock->l_flags |= LDLM_FL_CBPENDING; -- ldlm_cancel_callback(lock); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- -- req = ptlrpc_prep_req(class_conn2cliimp(lock->l_connh), -- LDLM_CANCEL, 1, &size, NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- /* XXX FIXME bug 249 */ -- req->rq_request_portal = LDLM_CANCEL_REQUEST_PORTAL; -- req->rq_reply_portal = LDLM_CANCEL_REPLY_PORTAL; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- memcpy(&body->lock_handle1, &lock->l_remote_handle, -- sizeof(body->lock_handle1)); -- -- req->rq_replen = lustre_msg_size(0, NULL); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- ptlrpc_req_finished(req); -- if (rc != ELDLM_OK) -- GOTO(out, rc); -- -- ldlm_lock_cancel(lock); -- } else { -- LDLM_DEBUG(lock, "client-side local cancel"); -- if (lock->l_resource->lr_namespace->ns_client) { -- CERROR("Trying to cancel local lock\n"); -- LBUG(); -- } -- ldlm_lock_cancel(lock); -- ldlm_reprocess_all(lock->l_resource); -- LDLM_DEBUG(lock, "client-side local cancel handler END"); -- } - - lock->l_flags |= LDLM_FL_CANCELING; -- -- EXIT; -- out: -- LDLM_LOCK_PUT(lock); -- return rc; --} -- --int ldlm_cancel_lru(struct ldlm_namespace *ns) --{ -- struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); -- int count, rc = 0; -- struct ldlm_ast_work *w; -- ENTRY; -- -- l_lock(&ns->ns_lock); -- count = ns->ns_nr_unused - ns->ns_max_unused; -- -- if (count <= 0) { -- l_unlock(&ns->ns_lock); -- RETURN(0); -- } -- -- list_for_each_safe(tmp, next, &ns->ns_unused_list) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_lru); -- -- LASSERT(!lock->l_readers && !lock->l_writers); -- -- /* Setting the CBPENDING flag is a little misleading, but -- * prevents an important race; namely, once CBPENDING is set, -- * the lock can accumulate no more readers/writers. Since -- * readers and writers are already zero here, ldlm_lock_decref -- * won't see this flag and call l_blocking_ast */ -- lock->l_flags |= LDLM_FL_CBPENDING; -- -- OBD_ALLOC(w, sizeof(*w)); -- LASSERT(w); -- -- w->w_lock = LDLM_LOCK_GET(lock); -- list_add(&w->w_list, &list); - list_del_init(&lock->l_lru); - ldlm_lock_remove_from_lru(lock); -- -- if (--count == 0) -- break; -- } -- l_unlock(&ns->ns_lock); -- -- list_for_each_safe(tmp, next, &list) { -- struct lustre_handle lockh; -- int rc; -- w = list_entry(tmp, struct ldlm_ast_work, w_list); -- -- ldlm_lock2handle(w->w_lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc != ELDLM_OK) -- CDEBUG(D_INFO, "ldlm_cli_cancel: %d\n", rc); -- -- list_del(&w->w_list); -- LDLM_LOCK_PUT(w->w_lock); -- OBD_FREE(w, sizeof(*w)); -- } -- -- RETURN(rc); --} -- --int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns, -- __u64 *res_id, int flags) --{ -- struct ldlm_resource *res; -- struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); -- struct ldlm_ast_work *w; -- ENTRY; - - if ((flags & LDLM_FL_REDUCE) && - ns->ns_max_unused > ns->ns_nr_unused) - RETURN(0); -- -- res = ldlm_resource_get(ns, NULL, res_id, 0, 0); -- if (res == NULL) { -- /* This is not a problem. */ -- CDEBUG(D_INFO, "No resource "LPU64"\n", res_id[0]); -- RETURN(0); -- } -- -- l_lock(&ns->ns_lock); -- list_for_each(tmp, &res->lr_granted) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- -- if (lock->l_readers || lock->l_writers) -- continue; -- -- /* See CBPENDING comment in ldlm_cancel_lru */ -- lock->l_flags |= LDLM_FL_CBPENDING; -- -- OBD_ALLOC(w, sizeof(*w)); -- LASSERT(w); -- -- w->w_lock = LDLM_LOCK_GET(lock); -- list_add(&w->w_list, &list); - if ((flags & LDLM_FL_REDUCE) && - ns->ns_max_unused > ns->ns_nr_unused) - break; -- } -- l_unlock(&ns->ns_lock); -- -- list_for_each_safe(tmp, next, &list) { -- struct lustre_handle lockh; -- int rc; -- w = list_entry(tmp, struct ldlm_ast_work, w_list); -- -- /* Prevent the cancel callback from being called by setting -- * LDLM_FL_CANCEL in the lock. Very sneaky. -p */ -- if (flags & LDLM_FL_NO_CALLBACK) -- w->w_lock->l_flags |= LDLM_FL_CANCEL; -- -- if (flags & LDLM_FL_LOCAL_ONLY) { -- ldlm_lock_cancel(w->w_lock); -- } else { -- ldlm_lock2handle(w->w_lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc != ELDLM_OK) -- CERROR("ldlm_cli_cancel: %d\n", rc); -- } -- list_del(&w->w_list); -- LDLM_LOCK_PUT(w->w_lock); -- OBD_FREE(w, sizeof(*w)); -- } -- - ldlm_resource_put(res); - ldlm_resource_putref(res); -- -- RETURN(0); --} -- --/* Cancel all locks on a namespace (or a specific resource, if given) that have -- * 0 readers/writers. -- * -- * If 'local_only' is true, throw the locks away without trying to notify the -- * server. */ --int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, __u64 *res_id, -- int flags) --{ -- int i; - ENTRY; -- -- if (res_id) -- RETURN(ldlm_cli_cancel_unused_resource(ns, res_id, flags)); -- -- l_lock(&ns->ns_lock); -- for (i = 0; i < RES_HASH_SIZE; i++) { -- struct list_head *tmp, *pos; -- list_for_each_safe(tmp, pos, &(ns->ns_hash[i])) { -- int rc; -- struct ldlm_resource *res; -- res = list_entry(tmp, struct ldlm_resource, lr_hash); -- ldlm_resource_getref(res); -- -- rc = ldlm_cli_cancel_unused_resource(ns, res->lr_name, -- flags); -- -- if (rc) -- CERROR("cancel_unused_res ("LPU64"): %d\n", -- res->lr_name[0], rc); - ldlm_resource_put(res); - ldlm_resource_putref(res); -- } -- } -- l_unlock(&ns->ns_lock); -- - return ELDLM_OK; - RETURN(ELDLM_OK); -} - -/* Lock iterators. */ - -int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter, - void *closure) -{ - struct list_head *tmp, *next; - struct ldlm_lock *lock; - int rc = LDLM_ITER_CONTINUE; - struct ldlm_namespace *ns = res->lr_namespace; - - ENTRY; - - if (!res) - RETURN(LDLM_ITER_CONTINUE); - - l_lock(&ns->ns_lock); - list_for_each_safe(tmp, next, &res->lr_granted) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - - list_for_each_safe(tmp, next, &res->lr_converting) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - - list_for_each_safe(tmp, next, &res->lr_waiting) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - - if (iter(lock, closure) == LDLM_ITER_STOP) - GOTO(out, rc = LDLM_ITER_STOP); - } - out: - l_unlock(&ns->ns_lock); - RETURN(rc); -} - -struct iter_helper_data { - ldlm_iterator_t iter; - void *closure; -}; - -static int ldlm_iter_helper(struct ldlm_lock *lock, void *closure) -{ - struct iter_helper_data *helper = closure; - return helper->iter(lock, helper->closure); -} - -int ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter, - void *closure) -{ - int i, rc = LDLM_ITER_CONTINUE; - struct iter_helper_data helper = { iter: iter, closure: closure }; - - l_lock(&ns->ns_lock); - for (i = 0; i < RES_HASH_SIZE; i++) { - struct list_head *tmp, *next; - list_for_each_safe(tmp, next, &(ns->ns_hash[i])) { - struct ldlm_resource *res = - list_entry(tmp, struct ldlm_resource, lr_hash); - - ldlm_resource_getref(res); - rc = ldlm_resource_foreach(res, ldlm_iter_helper, - &helper); - ldlm_resource_putref(res); - if (rc == LDLM_ITER_STOP) - GOTO(out, rc); - } - } - out: - l_unlock(&ns->ns_lock); - RETURN(rc); -} - -/* Lock replay */ - -static int ldlm_chain_lock_for_replay(struct ldlm_lock *lock, void *closure) -{ - struct list_head *list = closure; - - /* we use l_pending_chain here, because it's unused on clients. */ - list_add(&lock->l_pending_chain, list); - return LDLM_ITER_CONTINUE; -} - -static int replay_one_lock(struct obd_import *imp, struct ldlm_lock *lock, - int last) -{ - struct ptlrpc_request *req; - struct ldlm_request *body; - struct ldlm_reply *reply; - int rc, size; - int flags = LDLM_FL_REPLAY; - - flags |= lock->l_flags & - (LDLM_FL_BLOCK_GRANTED|LDLM_FL_BLOCK_CONV|LDLM_FL_BLOCK_WAIT); - - size = sizeof(*body); - req = ptlrpc_prep_req(imp, LDLM_ENQUEUE, 1, &size, NULL); - if (!req) - RETURN(-ENOMEM); - - body = lustre_msg_buf(req->rq_reqmsg, 0); - ldlm_lock2desc(lock, &body->lock_desc); - body->lock_flags = flags; - - ldlm_lock2handle(lock, &body->lock_handle1); - size = sizeof(*reply); - req->rq_replen = lustre_msg_size(1, &size); - - if (last) - req->rq_reqmsg->flags |= MSG_LAST_REPLAY; - - LDLM_DEBUG(lock, "replaying lock:"); - rc = ptlrpc_queue_wait(req); - if (rc != ELDLM_OK) - GOTO(out, rc); - - reply = lustre_msg_buf(req->rq_repmsg, 0); - memcpy(&lock->l_remote_handle, &reply->lock_handle, - sizeof(lock->l_remote_handle)); - LDLM_DEBUG(lock, "replayed lock:"); - out: - ptlrpc_req_finished(req); - RETURN(rc); -} - -int ldlm_replay_locks(struct obd_import *imp) -{ - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - struct list_head list, *pos, *next; - struct ldlm_lock *lock; - int rc = 0; - - ENTRY; - INIT_LIST_HEAD(&list); - - l_lock(&ns->ns_lock); - (void)ldlm_namespace_foreach(ns, ldlm_chain_lock_for_replay, &list); - - list_for_each_safe(pos, next, &list) { - lock = list_entry(pos, struct ldlm_lock, l_pending_chain); - rc = replay_one_lock(imp, lock, (next == &list)); - if (rc) - break; /* or try to do the rest? */ - } - l_unlock(&ns->ns_lock); - RETURN(rc); --} diff --cc lustre/ldlm/ldlm_resource.c index 53b835a,64ec591..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_resource.c +++ /dev/null @@@ -1,508 -1,522 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Cluster File Systems, Inc. -- */ -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include -- --kmem_cache_t *ldlm_resource_slab, *ldlm_lock_slab; -- --spinlock_t ldlm_namespace_lock = SPIN_LOCK_UNLOCKED; --struct list_head ldlm_namespace_list = LIST_HEAD_INIT(ldlm_namespace_list); --static struct proc_dir_entry *ldlm_ns_proc_dir = NULL; -- --int ldlm_proc_setup(struct obd_device *obd) --{ -- ENTRY; -- LASSERT(ldlm_ns_proc_dir == NULL); -- ldlm_ns_proc_dir=obd->obd_type->typ_procroot; -- RETURN(0); --} -- --void ldlm_proc_cleanup(struct obd_device *obd) --{ -- ldlm_ns_proc_dir = NULL; --} -- --#define MAX_STRING_SIZE 100 --void ldlm_proc_namespace(struct ldlm_namespace *ns) --{ -- struct lprocfs_vars lock_vars[2]; - char lock_names[MAX_STRING_SIZE]; - char lock_names[MAX_STRING_SIZE+1]; -- -- memset(lock_vars, 0, sizeof(lock_vars)); - snprintf(lock_names, MAX_STRING_SIZE, "%s/resource_count", - ns->ns_name); - snprintf(lock_names, MAX_STRING_SIZE, "%s/resource_count", ns->ns_name); -- lock_names[MAX_STRING_SIZE] = '\0'; -- lock_vars[0].name = lock_names; -- lock_vars[0].read_fptr = lprocfs_ll_rd; -- lock_vars[0].write_fptr = NULL; -- lock_vars[0].data = &ns->ns_resources; -- lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); -- -- memset(lock_vars, 0, sizeof(lock_vars)); -- snprintf(lock_names, MAX_STRING_SIZE, "%s/lock_count", ns->ns_name); -- lock_names[MAX_STRING_SIZE] = '\0'; -- lock_vars[0].name = lock_names; -- lock_vars[0].read_fptr = lprocfs_ll_rd; -- lock_vars[0].write_fptr = NULL; -- lock_vars[0].data = &ns->ns_locks; -- lprocfs_add_vars(ldlm_ns_proc_dir, lock_vars, 0); -- --} --#undef MAX_STRING_SIZE -- --#define LDLM_MAX_UNUSED 20 --struct ldlm_namespace *ldlm_namespace_new(char *name, __u32 client) --{ -- struct ldlm_namespace *ns = NULL; -- struct list_head *bucket; - - - ENTRY; -- -- OBD_ALLOC(ns, sizeof(*ns)); -- if (!ns) { -- LBUG(); -- GOTO(out, NULL); -- } -- -- ns->ns_hash = vmalloc(sizeof(*ns->ns_hash) * RES_HASH_SIZE); -- if (!ns->ns_hash) { -- LBUG(); -- GOTO(out, ns); -- } -- obd_memory += sizeof(*ns->ns_hash) * RES_HASH_SIZE; -- -- OBD_ALLOC(ns->ns_name, strlen(name) + 1); -- if (!ns->ns_name) { -- LBUG(); -- GOTO(out, ns); -- } -- strcpy(ns->ns_name, name); -- -- INIT_LIST_HEAD(&ns->ns_root_list); -- l_lock_init(&ns->ns_lock); -- ns->ns_refcount = 0; -- ns->ns_client = client; -- spin_lock_init(&ns->ns_counter_lock); -- ns->ns_locks = 0; -- ns->ns_resources = 0; -- -- for (bucket = ns->ns_hash + RES_HASH_SIZE - 1; bucket >= ns->ns_hash; -- bucket--) -- INIT_LIST_HEAD(bucket); -- -- INIT_LIST_HEAD(&ns->ns_unused_list); -- ns->ns_nr_unused = 0; -- ns->ns_max_unused = LDLM_MAX_UNUSED; -- -- spin_lock(&ldlm_namespace_lock); -- list_add(&ns->ns_list_chain, &ldlm_namespace_list); -- spin_unlock(&ldlm_namespace_lock); -- ldlm_proc_namespace(ns); -- RETURN(ns); -- -- out: -- if (ns && ns->ns_hash) { - memset(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); -- vfree(ns->ns_hash); -- obd_memory -= sizeof(*ns->ns_hash) * RES_HASH_SIZE; -- } -- if (ns && ns->ns_name) -- OBD_FREE(ns->ns_name, strlen(name) + 1); -- if (ns) -- OBD_FREE(ns, sizeof(*ns)); -- return NULL; --} -- --extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); -- --/* If 'local_only' is true, don't try to tell the server, just cleanup. */ --static void cleanup_resource(struct ldlm_resource *res, struct list_head *q, -- int local_only) --{ -- struct list_head *tmp, *pos; -- int rc = 0, client = res->lr_namespace->ns_client; -- ENTRY; -- -- list_for_each_safe(tmp, pos, q) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- LDLM_LOCK_GET(lock); -- -- /* At shutdown time, don't call the cancellation callback */ -- lock->l_flags |= LDLM_FL_CANCEL; -- -- if (client) { -- struct lustre_handle lockh; -- ldlm_lock2handle(lock, &lockh); -- if (!local_only) { -- rc = ldlm_cli_cancel(&lockh); -- if (rc) -- CERROR("ldlm_cli_cancel: %d\n", rc); -- } -- /* Force local cleanup on errors, too. */ -- if (local_only || rc != ELDLM_OK) -- ldlm_lock_cancel(lock); -- } else { -- LDLM_DEBUG(lock, "Freeing a lock still held by a " -- "client node.\n"); -- -- ldlm_resource_unlink_lock(lock); -- ldlm_lock_destroy(lock); -- } -- LDLM_LOCK_PUT(lock); -- } --} -- --int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only) --{ -- int i; -- -- l_lock(&ns->ns_lock); -- for (i = 0; i < RES_HASH_SIZE; i++) { -- struct list_head *tmp, *pos; -- list_for_each_safe(tmp, pos, &(ns->ns_hash[i])) { -- struct ldlm_resource *res; -- res = list_entry(tmp, struct ldlm_resource, lr_hash); -- ldlm_resource_getref(res); -- -- cleanup_resource(res, &res->lr_granted, local_only); -- cleanup_resource(res, &res->lr_converting, local_only); -- cleanup_resource(res, &res->lr_waiting, local_only); -- - /* XXX this is a bit counter-intuitive and should - * probably be cleaner: don't force cleanup if we're - * local_only (which is only used by recovery). We - * probably still have outstanding lock refs which - * reference these resources. -phil */ - if (!ldlm_resource_put(res) && !local_only) { - /* XXX what a mess: don't force cleanup if we're - * local_only (which is only used by recovery). In that - * case, we probably still have outstanding lock refs - * which reference these resources. -phil */ - if (!ldlm_resource_putref(res) && !local_only) { -- CERROR("Resource refcount nonzero (%d) after " -- "lock cleanup; forcing cleanup.\n", -- atomic_read(&res->lr_refcount)); -- ldlm_resource_dump(res); -- atomic_set(&res->lr_refcount, 1); - ldlm_resource_put(res); - ldlm_resource_putref(res); -- } -- } -- } -- l_unlock(&ns->ns_lock); -- -- return ELDLM_OK; --} -- --/* Cleanup, but also free, the namespace */ --int ldlm_namespace_free(struct ldlm_namespace *ns) --{ -- if (!ns) -- RETURN(ELDLM_OK); -- -- spin_lock(&ldlm_namespace_lock); -- list_del(&ns->ns_list_chain); -- -- spin_unlock(&ldlm_namespace_lock); -- -- ldlm_namespace_cleanup(ns, 0); -- - memset(ns->ns_hash, 0x5a, sizeof(*ns->ns_hash) * RES_HASH_SIZE); -- vfree(ns->ns_hash /* , sizeof(*ns->ns_hash) * RES_HASH_SIZE */); -- obd_memory -= sizeof(*ns->ns_hash) * RES_HASH_SIZE; -- OBD_FREE(ns->ns_name, strlen(ns->ns_name) + 1); -- OBD_FREE(ns, sizeof(*ns)); -- -- return ELDLM_OK; --} -- --int ldlm_client_free(struct obd_export *exp) --{ -- struct ldlm_export_data *led = &exp->exp_ldlm_data; -- ptlrpc_cleanup_client(&led->led_import); -- RETURN(0); --} -- --static __u32 ldlm_hash_fn(struct ldlm_resource *parent, __u64 *name) --{ -- __u32 hash = 0; -- int i; -- -- for (i = 0; i < RES_NAME_SIZE; i++) -- hash += name[i]; -- -- hash += (__u32)((unsigned long)parent >> 4); -- -- return (hash & RES_HASH_MASK); --} -- --static struct ldlm_resource *ldlm_resource_new(void) --{ -- struct ldlm_resource *res; -- -- res = kmem_cache_alloc(ldlm_resource_slab, SLAB_KERNEL); -- if (res == NULL) { -- LBUG(); -- return NULL; -- } -- memset(res, 0, sizeof(*res)); -- -- INIT_LIST_HEAD(&res->lr_children); -- INIT_LIST_HEAD(&res->lr_childof); -- INIT_LIST_HEAD(&res->lr_granted); -- INIT_LIST_HEAD(&res->lr_converting); -- INIT_LIST_HEAD(&res->lr_waiting); -- -- atomic_set(&res->lr_refcount, 1); -- -- return res; --} -- --/* Args: locked namespace -- * Returns: newly-allocated, referenced, unlocked resource */ --static struct ldlm_resource *ldlm_resource_add(struct ldlm_namespace *ns, -- struct ldlm_resource *parent, -- __u64 *name, __u32 type) --{ -- struct list_head *bucket; -- struct ldlm_resource *res; -- ENTRY; -- -- if (type < LDLM_MIN_TYPE || type > LDLM_MAX_TYPE) { -- LBUG(); -- RETURN(NULL); -- } -- -- res = ldlm_resource_new(); -- if (!res) { -- LBUG(); -- RETURN(NULL); -- } -- -- spin_lock(&ns->ns_counter_lock); -- ns->ns_resources++; -- spin_unlock(&ns->ns_counter_lock); -- - l_lock(&ns->ns_lock); -- memcpy(res->lr_name, name, sizeof(res->lr_name)); -- res->lr_namespace = ns; -- ns->ns_refcount++; -- -- res->lr_type = type; -- res->lr_most_restr = LCK_NL; -- -- bucket = ns->ns_hash + ldlm_hash_fn(parent, name); -- list_add(&res->lr_hash, bucket); -- - if (parent == NULL) - if (parent == NULL) { -- list_add(&res->lr_childof, &ns->ns_root_list); - else { - } else { -- res->lr_parent = parent; -- list_add(&res->lr_childof, &parent->lr_children); -- } - l_unlock(&ns->ns_lock); -- -- RETURN(res); --} -- --/* Args: unlocked namespace -- * Locks: takes and releases ns->ns_lock and res->lr_lock -- * Returns: referenced, unlocked ldlm_resource or NULL */ --struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, -- struct ldlm_resource *parent, -- __u64 *name, __u32 type, int create) --{ -- struct list_head *bucket; -- struct list_head *tmp = bucket; -- struct ldlm_resource *res = NULL; -- ENTRY; -- -- if (ns == NULL || ns->ns_hash == NULL) { -- LBUG(); -- RETURN(NULL); -- } -- -- l_lock(&ns->ns_lock); -- bucket = ns->ns_hash + ldlm_hash_fn(parent, name); -- -- list_for_each(tmp, bucket) { -- struct ldlm_resource *chk; -- chk = list_entry(tmp, struct ldlm_resource, lr_hash); -- -- if (memcmp(chk->lr_name, name, sizeof(chk->lr_name)) == 0) { -- res = chk; -- atomic_inc(&res->lr_refcount); - EXIT; - break; - l_unlock(&ns->ns_lock); - RETURN(res); -- } -- } -- - if (res == NULL && create) - if (create) -- res = ldlm_resource_add(ns, parent, name, type); -- l_unlock(&ns->ns_lock); -- -- RETURN(res); --} -- --struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res) --{ -- atomic_inc(&res->lr_refcount); - CDEBUG(D_INFO, "getref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); -- return res; --} -- --/* Returns 1 if the resource was freed, 0 if it remains. */ - int ldlm_resource_put(struct ldlm_resource *res) -int ldlm_resource_putref(struct ldlm_resource *res) --{ -- int rc = 0; -- -- if (atomic_dec_and_test(&res->lr_refcount)) { -- struct ldlm_namespace *ns = res->lr_namespace; -- ENTRY; - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); -- -- l_lock(&ns->ns_lock); -- -- if (atomic_read(&res->lr_refcount) != 0) { -- /* We lost the race. */ -- l_unlock(&ns->ns_lock); - goto out; - RETURN(rc); -- } -- - if (!list_empty(&res->lr_granted)) - if (!list_empty(&res->lr_granted)) { - ldlm_resource_dump(res); -- LBUG(); - } -- - if (!list_empty(&res->lr_converting)) - if (!list_empty(&res->lr_converting)) { - ldlm_resource_dump(res); -- LBUG(); - } -- - if (!list_empty(&res->lr_waiting)) - if (!list_empty(&res->lr_waiting)) { - ldlm_resource_dump(res); -- LBUG(); - } -- - if (!list_empty(&res->lr_children)) - if (!list_empty(&res->lr_children)) { - ldlm_resource_dump(res); -- LBUG(); - } -- -- ns->ns_refcount--; -- list_del(&res->lr_hash); -- list_del(&res->lr_childof); -- - memset(res, 0x5a, sizeof(*res)); -- kmem_cache_free(ldlm_resource_slab, res); -- l_unlock(&ns->ns_lock); -- -- spin_lock(&ns->ns_counter_lock); -- ns->ns_resources--; -- spin_unlock(&ns->ns_counter_lock); -- -- rc = 1; -- } else { -- ENTRY; - CDEBUG(D_INFO, "putref res: %p count: %d\n", res, - atomic_read(&res->lr_refcount)); -- out: - if (atomic_read(&res->lr_refcount) < 0) - LBUG(); - LASSERT(atomic_read(&res->lr_refcount) >= 0); -- } -- -- RETURN(rc); --} -- --void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head, -- struct ldlm_lock *lock) --{ -- l_lock(&res->lr_namespace->ns_lock); -- -- ldlm_resource_dump(res); -- ldlm_lock_dump(lock); -- - if (!list_empty(&lock->l_res_link)) - LBUG(); - LASSERT(list_empty(&lock->l_res_link)); -- -- list_add(&lock->l_res_link, head); -- l_unlock(&res->lr_namespace->ns_lock); --} -- --void ldlm_resource_unlink_lock(struct ldlm_lock *lock) --{ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- list_del_init(&lock->l_res_link); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); --} -- --void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc) --{ -- desc->lr_type = res->lr_type; -- memcpy(desc->lr_name, res->lr_name, sizeof(desc->lr_name)); -- memcpy(desc->lr_version, res->lr_version, sizeof(desc->lr_version)); --} -- --void ldlm_dump_all_namespaces(void) --{ -- struct list_head *tmp; -- -- spin_lock(&ldlm_namespace_lock); -- -- list_for_each(tmp, &ldlm_namespace_list) { -- struct ldlm_namespace *ns; -- ns = list_entry(tmp, struct ldlm_namespace, ns_list_chain); -- ldlm_namespace_dump(ns); -- } -- -- spin_unlock(&ldlm_namespace_lock); --} -- --void ldlm_namespace_dump(struct ldlm_namespace *ns) --{ -- struct list_head *tmp; -- -- l_lock(&ns->ns_lock); -- CDEBUG(D_OTHER, "--- Namespace: %s (rc: %d, client: %d)\n", ns->ns_name, -- ns->ns_refcount, ns->ns_client); -- -- list_for_each(tmp, &ns->ns_root_list) { -- struct ldlm_resource *res; -- res = list_entry(tmp, struct ldlm_resource, lr_childof); -- -- /* Once we have resources with children, this should really dump -- * them recursively. */ -- ldlm_resource_dump(res); -- } -- l_unlock(&ns->ns_lock); --} -- --void ldlm_resource_dump(struct ldlm_resource *res) --{ -- struct list_head *tmp; -- char name[256]; -- -- if (RES_NAME_SIZE != 3) -- LBUG(); -- -- snprintf(name, sizeof(name), "%Lx %Lx %Lx", -- (unsigned long long)res->lr_name[0], -- (unsigned long long)res->lr_name[1], -- (unsigned long long)res->lr_name[2]); -- -- CDEBUG(D_OTHER, "--- Resource: %p (%s) (rc: %d)\n", res, name, -- atomic_read(&res->lr_refcount)); -- CDEBUG(D_OTHER, "Namespace: %p (%s)\n", res->lr_namespace, -- res->lr_namespace->ns_name); -- CDEBUG(D_OTHER, "Parent: %p, root: %p\n", res->lr_parent, res->lr_root); -- -- CDEBUG(D_OTHER, "Granted locks:\n"); -- list_for_each(tmp, &res->lr_granted) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- ldlm_lock_dump(lock); -- } -- -- CDEBUG(D_OTHER, "Converting locks:\n"); -- list_for_each(tmp, &res->lr_converting) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- ldlm_lock_dump(lock); -- } -- -- CDEBUG(D_OTHER, "Waiting locks:\n"); -- list_for_each(tmp, &res->lr_waiting) { -- struct ldlm_lock *lock; -- lock = list_entry(tmp, struct ldlm_lock, l_res_link); -- ldlm_lock_dump(lock); -- } --} diff --cc lustre/ldlm/ldlm_test.c index ce7a73d,ce7a73d..0000000 deleted file mode 100644,100644 --- a/lustre/ldlm/ldlm_test.c +++ /dev/null @@@ -1,646 -1,646 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (c) 2002 Cluster File Systems, Inc. -- * Copyright (c) 2002 Lawrence Livermore National Laboratory -- * Author: James Newsome -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define DEBUG_SUBSYSTEM S_LDLM -- --#include --#include --#include -- --#include --#include -- --struct ldlm_test_thread { -- struct obd_device *obddev; -- struct ldlm_namespace *t_ns; -- struct list_head t_link; -- __u32 t_flags; -- wait_queue_head_t t_ctl_waitq; --}; -- --struct ldlm_test_lock { -- struct list_head l_link; -- struct lustre_handle l_lockh; --}; -- --static unsigned int max_locks; --static unsigned int num_resources; --static unsigned int num_extents; -- --static spinlock_t ctl_lock = SPIN_LOCK_UNLOCKED; --/* protect these with the ctl_lock */ --static LIST_HEAD(ctl_threads); --static int regression_running = 0; --static LIST_HEAD(lock_list); --static int num_locks = 0; -- --/* cumulative stats for regression test */ --static atomic_t locks_requested = ATOMIC_INIT(0); --static atomic_t converts_requested = ATOMIC_INIT(0); --static atomic_t locks_granted = ATOMIC_INIT(0); --static atomic_t locks_matched = ATOMIC_INIT(0); -- --/* making this a global avoids the problem of having pointers -- * to garbage after the test exits. -- */ --static struct lustre_handle regress_connh; -- --static int ldlm_do_decrement(void); --static int ldlm_do_enqueue(struct ldlm_test_thread *thread); --static int ldlm_do_convert(void); -- --/* -- * blocking ast for regression test. -- * Just cancels lock -- */ --static int ldlm_test_blocking_ast(struct ldlm_lock *lock, -- struct ldlm_lock_desc *new, -- void *data, __u32 data_len, int flag) --{ -- int rc; -- struct lustre_handle lockh; -- ENTRY; -- -- switch (flag) { -- case LDLM_CB_BLOCKING: -- LDLM_DEBUG(lock, "We're blocking. Cancelling lock"); -- ldlm_lock2handle(lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc < 0) { -- CERROR("ldlm_cli_cancel: %d\n", rc); -- LBUG(); -- } -- break; -- case LDLM_CB_CANCELING: -- LDLM_DEBUG(lock, "this lock is being cancelled"); -- break; -- default: -- LBUG(); -- } -- -- RETURN(0); --} -- --/* blocking ast for basic tests. noop */ --static int ldlm_blocking_ast(struct ldlm_lock *lock, -- struct ldlm_lock_desc *new, -- void *data, __u32 data_len, int flag) --{ -- ENTRY; -- CERROR("ldlm_blocking_ast: lock=%p, new=%p, flag=%d\n", lock, new, -- flag); -- RETURN(0); --} -- --/* Completion ast for regression test. -- * Does not sleep when blocked. -- */ --static int ldlm_test_completion_ast(struct ldlm_lock *lock, int flags) --{ -- struct ldlm_test_lock *lock_info; -- ENTRY; -- -- if (flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | -- LDLM_FL_BLOCK_CONV)) { -- LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock"); -- RETURN(0); -- } -- -- if (lock->l_granted_mode != lock->l_req_mode) -- CERROR("completion ast called with non-granted lock\n"); -- -- /* add to list of granted locks */ -- -- if (flags & LDLM_FL_WAIT_NOREPROC) { -- atomic_inc(&locks_matched); -- LDLM_DEBUG(lock, "lock matched"); -- } else { -- atomic_inc(&locks_granted); -- LDLM_DEBUG(lock, "lock granted"); -- } -- -- OBD_ALLOC(lock_info, sizeof(*lock_info)); -- if (lock_info == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- -- ldlm_lock2handle(lock, &lock_info->l_lockh); -- -- spin_lock(&ctl_lock); -- list_add_tail(&lock_info->l_link, &lock_list); -- num_locks++; -- spin_unlock(&ctl_lock); -- -- RETURN(0); --} -- --int ldlm_test_basics(struct obd_device *obddev) --{ -- struct ldlm_namespace *ns; -- struct ldlm_resource *res; -- __u64 res_id[RES_NAME_SIZE] = {1, 2, 3}; -- ldlm_error_t err; -- struct ldlm_lock *lock1, *lock; -- int flags; -- ENTRY; -- -- ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER); -- if (ns == NULL) -- LBUG(); -- -- lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_CR, NULL, 0); -- if (lock1 == NULL) -- LBUG(); -- err = ldlm_lock_enqueue(lock1, NULL, 0, &flags, -- ldlm_completion_ast, ldlm_blocking_ast); -- if (err != ELDLM_OK) -- LBUG(); -- -- lock = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_EX, NULL, 0); -- if (lock == NULL) -- LBUG(); -- err = ldlm_lock_enqueue(lock, NULL, 0, &flags, -- ldlm_completion_ast, ldlm_blocking_ast); -- if (err != ELDLM_OK) -- LBUG(); -- if (!(flags & LDLM_FL_BLOCK_GRANTED)) -- LBUG(); -- -- res = ldlm_resource_get(ns, NULL, res_id, LDLM_PLAIN, 1); -- if (res == NULL) -- LBUG(); -- ldlm_resource_dump(res); -- -- res = ldlm_lock_convert(lock1, LCK_NL, &flags); -- if (res != NULL) -- ldlm_reprocess_all(res); -- -- ldlm_resource_dump(res); -- ldlm_namespace_free(ns); -- -- RETURN(0); --} -- --int ldlm_test_extents(struct obd_device *obddev) --{ -- struct ldlm_namespace *ns; -- struct ldlm_resource *res; -- struct ldlm_lock *lock, *lock1, *lock2; -- __u64 res_id[RES_NAME_SIZE] = {0, 0, 0}; -- struct ldlm_extent ext1 = {4, 6}, ext2 = {6, 9}, ext3 = {10, 11}; -- ldlm_error_t err; -- int flags; -- ENTRY; -- -- ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER); -- if (ns == NULL) -- LBUG(); -- -- flags = 0; -- lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, NULL, -- 0); -- if (lock1 == NULL) -- LBUG(); -- err = ldlm_lock_enqueue(lock1, &ext1, sizeof(ext1), &flags, NULL, NULL); -- if (err != ELDLM_OK) -- LBUG(); -- if (!(flags & LDLM_FL_LOCK_CHANGED)) -- LBUG(); -- -- flags = 0; -- lock2 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, -- NULL, 0); -- err = ldlm_lock_enqueue(lock2, &ext2, sizeof(ext2), &flags, NULL, NULL); -- if (err != ELDLM_OK) -- LBUG(); -- if (!(flags & LDLM_FL_LOCK_CHANGED)) -- LBUG(); -- -- flags = 0; -- lock = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_EX, NULL, 0); -- if (lock == NULL) -- LBUG(); -- err = ldlm_lock_enqueue(lock, &ext3, sizeof(ext3), &flags, -- NULL, NULL); -- if (err != ELDLM_OK) -- LBUG(); -- if (!(flags & LDLM_FL_BLOCK_GRANTED)) -- LBUG(); -- if (flags & LDLM_FL_LOCK_CHANGED) -- LBUG(); -- -- /* Convert/cancel blocking locks */ -- flags = 0; -- res = ldlm_lock_convert(lock1, LCK_NL, &flags); -- if (res != NULL) -- ldlm_reprocess_all(res); -- -- ldlm_lock_cancel(lock2); -- if (res != NULL) -- ldlm_reprocess_all(res); -- -- /* Dump the results */ -- res = ldlm_resource_get(ns, NULL, res_id, LDLM_EXTENT, 0); -- if (res == NULL) -- LBUG(); -- ldlm_resource_dump(res); -- ldlm_namespace_free(ns); -- -- RETURN(0); --} -- --static int ldlm_test_network(struct obd_device *obddev, -- struct lustre_handle *connh) --{ -- -- __u64 res_id[RES_NAME_SIZE] = {1, 2, 3}; -- struct ldlm_extent ext = {4, 6}; -- struct lustre_handle lockh1; -- struct ldlm_lock *lock; -- int flags = 0; -- ldlm_error_t err; -- ENTRY; -- -- err = ldlm_cli_enqueue(connh, NULL, obddev->obd_namespace, NULL, res_id, -- LDLM_EXTENT, &ext, sizeof(ext), LCK_PR, &flags, -- ldlm_completion_ast, NULL, NULL, 0, &lockh1); -- -- CERROR("ldlm_cli_enqueue: %d\n", err); -- -- flags = 0; -- err = ldlm_cli_convert(&lockh1, LCK_EX, &flags); -- CERROR("ldlm_cli_convert: %d\n", err); -- -- lock = ldlm_handle2lock(&lockh1); -- ldlm_lock_dump(lock); -- ldlm_lock_put(lock); -- -- /* Need to decrement old mode. Don't bother incrementing new -- * mode since the test is done. -- */ -- if (err == ELDLM_OK) -- ldlm_lock_decref(&lockh1, LCK_PR); -- -- RETURN(err); --} -- --static int ldlm_do_decrement(void) --{ -- struct ldlm_test_lock *lock_info; -- struct ldlm_lock *lock; -- int rc = 0; -- ENTRY; -- -- spin_lock(&ctl_lock); -- if(list_empty(&lock_list)) { -- CERROR("lock_list is empty\n"); -- spin_unlock(&ctl_lock); -- RETURN(0); -- } -- -- /* delete from list */ -- lock_info = list_entry(lock_list.next, -- struct ldlm_test_lock, l_link); -- list_del(lock_list.next); -- num_locks--; -- spin_unlock(&ctl_lock); -- -- /* decrement and free the info */ -- lock = ldlm_handle2lock(&lock_info->l_lockh); -- ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); -- ldlm_lock_put(lock); -- -- OBD_FREE(lock_info, sizeof(*lock_info)); -- -- RETURN(rc); --} -- --static int ldlm_do_enqueue(struct ldlm_test_thread *thread) --{ -- struct lustre_handle lockh; -- __u64 res_id[3] = {0}; -- __u32 lock_mode; -- struct ldlm_extent ext; -- unsigned char random; -- int flags = 0, rc = 0; -- ENTRY; -- -- /* Pick a random resource from 1 to num_resources */ -- get_random_bytes(&random, sizeof(random)); -- res_id[0] = random % num_resources; -- -- /* Pick a random lock mode */ -- get_random_bytes(&random, sizeof(random)); -- lock_mode = random % LCK_NL + 1; -- -- /* Pick a random extent */ -- get_random_bytes(&random, sizeof(random)); -- ext.start = random % num_extents; -- get_random_bytes(&random, sizeof(random)); -- ext.end = random % -- (num_extents - (int)ext.start) + ext.start; -- -- LDLM_DEBUG_NOLOCK("about to enqueue with resource "LPX64", mode %d," -- " extent "LPX64" -> "LPX64, res_id[0], lock_mode, -- ext.start, ext.end); -- -- rc = ldlm_match_or_enqueue(®ress_connh, NULL, -- thread->obddev->obd_namespace, -- NULL, res_id, LDLM_EXTENT, &ext, -- sizeof(ext), lock_mode, &flags, -- ldlm_test_completion_ast, -- ldlm_test_blocking_ast, -- NULL, 0, &lockh); -- -- atomic_inc(&locks_requested); -- -- if (rc < 0) { -- CERROR("ldlm_cli_enqueue: %d\n", rc); -- LBUG(); -- } -- -- RETURN(rc); --} -- --static int ldlm_do_convert(void) --{ -- __u32 lock_mode; -- unsigned char random; -- int flags = 0, rc = 0; -- struct ldlm_test_lock *lock_info; -- struct ldlm_lock *lock; -- ENTRY; -- -- /* delete from list */ -- spin_lock(&ctl_lock); -- lock_info = list_entry(lock_list.next, struct ldlm_test_lock, l_link); -- list_del(lock_list.next); -- num_locks--; -- spin_unlock(&ctl_lock); -- -- /* Pick a random lock mode */ -- get_random_bytes(&random, sizeof(random)); -- lock_mode = random % LCK_NL + 1; -- -- /* do the conversion */ -- rc = ldlm_cli_convert(&lock_info->l_lockh , lock_mode, &flags); -- atomic_inc(&converts_requested); -- -- if (rc < 0) { -- CERROR("ldlm_cli_convert: %d\n", rc); -- LBUG(); -- } -- -- /* -- * Adjust reference counts. -- * FIXME: This is technically a bit... wrong, -- * since we don't know when/if the convert succeeded -- */ -- ldlm_lock_addref(&lock_info->l_lockh, lock_mode); -- lock = ldlm_handle2lock(&lock_info->l_lockh); -- ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); -- ldlm_lock_put(lock); -- -- OBD_FREE(lock_info, sizeof(*lock_info)); -- -- RETURN(rc); --} -- -- -- --static int ldlm_test_main(void *data) --{ -- struct ldlm_test_thread *thread = data; -- ENTRY; -- -- lock_kernel(); -- daemonize(); --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -- sigfillset(¤t->blocked); -- recalc_sigpending(); --#else -- spin_lock_irq(¤t->sigmask_lock); -- sigfillset(¤t->blocked); -- recalc_sigpending(current); -- spin_unlock_irq(¤t->sigmask_lock); --#endif -- -- sprintf(current->comm, "ldlm_test"); -- unlock_kernel(); -- -- /* Record that the thread is running */ -- thread->t_flags |= SVC_RUNNING; -- wake_up(&thread->t_ctl_waitq); -- -- while (!(thread->t_flags & SVC_STOPPING)) { -- unsigned char random; -- unsigned char dec_chance, con_chance; -- unsigned char chance_left = 100; -- -- spin_lock(&ctl_lock); -- /* probability of decrementing increases linearly -- * as more locks are held. -- */ -- dec_chance = chance_left * num_locks / max_locks; -- chance_left -= dec_chance; -- -- /* FIXME: conversions temporarily disabled -- * until they are working correctly. -- */ -- /* con_chance = chance_left * num_locks / max_locks; */ -- con_chance = 0; -- chance_left -= con_chance; -- spin_unlock(&ctl_lock); -- -- get_random_bytes(&random, sizeof(random)); -- -- random = random % 100; -- if (random < dec_chance) -- ldlm_do_decrement(); -- else if (random < (dec_chance + con_chance)) -- ldlm_do_convert(); -- else -- ldlm_do_enqueue(thread); -- -- LDLM_DEBUG_NOLOCK("locks requested: %d, " -- "conversions requested %d", -- atomic_read(&locks_requested), -- atomic_read(&converts_requested)); -- LDLM_DEBUG_NOLOCK("locks granted: %d, " -- "locks matched: %d", -- atomic_read(&locks_granted), -- atomic_read(&locks_matched)); -- -- spin_lock(&ctl_lock); -- LDLM_DEBUG_NOLOCK("lock references currently held: %d, ", -- num_locks); -- spin_unlock(&ctl_lock); -- -- /* -- * We don't sleep after a lock being blocked, so let's -- * make sure other things can run. -- */ -- schedule(); -- } -- -- thread->t_flags |= SVC_STOPPED; -- wake_up(&thread->t_ctl_waitq); -- -- RETURN(0); --} -- --static int ldlm_start_thread(struct obd_device *obddev, -- struct lustre_handle *connh) --{ -- struct ldlm_test_thread *test; -- int rc; -- ENTRY; -- -- OBD_ALLOC(test, sizeof(*test)); -- if (test == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- init_waitqueue_head(&test->t_ctl_waitq); -- -- test->obddev = obddev; -- -- spin_lock(&ctl_lock); -- list_add(&test->t_link, &ctl_threads); -- spin_unlock(&ctl_lock); -- -- rc = kernel_thread(ldlm_test_main, (void *)test, -- CLONE_VM | CLONE_FS | CLONE_FILES); -- if (rc < 0) { -- CERROR("cannot start thread\n"); -- RETURN(-EINVAL); -- } -- wait_event(test->t_ctl_waitq, test->t_flags & SVC_RUNNING); -- -- RETURN(0); --} -- --int ldlm_regression_start(struct obd_device *obddev, -- struct lustre_handle *connh, -- unsigned int threads, unsigned int max_locks_in, -- unsigned int num_resources_in, -- unsigned int num_extents_in) --{ -- int i, rc = 0; -- ENTRY; -- -- spin_lock(&ctl_lock); -- if (regression_running) { -- CERROR("You can't start the ldlm regression twice.\n"); -- spin_unlock(&ctl_lock); -- RETURN(-EINVAL); -- } -- regression_running = 1; -- spin_unlock(&ctl_lock); -- -- regress_connh = *connh; -- max_locks = max_locks_in; -- num_resources = num_resources_in; -- num_extents = num_extents_in; -- -- LDLM_DEBUG_NOLOCK("regression test started: threads: %d, max_locks: " -- "%d, num_res: %d, num_ext: %d\n", -- threads, max_locks_in, num_resources_in, -- num_extents_in); -- -- for (i = 0; i < threads; i++) { -- rc = ldlm_start_thread(obddev, connh); -- if (rc < 0) -- GOTO(cleanup, rc); -- } -- -- cleanup: -- if (rc < 0) -- ldlm_regression_stop(); -- RETURN(rc); --} -- --int ldlm_regression_stop(void) --{ -- ENTRY; -- -- spin_lock(&ctl_lock); -- if (!regression_running) { -- CERROR("The ldlm regression isn't started.\n"); -- spin_unlock(&ctl_lock); -- RETURN(-EINVAL); -- } -- -- while (!list_empty(&ctl_threads)) { -- struct ldlm_test_thread *thread; -- thread = list_entry(ctl_threads.next, struct ldlm_test_thread, -- t_link); -- -- thread->t_flags |= SVC_STOPPING; -- -- spin_unlock(&ctl_lock); -- wake_up(&thread->t_ctl_waitq); -- wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED); -- spin_lock(&ctl_lock); -- -- list_del(&thread->t_link); -- OBD_FREE(thread, sizeof(*thread)); -- } -- -- /* decrement all held locks */ -- while (!list_empty(&lock_list)) { -- struct ldlm_lock *lock; -- struct ldlm_test_lock *lock_info = -- list_entry(lock_list.next, struct ldlm_test_lock, -- l_link); -- list_del(lock_list.next); -- num_locks--; -- -- lock = ldlm_handle2lock(&lock_info->l_lockh); -- ldlm_lock_decref(&lock_info->l_lockh, lock->l_granted_mode); -- ldlm_lock_put(lock); -- -- OBD_FREE(lock_info, sizeof(*lock_info)); -- } -- -- regression_running = 0; -- spin_unlock(&ctl_lock); -- -- RETURN(0); --} -- --int ldlm_test(struct obd_device *obddev, struct lustre_handle *connh) --{ -- int rc; -- rc = ldlm_test_basics(obddev); -- if (rc) -- RETURN(rc); -- -- rc = ldlm_test_extents(obddev); -- if (rc) -- RETURN(rc); -- -- rc = ldlm_test_network(obddev, connh); -- RETURN(rc); --} diff --cc lustre/lib/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/lib/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/lib/Makefile.am index 0887dbc,da31808..0000000 deleted file mode 100644,100644 --- a/lustre/lib/Makefile.am +++ /dev/null @@@ -1,4 -1,4 +1,0 @@@ --EXTRA_DIST = mds_updates.c obd_pack.c ll_pack.c simple.c - EXTRA_DIST += client.c target.c lov_pack.c -EXTRA_DIST += client.c target.c -- --include $(top_srcdir)/Rules diff --cc lustre/lib/client.c index f070f63,c75b399..0000000 deleted file mode 100644,100644 --- a/lustre/lib/client.c +++ /dev/null @@@ -1,237 -1,267 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * Author: Peter J. Braam -- * Author: Phil Schwan -- * Author: Mike Shaver -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Client-common OBD method implementations and utility functions. -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_OST /* XXX WRONG */ -- --#include --#include --#include --#include -- --struct client_obd *client_conn2cli(struct lustre_handle *conn) --{ -- struct obd_export *export = class_conn2export(conn); -- if (!export) -- LBUG(); -- return &export->exp_obd->u.cli; --} -- --int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- struct obd_ioctl_data* data = buf; -- int rq_portal, rp_portal; -- char *name; -- struct client_obd *cli = &obddev->u.cli; - struct obd_import *imp = &cli->cl_import; -- obd_uuid_t server_uuid; -- ENTRY; -- -- if (obddev->obd_type->typ_ops->o_brw) { -- rq_portal = OST_REQUEST_PORTAL; -- rp_portal = OSC_REPLY_PORTAL; -- name = "osc"; -- } else { -- rq_portal = MDS_REQUEST_PORTAL; -- rp_portal = MDC_REPLY_PORTAL; -- name = "mdc"; -- } -- -- if (data->ioc_inllen1 < 1) { -- CERROR("requires a TARGET UUID\n"); -- RETURN(-EINVAL); -- } -- -- if (data->ioc_inllen1 > 37) { -- CERROR("client UUID must be less than 38 characters\n"); -- RETURN(-EINVAL); -- } -- -- if (data->ioc_inllen2 < 1) { -- CERROR("setup requires a SERVER UUID\n"); -- RETURN(-EINVAL); -- } -- -- if (data->ioc_inllen2 > 37) { -- CERROR("target UUID must be less than 38 characters\n"); -- RETURN(-EINVAL); -- } -- -- sema_init(&cli->cl_sem, 1); -- cli->cl_conn_count = 0; -- memcpy(cli->cl_target_uuid, data->ioc_inlbuf1, data->ioc_inllen1); -- memcpy(server_uuid, data->ioc_inlbuf2, MIN(data->ioc_inllen2, -- sizeof(server_uuid))); -- - cli->cl_import.imp_connection = ptlrpc_uuid_to_connection(server_uuid); - if (!cli->cl_import.imp_connection) - imp->imp_connection = ptlrpc_uuid_to_connection(server_uuid); - if (!imp->imp_connection) -- RETURN(-ENOENT); - - INIT_LIST_HEAD(&imp->imp_replay_list); - INIT_LIST_HEAD(&imp->imp_sending_list); - INIT_LIST_HEAD(&imp->imp_delayed_list); - spin_lock_init(&imp->imp_lock); -- -- ptlrpc_init_client(rq_portal, rp_portal, name, -- &obddev->obd_ldlm_client); - cli->cl_import.imp_client = &obddev->obd_ldlm_client; - cli->cl_import.imp_obd = obddev; - imp->imp_client = &obddev->obd_ldlm_client; - imp->imp_obd = obddev; -- -- cli->cl_max_mds_easize = sizeof(struct lov_mds_md); - cli->cl_max_ost_easize = sizeof(struct lov_stripe_md); -- -- MOD_INC_USE_COUNT; -- RETURN(0); --} -- --int client_obd_cleanup(struct obd_device * obddev) --{ -- struct client_obd *obd = &obddev->u.cli; -- -- ptlrpc_cleanup_client(&obd->cl_import); -- ptlrpc_put_connection(obd->cl_import.imp_connection); -- -- MOD_DEC_USE_COUNT; -- return 0; --} -- --int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- struct client_obd *cli = &obd->u.cli; -- struct ptlrpc_request *request; -- int rc, size[] = {sizeof(cli->cl_target_uuid), -- sizeof(obd->obd_uuid) }; -- char *tmp[] = {cli->cl_target_uuid, obd->obd_uuid}; -- int rq_opc = (obd->obd_type->typ_ops->o_brw) ? OST_CONNECT :MDS_CONNECT; -- struct ptlrpc_connection *c; - struct obd_import *imp = &cli->cl_import; -- -- ENTRY; -- down(&cli->cl_sem); -- MOD_INC_USE_COUNT; -- rc = class_connect(conn, obd, cluuid); -- if (rc) { -- MOD_DEC_USE_COUNT; -- GOTO(out_sem, rc); -- } -- cli->cl_conn_count++; -- if (cli->cl_conn_count > 1) -- GOTO(out_sem, rc); -- - if (obd->obd_namespace != NULL) - CERROR("already have namespace!\n"); -- obd->obd_namespace = ldlm_namespace_new(obd->obd_name, -- LDLM_NAMESPACE_CLIENT); -- if (obd->obd_namespace == NULL) -- GOTO(out_disco, rc = -ENOMEM); - - INIT_LIST_HEAD(&imp->imp_chain); - imp->imp_last_xid = 0; - imp->imp_max_transno = 0; - imp->imp_peer_last_xid = 0; - imp->imp_peer_committed_transno = 0; -- -- request = ptlrpc_prep_req(&cli->cl_import, rq_opc, 2, size, tmp); -- if (!request) -- GOTO(out_ldlm, rc = -ENOMEM); -- -- request->rq_level = LUSTRE_CONN_NEW; -- request->rq_replen = lustre_msg_size(0, NULL); -- request->rq_reqmsg->addr = conn->addr; -- request->rq_reqmsg->cookie = conn->cookie; -- c = class_conn2export(conn)->exp_connection = -- ptlrpc_connection_addref(request->rq_connection); - list_add(&imp->imp_chain, &c->c_imports); -- recovd_conn_manage(c, recovd, recover); -- - imp->imp_level = LUSTRE_CONN_CON; -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out_req, rc); -- -- if (rq_opc == MDS_CONNECT) - cli->cl_import.imp_flags |= IMP_REPLAYABLE; - list_add(&cli->cl_import.imp_chain, &c->c_imports); - c->c_level = LUSTRE_CONN_FULL; - cli->cl_import.imp_handle.addr = request->rq_repmsg->addr; - cli->cl_import.imp_handle.cookie = request->rq_repmsg->cookie; - imp->imp_flags |= IMP_REPLAYABLE; - imp->imp_level = LUSTRE_CONN_FULL; - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; -- -- EXIT; --out_req: -- ptlrpc_req_finished(request); -- if (rc) { --out_ldlm: -- ldlm_namespace_free(obd->obd_namespace); -- obd->obd_namespace = NULL; - if (rq_opc == MDS_CONNECT) { - /* Don't class_disconnect OSCs, because the LOV - * cares about them even if they can't connect to the - * OST. - * - * This is leak-bait, but without either a way to - * operate on the osc without an export or separate - * methods for connect-to-osc and connect-osc-to-ost - * it's not clear what else to do. - */ --out_disco: - class_disconnect(conn); - MOD_DEC_USE_COUNT; - cli->cl_conn_count--; - class_disconnect(conn); - MOD_DEC_USE_COUNT; - } -- } --out_sem: -- up(&cli->cl_sem); -- return rc; --} -- --int client_obd_disconnect(struct lustre_handle *conn) --{ -- struct obd_device *obd = class_conn2obd(conn); -- struct client_obd *cli = &obd->u.cli; -- int rq_opc; -- struct ptlrpc_request *request = NULL; -- int rc, err; -- ENTRY; -- -- if (!obd) { -- CERROR("invalid connection for disconnect: addr "LPX64 -- ", cookie "LPX64"\n", conn ? conn->addr : -1UL, -- conn ? conn->cookie : -1UL); -- RETURN(-EINVAL); -- } -- -- rq_opc = obd->obd_type->typ_ops->o_brw ? OST_DISCONNECT:MDS_DISCONNECT; -- down(&cli->cl_sem); -- if (!cli->cl_conn_count) { -- CERROR("disconnecting disconnected device (%s)\n", -- obd->obd_name); -- GOTO(out_sem, rc = -EINVAL); -- } -- -- cli->cl_conn_count--; -- if (cli->cl_conn_count) -- GOTO(out_disco, rc = 0); -- -- ldlm_namespace_free(obd->obd_namespace); -- obd->obd_namespace = NULL; - request = ptlrpc_prep_req(&cli->cl_import, rq_opc, 0, NULL, NULL); - request = ptlrpc_prep_req(&cli->cl_import, rq_opc, 0, NULL, - NULL); -- if (!request) -- GOTO(out_disco, rc = -ENOMEM); - - -- request->rq_replen = lustre_msg_size(0, NULL); -- - /* Process disconnects even if we're waiting for recovery. */ - request->rq_level = LUSTRE_CONN_RECOVD; - -- rc = ptlrpc_queue_wait(request); -- if (rc) -- GOTO(out_req, rc); -- -- EXIT; -- out_req: -- if (request) -- ptlrpc_req_finished(request); -- out_disco: -- err = class_disconnect(conn); -- if (!rc && err) -- rc = err; -- list_del_init(&cli->cl_import.imp_chain); -- MOD_DEC_USE_COUNT; -- out_sem: -- up(&cli->cl_sem); -- RETURN(rc); --} diff --cc lustre/lib/ll_pack.c index 184c2c1,184c2c1..0000000 deleted file mode 100644,100644 --- a/lustre/lib/ll_pack.c +++ /dev/null @@@ -1,67 -1,67 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * (Un)packing of OST/MDS requests -- * -- */ -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include -- --void obd_statfs_pack(struct obd_statfs *tgt, struct obd_statfs *src) --{ -- tgt->os_type = HTON__u64(src->os_type); -- tgt->os_blocks = HTON__u64(src->os_blocks); -- tgt->os_bfree = HTON__u64(src->os_bfree); -- tgt->os_bavail = HTON__u64(src->os_bavail); -- tgt->os_files = HTON__u64(src->os_files); -- tgt->os_ffree = HTON__u64(src->os_ffree); -- tgt->os_bsize = HTON__u32(src->os_bsize); -- tgt->os_namelen = HTON__u32(src->os_namelen); --} -- --#define obd_statfs_unpack(tgt, src) obd_statfs_pack(tgt, src) -- --void statfs_pack(struct obd_statfs *osfs, struct statfs *sfs) --{ -- osfs->os_type = sfs->f_type; -- osfs->os_blocks = sfs->f_blocks; -- osfs->os_bfree = sfs->f_bfree; -- osfs->os_bavail = sfs->f_bavail; -- osfs->os_files = sfs->f_files; -- osfs->os_ffree = sfs->f_ffree; -- osfs->os_bsize = sfs->f_bsize; -- osfs->os_namelen = sfs->f_namelen; --} -- --void statfs_unpack(struct statfs *sfs, struct obd_statfs *osfs) --{ -- sfs->f_type = osfs->os_type; -- sfs->f_blocks = osfs->os_blocks; -- sfs->f_bfree = osfs->os_bfree; -- sfs->f_bavail = osfs->os_bavail; -- sfs->f_files = osfs->os_files; -- sfs->f_ffree = osfs->os_ffree; -- sfs->f_bsize = osfs->os_bsize; -- sfs->f_namelen = osfs->os_namelen; --} -- diff --cc lustre/lib/mds_updates.c index 75a59da,6a53cb6..0000000 deleted file mode 100644,100644 --- a/lustre/lib/mds_updates.c +++ /dev/null @@@ -1,460 -1,478 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copryright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Lustre Lite Update Records -- */ -- --#include --#include --#include --#include --#include --#include --#include --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --#include // for wait_on_buffer --#else --#include // for wait_on_buffer --#endif --#include -- --#include --#include -- --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include -- --void mds_pack_inode2fid(struct ll_fid *fid, struct inode *inode) --{ -- fid->id = HTON__u64(inode->i_ino); -- fid->generation = HTON__u32(inode->i_generation); -- fid->f_type = HTON__u32(S_IFMT & inode->i_mode); --} -- -- --void mds_pack_inode2body(struct mds_body *b, struct inode *inode) --{ -- b->valid = OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | -- OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLUID | OBD_MD_FLGID | -- OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLNLINK | OBD_MD_FLGENER; -- b->ino = HTON__u32(inode->i_ino); -- b->atime = HTON__u32(inode->i_atime); -- b->mtime = HTON__u32(inode->i_mtime); -- b->ctime = HTON__u32(inode->i_ctime); -- b->mode = HTON__u32(inode->i_mode); -- b->size = HTON__u64(inode->i_size); -- b->uid = HTON__u32(inode->i_uid); -- b->gid = HTON__u32(inode->i_gid); -- b->flags = HTON__u32(inode->i_flags); -- b->rdev = HTON__u32(b->rdev); -- b->nlink = HTON__u32(inode->i_nlink); -- b->generation = HTON__u32(inode->i_generation); --} -- -- --void mds_pack_fid(struct ll_fid *fid) --{ -- fid->id = HTON__u64(fid->id); -- fid->generation = HTON__u32(fid->generation); -- fid->f_type = HTON__u32(fid->f_type); --} -- --static void mds_pack_body(struct mds_body *b) --{ -- if (b == NULL) -- LBUG(); -- -- b->fsuid = HTON__u32(current->fsuid); -- b->fsgid = HTON__u32(current->fsgid); -- b->capability = HTON__u32(current->cap_effective); -- -- mds_pack_fid(&b->fid1); -- mds_pack_fid(&b->fid2); -- b->size = HTON__u64(b->size); -- b->ino = HTON__u32(b->ino); -- b->valid = HTON__u32(b->valid); -- b->mode = HTON__u32(b->mode); -- b->uid = HTON__u32(b->uid); -- b->gid = HTON__u32(b->gid); -- b->mtime = HTON__u32(b->mtime); -- b->ctime = HTON__u32(b->ctime); -- b->atime = HTON__u32(b->atime); -- b->flags = HTON__u32(b->flags); -- b->rdev = HTON__u32(b->rdev); -- b->nlink = HTON__u32(b->nlink); -- b->generation = HTON__u32(b->generation); --} -- --void mds_getattr_pack(struct ptlrpc_request *req, int offset, -- struct inode *inode, -- const char *name, int namelen) --{ - struct mds_body *rec; - rec = lustre_msg_buf(req->rq_reqmsg, offset); - struct mds_body *b; - b = lustre_msg_buf(req->rq_reqmsg, offset); -- - ll_inode2fid(&rec->fid1, inode); - b->fsuid = HTON__u32(current->fsuid); - b->fsgid = HTON__u32(current->fsgid); - b->capability = HTON__u32(current->cap_effective); - - ll_inode2fid(&b->fid1, inode); -- if (name) { -- char *tmp; -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(name, namelen, tmp); -- } -} - -void mds_readdir_pack(struct ptlrpc_request *req, __u64 offset, - obd_id ino, int type) -{ - struct mds_body *b; - - b = lustre_msg_buf(req->rq_reqmsg, 0); - b->fsuid = HTON__u32(current->fsuid); - b->fsgid = HTON__u32(current->fsgid); - b->capability = HTON__u32(current->cap_effective); - b->fid1.id = HTON__u64(ino); - b->fid1.f_type = HTON__u32(type); - b->size = HTON__u64(offset); --} -- -- --void mds_pack_req_body(struct ptlrpc_request *req) --{ -- struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, 0); -- mds_pack_body(b); --} -- --void mds_pack_rep_body(struct ptlrpc_request *req) --{ -- struct mds_body *b = lustre_msg_buf(req->rq_repmsg, 0); -- mds_pack_body(b); --} -- -- --/* packing of MDS records */ - void mds_create_pack(struct ptlrpc_request *req, int offset, - struct inode *dir, __u32 mode, __u64 rdev, __u32 uid, - __u32 gid, __u64 time, const char *name, int namelen, - const char *tgt, int tgtlen) -void mds_create_pack(struct ptlrpc_request *req, int offset, struct inode *dir, - __u32 mode, __u64 rdev, __u32 uid, __u32 gid, __u64 time, - const char *name, int namelen, - const void *data, int datalen) --{ -- struct mds_rec_create *rec; -- char *tmp; -- rec = lustre_msg_buf(req->rq_reqmsg, offset); -- -- /* XXX do something about time, uid, gid */ -- rec->cr_opcode = HTON__u32(REINT_CREATE); -- rec->cr_fsuid = HTON__u32(current->fsuid); -- rec->cr_fsgid = HTON__u32(current->fsgid); -- rec->cr_cap = HTON__u32(current->cap_effective); -- ll_inode2fid(&rec->cr_fid, dir); - memset(&rec->cr_replayfid, 0, sizeof rec->cr_replayfid); - memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid)); -- rec->cr_mode = HTON__u32(mode); -- rec->cr_rdev = HTON__u64(rdev); -- rec->cr_uid = HTON__u32(uid); -- rec->cr_gid = HTON__u32(gid); -- rec->cr_time = HTON__u64(time); -- -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(name, namelen, tmp); -- - if (tgt) { - if (data) { -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2); - LOGL0(tgt, tgtlen, tmp); - LOGL0(data, datalen, tmp); -- } --} -- --void mds_setattr_pack(struct ptlrpc_request *req, int offset, -- struct inode *inode, struct iattr *iattr, -- const char *name, int namelen) --{ -- struct mds_rec_setattr *rec; -- rec = lustre_msg_buf(req->rq_reqmsg, offset); -- -- rec->sa_opcode = HTON__u32(REINT_SETATTR); -- rec->sa_fsuid = HTON__u32(current->fsuid); -- rec->sa_fsgid = HTON__u32(current->fsgid); -- rec->sa_cap = HTON__u32(current->cap_effective); -- ll_inode2fid(&rec->sa_fid, inode); -- rec->sa_valid = HTON__u32(iattr->ia_valid); -- rec->sa_mode = HTON__u32(iattr->ia_mode); -- rec->sa_uid = HTON__u32(iattr->ia_uid); -- rec->sa_gid = HTON__u32(iattr->ia_gid); -- rec->sa_size = HTON__u64(iattr->ia_size); -- rec->sa_atime = HTON__u64(iattr->ia_atime); -- rec->sa_mtime = HTON__u64(iattr->ia_mtime); -- rec->sa_ctime = HTON__u64(iattr->ia_ctime); -- rec->sa_attr_flags = HTON__u32(iattr->ia_attr_flags); -- -- if (namelen) { -- char *tmp; -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(name, namelen, tmp); -- } --} -- --void mds_unlink_pack(struct ptlrpc_request *req, int offset, -- struct inode *inode, struct inode *child, __u32 mode, -- const char *name, int namelen) --{ -- struct mds_rec_unlink *rec; -- char *tmp; -- -- rec = lustre_msg_buf(req->rq_reqmsg, offset); -- -- rec->ul_opcode = HTON__u32(REINT_UNLINK); -- rec->ul_fsuid = HTON__u32(current->fsuid); -- rec->ul_fsgid = HTON__u32(current->fsgid); -- rec->ul_cap = HTON__u32(current->cap_effective); -- rec->ul_mode = HTON__u32(mode); -- ll_inode2fid(&rec->ul_fid1, inode); -- if (child) -- ll_inode2fid(&rec->ul_fid2, child); -- -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(name, namelen, tmp); --} -- --void mds_link_pack(struct ptlrpc_request *req, int offset, -- struct inode *inode, struct inode *dir, -- const char *name, int namelen) --{ -- struct mds_rec_link *rec; -- char *tmp; -- -- rec = lustre_msg_buf(req->rq_reqmsg, offset); -- -- rec->lk_opcode = HTON__u32(REINT_LINK); -- rec->lk_fsuid = HTON__u32(current->fsuid); -- rec->lk_fsgid = HTON__u32(current->fsgid); -- rec->lk_cap = HTON__u32(current->cap_effective); -- ll_inode2fid(&rec->lk_fid1, inode); -- ll_inode2fid(&rec->lk_fid2, dir); -- -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(name, namelen, tmp); --} -- --void mds_rename_pack(struct ptlrpc_request *req, int offset, -- struct inode *srcdir, struct inode *tgtdir, -- const char *old, int oldlen, const char *new, int newlen) --{ -- struct mds_rec_rename *rec; -- char *tmp; -- -- rec = lustre_msg_buf(req->rq_reqmsg, offset); -- -- /* XXX do something about time, uid, gid */ -- rec->rn_opcode = HTON__u32(REINT_RENAME); -- rec->rn_fsuid = HTON__u32(current->fsuid); -- rec->rn_fsgid = HTON__u32(current->fsgid); -- rec->rn_cap = HTON__u32(current->cap_effective); -- ll_inode2fid(&rec->rn_fid1, srcdir); -- ll_inode2fid(&rec->rn_fid2, tgtdir); -- -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- LOGL0(old, oldlen, tmp); -- -- if (new) { -- tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2); -- LOGL0(new, newlen, tmp); -- } --} -- --/* unpacking */ --void mds_unpack_fid(struct ll_fid *fid) --{ -- fid->id = NTOH__u64(fid->id); -- fid->generation = NTOH__u32(fid->generation); -- fid->f_type = NTOH__u32(fid->f_type); --} -- --void mds_unpack_body(struct mds_body *b) --{ -- if (b == NULL) -- LBUG(); -- -- mds_unpack_fid(&b->fid1); -- mds_unpack_fid(&b->fid2); -- b->size = NTOH__u64(b->size); -- b->valid = NTOH__u32(b->valid); -- b->fsuid = NTOH__u32(b->fsuid); -- b->fsgid = NTOH__u32(b->fsgid); -- b->capability = NTOH__u32(b->capability); -- b->ino = NTOH__u32(b->ino); -- b->mode = NTOH__u32(b->mode); -- b->uid = NTOH__u32(b->uid); -- b->gid = NTOH__u32(b->gid); -- b->mtime = NTOH__u32(b->mtime); -- b->ctime = NTOH__u32(b->ctime); -- b->atime = NTOH__u32(b->atime); -- b->flags = NTOH__u32(b->flags); -- b->rdev = NTOH__u32(b->rdev); -- b->nlink = NTOH__u32(b->nlink); -- b->generation = NTOH__u32(b->generation); --} -- --static int mds_setattr_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r) --{ -- struct iattr *attr = &r->ur_iattr; -- struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset); -- ENTRY; -- -- if (req->rq_reqmsg->bufcount < offset + 1 || -- req->rq_reqmsg->buflens[offset] != sizeof(*rec)) -- RETURN(-EFAULT); -- -- r->ur_fsuid = NTOH__u32(rec->sa_fsuid); -- r->ur_fsgid = NTOH__u32(rec->sa_fsgid); -- r->ur_cap = NTOH__u32(rec->sa_cap); -- r->ur_fid1 = &rec->sa_fid; -- attr->ia_valid = NTOH__u32(rec->sa_valid); -- attr->ia_mode = NTOH__u32(rec->sa_mode); -- attr->ia_uid = NTOH__u32(rec->sa_uid); -- attr->ia_gid = NTOH__u32(rec->sa_gid); -- attr->ia_size = NTOH__u64(rec->sa_size); -- attr->ia_atime = NTOH__u64(rec->sa_atime); -- attr->ia_mtime = NTOH__u64(rec->sa_mtime); -- attr->ia_ctime = NTOH__u64(rec->sa_ctime); -- attr->ia_attr_flags = NTOH__u32(rec->sa_attr_flags); -- -- if (req->rq_reqmsg->bufcount == offset + 2) { -- r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; -- r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- } else -- r->ur_namelen = 0; -- -- RETURN(0); --} -- --static int mds_create_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r) --{ -- struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, offset); -- ENTRY; -- -- if (req->rq_reqmsg->bufcount < offset + 2 || -- req->rq_reqmsg->buflens[offset] != sizeof(*rec)) -- RETURN(-EFAULT); -- -- r->ur_fsuid = NTOH__u32(rec->cr_fsuid); -- r->ur_fsgid = NTOH__u32(rec->cr_fsgid); -- r->ur_cap = NTOH__u32(rec->cr_cap); -- r->ur_fid1 = &rec->cr_fid; -- r->ur_fid2 = &rec->cr_replayfid; -- r->ur_mode = NTOH__u32(rec->cr_mode); -- r->ur_rdev = NTOH__u64(rec->cr_rdev); -- r->ur_uid = NTOH__u32(rec->cr_uid); -- r->ur_gid = NTOH__u32(rec->cr_gid); -- r->ur_time = NTOH__u64(rec->cr_time); -- -- r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; -- - if (req->rq_reqmsg->bufcount == offset + 3) { - if (req->rq_reqmsg->bufcount == offset + 3) { -- r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2); -- r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2]; - } else { - } else { -- r->ur_tgt = NULL; -- r->ur_tgtlen = 0; -- } -- RETURN(0); --} -- --static int mds_link_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r) --{ -- struct mds_rec_link *rec = lustre_msg_buf(req->rq_reqmsg, offset); -- ENTRY; -- -- if (req->rq_reqmsg->bufcount != offset + 2 || -- req->rq_reqmsg->buflens[offset] != sizeof(*rec)) -- RETURN(-EFAULT); -- -- r->ur_fsuid = NTOH__u32(rec->lk_fsuid); -- r->ur_fsgid = NTOH__u32(rec->lk_fsgid); -- r->ur_cap = NTOH__u32(rec->lk_cap); -- r->ur_fid1 = &rec->lk_fid1; -- r->ur_fid2 = &rec->lk_fid2; -- -- r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; -- RETURN(0); --} -- --static int mds_unlink_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r) --{ -- struct mds_rec_unlink *rec = lustre_msg_buf(req->rq_reqmsg, offset); -- ENTRY; -- -- if (req->rq_reqmsg->bufcount != offset + 2 || -- req->rq_reqmsg->buflens[offset] != sizeof(*rec)) -- RETURN(-EFAULT); -- -- r->ur_fsuid = NTOH__u32(rec->ul_fsuid); -- r->ur_fsgid = NTOH__u32(rec->ul_fsgid); -- r->ur_cap = NTOH__u32(rec->ul_cap); -- r->ur_mode = NTOH__u32(rec->ul_mode); -- r->ur_fid1 = &rec->ul_fid1; -- r->ur_fid2 = &rec->ul_fid2; -- -- r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; -- RETURN(0); --} -- --static int mds_rename_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r) --{ -- struct mds_rec_rename *rec = lustre_msg_buf(req->rq_reqmsg, offset); -- ENTRY; -- -- if (req->rq_reqmsg->bufcount != offset + 3 || -- req->rq_reqmsg->buflens[offset] != sizeof(*rec)) -- RETURN(-EFAULT); -- -- r->ur_fsuid = NTOH__u32(rec->rn_fsuid); -- r->ur_fsgid = NTOH__u32(rec->rn_fsgid); -- r->ur_cap = NTOH__u32(rec->rn_cap); -- r->ur_fid1 = &rec->rn_fid1; -- r->ur_fid2 = &rec->rn_fid2; -- -- r->ur_name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; -- -- r->ur_tgt = lustre_msg_buf(req->rq_reqmsg, offset + 2); -- r->ur_tgtlen = req->rq_reqmsg->buflens[offset + 2]; -- RETURN(0); --} -- --typedef int (*update_unpacker)(struct ptlrpc_request *req, int offset, -- struct mds_update_record *r); -- --static update_unpacker mds_unpackers[REINT_MAX + 1] = { -- [REINT_SETATTR] mds_setattr_unpack, -- [REINT_CREATE] mds_create_unpack, -- [REINT_LINK] mds_link_unpack, -- [REINT_UNLINK] mds_unlink_unpack, -- [REINT_RENAME] mds_rename_unpack, --}; -- --int mds_update_unpack(struct ptlrpc_request *req, int offset, -- struct mds_update_record *rec) --{ -- __u32 *opcode = lustre_msg_buf(req->rq_reqmsg, offset); -- int rc, realop; -- ENTRY; -- -- if (!opcode || req->rq_reqmsg->buflens[offset] < sizeof(*opcode)) -- RETURN(-EFAULT); -- -- realop = rec->ur_opcode = NTOH__u32(*opcode); -- realop &= REINT_OPCODE_MASK; -- -- if (realop < 0 || realop > REINT_MAX) -- RETURN(-EFAULT); -- -- rc = mds_unpackers[realop](req, offset, rec); -- RETURN(rc); --} diff --cc lustre/lib/obd_pack.c index 8b3c33a,8b3c33a..0000000 deleted file mode 100644,100644 --- a/lustre/lib/obd_pack.c +++ /dev/null @@@ -1,80 -1,80 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * (Un)packing of OST requests -- * -- */ -- --#define DEBUG_SUBSYSTEM S_OST -- --#include --#include -- --void ost_pack_ioo(void **tmp, struct lov_stripe_md *lsm, int bufcnt) --{ -- struct obd_ioobj *ioo = *tmp; -- char *c = *tmp; -- -- ioo->ioo_id = HTON__u64(lsm->lsm_object_id); -- ioo->ioo_gr = HTON__u64(0); -- ioo->ioo_type = HTON__u32(S_IFREG); -- ioo->ioo_bufcnt = HTON__u32(bufcnt); -- *tmp = c + sizeof(*ioo); --} -- --void ost_unpack_ioo(void **tmp, struct obd_ioobj **ioop) --{ -- char *c = *tmp; -- struct obd_ioobj *ioo = *tmp; -- *ioop = *tmp; -- -- ioo->ioo_id = NTOH__u64(ioo->ioo_id); -- ioo->ioo_gr = NTOH__u64(ioo->ioo_gr); -- ioo->ioo_type = NTOH__u32(ioo->ioo_type); -- ioo->ioo_bufcnt = NTOH__u32(ioo->ioo_bufcnt); -- *tmp = c + sizeof(*ioo); --} -- --void ost_pack_niobuf(void **tmp, __u64 offset, __u32 len, __u32 flags, -- __u32 xid) --{ -- struct niobuf_remote *nb = *tmp; -- char *c = *tmp; -- -- nb->offset = HTON__u64(offset); -- nb->len = HTON__u32(len); -- nb->flags = HTON__u32(flags); -- nb->xid = HTON__u32(xid); -- *tmp = c + sizeof(*nb); --} -- --void ost_unpack_niobuf(void **tmp, struct niobuf_remote **nbp) --{ -- char *c = *tmp; -- struct niobuf_remote *nb = *tmp; -- -- *nbp = *tmp; -- -- nb->offset = NTOH__u64(nb->offset); -- nb->len = NTOH__u32(nb->len); -- nb->flags = NTOH__u32(nb->flags); -- -- *tmp = c + sizeof(*nb); --} diff --cc lustre/lib/simple.c index 0a3d058,4b423d4..0000000 deleted file mode 100644,100644 --- a/lustre/lib/simple.c +++ /dev/null @@@ -1,204 -1,236 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lib/simple.c -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Peter Braam -- * and Andreas Dilger -- */ -- --#define EXPORT_SYMTAB -- --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_FILTER -- --#include --#include --#include --#include --#include -- --#ifdef OBD_CTXT_DEBUG --/* Debugging check only needed during development */ --#define ASSERT_CTXT_MAGIC(magic) do { if ((magic) != OBD_RUN_CTXT_MAGIC) { \ -- CERROR("bad ctxt magic\n"); LBUG(); } } while(0) --#define ASSERT_NOT_KERNEL_CTXT(msg) do { if (segment_eq(get_fs(), get_ds())) { \ -- CERROR(msg); LBUG(); } } while(0) --#define ASSERT_KERNEL_CTXT(msg) do { if (!segment_eq(get_fs(), get_ds())) { \ -- CERROR(msg); LBUG(); } } while(0) --#else --#define ASSERT_CTXT_MAGIC(magic) do {} while(0) --#define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0) --#define ASSERT_KERNEL_CTXT(msg) do {} while(0) --#endif -- --/* push / pop to root of obd store */ - void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new, -void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, -- struct obd_ucred *uc) --{ -- //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n"); - ASSERT_CTXT_MAGIC(new->magic); - ASSERT_CTXT_MAGIC(new_ctx->magic); -- OBD_SET_CTXT_MAGIC(save); - - /* - CDEBUG(D_INFO, "== push %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - save, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ - -- save->fs = get_fs(); -- save->pwd = dget(current->fs->pwd); -- save->pwdmnt = mntget(current->fs->pwdmnt); -- -- LASSERT(save->pwd); -- LASSERT(save->pwdmnt); - LASSERT(new->pwd); - LASSERT(new->pwdmnt); - LASSERT(new_ctx->pwd); - LASSERT(new_ctx->pwdmnt); -- - save->fsuid = current->fsuid; - save->fsgid = current->fsgid; - save->cap = current->cap_effective; - if (uc) { - if (uc) { - save->fsuid = current->fsuid; - save->fsgid = current->fsgid; - save->cap = current->cap_effective; - -- current->fsuid = uc->ouc_fsuid; -- current->fsgid = uc->ouc_fsgid; -- current->cap_effective = uc->ouc_cap; -- } - set_fs(new->fs); - set_fs_pwd(current->fs, new->pwdmnt, new->pwd); - //if (save->override) - // cap_lower(current->cap_effective, CAP_DAC_OVERRIDE); - set_fs(new_ctx->fs); - set_fs_pwd(current->fs, new_ctx->pwdmnt, new_ctx->pwd); - - /* - CDEBUG(D_INFO, "== push %p==%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - new_ctx, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ --} -- - void pop_ctxt(struct obd_run_ctxt *saved) -void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, - struct obd_ucred *uc) --{ -- //printk("pc0"); -- ASSERT_CTXT_MAGIC(saved->magic); -- //printk("pc1"); -- ASSERT_KERNEL_CTXT("popping non-kernel context!\n"); - - /* - CDEBUG(D_INFO, " == pop %p==%p == cur %p pwd %p (%*s), pwdmnt %p\n", - new_ctx, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ - - LASSERT(current->fs->pwd == new_ctx->pwd); - LASSERT(current->fs->pwdmnt == new_ctx->pwdmnt); - -- //printk("pc2"); -- set_fs(saved->fs); -- //printk("pc3\n"); -- set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd); -- //printk("pc4"); -- -- dput(saved->pwd); -- //printk("pc5"); -- mntput(saved->pwdmnt); -- //printk("pc6\n"); - current->fsuid = saved->fsuid; - current->fsgid = saved->fsgid; - current->cap_effective = saved->cap; - if (uc) { - current->fsuid = saved->fsuid; - current->fsgid = saved->fsgid; - current->cap_effective = saved->cap; - } -- - // if (saved->override) - // cap_raise(current->cap_effective, CAP_DAC_OVERRIDE); - /* - CDEBUG(D_INFO, "== pop %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n", - saved, current, current->fs, current->fs->pwd, - current->fs->pwd->d_name.len, current->fs->pwd->d_name.name, - current->fs->pwdmnt); - */ --} -- --/* utility to make a file */ --struct dentry *simple_mknod(struct dentry *dir, char *name, int mode) --{ -- struct dentry *dchild; -- int err = 0; -- ENTRY; -- -- ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n"); -- CDEBUG(D_INODE, "creating file %*s\n", (int)strlen(name), name); -- -- down(&dir->d_inode->i_sem); -- dchild = lookup_one_len(name, dir, strlen(name)); -- if (IS_ERR(dchild)) -- GOTO(out, PTR_ERR(dchild)); -- -- if (dchild->d_inode) { -- if ((dchild->d_inode->i_mode & S_IFMT) != S_IFREG) -- GOTO(out, err = -EEXIST); -- -- GOTO(out, dchild); -- } -- -- err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG); -- EXIT; --out: -- up(&dir->d_inode->i_sem); -- if (err) { -- dput(dchild); -- RETURN(ERR_PTR(err)); -- } -- -- RETURN(dchild); --} -- --/* utility to make a directory */ --struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode) --{ -- struct dentry *dchild; -- int err = 0; -- ENTRY; -- -- ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n"); -- CDEBUG(D_INODE, "creating directory %*s\n", (int)strlen(name), name); -- down(&dir->d_inode->i_sem); -- dchild = lookup_one_len(name, dir, strlen(name)); -- if (IS_ERR(dchild)) -- GOTO(out, PTR_ERR(dchild)); -- -- if (dchild->d_inode) { -- if (!S_ISDIR(dchild->d_inode->i_mode)) -- GOTO(out, err = -ENOTDIR); -- -- GOTO(out, dchild); -- } -- -- err = vfs_mkdir(dir->d_inode, dchild, mode); -- EXIT; --out: -- up(&dir->d_inode->i_sem); -- if (err) { -- dput(dchild); -- RETURN(ERR_PTR(err)); -- } -- -- RETURN(dchild); --} -- --/* -- * Read a file from within kernel context. Prior to calling this -- * function we should already have done a push_ctxt(). -- */ --int lustre_fread(struct file *file, char *str, int len, loff_t *off) --{ -- ASSERT_KERNEL_CTXT("kernel doing read outside kernel context\n"); -- if (!file || !file->f_op || !file->f_op->read || !off) -- RETURN(-ENOSYS); -- -- return file->f_op->read(file, str, len, off); --} -- --/* -- * Write a file from within kernel context. Prior to calling this -- * function we should already have done a push_ctxt(). -- */ --int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off) --{ -- ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n"); -- if (!file || !file->f_op || !off) -- RETURN(-ENOSYS); -- -- if (!file->f_op->write) -- RETURN(-EROFS); -- -- return file->f_op->write(file, str, len, off); --} -- --/* -- * Sync a file from within kernel context. Prior to calling this -- * function we should already have done a push_ctxt(). -- */ --int lustre_fsync(struct file *file) --{ -- ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n"); -- if (!file || !file->f_op || !file->f_op->fsync) -- RETURN(-ENOSYS); -- -- return file->f_op->fsync(file, file->f_dentry, 0); --} diff --cc lustre/lib/target.c index 8786ee8,141e155..0000000 deleted file mode 100644,100644 --- a/lustre/lib/target.c +++ /dev/null @@@ -1,175 -1,175 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * Author: Peter J. Braam -- * Author: Phil Schwan -- * Author: Mike Shaver -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Target-common OBD method implementations and utility functions. -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_OST /* XXX WRONG */ -- --#include --#include --#include --#include -- --int target_handle_connect(struct ptlrpc_request *req) --{ -- struct obd_device *target; -- struct obd_export *export; -- struct obd_import *dlmimp; -- struct lustre_handle conn; -- char *tgtuuid, *cluuid; -- int rc, i; -- ENTRY; -- -- tgtuuid = lustre_msg_buf(req->rq_reqmsg, 0); -- if (req->rq_reqmsg->buflens[0] > 37) { -- CERROR("bad target UUID for connect\n"); -- GOTO(out, rc = -EINVAL); -- } -- -- cluuid = lustre_msg_buf(req->rq_reqmsg, 1); -- if (req->rq_reqmsg->buflens[1] > 37) { -- CERROR("bad client UUID for connect\n"); -- GOTO(out, rc = -EINVAL); -- } -- -- i = class_uuid2dev(tgtuuid); -- if (i == -1) { -- CERROR("UUID '%s' not found for connect\n", tgtuuid); -- GOTO(out, rc = -ENODEV); -- } -- -- target = &obd_dev[i]; -- if (!target) -- GOTO(out, rc = -ENODEV); -- -- conn.addr = req->rq_reqmsg->addr; -- conn.cookie = req->rq_reqmsg->cookie; -- -- rc = obd_connect(&conn, target, cluuid, ptlrpc_recovd, -- target_revoke_connection); - if (rc) - /* EALREADY indicates a reconnection, send the reply normally. */ - if (rc && rc != EALREADY) -- GOTO(out, rc); -- -- rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- GOTO(out, rc); -- req->rq_repmsg->addr = conn.addr; -- req->rq_repmsg->cookie = conn.cookie; -- -- export = class_conn2export(&conn); -- LASSERT(export); -- -- req->rq_export = export; -- export->exp_connection = ptlrpc_get_connection(&req->rq_peer, cluuid); -- if (req->rq_connection != NULL) -- ptlrpc_put_connection(req->rq_connection); -- req->rq_connection = ptlrpc_connection_addref(export->exp_connection); -- -- spin_lock(&export->exp_connection->c_lock); -- list_add(&export->exp_conn_chain, &export->exp_connection->c_exports); -- spin_unlock(&export->exp_connection->c_lock); -- recovd_conn_manage(export->exp_connection, ptlrpc_recovd, -- target_revoke_connection); -- -- dlmimp = &export->exp_ldlm_data.led_import; -- dlmimp->imp_connection = req->rq_connection; -- dlmimp->imp_client = &export->exp_obd->obd_ldlm_client; -- dlmimp->imp_handle.addr = req->rq_reqmsg->addr; -- dlmimp->imp_handle.cookie = req->rq_reqmsg->cookie; -- dlmimp->imp_obd = /* LDLM! */ NULL; - - req->rq_connection->c_level = LUSTRE_CONN_FULL; - spin_lock_init(&dlmimp->imp_lock); - dlmimp->imp_level = LUSTRE_CONN_FULL; --out: -- req->rq_status = rc; -- RETURN(rc); --} -- --int target_handle_disconnect(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- int rc; -- ENTRY; -- -- rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- req->rq_status = obd_disconnect(conn); -- -- RETURN(0); --} -- --static int target_disconnect_client(struct ptlrpc_connection *conn) --{ -- struct list_head *expiter, *n; -- struct lustre_handle hdl; -- struct obd_export *exp; -- int rc; -- ENTRY; -- -- list_for_each_safe(expiter, n, &conn->c_exports) { -- exp = list_entry(expiter, struct obd_export, exp_conn_chain); -- -- hdl.addr = (__u64)(unsigned long)exp; -- hdl.cookie = exp->exp_cookie; -- rc = obd_disconnect(&hdl); -- if (rc) -- CERROR("disconnecting export %p failed: %d\n", exp, rc); -- } -- -- /* XXX spank the connection (it's frozen in _RECOVD for now!) */ -- RETURN(0); --} -- --static int target_fence_failed_connection(struct ptlrpc_connection *conn) --{ -- ENTRY; -- - conn->c_level = LUSTRE_CONN_RECOVD; -- conn->c_recovd_data.rd_phase = RD_PREPARED; -- -- RETURN(0); --} -- --int target_revoke_connection(struct recovd_data *rd, int phase) --{ -- struct ptlrpc_connection *conn = class_rd2conn(rd); -- -- LASSERT(conn); -- ENTRY; -- -- switch (phase) { -- case PTLRPC_RECOVD_PHASE_PREPARE: -- RETURN(target_fence_failed_connection(conn)); -- case PTLRPC_RECOVD_PHASE_RECOVER: -- RETURN(target_disconnect_client(conn)); -- case PTLRPC_RECOVD_PHASE_FAILURE: -- LBUG(); -- RETURN(0); -- } -- -- LBUG(); -- RETURN(-ENOSYS); --} diff --cc lustre/llite/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/llite/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/llite/Makefile.am index fa2d02e,071c0fd..0000000 deleted file mode 100644,100644 --- a/lustre/llite/Makefile.am +++ /dev/null @@@ -1,23 -1,21 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --MODULE = llite --modulefs_DATA = llite.o --EXTRA_PROGRAMS = llite -- --LINX= ll_pack.c -- --llite_SOURCES = dcache.c commit_callback.c super.c rw.c super25.c --llite_SOURCES += file.c dir.c sysctl.c symlink.c $(LINX) - llite_SOURCES += lov_pack.c recover.c namei.c lproc_llite.c -llite_SOURCES += recover.c namei.c lproc_llite.c -- - lov_pack.c: - test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c . --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c . -- --include $(top_srcdir)/Rules diff --cc lustre/llite/commit_callback.c index e5a595a,e5a595a..0000000 deleted file mode 100644,100644 --- a/lustre/llite/commit_callback.c +++ /dev/null @@@ -1,133 -1,133 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * The daemon that causes completed but not committed transactions -- * on the MDS to be flushed periodically when they are committed. -- * A gratuitous getattr RPC is made to the MDS to discover the -- * last committed record. -- * -- * Lustre High Availability Daemon -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Peter Braam -- * -- */ -- --#define EXPORT_SYMTAB -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include -- --static int ll_commitcbd_check_event(struct ll_sb_info *sbi) --{ -- int rc = 0; -- ENTRY; -- -- spin_lock(&sbi->ll_commitcbd_lock); -- if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING) { -- GOTO(out, rc = 1); -- } -- -- out: -- spin_unlock(&sbi->ll_commitcbd_lock); -- RETURN(rc); --} -- --static int ll_commitcbd_main(void *arg) --{ -- struct ll_sb_info *sbi = (struct ll_sb_info *)arg; -- -- ENTRY; -- -- lock_kernel(); -- daemonize(); --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- spin_lock_irq(¤t->sigmask_lock); -- sigfillset(¤t->blocked); -- our_recalc_sigpending(current); -- spin_unlock_irq(¤t->sigmask_lock); --#else -- sigfillset(¤t->blocked); -- our_recalc_sigpending(current); --#endif -- -- sprintf(current->comm, "lustre_commitcbd"); -- unlock_kernel(); -- -- /* Record that the thread is running */ -- sbi->ll_commitcbd_waketime = CURRENT_TIME; -- sbi->ll_commitcbd_timeout = 10 * HZ; -- sbi->ll_commitcbd_thread = current; -- sbi->ll_commitcbd_flags = LL_COMMITCBD_RUNNING; -- wake_up(&sbi->ll_commitcbd_ctl_waitq); -- -- /* And now, loop forever on requests */ -- while (1) { -- wait_event(sbi->ll_commitcbd_waitq, -- ll_commitcbd_check_event(sbi)); -- -- spin_lock(&sbi->ll_commitcbd_lock); -- if (sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPING) { -- spin_unlock(&sbi->ll_commitcbd_lock); -- CERROR("lustre_commitd quitting\n"); -- EXIT; -- break; -- } -- -- schedule_timeout(sbi->ll_commitcbd_timeout); -- CERROR("commit callback daemon woken up - FIXME\n"); -- spin_unlock(&sbi->ll_commitcbd_lock); -- } -- -- sbi->ll_commitcbd_thread = NULL; -- sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPED; -- wake_up(&sbi->ll_commitcbd_ctl_waitq); -- CDEBUG(D_NET, "commit callback daemon exiting %d\n", current->pid); -- RETURN(0); --} -- -- -- --int ll_commitcbd_setup(struct ll_sb_info *sbi) --{ -- int rc; -- ENTRY; -- -- rc = kernel_thread(ll_commitcbd_main, (void *) sbi, -- CLONE_VM | CLONE_FS | CLONE_FILES); -- if (rc < 0) { -- CERROR("cannot start thread\n"); -- RETURN(rc); -- } -- wait_event(sbi->ll_commitcbd_ctl_waitq, -- sbi->ll_commitcbd_flags & LL_COMMITCBD_RUNNING); -- RETURN(0); --} -- -- --int ll_commitcbd_cleanup(struct ll_sb_info *sbi) --{ -- sbi->ll_commitcbd_flags = LL_COMMITCBD_STOPPING; -- -- wake_up(&sbi->ll_commitcbd_waitq); -- wait_event(sbi->ll_commitcbd_ctl_waitq, -- sbi->ll_commitcbd_flags & LL_COMMITCBD_STOPPED); -- RETURN(0); --} diff --cc lustre/llite/dcache.c index 816543a,9a12fd5..0000000 deleted file mode 100644,100644 --- a/lustre/llite/dcache.c +++ /dev/null @@@ -1,188 -1,185 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (c) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include --#include -- --extern struct address_space_operations ll_aops; -- --void ll_release(struct dentry *de) --{ -- ENTRY; -- -- OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data)); -- EXIT; --} -- --extern void d_delete_aliases(struct inode *); --void ll_intent_release(struct dentry *de, struct lookup_intent *it) --{ -- struct lustre_handle *handle; -- ENTRY; -- -- /* XXX the check for RENAME2 is a workaround for old kernels -- which call intent_release twice in rename -- */ -- if (it == NULL || it->it_op == IT_RENAME2) { -- EXIT; -- return; -- } -- -- LASSERT(ll_d2d(de) != NULL); -- -- if (it->it_lock_mode) { -- handle = (struct lustre_handle *)it->it_lock_handle; -- if (it->it_op == IT_SETATTR) { -- int rc; -- ldlm_lock_decref(handle, it->it_lock_mode); -- rc = ldlm_cli_cancel(handle); -- if (rc < 0) -- CERROR("ldlm_cli_cancel: %d\n", rc); -- } else -- ldlm_lock_decref(handle, it->it_lock_mode); - - /* intent_release may be called multiple times, and we don't - * want to double-decref this lock (see bug 494) */ - it->it_lock_mode = 0; -- } -- - if (it->it_op == IT_RELEASED_MAGIC) { - if (!de->d_it || it->it_op == IT_RELEASED_MAGIC) { -- EXIT; -- return; -- } -- - if (de->d_it && de->d_it == it) { - de->d_it = NULL; - up(&ll_d2d(de)->lld_it_sem); - it->it_op = IT_RELEASED_MAGIC; - } - if (de->d_it == it) - LL_GET_INTENT(de, it); -- -- EXIT; --} -- --extern struct dentry *ll_find_alias(struct inode *, struct dentry *); -- --static int revalidate2_finish(int flag, struct ptlrpc_request *request, -- struct dentry **de, -- struct lookup_intent *it, -- int offset, obd_id ino) --{ -- ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, -- (*de)->d_inode, sizeof(*((*de)->d_inode))); -- ptlrpc_req_finished(request); -- return 0; --} -- --static int ll_have_lock(struct dentry *de) --{ -- struct ll_sb_info *sbi = ll_s2sbi(de->d_sb); -- struct lustre_handle lockh; -- __u64 res_id[RES_NAME_SIZE] = {0}; -- struct obd_device *obddev; -- ENTRY; -- -- if (!de->d_inode) -- RETURN(0); -- -- obddev = class_conn2obd(&sbi->ll_mdc_conn); -- res_id[0] = de->d_inode->i_ino; -- res_id[1] = de->d_inode->i_generation; -- -- CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id[0]); -- -- if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, LCK_PR, &lockh)) { -- ldlm_lock_decref(&lockh, LCK_PR); -- RETURN(1); -- } -- -- if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, LCK_PW, &lockh)) { -- ldlm_lock_decref(&lockh, LCK_PW); -- RETURN(1); -- } -- RETURN(0); --} -- --int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) --{ -- int rc; -- ENTRY; -- -- /* We don't want to cache negative dentries, so return 0 immediately. -- * We believe that this is safe, that negative dentries cannot be -- * pinned by someone else */ -- if (de->d_inode == NULL) { -- CDEBUG(D_INODE, "negative dentry: ret 0 to force lookup2\n"); -- RETURN(0); -- } -- - if (it == NULL && ll_have_lock(de)) - GOTO(out, rc = 0); -// if (it == NULL && ll_have_lock(de)) -// RETURN(1); -- -- rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish); -- if (rc < 0) { -- /* Something bad happened; overwrite it_status? */ -- CERROR("ll_intent_lock: %d\n", rc); -- } -- /* unfortunately ll_intent_lock may cause a callback and revoke our -- dentry */ -- spin_lock(&dcache_lock); -- list_del_init(&de->d_hash); -- spin_unlock(&dcache_lock); -- d_rehash(de); - - out: - if (!it) - de->d_it = NULL; -- -- RETURN(1); --} -- --int ll_set_dd(struct dentry *de) --{ -- ENTRY; -- LASSERT(de != NULL); -- -- lock_kernel(); -- -- if (de->d_fsdata != NULL) { -- CERROR("dentry %p already has d_fsdata set\n", de); -- } else { -- OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); -- sema_init(&ll_d2d(de)->lld_it_sem, 1); -- } -- -- unlock_kernel(); -- -- RETURN(0); --} -- --struct dentry_operations ll_d_ops = { -- .d_revalidate2 = ll_revalidate2, -- .d_intent_release = ll_intent_release, -- .d_release = ll_release, --}; diff --cc lustre/llite/dir.c index 4384208,6f67f4b..0000000 deleted file mode 100644,100644 --- a/lustre/llite/dir.c +++ /dev/null @@@ -1,749 -1,751 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 1992, 1993, 1994, 1995 -- * Remy Card (card@masi.ibp.fr) -- * Laboratoire MASI - Institut Blaise Pascal -- * Universite Pierre et Marie Curie (Paris VI) -- * -- * from -- * -- * linux/fs/minix/dir.c -- * linux/fs/ext2/dir.c -- * -- * Copyright (C) 1991, 1992 Linus Torvalds -- * -- * ext2 directory handling functions -- * -- * Big-endian to little-endian byte-swapping/bitmaps by -- * David S. Miller (davem@caip.rutgers.edu), 1995 -- * -- * All code that works with directory layout had been switched to pagecache -- * and moved here. AV -- * -- * Adapted for Lustre Light -- * Copyright (C) 2002, Cluster File Systems, Inc. -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --#include // for wait_on_buffer --#else --#include // for wait_on_buffer --#endif -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include --#include --#include --#include --#include -- --typedef struct ext2_dir_entry_2 ext2_dirent; -- --#define PageChecked(page) test_bit(PG_checked, &(page)->flags) --#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) -- -- --static int ll_dir_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) --{ -- return 0; --} -- --/* returns the page unlocked, but with a reference */ --static int ll_dir_readpage(struct file *file, struct page *page) --{ -- struct inode *inode = page->mapping->host; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- char *buf; -- __u64 offset; -- int rc = 0; -- struct ptlrpc_request *request; -- struct lustre_handle lockh; -- struct mds_body *body; -- struct lookup_intent it = { .it_op = IT_READDIR }; -- -- ENTRY; -- -- if ((inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT <= page->index){ -- memset(kmap(page), 0, PAGE_CACHE_SIZE); -- kunmap(page); -- GOTO(readpage_out, rc); -- } -- -- rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, &it, LCK_PR, inode, -- NULL, &lockh, NULL, 0, inode, sizeof(*inode)); -- request = (struct ptlrpc_request *)it.it_data; -- if (request) -- ptlrpc_req_finished(request); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- unlock_page(page); -- RETURN(rc); -- } -- ldlm_lock_dump((void *)(unsigned long)lockh.addr); -- -- if (PageUptodate(page)) { -- CERROR("Explain this please?\n"); -- GOTO(readpage_out, rc); -- } -- -- offset = page->index << PAGE_SHIFT; -- buf = kmap(page); -- rc = mdc_readpage(&sbi->ll_mdc_conn, inode->i_ino, -- S_IFDIR, offset, buf, &request); -- kunmap(page); -- if (!rc) { -- body = lustre_msg_buf(request->rq_repmsg, 0); -- if (!body) -- rc = -EINVAL; -- else -- inode->i_size = body->size; -- } -- ptlrpc_req_finished(request); -- EXIT; -- -- readpage_out: -- if (!rc) -- SetPageUptodate(page); -- -- unlock_page(page); -- rc = ll_unlock(LCK_PR, &lockh); -- if (rc != ELDLM_OK) -- CERROR("ll_unlock: err: %d\n", rc); -- return rc; --} /* ll_dir_readpage */ -- --struct address_space_operations ll_dir_aops = { -- readpage: ll_dir_readpage, -- prepare_write: ll_dir_prepare_write --}; -- - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) --int waitfor_one_page(struct page *page) --{ -- int error = 0; -- struct buffer_head *bh, *head = page->buffers; -- -- bh = head; -- do { -- wait_on_buffer(bh); -- if (buffer_req(bh) && !buffer_uptodate(bh)) -- error = -EIO; -- } while ((bh = bh->b_this_page) != head); -- return error; --} - #else -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) --int waitfor_one_page(struct page *page) --{ -- wait_on_page_locked(page); -- return 0; --} --#endif -- --/* -- * ext2 uses block-sized chunks. Arguably, sector-sized ones would be -- * more robust, but we have what we have -- */ --static inline unsigned ext2_chunk_size(struct inode *inode) --{ -- return inode->i_sb->s_blocksize; --} -- --static inline void ext2_put_page(struct page *page) --{ -- kunmap(page); -- page_cache_release(page); --} -- --static inline unsigned long dir_pages(struct inode *inode) --{ -- return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; --} -- --extern void set_page_clean(struct page *page); -- --static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) --{ -- struct inode *dir = page->mapping->host; -- loff_t new_size = (page->index << PAGE_CACHE_SHIFT) + to; -- int err = 0; -- -- dir->i_version = ++event; -- if (new_size > dir->i_size) -- dir->i_size = new_size; -- SetPageUptodate(page); -- set_page_clean(page); -- -- //page->mapping->a_ops->commit_write(NULL, page, from, to); -- //if (IS_SYNC(dir)) -- // err = waitfor_one_page(page); -- return err; --} -- --static void ext2_check_page(struct page *page) --{ -- struct inode *dir = page->mapping->host; -- unsigned chunk_size = ext2_chunk_size(dir); -- char *kaddr = page_address(page); -- // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count); -- unsigned offs, rec_len; -- unsigned limit = PAGE_CACHE_SIZE; -- ext2_dirent *p; -- char *error; -- -- if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { -- limit = dir->i_size & ~PAGE_CACHE_MASK; -- if (limit & (chunk_size - 1)) { -- CERROR("limit %d dir size %lld index %ld\n", -- limit, dir->i_size, page->index); -- goto Ebadsize; -- } -- for (offs = limit; offsrec_len = cpu_to_le16(chunk_size); -- p->name_len = 0; -- p->inode = 0; -- } -- if (!limit) -- goto out; -- } -- for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) { -- p = (ext2_dirent *)(kaddr + offs); -- rec_len = le16_to_cpu(p->rec_len); -- -- if (rec_len < EXT2_DIR_REC_LEN(1)) -- goto Eshort; -- if (rec_len & 3) -- goto Ealign; -- if (rec_len < EXT2_DIR_REC_LEN(p->name_len)) -- goto Enamelen; -- if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)) -- goto Espan; -- // if (le32_to_cpu(p->inode) > max_inumber) -- //goto Einumber; -- } -- if (offs != limit) -- goto Eend; --out: -- SetPageChecked(page); -- return; -- -- /* Too bad, we had an error */ -- --Ebadsize: -- CERROR("ext2_check_page" -- "size of directory #%lu is not a multiple of chunk size\n", -- dir->i_ino -- ); -- goto fail; --Eshort: -- error = "rec_len is smaller than minimal"; -- goto bad_entry; --Ealign: -- error = "unaligned directory entry"; -- goto bad_entry; --Enamelen: -- error = "rec_len is too small for name_len"; -- goto bad_entry; --Espan: -- error = "directory entry across blocks"; -- goto bad_entry; -- //Einumber: -- // error = "inode out of bounds"; --bad_entry: -- CERROR("ext2_check_page: bad entry in directory #%lu: %s - " -- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", -- dir->i_ino, error, (page->index<inode), -- rec_len, p->name_len); -- goto fail; --Eend: -- p = (ext2_dirent *)(kaddr + offs); -- CERROR("ext2_check_page" -- "entry in directory #%lu spans the page boundary" -- "offset=%lu, inode=%lu", -- dir->i_ino, (page->index<inode)); --fail: -- SetPageChecked(page); -- SetPageError(page); -- LBUG(); --} -- - static struct page * ext2_get_page(struct inode *dir, unsigned long n) -static struct page * ll_get_page(struct inode *dir, unsigned long n) --{ -- struct address_space *mapping = dir->i_mapping; -- struct page *page = read_cache_page(mapping, n, -- (filler_t*)mapping->a_ops->readpage, NULL); -- if (!IS_ERR(page)) { -- wait_on_page(page); -- kmap(page); -- if (!PageUptodate(page)) -- goto fail; -- if (!PageChecked(page)) -- ext2_check_page(page); -- if (PageError(page)) -- goto fail; -- } -- return page; -- --fail: -- ext2_put_page(page); -- return ERR_PTR(-EIO); --} -- --/* -- * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure. -- * -- * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller. -- */ --static inline int ext2_match (int len, const char * const name, -- struct ext2_dir_entry_2 * de) --{ -- if (len != de->name_len) -- return 0; -- if (!de->inode) -- return 0; -- return !memcmp(name, de->name, len); --} -- --/* -- * p is at least 6 bytes before the end of page -- */ --static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) --{ -- return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len)); --} -- --static inline unsigned --ext2_validate_entry(char *base, unsigned offset, unsigned mask) --{ -- ext2_dirent *de = (ext2_dirent*)(base + offset); -- ext2_dirent *p = (ext2_dirent*)(base + (offset&mask)); -- while ((char*)p < (char*)de) -- p = ext2_next_entry(p); -- return (char *)p - base; --} -- --static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { -- [EXT2_FT_UNKNOWN] DT_UNKNOWN, -- [EXT2_FT_REG_FILE] DT_REG, -- [EXT2_FT_DIR] DT_DIR, -- [EXT2_FT_CHRDEV] DT_CHR, -- [EXT2_FT_BLKDEV] DT_BLK, -- [EXT2_FT_FIFO] DT_FIFO, -- [EXT2_FT_SOCK] DT_SOCK, -- [EXT2_FT_SYMLINK] DT_LNK, --}; -- --static unsigned int ll_dt2fmt[DT_WHT + 1] = { -- [EXT2_FT_UNKNOWN] 0, -- [EXT2_FT_REG_FILE] S_IFREG, -- [EXT2_FT_DIR] S_IFDIR, -- [EXT2_FT_CHRDEV] S_IFCHR, -- [EXT2_FT_BLKDEV] S_IFBLK, -- [EXT2_FT_FIFO] S_IFIFO, -- [EXT2_FT_SOCK] S_IFSOCK, -- [EXT2_FT_SYMLINK] S_IFLNK --}; -- --#define S_SHIFT 12 --static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { -- [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, -- [S_IFDIR >> S_SHIFT] EXT2_FT_DIR, -- [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV, -- [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV, -- [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO, -- [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK, -- [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK, --}; -- --static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) --{ -- mode_t mode = inode->i_mode; -- de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; --} -- --int ll_readdir(struct file * filp, void * dirent, filldir_t filldir) --{ -- loff_t pos = filp->f_pos; -- struct inode *inode = filp->f_dentry->d_inode; -- // XXX struct super_block *sb = inode->i_sb; -- unsigned offset = pos & ~PAGE_CACHE_MASK; -- unsigned long n = pos >> PAGE_CACHE_SHIFT; -- unsigned long npages = dir_pages(inode); -- unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); -- unsigned char *types = NULL; -- int need_revalidate = (filp->f_version != inode->i_version); -- ENTRY; -- -- if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) -- GOTO(done, 0); -- -- types = ext2_filetype_table; -- -- for ( ; n < npages; n++, offset = 0) { -- char *kaddr, *limit; -- ext2_dirent *de; - struct page *page = ext2_get_page(inode, n); - struct page *page; - - page = ll_get_page(inode, n); -- -- /* size might have been updated by mdc_readpage */ -- npages = dir_pages(inode); -- -- if (IS_ERR(page)) -- continue; -- kaddr = page_address(page); -- if (need_revalidate) { -- offset = ext2_validate_entry(kaddr, offset, chunk_mask); -- need_revalidate = 0; -- } -- de = (ext2_dirent *)(kaddr+offset); -- limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1); -- for ( ;(char*)de <= limit; de = ext2_next_entry(de)) -- if (de->inode) { -- int over; -- unsigned char d_type = DT_UNKNOWN; -- -- if (types && de->file_type < EXT2_FT_MAX) -- d_type = types[de->file_type]; -- -- offset = (char *)de - kaddr; -- over = filldir(dirent, de->name, de->name_len, -- (n<inode), d_type); -- if (over) { -- ext2_put_page(page); -- GOTO(done,0); -- } -- } -- ext2_put_page(page); -- } -- --done: -- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; -- filp->f_version = inode->i_version; -- UPDATE_ATIME(inode); -- RETURN(0); --} -- --/* -- * ext2_find_entry() -- * -- * finds an entry in the specified directory with the wanted name. It -- * returns the page in which the entry was found, and the entry itself -- * (as a parameter - res_dir). Page is returned mapped and unlocked. -- * Entry is guaranteed to be valid. -- */ --struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, -- struct dentry *dentry, struct page ** res_page) --{ -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; -- unsigned reclen = EXT2_DIR_REC_LEN(namelen); -- unsigned long start, n; -- unsigned long npages = dir_pages(dir); -- struct page *page = NULL; -- ext2_dirent * de; -- -- /* OFFSET_CACHE */ -- *res_page = NULL; -- -- // start = dir->u.ext2_i.i_dir_start_lookup; -- start = 0; -- if (start >= npages) -- start = 0; -- n = start; -- do { -- char *kaddr; - page = ext2_get_page(dir, n); - page = ll_get_page(dir, n); -- if (!IS_ERR(page)) { -- kaddr = page_address(page); -- de = (ext2_dirent *) kaddr; -- kaddr += PAGE_CACHE_SIZE - reclen; -- while ((char *) de <= kaddr) { -- if (ext2_match (namelen, name, de)) -- goto found; -- de = ext2_next_entry(de); -- } -- ext2_put_page(page); -- } -- if (++n >= npages) -- n = 0; -- } while (n != start); -- return NULL; -- --found: -- *res_page = page; -- // dir->u.ext2_i.i_dir_start_lookup = n; -- return de; --} -- --struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p) --{ - struct page *page = ext2_get_page(dir, 0); - struct page *page = ll_get_page(dir, 0); -- ext2_dirent *de = NULL; -- -- if (!IS_ERR(page)) { -- de = ext2_next_entry((ext2_dirent *) page_address(page)); -- *p = page; -- } -- return de; --} -- --obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type) --{ -- obd_id res = 0; -- struct ext2_dir_entry_2 * de; -- struct page *page; -- -- de = ext2_find_entry (dir, dentry, &page); -- if (de) { -- res = le32_to_cpu(de->inode); -- *type = ll_dt2fmt[de->file_type]; -- kunmap(page); -- page_cache_release(page); -- } -- return res; --} -- --/* Releases the page */ --void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, -- struct page *page, struct inode *inode) --{ -- unsigned from = (char *) de - (char *) page_address(page); -- unsigned to = from + le16_to_cpu(de->rec_len); -- int err; -- -- lock_page(page); -- err = page->mapping->a_ops->prepare_write(NULL, page, from, to); -- if (err) -- LBUG(); -- de->inode = cpu_to_le32(inode->i_ino); -- ext2_set_de_type (de, inode); -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- err = ext2_commit_chunk(page, from, to); -- unlock_page(page); -- ext2_put_page(page); --} -- --/* -- * Parent is locked. -- */ --int ll_add_link (struct dentry *dentry, struct inode *inode) --{ -- struct inode *dir = dentry->d_parent->d_inode; -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; -- unsigned reclen = EXT2_DIR_REC_LEN(namelen); -- unsigned short rec_len, name_len; -- struct page *page = NULL; -- ext2_dirent * de; -- unsigned long npages = dir_pages(dir); -- unsigned long n; -- char *kaddr; -- unsigned from, to; -- int err; -- -- /* We take care of directory expansion in the same loop */ -- for (n = 0; n <= npages; n++) { - page = ext2_get_page(dir, n); - page = ll_get_page(dir, n); -- err = PTR_ERR(page); -- if (IS_ERR(page)) -- goto out; -- kaddr = page_address(page); -- de = (ext2_dirent *)kaddr; -- kaddr += PAGE_CACHE_SIZE - reclen; -- while ((char *)de <= kaddr) { -- err = -EEXIST; -- if (ext2_match (namelen, name, de)) -- goto out_page; -- name_len = EXT2_DIR_REC_LEN(de->name_len); -- rec_len = le16_to_cpu(de->rec_len); -- if ( n==npages && rec_len == 0) { -- CERROR("Fatal dir behaviour\n"); -- goto out_page; -- } -- if (!de->inode && rec_len >= reclen) -- goto got_it; -- if (rec_len >= name_len + reclen) -- goto got_it; -- de = (ext2_dirent *) ((char *) de + rec_len); -- } -- ext2_put_page(page); -- } -- LBUG(); -- return -EINVAL; -- --got_it: -- from = (char*)de - (char*)page_address(page); -- to = from + rec_len; -- lock_page(page); -- err = page->mapping->a_ops->prepare_write(NULL, page, from, to); -- if (err) -- goto out_unlock; -- if (de->inode) { -- ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len); -- de1->rec_len = cpu_to_le16(rec_len - name_len); -- de->rec_len = cpu_to_le16(name_len); -- de = de1; -- } -- de->name_len = namelen; -- memcpy (de->name, name, namelen); -- de->inode = cpu_to_le32(inode->i_ino); -- ext2_set_de_type (de, inode); -- CDEBUG(D_INODE, "type set to %o\n", de->file_type); -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- err = ext2_commit_chunk(page, from, to); -- -- // change_inode happens with the commit_chunk -- /* XXX OFFSET_CACHE */ -- --out_unlock: -- unlock_page(page); --out_page: -- ext2_put_page(page); --out: -- return err; --} -- --/* -- * ext2_delete_entry deletes a directory entry by merging it with the -- * previous entry. Page is up-to-date. Releases the page. -- */ --int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) --{ -- struct address_space *mapping = page->mapping; -- struct inode *inode = mapping->host; -- char *kaddr = page_address(page); -- unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); -- unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); -- ext2_dirent * pde = NULL; -- ext2_dirent * de = (ext2_dirent *) (kaddr + from); -- int err; -- -- while ((char*)de < (char*)dir) { -- pde = de; -- de = ext2_next_entry(de); -- } -- if (pde) -- from = (char*)pde - (char*)page_address(page); -- lock_page(page); -- err = mapping->a_ops->prepare_write(NULL, page, from, to); -- if (err) -- LBUG(); -- if (pde) -- pde->rec_len = cpu_to_le16(to-from); -- dir->inode = 0; -- inode->i_ctime = inode->i_mtime = CURRENT_TIME; -- err = ext2_commit_chunk(page, from, to); -- unlock_page(page); -- ext2_put_page(page); -- return err; --} -- --/* -- * Set the first fragment of directory. -- */ --int ext2_make_empty(struct inode *inode, struct inode *parent) --{ -- struct address_space *mapping = inode->i_mapping; -- struct page *page = grab_cache_page(mapping, 0); -- unsigned chunk_size = ext2_chunk_size(inode); -- struct ext2_dir_entry_2 * de; -- char *base; -- int err; -- ENTRY; -- -- if (!page) -- return -ENOMEM; -- base = kmap(page); -- if (!base) -- return -ENOMEM; -- -- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); -- if (err) -- goto fail; -- -- de = (struct ext2_dir_entry_2 *) base; -- de->name_len = 1; -- de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); -- memcpy (de->name, ".\0\0", 4); -- de->inode = cpu_to_le32(inode->i_ino); -- ext2_set_de_type (de, inode); -- -- de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1)); -- de->name_len = 2; -- de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1)); -- de->inode = cpu_to_le32(parent->i_ino); -- memcpy (de->name, "..\0", 4); -- ext2_set_de_type (de, inode); -- -- err = ext2_commit_chunk(page, 0, chunk_size); --fail: -- kunmap(page); -- unlock_page(page); -- page_cache_release(page); -- ENTRY; -- return err; --} -- --/* -- * routine to check that the specified directory is empty (for rmdir) -- */ --int ext2_empty_dir (struct inode * inode) --{ -- struct page *page = NULL; -- unsigned long i, npages = dir_pages(inode); -- -- for (i = 0; i < npages; i++) { -- char *kaddr; -- ext2_dirent * de; - page = ext2_get_page(inode, i); - page = ll_get_page(inode, i); -- -- if (IS_ERR(page)) -- continue; -- -- kaddr = page_address(page); -- de = (ext2_dirent *)kaddr; -- kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1); -- -- while ((char *)de <= kaddr) { -- if (de->inode != 0) { -- /* check for . and .. */ -- if (de->name[0] != '.') -- goto not_empty; -- if (de->name_len > 2) -- goto not_empty; -- if (de->name_len < 2) { -- if (de->inode != -- cpu_to_le32(inode->i_ino)) -- goto not_empty; -- } else if (de->name[1] != '.') -- goto not_empty; -- } -- de = ext2_next_entry(de); -- } -- ext2_put_page(page); -- } -- return 1; -- --not_empty: -- ext2_put_page(page); -- return 0; --} -- --struct file_operations ll_dir_operations = { -- read: generic_read_dir, -- readdir: ll_readdir --}; diff --cc lustre/llite/file.c index d6955c4,a67b023..0000000 deleted file mode 100644,100644 --- a/lustre/llite/file.c +++ /dev/null @@@ -1,805 -1,844 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/fs/ext2/file.c -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copyright (C) 1992, 1993, 1994, 1995 -- * Remy Card (card@masi.ibp.fr) -- * Laboratoire MASI - Institut Blaise Pascal -- * Universite Pierre et Marie Curie (Paris VI) -- * -- * from -- * -- * linux/fs/minix/file.c -- * -- * Copyright (C) 1991, 1992 Linus Torvalds -- * -- * ext2 fs regular file handling primitives -- * -- * 64-bit file support on 64-bit platforms by Jakub Jelinek -- * (jj@sunsite.ms.mff.cuni.cz) -- */ -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include -#include /* for lov_mds_md_size() in lov_setstripe() */ --#include -- --int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc); --extern int ll_setattr(struct dentry *de, struct iattr *attr); -- --int ll_create_objects(struct super_block *sb, obd_id id, uid_t uid, gid_t gid, - struct lov_stripe_md **lsmp) - struct lov_stripe_md **lsmp) --{ -- struct obdo *oa; -- int rc; -- ENTRY; -- -- oa = obdo_alloc(); -- if (!oa) -- RETURN(-ENOMEM); -- -- oa->o_mode = S_IFREG | 0600; - oa->o_easize = ll_mds_easize(sb); -- oa->o_id = id; -- oa->o_uid = uid; -- oa->o_gid = gid; -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | - OBD_MD_FLEASIZE | OBD_MD_FLUID | OBD_MD_FLGID; - OBD_MD_FLUID | OBD_MD_FLGID; -- rc = obd_create(ll_s2obdconn(sb), oa, lsmp); -- obdo_free(oa); -- -- if (!rc) -- LASSERT(*lsmp && (*lsmp)->lsm_object_id); -- RETURN(rc); --} -- --static int ll_file_open(struct inode *inode, struct file *file) --{ - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - struct lustre_handle *conn = ll_i2obdconn(inode); -- struct ptlrpc_request *req = NULL; -- struct ll_file_data *fd; -- struct obdo *oa; - struct lov_stripe_md *lsm = NULL; - struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm; - struct lov_mds_md *lmm = NULL; - int lmm_size = 0; -- int rc = 0; -- ENTRY; -- -- LASSERT(!file->private_data); -- -- lsm = lli->lli_smd; -- -- /* delayed create of object (intent created inode) */ -- /* XXX object needs to be cleaned up if mdc_open fails */ -- /* XXX error handling appropriate here? */ -- if (lsm == NULL) { -- if (file->f_flags & O_LOV_DELAY_CREATE) { -- CDEBUG(D_INODE, "delaying object creation\n"); -- RETURN(0); -- } -- down(&lli->lli_open_sem); -- /* Check to see if we lost the race */ -- if (!lli->lli_smd) -- rc = ll_create_objects(inode->i_sb, inode->i_ino, 0, 0, -- &lli->lli_smd); -- up(&lli->lli_open_sem); -- if (rc) -- RETURN(rc); -- -- lsm = lli->lli_smd; -- } - - /* XXX We should only send this to MDS if we just created these - * objects, except we also need to handle the user-stripe case. - */ - rc = obd_packmd(conn, &lmm, lli->lli_smd); - if (rc < 0) - GOTO(out, rc); - - lmm_size = rc; -- -- fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL); - if (!fd) - if (!fd) { - if (lmm) - obd_free_wiremd(conn, &lmm); -- GOTO(out, rc = -ENOMEM); - } -- memset(fd, 0, sizeof(*fd)); -- -- fd->fd_mdshandle.addr = (__u64)(unsigned long)file; -- get_random_bytes(&fd->fd_mdshandle.cookie, -- sizeof(fd->fd_mdshandle.cookie)); -- rc = mdc_open(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG | inode->i_mode, - file->f_flags, lsm, &fd->fd_mdshandle, &req); - file->f_flags, lmm, lmm_size, &fd->fd_mdshandle, &req); - if (lmm) - obd_free_wiremd(conn, &lmm); -- fd->fd_req = req; -- -- /* This is the "reply" refcount. */ -- ptlrpc_req_finished(req); -- if (rc) -- GOTO(out_req, -abs(rc)); -- if (!fd->fd_mdshandle.addr || -- fd->fd_mdshandle.addr == (__u64)(unsigned long)file) { -- CERROR("hmm, mdc_open didn't assign fd_mdshandle?\n"); -- /* XXX handle this how, abort or is it non-fatal? */ -- } -- -- oa = obdo_alloc(); -- if (!oa) -- GOTO(out_mdc, rc = -EINVAL); -- -- oa->o_id = lsm->lsm_object_id; -- oa->o_mode = S_IFREG; -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | -- OBD_MD_FLBLOCKS; -- rc = obd_open(ll_i2obdconn(inode), oa, lsm); -- obdo_to_inode(inode, oa, oa->o_valid & (OBD_MD_FLSIZE|OBD_MD_FLBLOCKS)); -- -- obd_oa2handle(&fd->fd_osthandle, oa); -- obdo_free(oa); -- -- if (rc) -- GOTO(out_mdc, rc = -abs(rc)); -- -- atomic_inc(&lli->lli_open_count); -- -- file->private_data = fd; -- -- RETURN(0); --out_mdc: -- mdc_close(&sbi->ll_mdc_conn, inode->i_ino, -- S_IFREG, &fd->fd_mdshandle, &req); --out_req: - ptlrpc_free_req(req); - ptlrpc_req_finished(req); /* once for reply */ - ptlrpc_req_finished(req); /* once for an early "commit" */ --//out_fd: -- fd->fd_mdshandle.cookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(ll_file_data_slab, fd); --out: -- return rc; --} -- --int ll_size_lock(struct inode *inode, struct lov_stripe_md *lsm, obd_off start, -- int mode, struct lustre_handle **lockhs_p) --{ -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct ldlm_extent extent; -- struct lustre_handle *lockhs = NULL; -- int rc, flags = 0, stripe_count; -- ENTRY; -- -- if (sbi->ll_flags & LL_SBI_NOLCK) { -- *lockhs_p = NULL; -- RETURN(0); -- } -- -- stripe_count = lsm->lsm_stripe_count; -- if (!stripe_count) -- stripe_count = 1; -- -- OBD_ALLOC(lockhs, stripe_count * sizeof(*lockhs)); -- if (lockhs == NULL) -- RETURN(-ENOMEM); -- -- extent.start = start; -- extent.end = OBD_OBJECT_EOF; -- -- rc = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, &extent, -- sizeof(extent), mode, &flags, ll_lock_callback, -- inode, sizeof(*inode), lockhs); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: %d\n", rc); -- OBD_FREE(lockhs, stripe_count * sizeof(*lockhs)); -- } else -- *lockhs_p = lockhs; -- RETURN(rc); --} -- --int ll_size_unlock(struct inode *inode, struct lov_stripe_md *lsm, int mode, -- struct lustre_handle *lockhs) --{ -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- int rc, stripe_count; -- ENTRY; -- -- if (sbi->ll_flags & LL_SBI_NOLCK) -- RETURN(0); -- -- if (lockhs == NULL) { -- LBUG(); -- RETURN(-EINVAL); -- } -- -- rc = obd_cancel(&sbi->ll_osc_conn, lsm, mode, lockhs); -- if (rc != ELDLM_OK) { -- CERROR("lock cancel: %d\n", rc); -- LBUG(); -- } -- -- stripe_count = lsm->lsm_stripe_count; -- if (!stripe_count) -- stripe_count = 1; -- -- OBD_FREE(lockhs, stripe_count * sizeof(*lockhs)); -- RETURN(rc); --} -- --int ll_file_size(struct inode *inode, struct lov_stripe_md *lsm) --{ -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct lustre_handle *lockhs; -- struct obdo oa; -- int err, rc; -- ENTRY; -- -- LASSERT(lsm); -- LASSERT(sbi); -- -- rc = ll_size_lock(inode, lsm, 0, LCK_PR, &lockhs); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: %d\n", rc); -- RETURN(rc); -- } -- -- oa.o_id = lsm->lsm_object_id; -- oa.o_mode = S_IFREG; -- oa.o_valid = OBD_MD_FLID|OBD_MD_FLTYPE|OBD_MD_FLSIZE|OBD_MD_FLBLOCKS; -- rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm); -- if (!rc) -- obdo_to_inode(inode, &oa, -- oa.o_valid & ~(OBD_MD_FLTYPE | OBD_MD_FLMODE)); -- -- err = ll_size_unlock(inode, lsm, LCK_PR, lockhs); -- if (err != ELDLM_OK) { -- CERROR("lock cancel: %d\n", err); -- LBUG(); -- } -- RETURN(rc); --} -- --static int ll_file_release(struct inode *inode, struct file *file) --{ -- struct ptlrpc_request *req = NULL; -- struct ll_file_data *fd; -- struct obdo oa; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct ll_inode_info *lli = ll_i2info(inode); -- struct lov_stripe_md *lsm = lli->lli_smd; -- int rc, rc2; -- -- ENTRY; -- -- fd = (struct ll_file_data *)file->private_data; -- if (!fd) { - LBUG(); - GOTO(out, rc = -EINVAL); - LASSERT(file->f_flags & O_LOV_DELAY_CREATE); - GOTO(out, rc = 0); -- } -- -- memset(&oa, 0, sizeof(oa)); -- oa.o_id = lsm->lsm_object_id; -- oa.o_mode = S_IFREG; -- oa.o_valid = OBD_MD_FLTYPE | OBD_MD_FLID; -- obd_handle2oa(&oa, &fd->fd_osthandle); -- rc = obd_close(ll_i2obdconn(inode), &oa, lsm); -- if (rc) -- GOTO(out_mdc, rc = -abs(rc)); -- --#if 0 --#error "This should only be done on the node that already has the EOF lock" --#error "and only in the case where the file size actually changed. For now" --#error "we don't care about the size on the MDS, since we never use it (the" --#error "OST always has the authoritative size and we don't even use the MDS." -- /* If this fails and we goto out_fd, the file size on the MDS is out of -- * date. Is that a big deal? */ -- if (file->f_mode & FMODE_WRITE) { -- struct lustre_handle *lockhs; -- -- rc = ll_size_lock(inode, lsm, 0, LCK_PR, &lockhs); -- if (rc) -- GOTO(out_mdc, -abs(rc)); -- -- oa.o_id = lsm->lsm_object_id; -- oa.o_mode = S_IFREG; -- oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | -- OBD_MD_FLBLOCKS; -- rc = obd_getattr(&sbi->ll_osc_conn, &oa, lsm); -- if (!rc) { -- struct iattr attr; -- attr.ia_valid = (ATTR_MTIME | ATTR_CTIME | ATTR_ATIME | -- ATTR_SIZE); -- attr.ia_mtime = inode->i_mtime; -- attr.ia_ctime = inode->i_ctime; -- attr.ia_atime = inode->i_atime; -- attr.ia_size = oa.o_size; -- -- inode->i_blocks = oa.o_blocks; -- -- /* XXX: this introduces a small race that we should -- * evaluate */ -- rc = ll_inode_setattr(inode, &attr, 0); -- } -- rc2 = ll_size_unlock(inode, lli->lli_smd, LCK_PR, lockhs); -- if (rc2) { -- CERROR("lock cancel: %d\n", rc); -- LBUG(); -- if (!rc) -- rc = rc2; -- } -- } --#endif -- --out_mdc: -- rc2 = mdc_close(&sbi->ll_mdc_conn, inode->i_ino, -- S_IFREG, &fd->fd_mdshandle, &req); -- ptlrpc_req_finished(req); -- if (rc2) { -- if (!rc) -- rc = -abs(rc2); -- GOTO(out_fd, rc); -- } - CDEBUG(D_HA, "matched req %p xid "LPD64" transno "LPD64" op " - "%d->%s:%d\n", fd->fd_req, fd->fd_req->rq_xid, - fd->fd_req->rq_repmsg->transno, fd->fd_req->rq_reqmsg->opc, - fd->fd_req->rq_import->imp_connection->c_remote_uuid, - fd->fd_req->rq_import->imp_client->cli_request_portal); - DEBUG_REQ(D_HA, fd->fd_req, "matched open for this close: "); -- ptlrpc_req_finished(fd->fd_req); -- -- if (atomic_dec_and_test(&lli->lli_open_count)) { -- CDEBUG(D_INFO, "last close, cancelling unused locks\n"); -- rc = obd_cancel_unused(ll_i2obdconn(inode), lsm, 0); -- if (rc) -- CERROR("obd_cancel_unused: %d\n", rc); -- } else { -- CDEBUG(D_INFO, "not last close, not cancelling unused locks\n"); -- } -- -- EXIT; -- --out_fd: -- fd->fd_mdshandle.cookie = DEAD_HANDLE_MAGIC; -- file->private_data = NULL; -- kmem_cache_free(ll_file_data_slab, fd); --out: -- return rc; --} -- --static inline void ll_remove_suid(struct inode *inode) --{ -- unsigned int mode; -- -- /* set S_IGID if S_IXGRP is set, and always set S_ISUID */ -- mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID; -- -- /* was any of the uid bits set? */ -- mode &= inode->i_mode; -- if (mode && !capable(CAP_FSETID)) { -- inode->i_mode &= ~mode; -- // XXX careful here - we cannot change the size -- } --} -- --static void ll_update_atime(struct inode *inode) --{ -- struct iattr attr; -- -- attr.ia_atime = CURRENT_TIME; -- attr.ia_valid = ATTR_ATIME; -- -- if (inode->i_atime == attr.ia_atime) return; -- if (IS_RDONLY(inode)) return; -- if (IS_NOATIME(inode)) return; -- -- /* ll_inode_setattr() sets inode->i_atime from attr.ia_atime */ -- ll_inode_setattr(inode, &attr, 0); --} -- --int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new, -- void *data, __u32 data_len, int flag) --{ -- struct inode *inode = data; -- struct lustre_handle lockh; -- int rc; -- ENTRY; -- -- if (data_len != sizeof(struct inode)) -- LBUG(); -- -- if (inode == NULL) -- LBUG(); -- -- switch (flag) { -- case LDLM_CB_BLOCKING: -- ldlm_lock2handle(lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc != ELDLM_OK) -- CERROR("ldlm_cli_cancel failed: %d\n", rc); -- break; -- case LDLM_CB_CANCELING: -- CDEBUG(D_INODE, "invalidating obdo/inode %ld\n", inode->i_ino); -- /* FIXME: do something better than throwing away everything */ -- //down(&inode->i_sem); -- ll_invalidate_inode_pages(inode); -- //up(&inode->i_sem); -- break; -- default: -- LBUG(); -- } -- -- RETURN(0); --} -- --static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, -- loff_t *ppos) --{ -- struct ll_file_data *fd = (struct ll_file_data *)filp->private_data; -- struct inode *inode = filp->f_dentry->d_inode; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct lustre_handle *lockhs = NULL; -- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; -- int flags = 0; -- ldlm_error_t err; -- ssize_t retval; -- ENTRY; -- -- /* If we don't refresh the file size, generic_file_read may not even -- * call us */ -- retval = ll_file_size(inode, lsm); -- if (retval < 0) { -- CERROR("ll_file_size: %d\n", retval); -- RETURN(retval); -- } -- -- if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && -- !(sbi->ll_flags & LL_SBI_NOLCK)) { -- struct ldlm_extent extent; -- OBD_ALLOC(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); -- if (!lockhs) -- RETURN(-ENOMEM); -- -- extent.start = *ppos; -- extent.end = *ppos + count; -- CDEBUG(D_INFO, "Locking inode %ld, start "LPU64" end "LPU64"\n", -- inode->i_ino, extent.start, extent.end); -- -- err = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, -- &extent, sizeof(extent), LCK_PR, &flags, -- ll_lock_callback, inode, sizeof(*inode), -- lockhs); -- if (err != ELDLM_OK) { -- OBD_FREE(lockhs, lsm->lsm_stripe_count*sizeof(*lockhs)); -- CERROR("lock enqueue: err: %d\n", err); -- RETURN(err); -- } -- } -- -- CDEBUG(D_INFO, "Reading inode %ld, %d bytes, offset %Ld\n", -- inode->i_ino, count, *ppos); -- retval = generic_file_read(filp, buf, count, ppos); -- -- if (retval > 0) -- ll_update_atime(inode); -- -- if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && -- !(sbi->ll_flags & LL_SBI_NOLCK)) { -- err = obd_cancel(&sbi->ll_osc_conn, lsm, LCK_PR, lockhs); -- if (err != ELDLM_OK) { -- CERROR("lock cancel: err: %d\n", err); -- retval = err; -- } -- } -- -- if (lockhs) -- OBD_FREE(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); -- RETURN(retval); --} -- --/* -- * Write to a file (through the page cache). -- */ --static ssize_t --ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) --{ -- struct ll_file_data *fd = (struct ll_file_data *)file->private_data; -- struct inode *inode = file->f_dentry->d_inode; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct lustre_handle *lockhs = NULL, *eof_lockhs = NULL; -- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; -- int flags = 0; -- ldlm_error_t err; -- ssize_t retval; -- ENTRY; -- -- if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { -- struct obdo *oa; -- -- oa = obdo_alloc(); -- if (!oa) -- RETURN(-ENOMEM); -- -- err = ll_size_lock(inode, lsm, 0, LCK_PW, &eof_lockhs); -- if (err) { -- obdo_free(oa); -- RETURN(err); -- } -- -- oa->o_id = lsm->lsm_object_id; -- oa->o_mode = inode->i_mode; -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLSIZE | -- OBD_MD_FLBLOCKS; -- obd_handle2oa(oa, &fd->fd_osthandle); -- retval = obd_getattr(&sbi->ll_osc_conn, oa, lsm); -- if (retval) { -- obdo_free(oa); -- GOTO(out_eof, retval); -- } -- -- *ppos = oa->o_size; -- obdo_to_inode(inode, oa, oa->o_valid); -- obdo_free(oa); -- } -- -- if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) && -- !(sbi->ll_flags & LL_SBI_NOLCK)) { -- struct ldlm_extent extent; -- OBD_ALLOC(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); -- if (!lockhs) -- GOTO(out_eof, retval = -ENOMEM); -- extent.start = *ppos; -- extent.end = *ppos + count; -- CDEBUG(D_INFO, "Locking inode %ld, start "LPU64" end "LPU64"\n", -- inode->i_ino, extent.start, extent.end); -- -- err = obd_enqueue(&sbi->ll_osc_conn, lsm, NULL, LDLM_EXTENT, -- &extent, sizeof(extent), LCK_PW, &flags, -- ll_lock_callback, inode, sizeof(*inode), -- lockhs); -- if (err != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", err); -- GOTO(out_free, retval = err); -- } -- } -- -- CDEBUG(D_INFO, "Writing inode %ld, %ld bytes, offset "LPD64"\n", -- inode->i_ino, (long)count, *ppos); -- -- retval = generic_file_write(file, buf, count, ppos); -- -- if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK) || -- sbi->ll_flags & LL_SBI_NOLCK) { -- err = obd_cancel(&sbi->ll_osc_conn, lsm, LCK_PW, lockhs); -- if (err != ELDLM_OK) { -- CERROR("lock cancel: err: %d\n", err); -- GOTO(out_free, retval = err); -- } -- } -- -- EXIT; -- out_free: -- if (lockhs) -- OBD_FREE(lockhs, lsm->lsm_stripe_count * sizeof(*lockhs)); -- -- out_eof: -- if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND) { -- err = ll_size_unlock(inode, lsm, LCK_PW, eof_lockhs); -- if (err && !retval) -- retval = err; -- } -- -- return retval; --} -- -/* Retrieve object striping information. - * - * @arg is a pointer to a user struct with one or more of the fields set to - * indicate the application preference: lmm_stripe_count, lmm_stripe_size, - * lmm_stripe_offset, and lmm_stripe_pattern. lmm_magic must be LOV_MAGIC. - */ --static int ll_lov_setstripe(struct inode *inode, struct file *file, - struct lov_user_md *lum) - unsigned long arg) --{ -- struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm; - int size = ll_mds_easize(inode->i_sb); - struct lov_mds_md *lmm = NULL, *lmmu = (void *)arg; - struct lustre_handle *conn = ll_i2obdconn(inode); -- int rc; -- - rc = verify_area(VERIFY_READ, lum, sizeof(*lum)); - if (rc) - rc = obd_alloc_wiremd(conn, &lmm); - if (rc < 0) -- RETURN(rc); - - rc = copy_from_user(lmm, lmmu, sizeof(*lmm)); - if (rc) - GOTO(out_free, rc = -EFAULT); - - if (lmm->lmm_magic != LOV_MAGIC) { - CERROR("bad LOV magic %X\n", lmm->lmm_magic); - GOTO(out_free, rc = -EINVAL); - } -- -- down(&lli->lli_open_sem); -- if (lli->lli_smd) { -- CERROR("striping data already set for %d\n", inode->i_ino); -- GOTO(out_lov_up, rc = -EPERM); -- } - - OBD_ALLOC(lli->lli_smd, size); - if (!lli->lli_smd) - GOTO(out_lov_up, rc = -ENOMEM); - - lsm = lli->lli_smd; - lsm->lsm_magic = LOV_MAGIC; - lsm->lsm_stripe_size = lum->lum_stripe_size; - lsm->lsm_stripe_pattern = lum->lum_stripe_pattern; - lsm->lsm_stripe_offset = lum->lum_stripe_offset; - lsm->lsm_stripe_count = lum->lum_stripe_count; - lsm->lsm_mds_easize = size; - rc = obd_unpackmd(conn, &lli->lli_smd, lmm); - if (rc < 0) { - CERROR("error setting LOV striping on %d: rc = %d\n", - inode->i_ino, rc); - GOTO(out_lov_up, rc); - } -- - file->f_flags &= ~O_LOV_DELAY_CREATE; - rc = ll_create_objects(inode->i_sb, inode->i_ino, 0, 0, &lsm); - if (rc) - OBD_FREE(lli->lli_smd, size); - else - rc = ll_create_objects(inode->i_sb, inode->i_ino, 0, 0, &lli->lli_smd); - if (rc) { - obd_free_memmd(conn, &lli->lli_smd); - } else { - file->f_flags &= ~O_LOV_DELAY_CREATE; -- rc = ll_file_open(inode, file); - } --out_lov_up: -- up(&lli->lli_open_sem); -out_free: - obd_free_wiremd(conn, &lmm); -- return rc; --} -- -/* Retrieve object striping information. - * - * @arg is a pointer to a user struct with lmm_ost_count indicating - * the maximum number of OST indices which will fit in the user buffer. - * lmm_magic must be LOV_MAGIC. - */ --static int ll_lov_getstripe(struct inode *inode, unsigned long arg) --{ - struct lov_user_md lum; - struct lov_user_md *lump; - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - struct lov_user_oinfo *luoip; - struct lov_oinfo *loip; - int count, len, i, rc; - struct lov_mds_md lmm, *lmmu = (void *)arg, *lmmk = NULL; - struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; - struct lustre_handle *conn = ll_i2obdconn(inode); - int ost_count, rc, lmm_size; -- - rc = copy_from_user(&lum, (void *)arg, sizeof(lum)); - if (rc) - RETURN(rc); - if (!lsm) - RETURN(-ENODATA); -- - if ((count = lsm->lsm_stripe_count) == 0) - count = 1; - rc = copy_from_user(&lmm, lmmu, sizeof(lmm)); - if (rc) - RETURN(-EFAULT); -- - if (lum.lum_stripe_count < count) - if (lmm.lmm_magic != LOV_MAGIC) -- RETURN(-EINVAL); -- - len = sizeof(*lump) + count * sizeof(*luoip); - if (lsm->lsm_stripe_count == 0) - ost_count = 1; - else { - struct obd_device *obd = class_conn2obd(conn); - struct lov_obd *lov = &obd->u.lov; - ost_count = lov->desc.ld_tgt_count; - } -- - rc = verify_area(VERIFY_WRITE, (void *)arg, len); - if (rc) - /* XXX we _could_ check if indices > user lmm_ost_count are zero */ - if (lmm.lmm_ost_count < ost_count) - RETURN(-EOVERFLOW); - - rc = obd_packmd(conn, &lmmk, lsm); - if (rc < 0) -- RETURN(rc); -- - lump = (struct lov_user_md *)arg; - lump->lum_stripe_count = count; - luoip = lump->lum_luoinfo; - lmm_size = rc; -- - /* LOV STACKING layering violation to make LOV/OSC return same data */ -- if (lsm->lsm_stripe_count == 0) { - lump->lum_stripe_size = 0; - lump->lum_stripe_pattern = 0; - lump->lum_stripe_offset = 0; - luoip->luo_idx = 0; - luoip->luo_id = lsm->lsm_object_id; - } else { - lump->lum_stripe_size = lsm->lsm_stripe_size; - lump->lum_stripe_pattern = lsm->lsm_stripe_pattern; - lump->lum_stripe_offset = lsm->lsm_stripe_offset; - struct lov_object_id *loi; -- - loip = lsm->lsm_oinfo; - for (i = 0; i < count; i++, luoip++, loip++) { - luoip->luo_idx = loip->loi_ost_idx; - luoip->luo_id = loip->loi_id; - loi = (void *)lmmu + offsetof(typeof(*lmmu), lmm_objects); - rc = copy_to_user(loi, &lsm->lsm_object_id, sizeof(*loi)); - if (rc) { - lmm_size = 0; - rc = -EFAULT; - } else { - lmmk->lmm_magic = LOV_MAGIC; - lmmk->lmm_ost_count = lmmk->lmm_stripe_count = 1; -- } -- } -- - RETURN(0); - if (lmm_size && copy_to_user(lmmu, lmmk, lmm_size)) - rc = -EFAULT; - - obd_free_wiremd(conn, &lmmk); - - RETURN(rc); --} -- --int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -- unsigned long arg) --{ -- struct ll_file_data *fd = (struct ll_file_data *)file->private_data; -- struct lustre_handle *conn; -- int flags; -- -- switch(cmd) { -- case LL_IOC_GETFLAGS: -- /* Get the current value of the file flags */ -- return put_user(fd->fd_flags, (int *)arg); -- case LL_IOC_SETFLAGS: -- case LL_IOC_CLRFLAGS: -- /* Set or clear specific file flags */ -- /* XXX This probably needs checks to ensure the flags are -- * not abused, and to handle any flag side effects. -- */ -- if (get_user(flags, (int *) arg)) -- return -EFAULT; -- -- if (cmd == LL_IOC_SETFLAGS) -- fd->fd_flags |= flags; -- else -- fd->fd_flags &= ~flags; -- return 0; -- case LL_IOC_LOV_SETSTRIPE: - return ll_lov_setstripe(inode, file, (struct lov_user_md *)arg); - return ll_lov_setstripe(inode, file, arg); -- case LL_IOC_LOV_GETSTRIPE: -- return ll_lov_getstripe(inode, arg); -- -- /* We need to special case any other ioctls we want to handle, -- * to send them to the MDS/OST as appropriate and to properly -- * network encode the arg field. -- case EXT2_IOC_GETFLAGS: -- case EXT2_IOC_SETFLAGS: -- case EXT2_IOC_GETVERSION_OLD: -- case EXT2_IOC_GETVERSION_NEW: -- case EXT2_IOC_SETVERSION_OLD: -- case EXT2_IOC_SETVERSION_NEW: -- */ -- default: -- conn = ll_i2obdconn(inode); -- return obd_iocontrol(cmd, conn, 0, NULL, (void *)arg); -- } --} -- --loff_t ll_file_seek(struct file *file, loff_t offset, int origin) --{ -- struct inode *inode = file->f_dentry->d_inode; -- long long retval; -- ENTRY; -- -- switch (origin) { -- case 2: { -- struct ll_inode_info *lli = ll_i2info(inode); -- -- retval = ll_file_size(inode, lli->lli_smd); -- if (retval) -- RETURN(retval); -- -- offset += inode->i_size; -- break; -- } -- case 1: -- offset += file->f_pos; -- } -- retval = -EINVAL; -- if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) { -- if (offset != file->f_pos) { -- file->f_pos = offset; --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- file->f_reada = 0; --#endif -- file->f_version = ++event; -- } -- retval = offset; -- } -- RETURN(retval); --} -- --/* XXX this does not need to do anything for data, it _does_ need to -- call setattr */ --int ll_fsync(struct file *file, struct dentry *dentry, int data) --{ -- return 0; --} -- -- -- --static int ll_inode_revalidate(struct dentry *dentry) --{ -- struct inode *inode = dentry->d_inode; -- struct lov_stripe_md *lsm; -- ENTRY; -- -- if (!inode) -- RETURN(0); -- -- lsm = ll_i2info(inode)->lli_smd; -- if (!lsm) /* object not yet allocated, don't validate size */ -- RETURN(0); -- -- RETURN(ll_file_size(inode, lsm)); --} -- --#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) --static int ll_getattr(struct vfsmount *mnt, struct dentry *de, -- struct kstat *stat) --{ -- return ll_inode_revalidate(de); --} --#endif -- --struct file_operations ll_file_operations = { -- read: ll_file_read, -- write: ll_file_write, -- ioctl: ll_file_ioctl, -- open: ll_file_open, -- release: ll_file_release, -- mmap: generic_file_mmap, -- llseek: ll_file_seek, -- fsync: NULL --}; -- --struct inode_operations ll_file_inode_operations = { -- setattr: ll_setattr, -- truncate: ll_truncate, --#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -- getattr: ll_getattr, --#else -- revalidate: ll_inode_revalidate, --#endif --}; diff --cc lustre/llite/lproc_llite.c index 0ccfb9c,65df985..0000000 deleted file mode 100644,100644 --- a/lustre/llite/lproc_llite.c +++ /dev/null @@@ -1,247 -1,249 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include -- -- - int rd_path(char* page, char **start, off_t off, int count, int *eof, -int rd_path(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} - int rd_fstype(char* page, char **start, off_t off, int count, int *eof, - -int rd_fstype(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct super_block *sb = (struct super_block*)data; - - len += snprintf(page, count, "%s\n", sb->s_type->name); - - len += snprintf(page, count, "%s\n", sb->s_type->name); -- return len; --} - int rd_blksize(char* page, char **start, off_t off, int count, int *eof, - -int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct super_block *sb = (struct super_block*)data; -- struct statfs mystats; -- -- (sb->s_op->statfs)(sb, &mystats); - len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bsize)); - len += snprintf(page, count, "%lu\n", mystats.f_bsize); -- return len; -- --} - int rd_kbytestotal(char* page, char **start, off_t off, int count, int *eof, - -int rd_kbytestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct super_block *sb = (struct super_block*)data; -- struct statfs mystats; -- __u32 blk_size; -- __u64 result; -- -- (sb->s_op->statfs)(sb, &mystats); -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_blocks; - - while(blk_size >>= 1){ - - while(blk_size >>= 1) -- result <<= 1; - } - - len += snprintf(page, count, LPU64"\n", result); - - len += snprintf(page, count, LPU64"\n", result); -- return len; - --} -- -- - int rd_kbytesfree(char* page, char **start, off_t off, int count, int *eof, -int rd_kbytesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct super_block *sb = (struct super_block*)data; - struct statfs mystats; - struct statfs mystats; -- __u32 blk_size; -- __u64 result; -- -- (sb->s_op->statfs)(sb, &mystats); -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_bfree; - - while(blk_size >>= 1){ - - while(blk_size >>= 1) -- result <<= 1; - } - - len += snprintf(page, count, LPU64"\n", result); - return len; -- - - len += snprintf(page, count, LPU64"\n", result); - return len; --} -- - int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ - -- int len = 0; -- struct super_block *sb = (struct super_block*)data; - struct statfs mystats; - - struct statfs mystats; - -- (sb->s_op->statfs)(sb, &mystats); - len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_files)); - len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_files)); -- return len; --} -- - int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ - -- int len = 0; -- struct super_block *sb = (struct super_block*)data; - struct statfs mystats; - - struct statfs mystats; - -- (sb->s_op->statfs)(sb, &mystats); - len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_ffree)); - len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_ffree)); -- return len; --} -- - int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} - int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct super_block *sb = (struct super_block*)data; -- struct ll_sb_info *sbi = ll_s2sbi(sb); - len += snprintf(page, count, "%s\n", sbi->ll_sb_uuid); - return len; - - len += snprintf(page, count, "%s\n", sbi->ll_sb_uuid); - - return len; -- --} - int rd_dev_name(char* page, char **start, off_t off, int count, int *eof, -int rd_dev_name(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_name); -- return len; --} -- - int rd_dev_uuid(char* page, char **start, off_t off, int count, int *eof, -int rd_dev_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_uuid); -- return len; --} -- -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/mntpt_path", rd_path, 0, 0}, -- {"status/fstype", rd_fstype, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytestotal",rd_kbytestotal, 0, 0}, -- {"status/kbytesfree", rd_kbytesfree, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {0} --}; -- - /* -/* -- * Proc registration function for Lustre -- * file system -- */ -- -- --#define MAX_STRING_SIZE 100 --void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc) --{ - char mnt_name[MAX_STRING_SIZE]; - char uuid_name[MAX_STRING_SIZE]; - char mnt_name[MAX_STRING_SIZE+1]; - char uuid_name[MAX_STRING_SIZE+1]; -- struct lprocfs_vars d_vars[3]; -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct obd_device* obd; -- int err; -- - -- /* Register this mount instance with LProcFS */ - snprintf(mnt_name, 100, "mount_%s", sbi->ll_sb_uuid); - snprintf(mnt_name, MAX_STRING_SIZE, "mount_%s", sbi->ll_sb_uuid); - mnt_name[MAX_STRING_SIZE] = '\0'; -- sbi->ll_proc_root = lprocfs_reg_mnt(mnt_name); - if (!sbi->ll_proc_root) - if (sbi->ll_proc_root == NULL) { -- CDEBUG(D_OTHER, "Could not register FS"); - return; - } -- /* Add the static configuration info */ -- err = lprocfs_add_vars(sbi->ll_proc_root,status_var_nm_1, sb); - if (err) - if (err) { -- CDEBUG(D_OTHER, "Unable to add procfs variables\n"); - - return; - } -- /* MDC */ -- obd = class_uuid2obd(mdc); - - - snprintf(mnt_name, MAX_STRING_SIZE, "status/%s/common_name", - snprintf(mnt_name, MAX_STRING_SIZE, "status/%s/common_name", -- obd->obd_type->typ_name); - - mnt_name[MAX_STRING_SIZE] = '\0'; -- memset(d_vars, 0, sizeof(d_vars)); -- d_vars[0].read_fptr = rd_dev_name; -- d_vars[0].write_fptr = NULL; -- d_vars[0].name = mnt_name; - -- snprintf(uuid_name, MAX_STRING_SIZE, "status/%s/uuid", -- obd->obd_type->typ_name); - uuid_name[MAX_STRING_SIZE] = '\0'; -- d_vars[1].read_fptr = rd_dev_uuid; -- d_vars[1].write_fptr = NULL; -- d_vars[1].name = uuid_name; -- -- err = lprocfs_add_vars(sbi->ll_proc_root, d_vars, obd); - if (err) - if (err) { -- CDEBUG(D_OTHER, "Unable to add fs proc dynamic variables\n"); - - return; - } -- /* OSC or LOV*/ -- obd = class_uuid2obd(osc); -- -- /* Reuse mnt_name */ - snprintf(mnt_name, MAX_STRING_SIZE, "status/%s/common_name", - obd->obd_type->typ_name); - - snprintf(mnt_name, MAX_STRING_SIZE, - "status/%s/common_name", obd->obd_type->typ_name); - mnt_name[MAX_STRING_SIZE] = '\0'; -- memset(d_vars, 0, sizeof(d_vars)); -- d_vars[0].read_fptr = rd_dev_name; -- d_vars[0].write_fptr = NULL; -- d_vars[0].name = mnt_name; -- -- snprintf(uuid_name, MAX_STRING_SIZE, "status/%s/uuid", -- obd->obd_type->typ_name); - uuid_name[MAX_STRING_SIZE] = '\0'; -- d_vars[1].read_fptr = rd_dev_uuid; -- d_vars[1].write_fptr = NULL; -- d_vars[1].name = uuid_name; -- -- err = lprocfs_add_vars(sbi->ll_proc_root, d_vars, obd); - if (err) - if (err) { -- CDEBUG(D_OTHER, "Unable to add fs proc dynamic variables\n"); - - return; - } --} --#undef MAX_STRING_SIZE diff --cc lustre/llite/namei.c index 8c6d9b6,9670af0..0000000 deleted file mode 100644,100644 --- a/lustre/llite/namei.c +++ /dev/null @@@ -1,997 -1,988 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copyright (C) 1992, 1993, 1994, 1995 -- * Remy Card (card@masi.ibp.fr) -- * Laboratoire MASI - Institut Blaise Pascal -- * Universite Pierre et Marie Curie (Paris VI) -- * -- * from -- * -- * linux/fs/ext2/namei.c -- * -- * Copyright (C) 1991, 1992 Linus Torvalds -- * -- * Big-endian to little-endian byte-swapping/bitmaps by -- * David S. Miller (davem@caip.rutgers.edu), 1995 -- * Directory entry file type support and forward compatibility hooks -- * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 -- * -- * Changes for use in OBDFS -- * Copyright (c) 1999, Seagate Technology Inc. -- * Copyright (C) 2001, Cluster File Systems, Inc. -- * Rewritten based on recent ext2 page cache use. -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include - #include -- --extern struct address_space_operations ll_aops; -- --/* from super.c */ --extern void ll_change_inode(struct inode *inode); --extern int ll_setattr(struct dentry *de, struct iattr *attr); -- --/* from dir.c */ --extern int ll_add_link (struct dentry *dentry, struct inode *inode); --obd_id ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *typ); --int ext2_make_empty(struct inode *inode, struct inode *parent); --struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, -- struct dentry *dentry, struct page ** res_page); --int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ); --int ext2_empty_dir (struct inode * inode); --struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p); --void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, -- struct page *page, struct inode *inode); -- --/* -- * Couple of helper functions - make the code slightly cleaner. -- */ --static inline void ext2_inc_count(struct inode *inode) --{ -- inode->i_nlink++; --} -- --/* postpone the disk update until the inode really goes away */ --static inline void ext2_dec_count(struct inode *inode) --{ -- inode->i_nlink--; --} - --static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) --{ -- int err; -- err = ll_add_link(dentry, inode); -- if (!err) { -- d_instantiate(dentry, inode); -- return 0; -- } -- ext2_dec_count(inode); -- iput(inode); -- return err; --} -- --/* methods */ -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --static int ll_find_inode(struct inode *inode, unsigned long ino, void *opaque) --#else --static int ll_test_inode(struct inode *inode, void *opaque) --#endif --{ -- struct ll_read_inode2_cookie *lic = opaque; -- struct mds_body *body = lic->lic_body; -- -- if (inode->i_generation != lic->lic_body->generation) -- return 0; -- -- /* Apply the attributes in 'opaque' to this inode */ -- ll_update_inode(inode, body); -- -- return 1; --} -- --extern struct dentry_operations ll_d_ops; -- --int ll_unlock(__u32 mode, struct lustre_handle *lockh) --{ -- ENTRY; -- -- ldlm_lock_decref(lockh, mode); -- -- RETURN(0); --} -- --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) --extern int ll_read_inode2(struct inode *inode, void *opaque); --struct inode *ll_iget(struct super_block *sb, ino_t hash, -- struct ll_read_inode2_cookie *lic) --{ -- struct inode *inode; - - inode = iget5_locked(sb, hash, ll_test_inode, ll_read_inode2, lic); -- - if (!inode) - return ERR_PTR(-ENOMEM); - LASSERT(hash != 0); - inode = iget5_locked(sb, hash, ll_test_inode, ll_read_inode2, lic); -- - if (inode->i_state & I_NEW) { - if (!inode) - return ERR_PTR(-ENOMEM); -- - unlock_new_inode(inode); - } - if (inode->i_state & I_NEW) - unlock_new_inode(inode); -- -- // XXX Coda always fills inodes, should Lustre? -- return inode; --} --#else --struct inode *ll_iget(struct super_block *sb, ino_t hash, -- struct ll_read_inode2_cookie *lic) --{ -- struct inode *inode; - LASSERT(hash != 0); -- inode = iget4(sb, hash, ll_find_inode, lic); -- return inode; --} --#endif -- --static int ll_intent_to_lock_mode(struct lookup_intent *it) --{ -- /* CREAT needs to be tested before open (both could be set) */ -- if ((it->it_op & (IT_CREAT | IT_MKDIR | IT_SETATTR | IT_MKNOD))) { -- return LCK_PW; -- } else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_UNLINK | -- IT_RMDIR | IT_RENAME | IT_RENAME2 | IT_READLINK| -- IT_LINK | IT_LINK2 | IT_LOOKUP | IT_SYMLINK)) { -- return LCK_PR; -- } -- -- LBUG(); -- RETURN(-EINVAL); --} -- --#define LL_LOOKUP_POSITIVE 1 --#define LL_LOOKUP_NEGATIVE 2 -- --int ll_intent_lock(struct inode *parent, struct dentry **de, -- struct lookup_intent *it, -- intent_finish_cb intent_finish) --{ -- struct dentry *dentry = *de; -- struct ll_sb_info *sbi = ll_i2sbi(parent); -- struct lustre_handle lockh; -- struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; -- struct ptlrpc_request *request = NULL; - char *tgt = NULL; - int rc, lock_mode, tgtlen = 0, offset, flag = LL_LOOKUP_POSITIVE; - char *data = NULL; - int rc, lock_mode, datalen = 0, offset, flag = LL_LOOKUP_POSITIVE; -- obd_id ino = 0; -- -- ENTRY; -- -- if (it == NULL) -- it = &lookup_it; -- -- CDEBUG(D_INFO, "name: %*s, intent: %s\n", dentry->d_name.len, -- dentry->d_name.name, ldlm_it2str(it->it_op)); -- -- if (dentry->d_name.len > EXT2_NAME_LEN) -- RETURN(-ENAMETOOLONG); -- -- lock_mode = ll_intent_to_lock_mode(it); -- if (it->it_op & IT_SYMLINK) { - tgt = it->it_data; - tgtlen = strlen(tgt); - data = it->it_data; - datalen = strlen(data) + 1; -- it->it_data = NULL; -- } -- -- rc = mdc_enqueue(&sbi->ll_mdc_conn, LDLM_PLAIN, it, lock_mode, parent, - dentry, &lockh, tgt, tgtlen, parent, sizeof(*parent)); - dentry, &lockh, data, datalen, parent,sizeof(*parent)); -- if (rc < 0) -- RETURN(rc); -- memcpy(it->it_lock_handle, &lockh, sizeof(lockh)); -- -- request = (struct ptlrpc_request *)it->it_data; -- /* it_disposition == 1 indicates that the server performed the -- * intent on our behalf. */ -- if (it->it_disposition) { -- struct mds_body *mds_body; - int mode, symlen = 0; - int mode; -- obd_flag valid; -- -- /* This long block is all about fixing up the local -- * state so that it is correct as of the moment -- * _before_ the operation was applied; that way, the -- * VFS will think that everything is normal and call -- * Lustre's regular FS function. -- * -- * If we're performing a creation, that means that unless the -- * creation failed with EEXIST, we should fake up a negative -- * dentry. Likewise for the target of a hard link. -- * -- * For everything else, we want to lookup to succeed. */ -- - /* One additional note: we add an extra reference to - * the request because we need to keep it around until - * ll_create gets called. For anything else which - * results in LL_LOOKUP_POSITIVE, we can do the iget() - /* One additional note: if CREATE/MKDIR/etc succeeded, - * we add an extra reference to the request because we - * need to keep it around until ll_create gets called. - * For anything else which results in - * LL_LOOKUP_POSITIVE, we can do the iget() -- * immediately with the contents of the reply (in the -- * intent_finish callback). In the create case, -- * however, we need to wait until ll_create_node to do - * the iget() or the VFS will abort with -EEXISTS. - * the iget() or the VFS will abort with -EEXISTS. -- */ -- -- offset = 1; -- mds_body = lustre_msg_buf(request->rq_repmsg, offset); -- ino = mds_body->fid1.id; -- mode = mds_body->mode; -- -- if (it->it_op & (IT_CREAT | IT_MKDIR | IT_SYMLINK | IT_MKNOD)) { -- mdc_store_inode_generation(request, 2, 1); -- /* For create ops, we want the lookup to be negative, -- * unless the create failed in a way that indicates -- * that the file is already there */ - if (it->it_status != -EEXIST) { - if (it->it_status == 0) -- atomic_inc(&request->rq_refcount); - if (it->it_status != -EEXIST) -- GOTO(out, flag = LL_LOOKUP_NEGATIVE); - } -- /* -- * Fall through to update attibutes: it may already -- * have appeared in the namespace of another client -- */ -- } else if (it->it_op & (IT_GETATTR | IT_SETATTR | IT_LOOKUP | -- IT_READLINK)) { -- /* For check ops, we want the lookup to succeed */ -- it->it_data = NULL; -- if (it->it_status) -- GOTO(out, flag = LL_LOOKUP_NEGATIVE); -- /* Fall through to update attibutes. */ -- } else if (it->it_op & (IT_RENAME | IT_LINK)) { -- /* For rename, we want the source lookup to succeed */ -- if (it->it_status) { -- it->it_data = NULL; -- GOTO(drop_req, rc = it->it_status); -- } -- /* Fall through to update attibutes. */ -- } else if (it->it_op & (IT_UNLINK | IT_RMDIR)) { -- /* For remove ops, we want the lookup to succeed unless -- * the file truly doesn't exist */ -- it->it_data = NULL; -- if (it->it_status == -ENOENT) -- GOTO(out, flag = LL_LOOKUP_NEGATIVE); -- /* No point in updating attributes that we're about to -- * unlink. -phil */ -- GOTO(out, flag = LL_LOOKUP_POSITIVE); -- } else if (it->it_op == IT_OPEN) { -- it->it_data = NULL; -- if (it->it_status && it->it_status != -EEXIST) -- GOTO(out, flag = LL_LOOKUP_NEGATIVE); -- /* Fall through to update attibutes. */ -- } else if (it->it_op & (IT_RENAME2 | IT_LINK2)) { -- it->it_data = NULL; -- /* This means the target lookup is negative */ -- if (mds_body->valid == 0) -- GOTO(out, flag = LL_LOOKUP_NEGATIVE); -- /* XXX bug 289: should we maybe fall through here? -p */ -- GOTO(out, flag = LL_LOOKUP_POSITIVE); -- } -- -- /* Do a getattr now that we have the lock */ - valid = OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE; - valid = OBD_MD_FLNOTOBD; -- if (it->it_op == IT_READLINK) { - datalen = mds_body->size; -- valid |= OBD_MD_LINKNAME; - symlen = mds_body->size; - } else if (S_ISREG(mode)) { - datalen = obd_size_wiremd(&sbi->ll_osc_conn, NULL); - valid |= OBD_MD_FLEASIZE; -- } -- ptlrpc_req_finished(request); -- request = NULL; -- rc = mdc_getattr(&sbi->ll_mdc_conn, ino, mode, - valid, symlen, &request); - valid, datalen, &request); -- if (rc) { -- CERROR("failure %d inode "LPX64"\n", rc, ino); -- GOTO(drop_req, rc = -abs(rc)); -- } -- offset = 0; -- } else { - struct ll_inode_info *lli = ll_i2info(parent); - obd_flag valid; -- int mode; -- -- LBUG(); /* For the moment, no non-intent locks */ -- -- /* it_disposition == 0 indicates that it just did a simple lock -- * request, for which we are very thankful. move along with -- * the local lookup then. */ -- - memcpy(&lli->lli_intent_lock_handle, &lockh, sizeof(lockh)); - //memcpy(&lli->lli_intent_lock_handle, &lockh, sizeof(lockh)); -- offset = 0; -- -- ino = ll_inode_by_name(parent, dentry, &mode); -- if (!ino) { -- CERROR("inode %*s not found by name\n", -- dentry->d_name.len, dentry->d_name.name); -- GOTO(drop_lock, rc = -ENOENT); -- } -- - rc = mdc_getattr(&sbi->ll_mdc_conn, ino, mode, - OBD_MD_FLNOTOBD|OBD_MD_FLEASIZE, 0, &request); - valid = OBD_MD_FLNOTOBD; - - if (S_ISREG(mode)) { - datalen = obd_size_wiremd(&sbi->ll_osc_conn, NULL), - valid |= OBD_MD_FLEASIZE; - } - - rc = mdc_getattr(&sbi->ll_mdc_conn, ino, mode, valid, - datalen, &request); -- if (rc) { -- CERROR("failure %d inode "LPX64"\n", rc, ino); -- GOTO(drop_req, rc = -abs(rc)); -- } -- } -- -- EXIT; -- out: -- if (intent_finish != NULL) { -- rc = intent_finish(flag, request, de, it, offset, ino); -- dentry = *de; /* intent_finish may change *de */ -- } else { -- ptlrpc_req_finished(request); -- } -- -- if (it->it_disposition && it->it_op & (IT_RENAME | IT_LINK)) -- it->it_data = dentry; -- -- /* this places the intent in the dentry so that the vfs_xxx -- * operation can lay its hands on it; but that is not -- * always needed... -- */ -- if ( // it->it_status == 0 && -- it->it_op != IT_RENAME2 && -- it->it_op != IT_SETATTR && -- it->it_op != IT_GETATTR && -- it->it_op != IT_READDIR && -- it->it_op != IT_LOOKUP) { -- LL_SAVE_INTENT(dentry, it); -- } else { - dentry->d_it = NULL; -- CDEBUG(D_DENTRY, -- "D_IT dentry %p fsdata %p intent: %s status %d\n", -- dentry, ll_d2d(dentry), ldlm_it2str(it->it_op), -- it->it_status); -- } -- -- if (rc < 0 || it->it_op == IT_LOOKUP) -- ll_intent_release(dentry, it); -- - return rc; - RETURN(rc); -- -- drop_req: -- ptlrpc_free_req(request); -- drop_lock: --#warning FIXME: must release lock here - return rc; - RETURN(rc); --} -- --/* Search "inode"'s alias list for a dentry that has the same name and parent as -- * de. If found, return it. If not found, return de. */ --struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) --{ - struct list_head *tmp; - struct list_head *tmp; -- - spin_lock(&dcache_lock); - spin_lock(&dcache_lock); -- list_for_each(tmp, &inode->i_dentry) { - struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); - struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); -- -- /* We are called here with 'de' already on the aliases list. */ -- if (dentry == de) { -- CERROR("whoops\n"); -- continue; -- } -- -- if (dentry->d_parent != de->d_parent) -- continue; -- -- if (dentry->d_name.len != de->d_name.len) -- continue; -- -- if (memcmp(dentry->d_name.name, de->d_name.name, -- de->d_name.len) != 0) -- continue; -- -- if (!list_empty(&dentry->d_lru)) -- list_del_init(&dentry->d_lru); -- -- list_del_init(&dentry->d_hash); -- spin_unlock(&dcache_lock); -- d_rehash(dentry); - atomic_inc(&dentry->d_count); - atomic_inc(&dentry->d_count); -- iput(inode); -- return dentry; - } - } -- - spin_unlock(&dcache_lock); - spin_unlock(&dcache_lock); -- -- return de; --} -- --static int --lookup2_finish(int flag, struct ptlrpc_request *request, struct dentry **de, -- struct lookup_intent *it, int offset, obd_id ino) --{ -- struct dentry *dentry = *de, *saved = *de; -- struct inode *inode = NULL; - struct ll_read_inode2_cookie lic; - struct ll_read_inode2_cookie lic = {.lic_body = NULL, .lic_lmm = NULL}; -- -- if (flag == LL_LOOKUP_POSITIVE) { -- ENTRY; -- lic.lic_body = lustre_msg_buf(request->rq_repmsg, offset); -- -- if (S_ISREG(lic.lic_body->mode) && -- lic.lic_body->valid & OBD_MD_FLEASIZE) { -- LASSERT(request->rq_repmsg->bufcount > offset); -- lic.lic_lmm = lustre_msg_buf(request->rq_repmsg, -- offset + 1); -- } else { -- lic.lic_lmm = NULL; -- } -- -- /* No rpc's happen during iget4, -ENOMEM's are possible */ - LASSERT(ino != 0); -- inode = ll_iget(dentry->d_sb, ino, &lic); -- if (!inode) { -- /* XXX make sure that request is freed in this case; -- * I think it is, but double-check refcounts. -phil */ -- RETURN(-ENOMEM); -- } -- -- dentry = *de = ll_find_alias(inode, dentry); -- -- /* We asked for a lock on the directory, and may have been -- * granted a lock on the inode. Just in case, fixup the data -- * pointer. */ -- ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, -- inode, sizeof(*inode)); -- -- EXIT; -- } else { -- ENTRY; -- } -- -- ptlrpc_req_finished(request); -- -- dentry->d_op = &ll_d_ops; -- if (ll_d2d(dentry) == NULL) { -- ll_set_dd(dentry); -- } -- -- if (dentry == saved) -- d_add(dentry, inode); -- -- RETURN(0); --} -- --static struct dentry *ll_lookup2(struct inode *parent, struct dentry *dentry, -- struct lookup_intent *it) --{ -- struct dentry *save = dentry; -- int rc; -- -- rc = ll_intent_lock(parent, &dentry, it, lookup2_finish); -- if (rc < 0) { -- CERROR("ll_intent_lock: %d\n", rc); -- return ERR_PTR(rc); -- } -- -- if (dentry == save) -- return NULL; -- else -- return dentry; --} -- --static struct inode *ll_create_node(struct inode *dir, const char *name, - int namelen, const char *tgt, int tgtlen, - int namelen, const void *data, int datalen, -- int mode, __u64 extra, - struct lookup_intent *it, - struct lov_stripe_md *lsm) - struct lookup_intent *it) --{ -- struct inode *inode; -- struct ptlrpc_request *request = NULL; -- struct mds_body *body; -- time_t time = CURRENT_TIME; -- struct ll_sb_info *sbi = ll_i2sbi(dir); - struct ll_read_inode2_cookie lic; - struct lov_mds_md *lmm = NULL; - struct ll_read_inode2_cookie lic = { .lic_lmm = NULL, }; -- ENTRY; -- -- if (it && it->it_disposition) { -- int rc = it->it_status; -- if (rc) { -- CERROR("error creating MDS inode for %*s: rc = %d\n", -- namelen, name, rc); -- RETURN(ERR_PTR(rc)); -- } -- ll_invalidate_inode_pages(dir); -- request = it->it_data; -- body = lustre_msg_buf(request->rq_repmsg, 1); - lic.lic_lmm = NULL; -- } else { -- int gid = current->fsgid; -- int rc; - - if (lsm) { - OBD_ALLOC(lmm, lsm->lsm_mds_easize); - if (!lmm) - RETURN(ERR_PTR(-ENOMEM)); - lov_packmd(lmm, lsm); - lic.lic_lmm = lmm; - } else - lic.lic_lmm = NULL; -- -- if (dir->i_mode & S_ISGID) { -- gid = dir->i_gid; -- if (S_ISDIR(mode)) -- mode |= S_ISGID; -- } -- - rc = mdc_create(&sbi->ll_mdc_conn, dir, name, namelen, tgt, - tgtlen, mode, current->fsuid, gid, - time, extra, lsm, &request); - rc = mdc_create(&sbi->ll_mdc_conn, dir, name, namelen, - data, datalen, mode, current->fsuid, gid, - time, extra, &request); -- if (rc) { -- inode = ERR_PTR(rc); -- GOTO(out, rc); -- } -- body = lustre_msg_buf(request->rq_repmsg, 0); -- } -- -- lic.lic_body = body; -- - LASSERT(body->ino != 0); -- inode = ll_iget(dir->i_sb, body->ino, &lic); -- if (IS_ERR(inode)) { -- int rc = PTR_ERR(inode); -- CERROR("new_inode -fatal: rc %d\n", rc); -- LBUG(); -- GOTO(out, rc); -- } -- -- if (!list_empty(&inode->i_dentry)) { -- CERROR("new_inode -fatal: inode %d, ct %d lnk %d\n", -- body->ino, atomic_read(&inode->i_count), -- inode->i_nlink); -- iput(inode); -- LBUG(); -- inode = ERR_PTR(-EIO); -- GOTO(out, -EIO); -- } -- -- if (it && it->it_disposition) { -- /* We asked for a lock on the directory, but were -- * granted a lock on the inode. Since we finally have -- * an inode pointer, stuff it in the lock. */ -- ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle, -- inode, sizeof(*inode)); -- } -- -- EXIT; -- out: - if (lsm && lmm) - OBD_FREE(lmm, lsm->lsm_mds_easize); -- ptlrpc_req_finished(request); -- return inode; --} -- --static int ll_mdc_unlink(struct inode *dir, struct inode *child, __u32 mode, -- const char *name, int len) --{ -- struct ptlrpc_request *request = NULL; -- struct ll_sb_info *sbi = ll_i2sbi(dir); -- int err; -- -- ENTRY; -- -- err = mdc_unlink(&sbi->ll_mdc_conn, dir, child, mode, name, len, -- &request); -- ptlrpc_req_finished(request); -- -- RETURN(err); --} -- --int ll_mdc_link(struct dentry *src, struct inode *dir, -- const char *name, int len) --{ -- struct ptlrpc_request *request = NULL; -- int err; -- struct ll_sb_info *sbi = ll_i2sbi(dir); -- -- ENTRY; -- -- err = mdc_link(&sbi->ll_mdc_conn, src, dir, name, len, &request); -- ptlrpc_req_finished(request); -- -- RETURN(err); --} -- --int ll_mdc_rename(struct inode *src, struct inode *tgt, -- struct dentry *old, struct dentry *new) --{ -- struct ptlrpc_request *request = NULL; -- struct ll_sb_info *sbi = ll_i2sbi(src); -- int err; -- -- ENTRY; -- -- err = mdc_rename(&sbi->ll_mdc_conn, src, tgt, -- old->d_name.name, old->d_name.len, -- new->d_name.name, new->d_name.len, &request); -- ptlrpc_req_finished(request); -- -- RETURN(err); --} -- --/* -- * By the time this is called, we already have created the directory cache -- * entry for the new file, but it is so far negative - it has no inode. - * -- * We defer creating the OBD object(s) until open, to keep the intent and -- * non-intent code paths similar, and also because we do not have the MDS -- * inode number before calling ll_create_node() (which is needed for LOV), -- * so we would need to do yet another RPC to the MDS to store the LOV EA - * data on the MDS. - * data on the MDS. If needed, we would pass the PACKED lmm as data and - * lmm_size in datalen (the MDS still has code which will handle that). -- * -- * If the create succeeds, we fill in the inode information -- * with d_instantiate(). -- */ --static int ll_create(struct inode *dir, struct dentry *dentry, int mode) --{ -- struct lookup_intent *it; -- struct inode *inode; -- int rc = 0; -- ENTRY; -- -- LL_GET_INTENT(dentry, it); -- -- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, mode, 0, it, NULL); - NULL, 0, mode, 0, it); -- -- if (IS_ERR(inode)) -- RETURN(PTR_ERR(inode)); -- -- if (it && it->it_disposition) { - struct ll_inode_info *lli = ll_i2info(inode); - memcpy(&lli->lli_intent_lock_handle, it->it_lock_handle, - sizeof(lli->lli_intent_lock_handle)); -- d_instantiate(dentry, inode); -- } else { -- /* no directory data updates when intents rule */ -- rc = ext2_add_nondir(dentry, inode); -- } -- -- RETURN(rc); --} -- --static int ll_mknod(struct inode *dir, struct dentry *dentry, int mode, -- int rdev) --{ -- struct lookup_intent *it; -- struct inode *inode; -- int rc = 0; -- -- LL_GET_INTENT(dentry, it); -- -- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, mode, rdev, it, NULL); - NULL, 0, mode, rdev, it); -- -- if (IS_ERR(inode)) -- RETURN(PTR_ERR(inode)); -- -- /* no directory data updates when intents rule */ -- if (it && it->it_disposition) -- d_instantiate(dentry, inode); -- else -- rc = ext2_add_nondir(dentry, inode); -- -- return rc; --} -- --static int ll_symlink(struct inode *dir, struct dentry *dentry, -- const char *symname) --{ -- struct lookup_intent *it; - unsigned l = strlen(symname); - unsigned l = strlen(symname) + 1; -- struct inode *inode; -- struct ll_inode_info *lli; -- int err = 0; -- ENTRY; -- -- LL_GET_INTENT(dentry, it); -- -- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - symname, l, S_IFLNK | S_IRWXUGO, 0, it, NULL); - symname, l, S_IFLNK | S_IRWXUGO, 0, it); -- if (IS_ERR(inode)) -- RETURN(PTR_ERR(inode)); -- -- lli = ll_i2info(inode); -- - OBD_ALLOC(lli->lli_symlink_name, l + 1); - OBD_ALLOC(lli->lli_symlink_name, l); -- /* this _could_ be a non-fatal error, since the symlink is already -- * stored on the MDS by this point, and we can re-get it in readlink. -- */ -- if (!lli->lli_symlink_name) -- RETURN(-ENOMEM); -- - memcpy(lli->lli_symlink_name, symname, l + 1); - inode->i_size = l; - memcpy(lli->lli_symlink_name, symname, l); - inode->i_size = l - 1; -- -- /* no directory data updates when intents rule */ -- if (it && it->it_disposition) -- d_instantiate(dentry, inode); -- else -- err = ext2_add_nondir(dentry, inode); -- -- RETURN(err); --} -- --static int ll_link(struct dentry *old_dentry, struct inode * dir, -- struct dentry *dentry) --{ -- struct lookup_intent *it; -- struct inode *inode = old_dentry->d_inode; -- int rc; -- -- LL_GET_INTENT(dentry, it); -- -- if (it && it->it_disposition) { -- if (it->it_status) -- RETURN(it->it_status); -- inode->i_ctime = CURRENT_TIME; -- ext2_inc_count(inode); -- atomic_inc(&inode->i_count); -- d_instantiate(dentry, inode); -- ll_invalidate_inode_pages(dir); -- RETURN(0); -- } -- -- if (S_ISDIR(inode->i_mode)) -- return -EPERM; -- -- if (inode->i_nlink >= EXT2_LINK_MAX) -- return -EMLINK; -- -- rc = ll_mdc_link(old_dentry, dir, -- dentry->d_name.name, dentry->d_name.len); -- if (rc) -- RETURN(rc); -- -- inode->i_ctime = CURRENT_TIME; -- ext2_inc_count(inode); -- atomic_inc(&inode->i_count); -- -- return ext2_add_nondir(dentry, inode); --} -- --static int ll_mkdir(struct inode *dir, struct dentry *dentry, int mode) --{ -- struct lookup_intent *it; -- struct inode * inode; -- int err = -EMLINK; -- ENTRY; -- -- LL_GET_INTENT(dentry, it); -- -- if (dir->i_nlink >= EXT2_LINK_MAX) -- goto out; -- -- ext2_inc_count(dir); -- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, - NULL, 0, S_IFDIR | mode, 0, it, NULL); - NULL, 0, S_IFDIR | mode, 0, it); -- err = PTR_ERR(inode); -- if (IS_ERR(inode)) -- goto out_dir; -- -- err = ext2_make_empty(inode, dir); -- if (err) -- goto out_fail; -- -- /* no directory data updates when intents rule */ -- if (!it || !it->it_disposition) { -- /* XXX FIXME This code needs re-checked for non-intents */ -- ext2_inc_count(inode); -- err = ll_add_link(dentry, inode); -- if (err) -- goto out_fail; -- } -- -- d_instantiate(dentry, inode); --out: -- EXIT; -- return err; -- --out_fail: -- ext2_dec_count(inode); -- ext2_dec_count(inode); -- iput(inode); -- EXIT; --out_dir: -- ext2_dec_count(dir); -- EXIT; -- goto out; --} -- --static int ll_common_unlink(struct inode *dir, struct dentry *dentry, -- struct lookup_intent *it, __u32 mode) --{ -- struct inode *inode = dentry->d_inode; -- struct ext2_dir_entry_2 * de; -- struct page * page; -- int rc = 0; -- -- if (it && it->it_disposition) { -- rc = it->it_status; -- ll_invalidate_inode_pages(dir); -- if (rc) -- GOTO(out, rc); -- GOTO(out_dec, 0); -- } -- -- de = ext2_find_entry(dir, dentry, &page); -- if (!de) -- GOTO(out, rc = -ENOENT); -- rc = ll_mdc_unlink(dir, dentry->d_inode, mode, -- dentry->d_name.name, dentry->d_name.len); -- if (rc) -- GOTO(out, rc); -- -- rc = ext2_delete_entry(de, page); -- if (rc) -- GOTO(out, rc); -- -- /* AED: not sure if needed - directory lock revocation should do it -- * in the case where the client has cached it for non-intent ops. -- */ -- ll_invalidate_inode_pages(dir); -- -- inode->i_ctime = dir->i_ctime; --out_dec: -- ext2_dec_count(inode); --out: -- return rc; --} -- --static int ll_unlink(struct inode *dir, struct dentry *dentry) --{ -- struct lookup_intent * it; -- -- LL_GET_INTENT(dentry, it); -- -- return ll_common_unlink(dir, dentry, it, S_IFREG); --} -- --static int ll_rmdir(struct inode *dir, struct dentry *dentry) --{ -- struct inode * inode = dentry->d_inode; -- struct lookup_intent *it; -- int rc; -- ENTRY; -- -- LL_GET_INTENT(dentry, it); -- -- if ((!it || !it->it_disposition) && !ext2_empty_dir(inode)) -- RETURN(-ENOTEMPTY); -- -- rc = ll_common_unlink(dir, dentry, it, S_IFDIR); -- if (!rc) { -- inode->i_size = 0; -- ext2_dec_count(inode); -- ext2_dec_count(dir); -- } -- -- RETURN(rc); --} -- --static int ll_rename(struct inode * old_dir, struct dentry * old_dentry, -- struct inode * new_dir, struct dentry * new_dentry) --{ -- struct lookup_intent *it; -- struct inode * old_inode = old_dentry->d_inode; -- struct inode * tgt_inode = new_dentry->d_inode; -- struct page * dir_page = NULL; -- struct ext2_dir_entry_2 * dir_de = NULL; -- struct ext2_dir_entry_2 * old_de; -- struct page * old_page; -- int err; -- -- LL_GET_INTENT(old_dentry, it); -- -- if (it && it->it_disposition) { -- if (tgt_inode) { -- tgt_inode->i_ctime = CURRENT_TIME; -- tgt_inode->i_nlink--; -- } -- ll_invalidate_inode_pages(old_dir); -- ll_invalidate_inode_pages(new_dir); -- GOTO(out, err = it->it_status); -- } -- -- err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry); -- if (err) -- goto out; -- -- old_de = ext2_find_entry (old_dir, old_dentry, &old_page); -- if (!old_de) -- goto out; -- -- if (S_ISDIR(old_inode->i_mode)) { -- err = -EIO; -- dir_de = ext2_dotdot(old_inode, &dir_page); -- if (!dir_de) -- goto out_old; -- } -- -- if (tgt_inode) { -- struct page *new_page; -- struct ext2_dir_entry_2 *new_de; -- -- err = -ENOTEMPTY; -- if (dir_de && !ext2_empty_dir (tgt_inode)) -- goto out_dir; -- -- err = -ENOENT; -- new_de = ext2_find_entry (new_dir, new_dentry, &new_page); -- if (!new_de) -- goto out_dir; -- ext2_inc_count(old_inode); -- ext2_set_link(new_dir, new_de, new_page, old_inode); -- tgt_inode->i_ctime = CURRENT_TIME; -- if (dir_de) -- tgt_inode->i_nlink--; -- ext2_dec_count(tgt_inode); -- } else { -- if (dir_de) { -- err = -EMLINK; -- if (new_dir->i_nlink >= EXT2_LINK_MAX) -- goto out_dir; -- } -- ext2_inc_count(old_inode); -- err = ll_add_link(new_dentry, old_inode); -- if (err) { -- ext2_dec_count(old_inode); -- goto out_dir; -- } -- if (dir_de) -- ext2_inc_count(new_dir); -- } -- -- ext2_delete_entry (old_de, old_page); -- ext2_dec_count(old_inode); -- -- if (dir_de) { -- ext2_set_link(old_inode, dir_de, dir_page, new_dir); -- ext2_dec_count(old_dir); -- } -- return 0; -- --out_dir: -- if (dir_de) { -- kunmap(dir_page); -- page_cache_release(dir_page); -- } --out_old: -- kunmap(old_page); -- page_cache_release(old_page); --out: -- return err; --} -- --struct inode_operations ll_dir_inode_operations = { -- create: ll_create, -- lookup2: ll_lookup2, -- link: ll_link, -- unlink: ll_unlink, -- symlink: ll_symlink, -- mkdir: ll_mkdir, -- rmdir: ll_rmdir, -- mknod: ll_mknod, -- rename: ll_rename, -- setattr: ll_setattr --}; diff --cc lustre/llite/recover.c index b688fb9,3310c34..0000000 deleted file mode 100644,100644 --- a/lustre/llite/recover.c +++ /dev/null @@@ -1,219 -1,55 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Lustre Lite recovery infrastructure. -- * -- * Copyright (C) 2002 Cluster File Systems Inc. -- */ -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include --#include - #include /* for IOC_LOV_SET_OSC_ACTIVE */ -- --static int ll_retry_recovery(struct ptlrpc_connection *conn) --{ -- ENTRY; -- RETURN(0); - } - - /* XXX looks a lot like super.c:invalidate_request_list, don't it? */ - static void abort_inflight_for_import(struct obd_import *imp) - { - struct list_head *tmp, *n; - - /* Make sure that no new requests get processed for this import. - * ptlrpc_queue_wait must (and does) hold c_lock while testing this - * flags and then putting requests on sending_head or delayed_head. - */ - spin_lock(&imp->imp_connection->c_lock); - imp->imp_flags |= IMP_INVALID; - spin_unlock(&imp->imp_connection->c_lock); - - list_for_each_safe(tmp, n, &imp->imp_connection->c_sending_head) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - - if (req->rq_import != imp) - continue; - - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - /* no need to replay, just discard */ - CERROR("uncommitted req xid "LPD64" op %d to OST %s\n", - (unsigned long long)req->rq_xid, - req->rq_reqmsg->opc, - imp->imp_obd->u.cli.cl_target_uuid); - ptlrpc_req_finished(req); - } else { - CERROR("inflight req xid "LPD64" op %d to OST %s\n", - (unsigned long long)req->rq_xid, - req->rq_reqmsg->opc, - imp->imp_obd->u.cli.cl_target_uuid); - - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } - } - - list_for_each_safe(tmp, n, &imp->imp_connection->c_delayed_head) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - CERROR("aborting waiting req xid "LPD64" op %d to OST %s\n", - (unsigned long long)req->rq_xid, req->rq_reqmsg->opc, - imp->imp_obd->u.cli.cl_target_uuid); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } - } - - static void set_osc_active(struct obd_import *imp, int active) - { - struct obd_device *notify_obd = imp->imp_obd->u.cli.cl_containing_lov; - - if (notify_obd == NULL) - return; - - /* How gross is _this_? */ - if (!list_empty(¬ify_obd->obd_exports)) { - int rc; - struct lustre_handle fakeconn; - struct obd_ioctl_data ioc_data; - struct obd_export *exp = - list_entry(notify_obd->obd_exports.next, - struct obd_export, exp_obd_chain); - - fakeconn.addr = (__u64)(unsigned long)exp; - fakeconn.cookie = exp->exp_cookie; - ioc_data.ioc_inlbuf1 = imp->imp_obd->obd_uuid; - ioc_data.ioc_offset = active; - rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn, - sizeof ioc_data, &ioc_data, NULL); - if (rc) - CERROR("disabling %s on LOV %p/%s: %d\n", - imp->imp_obd->obd_uuid, notify_obd, - notify_obd->obd_uuid, rc); - } else { - CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about " - "%p\n", notify_obd, notify_obd->obd_uuid, - imp->imp_obd->obd_uuid); - } - } - - static void prepare_osc(struct obd_import *imp) - { - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - - CDEBUG(D_HA, "invalidating all locks for OST imp %p (to %s):\n", - imp, imp->imp_connection->c_remote_uuid); - ldlm_namespace_dump(ns); - ldlm_namespace_cleanup(ns, 1 /* no network ops */); - - abort_inflight_for_import(imp); - - set_osc_active(imp, 0 /* inactive */); - } - - static void prepare_mdc(struct obd_import *imp) - { - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - ldlm_cli_cancel_unused(ns, NULL, LDLM_FL_LOCAL_ONLY); - } - - static int ll_prepare_recovery(struct ptlrpc_connection *conn) - { - struct list_head *tmp; - - list_for_each(tmp, &conn->c_imports) { - struct obd_import *imp = list_entry(tmp, struct obd_import, - imp_chain); - - if (imp->imp_obd->obd_type->typ_ops->o_brw) - prepare_osc(imp); - else - prepare_mdc(imp); - } - - return ptlrpc_run_recovery_upcall(conn); - } - - static void reconnect_osc(struct obd_import *imp) - { - int rc = ptlrpc_reconnect_import(imp, OST_CONNECT); - if (rc == 0) - set_osc_active(imp, 1 /* active */); - else - CDEBUG(D_HA, "reconnection failed, not reactivating OSC %s\n", - imp->imp_obd->obd_uuid); - } - - static int reconnect_mdc(struct obd_import *imp) - { - return ptlrpc_reconnect_import(imp, MDS_CONNECT); - } - - static int ll_reconnect(struct ptlrpc_connection *conn) - { - struct list_head *tmp; - int need_replay = 0; - - ENTRY; - - /* XXX c_lock semantics! */ - conn->c_level = LUSTRE_CONN_CON; - - /* XXX this code MUST be shared with class_obd_connect! */ - list_for_each(tmp, &conn->c_imports) { - struct obd_import *imp = list_entry(tmp, struct obd_import, - imp_chain); - if (imp->imp_obd->obd_type->typ_ops->o_brw) { - /* XXX what to do if we fail? */ - reconnect_osc(imp); - } else { - int rc = reconnect_mdc(imp); - if (!rc) { - need_replay = 1; - } - /* make sure we don't try to replay for dead imps? - * - * else imp->imp_connection = NULL; - * - */ - - } - } - - if (!need_replay) { - /* all done! */ - conn->c_level = LUSTRE_CONN_FULL; - RETURN(0); - } - - conn->c_level = LUSTRE_CONN_RECOVD; - /* this will replay, up the c_level, recovd_conn_fixed and continue - * reqs. also, makes a mean cup of coffee. - */ - RETURN(ptlrpc_replay(conn)); --} -- --int ll_recover(struct recovd_data *rd, int phase) --{ -- struct ptlrpc_connection *conn = class_rd2conn(rd); - struct list_head *tmp; -- -- LASSERT(conn); -- ENTRY; -- -- switch (phase) { -- case PTLRPC_RECOVD_PHASE_PREPARE: - RETURN(ll_prepare_recovery(conn)); -- case PTLRPC_RECOVD_PHASE_RECOVER: - RETURN(ll_reconnect(conn)); - list_for_each(tmp, &conn->c_imports) { - struct obd_import *imp = - list_entry(tmp, struct obd_import, imp_chain); - - if (phase == PTLRPC_RECOVD_PHASE_PREPARE) { - spin_lock(&imp->imp_lock); - imp->imp_level = LUSTRE_CONN_RECOVD; - spin_unlock(&imp->imp_lock); - } - imp->imp_recover(imp, phase); - } - - if (phase == PTLRPC_RECOVD_PHASE_PREPARE) - RETURN(ptlrpc_run_recovery_upcall(conn)); - RETURN(0); - -- case PTLRPC_RECOVD_PHASE_FAILURE: -- RETURN(ll_retry_recovery(conn)); -- } -- -- LBUG(); -- RETURN(-ENOSYS); --} diff --cc lustre/llite/rw.c index dcb2ecd,095c145..0000000 deleted file mode 100644,100644 --- a/lustre/llite/rw.c +++ /dev/null @@@ -1,386 -1,429 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Lustre Lite I/O Page Cache -- * - * Copyright (C) 2002 Cluster File Systems, Inc. - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre 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. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include -- --/* -- * Remove page from dirty list -- */ --static void __set_page_clean(struct page *page) --{ -- struct address_space *mapping = page->mapping; -- struct inode *inode; -- -- if (!mapping) -- return; -- --#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) -- spin_lock(&pagecache_lock); --#endif -- -- list_del(&page->list); -- list_add(&page->list, &mapping->clean_pages); -- -- inode = mapping->host; -- if (list_empty(&mapping->dirty_pages)) { -- CDEBUG(D_INODE, "inode clean\n"); -- inode->i_state &= ~I_DIRTY_PAGES; -- } --#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) -- spin_unlock(&pagecache_lock); --#endif -- EXIT; --} -- --inline void set_page_clean(struct page *page) --{ -- if (PageDirty(page)) { -- ClearPageDirty(page); -- __set_page_clean(page); -- } --} -- --/* SYNCHRONOUS I/O to object storage for an inode */ --static int ll_brw(int cmd, struct inode *inode, struct page *page, int create) --{ -- struct ll_inode_info *lli = ll_i2info(inode); -- struct lov_stripe_md *lsm = lli->lli_smd; - struct brw_cb_data *brw_cbd = ll_init_brw_cb_data(); - struct obd_brw_set *set; -- struct brw_page pg; - int err; - int rc; -- ENTRY; -- - if (!brw_cbd) - set = obd_brw_set_new(); - if (set == NULL) -- RETURN(-ENOMEM); -- -- pg.pg = page; -- pg.off = ((obd_off)page->index) << PAGE_SHIFT; -- -- if (cmd == OBD_BRW_WRITE && (pg.off + PAGE_SIZE > inode->i_size)) - pg.count = inode->i_size % PAGE_SIZE; - pg.count = inode->i_size % PAGE_SIZE; -- else -- pg.count = PAGE_SIZE; -- -- pg.flag = create ? OBD_BRW_CREATE : 0; -- - err = obd_brw(cmd, ll_i2obdconn(inode),lsm, 1, &pg, ll_sync_brw_cb, - brw_cbd); - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(cmd, ll_i2obdconn(inode), lsm, 1, &pg, set); - if (rc) { - if (rc != -EIO) - CERROR("error from obd_brw: rc = %d\n", rc); - } else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_free(set); -- - RETURN(err); - } /* ll_brw */ - RETURN(rc); -} -- --/* returns the page unlocked, but with a reference */ --static int ll_readpage(struct file *file, struct page *page) --{ -- struct inode *inode = page->mapping->host; -- obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; -- int rc = 0; -- ENTRY; -- -- if (!PageLocked(page)) -- LBUG(); -- -- if (inode->i_size <= offset) { -- memset(kmap(page), 0, PAGE_SIZE); -- kunmap(page); -- GOTO(readpage_out, rc); -- } -- -- if (PageUptodate(page)) { -- CERROR("Explain this please?\n"); -- GOTO(readpage_out, rc); -- } -- -- rc = ll_brw(OBD_BRW_READ, inode, page, 0); -- EXIT; -- -- readpage_out: -- if (!rc) -- SetPageUptodate(page); -- unlock_page(page); -- return 0; --} /* ll_readpage */ -- --void ll_truncate(struct inode *inode) --{ -- struct obdo oa = {0}; -- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; -- struct lustre_handle *lockhs = NULL; -- int err; -- ENTRY; -- -- if (!lsm) { -- /* object not yet allocated */ -- inode->i_mtime = inode->i_ctime = CURRENT_TIME; -- return; -- } -- -- oa.o_id = lsm->lsm_object_id; -- oa.o_mode = inode->i_mode; -- oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE; -- -- CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after "LPD64")\n", -- oa.o_id, inode->i_size); -- -- err = ll_size_lock(inode, lsm, inode->i_size, LCK_PW, &lockhs); -- if (err) { -- CERROR("ll_size_lock failed: %d\n", err); -- /* FIXME: What to do here? It's too late to back out... */ -- LBUG(); -- } -- -- /* truncate == punch from new size to absolute end of file */ -- err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size, -- OBD_OBJECT_EOF); - if (err) - CERROR("obd_truncate fails (%d)\n", err); - else - if (err) { - LBUG(); - CERROR("obd_truncate fails (%d) ino %ld\n", err, - inode->i_ino); - } else -- obdo_to_inode(inode, &oa, oa.o_valid); -- -- err = ll_size_unlock(inode, lsm, LCK_PW, lockhs); -- if (err) -- CERROR("ll_size_unlock failed: %d\n", err); -- -- EXIT; -- return; --} /* ll_truncate */ -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- --static int ll_prepare_write(struct file *file, struct page *page, unsigned from, -- unsigned to) --{ -- struct inode *inode = page->mapping->host; -- obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; -- int rc = 0; -- char *addr; -- ENTRY; -- -- addr = kmap(page); -- if (!PageLocked(page)) -- LBUG(); -- -- if (Page_Uptodate(page)) -- GOTO(prepare_done, rc); -- -- /* We're completely overwriting an existing page, so _don't_ set it up -- * to date until commit_write */ -- if (from == 0 && to == PAGE_SIZE) -- RETURN(0); -- -- /* We are writing to a new page, no need to read old data */ -- if (inode->i_size <= offset) { -- memset(addr, 0, PAGE_SIZE); -- GOTO(prepare_done, rc=0); -- } -- -- rc = ll_brw(OBD_BRW_READ, inode, page, 0); -- -- EXIT; -- prepare_done: -- if (!rc) -- SetPageUptodate(page); -- -- return rc; --} -- --/* returns the page unlocked, but with a reference */ --static int ll_writepage(struct page *page) --{ -- struct inode *inode = page->mapping->host; -- int err; -- ENTRY; -- -- if (!PageLocked(page)) -- LBUG(); -- -- err = ll_brw(OBD_BRW_WRITE, inode, page, 1); -- if ( !err ) { -- //SetPageUptodate(page); -- set_page_clean(page); -- } else { -- CERROR("ll_brw failure %d\n", err); -- } -- unlock_page(page); -- RETURN(err); --} -- -- --/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated -- * too */ --static int ll_commit_write(struct file *file, struct page *page, -- unsigned from, unsigned to) --{ - int create = 1; -- struct inode *inode = page->mapping->host; -- struct ll_inode_info *lli = ll_i2info(inode); -- struct lov_stripe_md *md = lli->lli_smd; -- struct brw_page pg; - int err; - struct obd_brw_set *set; - int rc, create = 1; -- loff_t size; - struct brw_cb_data *cbd = ll_init_brw_cb_data(); -- ENTRY; -- -- pg.pg = page; -- pg.count = to; -- pg.off = (((obd_off)page->index) << PAGE_SHIFT); -- pg.flag = create ? OBD_BRW_CREATE : 0; -- - if (!cbd) - set = obd_brw_set_new(); - if (set == NULL) -- RETURN(-ENOMEM); -- -- SetPageUptodate(page); -- -- if (!PageLocked(page)) -- LBUG(); -- -- CDEBUG(D_INODE, "commit_page writing (off "LPD64"), count "LPD64"\n", -- pg.off, pg.count); -- - err = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), md, - 1, &pg, ll_sync_brw_cb, cbd); - set->brw_callback = ll_brw_sync_wait; - rc = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), md, 1, &pg, set); - if (rc) - CERROR("error from obd_brw: rc = %d\n", rc); - else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_free(set); -- kunmap(page); -- -- size = pg.off + pg.count; -- /* do NOT truncate when writing in the middle of a file */ -- if (size > inode->i_size) -- inode->i_size = size; -- - RETURN(err); - RETURN(rc); --} /* ll_commit_write */ -- -- --static int ll_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf, -- unsigned long blocknr, int blocksize) --{ -- obd_count bufs_per_obdo = iobuf->nr_pages; -- struct ll_inode_info *lli = ll_i2info(inode); -- struct lov_stripe_md *lsm = lli->lli_smd; -- struct brw_page *pga; - struct obd_brw_set *set; -- int i, rc = 0; - struct brw_cb_data *cbd; - -- ENTRY; - -- if (!lsm || !lsm->lsm_object_id) -- RETURN(-ENOMEM); -- -- if (blocksize != PAGE_SIZE) { -- CERROR("direct_IO blocksize != PAGE_SIZE\n"); -- RETURN(-EINVAL); -- } -- - cbd = ll_init_brw_cb_data(); - if (!cbd) - set = obd_brw_set_new(); - if (set == NULL) -- RETURN(-ENOMEM); -- -- OBD_ALLOC(pga, sizeof(*pga) * bufs_per_obdo); -- if (!pga) { - OBD_FREE(cbd, sizeof(*cbd)); - obd_brw_set_free(set); -- RETURN(-ENOMEM); -- } -- -- /* NB: we can't use iobuf->maplist[i]->index for the offset -- * instead of "blocknr" because ->index contains garbage. -- */ -- for (i = 0; i < bufs_per_obdo; i++, blocknr++) { -- pga[i].pg = iobuf->maplist[i]; -- pga[i].count = PAGE_SIZE; -- pga[i].off = (obd_off)blocknr << PAGE_SHIFT; -- pga[i].flag = OBD_BRW_CREATE; -- } -- - set->brw_callback = ll_brw_sync_wait; -- rc = obd_brw(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, - ll_i2obdconn(inode), lsm, bufs_per_obdo, pga, - ll_sync_brw_cb, cbd); - ll_i2obdconn(inode), lsm, bufs_per_obdo, pga, set); - if (rc) - CERROR("error from obd_brw: rc = %d\n", rc); - else { - rc = ll_brw_sync_wait(set, CB_PHASE_START); - if (rc) - CERROR("error from callback: rc = %d\n", rc); - } - obd_brw_set_free(set); -- if (rc == 0) -- rc = bufs_per_obdo * PAGE_SIZE; -- -- OBD_FREE(pga, sizeof(*pga) * bufs_per_obdo); -- RETURN(rc); --} -- --int ll_flush_inode_pages(struct inode * inode) --{ -- obd_count bufs_per_obdo = 0; -- obd_size *count = NULL; -- obd_off *offset = NULL; -- obd_flag *flags = NULL; -- int err = 0; -- -- ENTRY; -- -- spin_lock(&pagecache_lock); -- -- spin_unlock(&pagecache_lock); -- -- -- OBD_ALLOC(count, sizeof(*count) * bufs_per_obdo); -- OBD_ALLOC(offset, sizeof(*offset) * bufs_per_obdo); -- OBD_ALLOC(flags, sizeof(*flags) * bufs_per_obdo); -- if (!count || !offset || !flags) -- GOTO(out, err=-ENOMEM); -- --#if 0 -- for (i = 0 ; i < bufs_per_obdo ; i++) { -- count[i] = PAGE_SIZE; -- offset[i] = ((obd_off)(iobuf->maplist[i])->index) << PAGE_SHIFT; -- flags[i] = OBD_BRW_CREATE; -- } -- -- err = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), -- ll_i2info(inode)->lli_smd, bufs_per_obdo, -- iobuf->maplist, count, offset, flags, NULL, NULL); -- if (err == 0) -- err = bufs_per_obdo * 4096; --#endif -- out: -- OBD_FREE(flags, sizeof(*flags) * bufs_per_obdo); -- OBD_FREE(count, sizeof(*count) * bufs_per_obdo); -- OBD_FREE(offset, sizeof(*offset) * bufs_per_obdo); -- RETURN(err); --} -- --#endif -- -- --struct address_space_operations ll_aops = { -- readpage: ll_readpage, --#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) -- direct_IO: ll_direct_IO, -- writepage: ll_writepage, -- sync_page: block_sync_page, -- prepare_write: ll_prepare_write, -- commit_write: ll_commit_write, -- bmap: NULL --#endif --}; diff --cc lustre/llite/super.c index a348883,cb3ae90..0000000 deleted file mode 100644,100644 --- a/lustre/llite/super.c +++ /dev/null @@@ -1,647 -1,621 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Lustre Light Super operations -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copryright (C) 2002 Cluster File Systems, Inc. -- */ -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include --#include --#include - #include --#include --#include --#include --#include -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --kmem_cache_t *ll_file_data_slab; --extern struct address_space_operations ll_aops; --extern struct address_space_operations ll_dir_aops; --struct super_operations ll_super_operations; -- --extern int ll_recover(struct recovd_data *, int); --extern int ll_commitcbd_setup(struct ll_sb_info *); --extern int ll_commitcbd_cleanup(struct ll_sb_info *); -- --extern void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc); -- --static char *ll_read_opt(const char *opt, char *data) --{ -- char *value; -- char *retval; -- ENTRY; -- -- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); -- if ( strncmp(opt, data, strlen(opt)) ) -- RETURN(NULL); -- if ( (value = strchr(data, '=')) == NULL ) -- RETURN(NULL); -- -- value++; -- OBD_ALLOC(retval, strlen(value) + 1); -- if ( !retval ) { -- CERROR("out of memory!\n"); -- RETURN(NULL); -- } -- -- memcpy(retval, value, strlen(value)+1); -- CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); -- RETURN(retval); --} -- --static int ll_set_opt(const char *opt, char *data, int fl) --{ -- ENTRY; -- -- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); -- if ( strncmp(opt, data, strlen(opt)) ) -- RETURN(0); -- else -- RETURN(fl); --} -- --static void ll_options(char *options, char **ost, char **mds, int *flags) --{ -- char *this_char; -- ENTRY; -- -- if (!options) { -- EXIT; -- return; -- } -- -- for (this_char = strtok (options, ","); -- this_char != NULL; -- this_char = strtok (NULL, ",")) { -- CDEBUG(D_SUPER, "this_char %s\n", this_char); -- if ( (!*ost && (*ost = ll_read_opt("osc", this_char)))|| -- (!*mds && (*mds = ll_read_opt("mdc", this_char)))|| -- (!(*flags & LL_SBI_NOLCK) && ((*flags) = (*flags) | -- ll_set_opt("nolock", this_char, LL_SBI_NOLCK))) ) -- continue; -- } -- EXIT; --} -- --#ifndef log2 --#define log2(n) ffz(~(n)) --#endif -- --static struct super_block * ll_read_super(struct super_block *sb, -- void *data, int silent) --{ -- struct inode *root = 0; -- struct obd_device *obd; -- struct ll_sb_info *sbi; -- char *osc = NULL; -- char *mdc = NULL; -- int err; -- struct ll_fid rootfid; -- struct obd_statfs osfs; -- struct ptlrpc_request *request = NULL; -- struct ptlrpc_connection *mdc_conn; -- struct ll_read_inode2_cookie lic; -- class_uuid_t uuid; - - -- -- ENTRY; -- MOD_INC_USE_COUNT; -- -- OBD_ALLOC(sbi, sizeof(*sbi)); -- if (!sbi) { -- MOD_DEC_USE_COUNT; -- RETURN(NULL); -- } -- -- INIT_LIST_HEAD(&sbi->ll_conn_chain); -- INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list); -- generate_random_uuid(uuid); -- class_uuid_unparse(uuid, sbi->ll_sb_uuid); -- -- sb->u.generic_sbp = sbi; -- -- ll_options(data, &osc, &mdc, &sbi->ll_flags); -- -- if (!osc) { -- CERROR("no osc\n"); -- GOTO(out_free, sb = NULL); -- } -- -- if (!mdc) { -- CERROR("no mdc\n"); -- GOTO(out_free, sb = NULL); -- } -- -- obd = class_uuid2obd(mdc); -- if (!obd) { -- CERROR("MDC %s: not setup or attached\n", mdc); -- GOTO(out_free, sb = NULL); -- } -- -- err = obd_connect(&sbi->ll_mdc_conn, obd, sbi->ll_sb_uuid, -- ptlrpc_recovd, ll_recover); -- if (err) { -- CERROR("cannot connect to %s: rc = %d\n", mdc, err); -- GOTO(out_free, sb = NULL); -- } -- - #warning Mike: is this the right place to raise the connection level? -- mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection; - mdc_conn->c_level = LUSTRE_CONN_FULL; -- list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain); -- -- obd = class_uuid2obd(osc); -- if (!obd) { -- CERROR("OSC %s: not setup or attached\n", osc); -- GOTO(out_mdc, sb = NULL); -- } -- -- err = obd_connect(&sbi->ll_osc_conn, obd, sbi->ll_sb_uuid, -- ptlrpc_recovd, ll_recover); -- if (err) { -- CERROR("cannot connect to %s: rc = %d\n", osc, err); -- GOTO(out_mdc, sb = NULL); -- } -- -- err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); -- if (err) { -- CERROR("cannot mds_connect: rc = %d\n", err); -- GOTO(out_mdc, sb = NULL); -- } -- CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id); -- sbi->ll_rootino = rootfid.id; -- -- memset(&osfs, 0, sizeof(osfs)); -- err = obd_statfs(&sbi->ll_mdc_conn, &osfs); -- sb->s_blocksize = osfs.os_bsize; -- sb->s_blocksize_bits = log2(osfs.os_bsize); -- sb->s_magic = LL_SUPER_MAGIC; -- sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize; -- -- sb->s_op = &ll_super_operations; -- -- /* make root inode */ -- err = mdc_getattr(&sbi->ll_mdc_conn, sbi->ll_rootino, S_IFDIR, -- OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); -- if (err) { -- CERROR("mdc_getattr failed for root: rc = %d\n", err); -- GOTO(out_request, sb = NULL); -- } -- -- /* initialize committed transaction callback daemon */ -- spin_lock_init(&sbi->ll_commitcbd_lock); -- init_waitqueue_head(&sbi->ll_commitcbd_waitq); -- init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq); -- sbi->ll_commitcbd_flags = 0; -- err = ll_commitcbd_setup(sbi); -- if (err) { -- CERROR("failed to start commit callback daemon: rc = %d\n",err); -- GOTO(out_request, sb = NULL); -- } -- -- lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0); -- lic.lic_lmm = NULL; -- LASSERT(sbi->ll_rootino != 0); -- root = iget4(sb, sbi->ll_rootino, NULL, &lic); -- -- if (root) { -- sb->s_root = d_alloc_root(root); -- } else { -- CERROR("lustre_lite: bad iget4 for root\n"); -- GOTO(out_cdb, sb = NULL); -- } -- -- ptlrpc_req_finished(request); -- request = NULL; -- ll_proc_namespace(sb, osc, mdc); -- --out_dev: -- if (mdc) -- OBD_FREE(mdc, strlen(mdc) + 1); -- if (osc) -- OBD_FREE(osc, strlen(osc) + 1); -- -- RETURN(sb); -- --out_cdb: -- ll_commitcbd_cleanup(sbi); --out_request: -- ptlrpc_req_finished(request); -- obd_disconnect(&sbi->ll_osc_conn); --out_mdc: -- obd_disconnect(&sbi->ll_mdc_conn); --out_free: -- OBD_FREE(sbi, sizeof(*sbi)); -- -- MOD_DEC_USE_COUNT; -- goto out_dev; --} /* ll_read_super */ -- --static void ll_put_super(struct super_block *sb) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct list_head *tmp, *next; -- struct ll_fid rootfid; -- ENTRY; -- -- list_del(&sbi->ll_conn_chain); -- ll_commitcbd_cleanup(sbi); -- obd_disconnect(&sbi->ll_osc_conn); -- -- /* NULL request to force sync on the MDS, and get the last_committed -- * value to flush remaining RPCs from the sending queue on client. -- * -- * XXX This should be an mdc_sync() call to sync the whole MDS fs, -- * which we can call for other reasons as well. -- */ -- mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); -- -- lprocfs_dereg_mnt(sbi->ll_proc_root); -- sbi->ll_proc_root = NULL; - - -- obd_disconnect(&sbi->ll_mdc_conn); -- -- spin_lock(&dcache_lock); -- list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) { -- struct dentry *dentry = list_entry(tmp, struct dentry, d_hash); -- shrink_dcache_parent(dentry); -- } -- spin_unlock(&dcache_lock); -- -- OBD_FREE(sbi, sizeof(*sbi)); -- -- MOD_DEC_USE_COUNT; -- EXIT; --} /* ll_put_super */ -- --static void ll_clear_inode(struct inode *inode) --{ -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- struct ll_inode_info *lli = ll_i2info(inode); -- int rc; -- ENTRY; -- -- rc = mdc_cancel_unused(&sbi->ll_mdc_conn, inode, LDLM_FL_NO_CALLBACK); -- if (rc < 0) { -- CERROR("mdc_cancel_unused: %d\n", rc); -- /* XXX FIXME do something dramatic */ -- } -- -- if (lli->lli_smd) { -- rc = obd_cancel_unused(&sbi->ll_osc_conn, lli->lli_smd, 0); -- if (rc < 0) { -- CERROR("obd_cancel_unused: %d\n", rc); -- /* XXX FIXME do something dramatic */ -- } -- } -- -- if (atomic_read(&inode->i_count) == 0) { - struct lov_stripe_md *lsm = lli->lli_smd; -- char *symlink_name = lli->lli_symlink_name; -- - if (lsm) { - OBD_FREE(lsm, ll_ost_easize(inode->i_sb)); - lli->lli_smd = NULL; - } - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); - -- if (symlink_name) { -- OBD_FREE(symlink_name, strlen(symlink_name) + 1); -- lli->lli_symlink_name = NULL; -- } -- } -- -- EXIT; --} -- --static void ll_delete_inode(struct inode *inode) --{ -- ENTRY; -- if (S_ISREG(inode->i_mode)) { -- int err; -- struct obdo *oa; -- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; -- -- if (!lsm) -- GOTO(out, -EINVAL); -- -- if (lsm->lsm_object_id == 0) { -- CERROR("This really happens\n"); -- /* No obdo was ever created */ -- GOTO(out, 0); -- } -- -- oa = obdo_alloc(); -- if (oa == NULL) -- GOTO(out, -ENOMEM); -- -- oa->o_id = lsm->lsm_object_id; - oa->o_easize = ll_mds_easize(inode->i_sb); -- oa->o_mode = inode->i_mode; -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLEASIZE | OBD_MD_FLTYPE; -- -- err = obd_destroy(ll_i2obdconn(inode), oa, lsm); -- obdo_free(oa); -- CDEBUG(D_SUPER, "obd destroy of objid "LPX64" error %d\n", -- lsm->lsm_object_id, err); -- } --out: -- clear_inode(inode); -- EXIT; --} -- --/* like inode_setattr, but doesn't mark the inode dirty */ --static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc) --{ -- unsigned int ia_valid = attr->ia_valid; -- int error = 0; -- -- if ((ia_valid & ATTR_SIZE) && trunc) { -- error = vmtruncate(inode, attr->ia_size); -- if (error) -- goto out; -- } else if (ia_valid & ATTR_SIZE) -- inode->i_size = attr->ia_size; -- -- if (ia_valid & ATTR_UID) -- inode->i_uid = attr->ia_uid; -- if (ia_valid & ATTR_GID) -- inode->i_gid = attr->ia_gid; -- if (ia_valid & ATTR_ATIME) -- inode->i_atime = attr->ia_atime; -- if (ia_valid & ATTR_MTIME) -- inode->i_mtime = attr->ia_mtime; -- if (ia_valid & ATTR_CTIME) -- inode->i_ctime = attr->ia_ctime; -- if (ia_valid & ATTR_MODE) { -- inode->i_mode = attr->ia_mode; -- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) -- inode->i_mode &= ~S_ISGID; -- } --out: -- return error; --} -- --int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc) --{ -- struct ptlrpc_request *request = NULL; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- int err; -- -- ENTRY; -- -- /* change incore inode */ -- ll_attr2inode(inode, attr, do_trunc); -- -- err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, &request); -- if (err) -- CERROR("mdc_setattr fails (%d)\n", err); -- -- ptlrpc_req_finished(request); -- -- RETURN(err); --} -- --int ll_setattr(struct dentry *de, struct iattr *attr) --{ -- int rc = inode_change_ok(de->d_inode, attr); -- -- if (rc) -- return rc; -- -- return ll_inode_setattr(de->d_inode, attr, 1); --} -- --static int ll_statfs(struct super_block *sb, struct statfs *sfs) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct obd_statfs osfs; -- int rc; -- ENTRY; -- -- memset(sfs, 0, sizeof(*sfs)); -- rc = obd_statfs(&sbi->ll_mdc_conn, &osfs); -- statfs_unpack(sfs, &osfs); -- if (rc) -- CERROR("mdc_statfs fails: rc = %d\n", rc); -- else -- CDEBUG(D_SUPER, "mdc_statfs shows blocks "LPU64"/"LPU64 -- " objects "LPU64"/"LPU64"\n", -- osfs.os_bavail, osfs.os_blocks, -- osfs.os_ffree, osfs.os_files); -- -- /* temporary until mds_statfs returns statfs info for all OSTs */ -- if (!rc) { -- rc = obd_statfs(&sbi->ll_osc_conn, &osfs); -- if (rc) { -- CERROR("obd_statfs fails: rc = %d\n", rc); -- GOTO(out, rc); -- } -- CDEBUG(D_SUPER, "obd_statfs shows blocks "LPU64"/"LPU64 -- " objects "LPU64"/"LPU64"\n", -- osfs.os_bavail, osfs.os_blocks, -- osfs.os_ffree, osfs.os_files); -- -- while (osfs.os_blocks > ~0UL) { -- sfs->f_bsize <<= 1; -- -- osfs.os_blocks >>= 1; -- osfs.os_bfree >>= 1; -- osfs.os_bavail >>= 1; -- } -- sfs->f_blocks = osfs.os_blocks; -- sfs->f_bfree = osfs.os_bfree; -- sfs->f_bavail = osfs.os_bavail; -- if (osfs.os_ffree < (__u64)sfs->f_ffree) -- sfs->f_ffree = osfs.os_ffree; -- } -- --out: -- RETURN(rc); --} -- --void ll_update_inode(struct inode *inode, struct mds_body *body) --{ -- if (body->valid & OBD_MD_FLID) -- inode->i_ino = body->ino; -- if (body->valid & OBD_MD_FLATIME) -- inode->i_atime = body->atime; -- if (body->valid & OBD_MD_FLMTIME) -- inode->i_mtime = body->mtime; -- if (body->valid & OBD_MD_FLCTIME) -- inode->i_ctime = body->ctime; -- if (body->valid & OBD_MD_FLMODE) -- inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); -- if (body->valid & OBD_MD_FLTYPE) -- inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); -- if (body->valid & OBD_MD_FLUID) -- inode->i_uid = body->uid; -- if (body->valid & OBD_MD_FLGID) -- inode->i_gid = body->gid; -- if (body->valid & OBD_MD_FLFLAGS) -- inode->i_flags = body->flags; -- if (body->valid & OBD_MD_FLNLINK) -- inode->i_nlink = body->nlink; -- if (body->valid & OBD_MD_FLGENER) -- inode->i_generation = body->generation; -- if (body->valid & OBD_MD_FLRDEV) -- inode->i_rdev = body->rdev; -- if (body->valid & OBD_MD_FLSIZE) -- inode->i_size = body->size; --} -- --static void ll_read_inode2(struct inode *inode, void *opaque) --{ -- struct ll_read_inode2_cookie *lic = opaque; -- struct mds_body *body = lic->lic_body; -- struct ll_inode_info *lli = ll_i2info(inode); -- ENTRY; -- -- sema_init(&lli->lli_open_sem, 1); -- atomic_set(&lli->lli_open_count, 0); -- -- /* core attributes first */ -- ll_update_inode(inode, body); -- -- //if (body->valid & OBD_MD_FLEASIZE) - if (lic && lic->lic_lmm) { - struct lov_mds_md *lmm = lic->lic_lmm; - int size; - - /* XXX This should probably not be an error in the future, - * when we allow LOV OSTs to be added. - */ - if (lmm->lmm_easize != ll_mds_easize(inode->i_sb)) { - CERROR("Striping metadata size error %ld\n", - inode->i_ino); - LBUG(); - } - size = ll_ost_easize(inode->i_sb); - OBD_ALLOC(lli->lli_smd, size); - if (!lli->lli_smd) { - CERROR("No memory for %d\n", size); - LBUG(); - } - lov_unpackmd(lli->lli_smd, lmm); - } else { - lli->lli_smd = NULL; - } - LASSERT(!lli->lli_smd); - if (lic && lic->lic_lmm) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lic->lic_lmm); -- -- /* Get the authoritative file size */ -- if (lli->lli_smd && (inode->i_mode & S_IFREG)) { -- int rc; - - LASSERT(lli->lli_smd->lsm_object_id != 0); -- rc = ll_file_size(inode, lli->lli_smd); -- if (rc) { -- CERROR("ll_file_size: %d\n", rc); -- /* FIXME: need to somehow prevent inode creation */ -- LBUG(); - make_bad_inode(inode); -- } -- } -- -- /* OIDEBUG(inode); */ -- -- if (S_ISREG(inode->i_mode)) { -- inode->i_op = &ll_file_inode_operations; -- inode->i_fop = &ll_file_operations; -- inode->i_mapping->a_ops = &ll_aops; -- EXIT; -- } else if (S_ISDIR(inode->i_mode)) { -- inode->i_op = &ll_dir_inode_operations; -- inode->i_fop = &ll_dir_operations; -- inode->i_mapping->a_ops = &ll_dir_aops; -- EXIT; -- } else if (S_ISLNK(inode->i_mode)) { -- inode->i_op = &ll_fast_symlink_inode_operations; -- EXIT; -- } else { -- init_special_inode(inode, inode->i_mode, inode->i_rdev); -- EXIT; -- } --} -- --static inline void invalidate_request_list(struct list_head *req_list) --{ -- struct list_head *tmp, *n; -- list_for_each_safe(tmp, n, req_list) { -- struct ptlrpc_request *req = -- list_entry(tmp, struct ptlrpc_request, rq_list); -- CERROR("invalidating req xid "LPD64" op %d to %s:%d\n", -- (unsigned long long)req->rq_xid, req->rq_reqmsg->opc, -- req->rq_connection->c_remote_uuid, -- req->rq_import->imp_client->cli_request_portal); -- req->rq_flags |= PTL_RPC_FL_ERR; -- wake_up(&req->rq_wait_for_rep); -- } --} -- --void ll_umount_begin(struct super_block *sb) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct list_head *ctmp; -- -- ENTRY; -- -- list_for_each(ctmp, &sbi->ll_conn_chain) { -- struct ptlrpc_connection *conn; -- conn = list_entry(ctmp, struct ptlrpc_connection, c_sb_chain); -- -- spin_lock(&conn->c_lock); -- /* XXX should just be dealing with imports, probably through -- * XXX iocontrol, need next-gen recovery! */ -- conn->c_flags |= CONN_INVALID; - invalidate_request_list(&conn->c_sending_head); - /* invalidate_request_list(&conn->c_sending_head); */ -- invalidate_request_list(&conn->c_delayed_head); -- spin_unlock(&conn->c_lock); -- } -- -- EXIT; --} -- --/* exported operations */ --struct super_operations ll_super_operations = --{ -- read_inode2: ll_read_inode2, -- clear_inode: ll_clear_inode, -- delete_inode: ll_delete_inode, -- put_super: ll_put_super, -- statfs: ll_statfs, -- umount_begin: ll_umount_begin --}; -- --struct file_system_type lustre_lite_fs_type = { -- "lustre_lite", 0, ll_read_super, NULL --}; -- --static int __init init_lustre_lite(void) --{ -- printk(KERN_INFO "Lustre Lite 0.5.14, info@clusterfs.com\n"); -- ll_file_data_slab = kmem_cache_create("ll_file_data", -- sizeof(struct ll_file_data), 0, -- SLAB_HWCACHE_ALIGN, NULL, NULL); -- if (ll_file_data_slab == NULL) -- return -ENOMEM; -- return register_filesystem(&lustre_lite_fs_type); --} -- --static void __exit exit_lustre_lite(void) --{ -- unregister_filesystem(&lustre_lite_fs_type); -- kmem_cache_destroy(ll_file_data_slab); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Lite Client File System v1.0"); --MODULE_LICENSE("GPL"); -- --module_init(init_lustre_lite); --module_exit(exit_lustre_lite); --#endif diff --cc lustre/llite/super25.c index 270ecb6,cd6544a..0000000 deleted file mode 100644,100644 --- a/lustre/llite/super25.c +++ /dev/null @@@ -1,684 -1,659 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Lustre Light Super operations -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copryright (C) 2002 Cluster File Systems, Inc. -- */ -- --#define DEBUG_SUBSYSTEM S_LLITE -- --#include --#include --#include --#include --#include - #include --#include --#include --#include --#include -- --#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) --kmem_cache_t *ll_file_data_slab; --extern struct address_space_operations ll_aops; --extern struct address_space_operations ll_dir_aops; --struct super_operations ll_super_operations; -- --extern int ll_init_inodecache(void); --extern void ll_destroy_inodecache(void); --extern int ll_recover(struct recovd_data *, int); --extern int ll_commitcbd_setup(struct ll_sb_info *); --extern int ll_commitcbd_cleanup(struct ll_sb_info *); --int ll_read_inode2(struct inode *inode, void *opaque); -- --extern void ll_proc_namespace(struct super_block* sb, char* osc, char* mdc) -- --static char *ll_read_opt(const char *opt, char *data) --{ -- char *value; -- char *retval; -- ENTRY; -- -- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); -- if ( strncmp(opt, data, strlen(opt)) ) -- RETURN(NULL); -- if ( (value = strchr(data, '=')) == NULL ) -- RETURN(NULL); -- -- value++; -- OBD_ALLOC(retval, strlen(value) + 1); -- if ( !retval ) { -- CERROR("out of memory!\n"); -- RETURN(NULL); -- } -- -- memcpy(retval, value, strlen(value)+1); -- CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); -- RETURN(retval); --} -- --static int ll_set_opt(const char *opt, char *data, int fl) --{ -- ENTRY; -- -- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data); -- if ( strncmp(opt, data, strlen(opt)) ) -- RETURN(0); -- else -- RETURN(fl); --} -- --static void ll_options(char *options, char **ost, char **mds, int *flags) --{ -- char *opt_ptr = options; -- char *this_char; -- ENTRY; -- -- if (!options) { -- EXIT; -- return; -- } -- -- while ((this_char = strsep (&opt_ptr, ",")) != NULL) { -- CDEBUG(D_SUPER, "this_char %s\n", this_char); -- if ( (!*ost && (*ost = ll_read_opt("osc", this_char)))|| -- (!*mds && (*mds = ll_read_opt("mdc", this_char)))|| - (!(*flags & LL_SBI_NOLCK) && ((*flags) = (*flags) | - (!(*flags & LL_SBI_NOLCK) && ((*flags) = (*flags) | -- ll_set_opt("nolock", this_char, LL_SBI_NOLCK))) ) -- continue; -- } -- EXIT; --} -- --#ifndef log2 --#define log2(n) ffz(~(n)) --#endif -- -- --static int ll_fill_super(struct super_block *sb, void *data, int silent) --{ -- struct inode *root = 0; -- struct obd_device *obd; -- struct ll_sb_info *sbi; -- char *osc = NULL; -- char *mdc = NULL; -- int err; -- struct ll_fid rootfid; -- struct obd_statfs osfs; -- struct ptlrpc_request *request = NULL; -- struct ptlrpc_connection *mdc_conn; -- struct ll_read_inode2_cookie lic; -- class_uuid_t uuid; -- -- ENTRY; -- MOD_INC_USE_COUNT; -- -- OBD_ALLOC(sbi, sizeof(*sbi)); -- if (!sbi) { -- MOD_DEC_USE_COUNT; -- RETURN(-ENOMEM); -- } -- -- INIT_LIST_HEAD(&sbi->ll_conn_chain); -- generate_random_uuid(uuid); -- class_uuid_unparse(uuid, sbi->ll_sb_uuid); -- -- sb->s_fs_info = sbi; -- -- ll_options(data, &osc, &mdc, &sbi->ll_flags); -- -- if (!osc) { -- CERROR("no osc\n"); -- GOTO(out_free, sb = NULL); -- } -- -- if (!mdc) { -- CERROR("no mdc\n"); -- GOTO(out_free, sb = NULL); -- } -- -- obd = class_uuid2obd(mdc); -- if (!obd) { -- CERROR("MDC %s: not setup or attached\n", mdc); -- GOTO(out_free, sb = NULL); -- } -- -- err = obd_connect(&sbi->ll_mdc_conn, obd, sbi->ll_sb_uuid, -- ptlrpc_recovd, ll_recover); -- if (err) { -- CERROR("cannot connect to %s: rc = %d\n", mdc, err); -- GOTO(out_free, sb = NULL); -- } -- - #warning Peter: is this the right place to raise the connection level? -- mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection; - mdc_conn->c_level = LUSTRE_CONN_FULL; -- list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain); -- -- obd = class_uuid2obd(osc); -- if (!obd) { -- CERROR("OSC %s: not setup or attached\n", osc); -- GOTO(out_mdc, sb = NULL); -- } -- -- err = obd_connect(&sbi->ll_osc_conn, obd, sbi->ll_sb_uuid, -- ptlrpc_recovd, ll_recover); -- if (err) { -- CERROR("cannot connect to %s: rc = %d\n", osc, err); -- GOTO(out_mdc, sb = NULL); -- } -- -- err = mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); -- if (err) { -- CERROR("cannot mds_connect: rc = %d\n", err); -- GOTO(out_mdc, sb = NULL); -- } -- CDEBUG(D_SUPER, "rootfid "LPU64"\n", rootfid.id); -- sbi->ll_rootino = rootfid.id; -- -- memset(&osfs, 0, sizeof(osfs)); -- err = mdc_statfs(&sbi->ll_mdc_conn, &osfs); -- sb->s_blocksize = osfs.os_bsize; -- sb->s_blocksize_bits = log2(osfs.os_bsize); -- sb->s_magic = LL_SUPER_MAGIC; -- sb->s_maxbytes = (1ULL << (32 + 9)) - osfs.os_bsize; -- -- sb->s_op = &ll_super_operations; -- -- /* make root inode */ -- err = mdc_getattr(&sbi->ll_mdc_conn, sbi->ll_rootino, S_IFDIR, -- OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); -- if (err) { -- CERROR("mdc_getattr failed for root: rc = %d\n", err); -- GOTO(out_request, sb = NULL); -- } -- -- /* initialize committed transaction callback daemon */ -- spin_lock_init(&sbi->ll_commitcbd_lock); -- init_waitqueue_head(&sbi->ll_commitcbd_waitq); -- init_waitqueue_head(&sbi->ll_commitcbd_ctl_waitq); -- sbi->ll_commitcbd_flags = 0; -- err = ll_commitcbd_setup(sbi); -- if (err) { -- CERROR("failed to start commit callback daemon: rc = %d\n",err); -- GOTO(out_request, sb = NULL); -- } -- -- lic.lic_body = lustre_msg_buf(request->rq_repmsg, 0); -- lic.lic_lmm = NULL; -- root = iget5_locked(sb, sbi->ll_rootino, NULL, -- ll_read_inode2, &lic); -- -- if (root) { -- sb->s_root = d_alloc_root(root); -- } else { -- CERROR("lustre_lite: bad iget4 for root\n"); -- GOTO(out_cdb, sb = NULL); -- } -- -- ptlrpc_req_finished(request); -- request = NULL; -- ll_proc_namespace(sb, osc, mdc) --out_dev: -- if (mdc) -- OBD_FREE(mdc, strlen(mdc) + 1); -- if (osc) -- OBD_FREE(osc, strlen(osc) + 1); -- -- RETURN(0); -- --out_cdb: -- ll_commitcbd_cleanup(sbi); --out_request: -- ptlrpc_req_finished(request); -- obd_disconnect(&sbi->ll_osc_conn); --out_mdc: -- obd_disconnect(&sbi->ll_mdc_conn); --out_free: -- OBD_FREE(sbi, sizeof(*sbi)); -- -- MOD_DEC_USE_COUNT; -- goto out_dev; --} /* ll_fill_super */ -- - struct super_block * ll_get_sb(struct file_system_type *fs_type, - int flags, char *devname, void * data) -struct super_block * ll_get_sb(struct file_system_type *fs_type, - int flags, char *devname, void * data) --{ -- return get_sb_nodev(fs_type, flags, data, ll_fill_super); --} -- --static void ll_put_super(struct super_block *sb) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct ll_fid rootfid; -- ENTRY; -- -- list_del(&sbi->ll_conn_chain); -- ll_commitcbd_cleanup(sbi); -- obd_disconnect(&sbi->ll_osc_conn); -- -- /* NULL request to force sync on the MDS, and get the last_committed -- * value to flush remaining RPCs from the pending queue on client. -- * -- * XXX This should be an mdc_sync() call to sync the whole MDS fs, -- * which we can call for other reasons as well. -- */ -- mdc_getstatus(&sbi->ll_mdc_conn, &rootfid); -- -- lprocfs_dereg_mnt(sbi->ll_proc_root); -- sbi->ll_proc_root = NULL; -- -- obd_disconnect(&sbi->ll_mdc_conn); -- OBD_FREE(sbi, sizeof(*sbi)); -- -- MOD_DEC_USE_COUNT; -- EXIT; --} /* ll_put_super */ -- --static void ll_clear_inode(struct inode *inode) --{ -- ENTRY; -- -- if (atomic_read(&inode->i_count) == 0) { -- struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; -- char *symlink_name = lli->lli_symlink_name; -- - if (lsm) { - OBD_FREE(lsm, ll_ost_easize(inode->i_sb)); - lli->lli_smd = NULL; - } - if (lli->lli_smd) - obd_free_memmd(&sbi->ll_osc_conn, &lli->lli_smd); -- if (symlink_name) { -- OBD_FREE(symlink_name, strlen(symlink_name) + 1); -- lli->lli_symlink_name = NULL; -- } -- } -- EXIT; --} -- --static void ll_delete_inode(struct inode *inode) --{ -- ENTRY; -- if (S_ISREG(inode->i_mode)) { -- int err; -- struct obdo *oa; -- struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd; -- -- if (!lsm) -- GOTO(out, -EINVAL); -- -- if (lsm->lsm_object_id == 0) { -- CERROR("This really happens\n"); -- /* No obdo was ever created */ -- GOTO(out, 0); -- } -- -- oa = obdo_alloc(); -- if (oa == NULL) -- GOTO(out, -ENOMEM); -- -- oa->o_id = lsm->lsm_object_id; - oa->o_easize = ll_mds_easize(inode->i_sb); -- oa->o_mode = inode->i_mode; -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLEASIZE | OBD_MD_FLTYPE; -- -- err = obd_destroy(ll_i2obdconn(inode), oa, lsm); -- obdo_free(oa); -- CDEBUG(D_SUPER, "obd destroy of objid "LPX64" error %d\n", -- lsm->lsm_object_id, err); -- } --out: -- clear_inode(inode); -- EXIT; --} -- --/* like inode_setattr, but doesn't mark the inode dirty */ --static int ll_attr2inode(struct inode * inode, struct iattr * attr, int trunc) --{ -- unsigned int ia_valid = attr->ia_valid; -- int error = 0; -- -- if ((ia_valid & ATTR_SIZE) && trunc) { -- error = vmtruncate(inode, attr->ia_size); -- if (error) -- goto out; -- } else if (ia_valid & ATTR_SIZE) -- inode->i_size = attr->ia_size; -- -- if (ia_valid & ATTR_UID) -- inode->i_uid = attr->ia_uid; -- if (ia_valid & ATTR_GID) -- inode->i_gid = attr->ia_gid; -- if (ia_valid & ATTR_ATIME) -- inode->i_atime = attr->ia_atime; -- if (ia_valid & ATTR_MTIME) -- inode->i_mtime = attr->ia_mtime; -- if (ia_valid & ATTR_CTIME) -- inode->i_ctime = attr->ia_ctime; -- if (ia_valid & ATTR_MODE) { -- inode->i_mode = attr->ia_mode; -- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) -- inode->i_mode &= ~S_ISGID; -- } --out: -- return error; --} -- --int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc) --{ -- struct ptlrpc_request *request = NULL; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- int err; -- -- ENTRY; -- -- /* change incore inode */ -- ll_attr2inode(inode, attr, do_trunc); -- -- err = mdc_setattr(&sbi->ll_mdc_conn, inode, attr, &request); -- if (err) -- CERROR("mdc_setattr fails (%d)\n", err); -- -- ptlrpc_req_finished(request); -- -- RETURN(err); --} -- --int ll_setattr(struct dentry *de, struct iattr *attr) --{ -- int rc = inode_change_ok(de->d_inode, attr); -- -- if (rc) -- return rc; -- -- return ll_inode_setattr(de->d_inode, attr, 1); --} -- --static int ll_statfs(struct super_block *sb, struct statfs *sfs) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct obd_statfs osfs; -- int rc; -- ENTRY; -- -- memset(sfs, 0, sizeof(*sfs)); -- rc = obd_statfs(&sbi->ll_mdc_conn, &osfs); -- statfs_unpack(sfs, &osfs); -- if (rc) -- CERROR("mdc_statfs fails: rc = %d\n", rc); -- else -- CDEBUG(D_SUPER, "mdc_statfs shows blocks "LPU64"/"LPU64 -- " objects "LPU64"/"LPU64"\n", -- osfs.os_bavail, osfs.os_blocks, -- osfs.os_ffree, osfs.os_files); -- -- /* temporary until mds_statfs returns statfs info for all OSTs */ -- if (!rc) { -- rc = obd_statfs(&sbi->ll_osc_conn, &osfs); -- if (rc) { -- CERROR("obd_statfs fails: rc = %d\n", rc); -- GOTO(out, rc); -- } -- CDEBUG(D_SUPER, "obd_statfs shows blocks "LPU64"/"LPU64 -- " objects "LPU64"/"LPU64"\n", -- osfs.os_bavail, osfs.os_blocks, -- osfs.os_ffree, osfs.os_files); -- -- while (osfs.os_blocks > ~0UL) { -- sfs->f_bsize <<= 1; -- -- osfs.os_blocks >>= 1; -- osfs.os_bfree >>= 1; -- osfs.os_bavail >>= 1; -- } -- sfs->f_blocks = osfs.os_blocks; -- sfs->f_bfree = osfs.os_bfree; -- sfs->f_bavail = osfs.os_bavail; -- if (osfs.os_ffree < (__u64)sfs->f_ffree) -- sfs->f_ffree = osfs.os_ffree; -- } -- --out: -- RETURN(rc); --} -- --void ll_update_inode(struct inode *inode, struct mds_body *body) --{ -- if (body->valid & OBD_MD_FLID) -- inode->i_ino = body->ino; -- if (body->valid & OBD_MD_FLATIME) -- inode->i_atime = body->atime; -- if (body->valid & OBD_MD_FLMTIME) -- inode->i_mtime = body->mtime; -- if (body->valid & OBD_MD_FLCTIME) -- inode->i_ctime = body->ctime; -- if (body->valid & OBD_MD_FLMODE) -- inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); -- if (body->valid & OBD_MD_FLTYPE) -- inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); -- if (body->valid & OBD_MD_FLUID) -- inode->i_uid = body->uid; -- if (body->valid & OBD_MD_FLGID) -- inode->i_gid = body->gid; -- if (body->valid & OBD_MD_FLFLAGS) -- inode->i_flags = body->flags; -- if (body->valid & OBD_MD_FLNLINK) -- inode->i_nlink = body->nlink; -- if (body->valid & OBD_MD_FLGENER) -- inode->i_generation = body->generation; -- if (body->valid & OBD_MD_FLRDEV) -- inode->i_rdev = to_kdev_t(body->rdev); -- if (body->valid & OBD_MD_FLSIZE) -- inode->i_size = body->size; --} -- --int ll_read_inode2(struct inode *inode, void *opaque) --{ -- struct ll_read_inode2_cookie *lic = opaque; -- struct mds_body *body = lic->lic_body; -- struct ll_inode_info *lli = ll_i2info(inode); - int rc = 0; -- ENTRY; -- -- sema_init(&lli->lli_open_sem, 1); -- -- /* core attributes first */ -- ll_update_inode(inode, body); -- -- //if (body->valid & OBD_MD_FLEASIZE) - if (lic && lic->lic_lmm) { - struct lov_mds_md *lmm = lic->lic_lmm; - int size; - - /* XXX This should probably not be an error in the future, - * when we allow LOV OSTs to be added. - */ - if (lmm->lmm_easize != ll_mds_easize(inode->i_sb)) { - CERROR("Striping metadata size error %ld\n", - inode->i_ino); - LBUG(); - } - size = ll_ost_easize(inode->i_sb); - OBD_ALLOC(lli->lli_smd, size); - if (!lli->lli_smd) { - CERROR("No memory for %d\n", size); - LBUG(); - } - lov_unpackmd(lli->lli_smd, lmm); - } else { - lli->lli_smd = NULL; - } - LASSERT(!lli->lli_smd); - if (lic && lic->lic_lmm) - obd_unpackmd(ll_i2obdconn(inode), &lli->lli_smd, lic->lic_lmm); -- -- /* Get the authoritative file size */ - if (lli->lli_smd && (inode->i_mode & S_IFREG)) { - int rc; - - if (lli->lli_smd && S_ISREG(inode->i_mode)) { -- rc = ll_file_size(inode, lli->lli_smd); -- if (rc) { -- CERROR("ll_file_size: %d\n", rc); -- /* FIXME: need to somehow prevent inode creation */ -- LBUG(); - make_bad_inode(inode); -- } -- } -- -- /* OIDEBUG(inode); */ -- -- if (S_ISREG(inode->i_mode)) { -- inode->i_op = &ll_file_inode_operations; -- inode->i_fop = &ll_file_operations; -- inode->i_mapping->a_ops = &ll_aops; -- EXIT; -- } else if (S_ISDIR(inode->i_mode)) { -- inode->i_op = &ll_dir_inode_operations; -- inode->i_fop = &ll_dir_operations; -- inode->i_mapping->a_ops = &ll_dir_aops; -- EXIT; -- } else if (S_ISLNK(inode->i_mode)) { -- inode->i_op = &ll_fast_symlink_inode_operations; -- EXIT; -- } else { -- init_special_inode(inode, inode->i_mode, -- kdev_t_to_nr(inode->i_rdev)); -- EXIT; -- } - return 0; - - return rc; --} -- --static inline void invalidate_request_list(struct list_head *req_list) --{ -- struct list_head *tmp, *n; -- list_for_each_safe(tmp, n, req_list) { - struct ptlrpc_request *req = - struct ptlrpc_request *req = -- list_entry(tmp, struct ptlrpc_request, rq_list); -- CERROR("invalidating req xid %d op %d to %s:%d\n", -- (unsigned long long)req->rq_xid, req->rq_reqmsg->opc, -- req->rq_connection->c_remote_uuid, -- req->rq_import->imp_client->cli_request_portal); -- req->rq_flags |= PTL_RPC_FL_ERR; -- wake_up(&req->rq_wait_for_rep); -- } --} -- --void ll_umount_begin(struct super_block *sb) --{ -- struct ll_sb_info *sbi = ll_s2sbi(sb); -- struct list_head *ctmp; -- -- ENTRY; - - -- list_for_each(ctmp, &sbi->ll_conn_chain) { -- struct ptlrpc_connection *conn; -- conn = list_entry(ctmp, struct ptlrpc_connection, c_sb_chain); -- -- spin_lock(&conn->c_lock); -- conn->c_flags |= CONN_INVALID; -- invalidate_request_list(&conn->c_sending_head); -- invalidate_request_list(&conn->c_delayed_head); -- spin_unlock(&conn->c_lock); -- } -- -- EXIT; --} -- -- --static kmem_cache_t *ll_inode_cachep; -- --static struct inode *ll_alloc_inode(struct super_block *sb) --{ -- struct ll_inode_info *lli; -- lli = kmem_cache_alloc(ll_inode_cachep, SLAB_KERNEL); -- if (!lli) -- return NULL; -- -- memset(lli, 0, (char *)&lli->lli_vfs_inode - (char *)lli); -- sema_init(&lli->lli_open_sem, 1); -- -- return &lli->lli_vfs_inode; --} -- --static void ll_destroy_inode(struct inode *inode) --{ -- kmem_cache_free(ll_inode_cachep, ll_i2info(inode)); --} -- --static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) --{ -- struct ll_inode_info *lli = foo; -- -- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == -- SLAB_CTOR_CONSTRUCTOR) -- inode_init_once(&lli->lli_vfs_inode); --} -- --int ll_init_inodecache(void) --{ -- ll_inode_cachep = kmem_cache_create("lustre_inode_cache", -- sizeof(struct ll_inode_info), -- 0, SLAB_HWCACHE_ALIGN, -- init_once, NULL); -- if (ll_inode_cachep == NULL) -- return -ENOMEM; -- return 0; --} -- --void ll_destroy_inodecache(void) --{ -- if (kmem_cache_destroy(ll_inode_cachep)) -- CERROR("ll_inode_cache: not all structures were freed\n"); --} -- -- -- --/* exported operations */ --struct super_operations ll_super_operations = --{ -- alloc_inode: ll_alloc_inode, -- destroy_inode: ll_destroy_inode, -- clear_inode: ll_clear_inode, -- delete_inode: ll_delete_inode, -- put_super: ll_put_super, -- statfs: ll_statfs, -- umount_begin: ll_umount_begin --}; -- --struct file_system_type lustre_lite_fs_type = { -- .owner = THIS_MODULE, - .name = "lustre_lite", - .name = "lustre_lite", -- .get_sb = ll_get_sb, -- .kill_sb = kill_litter_super, --}; -- --static int __init init_lustre_lite(void) --{ -- int rc; -- printk(KERN_INFO "Lustre Lite 0.5.14, info@clusterfs.com\n"); -- rc = ll_init_inodecache(); - if (rc) - if (rc) -- return -ENOMEM; -- ll_file_data_slab = kmem_cache_create("ll_file_data", -- sizeof(struct ll_file_data), 0, -- SLAB_HWCACHE_ALIGN, NULL, NULL); - if (ll_file_data_slab == NULL) { - if (ll_file_data_slab == NULL) { -- ll_destroy_inodecache(); -- return -ENOMEM; -- } -- return register_filesystem(&lustre_lite_fs_type); --} -- --static void __exit exit_lustre_lite(void) --{ -- unregister_filesystem(&lustre_lite_fs_type); -- ll_destroy_inodecache(); -- kmem_cache_destroy(ll_file_data_slab); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Lite Client File System v1.0"); --MODULE_LICENSE("GPL"); -- --module_init(init_lustre_lite); --module_exit(exit_lustre_lite); --#endif diff --cc lustre/llite/symlink.c index 8042589,93a4bdb..0000000 deleted file mode 100644,100644 --- a/lustre/llite/symlink.c +++ /dev/null @@@ -1,123 -1,123 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (c) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#include --#include --#include --#include --#define DEBUG_SUBSYSTEM S_LLITE -- --#include -- --static int ll_readlink_internal(struct inode *inode, -- struct ptlrpc_request **request, char **symname) --{ -- struct ll_inode_info *lli = ll_i2info(inode); -- struct ll_sb_info *sbi = ll_i2sbi(inode); - int rc, len = inode->i_size + 1; - int rc, symlen = inode->i_size + 1; -- ENTRY; -- -- *request = NULL; -- -- if (lli->lli_symlink_name) { -- *symname = lli->lli_symlink_name; -- CDEBUG(D_INODE, "using cached symlink %s\n", *symname); -- RETURN(0); -- } -- -- rc = mdc_getattr(&sbi->ll_mdc_conn, inode->i_ino, S_IFLNK, - OBD_MD_LINKNAME, len, request); - OBD_MD_LINKNAME, symlen, request); -- if (rc) { -- CERROR("inode "LPD64": rc = %d\n", inode->i_ino, rc); -- RETURN(rc); -- } -- -- *symname = lustre_msg_buf((*request)->rq_repmsg, 1); -- - OBD_ALLOC(lli->lli_symlink_name, len); - OBD_ALLOC(lli->lli_symlink_name, symlen); -- /* do not return an error if we cannot cache the symlink locally */ -- if (lli->lli_symlink_name) - memcpy(lli->lli_symlink_name, *symname, len); - memcpy(lli->lli_symlink_name, *symname, symlen); -- -- RETURN(0); --} -- --static int ll_readlink(struct dentry *dentry, char *buffer, int buflen) --{ -- struct inode *inode = dentry->d_inode; -- struct ll_inode_info *lli = ll_i2info(inode); -- struct ptlrpc_request *request; -- char *symname; -- int rc; -- ENTRY; -- -- /* on symlinks lli_open_sem protects lli_symlink_name allocation/data */ -- down(&lli->lli_open_sem); -- rc = ll_readlink_internal(inode, &request, &symname); -- if (rc) -- GOTO(out, rc); -- -- rc = vfs_readlink(dentry, buffer, buflen, symname); -- out: -- up(&lli->lli_open_sem); -- ptlrpc_req_finished(request); -- -- RETURN(rc); --} -- --static int ll_follow_link(struct dentry *dentry, struct nameidata *nd, -- struct lookup_intent *it) --{ -- struct inode *inode = dentry->d_inode; -- struct ll_inode_info *lli = ll_i2info(inode); -- struct ptlrpc_request *request; - int op, mode; -- char *symname; -- int rc; -- ENTRY; -- - /* we got here from a lookup up to the symlink that we hit */ - if (it->it_lock_mode) { - struct lustre_handle *handle = - (struct lustre_handle *)it->it_lock_handle; - ldlm_lock_decref(handle, it->it_lock_mode); - it->it_lock_mode = 0; - memset(handle, 0, sizeof(*handle)); - } - op = it->it_op; - mode = it->it_mode; -- - ll_intent_release(dentry, it); -- down(&lli->lli_open_sem); - - it->it_op = op; - it->it_mode = mode; - -- rc = ll_readlink_internal(inode, &request, &symname); -- if (rc) -- GOTO(out, rc); -- -- rc = vfs_follow_link_it(nd, symname, it); -- out: -- up(&lli->lli_open_sem); -- ptlrpc_req_finished(request); -- -- RETURN(rc); --} -- --extern int ll_setattr(struct dentry *de, struct iattr *attr); --struct inode_operations ll_fast_symlink_inode_operations = { -- readlink: ll_readlink, -- setattr: ll_setattr, -- follow_link2: ll_follow_link --}; diff --cc lustre/llite/sysctl.c index ee4ac75,ee4ac75..0000000 deleted file mode 100644,100644 --- a/lustre/llite/sysctl.c +++ /dev/null @@@ -1,67 -1,67 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --struct ctl_table_header *ll_table_header = NULL; -- --int ll_debug_level = 0; --int ll_print_entry = 1; -- -- --#define LL_SYSCTL 1 -- --#define LL_DEBUG 1 /* control debugging */ --#define LL_ENTRY 2 /* control enter/leave pattern */ --#define LL_TIMEOUT 3 /* timeout on upcalls to become intrble */ --#define LL_HARD 4 /* mount type "hard" or "soft" */ --#define LL_VARS 5 --#define LL_INDEX 6 --#define LL_RESET 7 -- --#define LL_VARS_SLOT 2 -- --static ctl_table ll_table[] = { -- {LL_DEBUG, "debug", &ll_debug_level, sizeof(int), 0644, NULL, &proc_dointvec}, -- {LL_ENTRY, "trace", &ll_print_entry, sizeof(int), 0644, NULL, &proc_dointvec}, -- { 0 } --}; -- --static ctl_table top_table[] = { -- {LL_SYSCTL, "lustre_light", NULL, 0, 0555, ll_table}, -- {0} --}; -- --void ll_sysctl_init (void) --{ -- --#ifdef CONFIG_SYSCTL -- if ( !ll_table_header ) -- ll_table_header = register_sysctl_table(top_table, 0); --#endif --} -- --void ll_sysctl_clean (void) --{ --#ifdef CONFIG_SYSCTL -- if ( ll_table_header ) -- unregister_sysctl_table(ll_table_header); -- ll_table_header = NULL; --#endif --} diff --cc lustre/lov/.cvsignore index e995588,e995588..0000000 deleted file mode 100644,100644 --- a/lustre/lov/.cvsignore +++ /dev/null @@@ -1,3 -1,3 +1,0 @@@ --.deps --Makefile --Makefile.in diff --cc lustre/lov/Makefile.am index 38d23d4,2320dcc..0000000 deleted file mode 100644,100644 --- a/lustre/lov/Makefile.am +++ /dev/null @@@ -1,18 -1,15 +1,0 @@@ --# Copyright (C) 2002 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --MODULE = lov --modulefs_DATA = lov.o --EXTRA_PROGRAMS = lov - LINX= lov_pack.c - - lov_SOURCES = lov_obd.c lproc_lov.c $(LINX) -LINX= -- - lov_pack.c: - test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c -lov_SOURCES = lov_obd.c lov_pack.c lproc_lov.c $(LINX) -- --include $(top_srcdir)/Rules diff --cc lustre/lov/lov_obd.c index 7d41e3b,e7cf3cb..0000000 deleted file mode 100644,100644 --- a/lustre/lov/lov_obd.c +++ /dev/null @@@ -1,1422 -1,1503 +1,0 @@@ -- /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lov/lov.c -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Phil Schwan -- * Peter Braam -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_LOV -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --static kmem_cache_t *lov_file_cache; -- --struct lov_file_handles { -- struct list_head lfh_list; -- __u64 lfh_cookie; -- int lfh_count; -- struct lustre_handle *lfh_handles; --}; - -extern int lov_packmd(struct lustre_handle *conn, struct lov_mds_md **lmm, - struct lov_stripe_md *lsm); -extern int lov_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsm, - struct lov_mds_md *lmm); -- --/* obd methods */ -int lov_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -int lov_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - --static int lov_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- struct ptlrpc_request *req = NULL; -- struct lov_obd *lov = &obd->u.lov; -- struct client_obd *mdc = &lov->mdcobd->u.cli; -- struct lov_desc *desc = &lov->desc; -- struct obd_export *exp; -- struct lustre_handle mdc_conn; -- obd_uuid_t *uuidarray; -- int rc, rc2, i; -- ENTRY; -- -- MOD_INC_USE_COUNT; -- rc = class_connect(conn, obd, cluuid); - if (rc) { - MOD_DEC_USE_COUNT; - RETURN(rc); - } - if (rc) - GOTO(out_dec, rc); -- -- /* We don't want to actually do the underlying connections more than -- * once, so keep track. */ -- lov->refcount++; -- if (lov->refcount > 1) -- RETURN(0); -- -- exp = class_conn2export(conn); -- INIT_LIST_HEAD(&exp->exp_lov_data.led_open_head); -- -- /* retrieve LOV metadata from MDS */ -- rc = obd_connect(&mdc_conn, lov->mdcobd, NULL, recovd, recover); -- if (rc) { -- CERROR("cannot connect to mdc: rc = %d\n", rc); -- GOTO(out_conn, rc); -- } -- -- rc = mdc_getlovinfo(obd, &mdc_conn, &req); -- rc2 = obd_disconnect(&mdc_conn); -- if (rc) { -- CERROR("cannot get lov info %d\n", rc); -- GOTO(out_conn, rc); -- } -- -- if (rc2) { -- CERROR("error disconnecting from MDS %d\n", rc2); -- GOTO(out_conn, rc = rc2); -- } -- -- /* sanity... */ -- if (req->rq_repmsg->bufcount < 2 || -- req->rq_repmsg->buflens[0] < sizeof(*desc)) { -- CERROR("LOV desc: invalid descriptor returned\n"); -- GOTO(out_conn, rc = -EINVAL); -- } -- -- memcpy(desc, lustre_msg_buf(req->rq_repmsg, 0), sizeof(*desc)); -- lov_unpackdesc(desc); -- -- if (req->rq_repmsg->buflens[1] < sizeof(*uuidarray)*desc->ld_tgt_count){ -- CERROR("LOV desc: invalid uuid array returned\n"); -- GOTO(out_conn, rc = -EINVAL); -- } - - mdc->cl_max_mds_easize = lov_mds_md_size(desc->ld_tgt_count); - mdc->cl_max_ost_easize = lov_stripe_md_size(desc->ld_tgt_count); -- -- if (memcmp(obd->obd_uuid, desc->ld_uuid, sizeof(desc->ld_uuid))) { -- CERROR("LOV desc: uuid %s not on mds device (%s)\n", -- obd->obd_uuid, desc->ld_uuid); -- GOTO(out_conn, rc = -EINVAL); -- } -- -- if (desc->ld_tgt_count > 1000) { -- CERROR("LOV desc: target count > 1000 (%d)\n", -- desc->ld_tgt_count); -- GOTO(out_conn, rc = -EINVAL); -- } -- -- /* Because of 64-bit divide/mod operations only work with a 32-bit -- * divisor in a 32-bit kernel, we cannot support a stripe width -- * of 4GB or larger on 32-bit CPUs. -- */ -- if ((desc->ld_default_stripe_count ? -- desc->ld_default_stripe_count : desc->ld_tgt_count) * -- desc->ld_default_stripe_size > ~0UL) { -- CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n", -- desc->ld_default_stripe_size, -- desc->ld_default_stripe_count ? -- desc->ld_default_stripe_count : desc->ld_tgt_count,~0UL); -- GOTO(out_conn, rc = -EINVAL); -- } -- -- lov->bufsize = sizeof(struct lov_tgt_desc) * desc->ld_tgt_count; -- OBD_ALLOC(lov->tgts, lov->bufsize); -- if (!lov->tgts) { -- CERROR("Out of memory\n"); -- GOTO(out_conn, rc = -ENOMEM); -- } -- -- uuidarray = lustre_msg_buf(req->rq_repmsg, 1); -- for (i = 0; i < desc->ld_tgt_count; i++) -- memcpy(lov->tgts[i].uuid, uuidarray[i], sizeof(*uuidarray)); -- -- for (i = 0; i < desc->ld_tgt_count; i++) { -- struct obd_device *tgt = class_uuid2obd(uuidarray[i]); - int rc2; -- -- if (!tgt) { -- CERROR("Target %s not attached\n", uuidarray[i]); -- GOTO(out_disc, rc = -EINVAL); -- } -- -- if (!(tgt->obd_flags & OBD_SET_UP)) { -- CERROR("Target %s not set up\n", uuidarray[i]); -- GOTO(out_disc, rc = -EINVAL); -- } -- -- rc = obd_connect(&lov->tgts[i].conn, tgt, NULL, recovd, -- recover); - if (rc) { - CERROR("Target %s connect error %d\n", - uuidarray[i], rc); - GOTO(out_disc, rc); - - /* Register even if connect failed, so that we get reactivation - * notices. - */ - rc2 = obd_iocontrol(IOC_OSC_REGISTER_LOV, &lov->tgts[i].conn, - sizeof(struct obd_device *), obd, NULL); - if (rc2) { - CERROR("Target %s REGISTER_LOV error %d\n", - uuidarray[i], rc2); - GOTO(out_disc, rc2); -- } - rc = obd_iocontrol(IOC_OSC_REGISTER_LOV, &lov->tgts[i].conn, - sizeof(struct obd_device *), obd, NULL); - - /* But mark failed-connect OSCs as inactive! */ -- if (rc) { - CERROR("Target %s REGISTER_LOV error %d\n", - CDEBUG(D_INFO, "Target %s connect error %d\n", -- uuidarray[i], rc); - GOTO(out_disc, rc); - LASSERT(lov->tgts[i].active == 0); - rc = 0; - continue; -- } - -- desc->ld_active_tgt_count++; -- lov->tgts[i].active = 1; -- } - - mdc->cl_max_mds_easize = obd_size_wiremd(conn, NULL); -- -- out: -- ptlrpc_req_finished(req); -- RETURN(rc); -- -- out_disc: -- while (i-- > 0) { -- desc->ld_active_tgt_count--; -- lov->tgts[i].active = 0; -- rc2 = obd_disconnect(&lov->tgts[i].conn); -- if (rc2) -- CERROR("LOV Target %s disconnect error: rc = %d\n", -- uuidarray[i], rc2); -- } -- OBD_FREE(lov->tgts, lov->bufsize); -- out_conn: -- class_disconnect(conn); - out_dec: - MOD_DEC_USE_COUNT; -- goto out; --} -- --static int lov_disconnect(struct lustre_handle *conn) --{ -- struct obd_device *obd = class_conn2obd(conn); -- struct lov_obd *lov = &obd->u.lov; -- struct obd_export *exp; -- struct list_head *p, *n; -- int rc, i; -- -- if (!lov->tgts) -- goto out_local; -- -- /* Only disconnect the underlying layers on the final disconnect. */ -- lov->refcount--; -- if (lov->refcount != 0) -- goto out_local; -- -- for (i = 0; i < lov->desc.ld_tgt_count; i++) { - if (!lov->tgts[i].active) { - CERROR("Skipping disconnect for inactive OSC %s\n", - lov->tgts[i].uuid); - continue; - } - - lov->desc.ld_active_tgt_count--; - lov->tgts[i].active = 0; -- rc = obd_disconnect(&lov->tgts[i].conn); -- if (rc) { - CERROR("Target %s disconnect error %d\n", - lov->tgts[i].uuid, rc); - RETURN(rc); - if (lov->tgts[i].active) { - CERROR("Target %s disconnect error %d\n", - lov->tgts[i].uuid, rc); - } - rc = 0; - } - if (lov->tgts[i].active) { - lov->desc.ld_active_tgt_count--; - lov->tgts[i].active = 0; -- } -- } -- OBD_FREE(lov->tgts, lov->bufsize); -- lov->bufsize = 0; -- lov->tgts = NULL; -- -- exp = class_conn2export(conn); -- list_for_each_safe(p, n, &exp->exp_lov_data.led_open_head) { -- /* XXX close these, instead of just discarding them? */ -- struct lov_file_handles *lfh; -- lfh = list_entry(p, typeof(*lfh), lfh_list); -- CERROR("discarding open LOV handle %p:"LPX64"\n", -- lfh, lfh->lfh_cookie); -- list_del(&lfh->lfh_list); -- OBD_FREE(lfh->lfh_handles, -- lfh->lfh_count * sizeof(*lfh->lfh_handles)); -- kmem_cache_free(lov_file_cache, lfh); -- } -- -- out_local: -- rc = class_disconnect(conn); -- if (!rc) -- MOD_DEC_USE_COUNT; -- return rc; --} -- --/* Error codes: -- * -- * -EINVAL : UUID can't be found in the LOV's target list -- * -ENOTCONN: The UUID is found, but the target connection is bad (!) -- * -EBADF : The UUID is found, but the OBD is the wrong type (!) -- * -EALREADY: The OSC is already marked (in)active -- */ --static int lov_set_osc_active(struct lov_obd *lov, obd_uuid_t uuid, -- int activate) --{ -- struct obd_device *obd; -- int i, rc = 0; -- ENTRY; -- -- CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n", -- lov, uuid, activate); -- -- spin_lock(&lov->lov_lock); -- for (i = 0; i < lov->desc.ld_tgt_count; i++) -- if (strncmp(uuid, lov->tgts[i].uuid, -- sizeof(lov->tgts[i].uuid)) == 0) -- break; -- -- if (i == lov->desc.ld_tgt_count) -- GOTO(out, rc = -EINVAL); -- -- obd = class_conn2obd(&lov->tgts[i].conn); -- if (obd == NULL) { -- LBUG(); -- GOTO(out, rc = -ENOTCONN); -- } -- -- CDEBUG(D_INFO, "Found OBD %p type %s\n", obd, obd->obd_type->typ_name); -- if (strcmp(obd->obd_type->typ_name, "osc") != 0) { -- LBUG(); -- GOTO(out, rc = -EBADF); -- } -- -- if (lov->tgts[i].active == activate) { -- CDEBUG(D_INFO, "OBD %p already %sactive!\n", obd, -- activate ? "" : "in"); -- GOTO(out, rc = -EALREADY); -- } -- -- CDEBUG(D_INFO, "Marking OBD %p %sactive\n", obd, activate ? "" : "in"); -- -- lov->tgts[i].active = activate; - if (activate) - if (activate) { - /* - * foreach(export) - * foreach(open_file) - * if (file_handle uses this_osc) - * if (has_no_filehandle) - * open(file_handle, this_osc); - */ - /* XXX reconnect? */ -- lov->desc.ld_active_tgt_count++; - else - } else { - /* - * Should I invalidate filehandles that refer to this OSC, so - * that I reopen them during reactivation? - */ - /* XXX disconnect from OSC? */ -- lov->desc.ld_active_tgt_count--; - } -- -- EXIT; -- out: -- spin_unlock(&lov->lov_lock); -- return rc; --} -- --static int lov_setup(struct obd_device *obd, obd_count len, void *buf) --{ - struct obd_ioctl_data* data = buf; - struct obd_ioctl_data *data = buf; -- struct lov_obd *lov = &obd->u.lov; -- int rc = 0; -- ENTRY; -- -- if (data->ioc_inllen1 < 1) { - CERROR("osc setup requires an MDC UUID\n"); - CERROR("LOV setup requires an MDC UUID\n"); -- RETURN(-EINVAL); -- } -- -- if (data->ioc_inllen1 > 37) { -- CERROR("mdc UUID must be 36 characters or less\n"); -- RETURN(-EINVAL); -- } -- -- spin_lock_init(&lov->lov_lock); -- lov->mdcobd = class_uuid2obd(data->ioc_inlbuf1); -- if (!lov->mdcobd) { -- CERROR("LOV %s cannot locate MDC %s\n", obd->obd_uuid, -- data->ioc_inlbuf1); -- rc = -EINVAL; -- } -- RETURN(rc); --} -- --static struct lov_file_handles *lov_handle2lfh(struct lustre_handle *handle) --{ -- struct lov_file_handles *lfh = NULL; -- -- if (!handle || !handle->addr) -- RETURN(NULL); -- -- lfh = (struct lov_file_handles *)(unsigned long)(handle->addr); -- if (!kmem_cache_validate(lov_file_cache, lfh)) -- RETURN(NULL); -- -- if (lfh->lfh_cookie != handle->cookie) -- RETURN(NULL); -- -- return lfh; --} -- --/* the LOV expects oa->o_id to be set to the LOV object id */ --static int lov_create(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md **ea) --{ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_stripe_md *lsm; -- struct lov_oinfo *loi; -- struct obdo *tmp; - int ost_count, ost_idx = 1, i, rc = 0; - int ost_count, ost_idx = 1; - int rc = 0, i; -- ENTRY; -- -- LASSERT(ea); -- -- if (!export) -- RETURN(-EINVAL); -- -- tmp = obdo_alloc(); -- if (!tmp) -- RETURN(-ENOMEM); -- -- lov = &export->exp_obd->u.lov; - - if (!lov->desc.ld_active_tgt_count) - RETURN(-EIO); -- -- spin_lock(&lov->lov_lock); -- ost_count = lov->desc.ld_tgt_count; - oa->o_easize = lov_stripe_md_size(ost_count); -- -- lsm = *ea; - if (!lsm) { - OBD_ALLOC(lsm, oa->o_easize); - if (!lsm) { - - /* Can't create more stripes than we have targets (incl inactive). */ - if (lsm && lsm->lsm_stripe_count > lov->desc.ld_tgt_count) - GOTO(out_tmp, rc = -EINVAL); - - /* Free the user lsm if it needs to be changed, to avoid memory leaks */ - if (!lsm || (lsm && - lsm->lsm_stripe_count > lov->desc.ld_active_tgt_count)) { - struct lov_stripe_md *lsm_new = NULL; - rc = obd_alloc_memmd(conn, &lsm_new); - if (rc < 0) { -- spin_unlock(&lov->lov_lock); - GOTO(out_tmp, rc = -ENOMEM); - if (lsm) - obd_free_memmd(conn, &lsm); - GOTO(out_tmp, rc); -- } - lsm->lsm_magic = LOV_MAGIC; - lsm->lsm_mds_easize = lov_mds_md_size(ost_count); - if (lsm) { - LASSERT(lsm->lsm_magic == LOV_MAGIC); - CERROR("replace user LOV MD: stripes %u > %u active\n", - lsm->lsm_stripe_count, - lov->desc.ld_active_tgt_count); - lsm_new->lsm_stripe_offset = lsm->lsm_stripe_offset; - lsm_new->lsm_stripe_size = lsm->lsm_stripe_size; - lsm_new->lsm_stripe_pattern = lsm->lsm_stripe_pattern; - obd_free_memmd(conn, &lsm); - } - lsm = lsm_new; -- ost_idx = 0; /* if lsm->lsm_stripe_offset is set yet */ - lsm->lsm_magic = LOV_MAGIC; -- } -- -- LASSERT(oa->o_valid & OBD_MD_FLID); -- lsm->lsm_object_id = oa->o_id; - if (!lsm->lsm_stripe_count) - lsm->lsm_stripe_count = lov->desc.ld_default_stripe_count; - if (!lsm->lsm_stripe_count) - lsm->lsm_stripe_count = lov->desc.ld_active_tgt_count; - else if (lsm->lsm_stripe_count > lov->desc.ld_active_tgt_count) - lsm->lsm_stripe_count = lov->desc.ld_active_tgt_count; - -- if (!lsm->lsm_stripe_size) -- lsm->lsm_stripe_size = lov->desc.ld_default_stripe_size; -- -- /* Because of 64-bit divide/mod operations only work with a 32-bit -- * divisor in a 32-bit kernel, we cannot support a stripe width -- * of 4GB or larger on 32-bit CPUs. -- */ -- if (lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL) { -- CERROR("LOV: stripe width "LPU64"x%u > %lu on 32-bit system\n", -- lsm->lsm_stripe_size, lsm->lsm_stripe_count, ~0UL); -- spin_unlock(&lov->lov_lock); -- GOTO(out_free, rc = -EINVAL); -- } -- - lsm->lsm_ost_count = ost_count; -- if (!ost_idx || lsm->lsm_stripe_offset >= ost_count) { -- int mult = lsm->lsm_object_id * lsm->lsm_stripe_count; -- int stripe_offset = mult % ost_count; -- int sub_offset = (mult / ost_count) % lsm->lsm_stripe_count; -- -- lsm->lsm_stripe_offset = stripe_offset + sub_offset; -- } -- - /* Start with lsm_stripe_offset on an active OSC to avoid confusion */ -- while (!lov->tgts[lsm->lsm_stripe_offset].active) -- lsm->lsm_stripe_offset = (lsm->lsm_stripe_offset+1) % ost_count; -- -- /* Pick the OSTs before we release the lock */ -- ost_idx = lsm->lsm_stripe_offset; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- CDEBUG(D_INODE, "objid "LPX64"[%d] is ost_idx %d (uuid %s)\n", -- lsm->lsm_object_id, i, ost_idx, lov->tgts[ost_idx].uuid); -- loi->loi_ost_idx = ost_idx; -- do { -- ost_idx = (ost_idx + 1) % ost_count; -- } while (!lov->tgts[ost_idx].active); -- } -- -- spin_unlock(&lov->lov_lock); -- -- CDEBUG(D_INODE, "allocating %d subobjs for objid "LPX64" at idx %d\n", -- lsm->lsm_stripe_count,lsm->lsm_object_id,lsm->lsm_stripe_offset); -- -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- struct lov_stripe_md obj_md; -- struct lov_stripe_md *obj_mdp = &obj_md; -- -- ost_idx = loi->loi_ost_idx; -- -- /* create data objects with "parent" OA */ -- memcpy(tmp, oa, sizeof(*tmp)); - tmp->o_easize = sizeof(struct lov_stripe_md); - /* XXX: LOV STACKING: use real "obj_mdp" sub-data */ -- rc = obd_create(&lov->tgts[ost_idx].conn, tmp, &obj_mdp); -- if (rc) { -- CERROR("error creating objid "LPX64" sub-object on " -- "OST idx %d: rc = %d\n", oa->o_id, ost_idx, rc); -- GOTO(out_cleanup, rc); -- } -- loi->loi_id = tmp->o_id; - loi->loi_size = tmp->o_size; -- CDEBUG(D_INODE, "objid "LPX64" has subobj "LPX64" at idx %d\n", -- lsm->lsm_object_id, loi->loi_id, ost_idx); -- } -- -- *ea = lsm; -- -- out_tmp: -- obdo_free(tmp); - return rc; - RETURN(rc); -- -- out_cleanup: -- while (i-- > 0) { -- int err; -- -- --loi; -- /* destroy already created objects here */ -- memcpy(tmp, oa, sizeof(*tmp)); -- tmp->o_id = loi->loi_id; -- err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); -- if (err) -- CERROR("Failed to uncreate objid "LPX64" subobj " -- LPX64" on OST idx %d: rc = %d\n", -- oa->o_id, loi->loi_id, loi->loi_ost_idx, -- err); -- } -- out_free: - OBD_FREE(lsm, oa->o_easize); - if (!*ea) - obd_free_memmd(conn, &lsm); -- goto out_tmp; --} -- --static int lov_destroy(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm) --{ -- struct obdo tmp; -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea for destruction\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- if (oa->o_valid & OBD_MD_FLHANDLE) -- lfh = lov_handle2lfh(obdo_handle(oa)); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - if (lov->tgts[loi->loi_ost_idx].active == 0) { - /* Orphan clean up will (someday) fix this up. */ - continue; - } - -- memcpy(&tmp, oa, sizeof(tmp)); -- tmp.o_id = loi->loi_id; -- if (lfh) -- memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], -- sizeof(lfh->lfh_handles[i])); -- else -- tmp.o_valid &= ~OBD_MD_FLHANDLE; - rc = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL); - if (rc) - CERROR("Error destroying objid "LPX64" subobj "LPX64 - " on OST idx %d\n: rc = %d", - oa->o_id, loi->loi_id, loi->loi_ost_idx, rc); - err = obd_destroy(&lov->tgts[loi->loi_ost_idx].conn, &tmp, - NULL); - if (err && lov->tgts[loi->loi_ost_idx].active) { - CERROR("Error destroying objid "LPX64" subobj " - LPX64" on OST idx %d\n: rc = %d", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } -- } -- RETURN(rc); --} -- --/* compute object size given "stripeno" and the ost size */ --static obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size, -- int stripeno) --{ -- unsigned long ssize = lsm->lsm_stripe_size; -- unsigned long swidth = ssize * lsm->lsm_stripe_count; -- unsigned long stripe_size; -- obd_size lov_size; -- -- if (ost_size == 0) -- return 0; -- -- /* do_div(a, b) returns a % b, and a = a / b */ -- stripe_size = do_div(ost_size, ssize); -- -- if (stripe_size) -- lov_size = ost_size * swidth + stripeno * ssize + stripe_size; -- else -- lov_size = (ost_size - 1) * swidth + (stripeno + 1) * ssize; -- -- return lov_size; --} -- --static void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_flag valid, -- struct lov_stripe_md *lsm, int stripeno, int *new) --{ -- if (*new) { -- obdo_cpy_md(tgt, src, valid); -- if (valid & OBD_MD_FLSIZE) -- tgt->o_size = lov_stripe_size(lsm,src->o_size,stripeno); -- *new = 0; -- } else { -- if (valid & OBD_MD_FLSIZE) { -- /* this handles sparse files properly */ -- obd_size lov_size; -- -- lov_size = lov_stripe_size(lsm, src->o_size, stripeno); -- if (lov_size > tgt->o_size) -- tgt->o_size = lov_size; -- } -- if (valid & OBD_MD_FLBLOCKS) -- tgt->o_blocks += src->o_blocks; -- if (valid & OBD_MD_FLCTIME && tgt->o_ctime < src->o_ctime) -- tgt->o_ctime = src->o_ctime; -- if (valid & OBD_MD_FLMTIME && tgt->o_mtime < src->o_mtime) -- tgt->o_mtime = src->o_mtime; -- } --} -- --static int lov_getattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm) --{ -- struct obdo tmp; -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; - int rc = 0, i; - int i; -- int new = 1; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- lov = &export->exp_obd->u.lov; -- -- if (oa->o_valid & OBD_MD_FLHANDLE) -- lfh = lov_handle2lfh(obdo_handle(oa)); -- -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- int err; -- -- if (loi->loi_id == 0) - continue; - - if (lov->tgts[loi->loi_ost_idx].active == 0) -- continue; -- -- CDEBUG(D_INFO, "objid "LPX64"[%d] has subobj "LPX64" at idx " -- "%u\n", oa->o_id, i, loi->loi_id, loi->loi_ost_idx); -- /* create data objects with "parent" OA */ -- memcpy(&tmp, oa, sizeof(tmp)); -- tmp.o_id = loi->loi_id; -- if (lfh) -- memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], -- sizeof(lfh->lfh_handles[i])); -- else -- tmp.o_valid &= ~OBD_MD_FLHANDLE; -- -- err = obd_getattr(&lov->tgts[loi->loi_ost_idx].conn, &tmp,NULL); - if (err) { - if (err && lov->tgts[loi->loi_ost_idx].active) { -- CERROR("Error getattr objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", -- oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - continue; /* XXX or break? */ - RETURN(err); -- } -- lov_merge_attrs(oa, &tmp, tmp.o_valid, lsm, i, &new); -- } - RETURN(rc); - - RETURN(0); --} -- --static int lov_setattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm) --{ -- struct obdo *tmp; -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; -- int rc = 0, i; -- ENTRY; -- -- /* Note that this code is currently unused, hence LBUG(), just -- * to know when/if it is ever revived that it needs cleanups. -- */ -- LBUG(); -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- /* size changes should go through punch and not setattr */ -- LASSERT(!(oa->o_valid & OBD_MD_FLSIZE)); -- -- tmp = obdo_alloc(); -- if (!tmp) -- RETURN(-ENOMEM); -- -- if (oa->o_valid & OBD_MD_FLHANDLE) -- lfh = lov_handle2lfh(obdo_handle(oa)); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- int err; -- -- obdo_cpy_md(tmp, oa, oa->o_valid); -- -- if (lfh) -- memcpy(obdo_handle(tmp), &lfh->lfh_handles[i], -- sizeof(lfh->lfh_handles[i])); -- else -- tmp->o_valid &= ~OBD_MD_FLHANDLE; -- -- tmp->o_id = loi->loi_id; -- -- err = obd_setattr(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); -- if (err) { -- CERROR("Error setattr objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", -- oa->o_id, loi->loi_id, loi->loi_ost_idx, err); -- if (!rc) -- rc = err; -- } -- } -- obdo_free(tmp); -- RETURN(rc); --} -- --static int lov_open(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm) --{ - struct obdo *tmp; - struct obdo *tmp; /* on the heap here, on the stack in lov_close? */ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; - struct lustre_handle *handle; -- int new = 1; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea for opening\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- tmp = obdo_alloc(); -- if (!tmp) -- RETURN(-ENOMEM); -- -- lfh = kmem_cache_alloc(lov_file_cache, GFP_KERNEL); -- if (!lfh) -- GOTO(out_tmp, rc = -ENOMEM); -- OBD_ALLOC(lfh->lfh_handles, -- lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); -- if (!lfh->lfh_handles) -- GOTO(out_lfh, rc = -ENOMEM); -- -- lov = &export->exp_obd->u.lov; -- oa->o_size = 0; -- oa->o_blocks = 0; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) { - continue; - } -- -- /* create data objects with "parent" OA */ -- memcpy(tmp, oa, sizeof(*tmp)); -- tmp->o_id = loi->loi_id; -- - err = obd_open(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (err) { - rc = obd_open(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (rc && lov->tgts[loi->loi_ost_idx].active) { -- CERROR("Error open objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", -- oa->o_id, lsm->lsm_oinfo[i].loi_id, -- loi->loi_ost_idx, rc); - if (!rc) - rc = err; - goto out_handles; -- } -- -- lov_merge_attrs(oa, tmp, tmp->o_valid, lsm, i, &new); -- -- if (tmp->o_valid & OBD_MD_FLHANDLE) -- memcpy(&lfh->lfh_handles[i], obdo_handle(tmp), -- sizeof(lfh->lfh_handles[i])); -- } - - if (tmp->o_valid & OBD_MD_FLHANDLE) { - struct lustre_handle *handle = obdo_handle(oa); - - lfh->lfh_count = lsm->lsm_stripe_count; - get_random_bytes(&lfh->lfh_cookie, sizeof(lfh->lfh_cookie)); -- - handle->addr = (__u64)(unsigned long)lfh; - handle->cookie = lfh->lfh_cookie; - oa->o_valid |= OBD_MD_FLHANDLE; - list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head); - } else - goto out_handles; - handle = obdo_handle(oa); - - lfh->lfh_count = lsm->lsm_stripe_count; - get_random_bytes(&lfh->lfh_cookie, sizeof(lfh->lfh_cookie)); - - handle->addr = (__u64)(unsigned long)lfh; - handle->cookie = lfh->lfh_cookie; - oa->o_valid |= OBD_MD_FLHANDLE; - list_add(&lfh->lfh_list, &export->exp_lov_data.led_open_head); -- - /* FIXME: returning an error, but having opened some objects is a bad - * idea, since they will likely never be closed. We either - * need to not return an error if _some_ objects could be - * opened, and leave it to read/write to return -EIO (with - * hopefully partial error status) or close all opened objects - * and return an error. I think the former is preferred. - */ --out_tmp: -- obdo_free(tmp); -- RETURN(rc); -- --out_handles: - for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - memcpy(tmp, oa, sizeof(*tmp)); - tmp->o_id = loi->loi_id; - memcpy(obdo_handle(tmp), &lfh->lfh_handles[i], - sizeof(lfh->lfh_handles[i])); - - err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, tmp, NULL); - if (err) { - CERROR("Error closing objid "LPX64" subobj "LPX64 - " on OST idx %d after open error: rc = %d\n", - oa->o_id, loi->loi_id, loi->loi_ost_idx, err); - } - } - -- OBD_FREE(lfh->lfh_handles, -- lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); --out_lfh: -- lfh->lfh_cookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(lov_file_cache, lfh); -- goto out_tmp; --} -- --static int lov_close(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm) --{ -- struct obdo tmp; -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- if (oa->o_valid & OBD_MD_FLHANDLE) -- lfh = lov_handle2lfh(obdo_handle(oa)); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; -- -- /* create data objects with "parent" OA */ -- memcpy(&tmp, oa, sizeof(tmp)); -- tmp.o_id = loi->loi_id; -- if (lfh) -- memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], -- sizeof(lfh->lfh_handles[i])); -- else -- tmp.o_valid &= ~OBD_MD_FLHANDLE; -- -- err = obd_close(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL); -- if (err) { -- CERROR("Error close objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", -- oa->o_id, loi->loi_id, loi->loi_ost_idx, err); -- if (!rc) -- rc = err; -- } -- } -- if (lfh) { -- list_del(&lfh->lfh_list); -- OBD_FREE(lfh->lfh_handles, -- lsm->lsm_stripe_count * sizeof(*lfh->lfh_handles)); -- lfh->lfh_cookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(lov_file_cache, lfh); -- } -- -- RETURN(rc); --} -- --#ifndef log2 --#define log2(n) ffz(~(n)) --#endif -- --#warning FIXME: merge these two functions now that they are nearly the same -- --/* compute ost offset in stripe "stripeno" corresponding to offset "lov_off" */ --static obd_off lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, -- int stripeno) --{ -- unsigned long ssize = lsm->lsm_stripe_size; -- unsigned long swidth = ssize * lsm->lsm_stripe_count; -- unsigned long stripe_off, this_stripe; -- -- if (lov_off == OBD_OBJECT_EOF || lov_off == 0) -- return lov_off; -- -- /* do_div(a, b) returns a % b, and a = a / b */ -- stripe_off = do_div(lov_off, swidth); -- -- this_stripe = stripeno * ssize; -- if (stripe_off <= this_stripe) -- stripe_off = 0; -- else { -- stripe_off -= this_stripe; -- -- if (stripe_off > ssize) -- stripe_off = ssize; -- } -- -- -- return lov_off * ssize + stripe_off; --} -- --/* compute which stripe number "lov_off" will be written into */ --static int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off) --{ -- unsigned long ssize = lsm->lsm_stripe_size; -- unsigned long swidth = ssize * lsm->lsm_stripe_count; -- unsigned long stripe_off; -- -- stripe_off = do_div(lov_off, swidth); -- -- return stripe_off / ssize; --} -- -- --/* FIXME: maybe we'll just make one node the authoritative attribute node, then -- * we can send this 'punch' to just the authoritative node and the nodes -- * that the punch will affect. */ --static int lov_punch(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm, -- obd_off start, obd_off end) --{ -- struct obdo tmp; -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- struct lov_file_handles *lfh = NULL; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- if (oa->o_valid & OBD_MD_FLHANDLE) -- lfh = lov_handle2lfh(obdo_handle(oa)); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- obd_off starti = lov_stripe_offset(lsm, start, i); -- obd_off endi = lov_stripe_offset(lsm, end, i); -- int err; -- -- if (starti == endi) -- continue; -- /* create data objects with "parent" OA */ -- memcpy(&tmp, oa, sizeof(tmp)); -- tmp.o_id = loi->loi_id; -- if (lfh) -- memcpy(obdo_handle(&tmp), &lfh->lfh_handles[i], -- sizeof(lfh->lfh_handles[i])); -- else -- tmp.o_valid &= ~OBD_MD_FLHANDLE; -- -- err = obd_punch(&lov->tgts[loi->loi_ost_idx].conn, &tmp, NULL, -- starti, endi); -- if (err) { -- CERROR("Error punch objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", -- oa->o_id, loi->loi_id, loi->loi_ost_idx, err); -- if (!rc) -- rc = err; -- } -- } -- RETURN(rc); - } - - static int lov_osc_brw_cb(struct brw_cb_data *brw_cbd, int err, int phase) - { - int ret = 0; - ENTRY; - - if (phase == CB_PHASE_START) - RETURN(0); - - if (phase == CB_PHASE_FINISH) { - if (err) - brw_cbd->brw_err = err; - if (atomic_dec_and_test(&brw_cbd->brw_refcount)) - ret = brw_cbd->brw_cb(brw_cbd->brw_data, brw_cbd->brw_err, phase); - RETURN(ret); - } - - LBUG(); - return 0; --} -- --static inline int lov_brw(int cmd, struct lustre_handle *conn, -- struct lov_stripe_md *lsm, obd_count oa_bufs, - struct brw_page *pga, - brw_cb_t brw_cb, struct brw_cb_data *brw_cbd) - struct brw_page *pga, struct obd_brw_set *set) --{ - int stripe_count = lsm->lsm_stripe_count; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; -- struct { -- int bufct; -- int index; -- int subcount; -- struct lov_stripe_md lsm; -- int ost_idx; -- } *stripeinfo, *si, *si_last; - struct obd_export *export = class_conn2export(conn); - struct lov_obd *lov; -- struct brw_page *ioarr; - int rc, i; - struct brw_cb_data *osc_brw_cbd; -- struct lov_oinfo *loi; - int *where; - int rc = 0, i, *where, stripe_count = lsm->lsm_stripe_count; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- lov = &export->exp_obd->u.lov; - - osc_brw_cbd = ll_init_brw_cb_data(); - if (!osc_brw_cbd) - RETURN(-ENOMEM); -- -- OBD_ALLOC(stripeinfo, stripe_count * sizeof(*stripeinfo)); -- if (!stripeinfo) -- GOTO(out_cbdata, rc = -ENOMEM); -- -- OBD_ALLOC(where, sizeof(*where) * oa_bufs); -- if (!where) -- GOTO(out_sinfo, rc = -ENOMEM); -- -- OBD_ALLOC(ioarr, sizeof(*ioarr) * oa_bufs); -- if (!ioarr) -- GOTO(out_where, rc = -ENOMEM); - - /* This is the only race-free way I can think of to get the refcount - * correct. -phil */ - atomic_set(&osc_brw_cbd->brw_refcount, 0); - osc_brw_cbd->brw_cb = brw_cb; - osc_brw_cbd->brw_data = brw_cbd; -- -- for (i = 0; i < oa_bufs; i++) { -- where[i] = lov_stripe_number(lsm, pga[i].off); - if (stripeinfo[where[i]].bufct++ == 0) - atomic_inc(&osc_brw_cbd->brw_refcount); - stripeinfo[where[i]].bufct++; -- } -- -- for (i = 0, loi = lsm->lsm_oinfo, si_last = si = stripeinfo; -- i < stripe_count; i++, loi++, si_last = si, si++) { - if (lov->tgts[loi->loi_ost_idx].active == 0) - GOTO(out_ioarr, rc = -EIO); -- if (i > 0) -- si->index = si_last->index + si_last->bufct; -- si->lsm.lsm_object_id = loi->loi_id; -- si->ost_idx = loi->loi_ost_idx; -- } -- -- for (i = 0; i < oa_bufs; i++) { -- int which = where[i]; -- int shift; -- -- shift = stripeinfo[which].index + stripeinfo[which].subcount; -- LASSERT(shift < oa_bufs); -- ioarr[shift] = pga[i]; -- ioarr[shift].off = lov_stripe_offset(lsm, pga[i].off, which); -- stripeinfo[which].subcount++; -- } -- -- for (i = 0, si = stripeinfo; i < stripe_count; i++, si++) { -- int shift = si->index; -- -- if (si->bufct) { -- LASSERT(shift < oa_bufs); - /* XXX handle error returns here */ - obd_brw(cmd, &lov->tgts[si->ost_idx].conn, - &si->lsm, si->bufct, &ioarr[shift], - lov_osc_brw_cb, osc_brw_cbd); - rc = obd_brw(cmd, &lov->tgts[si->ost_idx].conn, - &si->lsm, si->bufct, &ioarr[shift], set); - if (rc) - GOTO(out_ioarr, rc); -- } -- } - - rc = brw_cb(brw_cbd, 0, CB_PHASE_START); -- - out_ioarr: -- OBD_FREE(ioarr, sizeof(*ioarr) * oa_bufs); -- out_where: -- OBD_FREE(where, sizeof(*where) * oa_bufs); -- out_sinfo: -- OBD_FREE(stripeinfo, stripe_count * sizeof(*stripeinfo)); -- out_cbdata: - OBD_FREE(osc_brw_cbd, sizeof(*osc_brw_cbd)); -- RETURN(rc); --} -- --static int lov_enqueue(struct lustre_handle *conn, struct lov_stripe_md *lsm, -- struct lustre_handle *parent_lock, -- __u32 type, void *cookie, int cookielen, __u32 mode, -- int *flags, void *cb, void *data, int datalen, -- struct lustre_handle *lockhs) --{ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; - struct lov_stripe_md submd; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } - - /* we should never be asked to replay a lock. */ - - LASSERT((*flags & LDLM_FL_REPLAY) == 0); -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); - - memset(lockhs, 0, sizeof(*lockhs) * lsm->lsm_stripe_count); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- struct ldlm_extent *extent = (struct ldlm_extent *)cookie; -- struct ldlm_extent sub_ext; - struct lov_stripe_md submd; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; -- - *flags = 0; -- sub_ext.start = lov_stripe_offset(lsm, extent->start, i); -- sub_ext.end = lov_stripe_offset(lsm, extent->end, i); -- if (sub_ext.start == sub_ext.end) -- continue; -- -- submd.lsm_object_id = loi->loi_id; - /* XXX submd lsm_mds_easize should be that from the subobj, - * and the subobj should get it opaquely from the LOV. - /* XXX submd should be that from the subobj, it should come - * opaquely from the LOV. -- */ - submd.lsm_mds_easize = lov_mds_md_size(lsm->lsm_ost_count); -- submd.lsm_stripe_count = 0; -- /* XXX submd is not fully initialized here */ - *flags = 0; -- rc = obd_enqueue(&(lov->tgts[loi->loi_ost_idx].conn), &submd, -- parent_lock, type, &sub_ext, sizeof(sub_ext), -- mode, flags, cb, data, datalen, &(lockhs[i])); -- // XXX add a lock debug statement here - if (rc) { - if (rc && lov->tgts[loi->loi_ost_idx].active) { -- CERROR("Error enqueue objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", lsm->lsm_object_id, -- loi->loi_id, loi->loi_ost_idx, rc); - memset(&(lockhs[i]), 0, sizeof(lockhs[i])); - goto out_locks; - } - } - - RETURN(0); - - out_locks: - for (i--, loi = &lsm->lsm_oinfo[i]; i >= 0; i--, loi--) { - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; - - submd.lsm_object_id = loi->loi_id; - submd.lsm_stripe_count = 0; - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - mode, &lockhs[i]); - if (err) { - CERROR("Error cancelling objid "LPX64" subobj "LPX64 - " on OST idx %d after enqueue error: rc = %d\n", - loi->loi_id, loi->loi_ost_idx, err); -- } -- } -- RETURN(rc); --} -- --static int lov_cancel(struct lustre_handle *conn, struct lov_stripe_md *lsm, -- __u32 mode, struct lustre_handle *lockhs) --{ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; -- int rc = 0, i; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea\n"); -- RETURN(-EINVAL); -- } -- -- if (lsm->lsm_magic != LOV_MAGIC) { -- CERROR("LOV striping magic bad %#lx != %#lx\n", -- lsm->lsm_magic, LOV_MAGIC); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- struct lov_stripe_md submd; - int err; - - if (lov->tgts[loi->loi_ost_idx].active == 0) - continue; -- -- if (lockhs[i].addr == 0) -- continue; -- -- submd.lsm_object_id = loi->loi_id; - submd.lsm_mds_easize = lov_mds_md_size(lsm->lsm_ost_count); -- submd.lsm_stripe_count = 0; - rc = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, - err = obd_cancel(&lov->tgts[loi->loi_ost_idx].conn, &submd, -- mode, &lockhs[i]); - if (rc) - if (err && lov->tgts[loi->loi_ost_idx].active) { -- CERROR("Error cancel objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", lsm->lsm_object_id, - loi->loi_id, loi->loi_ost_idx, rc); - loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } -- } -- RETURN(rc); --} -- --static int lov_cancel_unused(struct lustre_handle *conn, -- struct lov_stripe_md *lsm, int flags) --{ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct lov_oinfo *loi; - int rc = 0, i; - int rc = 0, i, err; -- ENTRY; -- -- if (!lsm) { -- CERROR("LOV requires striping ea for lock cancellation\n"); -- RETURN(-EINVAL); -- } -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- lov = &export->exp_obd->u.lov; -- for (i = 0,loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++,loi++) { -- struct lov_stripe_md submd; -- -- submd.lsm_object_id = loi->loi_id; - submd.lsm_mds_easize = lov_mds_md_size(lsm->lsm_ost_count); -- submd.lsm_stripe_count = 0; - rc = obd_cancel_unused(&lov->tgts[loi->loi_ost_idx].conn, - err = obd_cancel_unused(&lov->tgts[loi->loi_ost_idx].conn, -- &submd, flags); - if (rc) - if (err && lov->tgts[loi->loi_ost_idx].active) { -- CERROR("Error cancel unused objid "LPX64" subobj "LPX64 -- " on OST idx %d: rc = %d\n", lsm->lsm_object_id, - loi->loi_id, loi->loi_ost_idx, rc); - loi->loi_id, loi->loi_ost_idx, err); - if (!rc) - rc = err; - } -- } - -- RETURN(rc); --} -- --static int lov_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) --{ -- struct obd_export *export = class_conn2export(conn); -- struct lov_obd *lov; -- struct obd_statfs lov_sfs; -- int set = 0; -- int rc = 0; -- int i; -- ENTRY; -- -- if (!export || !export->exp_obd) -- RETURN(-ENODEV); -- -- lov = &export->exp_obd->u.lov; -- -- /* We only get block data from the OBD */ -- for (i = 0; i < lov->desc.ld_tgt_count; i++) { -- int err; -- -- if (!lov->tgts[i].active) -- continue; -- -- err = obd_statfs(&lov->tgts[i].conn, &lov_sfs); -- if (err) { -- CERROR("Error statfs OSC %s idx %d: err = %d\n", -- lov->tgts[i].uuid, i, err); -- if (!rc) -- rc = err; -- continue; /* XXX or break? - probably OK to continue */ -- } -- if (!set) { -- memcpy(osfs, &lov_sfs, sizeof(lov_sfs)); -- set = 1; -- } else { -- osfs->os_bfree += lov_sfs.os_bfree; -- osfs->os_bavail += lov_sfs.os_bavail; -- osfs->os_blocks += lov_sfs.os_blocks; -- /* XXX not sure about this one - depends on policy. -- * - could be minimum if we always stripe on all OBDs -- * (but that would be wrong for any other policy, -- * if one of the OBDs has no more objects left) -- * - could be sum if we stripe whole objects -- * - could be average, just to give a nice number -- * - we just pick first OST and hope it is enough -- sfs->f_ffree += lov_sfs.f_ffree; -- */ -- } -- } -- RETURN(rc); --} -- - static int lov_iocontrol(long cmd, struct lustre_handle *conn, int len, -static int lov_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, -- void *karg, void *uarg) --{ -- struct obd_device *obddev = class_conn2obd(conn); - struct obd_ioctl_data *data = karg; -- struct lov_obd *lov = &obddev->u.lov; - struct lov_desc *desc; - struct lov_tgt_desc *tgtdesc; - obd_uuid_t *uuidp; - char *buf; - int rc, i, count; - struct obd_ioctl_data *data = karg; - int i, count = lov->desc.ld_tgt_count; - int rc; - -- ENTRY; -- -- switch (cmd) { - case IOC_LOV_SET_OSC_ACTIVE: - case IOC_LOV_SET_OSC_ACTIVE: { -- rc = lov_set_osc_active(lov,data->ioc_inlbuf1,data->ioc_offset); -- break; - case OBD_IOC_LOV_GET_CONFIG: - } - case OBD_IOC_LOV_GET_CONFIG: { - struct lov_tgt_desc *tgtdesc; - struct lov_desc *desc; - obd_uuid_t *uuidp; - char *buf = NULL; - -- buf = NULL; -- len = 0; -- if (obd_ioctl_getdata(&buf, &len, (void *)uarg)) -- RETURN(-EINVAL); -- -- data = (struct obd_ioctl_data *)buf; -- -- if (sizeof(*desc) > data->ioc_inllen1) { -- OBD_FREE(buf, len); -- RETURN(-EINVAL); -- } - - count = lov->desc.ld_tgt_count; -- -- if (sizeof(*uuidp) * count > data->ioc_inllen2) { -- OBD_FREE(buf, len); -- RETURN(-EINVAL); -- } -- -- desc = (struct lov_desc *)data->ioc_inlbuf1; -- uuidp = (obd_uuid_t *)data->ioc_inlbuf2; -- memcpy(desc, &(lov->desc), sizeof(*desc)); -- -- tgtdesc = lov->tgts; -- for (i = 0; i < count; i++, uuidp++, tgtdesc++) -- memcpy(uuidp, tgtdesc->uuid, sizeof(*uuidp)); -- -- rc = copy_to_user((void *)uarg, buf, len); - if (rc) - rc = -EFAULT; -- OBD_FREE(buf, len); -- break; - } -- default: - if (lov->desc.ld_tgt_count == 0) - if (count == 0) -- RETURN(-ENOTTY); -- rc = 0; - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - for (i = 0; i < count; i++) { -- int err = obd_iocontrol(cmd, &lov->tgts[i].conn, - len, data, NULL); - len, karg, uarg); -- if (err && !rc) -- rc = err; -- } -- } -- -- RETURN(rc); - } - - int lov_attach(struct obd_device *dev, obd_count len, void *data) - { - return lprocfs_reg_obd(dev, status_var_nm_1, dev); - } - - int lov_detach(struct obd_device *dev) - { - return lprocfs_dereg_obd(dev); --} -- --struct obd_ops lov_obd_ops = { -- o_attach: lov_attach, -- o_detach: lov_detach, -- o_setup: lov_setup, -- o_connect: lov_connect, -- o_disconnect: lov_disconnect, - o_statfs: lov_statfs, - o_packmd: lov_packmd, - o_unpackmd: lov_unpackmd, -- o_create: lov_create, -- o_destroy: lov_destroy, -- o_getattr: lov_getattr, -- o_setattr: lov_setattr, - o_statfs: lov_statfs, -- o_open: lov_open, -- o_close: lov_close, -- o_brw: lov_brw, -- o_punch: lov_punch, -- o_enqueue: lov_enqueue, -- o_cancel: lov_cancel, -- o_cancel_unused: lov_cancel_unused, -- o_iocontrol: lov_iocontrol --}; -- -- --#define LOV_VERSION "v0.1" -- --static int __init lov_init(void) --{ -- int rc; -- printk(KERN_INFO "Lustre Logical Object Volume driver " LOV_VERSION -- ", info@clusterfs.com\n"); -- lov_file_cache = kmem_cache_create("ll_lov_file_data", -- sizeof(struct lov_file_handles), -- 0, 0, NULL, NULL); -- if (!lov_file_cache) -- RETURN(-ENOMEM); - -- rc = class_register_type(&lov_obd_ops, status_class_var, -- OBD_LOV_DEVICENAME); -- RETURN(rc); --} -- --static void __exit lov_exit(void) --{ -- if (kmem_cache_destroy(lov_file_cache)) -- CERROR("couldn't free LOV open cache\n"); -- class_unregister_type(OBD_LOV_DEVICENAME); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver " LOV_VERSION); --MODULE_LICENSE("GPL"); -- --module_init(lov_init); --module_exit(lov_exit); diff --cc lustre/lov/lproc_lov.c index 4845f41,a68b57e..0000000 deleted file mode 100644,100644 --- a/lustre/lov/lproc_lov.c +++ /dev/null @@@ -1,204 -1,204 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- --/* -- * Common STATUS namespace -- */ -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_uuid); -- return len; -- -- --} --int rd_stripesize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- (__u64)(lov->desc.ld_default_stripe_size)); -- -- return len; --} -- --int rd_stripeoffset(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- lov->desc.ld_default_stripe_offset); -- return len; -- --} -- --int rd_stripetype(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- (__u64)(lov->desc.ld_pattern)); -- return len; -- --} --int rd_stripecount(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- (__u64)(lov->desc.ld_default_stripe_count)); -- return len; -- --} --int rd_numobd(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov=&dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- (__u64)(lov->desc.ld_tgt_count)); -- return len; -- --} -- --int rd_activeobd(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, LPU64"\n", -- (__u64)(lov->desc.ld_active_tgt_count)); -- return len; -- --} -- --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- -- --int rd_kbtotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- -- --int rd_kbfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_target(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0, i = 0; -- struct lov_obd* lov = &dev->u.lov; -- struct lov_tgt_desc* tgts = lov->tgts; -- while(i < lov->desc.ld_tgt_count){ - len += snprintf(page, count, "%d: %s\n", i, tgts->uuid); - len += snprintf(&page[len], count, "%d: %s\n", i, tgts->uuid); -- i++; -- tgts++; -- } -- -- return len; --} --int rd_mdc(char* page, char **start, off_t off, int count, int *eof, void *data) --{ -- struct obd_device* dev = (struct obd_device*)data; -- int len = 0; -- struct lov_obd* lov = &dev->u.lov; -- len += snprintf(page, count, "%s\n", lov->mdcobd->obd_uuid); -- return len; --} -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/stripesize",rd_stripesize, 0, 0}, -- {"status/stripeoffset",rd_stripeoffset, 0, 0}, -- {"status/stripecount",rd_stripecount, 0, 0}, -- {"status/stripetype", rd_stripetype, 0, 0}, -- {"status/numobd",rd_numobd, 0, 0}, -- {"status/activeobd", rd_activeobd, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {"status/blocksize", rd_blksize, 0, 0}, -- {"status/kbytestotal", rd_kbtotal, 0, 0}, -- {"status/kbytesfree", rd_kbfree, 0, 0}, -- {"status/target_obd", rd_target, 0, 0}, -- {"status/target_mdc", rd_mdc, 0, 0}, -- -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[]={ -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/mdc/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/mdc/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/mdc/Makefile.am index 26c0053,8dd9175..0000000 deleted file mode 100644,100644 --- a/lustre/mdc/Makefile.am +++ /dev/null @@@ -1,25 -1,22 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --MODULE = mdc --modulefs_DATA = mdc.o --EXTRA_PROGRAMS = mdc -- - LINX= mds_updates.c ll_pack.c lov_pack.c client.c -LINX= mds_updates.c ll_pack.c client.c --mdc_SOURCES = mdc_request.c mdc_reint.c lproc_mdc.c $(LINX) -- - lov_pack.c: - test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c . --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c . --mds_updates.c: -- test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c . --client.c: -- test -e client.c || ln -sf $(top_srcdir)/lib/client.c . - -- --include $(top_srcdir)/Rules diff --cc lustre/mdc/lproc_mdc.c index b0fcad6,b0fcad6..0000000 deleted file mode 100644,100644 --- a/lustre/mdc/lproc_mdc.c +++ /dev/null @@@ -1,128 -1,128 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- int len = 0; -- len += snprintf(page, count, "%s\n",temp->obd_uuid); -- return len; -- -- --} --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --int rd_kbtotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_kbfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- -- --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --int rd_conn_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct client_obd* cli = &temp->u.cli; -- struct obd_import* imp = &cli->cl_import; -- int len = 0; -- -- len += snprintf(page, count, "%s\n",imp->imp_connection->c_remote_uuid); -- return len; --} -- --int rd_server_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct client_obd* cli = &temp->u.cli; -- int len = 0; -- -- len += snprintf(page, count, "%s\n",cli->cl_target_uuid); -- return len; --} -- --int rd_server_name(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; -- --} -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytestotal",rd_kbtotal, 0, 0}, -- {"status/kbytesfree", rd_kbfree, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {"status/mds_server_uuid", rd_server_uuid, 0, 0}, -- {"status/mds_conn_uuid", rd_conn_uuid, 0, 0}, -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/mdc/mdc_reint.c index 51cacf7,63c1ef0..0000000 deleted file mode 100644,100644 --- a/lustre/mdc/mdc_reint.c +++ /dev/null @@@ -1,200 -1,197 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define EXPORT_SYMTAB -- --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_MDC -- --#include --#include - #include -- --static int mdc_reint(struct ptlrpc_request *request, int level) --{ -- int rc; -- request->rq_level = level; -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- -- if (rc) { -- CERROR("error in handling %d\n", rc); -- } else { -- /* For future resend/replays. */ -- u32 *opcodeptr = lustre_msg_buf(request->rq_reqmsg, 0); -- *opcodeptr |= REINT_REPLAYING; -- } -- return rc; --} -- --int mdc_setattr(struct lustre_handle *conn, -- struct inode *inode, struct iattr *iattr, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- struct mds_rec_setattr *rec; -- int rc, size = sizeof(*rec); -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 1, &size, -- NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- mds_setattr_pack(req, 0, inode, iattr, NULL, 0); -- -- size = sizeof(struct mds_body); -- req->rq_replen = lustre_msg_size(1, &size); -- -- rc = mdc_reint(req, LUSTRE_CONN_FULL); -- *request = req; -- if (rc == -ERESTARTSYS ) -- rc = 0; -- -- RETURN(rc); --} -- - int mdc_create(struct lustre_handle *conn, - struct inode *dir, const char *name, int namelen, - const char *tgt, int tgtlen, int mode, __u32 uid, - __u32 gid, __u64 time, __u64 rdev, struct lov_stripe_md *lsm, -int mdc_create(struct lustre_handle *conn, struct inode *dir, - const char *name, int namelen, const void *data, int datalen, - int mode, __u32 uid, __u32 gid, __u64 time, __u64 rdev, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- int rc, size[3] = {sizeof(struct mds_rec_create), namelen + 1, 0}; -- int level, bufcount = 2; -- ENTRY; -- - if (S_ISLNK(mode)) { - size[2] = tgtlen + 1; - bufcount = 3; - if (data && datalen) { - size[bufcount] = datalen; - bufcount++; -- } -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* mds_create_pack fills msg->bufs[1] with name - * and msg->bufs[2] with tgt, for symlinks */ - * and msg->bufs[2] with tgt, for symlinks or lov MD data */ -- mds_create_pack(req, 0, dir, mode, rdev, uid, gid, time, - name, namelen, tgt, tgtlen); - name, namelen, data, datalen); -- -- size[0] = sizeof(struct mds_body); -- req->rq_replen = lustre_msg_size(1, size); -- -- level = LUSTRE_CONN_FULL; -- resend: -- rc = mdc_reint(req, level); -- /* Resend if we were told to. */ -- if (rc == -ERESTARTSYS) { -- level = LUSTRE_CONN_RECOVD; -- req->rq_flags = 0; -- goto resend; -- } -- -- mdc_store_inode_generation(req, 0, 0); -- -- *request = req; -- RETURN(rc); --} -- --int mdc_unlink(struct lustre_handle *conn, struct inode *dir, -- struct inode *child, __u32 mode, const char *name, int namelen, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1}; -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- mds_unlink_pack(req, 0, dir, child, mode, name, namelen); -- -- size[0] = sizeof(struct mds_body); -- req->rq_replen = lustre_msg_size(1, size); -- -- rc = mdc_reint(req, LUSTRE_CONN_FULL); -- *request = req; -- if (rc == -ERESTARTSYS) -- rc = 0; -- -- RETURN(rc); --} -- --int mdc_link(struct lustre_handle *conn, -- struct dentry *src, struct inode *dir, const char *name, -- int namelen, struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- int rc, size[2] = {sizeof(struct mds_rec_link), namelen + 1}; -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- mds_link_pack(req, 0, src->d_inode, dir, name, namelen); -- -- size[0] = sizeof(struct mds_body); -- req->rq_replen = lustre_msg_size(1, size); -- -- rc = mdc_reint(req, LUSTRE_CONN_FULL); -- *request = req; -- if (rc == -ERESTARTSYS ) -- rc = 0; -- -- RETURN(rc); --} -- --int mdc_rename(struct lustre_handle *conn, -- struct inode *src, struct inode *tgt, const char *old, -- int oldlen, const char *new, int newlen, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- int rc, size[3] = {sizeof(struct mds_rec_rename), oldlen + 1, -- newlen + 1}; -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 3, size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- mds_rename_pack(req, 0, src, tgt, old, oldlen, new, newlen); -- -- size[0] = sizeof(struct mds_body); -- req->rq_replen = lustre_msg_size(1, size); -- -- rc = mdc_reint(req, LUSTRE_CONN_FULL); -- *request = req; - if (rc == -ERESTARTSYS ) - if (rc == -ERESTARTSYS) -- rc = 0; -- -- RETURN(rc); --} diff --cc lustre/mdc/mdc_request.c index 1f884a4,79b07ba..0000000 deleted file mode 100644,100644 --- a/lustre/mdc/mdc_request.c +++ /dev/null @@@ -1,692 -1,730 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_MDC -- --#include --#include --#include --#include --#include --#include - #include --#include -- --#define REQUEST_MINOR 244 -- --extern int mds_queue_req(struct ptlrpc_request *); --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --/* should become mdc_getinfo() */ --int mdc_getstatus(struct lustre_handle *conn, struct ll_fid *rootfid) --{ -- struct ptlrpc_request *req; -- struct mds_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETSTATUS, 1, &size, -- NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- req->rq_level = LUSTRE_CONN_CON; -- req->rq_replen = lustre_msg_size(1, &size); -- -- mds_pack_req_body(req); -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- if (!rc) { -- body = lustre_msg_buf(req->rq_repmsg, 0); -- mds_unpack_body(body); -- memcpy(rootfid, &body->fid1, sizeof(*rootfid)); -- -- CDEBUG(D_NET, "root ino="LPU64", last_committed="LPU64 -- ", last_xid="LPU64"\n", -- rootfid->id, req->rq_repmsg->last_committed, -- req->rq_repmsg->last_xid); -- } -- -- EXIT; -- out: -- ptlrpc_req_finished(req); -- return rc; --} -- --int mdc_getlovinfo(struct obd_device *obd, struct lustre_handle *mdc_connh, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- struct mds_status_req *streq; -- int rc, size[2] = {sizeof(*streq)}; -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(mdc_connh), MDS_GETLOVINFO, 1, -- size, NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- *request = req; -- streq = lustre_msg_buf(req->rq_reqmsg, 0); -- streq->flags = HTON__u32(MDS_STATUS_LOV); -- streq->repbuf = HTON__u32(8192); -- -- /* prepare for reply */ -- req->rq_level = LUSTRE_CONN_CON; -- size[0] = 512; -- size[1] = 8192; -- req->rq_replen = lustre_msg_size(2, size); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- out: -- RETURN(rc); --} -- -- --int mdc_getattr(struct lustre_handle *conn, -- obd_id ino, int type, unsigned long valid, size_t ea_size, -- struct ptlrpc_request **request) --{ -- struct ptlrpc_request *req; -- struct mds_body *body; -- int rc, size[2] = {sizeof(*body), 0}, bufcount = 1; -- ENTRY; -- - /* XXX do we need to make another request here? We just did a getattr - * to do the lookup in the first place. - */ -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_GETATTR, 1, size, -- NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- ll_ino2fid(&body->fid1, ino, 0, type); -- body->valid = valid; -- - if (S_ISREG(type)) { - struct client_obd *mdc = &class_conn2obd(conn)->u.cli; - bufcount = 2; - size[1] = mdc->cl_max_mds_easize; - } else if (valid & OBD_MD_LINKNAME) { - bufcount = 2; - size[1] = ea_size; - if (ea_size) { - size[bufcount] = ea_size; - bufcount++; -- body->size = ea_size; - CDEBUG(D_INODE, "allocating %d bytes for symlink in packet\n", - CDEBUG(D_INODE, "reserving %d bytes for MD/symlink in packet\n", -- ea_size); -- } -- req->rq_replen = lustre_msg_size(bufcount, size); -- mds_pack_req_body(req); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- if (!rc) { -- body = lustre_msg_buf(req->rq_repmsg, 0); -- mds_unpack_body(body); -- CDEBUG(D_NET, "mode: %o\n", body->mode); -- } -- -- EXIT; -- out: -- *request = req; -- return rc; --} -- --void d_delete_aliases(struct inode *inode) --{ -- struct dentry *dentry = NULL; -- struct list_head *tmp; -- struct ll_sb_info *sbi = ll_i2sbi(inode); -- ENTRY; -- -- spin_lock(&dcache_lock); -- list_for_each(tmp, &inode->i_dentry) { -- dentry = list_entry(tmp, struct dentry, d_alias); - - // if (atomic_read(&dentry->d_count)) - // continue; - //if (!list_empty(&dentry->d_lru)) - // continue; -- -- list_del_init(&dentry->d_hash); -- list_add(&dentry->d_hash, &sbi->ll_orphan_dentry_list); -- } -- -- spin_unlock(&dcache_lock); -- EXIT; --} -- --static int mdc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, -- void *data, __u32 data_len, int flag) --{ -- int rc; -- struct lustre_handle lockh; -- ENTRY; -- -- switch (flag) { -- case LDLM_CB_BLOCKING: -- ldlm_lock2handle(lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc < 0) { -- CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc); -- RETURN(rc); -- } -- break; -- case LDLM_CB_CANCELING: { -- /* Invalidate all dentries associated with this inode */ -- struct inode *inode = data; -- --#warning "FIXME: what tells us that 'inode' is valid at all?" -- if (inode->i_state & I_FREEING) -- break; -- -- LASSERT(inode != NULL); -- LASSERT(data_len == sizeof(*inode)); -- -- if (S_ISDIR(inode->i_mode)) { -- CDEBUG(D_INODE, "invalidating inode %ld\n", -- inode->i_ino); -- -- ll_invalidate_inode_pages(inode); -- } -- -- if ( inode != inode->i_sb->s_root->d_inode ) { -- /* XXX should this igrab move up 12 lines? */ -- LASSERT(igrab(inode) == inode); -- d_delete_aliases(inode); -- iput(inode); -- } -- break; -- } -- default: -- LBUG(); -- } -- -- RETURN(0); --} -- --/* This should be called with both the request and the reply still packed. */ --void mdc_store_inode_generation(struct ptlrpc_request *req, int reqoff, -- int repoff) --{ -- struct mds_rec_create *rec = lustre_msg_buf(req->rq_reqmsg, reqoff); -- struct mds_body *body = lustre_msg_buf(req->rq_repmsg, repoff); -- - DEBUG_REQ(D_HA, req, "storing generation %x for ino "LPD64, - body->fid1.generation, body->fid1.id); -- memcpy(&rec->cr_replayfid, &body->fid1, sizeof rec->cr_replayfid); --} -- --int mdc_enqueue(struct lustre_handle *conn, int lock_type, -- struct lookup_intent *it, int lock_mode, struct inode *dir, -- struct dentry *de, struct lustre_handle *lockh, -- char *tgt, int tgtlen, void *data, int datalen) --{ -- struct ptlrpc_request *req; -- struct obd_device *obddev = class_conn2obd(conn); -- __u64 res_id[RES_NAME_SIZE] = {dir->i_ino, (__u64)dir->i_generation}; -- int size[6] = {sizeof(struct ldlm_request), sizeof(struct ldlm_intent)}; -- int rc, flags = LDLM_FL_HAS_INTENT; -- int repsize[3] = {sizeof(struct ldlm_reply), -- sizeof(struct mds_body), -- obddev->u.cli.cl_max_mds_easize}; -- struct ldlm_reply *dlm_rep; -- struct ldlm_intent *lit; -- struct ldlm_request *lockreq; -- ENTRY; -- - LDLM_DEBUG_NOLOCK("mdsintent %s dir %ld", ldlm_it2str(it->it_op), - dir->i_ino); - LDLM_DEBUG_NOLOCK("mdsintent %s parent dir %ld", - ldlm_it2str(it->it_op), dir->i_ino); -- -- if (it->it_op & (IT_MKDIR | IT_CREAT | IT_SYMLINK | IT_MKNOD)) { -- switch (it->it_op) { -- case IT_MKDIR: -- it->it_mode |= S_IFDIR; -- break; -- case (IT_CREAT|IT_OPEN): -- case IT_CREAT: -- it->it_mode |= S_IFREG; -- break; -- case IT_SYMLINK: -- it->it_mode |= S_IFLNK; -- break; -- } -- it->it_mode &= ~current->fs->umask; -- -- size[2] = sizeof(struct mds_rec_create); -- size[3] = de->d_name.len + 1; -- size[4] = tgtlen + 1; -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 5, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* pack the intent */ -- lit = lustre_msg_buf(req->rq_reqmsg, 1); -- lit->opc = NTOH__u64((__u64)it->it_op); -- -- /* pack the intended request */ -- mds_create_pack(req, 2, dir, it->it_mode, 0, current->fsuid, -- current->fsgid, CURRENT_TIME, de->d_name.name, -- de->d_name.len, tgt, tgtlen); -- req->rq_replen = lustre_msg_size(3, repsize); -- } else if (it->it_op == IT_RENAME2) { -- struct dentry *old_de = it->it_data; -- -- size[2] = sizeof(struct mds_rec_rename); -- size[3] = old_de->d_name.len + 1; -- size[4] = de->d_name.len + 1; -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 5, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* pack the intent */ -- lit = lustre_msg_buf(req->rq_reqmsg, 1); -- lit->opc = NTOH__u64((__u64)it->it_op); -- -- /* pack the intended request */ -- mds_rename_pack(req, 2, old_de->d_parent->d_inode, dir, -- old_de->d_name.name, old_de->d_name.len, -- de->d_name.name, de->d_name.len); -- req->rq_replen = lustre_msg_size(3, repsize); -- } else if (it->it_op == IT_LINK2) { -- struct dentry *old_de = it->it_data; -- -- size[2] = sizeof(struct mds_rec_link); -- size[3] = de->d_name.len + 1; -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* pack the intent */ -- lit = lustre_msg_buf(req->rq_reqmsg, 1); -- lit->opc = NTOH__u64((__u64)it->it_op); -- -- /* pack the intended request */ -- mds_link_pack(req, 2, old_de->d_inode, dir, -- de->d_name.name, de->d_name.len); -- req->rq_replen = lustre_msg_size(3, repsize); -- } else if (it->it_op == IT_UNLINK || it->it_op == IT_RMDIR) { -- size[2] = sizeof(struct mds_rec_unlink); -- size[3] = de->d_name.len + 1; -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* pack the intent */ -- lit = lustre_msg_buf(req->rq_reqmsg, 1); -- lit->opc = NTOH__u64((__u64)it->it_op); -- -- /* pack the intended request */ -- mds_unlink_pack(req, 2, dir, NULL, -- it->it_op == IT_UNLINK ? S_IFREG : S_IFDIR, -- de->d_name.name, de->d_name.len); -- -- req->rq_replen = lustre_msg_size(3, repsize); - } else if (it->it_op & (IT_GETATTR | IT_RENAME | IT_LINK | - IT_OPEN | IT_SETATTR | IT_LOOKUP | IT_READLINK)) { - } else if (it->it_op & (IT_GETATTR | IT_RENAME | IT_LINK | - IT_OPEN | IT_SETATTR | IT_LOOKUP | IT_READLINK)) { -- size[2] = sizeof(struct mds_body); -- size[3] = de->d_name.len + 1; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 4, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* pack the intent */ -- lit = lustre_msg_buf(req->rq_reqmsg, 1); -- lit->opc = NTOH__u64((__u64)it->it_op); -- -- /* pack the intended request */ -- mds_getattr_pack(req, 2, dir, de->d_name.name, de->d_name.len); -- -- /* get ready for the reply */ -- req->rq_replen = lustre_msg_size(3, repsize); -- } else if (it->it_op == IT_READDIR) { -- req = ptlrpc_prep_req(class_conn2cliimp(conn), LDLM_ENQUEUE, 1, -- size, NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- /* get ready for the reply */ -- req->rq_replen = lustre_msg_size(1, repsize); -- } else { -- LBUG(); -- RETURN(-EINVAL); -- } -- -- rc = ldlm_cli_enqueue(conn, req, obddev->obd_namespace, NULL, res_id, -- lock_type, NULL, 0, lock_mode, &flags, -- ldlm_completion_ast, mdc_blocking_ast, data, -- datalen, lockh); -- -- if (it->it_op != IT_READDIR) { -- /* XXX This should become a lustre_msg flag, but for now... */ -- __u32 *opp = lustre_msg_buf(req->rq_reqmsg, 2); -- *opp |= REINT_REPLAYING; -- } -- -- if (rc == -ENOENT) { -- /* This can go when we're sure that this can never happen */ -- LBUG(); -- } -- if (rc == ELDLM_LOCK_ABORTED) { -- lock_mode = 0; -- memset(lockh, 0, sizeof(*lockh)); -- /* rc = 0 */ -- } else if (rc != 0) { -- CERROR("ldlm_cli_enqueue: %d\n", rc); -- RETURN(rc); -- } else { -- /* The server almost certainly gave us a lock other than the one -- * that we asked for. If we already have a matching lock, then -- * cancel this one--we don't need two. */ -- struct ldlm_lock *lock = ldlm_handle2lock(lockh); -- struct lustre_handle lockh2; -- LASSERT(lock); -- -- LDLM_DEBUG(lock, "matching against this"); -- -- memcpy(&lockh2, lockh, sizeof(lockh2)); -- if (ldlm_lock_match(NULL, NULL, LDLM_PLAIN, NULL, 0, LCK_NL, -- &lockh2)) { -- /* We already have a lock; cancel the old one */ -- ldlm_lock_decref(lockh, lock_mode); -- ldlm_cli_cancel(lockh); -- memcpy(lockh, &lockh2, sizeof(lockh2)); -- } -- LDLM_LOCK_PUT(lock); -- } -- -- /* On replay, we don't want the lock granted. */ -- lockreq = lustre_msg_buf(req->rq_reqmsg, 0); -- lockreq->lock_flags |= LDLM_FL_INTENT_ONLY; -- -- dlm_rep = lustre_msg_buf(req->rq_repmsg, 0); -- it->it_disposition = (int) dlm_rep->lock_policy_res1; -- it->it_status = (int) dlm_rep->lock_policy_res2; -- it->it_lock_mode = lock_mode; -- it->it_data = req; -- -- RETURN(0); --} -- --int mdc_cancel_unused(struct lustre_handle *conn, struct inode *inode, -- int flags) --{ -- __u64 res_id[RES_NAME_SIZE] = {inode->i_ino, inode->i_generation}; -- struct obd_device *obddev = class_conn2obd(conn); -- ENTRY; -- RETURN(ldlm_cli_cancel_unused(obddev->obd_namespace, res_id, flags)); --} -- --struct replay_open_data { -- struct lustre_handle *fh; --}; -- --static void mdc_replay_open(struct ptlrpc_request *req) --{ -- int offset; -- struct replay_open_data *saved; -- struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 0); -- -- if (lustre_msg_get_op_flags(req->rq_reqmsg) & MDS_OPEN_HAS_EA) -- offset = 2; -- else -- offset = 1; -- -- saved = lustre_msg_buf(req->rq_reqmsg, offset); -- mds_unpack_body(body); -- CDEBUG(D_HA, "updating from "LPD64"/"LPD64" to "LPD64"/"LPD64"\n", -- saved->fh->addr, saved->fh->cookie, -- body->handle.addr, body->handle.cookie); -- memcpy(saved->fh, &body->handle, sizeof(body->handle)); --} -- --int mdc_open(struct lustre_handle *conn, obd_id ino, int type, int flags, - struct lov_stripe_md *lsm, struct lustre_handle *fh, - struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, -- struct ptlrpc_request **request) --{ -- struct mds_body *body; -- struct replay_open_data *replay_data; -- int rc, size[3] = {sizeof(*body), sizeof(*replay_data)}, bufcount = 2; -- struct ptlrpc_request *req; -- ENTRY; -- - if (lsm) { - if (lmm && lmm_size) { -- bufcount = 3; -- size[2] = size[1]; /* shuffle the spare data along */ - - size[1] = lsm->lsm_mds_easize; - size[1] = lmm_size; -- } -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_OPEN, bufcount, size, -- NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); - - if (lsm) - lustre_msg_set_op_flags(req->rq_reqmsg, MDS_OPEN_HAS_EA); - -- -- req->rq_flags |= PTL_RPC_FL_REPLAY; -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- ll_ino2fid(&body->fid1, ino, 0, type); -- body->flags = HTON__u32(flags); -- memcpy(&body->handle, fh, sizeof(body->handle)); -- - if (lsm) - lov_packmd(lustre_msg_buf(req->rq_reqmsg, 1), lsm); - if (lmm && lmm_size) { - CDEBUG(D_INODE, "sending %u bytes MD for ino "LPU64"\n", - lmm_size, ino); - lustre_msg_set_op_flags(req->rq_reqmsg, MDS_OPEN_HAS_EA); - memcpy(lustre_msg_buf(req->rq_reqmsg, 1), lmm, lmm_size); - body->flags |= HTON__u32(OBD_MD_FLEASIZE); - } -- -- req->rq_replen = lustre_msg_size(1, size); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- if (!rc) { -- body = lustre_msg_buf(req->rq_repmsg, 0); -- mds_unpack_body(body); -- memcpy(fh, &body->handle, sizeof(*fh)); -- } -- -- /* If open is replayed, we need to fix up the fh. */ -- req->rq_replay_cb = mdc_replay_open; - replay_data = lustre_msg_buf(req->rq_reqmsg, lsm ? 2 : 1); - replay_data = lustre_msg_buf(req->rq_reqmsg, lmm ? 2 : 1); -- replay_data->fh = fh; - - -- EXIT; -- out: -- *request = req; -- return rc; --} -- --int mdc_close(struct lustre_handle *conn, obd_id ino, int type, -- struct lustre_handle *fh, struct ptlrpc_request **request) --{ -- struct mds_body *body; -- int rc, size = sizeof(*body); -- struct ptlrpc_request *req; - ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_CLOSE, 1, &size, -- NULL); -- if (!req) -- GOTO(out, rc = -ENOMEM); -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- ll_ino2fid(&body->fid1, ino, 0, type); -- memcpy(&body->handle, fh, sizeof(body->handle)); -- -- req->rq_replen = lustre_msg_size(0, NULL); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- EXIT; -- out: -- *request = req; -- return rc; --} -- --int mdc_readpage(struct lustre_handle *conn, obd_id ino, int type, __u64 offset, -- char *addr, struct ptlrpc_request **request) --{ -- struct ptlrpc_connection *connection = -- client_conn2cli(conn)->cl_import.imp_connection; -- struct ptlrpc_request *req = NULL; -- struct ptlrpc_bulk_desc *desc = NULL; -- struct ptlrpc_bulk_page *bulk = NULL; -- struct mds_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- CDEBUG(D_INODE, "inode: %ld\n", (long)ino); -- -- desc = ptlrpc_prep_bulk(connection); -- if (desc == NULL) -- GOTO(out, rc = -ENOMEM); -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_READPAGE, 1, &size, -- NULL); -- if (!req) -- GOTO(out2, rc = -ENOMEM); -- -- bulk = ptlrpc_prep_bulk_page(desc); -- bulk->bp_buflen = PAGE_SIZE; -- bulk->bp_buf = addr; -- bulk->bp_xid = req->rq_xid; -- desc->bd_portal = MDS_BULK_PORTAL; -- -- rc = ptlrpc_register_bulk(desc); -- if (rc) { -- CERROR("couldn't setup bulk sink: error %d.\n", rc); -- GOTO(out2, rc); -- } -- - body = lustre_msg_buf(req->rq_reqmsg, 0); - body->fid1.id = ino; - body->fid1.f_type = type; - body->size = offset; - mds_readdir_pack(req, offset, ino, type); -- -- req->rq_replen = lustre_msg_size(1, &size); -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- if (rc) { -- ptlrpc_abort_bulk(desc); -- GOTO(out2, rc); -- } else { -- body = lustre_msg_buf(req->rq_repmsg, 0); -- mds_unpack_body(body); -- } -- -- EXIT; -- out2: -- ptlrpc_free_bulk(desc); -- out: -- *request = req; -- return rc; --} -- --static int mdc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) --{ -- struct ptlrpc_request *req; -- int rc, size = sizeof(*osfs); -- ENTRY; -- -- req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_STATFS, 0, NULL, -- NULL); -- if (!req) -- RETURN(-ENOMEM); -- -- req->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(req); - rc = ptlrpc_check_status(req, rc); -- -- if (rc) -- GOTO(out, rc); -- -- obd_statfs_unpack(osfs, lustre_msg_buf(req->rq_repmsg, 0)); -- -- EXIT; --out: -- ptlrpc_req_finished(req); -- -- return rc; --} - int mdc_attach(struct obd_device *dev, obd_count len, void *data) - -static int mdc_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- - int mdc_detach(struct obd_device *dev) -static int mdc_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); -} - -static int mdc_recover(struct obd_import *imp, int phase) -{ - int rc; - ENTRY; - - switch(phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: - ldlm_cli_cancel_unused(imp->imp_obd->obd_namespace, - NULL, LDLM_FL_LOCAL_ONLY); - RETURN(0); - case PTLRPC_RECOVD_PHASE_RECOVER: - rc = ptlrpc_reconnect_import(imp, MDS_CONNECT); - if (rc == EALREADY) - RETURN(ptlrpc_replay(imp, 0)); - if (rc) - RETURN(rc); - - rc = ptlrpc_replay(imp, 0 /* no last flag*/); - if (rc) - RETURN(rc); - - rc = ldlm_replay_locks(imp); - if (rc) - RETURN(rc); - - spin_lock(&imp->imp_lock); - imp->imp_level = LUSTRE_CONN_FULL; - spin_unlock(&imp->imp_lock); - - ptlrpc_wake_delayed(imp); - - rc = ptlrpc_resend(imp); - if (rc) - RETURN(rc); - - RETURN(0); - default: - RETURN(-EINVAL); - } -} - -static int mdc_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_import *imp = &obd->u.cli.cl_import; - imp->imp_recover = mdc_recover; - return client_obd_connect(conn, obd, cluuid, recovd, recover); --} - --struct obd_ops mdc_obd_ops = { -- o_attach: mdc_attach, -- o_detach: mdc_detach, -- o_setup: client_obd_setup, -- o_cleanup: client_obd_cleanup, - o_connect: client_obd_connect, - o_connect: mdc_connect, -- o_disconnect: client_obd_disconnect, -- o_statfs: mdc_statfs, --}; -- --static int __init ptlrpc_request_init(void) --{ - return class_register_type(&mdc_obd_ops, status_class_var, - return class_register_type(&mdc_obd_ops, status_class_var, -- LUSTRE_MDC_NAME); --} -- --static void __exit ptlrpc_request_exit(void) --{ -- class_unregister_type(LUSTRE_MDC_NAME); --} -- --MODULE_AUTHOR("Cluster File Systems "); --MODULE_DESCRIPTION("Lustre Metadata Client v1.0"); --MODULE_LICENSE("GPL"); -- --EXPORT_SYMBOL(d_delete_aliases); --EXPORT_SYMBOL(mdc_getstatus); --EXPORT_SYMBOL(mdc_getlovinfo); --EXPORT_SYMBOL(mdc_enqueue); --EXPORT_SYMBOL(mdc_cancel_unused); --EXPORT_SYMBOL(mdc_getattr); --EXPORT_SYMBOL(mdc_create); --EXPORT_SYMBOL(mdc_unlink); --EXPORT_SYMBOL(mdc_rename); --EXPORT_SYMBOL(mdc_link); --EXPORT_SYMBOL(mdc_readpage); --EXPORT_SYMBOL(mdc_setattr); --EXPORT_SYMBOL(mdc_close); --EXPORT_SYMBOL(mdc_open); -- --EXPORT_SYMBOL(mdc_store_inode_generation); -- --module_init(ptlrpc_request_init); --module_exit(ptlrpc_request_exit); diff --cc lustre/mds/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/mds/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/mds/Makefile.am index a5eefb4,3332d0b..0000000 deleted file mode 100644,100644 --- a/lustre/mds/Makefile.am +++ /dev/null @@@ -1,33 -1,31 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --if LINUX25 --FSMOD = mds_ext3 --else --FSMOD = mds_extN --endif -- --MODULE = mds --modulefs_DATA = mds.o $(FSMOD).o --EXTRA_PROGRAMS = mds $(FSMOD) -- - LINX= mds_updates.c simple.c ll_pack.c lov_pack.c target.c -LINX= mds_updates.c simple.c ll_pack.c target.c -- --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c --mds_updates.c: -- test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c --simple.c: -- test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c - lov_pack.c: - test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c --target.c: -- test -e target.c || ln -sf $(top_srcdir)/lib/target.c -- --mds_SOURCES = mds_lov.c handler.c mds_reint.c mds_fs.c lproc_mds.c $(LINX) -- --include $(top_srcdir)/Rules diff --cc lustre/mds/handler.c index b5db971,ee12652..0000000 deleted file mode 100644,100644 --- a/lustre/mds/handler.c +++ /dev/null @@@ -1,1569 -1,1839 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lustre/mds/handler.c -- * Lustre Metadata Server (mds) request handler -- * -- * Copyright (c) 2001, 2002 Cluster File Systems, Inc. -- * Author: Peter Braam -- * Author: Andreas Dilger -- * Author: Phil Schwan - * Author: Mike Shaver -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include --#include --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) --#include --#endif -#include --#include -- --static kmem_cache_t *mds_file_cache; -- --extern int mds_get_lovtgts(struct mds_obd *obd, int tgt_count, -- obd_uuid_t *uuidarray); --extern int mds_get_lovdesc(struct mds_obd *obd, struct lov_desc *desc); - extern int mds_update_last_rcvd(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req); -extern void mds_start_transno(struct mds_obd *mds); -extern int mds_finish_transno(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req, int rc); --static int mds_cleanup(struct obd_device * obddev); -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req) --{ -- return &req->rq_export->exp_obd->u.mds; --} -- --static int mds_bulk_timeout(void *data) --{ -- struct ptlrpc_bulk_desc *desc = data; -- -- ENTRY; - CERROR("(not yet) starting recovery of client %p\n", desc->bd_client); - recovd_conn_fail(desc->bd_connection); -- RETURN(1); --} -- --/* Assumes caller has already pushed into the kernel filesystem context */ --static int mds_sendpage(struct ptlrpc_request *req, struct file *file, -- __u64 offset) --{ -- int rc = 0; -- struct mds_obd *mds = mds_req2mds(req); -- struct ptlrpc_bulk_desc *desc; -- struct ptlrpc_bulk_page *bulk; -- struct l_wait_info lwi; -- char *buf; -- ENTRY; -- -- desc = ptlrpc_prep_bulk(req->rq_connection); -- if (desc == NULL) -- GOTO(out, rc = -ENOMEM); -- -- bulk = ptlrpc_prep_bulk_page(desc); -- if (bulk == NULL) -- GOTO(cleanup_bulk, rc = -ENOMEM); -- -- OBD_ALLOC(buf, PAGE_SIZE); -- if (buf == NULL) -- GOTO(cleanup_bulk, rc = -ENOMEM); -- -- rc = mds_fs_readpage(mds, file, buf, PAGE_SIZE, (loff_t *)&offset); -- -- if (rc != PAGE_SIZE) -- GOTO(cleanup_buf, rc = -EIO); -- -- bulk->bp_xid = req->rq_xid; -- bulk->bp_buf = buf; -- bulk->bp_buflen = PAGE_SIZE; -- desc->bd_portal = MDS_BULK_PORTAL; -- -- rc = ptlrpc_send_bulk(desc); -- if (rc) -- GOTO(cleanup_buf, rc); -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SENDPAGE)) { -- CERROR("obd_fail_loc=%x, fail operation rc=%d\n", -- OBD_FAIL_MDS_SENDPAGE, rc); -- ptlrpc_abort_bulk(desc); -- GOTO(cleanup_buf, rc); -- } -- -- lwi = LWI_TIMEOUT(obd_timeout * HZ, mds_bulk_timeout, desc); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags & PTL_BULK_FL_SENT, &lwi); - rc = l_wait_event(desc->bd_waitq, desc->bd_flags & PTL_BULK_FL_SENT, - &lwi); -- if (rc) { -- if (rc != -ETIMEDOUT) -- LBUG(); -- GOTO(cleanup_buf, rc); -- } -- -- EXIT; -- cleanup_buf: -- OBD_FREE(buf, PAGE_SIZE); -- cleanup_bulk: -- ptlrpc_free_bulk(desc); -- out: -- return rc; --} -- --/* -- * Look up a named entry in a directory, and get an LDLM lock on it. -- * 'dir' is a inode for which an LDLM lock has already been taken. -- * -- * If we do not need an exclusive or write lock on this entry (e.g. -- * a read lock for attribute lookup only) then we do not hold the - * directory on return. It is up to the caller to know what type - * of lock it is getting, and clean up appropriately. - * directory semaphore on return. It is up to the caller to know what - * type of lock it is getting, and clean up appropriately. -- */ --struct dentry *mds_name2locked_dentry(struct obd_device *obd, -- struct dentry *dir, struct vfsmount **mnt, -- char *name, int namelen, int lock_mode, -- struct lustre_handle *lockh, -- int dir_lock_mode) --{ -- struct dentry *dchild; -- int flags = 0, rc; -- __u64 res_id[3] = {0}; -- ENTRY; -- -- down(&dir->d_inode->i_sem); -- dchild = lookup_one_len(name, dir, namelen); -- if (IS_ERR(dchild)) { -- CERROR("child lookup error %ld\n", PTR_ERR(dchild)); -- up(&dir->d_inode->i_sem); -- LBUG(); -- RETURN(dchild); -- } -- if (dir_lock_mode != LCK_EX && dir_lock_mode != LCK_PW) { -- up(&dir->d_inode->i_sem); -- ldlm_lock_decref(lockh, dir_lock_mode); -- } -- -- if (lock_mode == 0 || !dchild->d_inode) -- RETURN(dchild); -- -- res_id[0] = dchild->d_inode->i_ino; -- res_id[1] = dchild->d_inode->i_generation; -- rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, lockh); -- if (rc != ELDLM_OK) { -- l_dput(dchild); -- up(&dir->d_inode->i_sem); -- RETURN(ERR_PTR(-ENOLCK)); /* XXX translate ldlm code */ -- } -- -- RETURN(dchild); --} -- --struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid, -- struct vfsmount **mnt, int lock_mode, -- struct lustre_handle *lockh) --{ -- struct mds_obd *mds = &obd->u.mds; -- struct dentry *de = mds_fid2dentry(mds, fid, mnt), *retval = de; -- int flags = 0, rc; -- __u64 res_id[3] = {0}; -- ENTRY; -- -- if (IS_ERR(de)) -- RETURN(de); -- -- res_id[0] = de->d_inode->i_ino; -- res_id[1] = de->d_inode->i_generation; -- rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, lockh); -- if (rc != ELDLM_OK) { -- l_dput(de); -- retval = ERR_PTR(-ENOLCK); /* XXX translate ldlm code */ -- } -- -- RETURN(retval); --} -- --#ifndef DCACHE_DISCONNECTED --#define DCACHE_DISCONNECTED DCACHE_NFSD_DISCONNECTED --#endif -- --/* Look up an entry by inode number. */ --struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, -- struct vfsmount **mnt) --{ -- /* stolen from NFS */ -- struct super_block *sb = mds->mds_sb; -- unsigned long ino = fid->id; -- __u32 generation = fid->generation; -- struct inode *inode; -- struct list_head *lp; -- struct dentry *result; -- -- if (ino == 0) -- RETURN(ERR_PTR(-ESTALE)); -- -- inode = iget(sb, ino); -- if (inode == NULL) -- RETURN(ERR_PTR(-ENOMEM)); -- -- CDEBUG(D_DENTRY, "--> mds_fid2dentry: sb %p\n", inode->i_sb); -- -- if (is_bad_inode(inode) || -- (generation && inode->i_generation != generation)) { -- /* we didn't find the right inode.. */ -- CERROR("bad inode %lu, link: %d ct: %d or version %u/%u\n", -- inode->i_ino, inode->i_nlink, -- atomic_read(&inode->i_count), inode->i_generation, -- generation); - LBUG(); -- iput(inode); - RETURN(ERR_PTR(-ESTALE)); - RETURN(ERR_PTR(-ENOENT)); -- } -- -- /* now to find a dentry. If possible, get a well-connected one */ -- if (mnt) -- *mnt = mds->mds_vfsmnt; -- spin_lock(&dcache_lock); -- list_for_each(lp, &inode->i_dentry) { -- result = list_entry(lp, struct dentry, d_alias); -- if (!(result->d_flags & DCACHE_DISCONNECTED)) { -- dget_locked(result); -- result->d_vfs_flags |= DCACHE_REFERENCED; -- spin_unlock(&dcache_lock); -- iput(inode); -- if (mnt) -- mntget(*mnt); -- return result; -- } -- } -- spin_unlock(&dcache_lock); -- result = d_alloc_root(inode); -- if (result == NULL) { -- iput(inode); -- return ERR_PTR(-ENOMEM); -- } -- if (mnt) -- mntget(*mnt); -- result->d_flags |= DCACHE_DISCONNECTED; -- return result; --} -- --/* Establish a connection to the MDS. -- * -- * This will set up an export structure for the client to hold state data -- * about that client, like open files, the last operation number it did -- * on the server, etc. -- */ --static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- struct obd_export *exp; -- struct mds_export_data *med; -- struct mds_client_data *mcd; -- struct list_head *p; -- int rc; -- ENTRY; -- -- if (!conn || !obd || !cluuid) -- RETURN(-EINVAL); -- -- MOD_INC_USE_COUNT; -- -- spin_lock(&obd->obd_dev_lock); -- list_for_each(p, &obd->obd_exports) { -- exp = list_entry(p, struct obd_export, exp_obd_chain); -- mcd = exp->exp_mds_data.med_mcd; - if (!memcmp(cluuid, mcd->mcd_uuid, sizeof(mcd->mcd_uuid))) { - if (!mcd) { - CERROR("FYI: NULL mcd - simultaneous connects\n"); - continue; - } - if (!memcmp(cluuid, mcd->mcd_uuid, sizeof mcd->mcd_uuid)) { - /* XXX make handle-found-export a subroutine */ -- LASSERT(exp->exp_obd == obd); -- - if (!list_empty(&exp->exp_conn_chain)) { - CERROR("existing uuid/export, list not empty!\n"); - spin_unlock(&obd->obd_dev_lock); - spin_unlock(&obd->obd_dev_lock); - if (exp->exp_connection) { - struct lustre_handle *hdl; - hdl = &exp->exp_ldlm_data.led_import.imp_handle; - /* Might be a re-connect after a partition. */ - if (!memcmp(conn, hdl, sizeof *conn)) { - CERROR("%s reconnecting\n", cluuid); - conn->addr = (__u64) (unsigned long)exp; - conn->cookie = exp->exp_cookie; - rc = EALREADY; - } else { - CERROR("%s reconnecting from %s, " - "handle mismatch (ours %Lx/%Lx, " - "theirs %Lx/%Lx)\n", cluuid, - exp->exp_connection-> - c_remote_uuid, hdl->addr, - hdl->cookie, conn->addr, - conn->cookie); - /* XXX disconnect them here? */ - memset(conn, 0, sizeof *conn); - rc = -EALREADY; - } -- MOD_DEC_USE_COUNT; - RETURN(-EALREADY); - RETURN(rc); -- } -- conn->addr = (__u64) (unsigned long)exp; -- conn->cookie = exp->exp_cookie; - spin_unlock(&obd->obd_dev_lock); -- CDEBUG(D_INFO, "existing export for UUID '%s' at %p\n", -- cluuid, exp); -- CDEBUG(D_IOCTL,"connect: addr %Lx cookie %Lx\n", -- (long long)conn->addr, (long long)conn->cookie); - MOD_DEC_USE_COUNT; -- RETURN(0); -- } -- } -- spin_unlock(&obd->obd_dev_lock); - - if (obd->u.mds.mds_recoverable_clients != 0) { - CERROR("denying connection for new client %s: in recovery\n", - cluuid); - MOD_DEC_USE_COUNT; - RETURN(-EBUSY); - } - -- /* XXX There is a small race between checking the list and adding a -- * new connection for the same UUID, but the real threat (list -- * corruption when multiple different clients connect) is solved. - * - * There is a second race between adding the export to the list, - * and filling in the client data below. Hence skipping the case - * of NULL mcd above. We should already be controlling multiple - * connects at the client, and we can't hold the spinlock over - * memory allocations without risk of deadlocking. -- */ -- rc = class_connect(conn, obd, cluuid); -- if (rc) -- GOTO(out_dec, rc); -- exp = class_conn2export(conn); -- LASSERT(exp); -- med = &exp->exp_mds_data; -- -- OBD_ALLOC(mcd, sizeof(*mcd)); -- if (!mcd) { -- CERROR("mds: out of memory for client data\n"); -- GOTO(out_export, rc = -ENOMEM); -- } -- -- memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid)); -- med->med_mcd = mcd; -- -- INIT_LIST_HEAD(&med->med_open_head); -- spin_lock_init(&med->med_open_lock); -- - rc = mds_client_add(med, -1); - rc = mds_client_add(&obd->u.mds, med, -1); -- if (rc) - GOTO(out_mdc, rc); - GOTO(out_mcd, rc); -- -- RETURN(0); -- - out_mdc: -out_mcd: -- OBD_FREE(mcd, sizeof(*mcd)); --out_export: -- class_disconnect(conn); --out_dec: -- MOD_DEC_USE_COUNT; -- -- return rc; --} -- --/* Call with med->med_open_lock held, please. */ --inline int mds_close_mfd(struct mds_file_data *mfd, struct mds_export_data *med) --{ -- struct file *file = mfd->mfd_file; -- LASSERT(file->private_data == mfd); -- -- list_del(&mfd->mfd_list); -- mfd->mfd_servercookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(mds_file_cache, mfd); -- -- return filp_close(file, 0); --} -- --static int mds_disconnect(struct lustre_handle *conn) --{ -- struct obd_export *export = class_conn2export(conn); -- struct list_head *tmp, *n; -- struct mds_export_data *med = &export->exp_mds_data; -- int rc; -- ENTRY; -- -- /* -- * Close any open files. -- */ -- spin_lock(&med->med_open_lock); -- list_for_each_safe(tmp, n, &med->med_open_head) { -- struct mds_file_data *mfd = -- list_entry(tmp, struct mds_file_data, mfd_list); -- rc = mds_close_mfd(mfd, med); -- if (rc) { -- /* XXX better diagnostics, with file path and stuff */ -- CDEBUG(D_INODE, "Error %d closing mfd %p\n", rc, mfd); -- } -- } -- spin_unlock(&med->med_open_lock); -- -- ldlm_cancel_locks_for_export(export); -- mds_client_free(export); -- -- rc = class_disconnect(conn); -- if (!rc) -- MOD_DEC_USE_COUNT; -- -- RETURN(rc); --} -- --/* -- * XXX This is NOT guaranteed to flush all transactions to disk (even though -- * it is equivalent to calling sync()) because it only _starts_ the flush -- * and does not wait for completion. It's better than nothing though. -- * What we really want is a mild form of fsync_dev_lockfs(), but it is -- * non-standard, or enabling do_sync_supers in ext3, just for this call. -- */ --static void mds_fsync_super(struct super_block *sb) --{ -- lock_kernel(); -- lock_super(sb); -- if (sb->s_dirt && sb->s_op && sb->s_op->write_super) -- sb->s_op->write_super(sb); -- unlock_super(sb); -- unlock_kernel(); --} -- --static int mds_getstatus(struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct mds_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETSTATUS_PACK)) { -- CERROR("mds: out of memory for message: size=%d\n", size); -- req->rq_status = -ENOMEM; -- RETURN(0); -- } -- -- /* Flush any outstanding transactions to disk so the client will -- * get the latest last_committed value and can drop their local -- * requests if they have any. This would be fsync_super() if it -- * was exported. -- */ -- mds_fsync_super(mds->mds_sb); -- -- body = lustre_msg_buf(req->rq_repmsg, 0); -- memcpy(&body->fid1, &mds->mds_rootfid, sizeof(body->fid1)); -- -- /* the last_committed and last_xid fields are filled in for all -- * replies already - no need to do so here also. -- */ -- RETURN(0); --} -- --static int mds_getlovinfo(struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct mds_status_req *streq; -- struct lov_desc *desc; -- int tgt_count; -- int rc, size[2] = {sizeof(*desc)}; -- ENTRY; -- -- streq = lustre_msg_buf(req->rq_reqmsg, 0); -- streq->flags = NTOH__u32(streq->flags); -- streq->repbuf = NTOH__u32(streq->repbuf); -- size[1] = streq->repbuf; -- -- rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) { -- CERROR("mds: out of memory for message: size=%d\n", size[1]); -- req->rq_status = -ENOMEM; -- RETURN(0); -- } -- -- desc = lustre_msg_buf(req->rq_repmsg, 0); -- rc = mds_get_lovdesc(mds, desc); -- if (rc) { - CERROR("mds_get_lovdesc error %d", rc); -- req->rq_status = rc; -- RETURN(0); -- } -- -- tgt_count = le32_to_cpu(desc->ld_tgt_count); -- if (tgt_count * sizeof(obd_uuid_t) > streq->repbuf) { -- CERROR("too many targets, enlarge client buffers\n"); -- req->rq_status = -ENOSPC; -- RETURN(0); -- } -- - mds->mds_max_mdsize = sizeof(struct lov_mds_md) + - tgt_count * sizeof(struct lov_object_id); - /* XXX the MDS should not really know about this */ - mds->mds_max_mdsize = lov_mds_md_size(tgt_count); -- rc = mds_get_lovtgts(mds, tgt_count, -- lustre_msg_buf(req->rq_repmsg, 1)); -- if (rc) { -- CERROR("get_lovtgts error %d\n", rc); -- req->rq_status = rc; -- RETURN(0); -- } -- RETURN(0); --} -- --int mds_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, -- void *data, __u32 data_len, int flag) --{ -- int do_ast; -- ENTRY; -- -- if (flag == LDLM_CB_CANCELING) { -- /* Don't need to do anything here. */ -- RETURN(0); -- } -- -- /* XXX layering violation! -phil */ -- l_lock(&lock->l_resource->lr_namespace->ns_lock); -- lock->l_flags |= LDLM_FL_CBPENDING; -- do_ast = (!lock->l_readers && !lock->l_writers); -- l_unlock(&lock->l_resource->lr_namespace->ns_lock); -- -- if (do_ast) { -- struct lustre_handle lockh; -- int rc; -- -- LDLM_DEBUG(lock, "already unused, calling ldlm_cli_cancel"); -- ldlm_lock2handle(lock, &lockh); -- rc = ldlm_cli_cancel(&lockh); -- if (rc < 0) -- CERROR("ldlm_cli_cancel: %d\n", rc); -- } else -- LDLM_DEBUG(lock, "Lock still has references, will be" -- "cancelled later"); -- RETURN(0); -} - -int mds_pack_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode) -{ - struct lov_mds_md *lmm; - int lmm_size = req->rq_repmsg->buflens[offset]; - int rc; - - if (lmm_size == 0) { - CDEBUG(D_INFO, "no space reserved for inode %u MD\n", inode->i_ino); - RETURN(0); - } - - lmm = lustre_msg_buf(req->rq_repmsg, offset); - - /* I don't really like this, but it is a sanity check on the client - * MD request. However, if the client doesn't know how much space - * to reserve for the MD, this shouldn't be fatal either... - */ - if (lmm_size > mds->mds_max_mdsize) { - CERROR("Reading MD for inode %u of %d bytes > max %d\n", - inode->i_ino, lmm_size, mds->mds_max_mdsize); - // RETURN(-EINVAL); - } - - /* We don't need to store the reply size, because this buffer is - * discarded right after unpacking, and the LOV can figure out the - * size itself from the ost count. - */ - if ((rc = mds_fs_get_md(mds, inode, lmm, lmm_size)) < 0) { - CDEBUG(D_INFO, "No md for ino %u: rc = %d\n", inode->i_ino, rc); - } else if (rc > 0) { - body->valid |= OBD_MD_FLEASIZE; - rc = 0; - } - - return rc; --} -- --static int mds_getattr_internal(struct mds_obd *mds, struct dentry *dentry, -- struct ptlrpc_request *req, -- struct mds_body *reqbody, int reply_off) --{ -- struct mds_body *body; -- struct inode *inode = dentry->d_inode; - int rc; - int rc = 0; -- ENTRY; -- -- if (inode == NULL) -- RETURN(-ENOENT); -- -- body = lustre_msg_buf(req->rq_repmsg, reply_off); -- -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); -- -- if (S_ISREG(inode->i_mode)) { - struct lov_mds_md *lmm; - - lmm = lustre_msg_buf(req->rq_repmsg, reply_off + 1); - lmm->lmm_easize = mds->mds_max_mdsize; - rc = mds_fs_get_md(mds, inode, lmm); - - if (rc < 0) { - if (rc == -ENODATA) - RETURN(0); - CERROR("mds_fs_get_md failed: %d\n", rc); - RETURN(rc); - } - body->valid |= OBD_MD_FLEASIZE; - rc = mds_pack_md(mds, req, reply_off + 1, body, inode); -- } else if (S_ISLNK(inode->i_mode) && reqbody->valid & OBD_MD_LINKNAME) { -- char *symname = lustre_msg_buf(req->rq_repmsg, reply_off + 1); -- int len = req->rq_repmsg->buflens[reply_off + 1]; -- -- rc = inode->i_op->readlink(dentry, symname, len); -- if (rc < 0) { -- CERROR("readlink failed: %d\n", rc); - RETURN(rc); - } else - } else { -- CDEBUG(D_INODE, "read symlink dest %s\n", symname); - - body->valid |= OBD_MD_LINKNAME; - body->valid |= OBD_MD_LINKNAME; - } -- } - RETURN(0); - RETURN(rc); --} -- --static int mds_getattr_name(int offset, struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_device *obd = req->rq_export->exp_obd; -- struct obd_run_ctxt saved; -- struct mds_body *body; -- struct dentry *de = NULL, *dchild = NULL; -- struct inode *dir; -- struct lustre_handle lockh; -- char *name; -- int namelen, flags = 0, lock_mode, rc = 0; -- struct obd_ucred uc; -- __u64 res_id[3] = {0, 0, 0}; -- ENTRY; -- -- LASSERT(!strcmp(req->rq_export->exp_obd->obd_type->typ_name, "mds")); -- -- if (req->rq_reqmsg->bufcount <= offset + 1) { -- LBUG(); -- GOTO(out_pre_de, rc = -EINVAL); -- } -- -- body = lustre_msg_buf(req->rq_reqmsg, offset); -- name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- namelen = req->rq_reqmsg->buflens[offset + 1]; -- /* requests were at offset 2, replies go back at 1 */ -- if (offset) -- offset = 1; -- -- uc.ouc_fsuid = body->fsuid; -- uc.ouc_fsgid = body->fsgid; -- uc.ouc_cap = body->capability; -- push_ctxt(&saved, &mds->mds_ctxt, &uc); -- de = mds_fid2dentry(mds, &body->fid1, NULL); -- if (IS_ERR(de)) { - LBUG(); - GOTO(out_pre_de, rc = -ESTALE); - GOTO(out_pre_de, rc = -ENOENT); -- } -- -- dir = de->d_inode; -- CDEBUG(D_INODE, "parent ino %ld, name %*s\n", dir->i_ino,namelen,name); -- -- lock_mode = LCK_PR; -- res_id[0] = dir->i_ino; -- res_id[1] = dir->i_generation; -- -- rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, lock_mode, &lockh); -- if (rc == 0) { -- LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &lockh); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- GOTO(out_create_de, rc = -EIO); -- } -- } -- ldlm_lock_dump((void *)(unsigned long)lockh.addr); -- -- down(&dir->i_sem); -- dchild = lookup_one_len(name, de, namelen - 1); -- if (IS_ERR(dchild)) { -- CDEBUG(D_INODE, "child lookup error %ld\n", PTR_ERR(dchild)); -- up(&dir->i_sem); - LBUG(); - GOTO(out_create_dchild, rc = -ESTALE); - GOTO(out_create_dchild, rc = PTR_ERR(dchild)); -- } -- -- rc = mds_getattr_internal(mds, dchild, req, body, offset); -- -- EXIT; --out_create_dchild: -- l_dput(dchild); -- up(&dir->i_sem); -- ldlm_lock_decref(&lockh, lock_mode); --out_create_de: -- l_dput(de); --out_pre_de: -- req->rq_status = rc; - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); -- return 0; --} -- --static int mds_getattr(int offset, struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_run_ctxt saved; -- struct dentry *de; -- struct inode *inode; -- struct mds_body *body; -- struct obd_ucred uc; -- int rc = 0, size[2] = {sizeof(*body)}, bufcount = 1; -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, offset); -- uc.ouc_fsuid = body->fsuid; -- uc.ouc_fsgid = body->fsgid; -- uc.ouc_cap = body->capability; -- push_ctxt(&saved, &mds->mds_ctxt, &uc); -- de = mds_fid2dentry(mds, &body->fid1, NULL); -- if (IS_ERR(de)) { -- rc = req->rq_status = -ENOENT; -- GOTO(out_pop, PTR_ERR(de)); -- } -- -- inode = de->d_inode; -- if (S_ISREG(body->fid1.f_type)) { - bufcount = 2; - size[1] = mds->mds_max_mdsize; - int rc = mds_fs_get_md(mds, inode, NULL, 0); - CDEBUG(D_INODE, "got %d bytes MD data for inode %u\n", - rc, inode->i_ino); - if (rc < 0) { - if (rc != -ENODATA) - CERROR("error getting inode %u MD: rc = %d\n", - inode->i_ino, rc); - size[bufcount] = 0; - } else if (rc > mds->mds_max_mdsize) { - size[bufcount] = 0; - CERROR("MD size %d larger than maximum possible %u\n", - rc, mds->mds_max_mdsize); - } else - size[bufcount] = rc; - bufcount++; -- } else if (body->valid & OBD_MD_LINKNAME) { - bufcount = 2; - size[1] = MIN(inode->i_size + 1, body->size); - size[bufcount] = MIN(inode->i_size + 1, body->size); - bufcount++; -- CDEBUG(D_INODE, "symlink size: %d, reply space: %d\n", -- inode->i_size + 1, body->size); -- } -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { - CERROR("failed GETATTR_PACK test\n"); - CERROR("failed MDS_GETATTR_PACK test\n"); -- req->rq_status = -ENOMEM; -- GOTO(out, rc = -ENOMEM); -- } -- -- rc = lustre_pack_msg(bufcount, size, NULL, &req->rq_replen, -- &req->rq_repmsg); -- if (rc) { - CERROR("out of memory or FAIL_MDS_GETATTR_PACK\n"); - CERROR("out of memoryK\n"); -- req->rq_status = rc; -- GOTO(out, rc); -- } -- -- req->rq_status = mds_getattr_internal(mds, de, req, body, 0); -- --out: -- l_dput(de); --out_pop: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); -- RETURN(rc); --} -- --static int mds_statfs(struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_statfs *osfs; -- struct statfs sfs; -- int rc, size = sizeof(*osfs); -- ENTRY; -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) { -- CERROR("mds: statfs lustre_pack_msg failed: rc = %d\n", rc); -- GOTO(out, rc); -- } -- -- rc = mds_fs_statfs(mds, &sfs); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- GOTO(out, rc); -- } -- osfs = lustre_msg_buf(req->rq_repmsg, 0); -- memset(osfs, 0, size); -- statfs_pack(osfs, &sfs); -- obd_statfs_pack(osfs, osfs); -- --out: -- req->rq_status = rc; -- RETURN(0); --} -- --static struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle) --{ -- struct mds_file_data *mfd = NULL; -- -- if (!handle || !handle->addr) -- RETURN(NULL); -- -- mfd = (struct mds_file_data *)(unsigned long)(handle->addr); -- if (!kmem_cache_validate(mds_file_cache, mfd)) -- RETURN(NULL); -- -- if (mfd->mfd_servercookie != handle->cookie) -- RETURN(NULL); -- -- return mfd; --} -- - static int mds_store_ea(struct mds_obd *mds, struct ptlrpc_request *req, - struct mds_body *body, struct dentry *de, - struct lov_mds_md *lmm) -static int mds_store_md(struct mds_obd *mds, struct ptlrpc_request *req, - int offset, struct mds_body *body, struct inode *inode) --{ - struct lov_mds_md *lmm = lustre_msg_buf(req->rq_reqmsg, offset); - int lmm_size = req->rq_reqmsg->buflens[offset]; -- struct obd_run_ctxt saved; -- struct obd_ucred uc; -- void *handle; -- int rc, rc2; - ENTRY; - - /* I don't really like this, but it is a sanity check on the client - * MD request. - */ - if (lmm_size > mds->mds_max_mdsize) { - CERROR("Saving MD for inode %u of %d bytes > max %d\n", - inode->i_ino, lmm_size, mds->mds_max_mdsize); - //RETURN(-EINVAL); - } -- - CDEBUG(D_INODE, "storing %d bytes MD for inode %u\n", - lmm_size, inode->i_ino); -- uc.ouc_fsuid = body->fsuid; -- uc.ouc_fsgid = body->fsgid; -- uc.ouc_cap = body->capability; - push_ctxt(&saved, &mds->mds_ctxt, &uc); - handle = mds_fs_start(mds, de->d_inode, MDS_FSOP_SETATTR); - if (!handle) - GOTO(out_ea, rc = -ENOMEM); - push_ctxt(&saved, &mds->mds_ctxt, &uc); - mds_start_transno(mds); - handle = mds_fs_start(mds, inode, MDS_FSOP_SETATTR); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_ea, rc); - } -- - rc = mds_fs_set_md(mds, de->d_inode, handle, lmm); - if (!rc) - rc = mds_update_last_rcvd(mds, handle, req); - rc = mds_fs_set_md(mds, inode, handle, lmm, lmm_size); - rc = mds_finish_transno(mds, handle, req, rc); -- - rc2 = mds_fs_commit(mds, de->d_inode, handle); - rc2 = mds_fs_commit(mds, inode, handle); -- if (rc2 && !rc) -- rc = rc2; --out_ea: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); -- - return rc; - RETURN(rc); --} -- --static int mds_open(struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct mds_body *body; -- struct mds_export_data *med; -- struct mds_file_data *mfd; -- struct dentry *de; -- struct file *file; -- struct vfsmount *mnt; -- __u32 flags; -- struct list_head *tmp; -- int rc, size = sizeof(*body); -- ENTRY; -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) { -- CERROR("test case OBD_FAIL_MDS_OPEN_PACK\n"); -- req->rq_status = -ENOMEM; -- RETURN(-ENOMEM); -- } -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) { -- CERROR("mds: pack error: rc = %d\n", rc); -- req->rq_status = rc; -- RETURN(rc); -- } -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- /* was this animal open already and the client lost the reply? */ -- /* XXX need some way to detect a reopen, to avoid locked list walks */ -- med = &req->rq_export->exp_mds_data; -- spin_lock(&med->med_open_lock); -- list_for_each(tmp, &med->med_open_head) { -- mfd = list_entry(tmp, typeof(*mfd), mfd_list); -- if (!memcmp(&mfd->mfd_clienthandle, &body->handle, -- sizeof(mfd->mfd_clienthandle)) && -- body->fid1.id == mfd->mfd_file->f_dentry->d_inode->i_ino) { -- de = mfd->mfd_file->f_dentry; -- spin_unlock(&med->med_open_lock); -- CERROR("Re opening "LPD64"\n", body->fid1.id); -- GOTO(out_pack, rc = 0); -- } -- } -- spin_unlock(&med->med_open_lock); -- -- mfd = kmem_cache_alloc(mds_file_cache, GFP_KERNEL); -- if (!mfd) { -- CERROR("mds: out of memory\n"); -- req->rq_status = -ENOMEM; -- RETURN(0); -- } -- -- de = mds_fid2dentry(mds, &body->fid1, &mnt); -- if (IS_ERR(de)) -- GOTO(out_free, rc = PTR_ERR(de)); -- -- /* check if this inode has seen a delayed object creation */ -- if (lustre_msg_get_op_flags(req->rq_reqmsg) & MDS_OPEN_HAS_EA) { - struct lov_mds_md *lmm = lustre_msg_buf(req->rq_reqmsg, 1); - - rc = mds_store_ea(mds, req, body, de, lmm); - rc = mds_store_md(mds, req, 1, body, de->d_inode); -- if (rc) { -- l_dput(de); -- mntput(mnt); -- GOTO(out_free, rc); -- } -- } -- -- flags = body->flags; -- /* dentry_open does a dput(de) and mntput(mnt) on error */ -- file = dentry_open(de, mnt, flags & ~O_DIRECT); -- if (IS_ERR(file)) { -- rc = PTR_ERR(file); -- GOTO(out_free, 0); -- } -- -- file->private_data = mfd; -- mfd->mfd_file = file; -- memcpy(&mfd->mfd_clienthandle, &body->handle, sizeof(body->handle)); -- get_random_bytes(&mfd->mfd_servercookie, sizeof(mfd->mfd_servercookie)); -- spin_lock(&med->med_open_lock); -- list_add(&mfd->mfd_list, &med->med_open_head); -- spin_unlock(&med->med_open_lock); -- --out_pack: -- body = lustre_msg_buf(req->rq_repmsg, 0); -- mds_pack_inode2fid(&body->fid1, de->d_inode); -- mds_pack_inode2body(body, de->d_inode); -- body->handle.addr = (__u64)(unsigned long)mfd; -- body->handle.cookie = mfd->mfd_servercookie; -- CDEBUG(D_INODE, "llite file "LPX64": addr %p, cookie "LPX64"\n", -- mfd->mfd_clienthandle.addr, mfd, mfd->mfd_servercookie); -- RETURN(0); -- --out_free: -- mfd->mfd_servercookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(mds_file_cache, mfd); -- req->rq_status = rc; -- RETURN(0); --} -- --static int mds_close(struct ptlrpc_request *req) --{ -- struct mds_export_data *med = &req->rq_export->exp_mds_data; -- struct mds_body *body; -- struct mds_file_data *mfd; -- int rc; -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- mfd = mds_handle2mfd(&body->handle); -- if (!mfd) { -- CERROR("no handle for file close "LPD64 -- ": addr "LPX64", cookie "LPX64"\n", -- body->fid1.id, body->handle.addr, body->handle.cookie); -- RETURN(-ESTALE); -- } -- -- spin_lock(&med->med_open_lock); -- req->rq_status = mds_close_mfd(mfd, med); -- spin_unlock(&med->med_open_lock); -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK)) { -- CERROR("test case OBD_FAIL_MDS_CLOSE_PACK\n"); -- req->rq_status = -ENOMEM; -- RETURN(-ENOMEM); -- } -- -- rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) { -- CERROR("mds: lustre_pack_msg: rc = %d\n", rc); -- req->rq_status = rc; -- } -- -- RETURN(0); --} -- --static int mds_readpage(struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct vfsmount *mnt; -- struct dentry *de; -- struct file *file; -- struct mds_body *body, *repbody; -- struct obd_run_ctxt saved; -- int rc, size = sizeof(*body); -- struct obd_ucred uc; -- ENTRY; -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_READPAGE_PACK)) { -- CERROR("mds: out of memory\n"); -- GOTO(out, rc = -ENOMEM); -- } -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- uc.ouc_fsuid = body->fsuid; -- uc.ouc_fsgid = body->fsgid; -- uc.ouc_cap = body->capability; -- push_ctxt(&saved, &mds->mds_ctxt, &uc); -- de = mds_fid2dentry(mds, &body->fid1, &mnt); -- if (IS_ERR(de)) -- GOTO(out_pop, rc = PTR_ERR(de)); -- -- CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino); -- -- file = dentry_open(de, mnt, O_RDONLY | O_LARGEFILE); -- /* note: in case of an error, dentry_open puts dentry */ -- if (IS_ERR(file)) -- GOTO(out_pop, rc = PTR_ERR(file)); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- repbody->size = file->f_dentry->d_inode->i_size; -- repbody->valid = OBD_MD_FLSIZE; -- -- /* to make this asynchronous make sure that the handling function -- doesn't send a reply when this function completes. Instead a -- callback function would send the reply */ -- /* note: in case of an error, dentry_open puts dentry */ -- rc = mds_sendpage(req, file, body->size); -- -- filp_close(file, 0); --out_pop: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); --out: -- req->rq_status = rc; -- RETURN(0); --} -- - int mds_reint(int offset, struct ptlrpc_request *req) -int mds_reint(struct ptlrpc_request *req, int offset) --{ -- int rc; -- struct mds_update_record rec; -- -- rc = mds_update_unpack(req, offset, &rec); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNPACK)) { -- CERROR("invalid record\n"); -- req->rq_status = -EINVAL; -- RETURN(0); -- } -- /* rc will be used to interrupt a for loop over multiple records */ -- rc = mds_reint_rec(&rec, offset, req); -- return rc; -} - -/* forward declaration */ -int mds_handle(struct ptlrpc_request *req); - -static int check_for_next_transno(struct mds_obd *mds) -{ - struct ptlrpc_request *req; - req = list_entry(mds->mds_recovery_queue.next, - struct ptlrpc_request, rq_list); - return req->rq_reqmsg->transno == mds->mds_next_recovery_transno; -} - -static void process_recovery_queue(struct mds_obd *mds) -{ - struct ptlrpc_request *req; - - for (;;) { - spin_lock(&mds->mds_processing_task_lock); - req = list_entry(mds->mds_recovery_queue.next, - struct ptlrpc_request, rq_list); - - if (req->rq_reqmsg->transno != mds->mds_next_recovery_transno) { - spin_unlock(&mds->mds_processing_task_lock); - wait_event(mds->mds_next_transno_waitq, - check_for_next_transno(mds)); - continue; - } - list_del(&req->rq_list); - spin_unlock(&mds->mds_processing_task_lock); - - DEBUG_REQ(D_HA, req, ""); - mds_handle(req); - - if (list_empty(&mds->mds_recovery_queue)) - break; - } -} - -static int queue_recovery_request(struct ptlrpc_request *req, - struct mds_obd *mds) -{ - struct list_head *tmp; - int inserted = 0, transno = req->rq_reqmsg->transno; - - if (!transno) { - DEBUG_REQ(D_HA, req, "not queueing"); - return 1; - } - - spin_lock(&mds->mds_processing_task_lock); - - if (mds->mds_processing_task == current->pid) { - /* Processing the queue right now, don't re-add. */ - spin_unlock(&mds->mds_processing_task_lock); - return 1; - } - - /* XXX O(n^2) */ - list_for_each(tmp, &mds->mds_recovery_queue) { - struct ptlrpc_request *reqiter = - list_entry(tmp, struct ptlrpc_request, rq_list); - if (reqiter->rq_reqmsg->transno > transno) { - list_add_tail(&req->rq_list, &reqiter->rq_list); - inserted = 1; - break; - } - } - - if (!inserted) - list_add_tail(&req->rq_list, &mds->mds_recovery_queue); - - if (mds->mds_processing_task != 0) { - /* Someone else is processing this queue, we'll leave it to - * them. - */ - spin_unlock(&mds->mds_processing_task_lock); - if (transno == mds->mds_next_recovery_transno) - wake_up(&mds->mds_next_transno_waitq); - return 0; - } - - /* Nobody is processing, and we know there's (at least) one to process - * now, so we'll do the honours. - */ - mds->mds_processing_task = current->pid; - spin_unlock(&mds->mds_processing_task_lock); - - process_recovery_queue(mds); - return 0; -} - -static int filter_recovery_request(struct ptlrpc_request *req, - struct mds_obd *mds, int *process) -{ - switch (req->rq_reqmsg->opc) { - case MDS_CONNECT: - case MDS_DISCONNECT: - case MDS_OPEN: - *process = 1; - RETURN(0); - - case MDS_GETSTATUS: /* used in unmounting */ - case MDS_REINT: - case LDLM_ENQUEUE: - *process = queue_recovery_request(req, mds); - RETURN(0); - - default: - DEBUG_REQ(D_ERROR, req, "not permitted during recovery"); - *process = 0; - RETURN(ptlrpc_error(req->rq_svc, req)); - } -} - -static int mds_queue_final_reply(struct ptlrpc_request *req, int rc) -{ - struct mds_obd *mds = mds_req2mds(req); - - if (rc) { - /* Just like ptlrpc_error, but without the sending. */ - lustre_pack_msg(0, NULL, NULL, &req->rq_replen, - &req->rq_repmsg); - req->rq_type = PTL_RPC_MSG_ERR; - } - - list_add(&req->rq_list, &mds->mds_delayed_reply_queue); - if (--mds->mds_recoverable_clients == 0) { - struct list_head *tmp, *n; - - CDEBUG(D_HA, - "all clients recovered, sending delayed replies\n"); - list_for_each_safe(tmp, n, &mds->mds_delayed_reply_queue) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "delayed:"); - ptlrpc_reply(req->rq_svc, req); - } - } else { - CDEBUG(D_HA, "%d recoverable clients remain\n", - mds->mds_recoverable_clients); - } - - return 1; --} - -static char *reint_names[] = { - [REINT_SETATTR] "setattr", - [REINT_CREATE] "create", - [REINT_LINK] "link", - [REINT_UNLINK] "unlink", - [REINT_RENAME] "rename" -}; -- --int mds_handle(struct ptlrpc_request *req) --{ -- int rc; - int should_process; - struct mds_obd *mds = NULL; /* quell gcc overwarning */ -- ENTRY; -- -- rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_HANDLE_UNPACK)) { -- CERROR("lustre_mds: Invalid request\n"); -- GOTO(out, rc); -- } - - if (req->rq_reqmsg->opc != MDS_CONNECT && req->rq_export == NULL) - GOTO(out, rc = -ENOTCONN); -- -- LASSERT(!strcmp(req->rq_obd->obd_type->typ_name, LUSTRE_MDT_NAME)); - - if (req->rq_reqmsg->opc != MDS_CONNECT) { - if (req->rq_export == NULL) - GOTO(out, rc = -ENOTCONN); - - mds = mds_req2mds(req); - if (mds->mds_recoverable_clients != 0) { - rc = filter_recovery_request(req, mds, &should_process); - if (rc || !should_process) - RETURN(rc); - } - } -- -- switch (req->rq_reqmsg->opc) { -- case MDS_CONNECT: - CDEBUG(D_INODE, "connect\n"); - DEBUG_REQ(D_INODE, req, "connect"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_CONNECT_NET, 0); -- rc = target_handle_connect(req); - /* Make sure that last_rcvd is correct. */ - if (!rc) { - /* Now that we have an export, set mds. */ - mds = mds_req2mds(req); - mds_fsync_super(mds->mds_sb); - } -- break; -- -- case MDS_DISCONNECT: - CDEBUG(D_INODE, "disconnect\n"); - DEBUG_REQ(D_INODE, req, "disconnect"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_DISCONNECT_NET, 0); -- rc = target_handle_disconnect(req); - /* Make sure that last_rcvd is correct. */ - if (!rc) - mds_fsync_super(mds->mds_sb); -- goto out; -- -- case MDS_GETSTATUS: - CDEBUG(D_INODE, "getstatus\n"); - DEBUG_REQ(D_INODE, req, "getstatus"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_GETSTATUS_NET, 0); -- rc = mds_getstatus(req); -- break; -- -- case MDS_GETLOVINFO: - CDEBUG(D_INODE, "getlovinfo\n"); - DEBUG_REQ(D_INODE, req, "getlovinfo"); -- rc = mds_getlovinfo(req); -- break; -- -- case MDS_GETATTR: - CDEBUG(D_INODE, "getattr\n"); - DEBUG_REQ(D_INODE, req, "getattr"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_GETATTR_NET, 0); -- rc = mds_getattr(0, req); -- break; -- -- case MDS_STATFS: - CDEBUG(D_INODE, "statfs\n"); - DEBUG_REQ(D_INODE, req, "statfs"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_STATFS_NET, 0); -- rc = mds_statfs(req); -- break; -- -- case MDS_READPAGE: - CDEBUG(D_INODE, "readpage\n"); - DEBUG_REQ(D_INODE, req, "readpage\n"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_READPAGE_NET, 0); -- rc = mds_readpage(req); -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SENDPAGE)) -- return 0; -- break; -- -- case MDS_REINT: { -- int size = sizeof(struct mds_body); - CDEBUG(D_INODE, "reint\n"); - int opc = *(u32 *)lustre_msg_buf(req->rq_reqmsg, 0), - realopc = opc & REINT_OPCODE_MASK; - - DEBUG_REQ(D_INODE, req, "reint (%s%s)", - reint_names[realopc], - opc & REINT_REPLAYING ? "|REPLAYING" : ""); - -- OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, -- &req->rq_repmsg); -- if (rc) { -- req->rq_status = rc; -- break; -- } - rc = mds_reint(0, req); - rc = mds_reint(req, 0); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_REINT_NET_REP, 0); -- break; -- } -- -- case MDS_OPEN: - CDEBUG(D_INODE, "open\n"); - DEBUG_REQ(D_INODE, req, "open"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_OPEN_NET, 0); -- rc = mds_open(req); -- break; -- -- case MDS_CLOSE: - CDEBUG(D_INODE, "close\n"); - DEBUG_REQ(D_INODE, req, "close"); -- OBD_FAIL_RETURN(OBD_FAIL_MDS_CLOSE_NET, 0); -- rc = mds_close(req); -- break; -- -- case LDLM_ENQUEUE: - CDEBUG(D_INODE, "enqueue\n"); - DEBUG_REQ(D_INODE, req, "enqueue"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0); -- rc = ldlm_handle_enqueue(req); -- break; -- case LDLM_CONVERT: - CDEBUG(D_INODE, "convert\n"); - DEBUG_REQ(D_INODE, req, "convert"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_CONVERT, 0); -- rc = ldlm_handle_convert(req); -- break; -- case LDLM_BL_CALLBACK: -- case LDLM_CP_CALLBACK: - CDEBUG(D_INODE, "callback\n"); - DEBUG_REQ(D_INODE, req, "callback"); -- CERROR("callbacks should not happen on MDS\n"); -- LBUG(); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); -- break; -- default: -- rc = ptlrpc_error(req->rq_svc, req); -- RETURN(rc); -- } -- -- EXIT; -- -- if (!rc) { -- struct mds_export_data *med = &req->rq_export->exp_mds_data; - struct mds_obd *mds = mds_req2mds(req); -- -- req->rq_repmsg->last_xid = -- HTON__u64(le64_to_cpu(med->med_mcd->mcd_last_xid)); -- req->rq_repmsg->last_committed = -- HTON__u64(mds->mds_last_committed); -- CDEBUG(D_INFO, "last_rcvd ~%Lu, last_committed %Lu, xid %d\n", -- (unsigned long long)mds->mds_last_rcvd, -- (unsigned long long)mds->mds_last_committed, -- cpu_to_le32(req->rq_xid)); -- } -- out: - if (rc) { - - if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) { - struct mds_obd *mds = mds_req2mds(req); - LASSERT(mds->mds_recoverable_clients); - DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply"); - return mds_queue_final_reply(req, rc); - } - - /* MDS_CONNECT / EALREADY (note: not -EALREADY!) isn't an error */ - if (rc && (req->rq_reqmsg->opc != MDS_CONNECT || - rc != EALREADY)) { -- CERROR("mds: processing error (opcode %d): %d\n", -- req->rq_reqmsg->opc, rc); -- ptlrpc_error(req->rq_svc, req); -- } else { -- CDEBUG(D_NET, "sending reply\n"); -- ptlrpc_reply(req->rq_svc, req); -- } -- return 0; --} -- --/* Update the server data on disk. This stores the new mount_count and -- * also the last_rcvd value to disk. If we don't have a clean shutdown, -- * then the server last_rcvd value may be less than that of the clients. -- * This will alert us that we may need to do client recovery. -- * -- * Assumes we are already in the server filesystem context. -- * -- * Also assumes for mds_last_rcvd that we are not modifying it (no locking). -- */ - static --int mds_update_server_data(struct mds_obd *mds) --{ -- struct mds_server_data *msd = mds->mds_server_data; -- struct file *filp = mds->mds_rcvd_filp; -- loff_t off = 0; -- int rc; -- -- msd->msd_last_rcvd = cpu_to_le64(mds->mds_last_rcvd); -- msd->msd_mount_count = cpu_to_le64(mds->mds_mount_count); -- -- CDEBUG(D_SUPER, "MDS mount_count is %Lu, last_rcvd is %Lu\n", -- (unsigned long long)mds->mds_mount_count, -- (unsigned long long)mds->mds_last_rcvd); -- rc = lustre_fwrite(filp, (char *)msd, sizeof(*msd), &off); -- if (rc != sizeof(*msd)) { -- CERROR("error writing MDS server data: rc = %d\n", rc); -- if (rc > 0) -- RETURN(-EIO); -- RETURN(rc); -- } --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- rc = fsync_dev(filp->f_dentry->d_inode->i_rdev); --#else -- rc = file_fsync(filp, filp->f_dentry, 1); --#endif -- if (rc) -- CERROR("error flushing MDS server data: rc = %d\n", rc); -- -- return 0; --} -- --/* Do recovery actions for the MDS */ - static int mds_recover(struct obd_device *obddev) -static int mds_recovery_complete(struct obd_device *obddev) --{ -- struct mds_obd *mds = &obddev->u.mds; -- struct obd_run_ctxt saved; -- int rc; - - LASSERT(mds->mds_recoverable_clients == 0); -- -- /* This happens at the end when recovery is complete */ -- ++mds->mds_mount_count; -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- rc = mds_update_server_data(mds); - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- -- return rc; --} -- --/* mount the file system (secretly) */ --static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- struct obd_ioctl_data* data = buf; -- struct mds_obd *mds = &obddev->u.mds; -- struct vfsmount *mnt; -- int rc = 0; -- ENTRY; -- -- MOD_INC_USE_COUNT; --#ifdef CONFIG_DEV_RDONLY -- dev_clear_rdonly(2); --#endif -- if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) -- GOTO(err_dec, rc = -EINVAL); -- -- mds->mds_fstype = strdup(data->ioc_inlbuf2); -- -- mnt = do_kern_mount(mds->mds_fstype, 0, data->ioc_inlbuf1, NULL); -- if (IS_ERR(mnt)) { -- rc = PTR_ERR(mnt); -- CERROR("do_kern_mount failed: rc = %d\n", rc); -- GOTO(err_kfree, rc); -- } -- -- CERROR("%s: mnt is %p\n", data->ioc_inlbuf1, mnt); -- mds->mds_sb = mnt->mnt_root->d_inode->i_sb; -- if (!mds->mds_sb) -- GOTO(err_put, rc = -ENODEV); -- - spin_lock_init(&mds->mds_last_lock); - init_MUTEX(&mds->mds_transno_sem); -- mds->mds_max_mdsize = sizeof(struct lov_mds_md); -- rc = mds_fs_setup(obddev, mnt); -- if (rc) { -- CERROR("MDS filesystem method init failed: rc = %d\n", rc); -- GOTO(err_put, rc); -- } -- -- obddev->obd_namespace = -- ldlm_namespace_new("mds_server", LDLM_NAMESPACE_SERVER); -- if (obddev->obd_namespace == NULL) { -- mds_cleanup(obddev); -- GOTO(err_fs, rc = -ENOMEM); -- } - - - rc = mds_recover(obddev); - if (rc) - GOTO(err_fs, rc); -- -- ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, -- "mds_ldlm_client", &obddev->obd_ldlm_client); -- - spin_lock_init(&mds->mds_processing_task_lock); - mds->mds_processing_task = 0; - INIT_LIST_HEAD(&mds->mds_recovery_queue); - INIT_LIST_HEAD(&mds->mds_delayed_reply_queue); - -- RETURN(0); -- --err_fs: -- mds_fs_cleanup(obddev); --err_put: -- unlock_kernel(); -- mntput(mds->mds_vfsmnt); -- mds->mds_sb = 0; -- lock_kernel(); --err_kfree: -- kfree(mds->mds_fstype); --err_dec: -- MOD_DEC_USE_COUNT; -- RETURN(rc); --} -- --static int mds_cleanup(struct obd_device *obddev) --{ -- struct super_block *sb; -- struct mds_obd *mds = &obddev->u.mds; -- struct obd_run_ctxt saved; -- ENTRY; -- -- sb = mds->mds_sb; -- if (!mds->mds_sb) -- RETURN(0); -- -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- mds_update_server_data(mds); -- -- if (mds->mds_rcvd_filp) { -- int rc = filp_close(mds->mds_rcvd_filp, 0); -- mds->mds_rcvd_filp = NULL; -- -- if (rc) -- CERROR("last_rcvd file won't close, rc=%d\n", rc); -- } - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- -- unlock_kernel(); -- mntput(mds->mds_vfsmnt); -- mds->mds_sb = 0; -- kfree(mds->mds_fstype); -- -- ldlm_namespace_free(obddev->obd_namespace); -- -- lock_kernel(); --#ifdef CONFIG_DEV_RDONLY -- dev_clear_rdonly(2); --#endif -- mds_fs_cleanup(obddev); -- -- MOD_DEC_USE_COUNT; -- RETURN(0); --} -- --static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie, -- ldlm_mode_t mode, int flags, void *data) --{ -- struct ptlrpc_request *req = req_cookie; -- int rc = 0; -- ENTRY; -- -- if (!req_cookie) -- RETURN(0); -- -- if (req->rq_reqmsg->bufcount > 1) { -- /* an intent needs to be considered */ -- struct ldlm_intent *it = lustre_msg_buf(req->rq_reqmsg, 1); -- struct mds_obd *mds= &req->rq_export->exp_obd->u.mds; -- struct mds_body *mds_rep; -- struct ldlm_reply *rep; -- __u64 new_resid[3] = {0, 0, 0}, old_res; -- int rc, size[3] = {sizeof(struct ldlm_reply), -- sizeof(struct mds_body), -- mds->mds_max_mdsize}; -- -- it->opc = NTOH__u64(it->opc); -- -- LDLM_DEBUG(lock, "intent policy, opc: %s", -- ldlm_it2str(it->opc)); -- -- rc = lustre_pack_msg(3, size, NULL, &req->rq_replen, -- &req->rq_repmsg); -- if (rc) { -- rc = req->rq_status = -ENOMEM; -- RETURN(rc); -- } -- -- rep = lustre_msg_buf(req->rq_repmsg, 0); -- rep->lock_policy_res1 = 1; -- -- /* execute policy */ -- switch ((long)it->opc) { -- case IT_CREAT|IT_OPEN: - rc = mds_reint(2, req); - rc = mds_reint(req, 2); -- if (rc || (req->rq_status != 0 && -- req->rq_status != -EEXIST)) { -- rep->lock_policy_res2 = req->rq_status; -- RETURN(ELDLM_LOCK_ABORTED); -- } -- break; -- case IT_CREAT: -- case IT_MKDIR: -- case IT_MKNOD: -- case IT_RENAME2: -- case IT_LINK2: -- case IT_RMDIR: -- case IT_SYMLINK: -- case IT_UNLINK: - rc = mds_reint(2, req); - rc = mds_reint(req, 2); -- if (rc || (req->rq_status != 0 && -- req->rq_status != -EISDIR && -- req->rq_status != -ENOTDIR)) { -- rep->lock_policy_res2 = req->rq_status; -- RETURN(ELDLM_LOCK_ABORTED); -- } -- break; -- case IT_GETATTR: -- case IT_LOOKUP: -- case IT_OPEN: -- case IT_READDIR: -- case IT_READLINK: -- case IT_RENAME: -- case IT_LINK: -- case IT_SETATTR: -- rc = mds_getattr_name(2, req); -- /* FIXME: we need to sit down and decide on who should -- * set req->rq_status, who should return negative and -- * positive return values, and what they all mean. */ -- if (rc || req->rq_status != 0) { -- rep->lock_policy_res2 = req->rq_status; -- RETURN(ELDLM_LOCK_ABORTED); -- } -- break; -- case IT_READDIR|IT_OPEN: -- LBUG(); -- break; -- default: -- CERROR("Unhandled intent "LPD64"\n", it->opc); -- LBUG(); -- } -- -- /* We don't bother returning a lock to the client for a file -- * or directory we are removing. -- * -- * As for link and rename, there is no reason for the client -- * to get a lock on the target at this point. If they are -- * going to modify the file/directory later they will get a -- * lock at that time. -- */ -- if (it->opc & (IT_UNLINK | IT_RMDIR | IT_LINK | IT_LINK2 | -- IT_RENAME | IT_RENAME2)) -- RETURN(ELDLM_LOCK_ABORTED); -- -- rep->lock_policy_res2 = req->rq_status; -- mds_rep = lustre_msg_buf(req->rq_repmsg, 1); -- -- /* If the client is about to open a file that doesn't have an MD -- * stripe record, it's going to need a write lock. */ - if (it->opc & IT_OPEN) { - struct lov_mds_md *lmm = - lustre_msg_buf(req->rq_repmsg, 2); - if (lmm->lmm_easize == 0) { - LDLM_DEBUG(lock, "open with no EA; returning PW" - " lock"); - lock->l_req_mode = LCK_PW; - } - if (it->opc & IT_OPEN && !(mds_rep->valid & OBD_MD_FLEASIZE)) { - LDLM_DEBUG(lock, "open with no EA; returning PW lock"); - lock->l_req_mode = LCK_PW; -- } -- -- if (flags & LDLM_FL_INTENT_ONLY) { -- LDLM_DEBUG(lock, "INTENT_ONLY, aborting lock"); -- RETURN(ELDLM_LOCK_ABORTED); -- } -- /* Give the client a lock on the child object, instead of the -- * parent that it requested. */ -- new_resid[0] = NTOH__u32(mds_rep->ino); -- new_resid[1] = NTOH__u32(mds_rep->generation); -- if (new_resid[0] == 0) -- LBUG(); -- old_res = lock->l_resource->lr_name[0]; -- -- ldlm_lock_change_resource(lock, new_resid); -- if (lock->l_resource == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- LDLM_DEBUG(lock, "intent policy, old res %ld", -- (long)old_res); -- RETURN(ELDLM_LOCK_CHANGED); -- } else { -- int size = sizeof(struct ldlm_reply); -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, -- &req->rq_repmsg); -- if (rc) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- } -- RETURN(rc); --} -- --int mds_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- --int mds_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); --} -- --static int mdt_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- int i; -- // struct obd_ioctl_data* data = buf; -- struct mds_obd *mds = &obddev->u.mds; -- int rc = 0; -- ENTRY; -- -- MOD_INC_USE_COUNT; -- -- mds->mds_service = ptlrpc_init_svc(MDS_NEVENTS, MDS_NBUFS, -- MDS_BUFSIZE, MDS_MAXREQSIZE, -- MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, -- "self", mds_handle, "mds"); -- if (!mds->mds_service) { -- CERROR("failed to start service\n"); - GOTO(err_dec, rc = -EINVAL); - GOTO(err_dec, rc = -ENOMEM); -- } -- -- for (i = 0; i < MDT_NUM_THREADS; i++) { -- char name[32]; -- sprintf(name, "ll_mdt_%02d", i); -- rc = ptlrpc_start_thread(obddev, mds->mds_service, name); -- if (rc) { -- CERROR("cannot start MDT thread #%d: rc %d\n", i, rc); -- GOTO(err_thread, rc); -- } -- } -- -- RETURN(0); -- --err_thread: -- ptlrpc_stop_all_threads(mds->mds_service); -- ptlrpc_unregister_service(mds->mds_service); --err_dec: -- MOD_DEC_USE_COUNT; -- RETURN(rc); --} -- -- --static int mdt_cleanup(struct obd_device *obddev) --{ -- struct mds_obd *mds = &obddev->u.mds; -- ENTRY; -- -- ptlrpc_stop_all_threads(mds->mds_service); -- ptlrpc_unregister_service(mds->mds_service); -- -- MOD_DEC_USE_COUNT; -- RETURN(0); --} -- - extern int mds_iocontrol(long cmd, struct lustre_handle *conn, -extern int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn, -- int len, void *karg, void *uarg); -- --/* use obd ops to offer management infrastructure */ --static struct obd_ops mds_obd_ops = { -- o_attach: mds_attach, -- o_detach: mds_detach, -- o_connect: mds_connect, -- o_disconnect: mds_disconnect, -- o_setup: mds_setup, -- o_cleanup: mds_cleanup, -- o_iocontrol: mds_iocontrol --}; -- --static struct obd_ops mdt_obd_ops = { -- o_setup: mdt_setup, -- o_cleanup: mdt_cleanup, --}; -- -- --static int __init mds_init(void) --{ -- -- mds_file_cache = kmem_cache_create("ll_mds_file_data", -- sizeof(struct mds_file_data), -- 0, 0, NULL, NULL); -- if (mds_file_cache == NULL) -- return -ENOMEM; -- -- class_register_type(&mds_obd_ops, status_class_var, LUSTRE_MDS_NAME); -- class_register_type(&mdt_obd_ops, 0, LUSTRE_MDT_NAME); -- ldlm_register_intent(ldlm_intent_policy); -- return 0; -- --} -- --static void __exit mds_exit(void) --{ -- -- -- ldlm_unregister_intent(); -- class_unregister_type(LUSTRE_MDS_NAME); -- class_unregister_type(LUSTRE_MDT_NAME); -- if (kmem_cache_destroy(mds_file_cache)) -- CERROR("couldn't free MDS file cache\n"); -- --} -- --MODULE_AUTHOR("Cluster File Systems "); --MODULE_DESCRIPTION("Lustre Metadata Server (MDS) v0.01"); --MODULE_LICENSE("GPL"); -- --module_init(mds_init); --module_exit(mds_exit); diff --cc lustre/mds/lproc_mds.c index 0fc96bd,0fc96bd..0000000 deleted file mode 100644,100644 --- a/lustre/mds/lproc_mds.c +++ /dev/null @@@ -1,183 -1,183 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- int len = 0; -- len += snprintf(page, count, "%s\n", temp->obd_uuid); -- return len; --} --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- struct statfs mystats; -- int rc, len = 0; -- -- rc = vfs_statfs(mds->mds_sb, &mystats); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- return 0; -- } -- len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_bsize)); -- return len; -- --} --int rd_kbtotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- struct statfs mystats; -- int rc, len = 0; -- __u32 blk_size; -- __u64 result; -- -- rc = vfs_statfs(mds->mds_sb, &mystats); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- return 0; -- } -- -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_blocks; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len += snprintf(page, count, LPU64"\n", result); -- return len; -- --} -- --int rd_kbfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- struct statfs mystats; -- int rc, len = 0; -- __u32 blk_size; -- __u64 result; -- -- -- rc = vfs_statfs(mds->mds_sb, &mystats); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- return 0; -- } -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_blocks; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len += snprintf(page, count, LPU64"\n", result); -- return len; -- --} -- --int rd_fstype(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- int len = 0; -- len += snprintf(page, count, "%s\n", mds->mds_fstype); -- return len; -- --} -- --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- struct statfs mystats; -- int rc, len = 0; -- -- rc = vfs_statfs(mds->mds_sb, &mystats); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- return 0; -- } -- -- len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_files)); -- return len; -- -- --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct mds_obd *mds = &temp->u.mds; -- struct statfs mystats; -- int rc, len = 0; -- -- rc = vfs_statfs(mds->mds_sb, &mystats); -- if (rc) { -- CERROR("mds: statfs failed: rc %d\n", rc); -- return 0; -- } -- -- len += snprintf(page, count, LPU64"\n", (__u64)(mystats.f_ffree)); -- return len; --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --struct lprocfs_vars status_var_nm_1[]={ -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytestotal",rd_kbtotal, 0, 0}, -- {"status/kbytesfree", rd_kbfree, 0, 0}, -- {"status/fstype", rd_fstype, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[]={ -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/mds/mds_ext2.c index ef1d8e5,ef1d8e5..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_ext2.c +++ /dev/null @@@ -1,145 -1,145 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/mds/mds_null.c -- * -- * Lustre Metadata Server (mds) journal abstraction routines -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * author: Andreas Dilger -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- */ -- --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include -- --static void *mds_ext2_start(struct inode *inode, int nblocks) --{ -- return (void *)1; --} -- --static int mds_ext2_stop(struct inode *inode, void *handle) --{ -- return 0; --} -- --static int mds_ext2_setattr(struct dentry *dentry, void *handle, -- struct iattr *iattr) --{ -- struct inode *inode = dentry->d_inode; -- -- lock_kernel(); -- -- /* a _really_ horrible hack to avoid removing the data stored -- in the block pointers; this data is the object id -- this will go into an extended attribute at some point. -- */ -- if (iattr->ia_valid & ATTR_SIZE) { -- /* ATTR_SIZE would invoke truncate: clear it */ -- iattr->ia_valid &= ~ATTR_SIZE; -- inode->i_size = iattr->ia_size; -- -- /* make sure _something_ gets set - so new inode -- goes to disk (probably won't work over XFS */ -- if (!iattr->ia_valid & ATTR_MODE) { -- iattr->ia_valid |= ATTR_MODE; -- iattr->ia_mode = inode->i_mode; -- } -- } -- -- if (inode->i_op->setattr) -- rc = inode->i_op->setattr(dentry, iattr); -- else -- rc = inode_setattr(inode, iattr); -- -- unlock_kernel(); -- -- return rc; --} -- --/* -- * FIXME: nasty hack - store the object id in the first two -- * direct block spots. This should be done with EAs... -- */ --static int mds_ext2_set_objid(struct inode *inode, void *handle, obd_id id) --{ -- (__u64)(inode->u.ext2_i.i_data[0]) = cpu_to_le64(id); -- return 0; --} -- --static int mds_ext2_get_objid(struct inode *inode, obd_id *id) --{ -- *id = le64_to_cpu(inode->u.ext2_i.i_data[0]); -- -- return 0; --} -- --static ssize_t mds_ext2_readpage(struct file *file, char *buf, size_t count, -- loff_t *offset) --{ -- if (S_ISREG(file->f_dentry->d_inode->i_mode)) -- return file->f_op->read(file, buf, count, offset); -- else -- return generic_file_read(file, buf, count, offset); --} -- --static struct mds_fs_operations mds_ext2_fs_ops; -- --static void mds_ext2_delete_inode(struct inode *inode) --{ -- if (S_ISREG(inode->i_mode)) -- mds_ext2_set_objid(inode, NULL, 0); -- -- mds_ext2_fs_ops.cl_delete_inode(inode); --} -- --static int mds_ext2_set_last_rcvd(struct mds_obd *mds, void *handle) --{ -- /* Bail for ext2 - can't tell when it is on disk anyways, sync? */ -- mds->mds_last_committed = mds->mds_last_rcvd; -- -- return 0; --} -- --static int mds_ext2_journal_data(struct file *filp) --{ -- return 0; --} -- --static struct mds_fs_operations mds_ext2_fs_ops = { -- fs_owner: THIS_MODULE, -- fs_start: mds_ext2_start, -- fs_commit: mds_ext2_stop, -- fs_setattr: mds_ext2_setattr, -- fs_set_objid: mds_ext2_set_objid, -- fs_get_objid: mds_ext2_get_objid, -- fs_readpage: mds_ext2_readpage, -- fs_delete_inode: mds_ext2_delete_inode, -- cl_delete_inode: clear_inode, -- fs_journal_data: mds_ext2_journal_data, -- fs_set_last_rcvd: mds_ext2_set_last_rcvd, --}; -- --static int __init mds_ext2_init(void) --{ -- return mds_register_fs_type(&mds_ext2_fs_ops, "ext2"); --} -- --static void __exit mds_ext2_exit(void) --{ -- mds_unregister_fs_type("ext2"); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre MDS ext2 Filesystem Helper v0.1"); --MODULE_LICENSE("GPL"); -- --module_init(mds_ext2_init); --module_exit(mds_ext2_exit); diff --cc lustre/mds/mds_ext3.c index 4f98f44,4fb5756..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_ext3.c +++ /dev/null @@@ -1,362 -1,357 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lustre/mds/mds_ext3.c -- * Lustre Metadata Server (mds) journal abstraction routines -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Andreas Dilger -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include --#include <../fs/ext3/xattr.h> --#include --#include --#include --#include - #include -- --static struct mds_fs_operations mds_ext3_fs_ops; --static kmem_cache_t *mcb_cache; --static int mcb_cache_count; -- --struct mds_cb_data { -- struct journal_callback cb_jcb; -- struct mds_obd *cb_mds; -- __u64 cb_last_rcvd; --}; -- --#define EXT3_XATTR_INDEX_LUSTRE 5 --#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - - #define XATTR_MDS_MO_MAGIC 0xEA0BD047 -- --/* -- * We don't currently need any additional blocks for rmdir and -- * unlink transactions because we are storing the OST oa_id inside -- * the inode (which we will be changing anyways as part of this -- * transaction). -- */ --static void *mds_ext3_start(struct inode *inode, int op) --{ -- /* For updates to the last recieved file */ -- int nblocks = EXT3_DATA_TRANS_BLOCKS; -- void *handle; -- -- switch(op) { -- case MDS_FSOP_RMDIR: -- case MDS_FSOP_UNLINK: -- nblocks += EXT3_DELETE_TRANS_BLOCKS; -- break; -- case MDS_FSOP_RENAME: -- /* We may be modifying two directories */ -- nblocks += EXT3_DATA_TRANS_BLOCKS; -- case MDS_FSOP_SYMLINK: -- /* Possible new block + block bitmap + GDT for long symlink */ -- nblocks += 3; -- case MDS_FSOP_CREATE: -- case MDS_FSOP_MKDIR: -- case MDS_FSOP_MKNOD: -- /* New inode + block bitmap + GDT for new file */ -- nblocks += 3; -- case MDS_FSOP_LINK: -- /* Change parent directory */ -- nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; -- break; -- case MDS_FSOP_SETATTR: -- /* Setattr on inode */ -- nblocks += 1; -- break; -- default: CERROR("unknown transaction start op %d\n", op); -- LBUG(); -- } -- -- lock_kernel(); -- handle = journal_start(EXT3_JOURNAL(inode), nblocks); -- unlock_kernel(); -- -- return handle; --} -- --static int mds_ext3_commit(struct inode *inode, void *handle) --{ -- int rc; -- -- lock_kernel(); -- rc = journal_stop((handle_t *)handle); -- unlock_kernel(); -- -- return rc; --} -- --static int mds_ext3_setattr(struct dentry *dentry, void *handle, -- struct iattr *iattr) --{ -- struct inode *inode = dentry->d_inode; -- int rc; -- -- lock_kernel(); -- if (inode->i_op->setattr) -- rc = inode->i_op->setattr(dentry, iattr); -- else -- rc = inode_setattr(inode, iattr); -- -- unlock_kernel(); -- -- return rc; --} -- --static int mds_ext3_set_md(struct inode *inode, void *handle, - struct lov_mds_md *lmm) - struct lov_mds_md *lmm, int lmm_size) --{ -- int rc; -- -- down(&inode->i_sem); -- lock_kernel(); -- rc = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, - lmm ? lmm->lmm_easize : 0, 0); - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); -- unlock_kernel(); -- up(&inode->i_sem); -- -- if (rc) { -- CERROR("error adding objectid "LPX64" to inode %ld: %d\n", -- lmm->lmm_object_id, inode->i_ino, rc); -- if (rc != -ENOSPC) LBUG(); -- } -- return rc; --} -- - static int mds_ext3_get_md(struct inode *inode, struct lov_mds_md *lmm) -static int mds_ext3_get_md(struct inode *inode, struct lov_mds_md *lmm,int size) --{ -- int rc; - int size = lmm->lmm_easize; -- -- down(&inode->i_sem); -- lock_kernel(); -- rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_LUSTRE, -- XATTR_LUSTRE_MDS_OBJID, lmm, size); -- unlock_kernel(); -- up(&inode->i_sem); -- -- /* This gives us the MD size */ -- if (lmm == NULL) - return rc; - return (rc == -ENODATA) ? 0 : rc; -- -- if (rc < 0) { -- CDEBUG(D_INFO, "error getting EA %s from MDS inode %ld: " -- "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); -- memset(lmm, 0, size); - return rc; - return (rc == -ENODATA) ? 0 : rc; -- } -- -- /* This field is byteswapped because it appears in the -- * catalogue. All others are opaque to the MDS */ -- lmm->lmm_object_id = le64_to_cpu(lmm->lmm_object_id); -- -- return rc; --} -- --static ssize_t mds_ext3_readpage(struct file *file, char *buf, size_t count, -- loff_t *offset) --{ -- struct inode *inode = file->f_dentry->d_inode; -- int rc = 0; -- -- if (S_ISREG(inode->i_mode)) -- rc = file->f_op->read(file, buf, count, offset); -- else { -- struct buffer_head *bh; -- -- /* FIXME: this assumes the blocksize == count, but the calling -- * function will detect this as an error for now */ -- bh = ext3_bread(NULL, inode, -- *offset >> inode->i_sb->s_blocksize_bits, -- 0, &rc); -- -- if (bh) { -- memcpy(buf, bh->b_data, inode->i_blksize); -- brelse(bh); -- rc = inode->i_blksize; -- } -- } -- -- return rc; --} -- --static void mds_ext3_delete_inode(struct inode *inode) --{ -- if (S_ISREG(inode->i_mode)) { -- void *handle = mds_ext3_start(inode, MDS_FSOP_UNLINK); -- -- if (IS_ERR(handle)) { -- CERROR("unable to start transaction"); -- EXIT; -- return; -- } - if (mds_ext3_set_md(inode, handle, NULL)) - if (mds_ext3_set_md(inode, handle, NULL, 0)) -- CERROR("error clearing objid on %ld\n", inode->i_ino); -- -- if (mds_ext3_fs_ops.cl_delete_inode) -- mds_ext3_fs_ops.cl_delete_inode(inode); -- -- if (mds_ext3_commit(inode, handle)) -- CERROR("error closing handle on %ld\n", inode->i_ino); -- } else -- mds_ext3_fs_ops.cl_delete_inode(inode); --} -- --static void mds_ext3_callback_status(struct journal_callback *jcb, int error) --{ -- struct mds_cb_data *mcb = (struct mds_cb_data *)jcb; -- -- CDEBUG(D_EXT2, "got callback for last_rcvd "LPD64": rc = %d\n", -- mcb->cb_last_rcvd, error); -- if (!error && mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed) -- mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd; -- -- kmem_cache_free(mcb_cache, mcb); -- --mcb_cache_count; --} -- --static int mds_ext3_set_last_rcvd(struct mds_obd *mds, void *handle) --{ -- struct mds_cb_data *mcb; -- -- mcb = kmem_cache_alloc(mcb_cache, GFP_NOFS); -- if (!mcb) -- RETURN(-ENOMEM); -- -- ++mcb_cache_count; -- mcb->cb_mds = mds; -- mcb->cb_last_rcvd = mds->mds_last_rcvd; -- --#ifdef HAVE_JOURNAL_CALLBACK_STATUS -- CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", -- mcb->cb_last_rcvd); -- lock_kernel(); -- /* Note that an "incompatible pointer" warning here is OK for now */ -- journal_callback_set(handle, mds_ext3_callback_status, -- (struct journal_callback *)mcb); -- unlock_kernel(); --#else --#warning "no journal callback kernel patch, faking it..." -- { -- static long next = 0; -- -- if (time_after(jiffies, next)) { -- CERROR("no journal callback kernel patch, faking it...\n"); -- next = jiffies + 300 * HZ; -- } -- -- mds_ext3_callback_status((struct journal_callback *)mcb, 0); --#endif -- -- return 0; --} -- --static int mds_ext3_journal_data(struct file *filp) --{ -- struct inode *inode = filp->f_dentry->d_inode; -- -- EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL; -- -- return 0; --} -- --/* -- * We need to hack the return value for the free inode counts because -- * the current EA code requires one filesystem block per inode with EAs, -- * so it is possible to run out of blocks before we run out of inodes. -- * -- * This can be removed when the ext3 EA code is fixed. -- */ --static int mds_ext3_statfs(struct super_block *sb, struct statfs *sfs) --{ -- int rc = vfs_statfs(sb, sfs); -- -- if (!rc && sfs->f_bfree < sfs->f_ffree) -- sfs->f_ffree = sfs->f_bfree; -- -- return rc; --} -- --static struct mds_fs_operations mds_ext3_fs_ops = { -- fs_owner: THIS_MODULE, -- fs_start: mds_ext3_start, -- fs_commit: mds_ext3_commit, -- fs_setattr: mds_ext3_setattr, -- fs_set_md: mds_ext3_set_md, -- fs_get_md: mds_ext3_get_md, -- fs_readpage: mds_ext3_readpage, -- fs_delete_inode: mds_ext3_delete_inode, -- cl_delete_inode: clear_inode, -- fs_journal_data: mds_ext3_journal_data, -- fs_set_last_rcvd: mds_ext3_set_last_rcvd, -- fs_statfs: mds_ext3_statfs, --}; -- --static int __init mds_ext3_init(void) --{ -- int rc; -- -- //rc = ext3_xattr_register(); -- mcb_cache = kmem_cache_create("mds_ext3_mcb", -- sizeof(struct mds_cb_data), 0, -- 0, NULL, NULL); -- if (!mcb_cache) { -- CERROR("error allocating MDS journal callback cache\n"); -- GOTO(out, rc = -ENOMEM); -- } -- -- rc = mds_register_fs_type(&mds_ext3_fs_ops, "ext3"); -- -- if (rc) -- kmem_cache_destroy(mcb_cache); --out: -- return rc; --} -- --static void __exit mds_ext3_exit(void) --{ -- int rc; -- -- mds_unregister_fs_type("ext3"); -- rc = kmem_cache_destroy(mcb_cache); -- -- if (rc || mcb_cache_count) { -- CERROR("can't free MDS callback cache: count %d, rc = %d\n", -- mcb_cache_count, rc); -- } -- -- //rc = ext3_xattr_unregister(); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre MDS ext3 Filesystem Helper v0.1"); --MODULE_LICENSE("GPL"); -- --module_init(mds_ext3_init); --module_exit(mds_ext3_exit); diff --cc lustre/mds/mds_extN.c index 8ba7979,8368573..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_extN.c +++ /dev/null @@@ -1,361 -1,356 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * lustre/mds/mds_extN.c -- * Lustre Metadata Server (mds) journal abstraction routines -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Andreas Dilger -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include - #include -- --static struct mds_fs_operations mds_extN_fs_ops; --static kmem_cache_t *mcb_cache; --static int mcb_cache_count; -- --struct mds_cb_data { -- struct journal_callback cb_jcb; -- struct mds_obd *cb_mds; -- __u64 cb_last_rcvd; --}; -- --#define EXTN_XATTR_INDEX_LUSTRE 5 --#define XATTR_LUSTRE_MDS_OBJID "system.lustre_mds_objid" - - #define XATTR_MDS_MO_MAGIC 0xEA0BD047 -- --/* -- * We don't currently need any additional blocks for rmdir and -- * unlink transactions because we are storing the OST oa_id inside -- * the inode (which we will be changing anyways as part of this -- * transaction). -- */ --static void *mds_extN_start(struct inode *inode, int op) --{ -- /* For updates to the last recieved file */ -- int nblocks = EXTN_DATA_TRANS_BLOCKS; -- void *handle; -- -- switch(op) { -- case MDS_FSOP_RMDIR: -- case MDS_FSOP_UNLINK: -- nblocks += EXTN_DELETE_TRANS_BLOCKS; -- break; -- case MDS_FSOP_RENAME: -- /* We may be modifying two directories */ -- nblocks += EXTN_DATA_TRANS_BLOCKS; -- case MDS_FSOP_SYMLINK: -- /* Possible new block + block bitmap + GDT for long symlink */ -- nblocks += 3; -- case MDS_FSOP_CREATE: -- case MDS_FSOP_MKDIR: -- case MDS_FSOP_MKNOD: -- /* New inode + block bitmap + GDT for new file */ -- nblocks += 3; -- case MDS_FSOP_LINK: -- /* Change parent directory */ -- nblocks += EXTN_INDEX_EXTRA_TRANS_BLOCKS+EXTN_DATA_TRANS_BLOCKS; -- break; -- case MDS_FSOP_SETATTR: -- /* Setattr on inode */ -- nblocks += 1; -- break; -- default: CERROR("unknown transaction start op %d\n", op); -- LBUG(); -- } -- -- lock_kernel(); -- handle = journal_start(EXTN_JOURNAL(inode), nblocks); -- unlock_kernel(); -- -- return handle; --} -- --static int mds_extN_commit(struct inode *inode, void *handle) --{ -- int rc; -- -- lock_kernel(); -- rc = journal_stop((handle_t *)handle); -- unlock_kernel(); -- -- return rc; --} -- --static int mds_extN_setattr(struct dentry *dentry, void *handle, -- struct iattr *iattr) --{ -- struct inode *inode = dentry->d_inode; -- int rc; -- -- lock_kernel(); -- if (inode->i_op->setattr) -- rc = inode->i_op->setattr(dentry, iattr); -- else -- rc = inode_setattr(inode, iattr); -- -- unlock_kernel(); -- -- return rc; --} -- --static int mds_extN_set_md(struct inode *inode, void *handle, - struct lov_mds_md *lmm) - struct lov_mds_md *lmm, int lmm_size) --{ -- int rc; -- -- down(&inode->i_sem); -- lock_kernel(); -- rc = extN_xattr_set(handle, inode, EXTN_XATTR_INDEX_LUSTRE, - XATTR_LUSTRE_MDS_OBJID, lmm, - lmm ? lmm->lmm_easize : 0, 0); - XATTR_LUSTRE_MDS_OBJID, lmm, lmm_size, 0); -- unlock_kernel(); -- up(&inode->i_sem); -- -- if (rc) { -- CERROR("error adding objectid "LPX64" to inode %ld: %d\n", -- lmm->lmm_object_id, inode->i_ino, rc); -- if (rc != -ENOSPC) LBUG(); -- } -- return rc; --} -- - static int mds_extN_get_md(struct inode *inode, struct lov_mds_md *lmm) -static int mds_extN_get_md(struct inode *inode, struct lov_mds_md *lmm,int size) --{ -- int rc; - int size = lmm->lmm_easize; -- -- down(&inode->i_sem); -- lock_kernel(); -- rc = extN_xattr_get(inode, EXTN_XATTR_INDEX_LUSTRE, -- XATTR_LUSTRE_MDS_OBJID, lmm, size); -- unlock_kernel(); -- up(&inode->i_sem); -- -- /* This gives us the MD size */ -- if (lmm == NULL) - return rc; - return (rc == -ENODATA) ? 0 : rc; -- -- if (rc < 0) { -- CDEBUG(D_INFO, "error getting EA %s from MDS inode %ld: " -- "rc = %d\n", XATTR_LUSTRE_MDS_OBJID, inode->i_ino, rc); -- memset(lmm, 0, size); - return rc; - return (rc == -ENODATA) ? 0 : rc; -- } -- -- /* This field is byteswapped because it appears in the -- * catalogue. All others are opaque to the MDS */ -- lmm->lmm_object_id = le64_to_cpu(lmm->lmm_object_id); -- -- return rc; --} -- --static ssize_t mds_extN_readpage(struct file *file, char *buf, size_t count, -- loff_t *offset) --{ -- struct inode *inode = file->f_dentry->d_inode; -- int rc = 0; -- -- if (S_ISREG(inode->i_mode)) -- rc = file->f_op->read(file, buf, count, offset); -- else { -- struct buffer_head *bh; -- -- /* FIXME: this assumes the blocksize == count, but the calling -- * function will detect this as an error for now */ -- bh = extN_bread(NULL, inode, -- *offset >> inode->i_sb->s_blocksize_bits, -- 0, &rc); -- -- if (bh) { -- memcpy(buf, bh->b_data, inode->i_blksize); -- brelse(bh); -- rc = inode->i_blksize; -- } -- } -- -- return rc; --} -- --static void mds_extN_delete_inode(struct inode *inode) --{ -- if (S_ISREG(inode->i_mode)) { -- void *handle = mds_extN_start(inode, MDS_FSOP_UNLINK); -- -- if (IS_ERR(handle)) { -- CERROR("unable to start transaction"); -- EXIT; -- return; -- } - if (mds_extN_set_md(inode, handle, NULL)) - if (mds_extN_set_md(inode, handle, NULL, 0)) -- CERROR("error clearing objid on %ld\n", inode->i_ino); -- -- if (mds_extN_fs_ops.cl_delete_inode) -- mds_extN_fs_ops.cl_delete_inode(inode); -- -- if (mds_extN_commit(inode, handle)) -- CERROR("error closing handle on %ld\n", inode->i_ino); -- } else -- mds_extN_fs_ops.cl_delete_inode(inode); --} -- --static void mds_extN_callback_status(struct journal_callback *jcb, int error) --{ -- struct mds_cb_data *mcb = (struct mds_cb_data *)jcb; -- -- CDEBUG(D_EXT2, "got callback for last_rcvd "LPD64": rc = %d\n", -- mcb->cb_last_rcvd, error); -- if (!error && mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed) -- mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd; -- -- kmem_cache_free(mcb_cache, mcb); -- --mcb_cache_count; --} -- --static int mds_extN_set_last_rcvd(struct mds_obd *mds, void *handle) --{ -- struct mds_cb_data *mcb; -- -- mcb = kmem_cache_alloc(mcb_cache, GFP_NOFS); -- if (!mcb) -- RETURN(-ENOMEM); -- -- ++mcb_cache_count; -- mcb->cb_mds = mds; -- mcb->cb_last_rcvd = mds->mds_last_rcvd; -- --#ifdef HAVE_JOURNAL_CALLBACK_STATUS -- CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", -- mcb->cb_last_rcvd); -- lock_kernel(); -- /* Note that an "incompatible pointer" warning here is OK for now */ -- journal_callback_set(handle, mds_extN_callback_status, -- (struct journal_callback *)mcb); -- unlock_kernel(); --#else --#warning "no journal callback kernel patch, faking it..." -- { -- static long next = 0; -- -- if (time_after(jiffies, next)) { -- CERROR("no journal callback kernel patch, faking it...\n"); -- next = jiffies + 300 * HZ; -- } -- -- mds_extN_callback_status((struct journal_callback *)mcb, 0); --#endif -- -- return 0; --} -- --static int mds_extN_journal_data(struct file *filp) --{ -- struct inode *inode = filp->f_dentry->d_inode; -- -- EXTN_I(inode)->i_flags |= EXTN_JOURNAL_DATA_FL; -- -- return 0; --} -- --/* -- * We need to hack the return value for the free inode counts because -- * the current EA code requires one filesystem block per inode with EAs, -- * so it is possible to run out of blocks before we run out of inodes. -- * -- * This can be removed when the extN EA code is fixed. -- */ --static int mds_extN_statfs(struct super_block *sb, struct statfs *sfs) --{ -- int rc = vfs_statfs(sb, sfs); -- -- if (!rc && sfs->f_bfree < sfs->f_ffree) -- sfs->f_ffree = sfs->f_bfree; -- -- return rc; --} -- --static struct mds_fs_operations mds_extN_fs_ops = { -- fs_owner: THIS_MODULE, -- fs_start: mds_extN_start, -- fs_commit: mds_extN_commit, -- fs_setattr: mds_extN_setattr, -- fs_set_md: mds_extN_set_md, -- fs_get_md: mds_extN_get_md, -- fs_readpage: mds_extN_readpage, -- fs_delete_inode: mds_extN_delete_inode, -- cl_delete_inode: clear_inode, -- fs_journal_data: mds_extN_journal_data, -- fs_set_last_rcvd: mds_extN_set_last_rcvd, -- fs_statfs: mds_extN_statfs, --}; -- --static int __init mds_extN_init(void) --{ -- int rc; -- -- //rc = extN_xattr_register(); -- mcb_cache = kmem_cache_create("mds_extN_mcb", -- sizeof(struct mds_cb_data), 0, -- 0, NULL, NULL); -- if (!mcb_cache) { -- CERROR("error allocating MDS journal callback cache\n"); -- GOTO(out, rc = -ENOMEM); -- } -- -- rc = mds_register_fs_type(&mds_extN_fs_ops, "extN"); -- -- if (rc) -- kmem_cache_destroy(mcb_cache); --out: -- return rc; --} -- --static void __exit mds_extN_exit(void) --{ -- int rc; -- -- mds_unregister_fs_type("extN"); -- rc = kmem_cache_destroy(mcb_cache); -- -- if (rc || mcb_cache_count) { -- CERROR("can't free MDS callback cache: count %d, rc = %d\n", -- mcb_cache_count, rc); -- } -- -- //rc = extN_xattr_unregister(); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre MDS extN Filesystem Helper v0.1"); --MODULE_LICENSE("GPL"); -- --module_init(mds_extN_init); --module_exit(mds_extN_exit); diff --cc lustre/mds/mds_fs.c index 3975f4f,163a45f..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_fs.c +++ /dev/null @@@ -1,461 -1,513 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/mds/mds_fs.c -- * -- * Lustre Metadata Server (MDS) filesystem interface code -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Andreas Dilger -- * -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include -- --LIST_HEAD(mds_fs_types); -- --struct mds_fs_type { -- struct list_head mft_list; -- struct mds_fs_operations *mft_ops; -- char *mft_name; --}; -- - #define MDS_MAX_CLIENTS 1024 -/* This limit is arbitrary, but for now we fit it in 1 page (32k clients) */ -#define MDS_MAX_CLIENTS (PAGE_SIZE * 8) --#define MDS_MAX_CLIENT_WORDS (MDS_MAX_CLIENTS / sizeof(unsigned long)) -- --static unsigned long last_rcvd_slots[MDS_MAX_CLIENT_WORDS]; - -#define LAST_RCVD "last_rcvd" -- --/* Add client data to the MDS. We use a bitmap to locate a free space -- * in the last_rcvd file if cl_off is -1 (i.e. a new client). -- * Otherwise, we have just read the data from the last_rcvd file and -- * we know its offset. -- */ - int mds_client_add(struct mds_export_data *med, int cl_off) -int mds_client_add(struct mds_obd *mds, struct mds_export_data *med, int cl_off) --{ - int new_client = (cl_off == -1); - -- /* the bitmap operations can handle cl_off > sizeof(long) * 8, so -- * there's no need for extra complication here -- */ - if (cl_off == -1) { - if (new_client) { -- cl_off = find_first_zero_bit(last_rcvd_slots, MDS_MAX_CLIENTS); -- repeat: -- if (cl_off >= MDS_MAX_CLIENTS) { -- CERROR("no room for clients - fix MDS_MAX_CLIENTS\n"); -- return -ENOMEM; -- } -- if (test_and_set_bit(cl_off, last_rcvd_slots)) { -- CERROR("MDS client %d: found bit is set in bitmap\n", -- cl_off); -- cl_off = find_next_zero_bit(last_rcvd_slots, -- MDS_MAX_CLIENTS, cl_off); -- goto repeat; -- } -- } else { -- if (test_and_set_bit(cl_off, last_rcvd_slots)) { -- CERROR("MDS client %d: bit already set in bitmap!!\n", -- cl_off); -- LBUG(); -- } -- } -- -- CDEBUG(D_INFO, "client at offset %d with UUID '%s' added\n", -- cl_off, med->med_mcd->mcd_uuid); -- -- med->med_off = cl_off; - - if (new_client) { - struct obd_run_ctxt saved; - loff_t off = MDS_LR_CLIENT + (cl_off * MDS_LR_SIZE); - ssize_t written; - - push_ctxt(&saved, &mds->mds_ctxt, NULL); - written = lustre_fwrite(mds->mds_rcvd_filp, - (char *)med->med_mcd, - sizeof(*med->med_mcd), &off); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - if (written != sizeof(*med->med_mcd)) { - if (written < 0) - RETURN(written); - RETURN(-EIO); - } - } -- return 0; --} -- --int mds_client_free(struct obd_export *exp) --{ -- struct mds_export_data *med = &exp->exp_mds_data; - struct mds_obd *mds = &exp->exp_obd->u.mds; - struct mds_client_data zero_mcd; - struct obd_run_ctxt saved; - int written; - loff_t off; -- -- if (!med->med_mcd) -- RETURN(0); -- -- CDEBUG(D_INFO, "freeing client at offset %d with UUID '%s'\n", -- med->med_off, med->med_mcd->mcd_uuid); -- -- if (!test_and_clear_bit(med->med_off, last_rcvd_slots)) { -- CERROR("MDS client %d: bit already clear in bitmap!!\n", -- med->med_off); - LBUG(); - } - - off = med->med_off; - - memset(&zero_mcd, 0, sizeof zero_mcd); - push_ctxt(&saved, &mds->mds_ctxt, NULL); - written = lustre_fwrite(mds->mds_rcvd_filp, (const char *)&zero_mcd, - sizeof zero_mcd, &off); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); - - if (written != sizeof zero_mcd) { - CERROR("error zeroing out client %s off %d in %s: %d\n", - med->med_mcd->mcd_uuid, med->med_off, LAST_RCVD, - written); -- LBUG(); - } else { - CDEBUG(D_INFO, "zeroed out disconnecting client %s at off %d\n", - med->med_mcd->mcd_uuid, med->med_off); -- } -- -- OBD_FREE(med->med_mcd, sizeof(*med->med_mcd)); -- -- return 0; --} -- --static int mds_server_free_data(struct mds_obd *mds) --{ -- OBD_FREE(mds->mds_server_data, sizeof(*mds->mds_server_data)); -- mds->mds_server_data = NULL; -- -- return 0; --} - - #define LAST_RCVD "last_rcvd" -- --static int mds_read_last_rcvd(struct obd_device *obddev, struct file *f) --{ -- struct mds_obd *mds = &obddev->u.mds; -- struct mds_server_data *msd; -- struct mds_client_data *mcd = NULL; - loff_t fsize = f->f_dentry->d_inode->i_size; -- loff_t off = 0; -- int cl_off; - int max_off = f->f_dentry->d_inode->i_size / sizeof(*mcd); -- __u64 last_rcvd = 0; -- __u64 last_mount; - int clients = 0; -- int rc = 0; -- -- OBD_ALLOC(msd, sizeof(*msd)); -- if (!msd) -- RETURN(-ENOMEM); -- rc = lustre_fread(f, (char *)msd, sizeof(*msd), &off); -- -- mds->mds_server_data = msd; -- if (rc == 0) { -- CERROR("empty MDS %s, new MDS?\n", LAST_RCVD); -- RETURN(0); -- } -- -- if (rc != sizeof(*msd)) { -- CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD, rc); -- if (rc > 0) { -- rc = -EIO; -- } -- GOTO(err_msd, rc); -- } -- -- /* -- * When we do a clean MDS shutdown, we save the last_rcvd into -- * the header. If we find clients with higher last_rcvd values -- * then those clients may need recovery done. -- */ -- last_rcvd = le64_to_cpu(msd->msd_last_rcvd); -- mds->mds_last_rcvd = last_rcvd; -- CDEBUG(D_INODE, "got %Lu for server last_rcvd value\n", -- (unsigned long long)last_rcvd); -- -- last_mount = le64_to_cpu(msd->msd_mount_count); -- mds->mds_mount_count = last_mount; -- CDEBUG(D_INODE, "got %Lu for server last_mount value\n", -- (unsigned long long)last_mount); -- - for (off = MDS_LR_CLIENT, cl_off = 0, rc = sizeof(*mcd); - off <= fsize - sizeof(*mcd) && rc == sizeof(*mcd); - off = MDS_LR_CLIENT + ++cl_off * MDS_LR_SIZE) { - for (off = MDS_LR_CLIENT, cl_off = 0; - off < max_off; - off += MDS_LR_SIZE, cl_off++) { - int mount_age; - -- if (!mcd) { -- OBD_ALLOC(mcd, sizeof(*mcd)); -- if (!mcd) -- GOTO(err_msd, rc = -ENOMEM); -- } -- -- rc = lustre_fread(f, (char *)mcd, sizeof(*mcd), &off); -- if (rc != sizeof(*mcd)) { -- CERROR("error reading MDS %s offset %d: rc = %d\n", -- LAST_RCVD, cl_off, rc); -- if (rc > 0) -- rc = -EIO; -- break; - } - - if (mcd->mcd_uuid[0] == '\0') { - CDEBUG(D_INFO, "skipping zeroed client at offset %d\n", - cl_off); - continue; -- } -- -- last_rcvd = le64_to_cpu(mcd->mcd_last_rcvd); -- -- /* The exports are cleaned up by mds_disconnect, so they -- * need to be set up like real exports also. -- */ - if (last_rcvd && (last_mount - le64_to_cpu(mcd->mcd_mount_count) - < MDS_MOUNT_RECOV)) { - mount_age = last_mount - le64_to_cpu(mcd->mcd_mount_count); - if (last_rcvd && mount_age < MDS_MOUNT_RECOV) { -- struct obd_export *exp = class_new_export(obddev); -- struct mds_export_data *med; -- -- if (!exp) { -- rc = -ENOMEM; -- break; -- } -- -- med = &exp->exp_mds_data; -- med->med_mcd = mcd; - mds_client_add(med, cl_off); - mds_client_add(mds, med, cl_off); -- /* XXX put this in a helper if it gets more complex */ -- INIT_LIST_HEAD(&med->med_open_head); -- spin_lock_init(&med->med_open_lock); -- -- mcd = NULL; - clients++; - mds->mds_recoverable_clients++; -- MOD_INC_USE_COUNT; -- } else { -- CDEBUG(D_INFO, - "ignored client %d, UUID '%s', last_mount %Ld\n", - "discarded client %d, UUID '%s', count %Ld\n", -- cl_off, mcd->mcd_uuid, -- (long long)le64_to_cpu(mcd->mcd_mount_count)); -- } -- -- if (last_rcvd > mds->mds_last_rcvd) { -- CDEBUG(D_OTHER, -- "client at offset %d has last_rcvd = %Lu\n", -- cl_off, (unsigned long long)last_rcvd); -- mds->mds_last_rcvd = last_rcvd; -- } -- } - CDEBUG(D_INODE, "got %Lu for highest last_rcvd value, %d/%d clients\n", - (unsigned long long)mds->mds_last_rcvd, clients, cl_off); - - mds->mds_last_committed = mds->mds_last_rcvd; - if (mds->mds_recoverable_clients) { - CERROR("need recovery: %d recoverable clients, last_rcvd %Lu\n", - mds->mds_recoverable_clients, mds->mds_last_rcvd); - } -- -- if (mcd) -- OBD_FREE(mcd, sizeof(*mcd)); - - /* After recovery, there can be no local uncommitted transactions */ - mds->mds_last_committed = mds->mds_last_rcvd; -- -- return 0; -- --err_msd: -- mds_server_free_data(mds); -- return rc; --} -- --static int mds_fs_prep(struct obd_device *obddev) --{ -- struct mds_obd *mds = &obddev->u.mds; -- struct obd_run_ctxt saved; -- struct dentry *dentry; -- struct file *f; -- int rc; -- -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot create ROOT directory: rc = %d\n", rc); -- GOTO(err_pop, rc); -- } -- -- mds->mds_rootfid.id = dentry->d_inode->i_ino; -- mds->mds_rootfid.generation = dentry->d_inode->i_generation; -- mds->mds_rootfid.f_type = S_IFDIR; -- -- dput(dentry); -- -- dentry = simple_mkdir(current->fs->pwd, "FH", 0700); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot create FH directory: rc = %d\n", rc); -- GOTO(err_pop, rc); -- } -- /* XXX probably want to hold on to this later... */ -- dput(dentry); -- -- f = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0644); -- if (IS_ERR(f)) { -- rc = PTR_ERR(f); -- CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc); -- GOTO(err_pop, rc = PTR_ERR(f)); -- } -- if (!S_ISREG(f->f_dentry->d_inode->i_mode)) { -- CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD, -- f->f_dentry->d_inode->i_mode); -- GOTO(err_pop, rc = -ENOENT); -- } -- -- rc = mds_fs_journal_data(mds, f); -- if (rc) { -- CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc); -- GOTO(err_filp, rc); -- } -- -- rc = mds_read_last_rcvd(obddev, f); -- if (rc) { -- CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc); -- GOTO(err_client, rc); -- } -- mds->mds_rcvd_filp = f; --err_pop: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- -- return rc; -- --err_client: -- class_disconnect_all(obddev); --err_filp: -- if (filp_close(f, 0)) -- CERROR("can't close %s after error\n", LAST_RCVD); -- goto err_pop; --} -- --static struct mds_fs_operations *mds_search_fs_type(const char *name) --{ -- struct list_head *p; -- struct mds_fs_type *type; -- -- /* lock mds_fs_types list */ -- list_for_each(p, &mds_fs_types) { -- type = list_entry(p, struct mds_fs_type, mft_list); -- if (!strcmp(type->mft_name, name)) { -- /* unlock mds_fs_types list */ -- return type->mft_ops; -- } -- } -- /* unlock mds_fs_types list */ -- return NULL; --} -- --int mds_register_fs_type(struct mds_fs_operations *ops, const char *name) --{ -- struct mds_fs_operations *found; -- struct mds_fs_type *type; -- -- if ((found = mds_search_fs_type(name))) { -- if (found != ops) { -- CERROR("different operations for type %s\n", name); -- RETURN(-EEXIST); -- } -- return 0; -- } -- OBD_ALLOC(type, sizeof(*type)); -- if (!type) -- RETURN(-ENOMEM); -- -- INIT_LIST_HEAD(&type->mft_list); -- type->mft_ops = ops; -- type->mft_name = strdup(name); -- if (!type->mft_name) { -- OBD_FREE(type, sizeof(*type)); -- RETURN(-ENOMEM); -- } -- MOD_INC_USE_COUNT; -- list_add(&type->mft_list, &mds_fs_types); -- -- return 0; --} -- --void mds_unregister_fs_type(const char *name) --{ -- struct list_head *p; -- -- /* lock mds_fs_types list */ -- list_for_each(p, &mds_fs_types) { -- struct mds_fs_type *type; -- -- type = list_entry(p, struct mds_fs_type, mft_list); -- if (!strcmp(type->mft_name, name)) { -- list_del(p); -- kfree(type->mft_name); -- OBD_FREE(type, sizeof(*type)); -- MOD_DEC_USE_COUNT; -- break; -- } -- } -- /* unlock mds_fs_types list */ --} -- --struct mds_fs_operations *mds_fs_get_ops(char *fstype) --{ -- struct mds_fs_operations *fs_ops; -- -- if (!(fs_ops = mds_search_fs_type(fstype))) { -- char name[32]; -- int rc; -- -- snprintf(name, sizeof(name) - 1, "mds_%s", fstype); -- name[sizeof(name) - 1] = '\0'; -- -- if ((rc = request_module(name))) { -- fs_ops = mds_search_fs_type(fstype); -- CDEBUG(D_INFO, "Loaded module '%s'\n", name); -- if (!fs_ops) -- rc = -ENOENT; -- } -- -- if (rc) { -- CERROR("Can't find MDS fs interface '%s'\n", name); -- RETURN(ERR_PTR(rc)); -- } -- } -- __MOD_INC_USE_COUNT(fs_ops->fs_owner); -- -- return fs_ops; --} -- --void mds_fs_put_ops(struct mds_fs_operations *fs_ops) --{ -- __MOD_DEC_USE_COUNT(fs_ops->fs_owner); --} -- --int mds_fs_setup(struct obd_device *obddev, struct vfsmount *mnt) --{ -- struct mds_obd *mds = &obddev->u.mds; -- int rc; -- -- mds->mds_fsops = mds_fs_get_ops(mds->mds_fstype); -- if (IS_ERR(mds->mds_fsops)) -- RETURN(PTR_ERR(mds->mds_fsops)); -- -- mds->mds_vfsmnt = mnt; -- -- OBD_SET_CTXT_MAGIC(&mds->mds_ctxt); -- mds->mds_ctxt.pwdmnt = mnt; -- mds->mds_ctxt.pwd = mnt->mnt_root; -- mds->mds_ctxt.fs = get_ds(); -- -- /* -- * Replace the client filesystem delete_inode method with our own, -- * so that we can clear the object ID before the inode is deleted. -- * The fs_delete_inode method will call cl_delete_inode for us. -- * We need to do this for the MDS superblock only, hence we install -- * a modified copy of the original superblock method table. -- * -- * We still assume that there is only a single MDS client filesystem -- * type, as we don't have access to the mds struct in delete_inode -- * and store the client delete_inode method in a global table. This -- * will only become a problem if/when multiple MDSs are running on a -- * single host with different underlying filesystems. -- */ -- OBD_ALLOC(mds->mds_sop, sizeof(*mds->mds_sop)); -- if (!mds->mds_sop) -- GOTO(out_dec, rc = -ENOMEM); -- -- memcpy(mds->mds_sop, mds->mds_sb->s_op, sizeof(*mds->mds_sop)); -- mds->mds_fsops->cl_delete_inode = mds->mds_sop->delete_inode; -- mds->mds_sop->delete_inode = mds->mds_fsops->fs_delete_inode; -- mds->mds_sb->s_op = mds->mds_sop; -- -- rc = mds_fs_prep(obddev); -- -- if (rc) -- GOTO(out_free, rc); -- -- return 0; -- --out_free: -- OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); --out_dec: -- mds_fs_put_ops(mds->mds_fsops); -- return rc; --} -- --void mds_fs_cleanup(struct obd_device *obddev) --{ -- struct mds_obd *mds = &obddev->u.mds; -- -- class_disconnect_all(obddev); /* this cleans up client info too */ -- mds_server_free_data(mds); -- -- OBD_FREE(mds->mds_sop, sizeof(*mds->mds_sop)); -- mds_fs_put_ops(mds->mds_fsops); --} -- --EXPORT_SYMBOL(mds_register_fs_type); --EXPORT_SYMBOL(mds_unregister_fs_type); diff --cc lustre/mds/mds_lov.c index 9d49de1,ba9a750..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_lov.c +++ /dev/null @@@ -1,198 -1,211 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/mds/mds_lov.c -- * -- * Lustre Metadata Server (mds) handling of striped file data -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Peter Braam & -- * -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include - -/* lov_unpackdesc() is in lov/lov_pack.c */ - -void lov_packdesc(struct lov_desc *ld) -{ - ld->ld_tgt_count = HTON__u32(ld->ld_tgt_count); - ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count); - ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size); - ld->ld_pattern = HTON__u32(ld->ld_pattern); -} -- --int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc, -- obd_uuid_t *uuidarray) --{ -- struct mds_obd *mds = &obd->u.mds; -- struct obd_run_ctxt saved; -- struct file *f; -- int tgt_count; -- int rc; -- int i; - ENTRY; -- -- tgt_count = desc->ld_tgt_count; -- lov_packdesc(desc); -- -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644); -- if (IS_ERR(f)) { -- CERROR("Cannot open/create LOVDESC file\n"); -- GOTO(out, rc = PTR_ERR(f)); -- } -- -- rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &f->f_pos); -- if (filp_close(f, 0)) -- CERROR("Error closing LOVDESC file\n"); -- if (rc != sizeof(*desc)) { -- CERROR("Cannot open/create LOVDESC file\n"); -- GOTO(out, rc = PTR_ERR(f)); -- } -- -- f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644); -- if (IS_ERR(f)) { -- CERROR("Cannot open/create LOVTGTS file\n"); -- GOTO(out, rc = PTR_ERR(f)); -- } -- -- rc = 0; -- for (i = 0; i < tgt_count ; i++) { -- rc = lustre_fwrite(f, uuidarray[i], -- sizeof(uuidarray[i]), &f->f_pos); -- if (rc != sizeof(uuidarray[i])) { -- CERROR("cannot write LOV UUID %s (%d)\n", -- uuidarray[i], i); -- if (rc >= 0) -- rc = -EIO; -- break; -- } else -- rc = 0; -- } -- if (filp_close(f, 0)) -- CERROR("Error closing LOVTGTS file\n"); -- --out: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- RETURN(rc); --} -- --int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc) --{ -- struct obd_run_ctxt saved; -- struct file *f; -- int rc; - ENTRY; -- -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- f = filp_open("LOVDESC", O_RDONLY, 0644); - if (!f || IS_ERR(f)) { - if (IS_ERR(f)) { -- CERROR("Cannot open LOVDESC file\n"); - pop_ctxt(&saved); - RETURN(-EIO); - GOTO(out, rc = PTR_ERR(f)); -- } -- -- rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos); -- if (filp_close(f, 0)) -- CERROR("Error closing LOVDESC file\n"); -- -- if (rc != sizeof(*desc)) { - CERROR("Cannot read LOVDESC file\n"); - pop_ctxt(&saved); - RETURN(-EIO); - } - pop_ctxt(&saved); - CERROR("Cannot read LOVDESC file: rc = %d\n", rc); - GOTO(out, rc = -EIO); - } else - rc = 0; - EXIT; -out: - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- - RETURN(0); - return rc; --} -- --int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,obd_uuid_t *uuidarray) --{ -- struct obd_run_ctxt saved; -- struct file *f; -- int rc; -- int rc2; -- -- push_ctxt(&saved, &mds->mds_ctxt, NULL); -- f = filp_open("LOVTGTS", O_RDONLY, 0644); -- if (IS_ERR(f)) { -- CERROR("Cannot open LOVTGTS file\n"); -- GOTO(out, rc = PTR_ERR(f)); -- } -- -- rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray), -- &f->f_pos); -- rc2 = filp_close(f, 0); -- if (rc2) -- CERROR("Error closing LOVTGTS file: rc = %d\n", rc2); -- -- if (rc != tgt_count * sizeof(*uuidarray)) { -- CERROR("Error reading LOVTGTS file: rc = %d\n", rc); -- if (rc >= 0) -- rc = -EIO; -- GOTO(out, rc); - } else - } else -- rc = 0; -- EXIT; --out: - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, NULL); -- -- RETURN(rc); --} -- - int mds_iocontrol(long cmd, struct lustre_handle *conn, -int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn, -- int len, void *karg, void *uarg) --{ -- struct obd_device *obd = class_conn2obd(conn); -- struct obd_ioctl_data *data = karg; -- struct lov_desc *desc; -- obd_uuid_t *uuidarray; -- int count; -- int rc; -- -- -- switch (cmd) { -- case OBD_IOC_LOV_SET_CONFIG: -- desc = (struct lov_desc *)data->ioc_inlbuf1; -- if (sizeof(*desc) > data->ioc_inllen1) { -- CERROR("descriptor size wrong\n"); -- RETURN(-EINVAL); -- } -- -- count = desc->ld_tgt_count; -- uuidarray = (obd_uuid_t *)data->ioc_inlbuf2; -- if (sizeof(*uuidarray) * count != data->ioc_inllen2) { -- CERROR("UUID array size wrong\n"); -- RETURN(-EINVAL); -- } -- rc = mds_set_lovdesc(obd, desc, uuidarray); -- -- RETURN(rc); -- case OBD_IOC_LOV_GET_CONFIG: -- desc = (struct lov_desc *)data->ioc_inlbuf1; -- if (sizeof(*desc) > data->ioc_inllen1) { -- CERROR("descriptor size wrong\n"); -- RETURN(-EINVAL); -- } -- -- count = desc->ld_tgt_count; -- uuidarray = (obd_uuid_t *)data->ioc_inlbuf2; -- if (sizeof(*uuidarray) * count != data->ioc_inllen2) { -- CERROR("UUID array size wrong\n"); -- RETURN(-EINVAL); -- } -- rc = mds_get_lovdesc(&obd->u.mds, desc); -- if (desc->ld_tgt_count > count) { -- CERROR("UUID array size too small\n"); -- RETURN(-ENOSPC); -- } -- rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count, uuidarray); -- -- RETURN(rc); -- default: -- RETURN(-EINVAL); -- } -- -- RETURN(0); --} diff --cc lustre/mds/mds_reint.c index 318bbb0,5ac6e6e..0000000 deleted file mode 100644,100644 --- a/lustre/mds/mds_reint.c +++ /dev/null @@@ -1,866 -1,867 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/mds/mds_reint.c -- * Lustre Metadata Server (mds) reintegration routines -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Author: Peter Braam -- * Author: Andreas Dilger -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_MDS -- --#include --#include --#include --#include --#include --#include --#include --#include -- --extern inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req); - -void mds_start_transno(struct mds_obd *mds) -{ - ENTRY; - down(&mds->mds_transno_sem); -} -- --/* Assumes caller has already pushed us into the kernel context. */ - int mds_update_last_rcvd(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req) -int mds_finish_transno(struct mds_obd *mds, void *handle, - struct ptlrpc_request *req, int rc) --{ -- struct mds_export_data *med = &req->rq_export->exp_mds_data; -- struct mds_client_data *mcd = med->med_mcd; -- __u64 last_rcvd; -- loff_t off; - int rc; - ssize_t written; - - /* Propagate error code. */ - if (rc) - goto out; -- -- /* we don't allocate new transnos for replayed requests */ - if (req->rq_level == LUSTRE_CONN_RECOVD) - RETURN(0); - if (req->rq_level == LUSTRE_CONN_RECOVD) { - rc = 0; - goto out; - } -- -- off = MDS_LR_CLIENT + med->med_off * MDS_LR_SIZE; -- - spin_lock(&mds->mds_last_lock); -- last_rcvd = ++mds->mds_last_rcvd; - spin_unlock(&mds->mds_last_lock); -- req->rq_repmsg->transno = HTON__u64(last_rcvd); -- mcd->mcd_last_rcvd = cpu_to_le64(last_rcvd); -- mcd->mcd_mount_count = cpu_to_le64(mds->mds_mount_count); -- mcd->mcd_last_xid = cpu_to_le64(req->rq_xid); -- -- mds_fs_set_last_rcvd(mds, handle); - rc = lustre_fwrite(mds->mds_rcvd_filp, (char *)mcd, sizeof(*mcd), &off); - CDEBUG(D_INODE, "wrote trans #"LPD64" for client '%s' at #%d: rc = " - "%d\n", last_rcvd, mcd->mcd_uuid, med->med_off, rc); - written = lustre_fwrite(mds->mds_rcvd_filp, (char *)mcd, sizeof(*mcd), - &off); - CDEBUG(D_INODE, "wrote trans #"LPD64" for client %s at #%d: written = " - "%d\n", last_rcvd, mcd->mcd_uuid, med->med_off, written); -- - if (rc == sizeof(*mcd)) - rc = 0; - else { - CERROR("error writing to last_rcvd file: rc = %d\n", rc); - if (rc >= 0) - rc = -EIO; - } - if (written == sizeof(*mcd)) - GOTO(out, rc = 0); - CERROR("error writing to last_rcvd file: rc = %d\n", rc); - if (written >= 0) - GOTO(out, rc = -EIO); - - rc = 0; -- - out: - EXIT; - up(&mds->mds_transno_sem); -- return rc; --} -- --/* In the write-back case, the client holds a lock on a subtree. -- * In the intent case, the client holds a lock on the child inode. -- * In the pathname case, the client (may) hold a lock on the child inode. */ --static int mds_reint_setattr(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_device *obd = req->rq_export->exp_obd; -- struct mds_body *body; -- struct dentry *de; -- struct inode *inode; -- void *handle; -- struct lustre_handle child_lockh; -- int rc = 0, err; -- -- if (req->rq_reqmsg->bufcount > offset + 1) { -- struct dentry *dir; -- struct lustre_handle dir_lockh; -- char *name; -- int namelen; -- -- /* a name was supplied by the client; fid1 is the directory */ -- dir = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, LCK_PR, -- &dir_lockh); -- if (IS_ERR(dir)) { -- LBUG(); -- GOTO(out_setattr, rc = PTR_ERR(dir)); -- } -- -- name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- namelen = req->rq_reqmsg->buflens[offset + 1] - 1; -- de = mds_name2locked_dentry(obd, dir, NULL, name, namelen, -- 0, &child_lockh, LCK_PR); -- l_dput(dir); -- if (IS_ERR(de)) { -- LBUG(); -- GOTO(out_setattr_de, rc = PTR_ERR(de)); -- } -- } else { -- de = mds_fid2dentry(mds, rec->ur_fid1, NULL); -- if (!de || IS_ERR(de)) { - LBUG(); - GOTO(out_setattr_de, rc = -ESTALE); - GOTO(out_setattr_de, rc = PTR_ERR(de)); -- } -- } -- inode = de->d_inode; -- CDEBUG(D_INODE, "ino %ld\n", inode->i_ino); -- -- OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE, -- to_kdev_t(inode->i_sb->s_dev)); -- - mds_start_transno(mds); -- handle = mds_fs_start(mds, inode, MDS_FSOP_SETATTR); - if (!handle) - GOTO(out_setattr_de, rc = PTR_ERR(handle)); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - (void)mds_finish_transno(mds, handle, req, rc); - GOTO(out_setattr_de, rc); - } -- -- rc = mds_fs_setattr(mds, de, handle, &rec->ur_iattr); -- -- if (offset) { -- body = lustre_msg_buf(req->rq_repmsg, 1); -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); -- } -- - if (!rc) - rc = mds_update_last_rcvd(mds, handle, req); - rc = mds_finish_transno(mds, handle, req, rc); -- -- err = mds_fs_commit(mds, de->d_inode, handle); -- if (err) { -- CERROR("error on commit: err = %d\n", err); -- if (!rc) -- rc = err; -- } -- -- EXIT; --out_setattr_de: -- l_dput(de); --out_setattr: -- req->rq_status = rc; -- return 0; --} -- --static int mds_reint_create(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct dentry *de = NULL; -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_device *obd = req->rq_export->exp_obd; -- struct dentry *dchild = NULL; -- struct inode *dir; -- void *handle; -- struct lustre_handle lockh; -- int rc = 0, err, lock_mode, type = rec->ur_mode & S_IFMT; -- ENTRY; -- -- /* requests were at offset 2, replies go back at 1 */ -- if (offset) -- offset = 1; -- -- LASSERT(!strcmp(req->rq_export->exp_obd->obd_type->typ_name, "mds")); -- -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW; -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) -- GOTO(out_create, rc = -ESTALE); -- -- de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, lock_mode, &lockh); -- if (IS_ERR(de)) { -- rc = PTR_ERR(de); -- CERROR("parent lookup error %d\n", rc); -- LBUG(); -- GOTO(out_create, rc); -- } -- dir = de->d_inode; -- CDEBUG(D_INODE, "parent ino %ld name %s mode %o\n", -- dir->i_ino, rec->ur_name, rec->ur_mode); -- -- ldlm_lock_dump((void *)(unsigned long)lockh.addr); -- -- down(&dir->i_sem); -- dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1); -- if (IS_ERR(dchild)) { -- CERROR("child lookup error %ld\n", PTR_ERR(dchild)); -- LBUG(); -- GOTO(out_create_de, rc = -ESTALE); -- } -- -- if (dchild->d_inode) { -- struct mds_body *body; -- struct inode *inode = dchild->d_inode; -- -- CDEBUG(D_INODE, "child exists (dir %ld, name %s, ino %ld)\n", -- dir->i_ino, rec->ur_name, dchild->d_inode->i_ino); -- -- /* XXX check that mode is correct? */ -- -- body = lustre_msg_buf(req->rq_repmsg, offset); -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) { - struct lov_mds_md *lmm; - - lmm = lustre_msg_buf(req->rq_repmsg, offset + 1); - lmm->lmm_easize = mds->mds_max_mdsize; - - if (mds_fs_get_md(mds, inode, lmm) < 0) { - CDEBUG(D_INFO,"No md for %ld: rc %d\n", - inode->i_ino, rc); - memset(lmm, 0, lmm->lmm_easize); - } else - body->valid |= OBD_MD_FLEASIZE; - } - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, offset + 1, body, inode); -- -- /* This isn't an error for RECREATE. */ -- if (rec->ur_opcode & REINT_REPLAYING) { -- CDEBUG(D_INODE, "EEXIST suppressed for REPLAYING\n"); -- rc = 0; -- } else { -- rc = -EEXIST; -- } -- GOTO(out_create_dchild, rc); -- } -- -- OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE, -- to_kdev_t(dir->i_sb->s_dev)); -- -- if (dir->i_mode & S_ISGID) { -- rec->ur_gid = dir->i_gid; -- if (S_ISDIR(rec->ur_mode)) -- rec->ur_mode |= S_ISGID; -- } - - /* From here on, we must exit via a path that calls mds_finish_transno, - * so that we release the mds_transno_sem (and, in the case of success, - * update the transno correctly). out_create_commit and - * out_transno_dchild are good candidates. - */ - mds_start_transno(mds); -- -- switch (type) { -- case S_IFREG:{ -- handle = mds_fs_start(mds, dir, MDS_FSOP_CREATE); - if (!handle) - GOTO(out_create_dchild, PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); -- rc = vfs_create(dir, dchild, rec->ur_mode); -- EXIT; -- break; -- } -- case S_IFDIR:{ -- handle = mds_fs_start(mds, dir, MDS_FSOP_MKDIR); - if (!handle) - GOTO(out_create_dchild, PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); -- rc = vfs_mkdir(dir, dchild, rec->ur_mode); -- EXIT; -- break; -- } -- case S_IFLNK:{ -- handle = mds_fs_start(mds, dir, MDS_FSOP_SYMLINK); - if (!handle) - GOTO(out_create_dchild, PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); -- rc = vfs_symlink(dir, dchild, rec->ur_name); -- EXIT; -- break; -- } -- case S_IFCHR: -- case S_IFBLK: -- case S_IFIFO: -- case S_IFSOCK:{ -- int rdev = rec->ur_rdev; -- handle = mds_fs_start(mds, dir, MDS_FSOP_MKNOD); - if (!handle) - GOTO(out_create_dchild, PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_transno_dchild, rc = PTR_ERR(handle)); -- rc = vfs_mknod(dir, dchild, rec->ur_mode, rdev); -- EXIT; -- break; -- } -- default: -- CERROR("bad file type %o creating %s\n", type, rec->ur_name); - GOTO(out_create_dchild, rc = -EINVAL); - handle = NULL; /* quell uninitialized warning */ - GOTO(out_transno_dchild, rc = -EINVAL); -- } -- -- if (rc) { -- CDEBUG(D_INODE, "error during create: %d\n", rc); -- GOTO(out_create_commit, rc); -- } else { -- struct iattr iattr; -- struct inode *inode = dchild->d_inode; -- struct mds_body *body; -- -- iattr.ia_atime = rec->ur_time; -- iattr.ia_ctime = rec->ur_time; -- iattr.ia_mtime = rec->ur_time; -- iattr.ia_uid = rec->ur_uid; -- iattr.ia_gid = rec->ur_gid; -- iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME | -- ATTR_MTIME | ATTR_CTIME; -- -- if (rec->ur_fid2->id) { -- LASSERT(rec->ur_opcode & REINT_REPLAYING); -- inode->i_generation = rec->ur_fid2->generation; - /* Dirtied and committed by this setattr: */ - /* Dirtied and committed by the upcoming setattr. */ -- CDEBUG(D_INODE, "recreated ino %ld with gen %ld\n", -- inode->i_ino, inode->i_generation); -- } else { -- CDEBUG(D_INODE, "created ino %ld\n", inode->i_ino); -- } -- -- rc = mds_fs_setattr(mds, dchild, handle, &iattr); -- if (rc) { -- CERROR("error on setattr: rc = %d\n", rc); -- /* XXX should we abort here in case of error? */ - } - - rc = mds_update_last_rcvd(mds, handle, req); - if (rc) { - CERROR("error on mds_update_last_rcvd: rc = %d\n", rc); - GOTO(out_create_unlink, rc); -- } -- -- body = lustre_msg_buf(req->rq_repmsg, offset); -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); -- } -- EXIT; --out_create_commit: - if (rc) { - rc = mds_finish_transno(mds, handle, req, rc); - } else { - rc = mds_finish_transno(mds, handle, req, rc); - if (rc) - GOTO(out_create_unlink, rc); - } -- err = mds_fs_commit(mds, dir, handle); -- if (err) { -- CERROR("error on commit: err = %d\n", err); -- if (!rc) -- rc = err; -- } --out_create_dchild: -- l_dput(dchild); -- ldlm_lock_decref(&lockh, lock_mode); --out_create_de: -- up(&dir->i_sem); -- l_dput(de); --out_create: -- req->rq_status = rc; -- return 0; - -out_transno_dchild: - /* Need to release the transno lock, and then put the dchild. */ - LASSERT(rc); - mds_finish_transno(mds, handle, req, rc); - goto out_create_dchild; -- --out_create_unlink: -- /* Destroy the file we just created. This should not need extra -- * journal credits, as we have already modified all of the blocks -- * needed in order to create the file in the first place. -- */ -- switch (type) { -- case S_IFDIR: -- err = vfs_rmdir(dir, dchild); -- if (err) -- CERROR("failed rmdir in error path: rc = %d\n", err); -- break; -- default: -- err = vfs_unlink(dir, dchild); -- if (err) -- CERROR("failed unlink in error path: rc = %d\n", err); -- break; -- } -- -- goto out_create_commit; --} -- --static int mds_reint_unlink(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct dentry *de = NULL; -- struct dentry *dchild = NULL; -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_device *obd = req->rq_export->exp_obd; -- struct mds_body *body = NULL; -- char *name; -- struct inode *dir, *inode; -- struct lustre_handle lockh, child_lockh; -- void *handle; -- int namelen, lock_mode, err, rc = 0; -- ENTRY; -- -- /* a name was supplied by the client; fid1 is the directory */ -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; -- de = mds_fid2locked_dentry(obd, rec->ur_fid1, NULL, lock_mode, &lockh); -- if (IS_ERR(de)) { -- LBUG(); -- RETURN(PTR_ERR(de)); -- } -- -- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) -- GOTO(out_unlink, rc = -ENOENT); -- -- name = lustre_msg_buf(req->rq_reqmsg, offset + 1); -- namelen = req->rq_reqmsg->buflens[offset + 1] - 1; --#warning "FIXME: if mds_name2locked_dentry decrefs this lock, we must not" -- memcpy(&child_lockh, &lockh, sizeof(child_lockh)); -- dchild = mds_name2locked_dentry(obd, de, NULL, name, namelen, -- LCK_EX, &child_lockh, lock_mode); -- -- if (IS_ERR(dchild)) { -- LBUG(); -- GOTO(out_unlink, rc = PTR_ERR(dchild)); -- } -- -- dir = de->d_inode; -- inode = dchild->d_inode; -- CDEBUG(D_INODE, "parent ino %ld\n", dir->i_ino); -- -- if (!inode) { -- if (rec->ur_opcode & REINT_REPLAYING) { -- CDEBUG(D_INODE, -- "child missing (%ld/%s); OK for REPLAYING\n", -- dir->i_ino, rec->ur_name); -- rc = 0; -- } else { -- CDEBUG(D_INODE, -- "child doesn't exist (dir %ld, name %s)\n", -- dir->i_ino, rec->ur_name); -- rc = -ENOENT; -- } -- /* going to out_unlink_cancel causes an LBUG, don't know why */ -- GOTO(out_unlink_dchild, rc); -- } -- -- if (offset) { -- /* XXX offset? */ -- offset = 1; -- -- body = lustre_msg_buf(req->rq_repmsg, offset); -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); -- } -- -- OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE, -- to_kdev_t(dir->i_sb->s_dev)); -- - mds_start_transno(mds); -- switch (rec->ur_mode /* & S_IFMT ? */) { -- case S_IFDIR: -- handle = mds_fs_start(mds, dir, MDS_FSOP_RMDIR); - if (!handle) - GOTO(out_unlink_cancel, rc = PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_unlink_cancel_transno, rc = PTR_ERR(handle)); -- rc = vfs_rmdir(dir, dchild); -- break; -- case S_IFREG: -- /* get OBD EA data first so client can also destroy object */ - if ((inode->i_mode & S_IFMT) == S_IFREG && offset) { - struct lov_mds_md *lmm; - - lmm = lustre_msg_buf(req->rq_repmsg, offset + 1); - lmm->lmm_easize = mds->mds_max_mdsize; - if ((rc = mds_fs_get_md(mds, inode, lmm)) < 0) { - CDEBUG(D_INFO, "No md for ino %ld: rc = %d\n", - inode->i_ino, rc); - memset(lmm, 0, lmm->lmm_easize); - } else - body->valid |= OBD_MD_FLEASIZE; - } - if ((inode->i_mode & S_IFMT) == S_IFREG && offset) - mds_pack_md(mds, req, offset + 1, body, inode); -- /* no break */ -- case S_IFLNK: -- case S_IFCHR: -- case S_IFBLK: -- case S_IFIFO: -- case S_IFSOCK: -- handle = mds_fs_start(mds, dir, MDS_FSOP_UNLINK); - if (!handle) - GOTO(out_unlink_cancel, rc = PTR_ERR(handle)); - if (IS_ERR(handle)) - GOTO(out_unlink_cancel_transno, rc = PTR_ERR(handle)); -- rc = vfs_unlink(dir, dchild); -- break; -- default: -- CERROR("bad file type %o unlinking %s\n", rec->ur_mode, name); -- handle = NULL; -- LBUG(); - GOTO(out_unlink_cancel, rc = -EINVAL); - GOTO(out_unlink_cancel_transno, rc = -EINVAL); -- } -- - if (!rc) - rc = mds_update_last_rcvd(mds, handle, req); - rc = mds_finish_transno(mds, handle, req, rc); -- err = mds_fs_commit(mds, dir, handle); -- if (err) { -- CERROR("error on commit: err = %d\n", err); -- if (!rc) -- rc = err; -- } -- -- EXIT; -- --out_unlink_cancel: -- ldlm_lock_decref(&child_lockh, LCK_EX); -- err = ldlm_cli_cancel(&child_lockh); -- if (err < 0) { -- CERROR("failed to cancel child inode lock: err = %d\n", err); -- if (!rc) -- rc = -ENOLCK; /*XXX translate LDLM lock error */ -- } --out_unlink_dchild: -- l_dput(dchild); -- up(&dir->i_sem); --out_unlink: -- ldlm_lock_decref(&lockh, lock_mode); -- l_dput(de); -- req->rq_status = rc; -- return 0; - -out_unlink_cancel_transno: - rc = mds_finish_transno(mds, handle, req, rc); - goto out_unlink_cancel; --} -- --static int mds_reint_link(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct obd_device *obd = req->rq_export->exp_obd; -- struct dentry *de_src = NULL; -- struct dentry *de_tgt_dir = NULL; -- struct dentry *dchild = NULL; -- struct mds_obd *mds = mds_req2mds(req); -- struct lustre_handle *handle, tgtlockh, srclockh; -- int lock_mode; -- __u64 res_id[3] = { 0 }; -- int flags = 0; -- int rc = 0, err; -- -- ENTRY; -- de_src = mds_fid2dentry(mds, rec->ur_fid1, NULL); -- if (IS_ERR(de_src) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_LINK)) { -- GOTO(out_link, rc = -ESTALE); -- } -- -- /* plan to change the link count on this inode: write lock */ -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; -- res_id[0] = de_src->d_inode->i_ino; -- res_id[1] = de_src->d_inode->i_generation; -- -- rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, lock_mode, &srclockh); -- if (rc == 0) { -- LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &srclockh); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- GOTO(out_link_src_put, rc = -EIO); -- } -- } else -- ldlm_lock_dump((void *)(unsigned long)srclockh.addr); -- -- de_tgt_dir = mds_fid2dentry(mds, rec->ur_fid2, NULL); -- if (IS_ERR(de_tgt_dir)) { -- GOTO(out_link_src, rc = -ESTALE); -- } -- -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; -- res_id[0] = de_tgt_dir->d_inode->i_ino; -- res_id[1] = de_tgt_dir->d_inode->i_generation; -- -- rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, lock_mode, &tgtlockh); -- if (rc == 0) { -- LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &tgtlockh); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- GOTO(out_link_tgt_dir_put, rc = -EIO); -- } -- } else -- ldlm_lock_dump((void *)(unsigned long)tgtlockh.addr); -- -- down(&de_tgt_dir->d_inode->i_sem); -- dchild = lookup_one_len(rec->ur_name, de_tgt_dir, rec->ur_namelen - 1); -- if (IS_ERR(dchild)) { -- CERROR("child lookup error %ld\n", PTR_ERR(dchild)); -- GOTO(out_link_tgt_dir, rc = -ESTALE); -- } -- -- if (dchild->d_inode) { -- struct inode *inode = dchild->d_inode; -- /* in intent case ship back attributes to client */ -- if (offset) { -- struct mds_body *body = -- lustre_msg_buf(req->rq_repmsg, 1); -- -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) { - struct lov_mds_md *lmm; - - lmm = lustre_msg_buf(req->rq_repmsg, 2); - lmm->lmm_easize = mds->mds_max_mdsize; - if ((rc = mds_fs_get_md(mds, inode, lmm)) < 0) { - CDEBUG(D_INFO,"No md for %ld: rc %d\n", - inode->i_ino, rc); - memset(lmm, 0, lmm->lmm_easize); - } else - body->valid |= OBD_MD_FLEASIZE; - } - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, 2, body, inode); -- } -- if (rec->ur_opcode & REINT_REPLAYING) { -- /* XXX verify that the link is to the the right file? */ -- rc = 0; -- CDEBUG(D_INODE, -- "child exists (dir %ld, name %s) (REPLAYING)\n", -- de_tgt_dir->d_inode->i_ino, rec->ur_name); -- } else { -- rc = -EEXIST; -- CERROR("child exists (dir %ld, name %s)\n", -- de_tgt_dir->d_inode->i_ino, rec->ur_name); -- } -- GOTO(out_link_dchild, rc); -- } -- -- OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE, -- to_kdev_t(de_src->d_inode->i_sb->s_dev)); -- - mds_start_transno(mds); -- handle = mds_fs_start(mds, de_tgt_dir->d_inode, MDS_FSOP_LINK); - if (!handle) - GOTO(out_link_dchild, rc = PTR_ERR(handle)); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_link_dchild, rc); - } -- -- rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild); -- if (rc) -- CERROR("link error %d\n", rc); - if (!rc) - rc = mds_update_last_rcvd(mds, handle, req); - rc = mds_finish_transno(mds, handle, req, rc); -- -- err = mds_fs_commit(mds, de_tgt_dir->d_inode, handle); -- if (err) { -- CERROR("error on commit: err = %d\n", err); -- if (!rc) -- rc = err; -- } -- EXIT; -- --out_link_dchild: -- l_dput(dchild); --out_link_tgt_dir: -- ldlm_lock_decref(&tgtlockh, lock_mode); --out_link_tgt_dir_put: -- up(&de_tgt_dir->d_inode->i_sem); -- l_dput(de_tgt_dir); --out_link_src: -- ldlm_lock_decref(&srclockh, lock_mode); --out_link_src_put: -- l_dput(de_src); --out_link: -- req->rq_status = rc; -- return 0; --} -- --static int mds_reint_rename(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct obd_device *obd = req->rq_export->exp_obd; -- struct dentry *de_srcdir = NULL; -- struct dentry *de_tgtdir = NULL; -- struct dentry *de_old = NULL; -- struct dentry *de_new = NULL; -- struct mds_obd *mds = mds_req2mds(req); -- struct lustre_handle tgtlockh, srclockh, oldhandle; -- int flags = 0, lock_mode, rc = 0, err; -- void *handle; -- __u64 res_id[3] = { 0 }; -- ENTRY; -- -- de_srcdir = mds_fid2dentry(mds, rec->ur_fid1, NULL); -- if (IS_ERR(de_srcdir)) -- GOTO(out_rename, rc = -ESTALE); -- -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; -- res_id[0] = de_srcdir->d_inode->i_ino; -- res_id[1] = de_srcdir->d_inode->i_generation; -- -- rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, lock_mode, &srclockh); -- if (rc == 0) { -- LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &srclockh); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- GOTO(out_rename_srcput, rc = -EIO); -- } -- } else -- ldlm_lock_dump((void *)(unsigned long)srclockh.addr); -- -- de_tgtdir = mds_fid2dentry(mds, rec->ur_fid2, NULL); -- if (IS_ERR(de_tgtdir)) -- GOTO(out_rename_srcdir, rc = -ESTALE); -- -- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_PW : LCK_PW; -- res_id[0] = de_tgtdir->d_inode->i_ino; -- res_id[1] = de_tgtdir->d_inode->i_generation; -- -- rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, -- NULL, 0, lock_mode, &tgtlockh); -- if (rc == 0) { -- flags = 0; -- LDLM_DEBUG_NOLOCK("enqueue res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, lock_mode, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &tgtlockh); -- if (rc != ELDLM_OK) { -- CERROR("lock enqueue: err: %d\n", rc); -- GOTO(out_rename_tgtput, rc = -EIO); -- } -- } else -- ldlm_lock_dump((void *)(unsigned long)tgtlockh.addr); -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- double_lock(de_tgtdir, de_srcdir); --#endif -- de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1); -- if (IS_ERR(de_old)) { -- CERROR("old child lookup error (%*s): %ld\n", -- rec->ur_namelen - 1, rec->ur_name, PTR_ERR(de_old)); -- GOTO(out_rename_tgtdir, rc = -ENOENT); -- } -- -- de_new = lookup_one_len(rec->ur_tgt, de_tgtdir, rec->ur_tgtlen - 1); -- if (IS_ERR(de_new)) { -- CERROR("new child lookup error (%*s): %ld\n", -- rec->ur_tgtlen - 1, rec->ur_tgt, PTR_ERR(de_new)); -- GOTO(out_rename_deold, rc = -ENOENT); -- } -- -- /* in intent case ship back attributes to client */ -- if (offset) { -- struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); -- struct inode *inode = de_new->d_inode; -- -- if (!inode) { -- body->valid = 0; -- } else { -- mds_pack_inode2fid(&body->fid1, inode); -- mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) { - struct lov_mds_md *lmm; - - lmm = lustre_msg_buf(req->rq_repmsg, 2); - lmm->lmm_easize = mds->mds_max_mdsize; - if ((rc = mds_fs_get_md(mds, inode, lmm)) < 0) { - CDEBUG(D_INFO,"No md for %ld: rc %d\n", - inode->i_ino, rc); - memset(lmm, 0, lmm->lmm_easize); - } else - body->valid |= OBD_MD_FLEASIZE; - } - if (S_ISREG(inode->i_mode)) - mds_pack_md(mds, req, 2, body, inode); -- } -- } -- -- OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE, -- to_kdev_t(de_srcdir->d_inode->i_sb->s_dev)); -- - mds_start_transno(mds); -- handle = mds_fs_start(mds, de_tgtdir->d_inode, MDS_FSOP_RENAME); - if (!handle) - GOTO(out_rename_denew, rc = PTR_ERR(handle)); - if (IS_ERR(handle)) { - rc = PTR_ERR(handle); - mds_finish_transno(mds, handle, req, rc); - GOTO(out_rename_denew, rc); - } - -- lock_kernel(); -- rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new, -- NULL); -- unlock_kernel(); -- - if (!rc) - rc = mds_update_last_rcvd(mds, handle, req); - rc = mds_finish_transno(mds, handle, req, rc); -- -- err = mds_fs_commit(mds, de_tgtdir->d_inode, handle); -- if (err) { -- CERROR("error on commit: err = %d\n", err); -- if (!rc) -- rc = err; -- } -- EXIT; -- --out_rename_denew: -- l_dput(de_new); --out_rename_deold: -- if (!rc) { -- res_id[0] = de_old->d_inode->i_ino; -- res_id[1] = de_old->d_inode->i_generation; -- flags = 0; -- /* Take an exclusive lock on the resource that we're -- * about to free, to force everyone to drop their -- * locks. */ -- LDLM_DEBUG_NOLOCK("getting EX lock res "LPU64, res_id[0]); -- rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, NULL, -- res_id, LDLM_PLAIN, NULL, 0, LCK_EX, -- &flags, ldlm_completion_ast, -- mds_blocking_ast, NULL, 0, &oldhandle); -- if (rc) -- CERROR("failed to get child inode lock (child ino " -- LPD64" dir ino %ld)\n", -- res_id[0], de_old->d_inode->i_ino); -- } -- -- l_dput(de_old); -- -- if (!rc) { -- ldlm_lock_decref(&oldhandle, LCK_EX); -- rc = ldlm_cli_cancel(&oldhandle); -- if (rc < 0) -- CERROR("failed to cancel child inode lock ino " -- LPD64": %d\n", res_id[0], rc); -- } --out_rename_tgtdir: --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- double_up(&de_srcdir->d_inode->i_sem, &de_tgtdir->d_inode->i_sem); --#endif -- ldlm_lock_decref(&tgtlockh, lock_mode); --out_rename_tgtput: -- l_dput(de_tgtdir); --out_rename_srcdir: -- ldlm_lock_decref(&srclockh, lock_mode); --out_rename_srcput: -- l_dput(de_srcdir); --out_rename: -- req->rq_status = rc; -- return 0; --} -- --typedef int (*mds_reinter) (struct mds_update_record *, int offset, -- struct ptlrpc_request *); -- --static mds_reinter reinters[REINT_MAX + 1] = { -- [REINT_SETATTR] mds_reint_setattr, -- [REINT_CREATE] mds_reint_create, -- [REINT_UNLINK] mds_reint_unlink, -- [REINT_LINK] mds_reint_link, -- [REINT_RENAME] mds_reint_rename, --}; -- --int mds_reint_rec(struct mds_update_record *rec, int offset, -- struct ptlrpc_request *req) --{ -- struct mds_obd *mds = mds_req2mds(req); -- struct obd_run_ctxt saved; -- struct obd_ucred uc; -- int realop = rec->ur_opcode & REINT_OPCODE_MASK; -- int rc; -- -- if (realop < 1 || realop > REINT_MAX) { -- CERROR("opcode %d not valid (%sREPLAYING)\n", realop, -- rec->ur_opcode & REINT_REPLAYING ? "" : "not "); -- rc = req->rq_status = -EINVAL; -- RETURN(rc); -- } -- -- uc.ouc_fsuid = rec->ur_fsuid; -- uc.ouc_fsgid = rec->ur_fsgid; -- uc.ouc_cap = rec->ur_cap; -- -- push_ctxt(&saved, &mds->mds_ctxt, &uc); -- rc = reinters[realop] (rec, offset, req); - pop_ctxt(&saved); - pop_ctxt(&saved, &mds->mds_ctxt, &uc); -- -- return rc; --} diff --cc lustre/missing index 6a37006,6a37006..0000000 deleted file mode 100755,100755 --- a/lustre/missing +++ /dev/null @@@ -1,336 -1,336 +1,0 @@@ --#! /bin/sh --# Common stub for a few missing GNU programs while installing. --# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. --# Originally by Fran,cois Pinard , 1996. -- --# This program 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, or (at your option) --# any later version. -- --# 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. -- --# 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. -- --# As a special exception to the GNU General Public License, if you --# distribute this file as part of a program that contains a --# configuration script generated by Autoconf, you may include it under --# the same distribution terms that you use for the rest of that program. -- --if test $# -eq 0; then -- echo 1>&2 "Try \`$0 --help' for more information" -- exit 1 --fi -- --run=: -- --# In the cases where this matters, `missing' is being run in the --# srcdir already. --if test -f configure.ac; then -- configure_ac=configure.ac --else -- configure_ac=configure.in --fi -- --case "$1" in ----run) -- # Try to run requested program, and just exit if it succeeds. -- run= -- shift -- "$@" && exit 0 -- ;; --esac -- --# If it does not exist, or fails to run (possibly an outdated version), --# try to emulate it. --case "$1" in -- -- -h|--h|--he|--hel|--help) -- echo "\ --$0 [OPTION]... PROGRAM [ARGUMENT]... -- --Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an --error status if there is no known handling for PROGRAM. -- --Options: -- -h, --help display this help and exit -- -v, --version output version information and exit -- --run try to run the given command, and emulate it if it fails -- --Supported PROGRAM values: -- aclocal touch file \`aclocal.m4' -- autoconf touch file \`configure' -- autoheader touch file \`config.h.in' -- automake touch all \`Makefile.in' files -- bison create \`y.tab.[ch]', if possible, from existing .[ch] -- flex create \`lex.yy.c', if possible, from existing .c -- help2man touch the output file -- lex create \`lex.yy.c', if possible, from existing .c -- makeinfo touch the output file -- tar try tar, gnutar, gtar, then tar without non-portable flags -- yacc create \`y.tab.[ch]', if possible, from existing .[ch]" -- ;; -- -- -v|--v|--ve|--ver|--vers|--versi|--versio|--version) -- echo "missing 0.4 - GNU automake" -- ;; -- -- -*) -- echo 1>&2 "$0: Unknown \`$1' option" -- echo 1>&2 "Try \`$0 --help' for more information" -- exit 1 -- ;; -- -- aclocal*) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified \`acinclude.m4' or \`${configure_ac}'. You might want -- to install the \`Automake' and \`Perl' packages. Grab them from -- any GNU archive site." -- touch aclocal.m4 -- ;; -- -- autoconf) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified \`${configure_ac}'. You might want to install the -- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU -- archive site." -- touch configure -- ;; -- -- autoheader) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified \`acconfig.h' or \`${configure_ac}'. You might want -- to install the \`Autoconf' and \`GNU m4' packages. Grab them -- from any GNU archive site." -- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` -- test -z "$files" && files="config.h" -- touch_files= -- for f in $files; do -- case "$f" in -- *:*) touch_files="$touch_files "`echo "$f" | -- sed -e 's/^[^:]*://' -e 's/:.*//'`;; -- *) touch_files="$touch_files $f.in";; -- esac -- done -- touch $touch_files -- ;; -- -- automake*) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. -- You might want to install the \`Automake' and \`Perl' packages. -- Grab them from any GNU archive site." -- find . -type f -name Makefile.am -print | -- sed 's/\.am$/.in/' | -- while read f; do touch "$f"; done -- ;; -- -- autom4te) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is needed, and you do not seem to have it handy on your -- system. You might have modified some files without having the -- proper tools for further handling them. -- You can get \`$1Help2man' as part of \`Autoconf' from any GNU -- archive site." -- -- file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` -- test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` -- if test -f "$file"; then -- touch $file -- else -- test -z "$file" || exec >$file -- echo "#! /bin/sh" -- echo "# Created by GNU Automake missing as a replacement of" -- echo "# $ $@" -- echo "exit 0" -- chmod +x $file -- exit 1 -- fi -- ;; -- -- bison|yacc) -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified a \`.y' file. You may need the \`Bison' package -- in order for those modifications to take effect. You can get -- \`Bison' from any GNU archive site." -- rm -f y.tab.c y.tab.h -- if [ $# -ne 1 ]; then -- eval LASTARG="\${$#}" -- case "$LASTARG" in -- *.y) -- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` -- if [ -f "$SRCFILE" ]; then -- cp "$SRCFILE" y.tab.c -- fi -- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` -- if [ -f "$SRCFILE" ]; then -- cp "$SRCFILE" y.tab.h -- fi -- ;; -- esac -- fi -- if [ ! -f y.tab.h ]; then -- echo >y.tab.h -- fi -- if [ ! -f y.tab.c ]; then -- echo 'main() { return 0; }' >y.tab.c -- fi -- ;; -- -- lex|flex) -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified a \`.l' file. You may need the \`Flex' package -- in order for those modifications to take effect. You can get -- \`Flex' from any GNU archive site." -- rm -f lex.yy.c -- if [ $# -ne 1 ]; then -- eval LASTARG="\${$#}" -- case "$LASTARG" in -- *.l) -- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` -- if [ -f "$SRCFILE" ]; then -- cp "$SRCFILE" lex.yy.c -- fi -- ;; -- esac -- fi -- if [ ! -f lex.yy.c ]; then -- echo 'main() { return 0; }' >lex.yy.c -- fi -- ;; -- -- help2man) -- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then -- # We have it, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified a dependency of a manual page. You may need the -- \`Help2man' package in order for those modifications to take -- effect. You can get \`Help2man' from any GNU archive site." -- -- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` -- if test -z "$file"; then -- file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` -- fi -- if [ -f "$file" ]; then -- touch $file -- else -- test -z "$file" || exec >$file -- echo ".ab help2man is required to generate this page" -- exit 1 -- fi -- ;; -- -- makeinfo) -- if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then -- # We have makeinfo, but it failed. -- exit 1 -- fi -- -- echo 1>&2 "\ --WARNING: \`$1' is missing on your system. You should only need it if -- you modified a \`.texi' or \`.texinfo' file, or any other file -- indirectly affecting the aspect of the manual. The spurious -- call might also be the consequence of using a buggy \`make' (AIX, -- DU, IRIX). You might want to install the \`Texinfo' package or -- the \`GNU make' package. Grab either from any GNU archive site." -- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` -- if test -z "$file"; then -- file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` -- file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` -- fi -- touch $file -- ;; -- -- tar) -- shift -- if test -n "$run"; then -- echo 1>&2 "ERROR: \`tar' requires --run" -- exit 1 -- fi -- -- # We have already tried tar in the generic part. -- # Look for gnutar/gtar before invocation to avoid ugly error -- # messages. -- if (gnutar --version > /dev/null 2>&1); then -- gnutar "$@" && exit 0 -- fi -- if (gtar --version > /dev/null 2>&1); then -- gtar "$@" && exit 0 -- fi -- firstarg="$1" -- if shift; then -- case "$firstarg" in -- *o*) -- firstarg=`echo "$firstarg" | sed s/o//` -- tar "$firstarg" "$@" && exit 0 -- ;; -- esac -- case "$firstarg" in -- *h*) -- firstarg=`echo "$firstarg" | sed s/h//` -- tar "$firstarg" "$@" && exit 0 -- ;; -- esac -- fi -- -- echo 1>&2 "\ --WARNING: I can't seem to be able to run \`tar' with the given arguments. -- You may want to install GNU tar or Free paxutils, or check the -- command line arguments." -- exit 1 -- ;; -- -- *) -- echo 1>&2 "\ --WARNING: \`$1' is needed, and you do not seem to have it handy on your -- system. You might have modified some files without having the -- proper tools for further handling them. Check the \`README' file, -- it often tells you about the needed prerequirements for installing -- this package. You may also peek at any GNU archive site, in case -- some other package would contain this missing \`$1' program." -- exit 1 -- ;; --esac -- --exit 0 diff --cc lustre/mkinstalldirs index a08f3ca,a08f3ca..0000000 deleted file mode 100755,100755 --- a/lustre/mkinstalldirs +++ /dev/null @@@ -1,40 -1,40 +1,0 @@@ --#! /bin/sh --# mkinstalldirs --- make directory hierarchy --# Author: Noah Friedman --# Created: 1993-05-16 --# Public domain -- --# $Id: mkinstalldirs,v 1.1 2002/05/27 16:48:11 pschwan Exp $ -- --errstatus=0 -- --for file --do -- set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` -- shift -- -- pathcomp= -- for d -- do -- pathcomp="$pathcomp$d" -- case "$pathcomp" in -- -* ) pathcomp=./$pathcomp ;; -- esac -- -- if test ! -d "$pathcomp"; then -- echo "mkdir $pathcomp" -- -- mkdir "$pathcomp" || lasterr=$? -- -- if test ! -d "$pathcomp"; then -- errstatus=$lasterr -- fi -- fi -- -- pathcomp="$pathcomp/" -- done --done -- --exit $errstatus -- --# mkinstalldirs ends here diff --cc lustre/nodist index 91aecad,91aecad..0000000 deleted file mode 100644,100644 --- a/lustre/nodist +++ /dev/null @@@ -1,21 -1,21 +1,0 @@@ --obd-*/obd-* --CVS --*~ --make.rules --config.* --*.o --*.orig --*.backup --.depfiles --ext2obd/dir.c --ext2obd/file.c --ext2obd/ialloc.c --ext2obd/inode.c --ext2obd/super.c --ext2obd/fsync.c --ext2obd/ioctl.c --ext2obd/balloc.c --ext2obd/acl.c --ext2obd/namei.c --ext2obd/symlink.c --ext2obd/bitmap.c diff --cc lustre/obdclass/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/obdclass/Makefile.am index 3ad8a59,d7df0bb..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/Makefile.am +++ /dev/null @@@ -1,6 -1,14 +1,0 @@@ -# FIXME: we need to make it clear that obdclass.o depends on -# lustre_build_version, or 'make -j2' breaks! --DEFS= --MODULE = obdclass - modulefs_DATA = obdclass.o -modulefs_DATA = lustre_build_version obdclass.o --EXTRA_PROGRAMS = obdclass --obdclass_SOURCES = debug.c genops.c class_obd.c sysctl.c uuid.c lprocfs_status.c --include $(top_srcdir)/Rules -lustre_build_version: - perl $(top_srcdir)/scripts/version_tag.pl $(top_srcdir) > tmpver - diff -u $(top_builddir)/include/linux/lustre_build_version.h tmpver \ - 2> /dev/null &&\ - $(RM) tmpver || \ - mv tmpver $(top_builddir)/include/linux/lustre_build_version.h diff --cc lustre/obdclass/class_obd.c index 9363959,32e8c08..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/class_obd.c +++ /dev/null @@@ -1,860 -1,715 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * These are the only exported functions, they provide some generic -- * infrastructure for managing object devices -- * -- * Object Devices Class Driver -- */ -- --#define EXPORT_SYMTAB --#include /* for CONFIG_PROC_FS */ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include --#include --#include --#include --#include /* for PTL_MD_MAX_IOV */ -#include -- --struct semaphore obd_conf_sem; /* serialize configuration commands */ --struct obd_device obd_dev[MAX_OBD_DEVICES]; --struct list_head obd_types; --unsigned long obd_memory; -- --/* The following are visible and mutable through /proc/sys/lustre/. */ --unsigned long obd_fail_loc; --unsigned long obd_timeout = 100; --char obd_recovery_upcall[128] = "/usr/lib/lustre/ha_assist"; -- --extern struct obd_type *class_nm_to_type(char *nm); -- --/* opening /dev/obd */ --static int obd_class_open(struct inode * inode, struct file * file) --{ -- ENTRY; -- -- file->private_data = NULL; -- CDEBUG(D_IOCTL, "MOD_INC_USE for open: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount)); -- MOD_INC_USE_COUNT; -- RETURN(0); --} -- --/* closing /dev/obd */ --static int obd_class_release(struct inode * inode, struct file * file) --{ -- ENTRY; -- -- // XXX drop lsm, connections here -- if (file->private_data) -- file->private_data = NULL; -- -- CDEBUG(D_IOCTL, "MOD_DEC_USE for close: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount) - 1); -- MOD_DEC_USE_COUNT; -- RETURN(0); --} - -- --static inline void obd_data2conn(struct lustre_handle *conn, -- struct obd_ioctl_data *data) --{ -- conn->addr = data->ioc_addr; -- conn->cookie = data->ioc_cookie; --} - -- --static inline void obd_conn2data(struct obd_ioctl_data *data, -- struct lustre_handle *conn) --{ -- data->ioc_addr = conn->addr; -- data->ioc_cookie = conn->cookie; --} -- --static void forcibly_detach_exports(struct obd_device *obd) --{ -- int rc; -- struct list_head *tmp, *n; -- struct lustre_handle fake_conn; -- -- CDEBUG(D_IOCTL, "OBD device %d (%p) has exports, " -- "disconnecting them", obd->obd_minor, obd); -- list_for_each_safe(tmp, n, &obd->obd_exports) { -- struct obd_export *exp = list_entry(tmp, struct obd_export, -- exp_obd_chain); -- fake_conn.addr = (__u64)(unsigned long)exp; -- fake_conn.cookie = exp->exp_cookie; -- rc = obd_disconnect(&fake_conn); -- if (rc) { -- CDEBUG(D_IOCTL, "disconnecting export %p failed: %d\n", -- exp, rc); -- } else { -- CDEBUG(D_IOCTL, "export %p disconnected\n", exp); -- } -- } --} -- --/* to control /dev/obd */ --static int obd_class_ioctl (struct inode * inode, struct file * filp, -- unsigned int cmd, unsigned long arg) --{ -- char *buf = NULL; - int len = 0; -- struct obd_ioctl_data *data; -- struct obd_device *obd = filp->private_data; - -- struct lustre_handle conn; - int rw = OBD_BRW_READ; - int err = 0; - int serialised = 0; - - int err = 0, len = 0, serialised = 0; -- ENTRY; -- - switch (cmd) - { - switch (cmd) { -- case OBD_IOC_BRW_WRITE: -- case OBD_IOC_BRW_READ: -- case OBD_IOC_GETATTR: -- break; -- default: -- down(&obd_conf_sem); -- serialised = 1; -- break; -- } -- -- if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS && - cmd != OBD_IOC_LIST && - cmd != OBD_IOC_LIST && cmd != OBD_GET_VERSION && -- cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) { -- CERROR("OBD ioctl: No device\n"); - GOTO(out, err=-EINVAL); - GOTO(out, err = -EINVAL); -- } -- if (obd_ioctl_getdata(&buf, &len, (void *)arg)) { -- CERROR("OBD ioctl: data error\n"); - GOTO(out, err=-EINVAL); - GOTO(out, err = -EINVAL); -- } -- data = (struct obd_ioctl_data *)buf; -- -- switch (cmd) { -- case TCGETS: -- GOTO(out, err=-EINVAL); -- case OBD_IOC_DEVICE: { -- CDEBUG(D_IOCTL, "\n"); -- if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) { -- CERROR("OBD ioctl: DEVICE insufficient devices\n"); -- GOTO(out, err=-EINVAL); -- } -- CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev); -- -- filp->private_data = &obd_dev[data->ioc_dev]; -- GOTO(out, err=0); -- } -- -- case OBD_IOC_LIST: { -- int i; -- char *buf2 = data->ioc_bulk; -- int remains = data->ioc_inllen1; -- -- if (!data->ioc_inlbuf1) { -- CERROR("No buffer passed!\n"); -- GOTO(out, err=-EINVAL); -- } -- -- -- for (i = 0 ; i < MAX_OBD_DEVICES ; i++) { -- int l; -- char *status; -- struct obd_device *obd = &obd_dev[i]; -- if (!obd->obd_type) -- continue; -- if (obd->obd_flags & OBD_SET_UP) -- status = "UP"; -- else if (obd->obd_flags & OBD_ATTACHED) -- status = "AT"; -- else -- status = "-"; -- l = snprintf(buf2, remains, "%2d %s %s %s %s %d\n", -- i, status, obd->obd_type->typ_name, -- obd->obd_name, obd->obd_uuid, obd->obd_type->typ_refcnt); -- buf2 +=l; -- remains -=l; -- if (remains <= 0) { -- CERROR("not enough space for device listing\n"); -- break; -- } -- } -- -- err = copy_to_user((void *)arg, data, len); -- if (err) -- err = -EFAULT; -- GOTO(out, err); -- } - - case OBD_GET_VERSION: - if (!data->ioc_inlbuf1) { - CERROR("No buffer passed in ioctl\n"); - GOTO(out, err = -EINVAL); - } - - if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) { - CERROR("ioctl buffer too small to hold version\n"); - GOTO(out, err = -EINVAL); - } - - memcpy(data->ioc_bulk, BUILD_VERSION, - strlen(BUILD_VERSION) + 1); -- - err = copy_to_user((void *)arg, data, len); - if (err) - err = -EFAULT; - GOTO(out, err); -- -- case OBD_IOC_NAME2DEV: { -- /* Resolve a device name. This does not change the -- * currently selected device. -- */ -- int dev; -- -- if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) { -- CERROR("No name passed,!\n"); -- GOTO(out, err=-EINVAL); -- } -- if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { -- CERROR("Name not nul terminated!\n"); -- GOTO(out, err=-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1); -- dev = class_name2dev(data->ioc_inlbuf1); -- data->ioc_dev = dev; -- if (dev == -1) { -- CDEBUG(D_IOCTL, "No device for name %s!\n", -- data->ioc_inlbuf1); -- GOTO(out, err=-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, -- dev); -- err = copy_to_user((void *)arg, data, sizeof(*data)); -- if (err) -- err = -EFAULT; -- GOTO(out, err); -- } -- -- case OBD_IOC_UUID2DEV: { -- /* Resolve a device uuid. This does not change the -- * currently selected device. -- */ -- int dev; -- -- if (!data->ioc_inllen1 || !data->ioc_inlbuf1) { -- CERROR("No UUID passed!\n"); -- GOTO(out, err=-EINVAL); -- } -- if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { -- CERROR("Name not nul terminated!\n"); -- GOTO(out, err=-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1); -- dev = class_uuid2dev(data->ioc_inlbuf1); -- data->ioc_dev = dev; -- if (dev == -1) { -- CDEBUG(D_IOCTL, "No device for name %s!\n", -- data->ioc_inlbuf1); -- GOTO(out, err=-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1, -- dev); -- err = copy_to_user((void *)arg, data, sizeof(*data)); -- if (err) -- err = -EFAULT; -- GOTO(out, err); -- } -- -- case OBD_IOC_NEWDEV: { -- int dev = -1; -- int i; -- -- filp->private_data = NULL; -- for (i = 0 ; i < MAX_OBD_DEVICES ; i++) { -- struct obd_device *obd = &obd_dev[i]; -- if (!obd->obd_type) { -- filp->private_data = obd; -- dev = i; -- break; -- } -- } -- -- -- data->ioc_dev = dev; -- if (dev == -1) -- GOTO(out, err=-EINVAL); -- -- err = copy_to_user((void *)arg, data, sizeof(*data)); -- if (err) -- err = -EFAULT; -- GOTO(out, err); -- } -- -- case OBD_IOC_ATTACH: { -- struct obd_type *type; -- int minor; -- -- /* have we attached a type to this device */ -- if (obd->obd_flags & OBD_ATTACHED || obd->obd_type) { -- CERROR("OBD: Device %d already typed as %s.\n", -- obd->obd_minor, MKSTR(obd->obd_type->typ_name)); -- GOTO(out, err=-EBUSY); -- } -- -- if (!data->ioc_inllen1 || !data->ioc_inlbuf1) { -- CERROR("No type passed!\n"); -- GOTO(out, err=-EINVAL); -- } -- if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) { -- CERROR("Type not nul terminated!\n"); -- GOTO(out, err=-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n", -- MKSTR(data->ioc_inlbuf1), -- MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3)); -- -- /* find the type */ -- type = class_nm_to_type(data->ioc_inlbuf1); -- if (!type) { -- CERROR("OBD: unknown type dev %d\n", obd->obd_minor); -- GOTO(out, err=-EINVAL); -- } -- -- minor = obd->obd_minor; -- memset(obd, 0, sizeof(*obd)); -- obd->obd_minor = minor; -- obd->obd_type = type; -- INIT_LIST_HEAD(&obd->obd_exports); -- INIT_LIST_HEAD(&obd->obd_imports); -- spin_lock_init(&obd->obd_dev_lock); -- - if (data->ioc_inlbuf2) { - int len = strlen(data->ioc_inlbuf2) + 1; - OBD_ALLOC(obd->obd_name, len); - if (!obd->obd_name) { - CERROR("no memory\n"); - LBUG(); - } - memcpy(obd->obd_name, data->ioc_inlbuf2, len); - } else { - CERROR("WARNING: unnamed obd device\n"); - if (data->ioc_inlbuf2) { - int len = strlen(data->ioc_inlbuf2) + 1; - OBD_ALLOC(obd->obd_name, len); - if (!obd->obd_name) { - CERROR("no memory\n"); - LBUG(); -- } - if (data->ioc_inlbuf3) { - int len = strlen(data->ioc_inlbuf3); - if (len >= sizeof(obd->obd_uuid)) { - CERROR("uuid must be < %d bytes long\n", - sizeof(obd->obd_uuid)); - if (obd->obd_name) - OBD_FREE(obd->obd_name, - strlen(obd->obd_name) + 1); - GOTO(out, err=-EINVAL); - } - memcpy(obd->obd_uuid, data->ioc_inlbuf3, len); - memcpy(obd->obd_name, data->ioc_inlbuf2, len); - } else { - CERROR("WARNING: unnamed obd device\n"); - } - if (data->ioc_inlbuf3) { - int len = strlen(data->ioc_inlbuf3); - if (len >= sizeof(obd->obd_uuid)) { - CERROR("uuid must be < %d bytes long\n", - sizeof(obd->obd_uuid)); - if (obd->obd_name) - OBD_FREE(obd->obd_name, - strlen(obd->obd_name) + 1); - GOTO(out, err=-EINVAL); -- } - memcpy(obd->obd_uuid, data->ioc_inlbuf3, len); - } -- /* do the attach */ -- if (OBP(obd, attach)) -- err = OBP(obd,attach)(obd, sizeof(*data), data); -- if (err) { -- if(data->ioc_inlbuf2) -- OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); -- obd->obd_type = NULL; - - } else { - } else { -- obd->obd_flags |= OBD_ATTACHED; -- -- type->typ_refcnt++; -- CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n", -- obd->obd_minor, data->ioc_inlbuf1); -- -- CDEBUG(D_IOCTL, "MOD_INC_USE for attach: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount)); -- MOD_INC_USE_COUNT; -- } -- -- GOTO(out, err); -- } -- -- case OBD_IOC_DETACH: { -- ENTRY; -- if (obd->obd_flags & OBD_SET_UP) { -- CERROR("OBD device %d still set up\n", obd->obd_minor); -- GOTO(out, err=-EBUSY); -- } -- if (!(obd->obd_flags & OBD_ATTACHED) ) { -- CERROR("OBD device %d not attached\n", obd->obd_minor); -- GOTO(out, err=-ENODEV); -- } -- if (!list_empty(&obd->obd_exports)) { -- if (!data->ioc_inlbuf1 || data->ioc_inlbuf1[0] != 'F') { -- CERROR("OBD device %d (%p) has exports\n", -- obd->obd_minor, obd); -- GOTO(out, err=-EBUSY); -- } -- forcibly_detach_exports(obd); -- } -- if (OBP(obd, detach)) -- err=OBP(obd,detach)(obd); -- -- if (obd->obd_name) { -- OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1); -- obd->obd_name = NULL; -- } -- -- obd->obd_flags &= ~OBD_ATTACHED; -- obd->obd_type->typ_refcnt--; -- obd->obd_type = NULL; -- CDEBUG(D_IOCTL, "MOD_DEC_USE for detach: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount) - 1); -- MOD_DEC_USE_COUNT; -- GOTO(out, err = 0); -- } -- -- case OBD_IOC_SETUP: { -- /* have we attached a type to this device? */ -- if (!(obd->obd_flags & OBD_ATTACHED)) { -- CERROR("Device %d not attached\n", obd->obd_minor); -- GOTO(out, err=-ENODEV); -- } -- -- /* has this been done already? */ -- if ( obd->obd_flags & OBD_SET_UP ) { -- CERROR("Device %d already setup (type %s)\n", -- obd->obd_minor, obd->obd_type->typ_name); -- GOTO(out, err=-EBUSY); -- } -- -- if ( OBT(obd) && OBP(obd, setup) ) -- err = obd_setup(obd, sizeof(*data), data); -- -- if (!err) { -- obd->obd_type->typ_refcnt++; -- obd->obd_flags |= OBD_SET_UP; -- } -- -- GOTO(out, err); -- } -- case OBD_IOC_CLEANUP: { -- /* have we attached a type to this device? */ -- if (!(obd->obd_flags & OBD_ATTACHED)) { -- CERROR("Device %d not attached\n", obd->obd_minor); -- GOTO(out, err=-ENODEV); -- } -- -- if ( OBT(obd) && OBP(obd, cleanup) ) -- err = obd_cleanup(obd); -- -- if (!err) { -- obd->obd_flags &= ~OBD_SET_UP; -- obd->obd_type->typ_refcnt--; -- } - GOTO(out, err); - GOTO(out, err); -- } -- -- case OBD_IOC_CONNECT: { -- char * cluuid = "OBD_CLASS_UUID"; -- obd_data2conn(&conn, data); -- -- err = obd_connect(&conn, obd, cluuid, NULL, NULL); -- -- CDEBUG(D_IOCTL, "assigned export "LPX64"\n", conn.addr); -- obd_conn2data(data, &conn); -- if (err) -- GOTO(out, err); -- -- err = copy_to_user((void *)arg, data, sizeof(*data)); -- if (err) -- err = -EFAULT; -- // XXX save connection data into file handle -- GOTO(out, err); -- } -- -- case OBD_IOC_DISCONNECT: { -- obd_data2conn(&conn, data); -- err = obd_disconnect(&conn); -- GOTO(out, err); -- } -- -- case OBD_IOC_DEC_USE_COUNT: { -- CDEBUG(D_IOCTL, "MOD_DEC_USE for force dec: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount) - 1); -- MOD_DEC_USE_COUNT; -- GOTO(out, err=0); - } - - case OBD_IOC_CREATE: { - struct lov_stripe_md *lsm = NULL; - obd_data2conn(&conn, data); - - #warning FIXME: save lsm into file handle for other ops, release on close - err = obd_create(&conn, &data->ioc_obdo1, &lsm); - if (!err) { - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - } - GOTO(out, err); - } - - case OBD_IOC_GETATTR: { - obd_data2conn(&conn, data); - err = obd_getattr(&conn, &data->ioc_obdo1, NULL); - if (!err) { - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - } - GOTO(out, err); - } - - case OBD_IOC_SETATTR: { - obd_data2conn(&conn, data); - err = obd_setattr(&conn, &data->ioc_obdo1, NULL); - if (!err) { - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - } - GOTO(out, err); - } - - case OBD_IOC_DESTROY: { - //void *ea; - obd_data2conn(&conn, data); - - err = obd_destroy(&conn, &data->ioc_obdo1, NULL); - if (!err) { - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - } - GOTO(out, err); - } - - case OBD_IOC_OPEN: { - struct lov_stripe_md *lsm = NULL; // XXX fill in from create - - obd_data2conn(&conn, data); - err = obd_open(&conn, &data->ioc_obdo1, lsm); - if (!err) { - err = copy_to_user((void *)arg, data, sizeof(*data)); - if (err) - err = -EFAULT; - } - GOTO(out, err); - } - - case OBD_IOC_CLOSE: { - struct lov_stripe_md *lsm = NULL; // XXX fill in from create - - obd_data2conn(&conn, data); - err = obd_close(&conn, &data->ioc_obdo1, lsm); - GOTO(out, err); -- } - - case OBD_IOC_BRW_WRITE: - rw = OBD_BRW_WRITE; - case OBD_IOC_BRW_READ: { - struct lov_stripe_md tmp_lsm; // XXX fill in from create - struct lov_stripe_md *lsm = &tmp_lsm; // XXX fill in from create - struct brw_cb_data *brw_cbd = ll_init_brw_cb_data(); - obd_count pages = 0; - struct brw_page *pga, *pgp; - __u64 id = data->ioc_obdo1.o_id; - int gfp_mask = (id & 1) ? GFP_HIGHUSER : GFP_KERNEL; - int verify = (id != 0); - __u64 off; - int j; - - if (!brw_cbd) - GOTO(out, err = -ENOMEM); - - obd_data2conn(&conn, data); - - pages = data->ioc_count / PAGE_SIZE; - off = data->ioc_offset; - - CDEBUG(D_INODE, "BRW %s with %d pages @ "LPX64"\n", - rw == OBD_BRW_READ ? "read" : "write", pages, off); - OBD_ALLOC(pga, pages * sizeof(*pga)); - if (!pga) { - CERROR("no memory for %d BRW per-page data\n", pages); - GOTO(brw_free, err = -ENOMEM); - } - - memset(lsm, 0, sizeof(*lsm)); // XXX don't do this later - lsm->lsm_object_id = id; // ensure id == lsm->lsm_object_id - - for (j = 0, pgp = pga; j < pages; j++, off += PAGE_SIZE, pgp++){ - pgp->pg = alloc_pages(gfp_mask, 0); - if (!pgp->pg) { - CERROR("no memory for brw pages\n"); - GOTO(brw_cleanup, err = -ENOMEM); - } - pgp->count = PAGE_SIZE; - pgp->off = off; - pgp->flag = 0; - - if (verify) { - void *addr = kmap(pgp->pg); - - if (rw == OBD_BRW_WRITE) - page_debug_setup(addr, pgp->count, - pgp->off, id); - else - page_debug_setup(addr, pgp->count, - 0xdeadbeef00c0ffee, - 0xdeadbeef00c0ffee); - kunmap(pgp->pg); - } - } - - err = obd_brw(rw, &conn, lsm, j, pga, ll_sync_brw_cb, brw_cbd); - if (err) - CERROR("test_brw: error from obd_brw: err = %d\n", err); - EXIT; - brw_cleanup: - for (j = 0, pgp = pga; j < pages; j++, pgp++) { - if (pgp->pg != NULL) { - if (verify && !err) { - void *addr = kmap(pgp->pg); -- - err = page_debug_check("test_brw", - addr, - PAGE_SIZE, - pgp->off,id); - kunmap(pgp->pg); - } - __free_pages(pgp->pg, 0); - } - } - brw_free: - OBD_FREE(pga, pages * sizeof(*pga)); - GOTO(out, err); - } -- default: -- obd_data2conn(&conn, data); -- -- err = obd_iocontrol(cmd, &conn, len, data, NULL); -- if (err) -- GOTO(out, err); -- -- err = copy_to_user((void *)arg, data, len); -- if (err) -- err = -EFAULT; -- GOTO(out, err); -- } -- -- out: -- if (buf) -- OBD_FREE(buf, len); -- if (serialised) -- up(&obd_conf_sem); -- RETURN(err); --} /* obd_class_ioctl */ -- -- -- --/* declare character device */ --static struct file_operations obd_psdev_fops = { - ioctl: obd_class_ioctl, /* ioctl */ - ioctl: obd_class_ioctl, /* ioctl */ -- open: obd_class_open, /* open */ - release: obd_class_release, /* release */ - release: obd_class_release, /* release */ --}; -- --/* modules setup */ --#define OBD_MINOR 241 --static struct miscdevice obd_psdev = { -- OBD_MINOR, -- "obd_psdev", -- &obd_psdev_fops --}; -- --void (*class_signal_connection_failure)(struct ptlrpc_connection *); -- --#ifdef CONFIG_HIGHMEM - #warning "using kmap accounting for deadlock avoidance" --/* Allow at most 3/4 of the kmap mappings to be consumed by vector I/O -- * requests. This avoids deadlocks on servers which have a lot of clients -- * doing vector I/O. We don't need to do this for non-vector I/O requests -- * because singleton requests will just block on the kmap itself and never -- * deadlock waiting for additional kmaps to complete. -- * -- * If we are a "server" task, we can have at most a single reservation -- * in excess of the maximum. This avoids a deadlock when multiple client -- * threads are on the same machine as the server threads, and the clients -- * have consumed all of the available mappings. As long as a single server -- * thread is can make progress, we are guaranteed to avoid deadlock. -- */ --#define OBD_KMAP_MAX (LAST_PKMAP * 3 / 4) --static atomic_t obd_kmap_count = ATOMIC_INIT(OBD_KMAP_MAX); --static DECLARE_WAIT_QUEUE_HEAD(obd_kmap_waitq); -- --void obd_kmap_get(int count, int server) --{ -- //CERROR("getting %d kmap counts (%d/%d)\n", count, -- // atomic_read(&obd_kmap_count), OBD_KMAP_MAX); -- if (count == 1) -- atomic_dec(&obd_kmap_count); -- else while (atomic_add_negative(-count, &obd_kmap_count)) { -- static long next_show = 0; -- static int skipped = 0; -- -- if (server && atomic_read(&obd_kmap_count) >= -PTL_MD_MAX_IOV) -- break; -- -- CDEBUG(D_OTHER, "negative kmap reserved count: %d\n", -- atomic_read(&obd_kmap_count)); -- atomic_add(count, &obd_kmap_count); -- -- if (time_after(jiffies, next_show)) { -- CERROR("blocking %s (and %d others) for kmaps\n", -- current->comm, skipped); -- next_show = jiffies + 5*HZ; -- skipped = 0; -- } else -- skipped++; -- wait_event(obd_kmap_waitq, -- atomic_read(&obd_kmap_count) >= count); -- } --} -- --void obd_kmap_put(int count) --{ -- atomic_add(count, &obd_kmap_count); -- /* Wake up sleepers. Sadly, this wakes up all of the tasks at once. -- * We could have something smarter here like: -- while (atomic_read(&obd_kmap_count) > 0) -- wake_up_nr(obd_kmap_waitq, 1); -- although we would need to set somewhere (probably obd_class_init): -- obd_kmap_waitq.flags |= WQ_FLAG_EXCLUSIVE; -- For now the wait_event() condition will handle this OK I believe. -- */ -- if (atomic_read(&obd_kmap_count) > 0) -- wake_up(&obd_kmap_waitq); --} -- --EXPORT_SYMBOL(obd_kmap_get); --EXPORT_SYMBOL(obd_kmap_put); --#endif -- --EXPORT_SYMBOL(obd_dev); --EXPORT_SYMBOL(obdo_cachep); --EXPORT_SYMBOL(obd_memory); --EXPORT_SYMBOL(obd_fail_loc); --EXPORT_SYMBOL(obd_timeout); --EXPORT_SYMBOL(obd_recovery_upcall); --EXPORT_SYMBOL(ptlrpc_put_connection_superhack); -- --EXPORT_SYMBOL(class_register_type); --EXPORT_SYMBOL(class_unregister_type); --EXPORT_SYMBOL(class_name2dev); --EXPORT_SYMBOL(class_uuid2dev); --EXPORT_SYMBOL(class_uuid2obd); --EXPORT_SYMBOL(class_new_export); --EXPORT_SYMBOL(class_destroy_export); --EXPORT_SYMBOL(class_connect); --EXPORT_SYMBOL(class_conn2export); --EXPORT_SYMBOL(class_conn2obd); --EXPORT_SYMBOL(class_conn2cliimp); --EXPORT_SYMBOL(class_conn2ldlmimp); --EXPORT_SYMBOL(class_disconnect); --EXPORT_SYMBOL(class_disconnect_all); - //EXPORT_SYMBOL(class_uuid_parse); --EXPORT_SYMBOL(class_uuid_unparse); - //EXPORT_SYMBOL(class_multi_setup); - //EXPORT_SYMBOL(class_multi_cleanup); -- --EXPORT_SYMBOL(class_signal_connection_failure); - EXPORT_SYMBOL(ll_sync_brw_cb); - EXPORT_SYMBOL(ll_init_brw_cb_data); --EXPORT_SYMBOL(class_nm_to_type); -- --static int __init init_obdclass(void) --{ -- struct obd_device *obd; -- int err; -- int i; -- - printk(KERN_INFO "OBD class driver v0.9, info@clusterfs.com\n"); - printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION - ", info@clusterfs.com\n"); -- -- sema_init(&obd_conf_sem, 1); -- INIT_LIST_HEAD(&obd_types); -- -- if ((err = misc_register(&obd_psdev))) { -- CERROR("cannot register %d err %d\n", OBD_MINOR, err); -- return err; -- } -- -- /* This struct is already zerod for us (static global) */ -- for (i = 0, obd = obd_dev; i < MAX_OBD_DEVICES; i++, obd++) -- obd->obd_minor = i; -- -- err = obd_init_caches(); -- -- if (err) -- return err; -- obd_sysctl_init(); -- -- err = lprocfs_reg_main(); -- -- return 0; --} -- --static void __exit cleanup_obdclass(void) --{ -- int i, err; -- ENTRY; -- -- misc_deregister(&obd_psdev); -- for (i = 0; i < MAX_OBD_DEVICES; i++) { -- struct obd_device *obd = &obd_dev[i]; -- if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) && -- OBT(obd) && OBP(obd, detach)) { -- /* XXX should this call generic detach otherwise? */ -- OBP(obd, detach)(obd); -- } -- } -- -- obd_cleanup_caches(); -- obd_sysctl_clean(); -- -- err = lprocfs_dereg_main(); -- -- CERROR("obd memory leaked: %ld bytes\n", obd_memory); -- EXIT; --} -- --/* Check that we're building against the appropriate version of the Lustre -- * kernel patch */ --#include - #if (LUSTRE_KERNEL_VERSION != 2) -#if (LUSTRE_KERNEL_VERSION != 3) --# error Cannot continue: Your Lustre kernel patch is out of date --#endif -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); - MODULE_DESCRIPTION("Lustre Class Driver v1.0"); -MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION); --MODULE_LICENSE("GPL"); -- --module_init(init_obdclass); --module_exit(cleanup_obdclass); diff --cc lustre/obdclass/debug.c index 8b28706,8b28706..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/debug.c +++ /dev/null @@@ -1,156 -1,156 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Helper routines for dumping data structs for debugging. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * Copryright (C) 2002 Cluster File Systems, Inc. -- * -- */ -- --#define DEBUG_SUBSYSTEM D_OTHER -- --#define EXPORT_SYMTAB --#include --#include --#include -- --int dump_ioo(struct obd_ioobj *ioo) --{ -- CERROR("obd_ioobj: ioo_id="LPD64", ioo_gr="LPD64", ioo_type=%d, ioo_bufct=%d\n", -- ioo->ioo_id, ioo->ioo_gr, ioo->ioo_type, ioo->ioo_bufcnt); -- return -EINVAL; --} -- --int dump_lniobuf(struct niobuf_local *nb) --{ -- CERROR("niobuf_local: addr=%p, offset="LPD64", len=%d, xid=%d, page=%p\n", -- nb->addr, nb->offset, nb->len, nb->xid, nb->page); -- CERROR("nb->page: index = %ld\n", nb->page ? nb->page->index : -1); -- -- return -EINVAL; --} -- --int dump_rniobuf(struct niobuf_remote *nb) --{ -- CERROR("niobuf_remote: offset="LPD64", len=%d, flags=%x, xid=%d\n", -- nb->offset, nb->len, nb->flags, nb->xid); -- -- return -EINVAL; --} -- --int dump_obdo(struct obdo *oa) --{ -- __u32 valid = oa->o_valid; -- -- CERROR("obdo: o_valid = %08x\n", valid); -- if (valid & OBD_MD_FLID) -- CERROR("obdo: o_id = "LPD64"\n", oa->o_id); -- if (valid & OBD_MD_FLATIME) -- CERROR("obdo: o_atime = "LPD64"\n", oa->o_atime); -- if (valid & OBD_MD_FLMTIME) -- CERROR("obdo: o_mtime = "LPD64"\n", oa->o_mtime); -- if (valid & OBD_MD_FLCTIME) -- CERROR("obdo: o_ctime = "LPD64"\n", oa->o_ctime); -- if (valid & OBD_MD_FLSIZE) -- CERROR("obdo: o_size = "LPD64"\n", oa->o_size); -- if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ -- CERROR("obdo: o_blocks = "LPD64"\n", oa->o_blocks); -- if (valid & OBD_MD_FLBLKSZ) -- CERROR("obdo: o_blksize = %d\n", oa->o_blksize); -- if (valid & (OBD_MD_FLTYPE | OBD_MD_FLMODE)) -- CERROR("obdo: o_mode = %o\n", -- oa->o_mode & ((valid & OBD_MD_FLTYPE ? S_IFMT : 0) | -- (valid & OBD_MD_FLMODE ? ~S_IFMT : 0))); -- if (valid & OBD_MD_FLUID) -- CERROR("obdo: o_uid = %d\n", oa->o_uid); -- if (valid & OBD_MD_FLGID) -- CERROR("obdo: o_gid = %d\n", oa->o_gid); -- if (valid & OBD_MD_FLFLAGS) -- CERROR("obdo: o_flags = %x\n", oa->o_flags); -- if (valid & OBD_MD_FLNLINK) -- CERROR("obdo: o_nlink = %d\n", oa->o_nlink); -- if (valid & OBD_MD_FLGENER) -- CERROR("obdo: o_generation = %d\n", oa->o_generation); -- -- return -EINVAL; --} -- --/* XXX assumes only a single page in request */ --/* --int dump_req(struct ptlrpc_request *req) --{ -- struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0); -- struct obd_ioobj *ioo = lustre_msg_buf(req->rq_reqmsg, 1); -- //struct niobuf *nb = lustre_msg_buf(req->rq_reqmsg, 2); -- -- dump_obdo(&body->oa); -- //dump_niobuf(nb); -- dump_ioo(ioo); -- -- return -EINVAL; --} --*/ -- --#define LPDS sizeof(__u64) --int page_debug_setup(void *addr, int len, __u64 off, __u64 id) --{ -- LASSERT(addr); -- -- off = HTON__u64(off); -- id = HTON__u64(id); -- memcpy(addr, (char *)&off, LPDS); -- memcpy(addr + LPDS, (char *)&id, LPDS); -- -- addr += len - LPDS - LPDS; -- memcpy(addr, (char *)&off, LPDS); -- memcpy(addr + LPDS, (char *)&id, LPDS); -- -- return 0; --} -- --int page_debug_check(char *who, void *addr, int end, __u64 off, __u64 id) --{ -- __u64 ne_off; -- int err = 0; -- -- LASSERT(addr); -- -- ne_off = HTON__u64(off); -- id = HTON__u64(id); -- if (memcmp(addr, (char *)&ne_off, LPDS)) { -- CERROR("%s: id "LPU64" offset "LPU64" off: "LPX64" != "LPX64"\n", -- who, id, off, *(__u64 *)addr, ne_off); -- err = -EINVAL; -- } -- if (memcmp(addr + LPDS, (char *)&id, LPDS)) { -- CERROR("%s: id "LPU64" offset "LPU64" id: "LPX64" != "LPX64"\n", -- who, id, off, *(__u64 *)(addr + LPDS), id); -- err = -EINVAL; -- } -- -- addr += end - LPDS - LPDS; -- if (memcmp(addr, (char *)&ne_off, LPDS)) { -- CERROR("%s: id "LPU64" offset "LPU64" end off: "LPX64" != "LPX64"\n", -- who, id, off, *(__u64 *)addr, ne_off); -- err = -EINVAL; -- } -- if (memcmp(addr + LPDS, (char *)&id, LPDS)) { -- CERROR("%s: id "LPU64" offset "LPU64" end id: "LPX64" != "LPX64"\n", -- who, id, off, *(__u64 *)(addr + LPDS), id); -- err = -EINVAL; -- } -- -- return err; --} --#undef LPDS -- --EXPORT_SYMBOL(dump_lniobuf); --EXPORT_SYMBOL(dump_rniobuf); --EXPORT_SYMBOL(dump_ioo); --//EXPORT_SYMBOL(dump_req); --EXPORT_SYMBOL(dump_obdo); --EXPORT_SYMBOL(page_debug_setup); --EXPORT_SYMBOL(page_debug_check); diff --cc lustre/obdclass/genops.c index 333159e,926991a..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/genops.c +++ /dev/null @@@ -1,572 -1,503 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * - * lustre/obdclass/genops.c - * Copyright (C) 2001-2002 Cluster File Systems, Inc. - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. -- * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre 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. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * These are the only exported functions, they provide some generic -- * infrastructure for managing object devices - * -- */ -- --#define DEBUG_SUBSYSTEM S_CLASS --#include /* for request_module() */ --#include --#include --#include --#include --#include -- --extern struct list_head obd_types; --kmem_cache_t *obdo_cachep = NULL; --kmem_cache_t *import_cachep = NULL; --kmem_cache_t *export_cachep = NULL; -- --int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c); - - /* I would prefer if these next four functions were in ptlrpc, to be honest, - * but obdclass uses them for the netregression ioctls. -phil */ - static int ll_sync_brw_timeout(void *data) - { - struct brw_cb_data *brw_cbd = data; - struct ptlrpc_bulk_desc *desc; - ENTRY; - - LASSERT(brw_cbd); - desc = brw_cbd->brw_desc; - - if (!desc) { - CERROR("no desc for timed-out BRW, reopen Bugzilla 214!\n"); - RETURN(0); /* back to sleep -- someone had better wake us up! */ - } - - LASSERT(desc->bd_connection); - - CERROR("IO of %d pages to/from %s:%d (conn %p) timed out\n", - desc->bd_page_count, desc->bd_connection->c_remote_uuid, - desc->bd_portal, desc->bd_connection); - desc->bd_connection->c_level = LUSTRE_CONN_RECOVD; - desc->bd_flags |= PTL_RPC_FL_TIMEOUT; - if (desc->bd_connection && class_signal_connection_failure) { - class_signal_connection_failure(desc->bd_connection); - - /* We go back to sleep, until we're resumed or interrupted. */ - RETURN(0); - } - - /* If we can't be recovered, just abort the syscall with -ETIMEDOUT. */ - RETURN(1); - } - - static int ll_sync_brw_intr(void *data) - { - struct brw_cb_data *brw_cbd = data; - struct ptlrpc_bulk_desc *desc = brw_cbd->brw_desc; - - ENTRY; - desc->bd_flags |= PTL_RPC_FL_INTR; - RETURN(1); /* ignored, as of this writing */ - } - - int ll_sync_brw_cb(struct brw_cb_data *brw_cbd, int err, int phase) - { - int ret; - ENTRY; - - if (phase == CB_PHASE_START) { - struct l_wait_info lwi; - lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, ll_sync_brw_timeout, - ll_sync_brw_intr, brw_cbd); - ret = l_wait_event(brw_cbd->brw_waitq, brw_cbd->brw_complete, &lwi); - if (atomic_dec_and_test(&brw_cbd->brw_refcount)) - OBD_FREE(brw_cbd, sizeof(*brw_cbd)); - if (ret == -EINTR) - RETURN(ret); - } else if (phase == CB_PHASE_FINISH) { - brw_cbd->brw_err = err; - brw_cbd->brw_complete = 1; - wake_up(&brw_cbd->brw_waitq); - if (atomic_dec_and_test(&brw_cbd->brw_refcount)) - OBD_FREE(brw_cbd, sizeof(*brw_cbd)); - RETURN(err); - } else - LBUG(); - EXIT; - return 0; - } - - struct brw_cb_data *ll_init_brw_cb_data(void) - { - struct brw_cb_data *brw_cbd; - - OBD_ALLOC(brw_cbd, sizeof(*brw_cbd)); - if (brw_cbd) { - init_waitqueue_head(&brw_cbd->brw_waitq); - atomic_set(&brw_cbd->brw_refcount, 2); - } - RETURN(brw_cbd); - } -- --/* -- * support functions: we could use inter-module communication, but this -- * is more portable to other OS's -- */ --static struct obd_type *class_search_type(char *nm) --{ -- struct list_head *tmp; -- struct obd_type *type; -- CDEBUG(D_INFO, "SEARCH %s\n", nm); -- -- tmp = &obd_types; -- list_for_each(tmp, &obd_types) { -- type = list_entry(tmp, struct obd_type, typ_chain); -- CDEBUG(D_INFO, "TYP %s\n", type->typ_name); -- if (strlen(type->typ_name) == strlen(nm) && -- strcmp(type->typ_name, nm) == 0 ) { -- return type; -- } -- } -- return NULL; --} -- --struct obd_type *class_nm_to_type(char *nm) --{ -- struct obd_type *type = class_search_type(nm); -- --#ifdef CONFIG_KMOD -- if ( !type ) { -- if ( !request_module(nm) ) { -- CDEBUG(D_INFO, "Loaded module '%s'\n", nm); -- type = class_search_type(nm); -- } else { -- CDEBUG(D_INFO, "Can't load module '%s'\n", nm); -- } -- } --#endif -- return type; --} -- - int class_register_type(struct obd_ops *ops, struct lprocfs_vars* vars, char *nm) -int class_register_type(struct obd_ops *ops, struct lprocfs_vars *vars, - char *nm) --{ -- struct obd_type *type; -- int rc; -- -- ENTRY; -- -- if (class_search_type(nm)) { -- CDEBUG(D_IOCTL, "Type %s already registered\n", nm); -- RETURN(-EEXIST); -- } -- -- OBD_ALLOC(type, sizeof(*type)); -- OBD_ALLOC(type->typ_ops, sizeof(*type->typ_ops)); -- OBD_ALLOC(type->typ_name, strlen(nm) + 1); -- if (!type) -- RETURN(-ENOMEM); -- INIT_LIST_HEAD(&type->typ_chain); -- CDEBUG(D_INFO, "MOD_INC_USE for register_type: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount)); -- MOD_INC_USE_COUNT; -- list_add(&type->typ_chain, &obd_types); -- memcpy(type->typ_ops, ops, sizeof(*type->typ_ops)); -- strcpy(type->typ_name, nm); -- rc = lprocfs_reg_class(type, vars, type); -- -- RETURN(rc); --} -- --int class_unregister_type(char *nm) --{ -- struct obd_type *type = class_nm_to_type(nm); -- -- ENTRY; -- -- if (!type) { -- CERROR("unknown obd type\n"); -- RETURN(-EINVAL); -- } -- -- if (type->typ_refcnt) { -- CERROR("type %s has refcount (%d)\n", nm, type->typ_refcnt); -- /* This is a bad situation, let's make the best of it */ -- /* Remove ops, but leave the name for debugging */ -- OBD_FREE(type->typ_ops, sizeof(*type->typ_ops)); -- RETURN(-EBUSY); -- } -- if(type->typ_procroot) -- lprocfs_dereg_class(type); -- -- list_del(&type->typ_chain); -- OBD_FREE(type->typ_name, strlen(nm) + 1); -- if (type->typ_ops != NULL) -- OBD_FREE(type->typ_ops, sizeof(*type->typ_ops)); -- OBD_FREE(type, sizeof(*type)); -- CDEBUG(D_INFO, "MOD_DEC_USE for register_type: count = %d\n", -- atomic_read(&(THIS_MODULE)->uc.usecount) - 1); -- MOD_DEC_USE_COUNT; -- RETURN(0); --} /* class_unregister_type */ -- --int class_name2dev(char *name) --{ -- int res = -1; -- int i; -- -- if (!name) -- return -1; -- -- for (i=0; i < MAX_OBD_DEVICES; i++) { -- struct obd_device *obd = &obd_dev[i]; -- if (obd->obd_name && strcmp(name, obd->obd_name) == 0) { -- res = i; -- return res; -- } -- } -- -- return res; --} -- --int class_uuid2dev(char *uuid) --{ -- int res = -1; -- int i; -- -- for (i=0; i < MAX_OBD_DEVICES; i++) { -- struct obd_device *obd = &obd_dev[i]; -- if (strncmp(uuid, obd->obd_uuid, sizeof(obd->obd_uuid)) == 0) { -- res = i; -- return res; -- } -- } -- -- return res; --} -- -- --struct obd_device *class_uuid2obd(char *uuid) --{ -- int i; -- -- for (i=0; i < MAX_OBD_DEVICES; i++) { -- struct obd_device *obd = &obd_dev[i]; -- if (strncmp(uuid, obd->obd_uuid, sizeof(obd->obd_uuid)) == 0) -- return obd; -- } -- -- return NULL; --} -- --void obd_cleanup_caches(void) --{ -- int rc; -- ENTRY; -- if (obdo_cachep) { -- rc = kmem_cache_destroy(obdo_cachep); -- if (rc) -- CERROR("Cannot destory ll_obdo_cache\n"); -- obdo_cachep = NULL; -- } -- if (import_cachep) { -- rc = kmem_cache_destroy(import_cachep); -- if (rc) -- CERROR("Cannot destory ll_import_cache\n"); -- import_cachep = NULL; -- } -- if (export_cachep) { -- rc = kmem_cache_destroy(export_cachep); -- if (rc) -- CERROR("Cannot destory ll_export_cache\n"); -- export_cachep = NULL; -- } -- EXIT; --} -- --int obd_init_caches(void) --{ -- ENTRY; -- LASSERT(obdo_cachep == NULL); -- obdo_cachep = kmem_cache_create("ll_obdo_cache", sizeof(struct obdo), -- 0, 0, NULL, NULL); -- if (!obdo_cachep) -- GOTO(out, -ENOMEM); -- -- LASSERT(export_cachep == NULL); -- export_cachep = kmem_cache_create("ll_export_cache", -- sizeof(struct obd_export), -- 0, 0, NULL, NULL); -- if (!export_cachep) -- GOTO(out, -ENOMEM); -- -- LASSERT(import_cachep == NULL); -- import_cachep = kmem_cache_create("ll_import_cache", -- sizeof(struct obd_import), -- 0, 0, NULL, NULL); -- if (!import_cachep) -- GOTO(out, -ENOMEM); -- -- RETURN(0); -- out: -- obd_cleanup_caches(); -- RETURN(-ENOMEM); -- --} -- --/* map connection to client */ --struct obd_export *class_conn2export(struct lustre_handle *conn) --{ -- struct obd_export *export; - ENTRY; -- -- if (!conn) { -- CDEBUG(D_CACHE, "looking for null handle\n"); -- RETURN(NULL); -- } -- -- if (conn->addr == -1) { /* this means assign a new connection */ -- CDEBUG(D_CACHE, "want a new connection\n"); -- RETURN(NULL); -- } -- -- if (!conn->addr) { -- CDEBUG(D_CACHE, "looking for null addr\n"); -- fixme(); -- RETURN(NULL); -- } -- -- CDEBUG(D_IOCTL, "looking for export addr "LPX64" cookie "LPX64"\n", -- conn->addr, conn->cookie); -- export = (struct obd_export *) (unsigned long)conn->addr; -- if (!kmem_cache_validate(export_cachep, (void *)export)) -- RETURN(NULL); -- -- if (export->exp_cookie != conn->cookie) -- RETURN(NULL); -- RETURN(export); --} /* class_conn2export */ -- --struct obd_device *class_conn2obd(struct lustre_handle *conn) --{ -- struct obd_export *export; -- export = class_conn2export(conn); -- if (export) -- return export->exp_obd; -- fixme(); -- return NULL; --} -- --struct obd_import *class_conn2cliimp(struct lustre_handle *conn) --{ -- return &class_conn2obd(conn)->u.cli.cl_import; --} -- --struct obd_import *class_conn2ldlmimp(struct lustre_handle *conn) --{ -- return &class_conn2export(conn)->exp_ldlm_data.led_import; --} -- --struct obd_export *class_new_export(struct obd_device *obddev) --{ -- struct obd_export * export; -- -- export = kmem_cache_alloc(export_cachep, GFP_KERNEL); -- if (!export) { -- CERROR("no memory! (minor %d)\n", obddev->obd_minor); -- return NULL; -- } -- -- memset(export, 0, sizeof(*export)); -- get_random_bytes(&export->exp_cookie, sizeof(export->exp_cookie)); -- export->exp_obd = obddev; -- /* XXX this should be in LDLM init */ -- INIT_LIST_HEAD(&export->exp_ldlm_data.led_held_locks); -- INIT_LIST_HEAD(&export->exp_conn_chain); -- spin_lock(&obddev->obd_dev_lock); -- list_add(&export->exp_obd_chain, &export->exp_obd->obd_exports); -- spin_unlock(&obddev->obd_dev_lock); -- return export; --} -- --void class_destroy_export(struct obd_export *exp) --{ -- ENTRY; -- -- LASSERT(exp->exp_cookie != DEAD_HANDLE_MAGIC); -- -- spin_lock(&exp->exp_obd->obd_dev_lock); -- list_del(&exp->exp_obd_chain); -- spin_unlock(&exp->exp_obd->obd_dev_lock); -- -- /* XXXshaver no connection here... */ -- if (exp->exp_connection) -- spin_lock(&exp->exp_connection->c_lock); -- list_del(&exp->exp_conn_chain); -- if (exp->exp_connection) { -- spin_unlock(&exp->exp_connection->c_lock); -- ptlrpc_put_connection_superhack(exp->exp_connection); -- } -- -- exp->exp_cookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(export_cachep, exp); -- -- EXIT; --} -- --/* a connection defines an export context in which preallocation can -- be managed. */ --int class_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid) --{ -- struct obd_export * export; -- if (conn == NULL) { -- LBUG(); -- return -EINVAL; -- } -- -- if (obd == NULL) { -- LBUG(); -- return -EINVAL; -- } -- -- export = class_new_export(obd); -- if (!export) -- return -ENOMEM; -- -- conn->addr = (__u64) (unsigned long)export; -- conn->cookie = export->exp_cookie; -- -- CDEBUG(D_IOCTL, "connect: addr %Lx cookie %Lx\n", -- (long long)conn->addr, (long long)conn->cookie); -- return 0; --} -- --int class_disconnect(struct lustre_handle *conn) --{ -- struct obd_export *export; -- ENTRY; -- -- if (!(export = class_conn2export(conn))) { -- fixme(); -- CDEBUG(D_IOCTL, "disconnect: attempting to free " -- "nonexistent client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- CDEBUG(D_IOCTL, "disconnect: addr %Lx cookie %Lx\n", -- (long long)conn->addr, (long long)conn->cookie); -- -- class_destroy_export(export); -- -- RETURN(0); --} -- --void class_disconnect_all(struct obd_device *obddev) --{ -- int again = 1; -- -- while (again) { -- spin_lock(&obddev->obd_dev_lock); -- if (!list_empty(&obddev->obd_exports)) { -- struct obd_export *export; -- struct lustre_handle conn; -- int rc; -- -- export = list_entry(obddev->obd_exports.next, -- struct obd_export, -- exp_obd_chain); -- conn.addr = (__u64)(unsigned long)export; -- conn.cookie = export->exp_cookie; -- spin_unlock(&obddev->obd_dev_lock); - CERROR("force disconnecting export %p\n", export); - CERROR("force disconnecting %s:%s export %p\n", - export->exp_obd->obd_type->typ_name, - export->exp_connection->c_remote_uuid, export); -- rc = obd_disconnect(&conn); -- if (rc < 0) { -- /* AED: not so sure about this... We can't -- * loop here forever, yet we shouldn't leak -- * exports on a struct we will soon destroy. -- */ -- CERROR("destroy export %p with err: rc = %d\n", -- export, rc); -- class_destroy_export(export); -- } -- } else { -- spin_unlock(&obddev->obd_dev_lock); -- again = 0; -- } -- } --} -- --#if 0 -- --/* FIXME: Data is a space- or comma-separated list of device IDs. This will -- * have to change. */ --int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data) --{ -- int count, rc; -- char *p; -- ENTRY; -- -- for (p = data, count = 0; p < (char *)data + len; count++) { -- char *end; -- int tmp = simple_strtoul(p, &end, 0); -- -- if (p == end) { -- CERROR("invalid device ID starting at: %s\n", p); -- GOTO(err_disconnect, rc = -EINVAL); -- } -- -- if (tmp < 0 || tmp >= MAX_OBD_DEVICES) { -- CERROR("Trying to sub dev %d - dev no too large\n", -- tmp); -- GOTO(err_disconnect, rc = -EINVAL); -- } -- -- rc = obd_connect(&obddev->obd_multi_conn[count], &obd_dev[tmp]); -- if (rc) { -- CERROR("cannot connect to device %d: rc = %d\n", tmp, -- rc); -- GOTO(err_disconnect, rc); -- } -- -- CDEBUG(D_INFO, "target OBD %d is of type %s\n", count, -- obd_dev[tmp].obd_type->typ_name); -- -- p = end + 1; -- } -- -- obddev->obd_multi_count = count; -- -- RETURN(0); -- -- err_disconnect: -- for (count--; count >= 0; count--) -- obd_disconnect(&obddev->obd_multi_conn[count]); -- return rc; --} -- --/* -- * remove all connections to this device -- * close all connections to lower devices -- * needed for forced unloads of OBD client drivers -- */ --int class_multi_cleanup(struct obd_device *obddev) --{ -- int i; -- -- for (i = 0; i < obddev->obd_multi_count; i++) { -- int rc; -- struct obd_device *obd = -- class_conn2obd(&obddev->obd_multi_conn[i]); -- -- if (!obd) { -- CERROR("no such device [i %d]\n", i); -- RETURN(-EINVAL); -- } -- -- rc = obd_disconnect(&obddev->obd_multi_conn[i]); -- if (rc) -- CERROR("disconnect failure %d\n", obd->obd_minor); -- } -- return 0; --} --#endif diff --cc lustre/obdclass/lprocfs_status.c index 1f8316c,62a806e..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/lprocfs_status.c +++ /dev/null @@@ -1,326 -1,331 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Author: Hariharan Thantry thantry@users.sourceforge.net -- */ --#define EXPORT_SYMTAB --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_CLASS --#include --#include -- --#ifdef LPROC_SNMP -- --#define DEFAULT_MODE 0444 --/* -- * Tokenizer array. Change this array to include special -- * characters for string tokenizing -- */ --const char tok[] = {'/', '\0'}; -- --/* -- * Externs -- */ --extern struct proc_dir_entry proc_root; /* Defined in proc/root.c */ -- --/* -- * Globals -- */ --struct proc_dir_entry *proc_lustre_root; --struct proc_dir_entry *proc_lustre_dev_root; --struct proc_dir_entry *proc_lustre_fs_root; -- --struct proc_dir_entry* lprocfs_mkdir(const char* dname, -- struct proc_dir_entry *parent) --{ -- struct proc_dir_entry *child_dir_entry; -- child_dir_entry = proc_mkdir(dname, parent); -- if (!child_dir_entry) -- CERROR("lustre: failed to create /proc entry %s\n", dname); -- return child_dir_entry; --} -- --struct proc_dir_entry* lprocfs_srch(struct proc_dir_entry* head, -- const char* name) --{ -- struct proc_dir_entry* temp; -- if (!head) -- return NULL; -- temp = head->subdir; -- while (temp != NULL) { -- if (!strcmp(temp->name, name)) -- return temp; -- temp = temp->next; -- } -- return NULL; --} -- --void lprocfs_remove_all(struct proc_dir_entry* root) --{ -- struct proc_dir_entry *temp = root; -- struct proc_dir_entry *rm_entry; -- struct proc_dir_entry *parent = root->parent; -- -- while (1) { -- while (temp->subdir) -- temp = temp->subdir; -- -- rm_entry = temp; -- temp = temp->parent; -- remove_proc_entry(rm_entry->name, rm_entry->parent); -- if (temp == parent) break; -- } --} -- --#define MAX_STRING_SIZE 100 --struct proc_dir_entry* lprocfs_new_dir(struct proc_dir_entry* root, -- const char* string, const char* tok) --{ -- struct proc_dir_entry* new_root; -- struct proc_dir_entry* temp_entry; - char temp_string[MAX_STRING_SIZE]; - char temp_string[MAX_STRING_SIZE+1]; -- char* my_str; -- char* mover_str; -- - strncpy(temp_string, string, MAX_STRING_SIZE-1); - strncpy(temp_string, string, MAX_STRING_SIZE); -- temp_string[MAX_STRING_SIZE] = '\0'; -- -- new_root = root; -- mover_str = temp_string; -- while ((my_str = strsep(&mover_str, tok))) { -- if(!*my_str) -- continue; -- CDEBUG(D_OTHER, "SEARCH= %s\t, ROOT=%s\n", my_str, -- new_root->name); -- temp_entry = lprocfs_srch(new_root, my_str); -- if (temp_entry == NULL) { -- CDEBUG(D_OTHER, "Adding: %s\n", my_str); -- temp_entry = lprocfs_mkdir(my_str, new_root); -- if (temp_entry == NULL) { -- CDEBUG(D_OTHER, -- "! Did not create new dir %s !!\n", -- my_str); -- return temp_entry; -- } -- } -- new_root = temp_entry; -- } -- return new_root; --} -- --int lprocfs_new_vars(struct proc_dir_entry* root, -- struct lprocfs_vars* list, -- const char* tok, void* data) --{ -- struct proc_dir_entry *temp_root; -- struct proc_dir_entry *new_leaf; -- struct proc_dir_entry *new_parent; - char temp_string[MAX_STRING_SIZE]; - char temp_string[MAX_STRING_SIZE+1]; -- -- if (list == NULL) -- return 0; -- -- while (list->name) { -- temp_root = lprocfs_new_dir(root, list->name, tok); -- if (temp_root == NULL) { -- CDEBUG(D_OTHER, "!LProcFS: Mods: No root!"); - return -EINVAL; - return -ENOMEM; -- } -- -- /* Convert the last element into a leaf-node */ - strncpy(temp_string, temp_root->name, MAX_STRING_SIZE-1); - strncpy(temp_string, temp_root->name, MAX_STRING_SIZE); -- temp_string[MAX_STRING_SIZE] = '\0'; -- new_parent = temp_root->parent; -- remove_proc_entry(temp_root->name, new_parent); -- new_leaf = create_proc_entry(temp_string, DEFAULT_MODE, -- new_parent); - if (new_leaf == NULL) { - CERROR("LprocFS: No memory to create /proc entry %s", - temp_string); - return -ENOMEM; - } -- new_leaf->read_proc = list->read_fptr; -- new_leaf->write_proc = list->write_fptr; -- if (data) -- new_leaf->data=data; -- else -- new_leaf->data=list->data; -- list++; -- } -- return 0; -- --} --#undef MAX_STRING_SIZE --/* -- * API implementations -- */ --int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *var, -- void *data) --{ -- return lprocfs_new_vars(root, var, tok, data); --} -- --int lprocfs_reg_obd(struct obd_device *device, struct lprocfs_vars *list, -- void *data) --{ -- struct proc_dir_entry* this_dev_root; -- int retval; -- -- if(lprocfs_srch(device->obd_type->typ_procroot, device->obd_name)){ -- CDEBUG(D_OTHER, "Device with name [%s] exists!", -- device->obd_name); -- return 0; -- } -- -- /* Obtain this device root */ -- this_dev_root = lprocfs_mkdir(device->obd_name, -- device->obd_type->typ_procroot); -- -- device->obd_proc_entry = this_dev_root; -- retval = lprocfs_add_vars(this_dev_root, list, data); -- -- return retval; --} -- --int lprocfs_dereg_obd(struct obd_device* device) --{ -- CDEBUG(D_OTHER, "LPROCFS removing device = %s\n", device->obd_name); -- -- if (device == NULL) { -- CDEBUG(D_OTHER, "! LProcfs: Null pointer !\n"); -- return 0; -- } -- if (device->obd_proc_entry == NULL) { -- CDEBUG(D_OTHER, "! Proc entry non-existent !"); -- return 0; -- } -- lprocfs_remove_all(device->obd_proc_entry); -- device->obd_proc_entry = NULL; -- if (device->counters) -- OBD_FREE(device->counters, device->cntr_mem_size); -- -- return 0; --} -- --struct proc_dir_entry* lprocfs_reg_mnt(char* mnt_name) --{ -- if(lprocfs_srch(proc_lustre_fs_root, mnt_name)){ -- CDEBUG(D_OTHER, "Mount with same name exists!"); -- return 0; -- } -- return lprocfs_mkdir(mnt_name, proc_lustre_fs_root); --} -- --int lprocfs_dereg_mnt(struct proc_dir_entry* root) --{ -- if(root == NULL){ -- CDEBUG(D_OTHER, "Non-existent root!"); -- return 0; -- } -- lprocfs_remove_all(root); -- return 0; --} -- --int lprocfs_reg_class(struct obd_type* type, struct lprocfs_vars* list, -- void* data) --{ -- -- struct proc_dir_entry* root; -- int retval; -- root = lprocfs_mkdir(type->typ_name, proc_lustre_dev_root); -- lprocfs_add_vars(root, list, data); -- type->typ_procroot = root; -- retval = lprocfs_add_vars(root, list, data); -- return retval; --} -- --int lprocfs_dereg_class(struct obd_type* class) --{ -- if(class == NULL){ -- CDEBUG(D_OTHER, "Non-existent class", -- class->typ_name); -- return 0; -- } -- lprocfs_remove_all(class->typ_procroot); -- class->typ_procroot = NULL; -- CDEBUG(D_OTHER, "LPROCFS removed = %s\n", class->typ_name); -- return 0; -- --} --int lprocfs_reg_main() --{ -- proc_lustre_root = lprocfs_mkdir("lustre", &proc_root); -- if (proc_lustre_root == NULL) { -- CERROR(" !! Cannot create /proc/lustre !! \n"); -- return -EINVAL; -- } -- -- proc_lustre_dev_root = lprocfs_mkdir("devices", proc_lustre_root); -- if (proc_lustre_dev_root == NULL) { -- CERROR(" !! Cannot create /proc/lustre/devices !! \n"); -- return -EINVAL; -- } -- proc_lustre_fs_root = lprocfs_mkdir("mnt_pnt", proc_lustre_root); -- -- if (proc_lustre_fs_root == NULL) { -- CERROR(" !! Cannot create /proc/lustre/mnt_pnt !! \n"); -- return -EINVAL; -- } -- -- return 0; --} -- --int lprocfs_dereg_main() --{ -- lprocfs_remove_all(proc_lustre_root); -- proc_lustre_root = NULL; -- proc_lustre_dev_root = NULL; -- proc_lustre_fs_root = NULL; -- return 0; --} -- -- --/* -- * Needs to go... -- */ --int lprocfs_ll_rd(char *page, char **start, off_t off, -- int count, int *eof, void *data) --{ -- __u64 *temp = (__u64 *)data; -- int len; -- len = snprintf(page, count, LPU64"\n", *temp); -- return len; --} -- --#endif /* LPROC_SNMP */ -- --EXPORT_SYMBOL(lprocfs_reg_obd); --EXPORT_SYMBOL(lprocfs_dereg_obd); --EXPORT_SYMBOL(lprocfs_reg_main); --EXPORT_SYMBOL(lprocfs_dereg_main); --EXPORT_SYMBOL(lprocfs_reg_mnt); --EXPORT_SYMBOL(lprocfs_dereg_mnt); --EXPORT_SYMBOL(lprocfs_add_vars); --EXPORT_SYMBOL(lprocfs_reg_class); --EXPORT_SYMBOL(lprocfs_dereg_class); --EXPORT_SYMBOL(lprocfs_ll_rd); -- -- diff --cc lustre/obdclass/sysctl.c index 8e74aab,8e74aab..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/sysctl.c +++ /dev/null @@@ -1,133 -1,133 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_CLASS -- --#include -- --struct ctl_table_header *obd_table_header = NULL; -- --static int vars[2]; --static int index = 0; -- --static int obd_sctl_vars( ctl_table * table, int write, struct file * -- filp, void * buffer, size_t * lenp ); --static int obd_sctl_reset( ctl_table * table, int write, struct file -- * filp, void * buffer, size_t * lenp ); -- --#define OBD_SYSCTL 300 -- --#define OBD_FAIL_LOC 1 /* control test failures instrumentation */ --#define OBD_ENTRY 2 /* control enter/leave pattern */ --#define OBD_VARS 3 --#define OBD_INDEX 4 --#define OBD_RESET 5 --#define OBD_TIMEOUT 6 /* RPC timeout before recovery/intr */ --/* XXX move to /proc/sys/lustre/recovery? */ --#define OBD_UPCALL 7 /* path to recovery upcall */ -- --#define OBD_VARS_SLOT 2 -- --static ctl_table obd_table[] = { -- {OBD_FAIL_LOC, "fail_loc", &obd_fail_loc, sizeof(int), 0644, NULL, &proc_dointvec}, -- {OBD_VARS, "vars", &vars[0], sizeof(int), 0644, NULL, &proc_dointvec}, -- {OBD_INDEX, "index", &index, sizeof(int), 0644, NULL, &obd_sctl_vars}, -- {OBD_RESET, "reset", NULL, 0, 0644, NULL, &obd_sctl_reset}, -- {OBD_TIMEOUT, "timeout", &obd_timeout, sizeof(int), 0644, NULL, &proc_dointvec}, -- /* XXX need to lock so we avoid update races with the recovery upcall! */ -- {OBD_UPCALL, "recovery_upcall", obd_recovery_upcall, 128, 0644, NULL, -- &proc_dostring, &sysctl_string }, -- { 0 } --}; -- --static ctl_table parent_table[] = { -- {OBD_SYSCTL, "lustre", NULL, 0, 0555, obd_table}, -- {0} --}; -- --void obd_sysctl_init (void) --{ --#ifdef CONFIG_SYSCTL -- if ( !obd_table_header ) -- obd_table_header = register_sysctl_table(parent_table, 0); --#endif --} -- --void obd_sysctl_clean (void) --{ --#ifdef CONFIG_SYSCTL -- if ( obd_table_header ) -- unregister_sysctl_table(obd_table_header); -- obd_table_header = NULL; --#endif --} -- --int obd_sctl_reset (ctl_table * table, int write, -- struct file * filp, void * buffer, -- size_t * lenp) --{ -- if ( write ) { -- /* do something here */ -- vars[0]=0; -- vars[1]=0; -- } -- -- *lenp = 0; -- return 0; --} -- --int obd_sctl_vars (ctl_table * table, int write, -- struct file * filp, void * buffer, -- size_t * lenp) --{ -- int rc; -- -- rc = proc_dointvec(table, write, filp, buffer, lenp); -- -- if ( rc ) -- return rc; -- -- if ( index < 0 || index > 1 ) { -- CERROR("Illegal index %d!\n", index); -- index = 0; -- } else { -- obd_table[OBD_VARS_SLOT].data = &vars[index]; -- } -- -- return rc; --} diff --cc lustre/obdclass/uuid.c index 7048baa,7048baa..0000000 deleted file mode 100644,100644 --- a/lustre/obdclass/uuid.c +++ /dev/null @@@ -1,136 -1,136 +1,0 @@@ --/* -- * Public include file for the UUID library -- * -- * Copyright (C) 1996, 1997, 1998 Theodore Ts'o. -- * Copyright (C) 2002 Cluster File System -- * - changed for use in lustre -- * -- * %Begin-Header% -- * This file may be redistributed under the terms of the GNU -- * Library General Public License. -- * %End-Header% -- */ --#include --#include -- --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include --#include -- --struct uuid { -- __u32 time_low; -- __u16 time_mid; -- __u16 time_hi_and_version; -- __u16 clock_seq; -- __u8 node[6]; --}; -- --static void uuid_unpack(class_uuid_t in, struct uuid *uu) --{ -- __u8 *ptr = in; -- __u32 tmp; -- -- tmp = *ptr++; -- tmp = (tmp << 8) | *ptr++; -- tmp = (tmp << 8) | *ptr++; -- tmp = (tmp << 8) | *ptr++; -- uu->time_low = tmp; -- -- tmp = *ptr++; -- tmp = (tmp << 8) | *ptr++; -- uu->time_mid = tmp; -- -- tmp = *ptr++; -- tmp = (tmp << 8) | *ptr++; -- uu->time_hi_and_version = tmp; -- -- tmp = *ptr++; -- tmp = (tmp << 8) | *ptr++; -- uu->clock_seq = tmp; -- -- memcpy(uu->node, ptr, 6); --} -- --#if 0 --static void uuid_pack(struct uuid *uu, class_uuid_t ptr) --{ -- __u32 tmp; -- unsigned char *out = ptr; -- -- tmp = uu->time_low; -- out[3] = (unsigned char) tmp; -- tmp >>= 8; -- out[2] = (unsigned char) tmp; -- tmp >>= 8; -- out[1] = (unsigned char) tmp; -- tmp >>= 8; -- out[0] = (unsigned char) tmp; -- -- tmp = uu->time_mid; -- out[5] = (unsigned char) tmp; -- tmp >>= 8; -- out[4] = (unsigned char) tmp; -- -- tmp = uu->time_hi_and_version; -- out[7] = (unsigned char) tmp; -- tmp >>= 8; -- out[6] = (unsigned char) tmp; -- -- tmp = uu->clock_seq; -- out[9] = (unsigned char) tmp; -- tmp >>= 8; -- out[8] = (unsigned char) tmp; -- -- memcpy(out+10, uu->node, 6); --} -- --int class_uuid_parse(obd_uuid_t in, class_uuid_t uu) --{ -- struct uuid uuid; -- int i; -- char *cp, buf[3]; -- -- if (strlen(in) != 36) -- return -1; -- for (i=0, cp = in; i <= 36; i++,cp++) { -- if ((i == 8) || (i == 13) || (i == 18) || -- (i == 23)) -- if (*cp == '-') -- continue; -- if (i== 36) -- if (*cp == 0) -- continue; -- if (!isxdigit(*cp)) -- return -1; -- } -- uuid.time_low = simple_strtoul(in, NULL, 16); -- uuid.time_mid = simple_strtoul(in+9, NULL, 16); -- uuid.time_hi_and_version = simple_strtoul(in+14, NULL, 16); -- uuid.clock_seq = simple_strtoul(in+19, NULL, 16); -- cp = in+24; -- buf[2] = 0; -- for (i=0; i < 6; i++) { -- buf[0] = *cp++; -- buf[1] = *cp++; -- uuid.node[i] = simple_strtoul(buf, NULL, 16); -- } -- -- uuid_pack(&uuid, uu); -- return 0; --} --#endif -- --void class_uuid_unparse(class_uuid_t uu, obd_uuid_t out) --{ -- struct uuid uuid; -- -- uuid_unpack(uu, &uuid); -- sprintf(out, -- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", -- uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, -- uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, -- uuid.node[0], uuid.node[1], uuid.node[2], -- uuid.node[3], uuid.node[4], uuid.node[5]); --} diff --cc lustre/obdecho/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/obdecho/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/obdecho/Makefile.am index b0ddafe,ad0e0ff..0000000 deleted file mode 100644,100644 --- a/lustre/obdecho/Makefile.am +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= --MODULE = obdecho --modulefs_DATA = obdecho.o --EXTRA_PROGRAMS = obdecho -- --LINX= - obdecho_SOURCES = echo.c lproc_echo.c $(LINX) -obdecho_SOURCES = echo.c echo_client.c lproc_echo.c $(LINX) -- --include $(top_srcdir)/Rules -- diff --cc lustre/obdecho/echo.c index 4934e15,76fddd8..0000000 deleted file mode 100644,100644 --- a/lustre/obdecho/echo.c +++ /dev/null @@@ -1,493 -1,507 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * - * linux/fs/obdecho/echo.c - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger -- * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * This file is part of Lustre, http://www.lustre.org. -- * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. -- * - * by Peter Braam - * and Andreas Dilger - * Lustre 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. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- - static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.48 2002/11/13 04:45:21 thantry Exp $"; - #define OBDECHO_VERSION "$Revision: 1.48 $" -#define OBDECHO_VERSION "1.0" -- --#define EXPORT_SYMTAB -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_ECHO -- --#include --#include --#include --#include --#include --#include -- --static atomic_t echo_page_rws; --static atomic_t echo_getattrs; -- --#define ECHO_PROC_STAT "sys/obdecho" --#define ECHO_INIT_OBJID 0x1000000000000000ULL -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --int echo_proc_read(char *page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- long long attrs = atomic_read(&echo_getattrs); -- long long pages = atomic_read(&echo_page_rws); -- int len; -- -- *eof = 1; -- if (off != 0) -- return (0); -- -- len = sprintf(page, "%Ld %Ld\n", attrs, pages); -- -- *start = page; -- return (len); --} -- --int echo_proc_write(struct file *file, const char *ubuffer, -- unsigned long count, void *data) --{ -- /* Ignore what we've been asked to write, and just zero the counters */ -- atomic_set (&echo_page_rws, 0); -- atomic_set (&echo_getattrs, 0); -- -- return (count); --} -- --void echo_proc_init(void) --{ -- struct proc_dir_entry *entry; -- -- entry = create_proc_entry(ECHO_PROC_STAT, S_IFREG|S_IRUGO|S_IWUSR,NULL); -- -- if (entry == NULL) { -- CERROR("couldn't create proc entry %s\n", ECHO_PROC_STAT); -- return; -- } -- -- entry->data = NULL; -- entry->read_proc = echo_proc_read; -- entry->write_proc = echo_proc_write; --} -- --void echo_proc_fini(void) --{ -- remove_proc_entry(ECHO_PROC_STAT, 0); --} -- --static int echo_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- int rc; -- -- MOD_INC_USE_COUNT; -- rc = class_connect(conn, obd, cluuid); -- -- if (rc) -- MOD_DEC_USE_COUNT; -- -- return rc; --} -- --static int echo_disconnect(struct lustre_handle *conn) --{ -- int rc; -- -- rc = class_disconnect(conn); -- if (!rc) -- MOD_DEC_USE_COUNT; -- -- return rc; --} -- --static __u64 echo_next_id(struct obd_device *obddev) --{ -- obd_id id; -- -- spin_lock(&obddev->u.echo.eo_lock); -- id = ++obddev->u.echo.eo_lastino; -- spin_unlock(&obddev->u.echo.eo_lock); -- -- return id; --} -- --int echo_create(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md **ea) --{ -- struct obd_device *obd = class_conn2obd(conn); -- -- if (!obd) { -- CERROR("invalid client %Lx\n", conn->addr); -- return -EINVAL; -- } -- -- if (!(oa->o_mode && S_IFMT)) { -- CERROR("filter obd: no type!\n"); -- return -ENOENT; -- } -- -- if (!(oa->o_valid & OBD_MD_FLTYPE)) { -- CERROR("invalid o_valid %08x\n", oa->o_valid); -- return -EINVAL; -- } -- -- oa->o_id = echo_next_id(obd); -- oa->o_valid = OBD_MD_FLID; -- atomic_inc(&obd->u.echo.eo_create); -- -- return 0; --} -- --int echo_destroy(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea) --{ -- struct obd_device *obd = class_conn2obd(conn); -- -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if (!(oa->o_valid & OBD_MD_FLID)) { -- CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); -- RETURN(-EINVAL); -- } -- -- if (oa->o_id > obd->u.echo.eo_lastino || oa->o_id < ECHO_INIT_OBJID) { -- CERROR("bad destroy objid: "LPX64"\n", oa->o_id); -- RETURN(-EINVAL); -- } -- -- atomic_inc(&obd->u.echo.eo_destroy); -- -- return 0; --} -- --static int echo_open(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- return 0; --} -- --static int echo_close(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- return 0; --} -- --static int echo_getattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct obd_device *obd = class_conn2obd(conn); -- obd_id id = oa->o_id; -- -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if (!(oa->o_valid & OBD_MD_FLID)) { -- CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); -- RETURN(-EINVAL); -- } -- -- memcpy(oa, &obd->u.echo.oa, sizeof(*oa)); -- oa->o_id = id; -- oa->o_valid |= OBD_MD_FLID; -- -- atomic_inc(&echo_getattrs); -- -- return 0; --} -- --static int echo_setattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct obd_device *obd = class_conn2obd(conn); -- -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if (!(oa->o_valid & OBD_MD_FLID)) { -- CERROR("obdo missing FLID valid flag: %08x\n", oa->o_valid); -- RETURN(-EINVAL); -- } -- -- memcpy(&obd->u.echo.oa, oa, sizeof(*oa)); -- -- atomic_inc(&obd->u.echo.eo_setattr); -- -- return 0; --} -- --/* This allows us to verify that desc_private is passed unmolested */ --#define DESC_PRIV 0x10293847 -- --int echo_preprw(int cmd, struct lustre_handle *conn, int objcount, -- struct obd_ioobj *obj, int niocount, struct niobuf_remote *nb, -- struct niobuf_local *res, void **desc_private) --{ -- struct obd_device *obd; -- struct niobuf_local *r = res; -- int rc = 0; -- int i; -- -- ENTRY; -- -- obd = class_conn2obd(conn); -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- memset(res, 0, sizeof(*res) * niocount); -- -- CDEBUG(D_PAGE, "%s %d obdos with %d IOs\n", -- cmd == OBD_BRW_READ ? "reading" : "writing", objcount, niocount); -- -- *desc_private = (void *)DESC_PRIV; -- -- obd_kmap_get(niocount, 1); -- -- for (i = 0; i < objcount; i++, obj++) { -- int gfp_mask = (obj->ioo_id & 1) ? GFP_HIGHUSER : GFP_KERNEL; -- int verify = obj->ioo_id != 0; -- int j; -- -- for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) { -- r->page = alloc_pages(gfp_mask, 0); -- if (!r->page) { -- CERROR("can't get page %d/%d for id "LPU64"\n", -- j, obj->ioo_bufcnt, obj->ioo_id); -- GOTO(preprw_cleanup, rc = -ENOMEM); -- } -- atomic_inc(&obd->u.echo.eo_prep); -- -- r->offset = nb->offset; -- r->addr = kmap(r->page); -- r->len = nb->len; -- -- CDEBUG(D_PAGE, "$$$$ get page %p, addr %p@"LPU64"\n", -- r->page, r->addr, r->offset); -- -- if (verify && cmd == OBD_BRW_READ) -- page_debug_setup(r->addr, r->len, r->offset, -- obj->ioo_id); -- else if (verify) -- page_debug_setup(r->addr, r->len, -- 0xecc0ecc0ecc0ecc0, -- 0xecc0ecc0ecc0ecc0); -- } -- } -- CDEBUG(D_PAGE, "%d pages allocated after prep\n", -- atomic_read(&obd->u.echo.eo_prep)); -- -- RETURN(0); -- --preprw_cleanup: -- /* It is possible that we would rather handle errors by allow -- * any already-set-up pages to complete, rather than tearing them -- * all down again. I believe that this is what the in-kernel -- * prep/commit operations do. -- */ -- CERROR("cleaning up %ld pages (%d obdos)\n", (long)(r - res), objcount); -- while (r-- > res) { -- kunmap(r->page); -- __free_pages(r->page, 0); -- atomic_dec(&obd->u.echo.eo_prep); -- } -- obd_kmap_put(niocount); -- memset(res, 0, sizeof(*res) * niocount); -- -- return rc; --} -- --int echo_commitrw(int cmd, struct lustre_handle *conn, int objcount, -- struct obd_ioobj *obj, int niocount, struct niobuf_local *res, -- void *desc_private) --{ -- struct obd_device *obd; -- struct niobuf_local *r = res; -- int rc = 0; -- int i; -- ENTRY; -- -- obd = class_conn2obd(conn); -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if ((cmd & OBD_BRW_RWMASK) == OBD_BRW_READ) { -- CDEBUG(D_PAGE, "reading %d obdos with %d IOs\n", -- objcount, niocount); -- } else { -- CDEBUG(D_PAGE, "writing %d obdos with %d IOs\n", -- objcount, niocount); -- } -- -- if (niocount && !r) { -- CERROR("NULL res niobuf with niocount %d\n", niocount); -- RETURN(-EINVAL); -- } -- -- LASSERT(desc_private == (void *)DESC_PRIV); -- -- for (i = 0; i < objcount; i++, obj++) { -- int verify = obj->ioo_id != 0; -- int j; -- -- for (j = 0 ; j < obj->ioo_bufcnt ; j++, r++) { -- struct page *page = r->page; -- void *addr; -- -- if (!page || !(addr = page_address(page)) || -- !kern_addr_valid(addr)) { -- -- CERROR("bad page objid "LPU64":%p, buf %d/%d\n", -- obj->ioo_id, page, j, obj->ioo_bufcnt); -- GOTO(commitrw_cleanup, rc = -EFAULT); -- } -- -- atomic_inc(&echo_page_rws); -- -- CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@"LPU64"\n", -- r->page, addr, r->offset); -- -- if (verify) -- page_debug_check("echo", addr, r->len, -- r->offset, obj->ioo_id); -- -- kunmap(page); -- obd_kmap_put(1); -- __free_pages(page, 0); -- atomic_dec(&obd->u.echo.eo_prep); -- } -- } -- CDEBUG(D_PAGE, "%d pages remain after commit\n", -- atomic_read(&obd->u.echo.eo_prep)); -- RETURN(0); -- --commitrw_cleanup: -- CERROR("cleaning up %ld pages (%d obdos)\n", -- niocount - (long)(r - res) - 1, objcount); -- while (++r < res + niocount) { -- struct page *page = r->page; -- -- kunmap(page); -- obd_kmap_put(1); -- __free_pages(page, 0); -- atomic_dec(&obd->u.echo.eo_prep); -- } -- return rc; --} -- --static int echo_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- ENTRY; -- -- obddev->obd_namespace = -- ldlm_namespace_new("echo-tgt", LDLM_NAMESPACE_SERVER); -- if (obddev->obd_namespace == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- spin_lock_init(&obddev->u.echo.eo_lock); -- obddev->u.echo.eo_lastino = ECHO_INIT_OBJID; -- -- RETURN(0); --} -- --static int echo_cleanup(struct obd_device *obddev) --{ -- ENTRY; -- -- ldlm_namespace_free(obddev->obd_namespace); -- CERROR("%d prep/commitrw pages leaked\n", -- atomic_read(&obddev->u.echo.eo_prep)); -- -- RETURN(0); --} -- --int echo_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- --int echo_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); --} - -- - struct obd_ops echo_obd_ops = { -static struct obd_ops echo_obd_ops = { -- o_attach: echo_attach, -- o_detach: echo_detach, -- o_connect: echo_connect, -- o_disconnect: echo_disconnect, -- o_create: echo_create, -- o_destroy: echo_destroy, -- o_open: echo_open, -- o_close: echo_close, -- o_getattr: echo_getattr, -- o_setattr: echo_setattr, -- o_preprw: echo_preprw, -- o_commitrw: echo_commitrw, -- o_setup: echo_setup, -- o_cleanup: echo_cleanup --}; - -extern int echo_client_init(void); -extern void echo_client_cleanup(void); -- --static int __init obdecho_init(void) --{ -- int rc; - -- -- printk(KERN_INFO "Echo OBD driver " OBDECHO_VERSION -- " info@clusterfs.com\n"); -- -- echo_proc_init(); - rc = class_register_type(&echo_obd_ops, status_class_var, - rc = class_register_type(&echo_obd_ops, status_class_var, -- OBD_ECHO_DEVICENAME); - RETURN(rc); - - if (rc) - RETURN(rc); - - rc = echo_client_init(); - if (rc) - class_unregister_type(OBD_ECHO_DEVICENAME); -- - RETURN(rc); --} -- --static void __exit obdecho_exit(void) --{ - -- echo_proc_fini(); - echo_client_cleanup(); -- class_unregister_type(OBD_ECHO_DEVICENAME); --} -- --MODULE_AUTHOR("Cluster Filesystems Inc. "); --MODULE_DESCRIPTION("Lustre Testing Echo OBD driver " OBDECHO_VERSION); --MODULE_LICENSE("GPL"); -- --module_init(obdecho_init); --module_exit(obdecho_exit); diff --cc lustre/obdecho/lproc_echo.c index 449f9c5,449f9c5..0000000 deleted file mode 100644,100644 --- a/lustre/obdecho/lproc_echo.c +++ /dev/null @@@ -1,67 -1,67 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_ECHO -- --#include --#include -- -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_uuid); -- return len; -- --} -- --int rd_fstype(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->u.echo.eo_fstype); -- return len; -- --} -- -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/fstype", rd_fstype, 0, 0}, -- {0} --}; -- --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/obdfilter/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/obdfilter/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/obdfilter/Makefile.am index a237004,a237004..0000000 deleted file mode 100644,100644 --- a/lustre/obdfilter/Makefile.am +++ /dev/null @@@ -1,25 -1,25 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= --MODULE = obdfilter --modulefs_DATA = obdfilter.o --EXTRA_PROGRAMS = obdfilter -- --LINX=simple.c ll_pack.c --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c -- --simple.c: -- test -e simple.c || ln -sf $(top_srcdir)/lib/simple.c -- --FILTERC = filter.c lproc_obdfilter.c --obdfilter_SOURCES = $(FILTERC) $(LINX) -- --dist-hook: -- list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done -- --include $(top_srcdir)/Rules -- diff --cc lustre/obdfilter/filter.c index 8a4d364,76d21cc..0000000 deleted file mode 100644,100644 --- a/lustre/obdfilter/filter.c +++ /dev/null @@@ -1,1839 -1,1864 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * linux/fs/obdfilter/filter.c -- * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * Copyright (c) 2001, 2002 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Andreas Dilger -- * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * This file is part of Lustre, http://www.lustre.org. -- * - * by Peter Braam - * and Andreas Dilger - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre 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. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_FILTER -- --#include --#include --#include --#include --#include --#include --#include --#include --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) --#include --#endif --#include --#include --#include --#include --#include -- --extern struct lprocfs_vars status_class_var[]; --extern struct lprocfs_vars status_var_nm_1[]; -- --static kmem_cache_t *filter_open_cache; --static kmem_cache_t *filter_dentry_cache; -- --#define FILTER_ROOTINO 2 --#define FILTER_ROOTINO_STR __stringify(FILTER_ROOTINO) -- --#define S_SHIFT 12 --static char *obd_type_by_mode[S_IFMT >> S_SHIFT] = { -- [0] NULL, -- [S_IFREG >> S_SHIFT] "R", -- [S_IFDIR >> S_SHIFT] "D", -- [S_IFCHR >> S_SHIFT] "C", -- [S_IFBLK >> S_SHIFT] "B", -- [S_IFIFO >> S_SHIFT] "F", -- [S_IFSOCK >> S_SHIFT] "S", -- [S_IFLNK >> S_SHIFT] "L" --}; -- --static inline const char *obd_mode_to_type(int mode) --{ -- return obd_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; --} -- --/* write the pathname into the string */ --static int filter_id(char *buf, obd_id id, obd_mode mode) --{ -- return sprintf(buf, "O/%s/"LPU64, obd_mode_to_type(mode), id); --} -- --static inline void f_dput(struct dentry *dentry) --{ -- /* Can't go inside filter_ddelete because it can block */ -- CDEBUG(D_INODE, "putting %s: %p, count = %d\n", -- dentry->d_name.name, dentry, atomic_read(&dentry->d_count) - 1); -- LASSERT(atomic_read(&dentry->d_count) > 0); -- -- dput(dentry); --} -- --/* Not racy w.r.t. others, because we are the only user of this dentry */ --static void filter_drelease(struct dentry *dentry) --{ -- if (dentry->d_fsdata) -- kmem_cache_free(filter_dentry_cache, dentry->d_fsdata); --} -- --struct dentry_operations filter_dops = { -- .d_release = filter_drelease, --}; -- --/* setup the object store with correct subdirectories */ --static int filter_prep(struct obd_device *obd) --{ -- struct obd_run_ctxt saved; -- struct filter_obd *filter = &obd->u.filter; -- struct dentry *dentry; -- struct dentry *root; -- struct file *file; -- struct inode *inode; -- int rc = 0; -- __u64 lastobjid = 2; -- int mode = 0; -- -- push_ctxt(&saved, &filter->fo_ctxt, NULL); -- dentry = simple_mkdir(current->fs->pwd, "O", 0700); -- CDEBUG(D_INODE, "got/created O: %p\n", dentry); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot open/create O: rc = %d\n", rc); -- GOTO(out, rc); -- } -- filter->fo_dentry_O = dentry; -- dentry = simple_mkdir(current->fs->pwd, "P", 0700); -- CDEBUG(D_INODE, "got/created P: %p\n", dentry); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot open/create P: rc = %d\n", rc); -- GOTO(out_O, rc); -- } -- f_dput(dentry); -- dentry = simple_mkdir(current->fs->pwd, "D", 0700); -- CDEBUG(D_INODE, "got/created D: %p\n", dentry); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot open/create D: rc = %d\n", rc); -- GOTO(out_O, rc); -- } -- -- root = simple_mknod(dentry, FILTER_ROOTINO_STR, S_IFREG | 0755); -- f_dput(dentry); -- if (IS_ERR(root)) { -- rc = PTR_ERR(root); -- CERROR("OBD filter: cannot open/create root %d: rc = %d\n", -- FILTER_ROOTINO, rc); -- GOTO(out_O, rc); -- } -- f_dput(root); -- -- /* -- * Create directories and/or get dentries for each object type. -- * This saves us from having to do multiple lookups for each one. -- */ -- for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) { -- char *type = obd_type_by_mode[mode]; -- -- if (!type) { -- filter->fo_dentry_O_mode[mode] = NULL; -- continue; -- } -- dentry = simple_mkdir(filter->fo_dentry_O, type, 0700); -- CDEBUG(D_INODE, "got/created O/%s: %p\n", type, dentry); -- if (IS_ERR(dentry)) { -- rc = PTR_ERR(dentry); -- CERROR("cannot create O/%s: rc = %d\n", type, rc); -- GOTO(out_O_mode, rc); -- } -- filter->fo_dentry_O_mode[mode] = dentry; -- } -- -- file = filp_open("D/status", O_RDWR | O_CREAT, 0700); -- if ( !file || IS_ERR(file) ) { -- rc = PTR_ERR(file); -- CERROR("OBD filter: cannot open/create status %s: rc = %d\n", -- "D/status", rc); -- GOTO(out_O_mode, rc); -- } -- -- /* steal operations */ -- inode = file->f_dentry->d_inode; -- filter->fo_fop = file->f_op; -- filter->fo_iop = inode->i_op; -- filter->fo_aops = inode->i_mapping->a_ops; -- -- if (inode->i_size == 0) { -- __u64 disk_lastobjid = cpu_to_le64(lastobjid); -- ssize_t retval = file->f_op->write(file,(char *)&disk_lastobjid, -- sizeof(disk_lastobjid), -- &file->f_pos); -- if (retval != sizeof(disk_lastobjid)) { -- CDEBUG(D_INODE,"OBD filter: error writing lastobjid\n"); -- filp_close(file, 0); -- GOTO(out_O_mode, rc = -EIO); -- } -- } else { -- __u64 disk_lastobjid; -- ssize_t retval = file->f_op->read(file, (char *)&disk_lastobjid, -- sizeof(disk_lastobjid), -- &file->f_pos); -- if (retval != sizeof(disk_lastobjid)) { -- CDEBUG(D_INODE,"OBD filter: error reading lastobjid\n"); -- filp_close(file, 0); -- GOTO(out_O_mode, rc = -EIO); -- } -- lastobjid = le64_to_cpu(disk_lastobjid); -- } -- filter->fo_lastobjid = lastobjid; -- filp_close(file, 0); -- -- rc = 0; -- out: - pop_ctxt(&saved); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); -- -- return(rc); -- --out_O_mode: -- while (mode-- > 0) { -- struct dentry *dentry = filter->fo_dentry_O_mode[mode]; -- if (dentry) { -- f_dput(dentry); -- filter->fo_dentry_O_mode[mode] = NULL; -- } -- } --out_O: -- f_dput(filter->fo_dentry_O); -- filter->fo_dentry_O = NULL; -- goto out; --} -- --/* cleanup the filter: write last used object id to status file */ --static void filter_post(struct obd_device *obd) --{ -- struct obd_run_ctxt saved; -- struct filter_obd *filter = &obd->u.filter; -- __u64 disk_lastobjid; -- long rc; -- struct file *file; -- int mode; -- -- push_ctxt(&saved, &filter->fo_ctxt, NULL); -- file = filp_open("D/status", O_RDWR | O_CREAT, 0700); -- if (IS_ERR(file)) { -- CERROR("OBD filter: cannot create status file\n"); -- goto out; -- } -- -- file->f_pos = 0; -- disk_lastobjid = cpu_to_le64(filter->fo_lastobjid); -- rc = file->f_op->write(file, (char *)&disk_lastobjid, -- sizeof(disk_lastobjid), &file->f_pos); -- if (rc != sizeof(disk_lastobjid)) -- CERROR("OBD filter: error writing lastobjid: rc = %ld\n", rc); -- -- rc = filp_close(file, NULL); -- if (rc) -- CERROR("OBD filter: cannot close status file: rc = %ld\n", rc); -- -- for (mode = 0; mode < (S_IFMT >> S_SHIFT); mode++) { -- struct dentry *dentry = filter->fo_dentry_O_mode[mode]; -- if (dentry) { -- f_dput(dentry); -- filter->fo_dentry_O_mode[mode] = NULL; -- } -- } -- f_dput(filter->fo_dentry_O); --out: - pop_ctxt(&saved); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); --} -- -- --static __u64 filter_next_id(struct obd_device *obd) --{ -- obd_id id; -- -- spin_lock(&obd->u.filter.fo_objidlock); -- id = ++obd->u.filter.fo_lastobjid; -- spin_unlock(&obd->u.filter.fo_objidlock); -- -- /* FIXME: write the lastobjid to disk here */ -- return id; --} -- --/* how to get files, dentries, inodes from object id's */ --/* parent i_sem is already held if needed for exclusivity */ --static struct dentry *filter_fid2dentry(struct obd_device *obd, -- struct dentry *dparent, - __u64 id, __u32 type) - __u64 id, __u32 type, int locked) --{ -- struct super_block *sb = obd->u.filter.fo_sb; -- struct dentry *dchild; -- char name[32]; -- int len; -- ENTRY; -- -- if (!sb || !sb->s_dev) { -- CERROR("fatal: device not initialized.\n"); -- RETURN(ERR_PTR(-ENXIO)); -- } -- -- if (id == 0) { -- CERROR("fatal: invalid object #0\n"); -- LBUG(); -- RETURN(ERR_PTR(-ESTALE)); -- } -- -- if (!(type & S_IFMT)) { -- CERROR("OBD %s, object "LPU64" has bad type: %o\n", -- __FUNCTION__, id, type); -- RETURN(ERR_PTR(-EINVAL)); -- } -- -- len = sprintf(name, LPU64, id); -- CDEBUG(D_INODE, "opening object O/%s/%s\n", obd_mode_to_type(type), -- name); - if (!locked) - down(&dparent->d_inode->i_sem); -- dchild = lookup_one_len(name, dparent, len); - if (!locked) - up(&dparent->d_inode->i_sem); -- if (IS_ERR(dchild)) { -- CERROR("child lookup error %ld\n", PTR_ERR(dchild)); -- RETURN(dchild); -- } -- -- CDEBUG(D_INODE, "got child obj O/%s/%s: %p, count = %d\n", -- obd_mode_to_type(type), name, dchild, -- atomic_read(&dchild->d_count)); -- -- LASSERT(atomic_read(&dchild->d_count) > 0); -- -- RETURN(dchild); --} -- --static inline struct dentry *filter_parent(struct obd_device *obd, -- obd_mode mode) --{ -- struct filter_obd *filter = &obd->u.filter; -- -- return filter->fo_dentry_O_mode[(mode & S_IFMT) >> S_SHIFT]; --} -- --static struct file *filter_obj_open(struct obd_export *export, -- __u64 id, __u32 type) --{ -- struct filter_obd *filter = &export->exp_obd->u.filter; -- struct super_block *sb = filter->fo_sb; -- struct dentry *dentry; -- struct filter_export_data *fed = &export->exp_filter_data; -- struct filter_dentry_data *fdd; -- struct filter_file_data *ffd; -- struct obd_run_ctxt saved; -- char name[24]; -- struct file *file; -- ENTRY; -- -- if (!sb || !sb->s_dev) { -- CERROR("fatal: device not initialized.\n"); -- RETURN(ERR_PTR(-ENXIO)); -- } -- -- if (!id) { -- CERROR("fatal: invalid obdo "LPU64"\n", id); -- RETURN(ERR_PTR(-ESTALE)); -- } -- -- if (!(type & S_IFMT)) { -- CERROR("OBD %s, object "LPU64" has bad type: %o\n", -- __FUNCTION__, id, type); -- RETURN(ERR_PTR(-EINVAL)); -- } -- -- ffd = kmem_cache_alloc(filter_open_cache, SLAB_KERNEL); -- if (!ffd) { -- CERROR("obdfilter: out of memory\n"); -- RETURN(ERR_PTR(-ENOMEM)); -- } -- -- /* We preallocate this to avoid blocking while holding fo_fddlock */ -- fdd = kmem_cache_alloc(filter_dentry_cache, SLAB_KERNEL); -- if (!fdd) { -- CERROR("obdfilter: out of memory\n"); -- GOTO(out_ffd, file = ERR_PTR(-ENOMEM)); -- } -- -- filter_id(name, id, type); -- push_ctxt(&saved, &filter->fo_ctxt, NULL); - file = filp_open(name, O_RDONLY | O_LARGEFILE, 0 /* type? */); - pop_ctxt(&saved); - file = filp_open(name, O_RDWR | O_LARGEFILE, 0 /* type? */); - pop_ctxt(&saved, &filter->fo_ctxt, NULL); -- - if (IS_ERR(file)) - if (IS_ERR(file)) { - CERROR("error opening %s: rc %d\n", name, PTR_ERR(file)); -- GOTO(out_fdd, file); - } -- -- dentry = file->f_dentry; -- spin_lock(&filter->fo_fddlock); -- if (dentry->d_fsdata) { -- spin_unlock(&filter->fo_fddlock); -- kmem_cache_free(filter_dentry_cache, fdd); -- fdd = dentry->d_fsdata; -- LASSERT(kmem_cache_validate(filter_dentry_cache, fdd)); -- /* should only happen during client recovery */ -- if (fdd->fdd_flags & FILTER_FLAG_DESTROY) -- CDEBUG(D_INODE,"opening destroyed object "LPX64"\n",id); -- atomic_inc(&fdd->fdd_open_count); -- } else { -- atomic_set(&fdd->fdd_open_count, 1); -- fdd->fdd_flags = 0; -- /* If this is racy, then we can use {cmp}xchg and atomic_add */ -- dentry->d_fsdata = fdd; -- spin_unlock(&filter->fo_fddlock); -- } -- -- get_random_bytes(&ffd->ffd_servercookie, sizeof(ffd->ffd_servercookie)); -- ffd->ffd_file = file; -- file->private_data = ffd; -- -- if (!dentry->d_op) -- dentry->d_op = &filter_dops; -- else -- LASSERT(dentry->d_op == &filter_dops); -- -- spin_lock(&fed->fed_lock); -- list_add(&ffd->ffd_export_list, &fed->fed_open_head); -- spin_unlock(&fed->fed_lock); -- - CDEBUG(D_INODE, "opening objid "LPX64": rc = %p\n", id, file); - CDEBUG(D_INODE, "opened objid "LPX64": rc = %p\n", id, file); -- --out: -- RETURN(file); -- --out_fdd: -- kmem_cache_free(filter_dentry_cache, fdd); --out_ffd: -- ffd->ffd_servercookie = DEAD_HANDLE_MAGIC; -- kmem_cache_free(filter_open_cache, ffd); -- goto out; --} -- --/* Caller must hold i_sem on dir_dentry->d_inode */ --static int filter_destroy_internal(struct obd_device *obd, -- struct dentry *dir_dentry, -- struct dentry *object_dentry) --{ -- struct obd_run_ctxt saved; -- struct inode *inode = object_dentry->d_inode; -- int rc; -- ENTRY; -- -- if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 1) { -- CERROR("destroying objid %*s nlink = %d, count = %d\n", -- object_dentry->d_name.len, -- object_dentry->d_name.name, -- inode->i_nlink, atomic_read(&inode->i_count)); -- } -- -- push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- rc = vfs_unlink(dir_dentry->d_inode, object_dentry); -- /* XXX unlink from PENDING directory now too */ - pop_ctxt(&saved); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- -- if (rc) -- CERROR("error unlinking objid %*s: rc %d\n", -- object_dentry->d_name.len, -- object_dentry->d_name.name, rc); -- -- RETURN(rc); --} -- --static int filter_close_internal(struct obd_device *obd, -- struct filter_file_data *ffd) --{ -- struct file *filp = ffd->ffd_file; -- struct dentry *object_dentry = dget(filp->f_dentry); -- struct filter_dentry_data *fdd = object_dentry->d_fsdata; -- int rc, rc2 = 0; -- ENTRY; -- -- LASSERT(filp->private_data == ffd); -- LASSERT(fdd); -- -- rc = filp_close(filp, 0); -- -- if (atomic_dec_and_test(&fdd->fdd_open_count) && -- fdd->fdd_flags & FILTER_FLAG_DESTROY) { -- struct dentry *dir_dentry = filter_parent(obd, S_IFREG); -- -- down(&dir_dentry->d_inode->i_sem); -- rc2 = filter_destroy_internal(obd, dir_dentry, object_dentry); -- if (rc2 && !rc) -- rc = rc2; -- up(&dir_dentry->d_inode->i_sem); -- } -- -- f_dput(object_dentry); -- kmem_cache_free(filter_open_cache, ffd); -- -- RETURN(rc); --} -- --/* obd methods */ --static int filter_connect(struct lustre_handle *conn, struct obd_device *obd, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- struct obd_export *exp; -- int rc; -- -- ENTRY; -- MOD_INC_USE_COUNT; -- rc = class_connect(conn, obd, cluuid); -- if (rc) -- GOTO(out_dec, rc); -- exp = class_conn2export(conn); -- LASSERT(exp); -- -- INIT_LIST_HEAD(&exp->exp_filter_data.fed_open_head); -- spin_lock_init(&exp->exp_filter_data.fed_lock); --out: -- RETURN(rc); -- --out_dec: -- MOD_DEC_USE_COUNT; -- goto out; --} -- --static int filter_disconnect(struct lustre_handle *conn) --{ -- struct obd_export *exp = class_conn2export(conn); -- struct filter_export_data *fed; -- int rc; -- ENTRY; -- -- LASSERT(exp); -- fed = &exp->exp_filter_data; -- spin_lock(&fed->fed_lock); -- while (!list_empty(&fed->fed_open_head)) { -- struct filter_file_data *ffd; -- -- ffd = list_entry(fed->fed_open_head.next, typeof(*ffd), -- ffd_export_list); -- list_del(&ffd->ffd_export_list); -- spin_unlock(&fed->fed_lock); -- -- CERROR("force closing file %*s on disconnect\n", -- ffd->ffd_file->f_dentry->d_name.len, -- ffd->ffd_file->f_dentry->d_name.name); -- -- filter_close_internal(exp->exp_obd, ffd); -- spin_lock(&fed->fed_lock); -- } -- spin_unlock(&fed->fed_lock); -- -- ldlm_cancel_locks_for_export(exp); -- rc = class_disconnect(conn); -- if (!rc) -- MOD_DEC_USE_COUNT; -- -- /* XXX cleanup preallocated inodes */ -- RETURN(rc); --} -- --/* mount the file system (secretly) */ --static int filter_setup(struct obd_device *obd, obd_count len, void *buf) --{ -- struct obd_ioctl_data* data = buf; -- struct filter_obd *filter; -- struct vfsmount *mnt; -- int err = 0; -- ENTRY; -- -- if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2) -- RETURN(-EINVAL); -- -- MOD_INC_USE_COUNT; -- mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, NULL); -- err = PTR_ERR(mnt); -- if (IS_ERR(mnt)) -- GOTO(err_dec, err); -- -- filter = &obd->u.filter;; -- filter->fo_vfsmnt = mnt; -- filter->fo_fstype = strdup(data->ioc_inlbuf2); -- filter->fo_sb = mnt->mnt_root->d_inode->i_sb; -- CERROR("%s: mnt is %p\n", data->ioc_inlbuf1, filter->fo_vfsmnt); -- /* XXX is this even possible if do_kern_mount succeeded? */ -- if (!filter->fo_sb) -- GOTO(err_kfree, err = -ENODEV); -- -- OBD_SET_CTXT_MAGIC(&filter->fo_ctxt); -- filter->fo_ctxt.pwdmnt = mnt; -- filter->fo_ctxt.pwd = mnt->mnt_root; -- filter->fo_ctxt.fs = get_ds(); -- -- err = filter_prep(obd); -- if (err) -- GOTO(err_kfree, err); -- spin_lock_init(&filter->fo_fddlock); -- spin_lock_init(&filter->fo_objidlock); -- INIT_LIST_HEAD(&filter->fo_export_list); -- -- obd->obd_namespace = -- ldlm_namespace_new("filter-tgt", LDLM_NAMESPACE_SERVER); -- if (obd->obd_namespace == NULL) -- LBUG(); -- -- ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, -- "filter_ldlm_cb_client", &obd->obd_ldlm_client); -- -- RETURN(0); -- --err_kfree: -- kfree(filter->fo_fstype); -- unlock_kernel(); -- mntput(filter->fo_vfsmnt); -- filter->fo_sb = 0; -- lock_kernel(); -- --err_dec: -- MOD_DEC_USE_COUNT; -- return err; --} -- -- --static int filter_cleanup(struct obd_device *obd) --{ -- struct super_block *sb; -- ENTRY; -- -- if (!list_empty(&obd->obd_exports)) { -- CERROR("still has clients!\n"); -- class_disconnect_all(obd); -- if (!list_empty(&obd->obd_exports)) { -- CERROR("still has exports after forced cleanup?\n"); -- RETURN(-EBUSY); -- } -- } -- -- ldlm_namespace_free(obd->obd_namespace); -- -- sb = obd->u.filter.fo_sb; -- if (!obd->u.filter.fo_sb) -- RETURN(0); -- -- filter_post(obd); -- -- shrink_dcache_parent(sb->s_root); -- unlock_kernel(); -- mntput(obd->u.filter.fo_vfsmnt); -- obd->u.filter.fo_sb = 0; -- kfree(obd->u.filter.fo_fstype); -- -- lock_kernel(); -- -- MOD_DEC_USE_COUNT; -- RETURN(0); --} -- -- --static void filter_from_inode(struct obdo *oa, struct inode *inode, int valid) --{ -- int type = oa->o_mode & S_IFMT; -- ENTRY; -- -- CDEBUG(D_INFO, "src inode %ld (%p), dst obdo %ld valid 0x%08x\n", -- inode->i_ino, inode, (long)oa->o_id, valid); -- /* Don't copy the inode number in place of the object ID */ -- obdo_from_inode(oa, inode, valid); -- oa->o_mode &= ~S_IFMT; -- oa->o_mode |= type; -- -- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { -- obd_rdev rdev = kdev_t_to_nr(inode->i_rdev); -- oa->o_rdev = rdev; -- oa->o_valid |= OBD_MD_FLRDEV; -- } -- -- EXIT; --} -- --static struct filter_file_data *filter_handle2ffd(struct lustre_handle *handle) --{ -- struct filter_file_data *ffd = NULL; -- ENTRY; -- -- if (!handle || !handle->addr) -- RETURN(NULL); -- -- ffd = (struct filter_file_data *)(unsigned long)(handle->addr); -- if (!kmem_cache_validate(filter_open_cache, (void *)ffd)) -- RETURN(NULL); -- -- if (ffd->ffd_servercookie != handle->cookie) -- RETURN(NULL); -- -- LASSERT(ffd->ffd_file->private_data == ffd); -- RETURN(ffd); --} -- --static struct dentry *__filter_oa2dentry(struct lustre_handle *conn, - struct obdo *oa, char *what) - struct obdo *oa, int locked,char *what) --{ -- struct dentry *dentry = NULL; -- -- if (oa->o_valid & OBD_MD_FLHANDLE) { -- struct lustre_handle *ost_handle = obdo_handle(oa); -- struct filter_file_data *ffd = filter_handle2ffd(ost_handle); -- -- if (ffd) -- dentry = dget(ffd->ffd_file->f_dentry); -- } -- -- if (!dentry) { -- struct obd_device *obd = class_conn2obd(conn); -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(ERR_PTR(-EINVAL)); -- } -- dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode), - oa->o_id, oa->o_mode); - oa->o_id, oa->o_mode, locked); - } - - if (IS_ERR(dentry)) { - CERROR("%s error looking up object: "LPX64"\n", what, oa->o_id); - RETURN(dentry); -- } -- -- if (!dentry->d_inode) { - CERROR("%s on non-existent object: "LPU64"\n", what, oa->o_id); - CERROR("%s on non-existent object: "LPX64"\n", what, oa->o_id); -- f_dput(dentry); - dentry = ERR_PTR(-ENOENT); - RETURN(ERR_PTR(-ENOENT)); -- } -- -- return dentry; --} -- - #define filter_oa2dentry(conn, oa) __filter_oa2dentry(conn, oa, __FUNCTION__) -#define filter_oa2dentry(conn, oa, locked) __filter_oa2dentry(conn, oa, locked,\ - __FUNCTION__) -- --static int filter_getattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct dentry *dentry = NULL; -- int rc = 0; -- ENTRY; -- - dentry = filter_oa2dentry(conn, oa); - dentry = filter_oa2dentry(conn, oa, 0); -- if (IS_ERR(dentry)) -- RETURN(PTR_ERR(dentry)); -- -- filter_from_inode(oa, dentry->d_inode, oa->o_valid); -- -- f_dput(dentry); -- RETURN(rc); --} -- --static int filter_setattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct obd_run_ctxt saved; -- struct obd_device *obd = class_conn2obd(conn); -- struct dentry *dentry; -- struct iattr iattr; -- struct inode *inode; -- int rc; -- ENTRY; -- - dentry = filter_oa2dentry(conn, oa); - dentry = filter_oa2dentry(conn, oa, 0); -- -- if (IS_ERR(dentry)) -- RETURN(PTR_ERR(dentry)); -- -- iattr_from_obdo(&iattr, oa, oa->o_valid); -- iattr.ia_mode = (iattr.ia_mode & ~S_IFMT) | S_IFREG; -- inode = dentry->d_inode; -- -- lock_kernel(); -- if (iattr.ia_valid & ATTR_SIZE) -- down(&inode->i_sem); -- push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- if (inode->i_op->setattr) -- rc = inode->i_op->setattr(dentry, &iattr); -- else -- rc = inode_setattr(inode, &iattr); - pop_ctxt(&saved); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- if (iattr.ia_valid & ATTR_SIZE) { -- up(&inode->i_sem); -- oa->o_valid = OBD_MD_FLBLOCKS | OBD_MD_FLCTIME | OBD_MD_FLMTIME; -- obdo_from_inode(oa, inode, oa->o_valid); -- } -- unlock_kernel(); -- -- f_dput(dentry); -- RETURN(rc); --} -- --static int filter_open(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea) --{ -- struct obd_export *export; -- struct lustre_handle *handle; -- struct filter_file_data *ffd; -- struct file *filp; -- int rc = 0; -- ENTRY; -- -- export = class_conn2export(conn); -- if (!export) { -- CDEBUG(D_IOCTL, "fatal: invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- filp = filter_obj_open(export, oa->o_id, oa->o_mode); -- if (IS_ERR(filp)) -- GOTO(out, rc = PTR_ERR(filp)); -- -- filter_from_inode(oa, filp->f_dentry->d_inode, oa->o_valid); -- -- ffd = filp->private_data; -- handle = obdo_handle(oa); -- handle->addr = (__u64)(unsigned long)ffd; -- handle->cookie = ffd->ffd_servercookie; -- oa->o_valid |= OBD_MD_FLHANDLE; - EXIT; --out: - RETURN(rc); - return rc; --} /* filter_open */ -- --static int filter_close(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea) --{ -- struct obd_export *exp; -- struct filter_file_data *ffd; -- struct filter_export_data *fed; -- int rc; -- ENTRY; -- -- exp = class_conn2export(conn); -- if (!exp) { -- CDEBUG(D_IOCTL, "fatal: invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if (!(oa->o_valid & OBD_MD_FLHANDLE)) { -- CERROR("no handle for close of objid "LPX64"\n", oa->o_id); -- RETURN(-EINVAL); -- } -- -- ffd = filter_handle2ffd(obdo_handle(oa)); -- if (!ffd) { -- struct lustre_handle *handle = obdo_handle(oa); -- CERROR("bad handle ("LPX64") or cookie ("LPX64") for close\n", -- handle->addr, handle->cookie); -- RETURN(-ESTALE); -- } -- -- fed = &exp->exp_filter_data; -- spin_lock(&fed->fed_lock); -- list_del(&ffd->ffd_export_list); -- spin_unlock(&fed->fed_lock); -- -- rc = filter_close_internal(exp->exp_obd, ffd); -- -- RETURN(rc); --} /* filter_close */ -- --static int filter_create(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md **ea) --{ -- struct obd_device *obd = class_conn2obd(conn); -- char name[64]; -- struct obd_run_ctxt saved; -- struct dentry *new; -- struct iattr; -- ENTRY; -- -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- return -EINVAL; -- } -- -- if (!(oa->o_mode & S_IFMT)) { -- CERROR("OBD %s, object "LPU64" has bad type: %o\n", -- __FUNCTION__, oa->o_id, oa->o_mode); -- return -ENOENT; -- } -- -- oa->o_id = filter_next_id(obd); -- -- //filter_id(name, oa->o_id, oa->o_mode); -- sprintf(name, LPU64, oa->o_id); -- push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- new = simple_mknod(filter_parent(obd, oa->o_mode), name, oa->o_mode); - pop_ctxt(&saved); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- if (IS_ERR(new)) { -- CERROR("Error mknod obj %s, err %ld\n", name, PTR_ERR(new)); -- return -ENOENT; -- } -- -- /* Set flags for fields we have set in the inode struct */ -- oa->o_valid = OBD_MD_FLID | OBD_MD_FLBLKSZ | OBD_MD_FLBLOCKS | -- OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME; -- filter_from_inode(oa, new->d_inode, oa->o_valid); -- f_dput(new); -- -- return 0; --} -- --static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea) --{ -- struct obd_device *obd = class_conn2obd(conn); -- struct dentry *dir_dentry, *object_dentry; -- struct filter_dentry_data *fdd; -- int rc; -- ENTRY; -- -- if (!obd) { -- CERROR("invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- CDEBUG(D_INODE, "destroying objid "LPX64"\n", oa->o_id); -- -- dir_dentry = filter_parent(obd, oa->o_mode); -- down(&dir_dentry->d_inode->i_sem); -- - object_dentry = filter_oa2dentry(conn, oa); - object_dentry = filter_oa2dentry(conn, oa, 1); -- if (IS_ERR(object_dentry)) -- GOTO(out, rc = -ENOENT); -- -- fdd = object_dentry->d_fsdata; -- if (fdd && atomic_read(&fdd->fdd_open_count)) { -- if (!(fdd->fdd_flags & FILTER_FLAG_DESTROY)) { -- fdd->fdd_flags |= FILTER_FLAG_DESTROY; -- /* XXX put into PENDING directory in case of crash */ -- CDEBUG(D_INODE, -- "defer destroy of %dx open objid "LPX64"\n", -- atomic_read(&fdd->fdd_open_count), oa->o_id); -- } else -- CDEBUG(D_INODE, -- "repeat destroy of %dx open objid "LPX64"\n", -- atomic_read(&fdd->fdd_open_count), oa->o_id); -- GOTO(out_dput, rc = 0); -- } -- -- rc = filter_destroy_internal(obd, dir_dentry, object_dentry); --out_dput: -- f_dput(object_dentry); -- -- EXIT; --out: -- up(&dir_dentry->d_inode->i_sem); -- return rc; --} -- --/* NB count and offset are used for punch, but not truncate */ --static int filter_truncate(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *lsm, -- obd_off start, obd_off end) --{ -- int error; -- ENTRY; -- -- if (end != OBD_OBJECT_EOF) -- CERROR("PUNCH not supported, only truncate works\n"); -- -- CDEBUG(D_INODE, "calling truncate for object "LPX64", valid = %x, " -- "o_size = "LPD64"\n", oa->o_id, oa->o_valid, start); -- oa->o_size = start; -- error = filter_setattr(conn, oa, NULL); -- RETURN(error); --} -- --static int filter_pgcache_brw(int cmd, struct lustre_handle *conn, -- struct lov_stripe_md *lsm, obd_count oa_bufs, - struct brw_page *pga, brw_cb_t callback, - struct brw_cb_data *brw_cbd) - struct brw_page *pga, struct obd_brw_set *set) --{ -- struct obd_export *export = class_conn2export(conn); -- struct obd_run_ctxt saved; -- struct super_block *sb; -- int pnum; /* index to pages (bufs) */ -- unsigned long retval; -- int error; -- struct file *file; -- int pg; -- ENTRY; -- -- if (!export) { -- CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- sb = export->exp_obd->u.filter.fo_sb; -- push_ctxt(&saved, &export->exp_obd->u.filter.fo_ctxt, NULL); -- pnum = 0; /* pnum indexes buf 0..num_pages */ -- -- file = filter_obj_open(export, lsm->lsm_object_id, S_IFREG); -- if (IS_ERR(file)) -- GOTO(out, retval = PTR_ERR(file)); -- -- /* count doubles as retval */ -- for (pg = 0; pg < oa_bufs; pg++) { -- CDEBUG(D_INODE, "OP %d obdo pgno: (%d) (%ld,"LPU64 -- ") off count ("LPU64",%d)\n", -- cmd, pnum, file->f_dentry->d_inode->i_ino, -- pga[pnum].off >> PAGE_CACHE_SHIFT, pga[pnum].off, -- (int)pga[pnum].count); -- if (cmd & OBD_BRW_WRITE) { -- loff_t off; -- char *buffer; -- off = pga[pnum].off; -- buffer = kmap(pga[pnum].pg); -- retval = file->f_op->write(file, buffer, -- pga[pnum].count, -- &off); -- kunmap(pga[pnum].pg); -- CDEBUG(D_INODE, "retval %ld\n", retval); -- } else { -- loff_t off = pga[pnum].off; -- char *buffer = kmap(pga[pnum].pg); -- -- if (off >= file->f_dentry->d_inode->i_size) { -- memset(buffer, 0, pga[pnum].count); -- retval = pga[pnum].count; -- } else { -- retval = file->f_op->read(file, buffer, -- pga[pnum].count, &off); -- } -- kunmap(pga[pnum].pg); -- -- if (retval != pga[pnum].count) { -- filp_close(file, 0); -- GOTO(out, retval = -EIO); -- } -- CDEBUG(D_INODE, "retval %ld\n", retval); -- } -- pnum++; -- } -- /* sizes and blocks are set by generic_file_write */ -- /* ctimes/mtimes will follow with a setattr call */ -- filp_close(file, 0); -- -- /* XXX: do something with callback if it is set? */ -- -- EXIT; --out: - pop_ctxt(&saved); - pop_ctxt(&saved, &export->exp_obd->u.filter.fo_ctxt, NULL); -- error = (retval >= 0) ? 0 : retval; -- return error; --} -- --/* -- * Calculate the number of buffer credits needed to write multiple pages in -- * a single ext3/extN transaction. No, this shouldn't be here, but as yet -- * ext3 doesn't have a nice API for calculating this sort of thing in advance. -- * -- * See comment above ext3_writepage_trans_blocks for details. We assume -- * no data journaling is being done, but it does allow for all of the pages -- * being non-contiguous. If we are guaranteed contiguous pages we could -- * reduce the number of (d)indirect blocks a lot. -- * -- * With N blocks per page and P pages, for each inode we have at most: -- * N*P indirect -- * min(N*P, blocksize/4 + 1) dindirect blocks -- * 1 tindirect -- * -- * For the entire filesystem, we have at most: -- * min(sum(nindir + P), ngroups) bitmap blocks (from the above) -- * min(sum(nindir + P), gdblocks) group descriptor blocks (from the above) -- * 1 inode block -- * 1 superblock -- * 2 * EXT3_SINGLEDATA_TRANS_BLOCKS for the quota files -- */ --static int ext3_credits_needed(struct super_block *sb, int objcount, -- struct obd_ioobj *obj) --{ -- struct obd_ioobj *o = obj; -- int blockpp = 1 << (PAGE_CACHE_SHIFT - sb->s_blocksize_bits); -- int addrpp = EXT3_ADDR_PER_BLOCK(sb) * blockpp; -- int nbitmaps = 0; -- int ngdblocks = 0; -- int needed = objcount + 1; -- int i; -- -- for (i = 0; i < objcount; i++, o++) { -- int nblocks = o->ioo_bufcnt * blockpp; -- int ndindirect = min(nblocks, addrpp + 1); -- int nindir = nblocks + ndindirect + 1; -- -- nbitmaps += nindir + nblocks; -- ngdblocks += nindir + nblocks; -- -- needed += nindir; -- } -- -- /* Assumes ext3 and extN have same sb_info layout at the start. */ -- if (nbitmaps > EXT3_SB(sb)->s_groups_count) -- nbitmaps = EXT3_SB(sb)->s_groups_count; -- if (ngdblocks > EXT3_SB(sb)->s_gdb_count) -- ngdblocks = EXT3_SB(sb)->s_gdb_count; -- -- needed += nbitmaps + ngdblocks; -- --#ifdef CONFIG_QUOTA -- /* We assume that there will be 1 bit set in s_dquot.flags for each -- * quota file that is active. This is at least true for now. -- */ -- needed += hweight32(sb_any_quota_enabled(sb)) * -- EXT3_SINGLEDATA_TRANS_BLOCKS; --#endif -- -- return needed; --} -- --/* We have to start a huge journal transaction here to hold all of the -- * metadata for the pages being written here. This is necessitated by -- * the fact that we do lots of prepare_write operations before we do -- * any of the matching commit_write operations, so even if we split -- * up to use "smaller" transactions none of them could complete until -- * all of them were opened. By having a single journal transaction, -- * we eliminate duplicate reservations for common blocks like the -- * superblock and group descriptors or bitmaps. -- * -- * We will start the transaction here, but each prepare_write will -- * add a refcount to the transaction, and each commit_write will -- * remove a refcount. The transaction will be closed when all of -- * the pages have been written. -- */ --static void *ext3_filter_journal_start(struct filter_obd *filter, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_remote *nb) --{ -- journal_t *journal = NULL; -- handle_t *handle = NULL; -- int needed; -- -- /* It appears that some kernels have different values for -- * EXT*_MAX_GROUP_LOADED (either 8 or 32), so we cannot -- * assume anything after s_inode_bitmap_number is the same. -- */ -- if (!strcmp(filter->fo_fstype, "ext3")) -- journal = EXT3_SB(filter->fo_sb)->s_journal; --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- else if (!strcmp(filter->fo_fstype, "extN")) -- journal = EXTN_SB(filter->fo_sb)->s_journal; --#endif -- needed = ext3_credits_needed(filter->fo_sb, objcount, obj); -- -- /* The number of blocks we could _possibly_ dirty can very large. -- * We reduce our request if it is absurd (and we couldn't get that -- * many credits for a single handle anyways). -- * -- * At some point we have to limit the size of I/Os sent at one time, -- * increase the size of the journal, or we have to calculate the -- * actual journal requirements more carefully by checking all of -- * the blocks instead of being maximally pessimistic. It remains to -- * be seen if this is a real problem or not. -- */ -- if (needed > journal->j_max_transaction_buffers) { -- CERROR("want too many journal credits (%d) using %d instead\n", -- needed, journal->j_max_transaction_buffers); -- needed = journal->j_max_transaction_buffers; -- } -- -- lock_kernel(); -- handle = journal_start(journal, needed); -- unlock_kernel(); -- if (IS_ERR(handle)) -- CERROR("can't get handle for %d credits: rc = %ld\n", needed, -- PTR_ERR(handle)); -- -- return(handle); --} -- --static void *filter_journal_start(void **journal_save, -- struct filter_obd *filter, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_remote *nb) --{ -- void *handle = NULL; -- -- /* This may not be necessary - we probably never have a -- * transaction started when we enter here, so we can -- * remove the saving of the journal state entirely. -- * For now leave it in just to see if it ever happens. -- */ -- *journal_save = current->journal_info; -- if (*journal_save) { -- CERROR("Already have handle %p???\n", *journal_save); -- LBUG(); -- current->journal_info = NULL; -- } -- -- if (!strcmp(filter->fo_fstype, "ext3") || -- !strcmp(filter->fo_fstype, "extN")) -- handle = ext3_filter_journal_start(filter, objcount, obj, -- niocount, nb); -- return handle; --} -- --static int ext3_filter_journal_stop(void *handle) --{ -- int rc; -- -- /* We got a refcount on the handle for each call to prepare_write, -- * so we can drop the "parent" handle here to avoid the need for -- * osc to call back into filterobd to close the handle. The -- * remaining references will be dropped in commit_write. -- */ -- lock_kernel(); -- rc = journal_stop((handle_t *)handle); -- unlock_kernel(); -- -- return rc; --} -- --static int filter_journal_stop(void *journal_save, struct filter_obd *filter, -- void *handle) --{ -- int rc = 0; -- -- if (!strcmp(filter->fo_fstype, "ext3") || -- !strcmp(filter->fo_fstype, "extN")) -- rc = ext3_filter_journal_stop(handle); -- -- if (rc) -- CERROR("error on journal stop: rc = %d\n", rc); -- -- current->journal_info = journal_save; -- -- return rc; --} -- --static inline void lustre_put_page(struct page *page) --{ -- kunmap(page); -- page_cache_release(page); --} -- -- --static struct page * --lustre_get_page_read(struct inode *inode, struct niobuf_remote *rnb) --{ -- unsigned long index = rnb->offset >> PAGE_SHIFT; -- struct address_space *mapping = inode->i_mapping; -- struct page *page; -- int rc; -- -- page = read_cache_page(mapping, index, -- (filler_t*)mapping->a_ops->readpage, NULL); -- if (!IS_ERR(page)) { -- wait_on_page(page); -- kmap(page); -- if (!PageUptodate(page)) { -- CERROR("page index %lu not uptodate\n", index); -- GOTO(err_page, rc = -EIO); -- } -- if (PageError(page)) { -- CERROR("page index %lu has error\n", index); -- GOTO(err_page, rc = -EIO); -- } -- } -- return page; -- --err_page: -- lustre_put_page(page); -- return ERR_PTR(rc); --} -- --static struct page * --lustre_get_page_write(struct inode *inode, unsigned long index) --{ -- struct address_space *mapping = inode->i_mapping; -- struct page *page; -- int rc; -- -- page = grab_cache_page(mapping, index); /* locked page */ -- -- if (!IS_ERR(page)) { -- kmap(page); -- /* Note: Called with "O" and "PAGE_SIZE" this is essentially -- * a no-op for most filesystems, because we write the whole -- * page. For partial-page I/O this will read in the page. -- */ -- rc = mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); -- if (rc) { -- CERROR("page index %lu, rc = %d\n", index, rc); -- if (rc != -ENOSPC) -- LBUG(); -- GOTO(err_unlock, rc); -- } -- /* XXX not sure if we need this if we are overwriting page */ -- if (PageError(page)) { -- CERROR("error on page index %lu, rc = %d\n", index, rc); -- LBUG(); -- GOTO(err_unlock, rc = -EIO); -- } -- } -- return page; -- --err_unlock: -- unlock_page(page); -- lustre_put_page(page); -- return ERR_PTR(rc); --} -- --#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) --int waitfor_one_page(struct page *page) --{ -- wait_on_page_locked(page); -- return 0; --} --#endif -- --static int lustre_commit_write(struct page *page, unsigned from, unsigned to) --{ -- struct inode *inode = page->mapping->host; -- int err; -- -- err = page->mapping->a_ops->commit_write(NULL, page, from, to); -- if (!err && IS_SYNC(inode)) -- err = waitfor_one_page(page); -- //SetPageUptodate(page); // the client commit_write will do this -- -- SetPageReferenced(page); -- unlock_page(page); -- lustre_put_page(page); -- return err; --} -- --struct page *filter_get_page_write(struct inode *inode, -- struct niobuf_remote *rnb, -- struct niobuf_local *lnb, int *pglocked) --{ -- unsigned long index = rnb->offset >> PAGE_SHIFT; -- struct address_space *mapping = inode->i_mapping; -- -- struct page *page; -- int rc; -- -- //ASSERT_PAGE_INDEX(index, GOTO(err, rc = -EINVAL)); -- if (*pglocked) -- page = grab_cache_page_nowait(mapping, index); /* locked page */ -- else -- page = grab_cache_page(mapping, index); /* locked page */ -- -- -- /* This page is currently locked, so get a temporary page instead. */ -- /* XXX I believe this is a very dangerous thing to do - consider if -- * we had multiple writers for the same file (definitely the case -- * if we are using this codepath). If writer A locks the page, -- * writer B writes to a copy (as here), writer A drops the page -- * lock, and writer C grabs the lock before B does, then B will -- * later overwrite the data from C, even if C had LDLM locked -- * and initiated the write after B did. -- */ -- if (!page) { -- unsigned long addr; -- CDEBUG(D_PAGE, "ino %ld page %ld locked\n", inode->i_ino,index); -- addr = __get_free_pages(GFP_KERNEL, 0); /* locked page */ -- if (!addr) { -- CERROR("no memory for a temp page\n"); -- LBUG(); -- GOTO(err, rc = -ENOMEM); -- } -- /* XXX debugging */ -- memset((void *)addr, 0xBA, PAGE_SIZE); -- page = virt_to_page(addr); -- kmap(page); -- page->index = index; -- lnb->flags |= N_LOCAL_TEMP_PAGE; -- } else if (!IS_ERR(page)) { -- (*pglocked)++; -- kmap(page); -- -- rc = mapping->a_ops->prepare_write(NULL, page, -- rnb->offset % PAGE_SIZE, -- rnb->len); -- if (rc) { -- CERROR("page index %lu, rc = %d\n", index, rc); -- if (rc != -ENOSPC) -- LBUG(); -- GOTO(err_unlock, rc); -- } -- /* XXX not sure if we need this if we are overwriting page */ -- if (PageError(page)) { -- CERROR("error on page index %lu, rc = %d\n", index, rc); -- LBUG(); -- GOTO(err_unlock, rc = -EIO); -- } -- } -- return page; -- --err_unlock: -- unlock_page(page); -- lustre_put_page(page); --err: -- return ERR_PTR(rc); --} -- --/* -- * We need to balance prepare_write() calls with commit_write() calls. -- * If the page has been prepared, but we have no data for it, we don't -- * want to overwrite valid data on disk, but we still need to zero out -- * data for space which was newly allocated. Like part of what happens -- * in __block_prepare_write() for newly allocated blocks. -- * -- * XXX currently __block_prepare_write() creates buffers for all the -- * pages, and the filesystems mark these buffers as BH_New if they -- * were newly allocated from disk. We use the BH_New flag similarly. -- */ --static int filter_commit_write(struct page *page, unsigned from, unsigned to, -- int err) --{ --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- if (err) { -- unsigned block_start, block_end; -- struct buffer_head *bh, *head = page->buffers; -- unsigned blocksize = head->b_size; -- void *addr = page_address(page); -- -- /* debugging: just seeing if this ever happens */ -- CERROR("called filter_commit_write for obj %ld:%ld on err %d\n", -- page->index, page->mapping->host->i_ino, err); -- -- /* Currently one buffer per page, but in the future... */ -- for (bh = head, block_start = 0; bh != head || !block_start; -- block_start = block_end, bh = bh->b_this_page) { -- block_end = block_start + blocksize; -- if (buffer_new(bh)) -- memset(addr + block_start, 0, blocksize); -- } -- } --#endif -- return lustre_commit_write(page, from, to); --} -- --static int filter_preprw(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_remote *nb, -- struct niobuf_local *res, void **desc_private) --{ -- struct obd_run_ctxt saved; -- struct obd_device *obd; -- struct obd_ioobj *o = obj; -- struct niobuf_remote *rnb = nb; -- struct niobuf_local *lnb = res; -- void *journal_save = NULL; -- int pglocked = 0; -- int rc = 0; -- int i; -- ENTRY; -- -- obd = class_conn2obd(conn); -- if (!obd) { -- CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- memset(res, 0, sizeof(*res) * niocount); -- -- push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- -- if (cmd & OBD_BRW_WRITE) { -- *desc_private = filter_journal_start(&journal_save, -- &obd->u.filter, -- objcount, obj, niocount, -- nb); -- if (IS_ERR(*desc_private)) -- GOTO(out_ctxt, rc = PTR_ERR(*desc_private)); -- } -- -- obd_kmap_get(niocount, 1); -- -- for (i = 0; i < objcount; i++, o++) { -- struct dentry *dentry; -- struct inode *inode; -- int j; -- -- dentry = filter_fid2dentry(obd, filter_parent(obd, S_IFREG), - o->ioo_id, S_IFREG); - o->ioo_id, S_IFREG, 0); -- if (IS_ERR(dentry)) -- GOTO(out_clean, rc = PTR_ERR(dentry)); -- inode = dentry->d_inode; -- if (!inode) { -- CERROR("trying to BRW to non-existent file "LPU64"\n", -- o->ioo_id); -- f_dput(dentry); -- GOTO(out_clean, rc = -ENOENT); -- } -- -- for (j = 0; j < o->ioo_bufcnt; j++, rnb++, lnb++) { -- struct page *page; -- -- if (j == 0) -- lnb->dentry = dentry; -- else -- lnb->dentry = dget(dentry); -- -- if (cmd & OBD_BRW_WRITE) -- page = filter_get_page_write(inode, rnb, lnb, -- &pglocked); -- else -- page = lustre_get_page_read(inode, rnb); -- -- if (IS_ERR(page)) { -- f_dput(dentry); -- GOTO(out_clean, rc = PTR_ERR(page)); -- } -- -- lnb->addr = page_address(page); -- lnb->offset = rnb->offset; -- lnb->page = page; -- lnb->len = rnb->len; -- } -- } -- --out_stop: -- if (cmd & OBD_BRW_WRITE) { -- int err = filter_journal_stop(journal_save, &obd->u.filter, -- *desc_private); -- if (!rc) -- rc = err; -- } --out_ctxt: - pop_ctxt(&saved); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- RETURN(rc); --out_clean: -- while (lnb-- > res) { -- CERROR("error cleanup on brw\n"); -- f_dput(lnb->dentry); -- if (cmd & OBD_BRW_WRITE) -- filter_commit_write(lnb->page, 0, PAGE_SIZE, rc); -- else -- lustre_put_page(lnb->page); -- } -- obd_kmap_put(niocount); -- goto out_stop; --} -- --static int filter_write_locked_page(struct niobuf_local *lnb) --{ -- struct page *lpage; -- int rc; -- -- lpage = lustre_get_page_write(lnb->dentry->d_inode, lnb->page->index); -- if (IS_ERR(lpage)) { -- /* It is highly unlikely that we would ever get an error here. -- * The page we want to get was previously locked, so it had to -- * have already allocated the space, and we were just writing -- * over the same data, so there would be no hole in the file. -- * -- * XXX: possibility of a race with truncate could exist, need -- * to check that. There are no guarantees w.r.t. -- * write order even on a local filesystem, although the -- * normal response would be to return the number of bytes -- * successfully written and leave the rest to the app. -- */ -- rc = PTR_ERR(lpage); -- CERROR("error getting locked page index %ld: rc = %d\n", -- lnb->page->index, rc); -- GOTO(out, rc); -- } -- -- /* lpage is kmapped in lustre_get_page_write() above and kunmapped in -- * lustre_commit_write() below, lnb->page was kmapped previously in -- * filter_get_page_write() and kunmapped in lustre_put_page() below. -- */ -- memcpy(page_address(lpage), page_address(lnb->page), PAGE_SIZE); -- rc = lustre_commit_write(lpage, 0, PAGE_SIZE); -- if (rc) -- CERROR("error committing locked page %ld: rc = %d\n", -- lnb->page->index, rc); --out: -- lustre_put_page(lnb->page); -- -- return rc; --} -- --static int filter_commitrw(int cmd, struct lustre_handle *conn, -- int objcount, struct obd_ioobj *obj, -- int niocount, struct niobuf_local *res, -- void *private) --{ -- struct obd_run_ctxt saved; -- struct obd_ioobj *o; -- struct niobuf_local *r; -- struct obd_device *obd = class_conn2obd(conn); -- void *journal_save; -- int found_locked = 0; -- int rc = 0; -- int i; -- ENTRY; -- -- push_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- lock_kernel(); -- journal_save = current->journal_info; -- LASSERT(!journal_save); -- -- current->journal_info = private; -- unlock_kernel(); -- for (i = 0, o = obj, r = res; i < objcount; i++, o++) { -- int j; -- for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) { -- struct page *page = r->page; -- -- if (!page) -- LBUG(); -- -- if (r->flags & N_LOCAL_TEMP_PAGE) { -- found_locked++; -- continue; -- } -- -- if (cmd & OBD_BRW_WRITE) { -- int err = filter_commit_write(page, 0, -- r->len, 0); -- -- if (!rc) -- rc = err; -- } else -- lustre_put_page(page); -- -- obd_kmap_put(1); -- f_dput(r->dentry); -- } -- } -- lock_kernel(); -- current->journal_info = journal_save; -- unlock_kernel(); -- -- if (!found_locked) -- goto out_ctxt; -- -- for (i = 0, o = obj, r = res; i < objcount; i++, o++) { -- int j; -- for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) { -- int err; -- if (!(r->flags & N_LOCAL_TEMP_PAGE)) -- continue; -- -- err = filter_write_locked_page(r); -- obd_kmap_put(1); -- if (!rc) -- rc = err; -- f_dput(r->dentry); -- } -- } -- --out_ctxt: - pop_ctxt(&saved); - pop_ctxt(&saved, &obd->u.filter.fo_ctxt, NULL); -- RETURN(rc); --} -- --static int filter_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) --{ -- struct obd_device *obd = class_conn2obd(conn); -- struct statfs sfs; -- int rc; -- -- ENTRY; -- rc = vfs_statfs(obd->u.filter.fo_sb, &sfs); -- if (!rc) -- statfs_pack(osfs, &sfs); -- -- return rc; --} -- --static int filter_get_info(struct lustre_handle *conn, obd_count keylen, -- void *key, obd_count *vallen, void **val) --{ -- struct obd_device *obd; -- ENTRY; -- -- obd = class_conn2obd(conn); -- if (!obd) { -- CDEBUG(D_IOCTL, "invalid client "LPX64"\n", conn->addr); -- RETURN(-EINVAL); -- } -- -- if ( keylen == strlen("blocksize") && -- memcmp(key, "blocksize", keylen) == 0 ) { -- *vallen = sizeof(long); -- *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize; -- RETURN(0); -- } -- -- if ( keylen == strlen("blocksize_bits") && -- memcmp(key, "blocksize_bits", keylen) == 0 ){ -- *vallen = sizeof(long); -- *val = (void *)(long)obd->u.filter.fo_sb->s_blocksize_bits; -- RETURN(0); -- } -- -- if ( keylen == strlen("root_ino") && -- memcmp(key, "root_ino", keylen) == 0 ){ -- *vallen = sizeof(obd_id); -- *val = (void *)(obd_id)FILTER_ROOTINO; -- RETURN(0); -- } -- -- CDEBUG(D_IOCTL, "invalid key\n"); -- RETURN(-EINVAL); --} -- --int filter_copy_data(struct lustre_handle *dst_conn, struct obdo *dst, -- struct lustre_handle *src_conn, struct obdo *src, -- obd_size count, obd_off offset) --{ -- struct page *page; -- struct lov_stripe_md srcmd, dstmd; -- unsigned long index = 0; -- int err = 0; -- -- memset(&srcmd, 0, sizeof(srcmd)); -- memset(&dstmd, 0, sizeof(dstmd)); -- srcmd.lsm_object_id = src->o_id; -- dstmd.lsm_object_id = dst->o_id; -- -- ENTRY; -- CDEBUG(D_INFO, "src: ino "LPU64" blocks "LPU64", size "LPU64 -- ", dst: ino "LPU64"\n", -- src->o_id, src->o_blocks, src->o_size, dst->o_id); -- page = alloc_page(GFP_USER); -- if (page == NULL) -- RETURN(-ENOMEM); -- --#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -- while (TryLockPage(page)) -- ___wait_on_page(page); --#else -- wait_on_page_locked(page); --#endif -- -- /* XXX with brw vector I/O, we could batch up reads and writes here, -- * all we need to do is allocate multiple pages to handle the I/Os -- * and arrays to handle the request parameters. -- */ -- while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) { -- struct brw_page pg; - struct brw_cb_data *brw_cbd = ll_init_brw_cb_data(); - struct obd_brw_set *set; -- - if (!brw_cbd) { - set = obd_brw_set_new(); - if (set == NULL) { -- err = -ENOMEM; -- EXIT; -- break; -- } -- -- pg.pg = page; -- pg.count = PAGE_SIZE; -- pg.off = (page->index) << PAGE_SHIFT; -- pg.flag = 0; -- -- page->index = index; - err = obd_brw(OBD_BRW_READ, src_conn, &srcmd, 1, &pg, - ll_sync_brw_cb, brw_cbd); - - if ( err ) { - set->brw_callback = ll_brw_sync_wait; - err = obd_brw(OBD_BRW_READ, src_conn, &srcmd, 1, &pg, set); - obd_brw_set_free(set); - if (err) { -- EXIT; -- break; -- } -- - brw_cbd = ll_init_brw_cb_data(); - if (!brw_cbd) { - set = obd_brw_set_new(); - if (set == NULL) { -- err = -ENOMEM; -- EXIT; -- break; -- } -- pg.flag = OBD_BRW_CREATE; -- CDEBUG(D_INFO, "Read page %ld ...\n", page->index); -- - err = obd_brw(OBD_BRW_WRITE, dst_conn, &dstmd, 1, &pg, - ll_sync_brw_cb, brw_cbd); - set->brw_callback = ll_brw_sync_wait; - err = obd_brw(OBD_BRW_WRITE, dst_conn, &dstmd, 1, &pg, set); - obd_brw_set_free(set); -- -- /* XXX should handle dst->o_size, dst->o_blocks here */ - if ( err ) { - if (err) { -- EXIT; -- break; -- } -- -- CDEBUG(D_INFO, "Wrote page %ld ...\n", page->index); -- -- index++; -- } -- dst->o_size = src->o_size; -- dst->o_blocks = src->o_blocks; -- dst->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; -- unlock_page(page); -- __free_page(page); -- -- RETURN(err); --} --int filter_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- --int filter_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); --} --static struct obd_ops filter_obd_ops = { -- o_attach: filter_attach, -- o_detach: filter_detach, -- o_get_info: filter_get_info, -- o_setup: filter_setup, -- o_cleanup: filter_cleanup, -- o_connect: filter_connect, -- o_disconnect: filter_disconnect, -- o_statfs: filter_statfs, -- o_getattr: filter_getattr, -- o_create: filter_create, -- o_setattr: filter_setattr, -- o_destroy: filter_destroy, -- o_open: filter_open, -- o_close: filter_close, -- o_brw: filter_pgcache_brw, -- o_punch: filter_truncate, -- o_preprw: filter_preprw, -- o_commitrw: filter_commitrw --#if 0 -- o_preallocate: filter_preallocate_inodes, -- o_migrate: filter_migrate, -- o_copy: filter_copy_data, -- o_iterate: filter_iterate --#endif --}; -- -- --static int __init obdfilter_init(void) --{ -- printk(KERN_INFO "Filtering OBD driver v0.001, info@clusterfs.com\n"); -- filter_open_cache = kmem_cache_create("ll_filter_fdata", -- sizeof(struct filter_file_data), -- 0, 0, NULL, NULL); -- if (!filter_open_cache) -- RETURN(-ENOMEM); -- -- filter_dentry_cache = kmem_cache_create("ll_filter_dentry", -- sizeof(struct filter_dentry_data), -- 0, 0, NULL, NULL); -- if (!filter_dentry_cache) { -- kmem_cache_destroy(filter_open_cache); -- RETURN(-ENOMEM); -- } -- -- return class_register_type(&filter_obd_ops, status_class_var, -- OBD_FILTER_DEVICENAME); --} -- --static void __exit obdfilter_exit(void) --{ -- class_unregister_type(OBD_FILTER_DEVICENAME); -- if (kmem_cache_destroy(filter_dentry_cache)) -- CERROR("couldn't free obdfilter dentry cache\n"); -- if (kmem_cache_destroy(filter_open_cache)) -- CERROR("couldn't free obdfilter open cache\n"); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Filtering OBD driver v1.0"); --MODULE_LICENSE("GPL"); -- --module_init(obdfilter_init); --module_exit(obdfilter_exit); diff --cc lustre/obdfilter/lproc_obdfilter.c index e680784,e680784..0000000 deleted file mode 100644,100644 --- a/lustre/obdfilter/lproc_obdfilter.c +++ /dev/null @@@ -1,145 -1,145 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_uuid); -- return len; --} --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct statfs mystats; -- int len = 0; -- -- vfs_statfs(temp->u.filter.fo_sb, &mystats); -- len+=snprintf(page, count, "%ld\n", mystats.f_bsize); -- return len; --} --int rd_kbtotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct statfs mystats; -- int len = 0; -- __u32 blk_size; -- __u64 result; -- -- vfs_statfs(temp->u.filter.fo_sb, &mystats); -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_blocks; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len+=snprintf(page, count, LPU64"\n", result); -- return len; --} -- --int rd_kbfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct statfs mystats; -- int len = 0; -- __u32 blk_size; -- __u64 result; -- -- vfs_statfs(temp->u.filter.fo_sb, &mystats); -- blk_size = mystats.f_bsize; -- blk_size >>= 10; -- result = mystats.f_bfree; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len += snprintf(page, count, LPU64"\n", result); -- return len; --} -- --int rd_fstype(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- int len = 0; -- len += snprintf(page, count, "%s\n", temp->u.filter.fo_fstype); -- return len; --} --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct statfs mystats; -- int len = 0; -- vfs_statfs(temp->u.filter.fo_sb, &mystats); -- len += snprintf(page, count, "%ld\n", mystats.f_files); -- return len; --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct statfs mystats; -- int len = 0; -- vfs_statfs(temp->u.filter.fo_sb, &mystats); -- len += snprintf(page, count, "%ld\n", mystats.f_ffree); -- return len; --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytestotal",rd_kbtotal, 0, 0}, -- {"status/kbytesfree", rd_kbfree, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {"status/fstype", rd_fstype, 0, 0}, -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/osc/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/osc/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/osc/Makefile.am index 284c2d6,284c2d6..0000000 deleted file mode 100644,100644 --- a/lustre/osc/Makefile.am +++ /dev/null @@@ -1,25 -1,25 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --MODULE = osc --modulefs_DATA = osc.o --EXTRA_PROGRAMS = osc -- --LINX= obd_pack.c ll_pack.c client.c --osc_SOURCES = osc_request.c lproc_osc.c $(LINX) -- --obd_pack.c: -- test -e obd_pack.c || ln -sf $(top_srcdir)/lib/obd_pack.c --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c --client.c: -- test -e client.c || ln -sf $(top_srcdir)/lib/client.c -- --dist-hook: -- list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done -- --include $(top_srcdir)/Rules diff --cc lustre/osc/lproc_osc.c index 58e9097,58e9097..0000000 deleted file mode 100644,100644 --- a/lustre/osc/lproc_osc.c +++ /dev/null @@@ -1,119 -1,119 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- struct obd_device* dev = (struct obd_device*)data; -- len += snprintf(page, count, "%s\n", dev->obd_uuid); -- return len; -- --} --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --int rd_kbytestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_kbytesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} --int rd_server_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- struct client_obd* cli = &temp->u.cli; -- int len = 0; -- len += snprintf(page, count, "%s\n",cli->cl_target_uuid); -- return len; -- -- --} --int rd_conn_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp=(struct obd_device*)data; -- struct client_obd* cli=&temp->u.cli; -- struct obd_import* imp=&cli->cl_import; -- int len = 0; -- len += snprintf(page, count, "%s\n", -- imp->imp_connection->c_remote_uuid); -- return len; -- --} -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytestotal", rd_kbytestotal, 0, 0}, -- {"status/kbytesfree", rd_kbytesfree, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {"status/ost_server_uuid", rd_server_uuid, 0, 0}, -- {"status/ost_conn_uuid", rd_conn_uuid, 0, 0}, -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/osc/osc_request.c index e626160,de403b5..0000000 deleted file mode 100644,100644 --- a/lustre/osc/osc_request.c +++ /dev/null @@@ -1,921 -1,1029 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * Copyright (C) 2001, 2002 Cluster File Systems, Inc. - * Author Peter Braam -- * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * This file is part of Lustre, http://www.lustre.org. -- * - * Author Peter Braam - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. -- * - * This server is single threaded at present (but can easily be multi - * threaded). For testing and management it is treated as an - * obd_device, although it does not export a full OBD method table - * (the requests are coming in over the wire, so object target - * modules do not have a full method table.) - * Lustre 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. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For testing and management it is treated as an obd_device, - * although * it does not export a full OBD method table (the - * requests are coming * in over the wire, so object target modules - * do not have a full * method table.) -- * -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_OSC -- --#include --#include --#include --#include --#include --#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) --#include --#endif --#include --#include /* for mds_objid */ --#include - #include -#include /* for IOC_LOV_SET_OSC_ACTIVE */ --#include --#include --#include --#include /* for OBD_FAIL_CHECK */ --#include /* for ll_i2info */ --#include /* for PTL_MD_MAX_IOV */ --#include -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; - -static int osc_attach(struct obd_device *dev, obd_count len, void *data) -{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); -} - -static int osc_detach(struct obd_device *dev) -{ - return lprocfs_dereg_obd(dev); -} - -/* Pack OSC object metadata for shipment to the MDS. */ -static int osc_packmd(struct lustre_handle *conn, struct lov_mds_md **lmmp, - struct lov_stripe_md *lsm) -{ - int lmm_size; - - lmm_size = sizeof(**lmmp); - if (!lmmp) - RETURN(lmm_size); - - if (*lmmp && !lsm) { - OBD_FREE(*lmmp, lmm_size); - *lmmp = NULL; - RETURN(0); - } - - if (!*lmmp) { - OBD_ALLOC(*lmmp, lmm_size); - if (!*lmmp) - RETURN(-ENOMEM); - } - if (lsm) { - LASSERT(lsm->lsm_object_id); - (*lmmp)->lmm_object_id = (lsm->lsm_object_id); - } - - return lmm_size; -} - -static int osc_unpackmd(struct lustre_handle *conn, struct lov_stripe_md **lsmp, - struct lov_mds_md *lmm) -{ - int lsm_size; - - lsm_size = sizeof(**lsmp); - if (!lsmp) - RETURN(lsm_size); - - if (*lsmp && !lmm) { - OBD_FREE(*lsmp, lsm_size); - *lsmp = NULL; - RETURN(0); - } - - if (!*lsmp) { - OBD_ALLOC(*lsmp, lsm_size); - if (!*lsmp) - RETURN(-ENOMEM); - } - - /* XXX endianness */ - if (lmm) { - (*lsmp)->lsm_object_id = (lmm->lmm_object_id); - LASSERT((*lsmp)->lsm_object_id); - } - - return lsm_size; -} -- --static int osc_getattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_GETATTR, 1, -- &size, NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); --#warning FIXME: pack only valid fields instead of memcpy, endianness -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) { -- CERROR("%s failed: rc = %d\n", __FUNCTION__, rc); -- GOTO(out, rc); -- } -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); -- if (oa) -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} -- --static int osc_open(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_OPEN, 1, &size, -- NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); --#warning FIXME: pack only valid fields instead of memcpy, endianness -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out, rc); -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); -- if (oa) -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} -- --static int osc_close(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_CLOSE, 1, &size, -- NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); --#warning FIXME: pack only valid fields instead of memcpy, endianness -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out, rc); -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- CDEBUG(D_INODE, "mode: %o\n", body->oa.o_mode); -- if (oa) -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} -- --static int osc_setattr(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_SETATTR, 1, -- &size, NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- -- ptlrpc_req_finished(request); -- return rc; --} -- --static int osc_create(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md **ea) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- struct lov_stripe_md *lsm; -- int rc, size = sizeof(*body); -- ENTRY; -- -- LASSERT(oa); -- LASSERT(ea); -- -- lsm = *ea; -- if (!lsm) { - // XXX check oa->o_valid & OBD_MD_FLEASIZE first... - OBD_ALLOC(lsm, oa->o_easize); - if (!lsm) - RETURN(-ENOMEM); - lsm->lsm_mds_easize = oa->o_easize; - rc = obd_alloc_memmd(conn, &lsm); - if (rc < 0) - RETURN(rc); -- } -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_CREATE, 1, &size, -- NULL); -- if (!request) -- GOTO(out, rc = -ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out_req, rc); -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- lsm->lsm_object_id = oa->o_id; -- lsm->lsm_stripe_count = 0; -- *ea = lsm; -- EXIT; --out_req: -- ptlrpc_req_finished(request); --out: -- if (rc && !*ea) - OBD_FREE(lsm, oa->o_easize); - obd_free_memmd(conn, &lsm); -- return rc; --} -- --static int osc_punch(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *md, obd_size start, -- obd_size end) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- if (!oa) { -- CERROR("oa NULL\n"); -- RETURN(-EINVAL); -- } -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_PUNCH, 1, &size, -- NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); --#warning FIXME: pack only valid fields instead of memcpy, endianness, valid -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- /* overload the size and blocks fields in the oa with start/end */ -- body->oa.o_size = HTON__u64(start); -- body->oa.o_blocks = HTON__u64(end); -- body->oa.o_valid |= HTON__u32(OBD_MD_FLSIZE | OBD_MD_FLBLOCKS); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out, rc); -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} -- --static int osc_destroy(struct lustre_handle *conn, struct obdo *oa, -- struct lov_stripe_md *ea) --{ -- struct ptlrpc_request *request; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- if (!oa) { -- CERROR("oa NULL\n"); -- RETURN(-EINVAL); -- } -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_DESTROY, 1, -- &size, NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); --#warning FIXME: pack only valid fields instead of memcpy, endianness -- memcpy(&body->oa, oa, sizeof(*oa)); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out, rc); -- -- body = lustre_msg_buf(request->rq_repmsg, 0); -- memcpy(oa, &body->oa, sizeof(*oa)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} - - struct osc_brw_cb_data { - brw_cb_t callback; - void *cb_data; - void *obd_data; - size_t obd_size; - }; -- --/* Our bulk-unmapping bottom half. */ --static void unmap_and_decref_bulk_desc(void *data) --{ -- struct ptlrpc_bulk_desc *desc = data; -- struct list_head *tmp; -- ENTRY; -- -- /* This feels wrong to me. */ -- list_for_each(tmp, &desc->bd_page_list) { -- struct ptlrpc_bulk_page *bulk; -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); -- -- kunmap(bulk->bp_page); -- obd_kmap_put(1); -- } -- -- ptlrpc_bulk_decref(desc); -- EXIT; --} -- --/* this is the callback function which is invoked by the Portals -- * event handler associated with the bulk_sink queue and bulk_source queue. -- */ - - static void osc_ptl_ev_hdlr(struct ptlrpc_bulk_desc *desc, void *data) -static void osc_ptl_ev_hdlr(struct ptlrpc_bulk_desc *desc) --{ - struct osc_brw_cb_data *cb_data = data; - int err = 0; -- ENTRY; - - if (desc->bd_flags & PTL_RPC_FL_TIMEOUT) { - err = (desc->bd_flags & PTL_RPC_FL_INTR ? -ERESTARTSYS : - -ETIMEDOUT); - } -- - if (cb_data->callback) - cb_data->callback(cb_data->cb_data, err, CB_PHASE_FINISH); - LASSERT(desc->bd_brw_set != NULL); - LASSERT(desc->bd_brw_set->brw_callback != NULL); -- - if (cb_data->obd_data) - OBD_FREE(cb_data->obd_data, cb_data->obd_size); - OBD_FREE(cb_data, sizeof(*cb_data)); - desc->bd_brw_set->brw_callback(desc->bd_brw_set, CB_PHASE_FINISH); -- -- /* We can't kunmap the desc from interrupt context, so we do it from -- * the bottom half above. */ -- prepare_work(&desc->bd_queue, unmap_and_decref_bulk_desc, desc); -- schedule_work(&desc->bd_queue); -- -- EXIT; --} -- --static int osc_brw_read(struct lustre_handle *conn, struct lov_stripe_md *lsm, -- obd_count page_count, struct brw_page *pga, - brw_cb_t callback, struct brw_cb_data *data) - struct obd_brw_set *set) --{ - struct ptlrpc_connection *connection = - client_conn2cli(conn)->cl_import.imp_connection; - struct obd_import *imp = class_conn2cliimp(conn); - struct ptlrpc_connection *connection = imp->imp_connection; -- struct ptlrpc_request *request = NULL; -- struct ptlrpc_bulk_desc *desc = NULL; -- struct ost_body *body; - struct osc_brw_cb_data *cb_data = NULL; - int rc, size[3] = {sizeof(*body)}; - int rc, size[3] = {sizeof(*body)}, mapped = 0; -- void *iooptr, *nioptr; - int mapped = 0; -- __u32 xid; -- ENTRY; -- -- size[1] = sizeof(struct obd_ioobj); -- size[2] = page_count * sizeof(struct niobuf_remote); -- - request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_READ, 3, size, - NULL); - request = ptlrpc_prep_req(imp, OST_READ, 3, size, NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); -- -- desc = ptlrpc_prep_bulk(connection); -- if (!desc) -- GOTO(out_req, rc = -ENOMEM); -- desc->bd_portal = OST_BULK_PORTAL; -- desc->bd_ptl_ev_hdlr = osc_ptl_ev_hdlr; - OBD_ALLOC(cb_data, sizeof(*cb_data)); - if (!cb_data) - GOTO(out_desc, rc = -ENOMEM); - - cb_data->callback = callback; - cb_data->cb_data = data; - CDEBUG(D_PAGE, "data(%p)->desc = %p\n", data, desc); - data->brw_desc = desc; - desc->bd_ptl_ev_data = cb_data; - CDEBUG(D_PAGE, "desc = %p\n", desc); -- -- iooptr = lustre_msg_buf(request->rq_reqmsg, 1); -- nioptr = lustre_msg_buf(request->rq_reqmsg, 2); -- ost_pack_ioo(&iooptr, lsm, page_count); -- /* end almost identical to brw_write case */ -- - spin_lock(&connection->c_lock); - xid = ++connection->c_xid_out; /* single xid for all pages */ - spin_unlock(&connection->c_lock); - spin_lock(&imp->imp_lock); - xid = ++imp->imp_last_xid; /* single xid for all pages */ - spin_unlock(&imp->imp_lock); -- -- obd_kmap_get(page_count, 0); -- -- for (mapped = 0; mapped < page_count; mapped++) { -- struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); -- if (bulk == NULL) -- GOTO(out_unmap, rc = -ENOMEM); -- -- bulk->bp_xid = xid; /* single xid for all pages */ -- -- bulk->bp_buf = kmap(pga[mapped].pg); -- bulk->bp_page = pga[mapped].pg; -- bulk->bp_buflen = PAGE_SIZE; -- ost_pack_niobuf(&nioptr, pga[mapped].off, pga[mapped].count, -- pga[mapped].flag, bulk->bp_xid); -- } -- -- /* -- * Register the bulk first, because the reply could arrive out of order, -- * and we want to be ready for the bulk data. -- * - * The reference is released when brw_finish is complete. - * One reference is released when brw_finish is complete, the other when - * the caller removes us from the "set" list. -- * -- * On error, we never do the brw_finish, so we handle all decrefs. -- */ -- if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_READ_BULK)) { -- CERROR("obd_fail_loc=%x, skipping register_bulk\n", -- OBD_FAIL_OSC_BRW_READ_BULK); -- } else { -- rc = ptlrpc_register_bulk(desc); -- if (rc) -- GOTO(out_unmap, rc); - obd_brw_set_add(set, desc); -- } -- -- request->rq_replen = lustre_msg_size(1, size); -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- -- /* -- * XXX: If there is an error during the processing of the callback, -- * such as a timeout in a sleep that it performs, brw_finish -- * will never get called, and we'll leak the desc, fail to kunmap -- * things, cats will live with dogs. One solution would be to -- * export brw_finish as osc_brw_finish, so that the timeout case -- * and its kin could call it for proper cleanup. An alternative -- * would be for an error return from the callback to cause us to -- * clean up, but that doesn't help the truly async cases (like -- * LOV), which will immediately return from their PHASE_START -- * callback, before any such cleanup-requiring error condition can -- * be detected. -- */ - if (rc) - GOTO(out_req, rc); - - /* Callbacks cause asynchronous handling. */ - rc = callback(data, 0, CB_PHASE_START); - - out_req: - out_req: -- ptlrpc_req_finished(request); -- RETURN(rc); -- -- /* Clean up on error. */ --out_unmap: -- while (mapped-- > 0) -- kunmap(pga[mapped].pg); -- obd_kmap_put(page_count); - OBD_FREE(cb_data, sizeof(*cb_data)); - out_desc: -- ptlrpc_bulk_decref(desc); -- goto out_req; --} -- --static int osc_brw_write(struct lustre_handle *conn, struct lov_stripe_md *md, -- obd_count page_count, struct brw_page *pga, - brw_cb_t callback, struct brw_cb_data *data) - struct obd_brw_set *set) --{ -- struct ptlrpc_connection *connection = -- client_conn2cli(conn)->cl_import.imp_connection; -- struct ptlrpc_request *request = NULL; -- struct ptlrpc_bulk_desc *desc = NULL; -- struct ost_body *body; -- struct niobuf_local *local = NULL; -- struct niobuf_remote *remote; - struct osc_brw_cb_data *cb_data = NULL; - int rc, j, size[3] = {sizeof(*body)}; - int rc, j, size[3] = {sizeof(*body)}, mapped = 0; -- void *iooptr, *nioptr; - int mapped = 0; -- ENTRY; -- -- size[1] = sizeof(struct obd_ioobj); -- size[2] = page_count * sizeof(*remote); -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_WRITE, 3, size, -- NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- body = lustre_msg_buf(request->rq_reqmsg, 0); -- -- desc = ptlrpc_prep_bulk(connection); -- if (!desc) - GOTO(out_req, rc = -ENOMEM); - GOTO(out_req, rc = -ENOMEM); -- desc->bd_portal = OSC_BULK_PORTAL; -- desc->bd_ptl_ev_hdlr = osc_ptl_ev_hdlr; - OBD_ALLOC(cb_data, sizeof(*cb_data)); - if (!cb_data) - GOTO(out_desc, rc = -ENOMEM); - - cb_data->callback = callback; - cb_data->cb_data = data; - CDEBUG(D_PAGE, "data(%p)->desc = %p\n", data, desc); - data->brw_desc = desc; - desc->bd_ptl_ev_data = cb_data; - CDEBUG(D_PAGE, "desc = %p\n", desc); -- -- iooptr = lustre_msg_buf(request->rq_reqmsg, 1); -- nioptr = lustre_msg_buf(request->rq_reqmsg, 2); -- ost_pack_ioo(&iooptr, md, page_count); -- /* end almost identical to brw_read case */ -- -- OBD_ALLOC(local, page_count * sizeof(*local)); -- if (!local) - GOTO(out_cb, rc = -ENOMEM); - - cb_data->obd_data = local; - cb_data->obd_size = page_count * sizeof(*local); - GOTO(out_desc, rc = -ENOMEM); -- -- obd_kmap_get(page_count, 0); -- -- for (mapped = 0; mapped < page_count; mapped++) { -- local[mapped].addr = kmap(pga[mapped].pg); -- -- CDEBUG(D_INFO, "kmap(pg) = %p ; pg->flags = %lx ; pg->count = " -- "%d ; page %d of %d\n", -- local[mapped].addr, pga[mapped].pg->flags, -- page_count(pga[mapped].pg), -- mapped, page_count - 1); -- -- local[mapped].offset = pga[mapped].off; -- local[mapped].len = pga[mapped].count; -- ost_pack_niobuf(&nioptr, pga[mapped].off, pga[mapped].count, -- pga[mapped].flag, 0); -- } -- -- size[1] = page_count * sizeof(*remote); -- request->rq_replen = lustre_msg_size(2, size); -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) -- GOTO(out_unmap, rc); -- -- nioptr = lustre_msg_buf(request->rq_repmsg, 1); -- if (!nioptr) -- GOTO(out_unmap, rc = -EINVAL); -- -- if (request->rq_repmsg->buflens[1] != size[1]) { -- CERROR("buffer length wrong (%d vs. %d)\n", -- request->rq_repmsg->buflens[1], size[1]); -- GOTO(out_unmap, rc = -EINVAL); -- } -- -- for (j = 0; j < page_count; j++) { -- struct ptlrpc_bulk_page *bulk; -- -- ost_unpack_niobuf(&nioptr, &remote); -- -- bulk = ptlrpc_prep_bulk_page(desc); -- if (!bulk) -- GOTO(out_unmap, rc = -ENOMEM); -- -- bulk->bp_buf = (void *)(unsigned long)local[j].addr; -- bulk->bp_buflen = local[j].len; -- bulk->bp_xid = remote->xid; -- bulk->bp_page = pga[j].pg; -- } -- -- if (desc->bd_page_count != page_count) -- LBUG(); -- -- if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_WRITE_BULK)) -- GOTO(out_unmap, rc = 0); -- - /* Our reference is released when brw_finish is complete. */ - OBD_FREE(local, page_count * sizeof(*local)); - - /* One reference is released when brw_finish is complete, the other - * when the caller removes it from the "set" list. */ - obd_brw_set_add(set, desc); -- rc = ptlrpc_send_bulk(desc); -- -- /* XXX: Mike, same question as in osc_brw_read. */ - if (rc) - GOTO(out_req, rc); - - /* Callbacks cause asynchronous handling. */ - rc = callback(data, 0, CB_PHASE_START); - --out_req: -- ptlrpc_req_finished(request); -- RETURN(rc); -- -- /* Clean up on error. */ --out_unmap: -- while (mapped-- > 0) -- kunmap(pga[mapped].pg); -- -- obd_kmap_put(page_count); -- -- OBD_FREE(local, page_count * sizeof(*local)); - out_cb: - OBD_FREE(cb_data, sizeof(*cb_data)); --out_desc: -- ptlrpc_bulk_decref(desc); -- goto out_req; --} -- --static int osc_brw(int cmd, struct lustre_handle *conn, -- struct lov_stripe_md *md, obd_count page_count, - struct brw_page *pga, brw_cb_t callback, - struct brw_cb_data *data) - struct brw_page *pga, struct obd_brw_set *set) --{ -- ENTRY; -- -- while (page_count) { -- obd_count pages_per_brw; -- int rc; -- -- if (page_count > PTL_MD_MAX_IOV) -- pages_per_brw = PTL_MD_MAX_IOV; -- else -- pages_per_brw = page_count; -- -- if (cmd & OBD_BRW_WRITE) - rc = osc_brw_write(conn, md, pages_per_brw, pga, - callback, data); - rc = osc_brw_write(conn, md, pages_per_brw, pga, set); -- else - rc = osc_brw_read(conn, md, pages_per_brw, pga, - callback, data); - rc = osc_brw_read(conn, md, pages_per_brw, pga, set); -- -- if (rc != 0) -- RETURN(rc); -- -- page_count -= pages_per_brw; -- pga += pages_per_brw; -- } -- RETURN(0); --} -- --static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *lsm, -- struct lustre_handle *parent_lock, -- __u32 type, void *extentp, int extent_len, __u32 mode, -- int *flags, void *callback, void *data, int datalen, -- struct lustre_handle *lockh) --{ -- __u64 res_id[RES_NAME_SIZE] = { lsm->lsm_object_id }; -- struct obd_device *obddev = class_conn2obd(connh); -- struct ldlm_extent *extent = extentp; -- int rc; -- ENTRY; -- -- /* Filesystem locks are given a bit of special treatment: if -- * this is not a file size lock (which has end == -1), we -- * fixup the lock to start and end on page boundaries. */ -- if (extent->end != OBD_OBJECT_EOF) { -- extent->start &= PAGE_MASK; - extent->end = (extent->end + PAGE_SIZE - 1) & PAGE_MASK; - extent->end = (extent->end & PAGE_MASK) + PAGE_SIZE - 1; -- } -- -- /* Next, search for already existing extent locks that will cover us */ -- rc = ldlm_lock_match(obddev->obd_namespace, res_id, type, extent, -- sizeof(extent), mode, lockh); -- if (rc == 1) -- /* We already have a lock, and it's referenced */ -- RETURN(ELDLM_OK); -- -- /* If we're trying to read, we also search for an existing PW lock. The -- * VFS and page cache already protect us locally, so lots of readers/ -- * writers can share a single PW lock. -- * -- * There are problems with conversion deadlocks, so instead of -- * converting a read lock to a write lock, we'll just enqueue a new -- * one. -- * -- * At some point we should cancel the read lock instead of making them -- * send us a blocking callback, but there are problems with canceling -- * locks out from other users right now, too. */ -- -- if (mode == LCK_PR) { -- rc = ldlm_lock_match(obddev->obd_namespace, res_id, type, -- extent, sizeof(extent), LCK_PW, lockh); -- if (rc == 1) { -- /* FIXME: This is not incredibly elegant, but it might -- * be more elegant than adding another parameter to -- * lock_match. I want a second opinion. */ -- ldlm_lock_addref(lockh, LCK_PR); -- ldlm_lock_decref(lockh, LCK_PW); -- -- RETURN(ELDLM_OK); -- } -- } -- -- rc = ldlm_cli_enqueue(connh, NULL, obddev->obd_namespace, parent_lock, -- res_id, type, extent, sizeof(extent), mode, flags, -- ldlm_completion_ast, callback, data, datalen, -- lockh); -- RETURN(rc); --} -- --static int osc_cancel(struct lustre_handle *oconn, struct lov_stripe_md *md, -- __u32 mode, struct lustre_handle *lockh) --{ -- ENTRY; -- -- ldlm_lock_decref(lockh, mode); -- -- RETURN(0); --} -- --static int osc_cancel_unused(struct lustre_handle *connh, -- struct lov_stripe_md *lsm, int flags) --{ -- struct obd_device *obddev = class_conn2obd(connh); -- __u64 res_id[RES_NAME_SIZE] = { lsm->lsm_object_id }; -- -- return ldlm_cli_cancel_unused(obddev->obd_namespace, res_id, flags); --} -- --static int osc_statfs(struct lustre_handle *conn, struct obd_statfs *osfs) --{ -- struct ptlrpc_request *request; -- int rc, size = sizeof(*osfs); -- ENTRY; -- -- request = ptlrpc_prep_req(class_conn2cliimp(conn), OST_STATFS, 0, NULL, -- NULL); -- if (!request) -- RETURN(-ENOMEM); -- -- request->rq_replen = lustre_msg_size(1, &size); -- -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); -- if (rc) { -- CERROR("%s failed: rc = %d\n", __FUNCTION__, rc); -- GOTO(out, rc); -- } -- -- obd_statfs_unpack(osfs, lustre_msg_buf(request->rq_repmsg, 0)); -- -- EXIT; -- out: -- ptlrpc_req_finished(request); -- return rc; --} -- - static int osc_iocontrol(long cmd, struct lustre_handle *conn, int len, -static int osc_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, -- void *karg, void *uarg) --{ -- struct obd_device *obddev = class_conn2obd(conn); -- struct obd_ioctl_data *data = karg; -- int err = 0; -- ENTRY; -- -- switch (cmd) { -- case IOC_LDLM_TEST: { -- err = ldlm_test(obddev, conn); -- CERROR("-- done err %d\n", err); -- GOTO(out, err); -- } -- case IOC_LDLM_REGRESS_START: { -- unsigned int numthreads = 1; -- unsigned int numheld = 10; -- unsigned int numres = 10; -- unsigned int numext = 10; -- char *parse; -- -- if (data->ioc_inllen1) { -- parse = data->ioc_inlbuf1; -- if (*parse != '\0') { -- while(isspace(*parse)) parse++; -- numthreads = simple_strtoul(parse, &parse, 0); -- while(isspace(*parse)) parse++; -- } -- if (*parse != '\0') { -- while(isspace(*parse)) parse++; -- numheld = simple_strtoul(parse, &parse, 0); -- while(isspace(*parse)) parse++; -- } -- if (*parse != '\0') { -- while(isspace(*parse)) parse++; -- numres = simple_strtoul(parse, &parse, 0); -- while(isspace(*parse)) parse++; -- } -- if (*parse != '\0') { -- while(isspace(*parse)) parse++; -- numext = simple_strtoul(parse, &parse, 0); -- while(isspace(*parse)) parse++; -- } -- } -- -- err = ldlm_regression_start(obddev, conn, numthreads, -- numheld, numres, numext); -- -- CERROR("-- done err %d\n", err); -- GOTO(out, err); -- } -- case IOC_LDLM_REGRESS_STOP: { -- err = ldlm_regression_stop(); -- CERROR("-- done err %d\n", err); -- GOTO(out, err); -- } -- case IOC_OSC_REGISTER_LOV: { -- if (obddev->u.cli.cl_containing_lov) -- GOTO(out, err = -EALREADY); -- obddev->u.cli.cl_containing_lov = (struct obd_device *)karg; -- GOTO(out, err); -- } -- case OBD_IOC_LOV_GET_CONFIG: { -- char *buf; -- struct lov_desc *desc; -- obd_uuid_t *uuidp; -- -- buf = NULL; -- len = 0; -- if (obd_ioctl_getdata(&buf, &len, (void *)uarg)) -- GOTO(out, err = -EINVAL); -- -- data = (struct obd_ioctl_data *)buf; -- -- if (sizeof(*desc) > data->ioc_inllen1) { -- OBD_FREE(buf, len); -- GOTO(out, err = -EINVAL); -- } -- -- if (data->ioc_inllen2 < sizeof(*uuidp)) { -- OBD_FREE(buf, len); -- GOTO(out, err = -EINVAL); -- } -- -- desc = (struct lov_desc *)data->ioc_inlbuf1; -- desc->ld_tgt_count = 1; -- desc->ld_active_tgt_count = 1; -- desc->ld_default_stripe_count = 1; -- desc->ld_default_stripe_size = 0; -- desc->ld_default_stripe_offset = 0; -- desc->ld_pattern = 0; -- memcpy(desc->ld_uuid, obddev->obd_uuid, sizeof(*uuidp)); -- -- uuidp = (obd_uuid_t *)data->ioc_inlbuf2; -- memcpy(uuidp, obddev->obd_uuid, sizeof(*uuidp)); -- -- err = copy_to_user((void *)uarg, buf, len); - if (err) - err = -EFAULT; -- OBD_FREE(buf, len); -- GOTO(out, err); -- } -- default: - CERROR ("osc_ioctl(): unrecognised ioctl %#lx\n", cmd); -- GOTO(out, err = -ENOTTY); -- } --out: -- return err; --} -- - int osc_attach(struct obd_device *dev, obd_count len, void *data) -static void set_osc_active(struct obd_import *imp, int active) --{ - return lprocfs_reg_obd(dev, status_var_nm_1, dev); - struct obd_device *notify_obd = imp->imp_obd->u.cli.cl_containing_lov; - - if (notify_obd == NULL) - return; - - /* How gross is _this_? */ - if (!list_empty(¬ify_obd->obd_exports)) { - int rc; - struct lustre_handle fakeconn; - struct obd_ioctl_data ioc_data; - struct obd_export *exp = - list_entry(notify_obd->obd_exports.next, - struct obd_export, exp_obd_chain); - - fakeconn.addr = (__u64)(unsigned long)exp; - fakeconn.cookie = exp->exp_cookie; - ioc_data.ioc_inlbuf1 = imp->imp_obd->obd_uuid; - ioc_data.ioc_offset = active; - rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn, - sizeof ioc_data, &ioc_data, NULL); - if (rc) - CERROR("disabling %s on LOV %p/%s: %d\n", - imp->imp_obd->obd_uuid, notify_obd, - notify_obd->obd_uuid, rc); - } else { - CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about " - "%p\n", notify_obd, notify_obd->obd_uuid, - imp->imp_obd->obd_uuid); - } --} -- - int osc_detach(struct obd_device *dev) - -/* XXX looks a lot like super.c:invalidate_request_list, don't it? */ -static void abort_inflight_for_import(struct obd_import *imp) --{ - return lprocfs_dereg_obd(dev); - struct list_head *tmp, *n; - - /* Make sure that no new requests get processed for this import. - * ptlrpc_queue_wait must (and does) hold imp_lock while testing this - * flag and then putting requests on sending_list or delayed_list. - */ - spin_lock(&imp->imp_lock); - imp->imp_flags |= IMP_INVALID; - spin_unlock(&imp->imp_lock); - - list_for_each_safe(tmp, n, &imp->imp_sending_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - - DEBUG_REQ(D_HA, req, "inflight"); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } - - list_for_each_safe(tmp, n, &imp->imp_delayed_list) { - struct ptlrpc_request *req = - list_entry(tmp, struct ptlrpc_request, rq_list); - - DEBUG_REQ(D_HA, req, "aborting waiting req"); - req->rq_flags |= PTL_RPC_FL_ERR; - wake_up(&req->rq_wait_for_rep); - } -} - -static int osc_recover(struct obd_import *imp, int phase) -{ - int rc; - ENTRY; - - switch(phase) { - case PTLRPC_RECOVD_PHASE_PREPARE: { - struct ldlm_namespace *ns = imp->imp_obd->obd_namespace; - ldlm_namespace_cleanup(ns, 1 /* no network ops */); - abort_inflight_for_import(imp); - set_osc_active(imp, 0 /* inactive */); - RETURN(0); - } - case PTLRPC_RECOVD_PHASE_RECOVER: - imp->imp_flags &= ~IMP_INVALID; - rc = ptlrpc_reconnect_import(imp, OST_CONNECT); - if (rc) { - imp->imp_flags |= IMP_INVALID; - RETURN(rc); - } - set_osc_active(imp, 1 /* active */); - RETURN(0); - default: - RETURN(-EINVAL); - } -} - -static int osc_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid, struct recovd_obd *recovd, - ptlrpc_recovery_cb_t recover) -{ - struct obd_import *imp = &obd->u.cli.cl_import; - imp->imp_recover = osc_recover; - return client_obd_connect(conn, obd, cluuid, recovd, recover); --} - --struct obd_ops osc_obd_ops = { -- o_attach: osc_attach, -- o_detach: osc_detach, -- o_setup: client_obd_setup, -- o_cleanup: client_obd_cleanup, - o_connect: osc_connect, - o_disconnect: client_obd_disconnect, -- o_statfs: osc_statfs, - o_packmd: osc_packmd, - o_unpackmd: osc_unpackmd, -- o_create: osc_create, -- o_destroy: osc_destroy, -- o_getattr: osc_getattr, -- o_setattr: osc_setattr, -- o_open: osc_open, -- o_close: osc_close, - o_connect: client_obd_connect, - o_disconnect: client_obd_disconnect, -- o_brw: osc_brw, -- o_punch: osc_punch, -- o_enqueue: osc_enqueue, -- o_cancel: osc_cancel, -- o_cancel_unused: osc_cancel_unused, -- o_iocontrol: osc_iocontrol --}; -- --static int __init osc_init(void) --{ - int rc; - rc = class_register_type(&osc_obd_ops, status_class_var, - LUSTRE_OSC_NAME); - RETURN(rc); - - RETURN(class_register_type(&osc_obd_ops, status_class_var, - LUSTRE_OSC_NAME)); --} -- --static void __exit osc_exit(void) --{ -- class_unregister_type(LUSTRE_OSC_NAME); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Object Storage Client (OSC) v1.0"); --MODULE_LICENSE("GPL"); -- --module_init(osc_init); --module_exit(osc_exit); diff --cc lustre/ost/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/ost/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/ost/Makefile.am index 3ad390a,3ad390a..0000000 deleted file mode 100644,100644 --- a/lustre/ost/Makefile.am +++ /dev/null @@@ -1,24 -1,24 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= --MODULE = ost --modulefs_DATA = ost.o --EXTRA_PROGRAMS = ost -- --LINX=obd_pack.c ll_pack.c target.c -- --ll_pack.c: -- test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c --obd_pack.c: -- test -e obd_pack.c || ln -sf $(top_srcdir)/lib/obd_pack.c --target.c: -- test -e target.c || ln -sf $(top_srcdir)/lib/target.c -- --ost_SOURCES = ost_handler.c lproc_ost.c $(LINX) --dist-hook: -- list='$(LINX)'; for f in $$list; do rm -f $(distdir)/$$f; done -- --include $(top_srcdir)/Rules diff --cc lustre/ost/lproc_ost.c index 1fa1c59,1fa1c59..0000000 deleted file mode 100644,100644 --- a/lustre/ost/lproc_ost.c +++ /dev/null @@@ -1,162 -1,162 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_OST -- --#include --#include -- -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- int len = 0; -- len += snprintf(page, count, "%s\n", temp->obd_uuid); -- return len; -- -- --} --int rd_blksize(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- struct ost_obd *ost = &temp->u.ost; -- struct lustre_handle *conn = &ost->ost_conn; -- struct obd_statfs mystats; -- int len = 0; -- -- obd_statfs(conn, &mystats); -- len += snprintf(page, count, "%d\n", mystats.os_bsize); -- return len; -- --} --int rd_kbtotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct ost_obd *ost = &temp->u.ost; -- struct lustre_handle *conn = &ost->ost_conn; -- struct obd_statfs mystats; -- int len = 0; -- __u32 blk_size; -- __u64 result; -- -- obd_statfs(conn, &mystats); -- blk_size = mystats.os_bsize; -- blk_size >>= 10; -- result = mystats.os_blocks; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len += snprintf(page, count, LPU64"\n", result); -- return len; -- --} -- -- --int rd_kbfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- struct ost_obd *ost = &temp->u.ost; -- struct lustre_handle *conn = &ost->ost_conn; -- struct obd_statfs mystats; -- int len = 0; -- __u32 blk_size; -- __u64 result; -- -- obd_statfs(conn, &mystats); -- blk_size = mystats.os_bsize; -- blk_size >>= 10; -- result = mystats.os_bfree; -- while(blk_size >>= 1){ -- result <<= 1; -- } -- len += snprintf(page, count, LPU64"\n", result); -- return len; --} -- --int rd_filestotal(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_device* temp = (struct obd_device*)data; -- struct ost_obd *ost = &temp->u.ost; -- struct lustre_handle *conn = &ost->ost_conn; -- struct obd_statfs mystats; -- int len = 0; -- -- obd_statfs(conn, &mystats); -- len += snprintf(page, count, LPU64"\n",mystats.os_files); -- return len; -- --} -- --int rd_filesfree(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- -- struct obd_device* temp = (struct obd_device*)data; -- struct ost_obd *ost = &temp->u.ost; -- struct lustre_handle *conn = &ost->ost_conn; -- struct obd_statfs mystats; -- int len = 0; -- -- obd_statfs(conn, &mystats); -- len += snprintf(page, count, LPU64"\n", mystats.os_ffree); -- return len; -- --} -- --int rd_filegroups(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- return 0; --} -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {"status/blocksize",rd_blksize, 0, 0}, -- {"status/kbytesfree", rd_kbfree, 0, 0}, -- {"status/kbytestotal", rd_kbtotal, 0, 0}, -- {"status/filestotal", rd_filestotal, 0, 0}, -- {"status/filesfree", rd_filesfree, 0, 0}, -- {"status/filegroups", rd_filegroups, 0, 0}, -- {0} --}; -- --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; -- diff --cc lustre/ost/ost_handler.c index 228115f,2d47fcd..0000000 deleted file mode 100644,100644 --- a/lustre/ost/ost_handler.c +++ /dev/null @@@ -1,706 -1,702 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * Author: Peter J. Braam -- * Author: Phil Schwan -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Storage Target Handling functions -- * Lustre Object Server Module (OST) -- * -- * This server is single threaded at present (but can easily be multi -- * threaded). For testing and management it is treated as an -- * obd_device, although it does not export a full OBD method table -- * (the requests are coming in over the wire, so object target -- * modules do not have a full method table.) -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_OST -- --#include --#include --#include --#include --#include --#include -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --static int ost_destroy(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- req->rq_status = obd_destroy(conn, &body->oa, NULL); -- RETURN(0); --} -- --static int ost_getattr(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_getattr(conn, &repbody->oa, NULL); -- RETURN(0); --} -- --static int ost_statfs(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct obd_statfs *osfs; -- int rc, size = sizeof(*osfs); -- ENTRY; -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- osfs = lustre_msg_buf(req->rq_repmsg, 0); -- memset(osfs, 0, size); -- -- rc = obd_statfs(conn, osfs); -- if (rc) { -- CERROR("ost: statfs failed: rc %d\n", rc); -- req->rq_status = rc; -- RETURN(rc); -- } -- obd_statfs_pack(osfs, osfs); -- -- RETURN(0); --} -- --static int ost_open(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_open(conn, &repbody->oa, NULL); -- RETURN(0); --} -- --static int ost_close(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_close(conn, &repbody->oa, NULL); -- RETURN(0); --} -- --static int ost_create(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_create(conn, &repbody->oa, NULL); -- RETURN(0); --} -- --static int ost_punch(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- if ((NTOH__u32(body->oa.o_valid) & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS))!= -- (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) -- RETURN(-EINVAL); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_punch(conn, &repbody->oa, NULL, -- repbody->oa.o_size, repbody->oa.o_blocks); -- RETURN(0); --} -- --static int ost_setattr(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ost_body *body, *repbody; -- int rc, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- repbody = lustre_msg_buf(req->rq_repmsg, 0); -- /* FIXME: unpack only valid fields instead of memcpy, endianness */ -- memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); -- req->rq_status = obd_setattr(conn, &repbody->oa, NULL); -- RETURN(0); --} -- --static int ost_bulk_timeout(void *data) --{ -- struct ptlrpc_bulk_desc *desc = data; -- -- ENTRY; - CERROR("(not yet) starting recovery of client %p\n", desc->bd_client); - recovd_conn_fail(desc->bd_connection); -- RETURN(1); --} -- --static int ost_brw_read(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ptlrpc_bulk_desc *desc; -- void *tmp1, *tmp2, *end2; -- struct niobuf_remote *remote_nb; -- struct niobuf_local *local_nb = NULL; -- struct obd_ioobj *ioo; -- struct ost_body *body; -- struct l_wait_info lwi; -- void *desc_priv = NULL; -- int rc, cmd, i, j, objcount, niocount, size = sizeof(*body); -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); -- tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); -- end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2]; -- objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo); -- niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb); -- cmd = OBD_BRW_READ; -- -- if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_READ_BULK)) -- GOTO(out, rc = 0); -- -- for (i = 0; i < objcount; i++) { -- ost_unpack_ioo(&tmp1, &ioo); -- if (tmp2 + ioo->ioo_bufcnt > end2) { -- LBUG(); -- GOTO(out, rc = -EFAULT); -- } -- for (j = 0; j < ioo->ioo_bufcnt; j++) -- ost_unpack_niobuf(&tmp2, &remote_nb); -- } -- -- OBD_ALLOC(local_nb, sizeof(*local_nb) * niocount); -- if (local_nb == NULL) -- GOTO(out, rc = -ENOMEM); -- -- /* The unpackers move tmp1 and tmp2, so reset them before using */ -- ioo = lustre_msg_buf(req->rq_reqmsg, 1); -- remote_nb = lustre_msg_buf(req->rq_reqmsg, 2); -- req->rq_status = obd_preprw(cmd, conn, objcount, ioo, niocount, -- remote_nb, local_nb, &desc_priv); -- -- if (req->rq_status) -- GOTO(out, rc = 0); -- -- desc = ptlrpc_prep_bulk(req->rq_connection); -- if (desc == NULL) -- GOTO(out_local, rc = -ENOMEM); -- desc->bd_portal = OST_BULK_PORTAL; -- -- for (i = 0; i < niocount; i++) { -- struct ptlrpc_bulk_page *bulk = ptlrpc_prep_bulk_page(desc); -- -- if (bulk == NULL) -- GOTO(out_bulk, rc = -ENOMEM); -- bulk->bp_xid = remote_nb[i].xid; -- bulk->bp_buf = local_nb[i].addr; -- bulk->bp_buflen = remote_nb[i].len; -- } -- -- rc = ptlrpc_send_bulk(desc); -- if (rc) -- GOTO(out_bulk, rc); -- -- lwi = LWI_TIMEOUT(obd_timeout * HZ, ost_bulk_timeout, desc); -- rc = l_wait_event(desc->bd_waitq, desc->bd_flags &PTL_BULK_FL_SENT, &lwi); -- if (rc) { -- LASSERT(rc == -ETIMEDOUT); -- GOTO(out_bulk, rc); -- } -- -- req->rq_status = obd_commitrw(cmd, conn, objcount, ioo, niocount, -- local_nb, desc_priv); -- -- rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); -- --out_bulk: -- ptlrpc_free_bulk(desc); --out_local: -- OBD_FREE(local_nb, sizeof(*local_nb) * niocount); --out: - if (rc) { - /* It's a lot of work to delay allocating the reply, and a lot - * less work to just free it here. */ - OBD_FREE(req->rq_repmsg, req->rq_replen); - req->rq_repmsg = NULL; - if (rc) -- ptlrpc_error(req->rq_svc, req); - } else - else -- ptlrpc_reply(req->rq_svc, req); -- RETURN(rc); --} -- --static int ost_brw_write(struct ptlrpc_request *req) --{ -- struct lustre_handle *conn = (struct lustre_handle *)req->rq_reqmsg; -- struct ptlrpc_bulk_desc *desc; -- struct niobuf_remote *remote_nb; -- struct niobuf_local *local_nb, *lnb; -- struct obd_ioobj *ioo; -- struct ost_body *body; -- int cmd, rc, i, j, objcount, niocount, size[2] = {sizeof(*body)}; -- void *tmp1, *tmp2, *end2; -- void *desc_priv = NULL; -- int reply_sent = 0; -- struct ptlrpc_service *srv; -- struct l_wait_info lwi; -- __u32 xid; -- ENTRY; -- -- body = lustre_msg_buf(req->rq_reqmsg, 0); -- tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); -- tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); -- end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2]; -- objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo); -- niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb); -- cmd = OBD_BRW_WRITE; -- -- for (i = 0; i < objcount; i++) { -- ost_unpack_ioo((void *)&tmp1, &ioo); -- if (tmp2 + ioo->ioo_bufcnt > end2) { -- rc = -EFAULT; -- break; -- } -- for (j = 0; j < ioo->ioo_bufcnt; j++) -- ost_unpack_niobuf((void *)&tmp2, &remote_nb); -- } -- -- size[1] = niocount * sizeof(*remote_nb); -- rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- GOTO(out, rc); -- remote_nb = lustre_msg_buf(req->rq_repmsg, 1); -- -- OBD_ALLOC(local_nb, niocount * sizeof(*local_nb)); -- if (local_nb == NULL) -- GOTO(out, rc = -ENOMEM); -- -- /* The unpackers move tmp1 and tmp2, so reset them before using */ -- tmp1 = lustre_msg_buf(req->rq_reqmsg, 1); -- tmp2 = lustre_msg_buf(req->rq_reqmsg, 2); -- req->rq_status = obd_preprw(cmd, conn, objcount, tmp1, niocount, tmp2, -- local_nb, &desc_priv); -- if (req->rq_status) -- GOTO(out_free, rc = 0); /* XXX is this correct? */ -- -- if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_WRITE_BULK)) -- GOTO(fail_preprw, rc = 0); -- -- desc = ptlrpc_prep_bulk(req->rq_connection); -- if (desc == NULL) -- GOTO(fail_preprw, rc = -ENOMEM); -- desc->bd_ptl_ev_hdlr = NULL; -- desc->bd_portal = OSC_BULK_PORTAL; -- desc->bd_desc_private = desc_priv; -- memcpy(&(desc->bd_conn), &conn, sizeof(conn)); -- -- srv = req->rq_obd->u.ost.ost_service; -- spin_lock(&srv->srv_lock); -- xid = srv->srv_xid++; /* single xid for all pages */ -- spin_unlock(&srv->srv_lock); -- -- for (i = 0, lnb = local_nb; i < niocount; i++, lnb++) { -- struct ptlrpc_bulk_page *bulk; -- -- bulk = ptlrpc_prep_bulk_page(desc); -- if (bulk == NULL) -- GOTO(fail_bulk, rc = -ENOMEM); -- -- bulk->bp_xid = xid; /* single xid for all pages */ -- -- bulk->bp_buf = lnb->addr; -- bulk->bp_page = lnb->page; -- bulk->bp_flags = lnb->flags; -- bulk->bp_dentry = lnb->dentry; -- bulk->bp_buflen = lnb->len; -- bulk->bp_cb = NULL; -- -- /* this advances remote_nb */ -- ost_pack_niobuf((void **)&remote_nb, lnb->offset, lnb->len, 0, -- bulk->bp_xid); -- } -- -- rc = ptlrpc_register_bulk(desc); -- if (rc) -- GOTO(fail_bulk, rc); -- -- reply_sent = 1; -- ptlrpc_reply(req->rq_svc, req); -- -- lwi = LWI_TIMEOUT(obd_timeout * HZ, ost_bulk_timeout, desc); -- rc = l_wait_event(desc->bd_waitq, desc->bd_flags & PTL_BULK_FL_RCVD, -- &lwi); -- if (rc) { -- if (rc != -ETIMEDOUT) -- LBUG(); -- GOTO(fail_bulk, rc); -- } -- -- rc = obd_commitrw(cmd, conn, objcount, tmp1, niocount, local_nb, -- desc->bd_desc_private); -- ptlrpc_free_bulk(desc); -- EXIT; --out_free: -- OBD_FREE(local_nb, niocount * sizeof(*local_nb)); --out: -- if (!reply_sent) { -- if (rc) { -- OBD_FREE(req->rq_repmsg, req->rq_replen); -- req->rq_repmsg = NULL; -- ptlrpc_error(req->rq_svc, req); -- } else -- ptlrpc_reply(req->rq_svc, req); -- } -- return rc; -- --fail_bulk: -- ptlrpc_free_bulk(desc); --fail_preprw: -- /* FIXME: how do we undo the preprw? */ -- goto out_free; --} -- --static int ost_handle(struct ptlrpc_request *req) --{ -- int rc; -- ENTRY; -- -- rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); -- if (rc || OBD_FAIL_CHECK(OBD_FAIL_OST_HANDLE_UNPACK)) { -- CERROR("lustre_ost: Invalid request\n"); -- GOTO(out, rc); -- } -- -- if (req->rq_reqmsg->opc != OST_CONNECT && -- req->rq_export == NULL) { -- CERROR("lustre_ost: operation %d on unconnected OST\n", -- req->rq_reqmsg->opc); -- GOTO(out, rc = -ENOTCONN); -- } -- -- if (strcmp(req->rq_obd->obd_type->typ_name, "ost") != 0) -- GOTO(out, rc = -EINVAL); -- -- switch (req->rq_reqmsg->opc) { -- case OST_CONNECT: -- CDEBUG(D_INODE, "connect\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_CONNECT_NET, 0); -- rc = target_handle_connect(req); -- break; -- case OST_DISCONNECT: -- CDEBUG(D_INODE, "disconnect\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_DISCONNECT_NET, 0); -- rc = target_handle_disconnect(req); -- break; -- case OST_CREATE: -- CDEBUG(D_INODE, "create\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_CREATE_NET, 0); -- rc = ost_create(req); -- break; -- case OST_DESTROY: -- CDEBUG(D_INODE, "destroy\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0); -- rc = ost_destroy(req); -- break; -- case OST_GETATTR: -- CDEBUG(D_INODE, "getattr\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_GETATTR_NET, 0); -- rc = ost_getattr(req); -- break; -- case OST_SETATTR: -- CDEBUG(D_INODE, "setattr\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_SETATTR_NET, 0); -- rc = ost_setattr(req); -- break; -- case OST_OPEN: -- CDEBUG(D_INODE, "open\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0); -- rc = ost_open(req); -- break; -- case OST_CLOSE: -- CDEBUG(D_INODE, "close\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0); -- rc = ost_close(req); -- break; -- case OST_WRITE: -- CDEBUG(D_INODE, "write\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); -- rc = ost_brw_write(req); -- /* ost_brw sends its own replies */ -- RETURN(rc); -- case OST_READ: -- CDEBUG(D_INODE, "read\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0); -- rc = ost_brw_read(req); -- /* ost_brw sends its own replies */ -- RETURN(rc); -- case OST_PUNCH: -- CDEBUG(D_INODE, "punch\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_PUNCH_NET, 0); -- rc = ost_punch(req); -- break; -- case OST_STATFS: -- CDEBUG(D_INODE, "statfs\n"); -- OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0); -- rc = ost_statfs(req); -- break; -- case LDLM_ENQUEUE: -- CDEBUG(D_INODE, "enqueue\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0); -- rc = ldlm_handle_enqueue(req); -- break; -- case LDLM_CONVERT: -- CDEBUG(D_INODE, "convert\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_CONVERT, 0); -- rc = ldlm_handle_convert(req); -- break; -- case LDLM_CANCEL: -- CDEBUG(D_INODE, "cancel\n"); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_CANCEL, 0); -- rc = ldlm_handle_cancel(req); -- break; -- case LDLM_BL_CALLBACK: -- case LDLM_CP_CALLBACK: -- CDEBUG(D_INODE, "callback\n"); -- CERROR("callbacks should not happen on OST\n"); -- LBUG(); -- OBD_FAIL_RETURN(OBD_FAIL_LDLM_BL_CALLBACK, 0); -- break; -- default: -- req->rq_status = -ENOTSUPP; -- rc = ptlrpc_error(req->rq_svc, req); -- RETURN(rc); -- } -- -- EXIT; --out: -- //req->rq_status = rc; -- if (rc) { -- CERROR("ost: processing error (opcode=%d): %d\n", -- req->rq_reqmsg->opc, rc); -- ptlrpc_error(req->rq_svc, req); -- } else { -- CDEBUG(D_INODE, "sending reply\n"); -- if (req->rq_repmsg == NULL) -- CERROR("handler for opcode %d returned rc=0 without " -- "creating rq_repmsg; needs to return rc != " -- "0!\n", req->rq_reqmsg->opc); -- ptlrpc_reply(req->rq_svc, req); -- } -- -- return 0; --} -- --/* mount the file system (secretly) */ --static int ost_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- struct obd_ioctl_data* data = buf; -- struct ost_obd *ost = &obddev->u.ost; -- struct obd_device *tgt; -- int err; -- int i; -- ENTRY; -- -- if (data->ioc_inllen1 < 1) { -- CERROR("requires a TARGET OBD UUID\n"); -- RETURN(-EINVAL); -- } -- if (data->ioc_inllen1 > 37) { -- CERROR("OBD UUID must be less than 38 characters\n"); -- RETURN(-EINVAL); -- } -- -- MOD_INC_USE_COUNT; -- tgt = class_uuid2obd(data->ioc_inlbuf1); -- if (!tgt || !(tgt->obd_flags & OBD_ATTACHED) || -- !(tgt->obd_flags & OBD_SET_UP)) { -- CERROR("device not attached or not set up (%d)\n", -- data->ioc_dev); -- GOTO(error_dec, err = -EINVAL); -- } -- -- err = obd_connect(&ost->ost_conn, tgt, NULL, NULL, NULL); -- if (err) { -- CERROR("fail to connect to device %d\n", data->ioc_dev); -- GOTO(error_dec, err = -EINVAL); -- } -- -- ost->ost_service = ptlrpc_init_svc(OST_NEVENTS, OST_NBUFS, -- OST_BUFSIZE, OST_MAXREQSIZE, -- OST_REQUEST_PORTAL, OSC_REPLY_PORTAL, -- "self", ost_handle, "ost"); -- if (!ost->ost_service) { -- CERROR("failed to start service\n"); -- GOTO(error_disc, err = -EINVAL); -- } -- -- for (i = 0; i < OST_NUM_THREADS; i++) { -- char name[32]; -- sprintf(name, "ll_ost_%02d", i); -- err = ptlrpc_start_thread(obddev, ost->ost_service, name); -- if (err) { -- CERROR("error starting thread #%d: rc %d\n", i, err); -- GOTO(error_disc, err = -EINVAL); -- } -- } -- -- RETURN(0); -- --error_disc: -- obd_disconnect(&ost->ost_conn); --error_dec: -- MOD_DEC_USE_COUNT; -- RETURN(err); --} -- --static int ost_cleanup(struct obd_device * obddev) --{ -- struct ost_obd *ost = &obddev->u.ost; -- int err; -- -- ENTRY; -- -- if ( !list_empty(&obddev->obd_exports) ) { -- CERROR("still has clients!\n"); -- RETURN(-EBUSY); -- } -- -- ptlrpc_stop_all_threads(ost->ost_service); -- ptlrpc_unregister_service(ost->ost_service); -- -- err = obd_disconnect(&ost->ost_conn); -- if (err) { -- CERROR("lustre ost: fail to disconnect device\n"); -- RETURN(-EINVAL); -- } -- -- MOD_DEC_USE_COUNT; -- RETURN(0); --} --int ost_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- --int ost_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); -- --} -- -- -- --/* use obd ops to offer management infrastructure */ --static struct obd_ops ost_obd_ops = { -- o_attach: ost_attach, -- o_detach: ost_detach, -- o_setup: ost_setup, -- o_cleanup: ost_cleanup, --}; -- --static int __init ost_init(void) --{ -- int rc; -- -- rc = class_register_type(&ost_obd_ops, status_class_var, -- LUSTRE_OST_NAME); -- RETURN(rc); -- --} -- --static void __exit ost_exit(void) --{ -- -- class_unregister_type(LUSTRE_OST_NAME); --} -- --MODULE_AUTHOR("Cluster File Systems, Inc. "); --MODULE_DESCRIPTION("Lustre Object Storage Target (OST) v0.01"); --MODULE_LICENSE("GPL"); -- --module_init(ost_init); --module_exit(ost_exit); diff --cc lustre/patches/.cvsignore index e530020,e530020..0000000 deleted file mode 100644,100644 --- a/lustre/patches/.cvsignore +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/patches/patch-2.4.18 index 4d7e278,4d7e278..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18 +++ /dev/null @@@ -1,1536 -1,1536 +1,0 @@@ ----- lum-pristine/arch/ia64/mm/init.c Fri Nov 9 17:26:17 2001 --+++ lum/arch/ia64/mm/init.c Thu Aug 1 18:07:35 2002 --@@ -37,6 +37,12 @@ -- -- static unsigned long totalram_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int -- do_check_pgt_cache (int low, int high) -- { ----- lum-pristine/arch/i386/mm/init.c Fri Dec 21 12:41:53 2001 --+++ lum/arch/i386/mm/init.c Thu Aug 1 18:07:35 2002 --@@ -43,6 +43,12 @@ -- static unsigned long totalram_pages; -- static unsigned long totalhigh_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int do_check_pgt_cache(int low, int high) -- { -- int freed = 0; ----- lum-pristine/drivers/block/blkpg.c Mon Feb 25 14:37:57 2002 --+++ lum/drivers/block/blkpg.c Thu Aug 1 18:07:35 2002 --@@ -294,3 +294,38 @@ -- } -- -- EXPORT_SYMBOL(blk_ioctl); --+ --+#define NUM_DEV_NO_WRITE 16 --+static int dev_no_write[NUM_DEV_NO_WRITE]; --+ --+/* --+ * Debug code for turning block devices "read-only" (will discard writes --+ * silently). This is for filesystem crash/recovery testing. --+ */ --+void dev_set_rdonly(kdev_t dev, int no_write) --+{ --+ if (dev) { --+ printk(KERN_WARNING "Turning device %s read-only\n", --+ bdevname(dev)); --+ dev_no_write[no_write] = 0xdead0000 + dev; --+ } --+} --+ --+int dev_check_rdonly(kdev_t dev) { --+ int i; --+ --+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { --+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && --+ dev == (dev_no_write[i] & 0xffff)) --+ return 1; --+ } --+ return 0; --+} --+ --+void dev_clear_rdonly(int no_write) { --+ dev_no_write[no_write] = 0; --+} --+ --+EXPORT_SYMBOL(dev_set_rdonly); --+EXPORT_SYMBOL(dev_check_rdonly); --+EXPORT_SYMBOL(dev_clear_rdonly); ----- lum-pristine/drivers/block/loop.c Fri Dec 21 12:41:53 2001 --+++ lum/drivers/block/loop.c Thu Aug 1 18:07:35 2002 --@@ -471,6 +471,11 @@ -- spin_unlock_irq(&lo->lo_lock); -- -- if (rw == WRITE) { --+#ifdef CONFIG_DEV_RDONLY --+ if (dev_check_rdonly(rbh->b_rdev)) --+ goto err; --+#endif --+ -- if (lo->lo_flags & LO_FLAGS_READ_ONLY) -- goto err; -- } else if (rw == READA) { ----- lum-pristine/drivers/ide/ide-disk.c Fri Dec 21 12:41:54 2001 --+++ lum/drivers/ide/ide-disk.c Thu Aug 1 18:07:35 2002 --@@ -367,6 +367,12 @@ -- */ -- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) -- { --+#ifdef CONFIG_DEV_RDONLY --+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { --+ ide_end_request(1, HWGROUP(drive)); --+ return ide_stopped; --+ } --+#endif -- if (IDE_CONTROL_REG) -- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); -- OUT_BYTE(0x00, IDE_FEATURE_REG); ----- lum-pristine/fs/ext3/Makefile Fri Dec 21 12:41:55 2001 --+++ lum/fs/ext3/Makefile Thu Aug 1 18:07:35 2002 --@@ -9,6 +9,8 @@ -- -- O_TARGET := ext3.o -- --+export-objs := super.o --+ -- obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o -- obj-m := $(O_TARGET) ----- lum-pristine/fs/ext3/super.c Mon Feb 25 14:38:08 2002 --+++ lum/fs/ext3/super.c Thu Aug 1 18:07:35 2002 --@@ -1744,7 +1744,7 @@ -- unregister_filesystem(&ext3_fs_type); -- } -- ---EXPORT_NO_SYMBOLS; --+EXPORT_SYMBOL(ext3_bread); -- -- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ----- lum-pristine/fs/jbd/commit.c Mon Feb 25 14:38:08 2002 --+++ lum/fs/jbd/commit.c Thu Aug 1 18:07:35 2002 --@@ -475,7 +475,7 @@ -- transaction's t_log_list queue, and metadata buffers are on -- the t_iobuf_list queue. -- --- Wait for the transactions in reverse order. That way we are --+ Wait for the buffers in reverse order. That way we are -- less likely to be woken up until all IOs have completed, and -- so we incur less scheduling load. -- */ --@@ -566,8 +566,10 @@ -- -- jbd_debug(3, "JBD: commit phase 6\n"); -- --- if (is_journal_aborted(journal)) --+ if (is_journal_aborted(journal)) { --+ unlock_journal(journal); -- goto skip_commit; --+ } -- -- /* Done it all: now write the commit record. We should have -- * cleaned up our previous buffers by now, so if we are in abort --@@ -577,6 +579,7 @@ -- descriptor = journal_get_descriptor_buffer(journal); -- if (!descriptor) { -- __journal_abort_hard(journal); --+ unlock_journal(journal); -- goto skip_commit; -- } -- --@@ -600,7 +603,6 @@ -- put_bh(bh); /* One for getblk() */ -- journal_unlock_journal_head(descriptor); -- } --- lock_journal(journal); -- -- /* End of a transaction! Finally, we can do checkpoint -- processing: any buffers committed as a result of this --@@ -609,6 +611,25 @@ -- -- skip_commit: -- --+ /* Call any callbacks that had been registered for handles in this --+ * transaction. It is up to the callback to free any allocated --+ * memory. --+ */ --+ if (!list_empty(&commit_transaction->t_jcb)) { --+ struct list_head *p, *n; --+ int error = is_journal_aborted(journal); --+ --+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { --+ struct journal_callback *jcb; --+ --+ jcb = list_entry(p, struct journal_callback, jcb_list); --+ list_del(p); --+ jcb->jcb_func(jcb, error); --+ } --+ } --+ --+ lock_journal(journal); --+ -- jbd_debug(3, "JBD: commit phase 7\n"); -- -- J_ASSERT(commit_transaction->t_sync_datalist == NULL); ----- lum-pristine/fs/jbd/journal.c Mon Feb 25 14:38:08 2002 --+++ lum/fs/jbd/journal.c Thu Aug 1 18:07:35 2002 --@@ -58,6 +58,7 @@ -- #endif -- EXPORT_SYMBOL(journal_flush); -- EXPORT_SYMBOL(journal_revoke); --+EXPORT_SYMBOL(journal_callback_set); -- -- EXPORT_SYMBOL(journal_init_dev); -- EXPORT_SYMBOL(journal_init_inode); ----- lum-pristine/fs/jbd/transaction.c Mon Feb 25 14:38:08 2002 --+++ lum/fs/jbd/transaction.c Thu Aug 1 18:07:35 2002 --@@ -57,6 +57,7 @@ -- transaction->t_state = T_RUNNING; -- transaction->t_tid = journal->j_transaction_sequence++; -- transaction->t_expires = jiffies + journal->j_commit_interval; --+ INIT_LIST_HEAD(&transaction->t_jcb); -- -- /* Set up the commit timer for the new transaction. */ -- J_ASSERT (!journal->j_commit_timer_active); --@@ -201,6 +202,20 @@ -- return 0; -- } -- --+/* Allocate a new handle. This should probably be in a slab... */ --+static handle_t *new_handle(int nblocks) --+{ --+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ if (!handle) --+ return NULL; --+ memset(handle, 0, sizeof (handle_t)); --+ handle->h_buffer_credits = nblocks; --+ handle->h_ref = 1; --+ INIT_LIST_HEAD(&handle->h_jcb); --+ --+ return handle; --+} --+ -- /* -- * Obtain a new handle. -- * --@@ -227,14 +242,11 @@ -- handle->h_ref++; -- return handle; -- } --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = new_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = start_this_handle(journal, handle); --@@ -333,14 +345,11 @@ -- -- if (is_journal_aborted(journal)) -- return ERR_PTR(-EIO); --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = new_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = try_start_this_handle(journal, handle); --@@ -1328,6 +1337,28 @@ -- #endif -- -- /* --+ * Register a callback function for this handle. The function will be --+ * called when the transaction that this handle is part of has been --+ * committed to disk with the original callback data struct and the --+ * error status of the journal as parameters. There is no guarantee of --+ * ordering between handles within a single transaction, nor between --+ * callbacks registered on the same handle. --+ * --+ * The caller is responsible for allocating the journal_callback struct. --+ * This is to allow the caller to add as much extra data to the callback --+ * as needed, but reduce the overhead of multiple allocations. The caller --+ * allocated struct must start with a struct journal_callback at offset 0, --+ * and has the caller-specific data afterwards. --+ */ --+void journal_callback_set(handle_t *handle, --+ void (*func)(struct journal_callback *jcb, int error), --+ struct journal_callback *jcb) --+{ --+ list_add(&jcb->jcb_list, &handle->h_jcb); --+ jcb->jcb_func = func; --+} --+ --+/* -- * All done for a particular handle. -- * -- * There is not much action needed here. We just return any remaining --@@ -1383,7 +1415,10 @@ -- wake_up(&journal->j_wait_transaction_locked); -- } -- --- /* --+ /* Move callbacks from the handle to the transaction. */ --+ list_splice(&handle->h_jcb, &transaction->t_jcb); --+ --+ /* -- * If the handle is marked SYNC, we need to set another commit -- * going! We also want to force a commit if the current -- * transaction is occupying too much of the log, or if the ----- lum-pristine/include/linux/blkdev.h Mon Nov 26 08:29:17 2001 --+++ lum/include/linux/blkdev.h Mon Aug 12 11:48:39 2002 --@@ -228,4 +228,8 @@ -- return retval; -- } -- --+#define CONFIG_DEV_RDONLY --+void dev_set_rdonly(kdev_t, int); --+int dev_check_rdonly(kdev_t); --+void dev_clear_rdonly(int); -- #endif ----- lum-pristine/include/linux/slab.h Fri Dec 21 12:42:04 2001 --+++ lum/include/linux/slab.h Mon Aug 12 11:48:38 2002 --@@ -57,6 +57,7 @@ -- extern int kmem_cache_shrink(kmem_cache_t *); -- extern void *kmem_cache_alloc(kmem_cache_t *, int); -- extern void kmem_cache_free(kmem_cache_t *, void *); --+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); -- -- extern void *kmalloc(size_t, int); -- extern void kfree(const void *); ----- lum-pristine/include/linux/jbd.h Mon Feb 25 14:38:13 2002 --+++ lum/include/linux/jbd.h Mon Aug 12 11:50:09 2002 --@@ -249,6 +249,13 @@ -- return bh->b_private; -- } -- --+#define HAVE_JOURNAL_CALLBACK_STATUS --+struct journal_callback { --+ struct list_head jcb_list; --+ void (*jcb_func)(struct journal_callback *jcb, int error); --+ /* user data goes here */ --+}; --+ -- struct jbd_revoke_table_s; -- -- /* The handle_t type represents a single atomic update being performed --@@ -279,6 +286,12 @@ -- operations */ -- int h_err; -- --+ /* List of application registered callbacks for this handle. --+ * The function(s) will be called after the transaction that --+ * this handle is part of has been committed to disk. --+ */ --+ struct list_head h_jcb; --+ -- /* Flags */ -- unsigned int h_sync: 1; /* sync-on-close */ -- unsigned int h_jdata: 1; /* force data journaling */ --@@ -398,6 +411,10 @@ -- -- /* How many handles used this transaction? */ -- int t_handle_count; --+ --+ /* List of registered callback functions for this transaction. --+ * Called when the transaction is committed. */ --+ struct list_head t_jcb; -- }; -- -- --@@ -646,6 +663,9 @@ -- extern int journal_try_to_free_buffers(journal_t *, struct page *, int); -- extern int journal_stop(handle_t *); -- extern int journal_flush (journal_t *); --+extern void journal_callback_set(handle_t *handle, --+ void (*fn)(struct journal_callback *,int), --+ struct journal_callback *jcb); -- -- extern void journal_lock_updates (journal_t *); -- extern void journal_unlock_updates (journal_t *); ----- lum-pristine/kernel/ksyms.c Mon Feb 25 14:38:13 2002 --+++ lum/kernel/ksyms.c Thu Aug 1 18:07:35 2002 --@@ -271,6 +271,12 @@ -- EXPORT_SYMBOL(lock_may_write); -- EXPORT_SYMBOL(dcache_readdir); -- --+/* lustre */ --+EXPORT_SYMBOL(panic_notifier_list); --+EXPORT_SYMBOL(pagecache_lock); --+EXPORT_SYMBOL(do_kern_mount); --+EXPORT_SYMBOL(kmem_cache_validate); --+ -- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ -- EXPORT_SYMBOL(default_llseek); -- EXPORT_SYMBOL(dentry_open); ----- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001 --+++ lum/include/linux/dcache.h Mon Aug 12 00:02:29 2002 --@@ -6,6 +6,34 @@ -- #include -- #include -- --+#define IT_OPEN (1) --+#define IT_CREAT (1<<1) --+#define IT_MKDIR (1<<2) --+#define IT_LINK (1<<3) --+#define IT_LINK2 (1<<4) --+#define IT_SYMLINK (1<<5) --+#define IT_UNLINK (1<<6) --+#define IT_RMDIR (1<<7) --+#define IT_RENAME (1<<8) --+#define IT_RENAME2 (1<<9) --+#define IT_READDIR (1<<10) --+#define IT_GETATTR (1<<11) --+#define IT_SETATTR (1<<12) --+#define IT_READLINK (1<<13) --+#define IT_MKNOD (1<<14) --+#define IT_LOOKUP (1<<15) --+ --+struct lookup_intent { --+ int it_op; --+ int it_mode; --+ int it_disposition; --+ int it_status; --+ struct iattr *it_iattr; --+ __u64 it_lock_handle[2]; --+ int it_lock_mode; --+ void *it_data; --+}; --+ -- /* -- * linux/include/linux/dcache.h -- * --@@ -78,6 +106,7 @@ -- unsigned long d_time; /* used by d_revalidate */ -- struct dentry_operations *d_op; -- struct super_block * d_sb; /* The root of the dentry tree */ --+ struct lookup_intent *d_it; -- unsigned long d_vfs_flags; -- void * d_fsdata; /* fs-specific data */ -- unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ --@@ -91,6 +119,8 @@ -- int (*d_delete)(struct dentry *); -- void (*d_release)(struct dentry *); -- void (*d_iput)(struct dentry *, struct inode *); --+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); --+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); -- }; -- -- /* the dentry parameter passed to d_hash and d_compare is the parent ----- lum-pristine/include/linux/fs.h Mon Aug 12 11:02:53 2002 --+++ lum/include/linux/fs.h Mon Aug 12 11:48:38 2002 --@@ -536,6 +536,7 @@ -- -- /* needed for tty driver, and maybe others */ -- void *private_data; --+ struct lookup_intent *f_intent; -- -- /* preallocated helper kiobuf to speedup O_DIRECT */ -- struct kiobuf *f_iobuf; --@@ -779,7 +780,9 @@ -- extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -- extern int vfs_rmdir(struct inode *, struct dentry *); -- extern int vfs_unlink(struct inode *, struct dentry *); ---extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); --+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it); -- -- /* -- * File types --@@ -840,6 +843,7 @@ -- struct inode_operations { -- int (*create) (struct inode *,struct dentry *,int); -- struct dentry * (*lookup) (struct inode *,struct dentry *); --+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); -- int (*link) (struct dentry *,struct inode *,struct dentry *); -- int (*unlink) (struct inode *,struct dentry *); -- int (*symlink) (struct inode *,struct dentry *,const char *); --@@ -986,7 +990,7 @@ -- extern struct vfsmount *kern_mount(struct file_system_type *); -- extern int may_umount(struct vfsmount *); -- extern long do_mount(char *, char *, char *, unsigned long, void *); --- --+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data); -- #define kern_umount mntput -- -- extern int vfs_statfs(struct super_block *, struct statfs *); --@@ -1307,6 +1311,7 @@ -- extern loff_t default_llseek(struct file *file, loff_t offset, int origin); -- -- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); --+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); -- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); -- extern int FASTCALL(path_walk(const char *, struct nameidata *)); -- extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); --@@ -1317,6 +1322,8 @@ -- extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -- #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) -- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) --+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) --+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) -- -- extern void iput(struct inode *); -- extern void force_delete(struct inode *); ----- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002 --+++ lum/fs/dcache.c Thu Aug 1 18:07:35 2002 --@@ -617,6 +617,7 @@ -- dentry->d_op = NULL; -- dentry->d_fsdata = NULL; -- dentry->d_mounted = 0; --+ dentry->d_it = NULL; -- INIT_LIST_HEAD(&dentry->d_hash); -- INIT_LIST_HEAD(&dentry->d_lru); -- INIT_LIST_HEAD(&dentry->d_subdirs); ----- lum-pristine/fs/nfsd/vfs.c Fri Dec 21 12:41:55 2001 --+++ lum/fs/nfsd/vfs.c Thu Aug 1 18:07:35 2002 --@@ -1285,7 +1285,7 @@ -- err = nfserr_perm; -- } else -- #endif --- err = vfs_rename(fdir, odentry, tdir, ndentry); --+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); -- if (!err && EX_ISSYNC(tfhp->fh_export)) { -- nfsd_sync_dir(tdentry); -- nfsd_sync_dir(fdentry); ----- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002 --+++ lum/fs/namei.c Mon Aug 12 11:47:56 2002 --@@ -94,6 +94,14 @@ -- * XEmacs seems to be relying on it... -- */ -- --+void intent_release(struct dentry *de, struct lookup_intent *it) --+{ --+ if (de->d_op && de->d_op->d_intent_release) --+ de->d_op->d_intent_release(de, it); --+ de->d_it = NULL; --+} --+ --+ -- /* In order to reduce some races, while at the same time doing additional -- * checking and hopefully speeding things up, we copy filenames to the -- * kernel data space before using them.. --@@ -260,10 +268,19 @@ -- * Internal lookup() using the new generic dcache. -- * SMP-safe -- */ ---static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * dentry = d_lookup(parent, name); -- --+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { --+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && --+ !d_invalidate(dentry)) { --+ dput(dentry); --+ dentry = NULL; --+ } --+ return dentry; --+ } else -- if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { -- if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { -- dput(dentry); --@@ -281,7 +298,8 @@ -- * make sure that nobody added the entry to the dcache in the meantime.. -- * SMP-safe -- */ ---static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * result; -- struct inode *dir = parent->d_inode; --@@ -300,6 +318,9 @@ -- result = ERR_PTR(-ENOMEM); -- if (dentry) { -- lock_kernel(); --+ if (dir->i_op->lookup2) --+ result = dir->i_op->lookup2(dir, dentry, it); --+ else -- result = dir->i_op->lookup(dir, dentry); -- unlock_kernel(); -- if (result) --@@ -321,6 +342,12 @@ -- dput(result); -- result = ERR_PTR(-ENOENT); -- } --+ } else if (result->d_op && result->d_op->d_revalidate2) { --+ if (!result->d_op->d_revalidate2(result, flags, it) && --+ !d_invalidate(result)) { --+ dput(result); --+ result = ERR_PTR(-ENOENT); --+ } -- } -- return result; -- } --@@ -445,7 +472,8 @@ -- * -- * We expect 'base' to be positive and a directory. -- */ ---int link_path_walk(const char * name, struct nameidata *nd) --+int link_path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- struct inode *inode; --@@ -518,9 +546,9 @@ -- break; -- } -- /* This does the actual lookups.. */ --- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- if (!dentry) { --- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -554,7 +582,7 @@ -- nd->dentry = dentry; -- } -- err = -ENOTDIR; --- if (!inode->i_op->lookup) --+ if (!inode->i_op->lookup && !inode->i_op->lookup2) -- break; -- continue; -- /* here ends the main loop */ --@@ -581,9 +609,9 @@ -- if (err < 0) -- break; -- } --- dentry = cached_lookup(nd->dentry, &this, 0); --+ dentry = cached_lookup(nd->dentry, &this, 0, it); -- if (!dentry) { --- dentry = real_lookup(nd->dentry, &this, 0); --+ dentry = real_lookup(nd->dentry, &this, 0, it); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -607,7 +635,8 @@ -- goto no_inode; -- if (lookup_flags & LOOKUP_DIRECTORY) { -- err = -ENOTDIR; --- if (!inode->i_op || !inode->i_op->lookup) --+ if (!inode->i_op || (!inode->i_op->lookup && --+ !inode->i_op->lookup2)) -- break; -- } -- goto return_base; --@@ -630,12 +660,23 @@ -- return err; -- } -- --+int link_path_walk(const char * name, struct nameidata *nd) --+{ --+ return link_path_walk_it(name, nd, NULL); --+} --+ --+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) --+{ --+ current->total_link_count = 0; --+ return link_path_walk_it(name, nd, it); --+} --+ -- int path_walk(const char * name, struct nameidata *nd) -- { -- current->total_link_count = 0; --- return link_path_walk(name, nd); --+ return link_path_walk_it(name, nd, NULL); -- } -- -- /* SMP-safe */ -- /* returns 1 if everything is done */ -- static int __emul_lookup_dentry(const char *name, struct nameidata *nd) --@@ -742,7 +786,8 @@ -- * needs parent already locked. Doesn't follow mounts. -- * SMP-safe. -- */ ---struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, --+ struct lookup_intent *it) -- { -- struct dentry * dentry; -- struct inode *inode; --@@ -765,13 +810,16 @@ -- goto out; -- } -- --- dentry = cached_lookup(base, name, 0); --+ dentry = cached_lookup(base, name, 0, it); -- if (!dentry) { -- struct dentry *new = d_alloc(base, name); -- dentry = ERR_PTR(-ENOMEM); -- if (!new) -- goto out; -- lock_kernel(); --+ if (inode->i_op->lookup2) --+ dentry = inode->i_op->lookup2(inode, new, it); --+ else -- dentry = inode->i_op->lookup(inode, new); -- unlock_kernel(); -- if (!dentry) --@@ -783,6 +831,12 @@ -- return dentry; -- } -- --+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+{ --+ return lookup_hash_it(name, base, NULL); --+} --+ --+ -- /* SMP-safe */ -- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -- { --@@ -804,7 +858,7 @@ -- } -- this.hash = end_name_hash(hash); -- --- return lookup_hash(&this, base); --+ return lookup_hash_it(&this, base, NULL); -- access: -- return ERR_PTR(-EACCES); -- } --@@ -836,6 +890,23 @@ -- return err; -- } -- --+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ char *tmp; --+ int err; --+ --+ tmp = getname(name); --+ err = PTR_ERR(tmp); --+ if (!IS_ERR(tmp)) { --+ err = 0; --+ if (path_init(tmp, flags, nd)) --+ err = path_walk_it(tmp, nd, it); --+ putname(tmp); --+ } --+ return err; --+} --+ -- /* -- * It's inline, so penalty for filesystems that don't use sticky bit is -- * minimal. --@@ -970,7 +1041,8 @@ -- * for symlinks (where the permissions are checked later). -- * SMP-safe -- */ ---int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) --+int open_namei_it(const char *pathname, int flag, int mode, --+ struct nameidata *nd, struct lookup_intent *it) -- { -- int acc_mode, error = 0; -- struct inode *inode; --@@ -985,7 +1057,7 @@ -- */ -- if (!(flag & O_CREAT)) { -- if (path_init(pathname, lookup_flags(flag), nd)) --- error = path_walk(pathname, nd); --+ error = path_walk_it(pathname, nd, it); -- if (error) -- return error; -- dentry = nd->dentry; --@@ -994,6 +1067,10 @@ -- /* -- * Create - we need to know the parent. -- */ --+ if (it) { --+ it->it_mode = mode; --+ it->it_op |= IT_CREAT; --+ } -- if (path_init(pathname, LOOKUP_PARENT, nd)) -- error = path_walk(pathname, nd); -- if (error) --@@ -1011,7 +1089,7 @@ -- -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- -- do_last: -- error = PTR_ERR(dentry); --@@ -1020,6 +1098,7 @@ -- goto exit; -- } -- --+ it->it_mode = mode; -- /* Negative dentry, just create the file */ -- if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, --@@ -1139,8 +1219,10 @@ -- return 0; -- -- exit_dput: --+ intent_release(dentry, it); -- dput(dentry); -- exit: --+ intent_release(nd->dentry, it); -- path_release(nd); -- return error; -- --@@ -1160,6 +1242,8 @@ -- */ -- UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (error) --+ intent_release(dentry, it); -- dput(dentry); -- if (error) -- return error; --@@ -1181,13 +1265,20 @@ -- } -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, NULL); -- putname(nd->last.name); -- goto do_last; -- } -- --+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) --+{ --+ return open_namei_it(pathname, flag, mode, nd, NULL); --+} --+ --+ -- /* SMP-safe */ ---static struct dentry *lookup_create(struct nameidata *nd, int is_dir) --+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- --@@ -1195,7 +1286,7 @@ -- dentry = ERR_PTR(-EEXIST); -- if (nd->last_type != LAST_NORM) -- goto fail; --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- if (IS_ERR(dentry)) -- goto fail; -- if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) --@@ -1241,6 +1332,7 @@ -- char * tmp; -- struct dentry * dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; -- -- if (S_ISDIR(mode)) -- return -EPERM; --@@ -1252,7 +1344,7 @@ -- error = path_walk(tmp, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- -- mode &= ~current->fs->umask; --@@ -1270,6 +1363,7 @@ -- default: -- error = -EINVAL; -- } --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1310,6 +1404,7 @@ -- { -- int error = 0; -- char * tmp; --+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; -- -- tmp = getname(pathname); -- error = PTR_ERR(tmp); --@@ -1321,11 +1416,12 @@ -- error = path_walk(tmp, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 1); --+ dentry = lookup_create(&nd, 1, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_mkdir(nd.dentry->d_inode, dentry, -- mode & ~current->fs->umask); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1407,6 +1504,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_RMDIR }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1429,10 +1527,11 @@ -- goto exit1; -- } -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_rmdir(nd.dentry->d_inode, dentry); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1476,6 +1576,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_UNLINK }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1489,14 +1590,15 @@ -- if (nd.last_type != LAST_NORM) -- goto exit1; -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- /* Why not before? Because we want correct error value */ -- if (nd.last.name[nd.last.len]) -- goto slashes; -- error = vfs_unlink(nd.dentry->d_inode, dentry); -- exit2: --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1543,6 +1646,7 @@ -- int error = 0; -- char * from; -- char * to; --+ struct lookup_intent it = { .it_op = IT_SYMLINK }; -- -- from = getname(oldname); -- if(IS_ERR(from)) --@@ -1557,10 +1661,12 @@ -- error = path_walk(to, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ it.it_data = from; --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_symlink(nd.dentry->d_inode, dentry, from); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1626,6 +1732,7 @@ -- int error; -- char * from; -- char * to; --+ struct lookup_intent it = { .it_op = IT_LINK }; -- -- from = getname(oldname); -- if(IS_ERR(from)) --@@ -1639,7 +1745,7 @@ -- -- error = 0; -- if (path_init(from, LOOKUP_POSITIVE, &old_nd)) --- error = path_walk(from, &old_nd); --+ error = path_walk_it(from, &old_nd, &it); -- if (error) -- goto exit; -- if (path_init(to, LOOKUP_PARENT, &nd)) --@@ -1648,10 +1755,12 @@ -- error = -EXDEV; -- if (old_nd.mnt != nd.mnt) -- goto out_release; --- new_dentry = lookup_create(&nd, 0); --+ it.it_op = IT_LINK2; --+ new_dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(new_dentry); -- if (!IS_ERR(new_dentry)) { -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); --+ intent_release(new_dentry, &it); -- dput(new_dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1694,7 +1803,8 @@ -- * locking]. -- */ -- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- struct inode *target; --@@ -1754,6 +1864,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- if (target) { -- if (!error) -- target->i_flags |= S_DEAD; --@@ -1775,7 +1887,8 @@ -- } -- -- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- --@@ -1806,6 +1919,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- double_up(&old_dir->i_zombie, &new_dir->i_zombie); -- if (error) -- return error; --@@ -1817,13 +1932,14 @@ -- } -- -- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- if (S_ISDIR(old_dentry->d_inode->i_mode)) --- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); -- else --- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); -- if (!error) { -- if (old_dir == new_dir) -- inode_dir_notify(old_dir, DN_RENAME); --@@ -1840,6 +1956,7 @@ -- int error = 0; -- struct dentry * old_dir, * new_dir; -- struct dentry * old_dentry, *new_dentry; --+ struct lookup_intent it = { .it_op = IT_RENAME }; -- struct nameidata oldnd, newnd; -- -- if (path_init(oldname, LOOKUP_PARENT, &oldnd)) --@@ -1868,7 +1985,7 @@ -- -- double_lock(new_dir, old_dir); -- --- old_dentry = lookup_hash(&oldnd.last, old_dir); --+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); -- error = PTR_ERR(old_dentry); -- if (IS_ERR(old_dentry)) -- goto exit3; --@@ -1884,18 +2003,21 @@ -- if (newnd.last.name[newnd.last.len]) -- goto exit4; -- } --- new_dentry = lookup_hash(&newnd.last, new_dir); --+ it.it_op = IT_RENAME2; --+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); -- error = PTR_ERR(new_dentry); -- if (IS_ERR(new_dentry)) -- goto exit4; -- -- lock_kernel(); -- error = vfs_rename(old_dir->d_inode, old_dentry, --- new_dir->d_inode, new_dentry); --+ new_dir->d_inode, new_dentry, &it); -- unlock_kernel(); -- --+ intent_release(new_dentry, &it); -- dput(new_dentry); -- exit4: --+ intent_release(old_dentry, &it); // FIXME: release same intent twice!!! -- dput(old_dentry); -- exit3: -- double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ----- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001 --+++ lum/fs/open.c Sun Aug 11 15:26:29 2002 --@@ -19,6 +19,9 @@ -- #include -- -- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) --+extern int path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it); --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- -- int vfs_statfs(struct super_block *sb, struct statfs *buf) -- { --@@ -94,12 +97,13 @@ -- struct nameidata nd; -- struct inode * inode; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- -- error = -EINVAL; -- if (length < 0) /* sorry, but loff_t says... */ -- goto out; -- --- error = user_path_walk(path, &nd); --+ error = user_path_walk_it(path, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -144,6 +149,7 @@ -- put_write_access(inode); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -235,8 +241,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -262,6 +270,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -279,8 +288,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- -- if (error) -- goto out; --@@ -306,6 +317,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -322,6 +334,7 @@ -- int old_fsuid, old_fsgid; -- kernel_cap_t old_cap; -- int res; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ -- return -EINVAL; --@@ -339,13 +352,14 @@ -- else -- current->cap_effective = current->cap_permitted; -- --- res = user_path_walk(filename, &nd); --+ res = user_path_walk_it(filename, &nd, &it); -- if (!res) { -- res = permission(nd.dentry->d_inode, mode); -- /* SuS v2 requires we report a read only fs too */ -- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) -- && !special_file(nd.dentry->d_inode->i_mode)) -- res = -EROFS; --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- --@@ -361,6 +375,7 @@ -- int error; -- struct nameidata nd; -- char *name; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- name = getname(filename); -- error = PTR_ERR(name); --@@ -369,7 +384,7 @@ -- -- error = 0; -- if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd)) --- error = path_walk(name, &nd); --+ error = path_walk_it(name, &nd, &it); -- putname(name); -- if (error) -- goto out; --@@ -381,6 +397,7 @@ -- set_fs_pwd(current->fs, nd.mnt, nd.dentry); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -421,6 +438,7 @@ -- int error; -- struct nameidata nd; -- char *name; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- name = getname(filename); -- error = PTR_ERR(name); --@@ -429,7 +447,7 @@ -- -- path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); --- error = path_walk(name, &nd); --+ error = path_walk_it(name, &nd, &it); -- putname(name); -- if (error) -- goto out; --@@ -446,6 +465,7 @@ -- set_fs_altroot(); -- error = 0; -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -490,8 +510,9 @@ -- struct inode * inode; -- int error; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -511,6 +532,7 @@ -- error = notify_change(nd.dentry, &newattrs); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -580,10 +602,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -593,10 +618,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -630,10 +658,16 @@ -- * for the internal routines (ie open_namei()/follow_link() etc). 00 is -- * used by symlinks. -- */ --+extern int open_namei_it(const char *filename, int namei_flags, int mode, --+ struct nameidata *nd, struct lookup_intent *it); --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it); --+ -- struct file *filp_open(const char * filename, int flags, int mode) -- { -- int namei_flags, error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_OPEN }; -- -- namei_flags = flags; -- if ((namei_flags+1) & O_ACCMODE) --@@ -641,14 +675,15 @@ -- if (namei_flags & O_TRUNC) -- namei_flags |= 2; -- --- error = open_namei(filename, namei_flags, mode, &nd); --- if (!error) --- return dentry_open(nd.dentry, nd.mnt, flags); --+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); --+ if (error) --+ return ERR_PTR(error); -- --- return ERR_PTR(error); --+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); -- } -- ---struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it) -- { -- struct file * f; -- struct inode *inode; --@@ -691,6 +726,7 @@ -- } -- f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); -- --+ intent_release(dentry, it); -- return f; -- -- cleanup_all: --@@ -705,11 +741,17 @@ -- cleanup_file: -- put_filp(f); -- cleanup_dentry: --+ intent_release(dentry, it); -- dput(dentry); -- mntput(mnt); -- return ERR_PTR(error); -- } -- --+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+{ --+ return dentry_open_it(dentry, mnt, flags, NULL); --+} --+ -- /* -- * Find an empty file descriptor entry, and mark it busy. -- */ ----- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001 --+++ lum/fs/stat.c Mon Aug 12 00:04:39 2002 --@@ -13,6 +13,7 @@ -- -- #include -- --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- /* -- * Revalidate the inode. This is required for proper NFS attribute caching. -- */ --@@ -135,13 +135,15 @@ -- asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) -- { -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- int error; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_old_stat(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -151,13 +153,15 @@ -- asmlinkage long sys_newstat(char * filename, struct stat * statbuf) -- { -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- int error; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_new_stat(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -172,13 +176,15 @@ -- asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) -- { -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- int error; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_old_stat(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -189,13 +195,15 @@ -- asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) -- { -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- int error; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_new_stat(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -247,20 +255,21 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_READLINK }; -- -- if (bufsiz <= 0) -- return -EINVAL; -- --- error = user_path_walk_link(path, &nd); --+ error = user_path_walk_link_it(path, &nd, &it); -- if (!error) { -- struct inode * inode = nd.dentry->d_inode; --- -- error = -EINVAL; -- if (inode->i_op && inode->i_op->readlink && -- !(error = do_revalidate(nd.dentry))) { -- UPDATE_ATIME(inode); -- error = inode->i_op->readlink(nd.dentry, buf, bufsiz); -- } --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -333,12 +342,14 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_new_stat64(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -348,12 +359,14 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = do_revalidate(nd.dentry); -- if (!error) -- error = cp_new_stat64(nd.dentry->d_inode, statbuf); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; ----- lum-pristine/mm/slab.c Fri Dec 21 12:42:05 2001 --+++ lum/mm/slab.c Thu Aug 1 18:07:35 2002 --@@ -1187,6 +1187,59 @@ -- * Called with the cache-lock held. -- */ -- --+extern struct page *check_get_page(unsigned long kaddr); --+struct page *page_mem_map(struct page *page); --+static int kmem_check_cache_obj (kmem_cache_t * cachep, --+ slab_t *slabp, void * objp) --+{ --+ int i; --+ unsigned int objnr; --+ --+#if DEBUG --+ if (cachep->flags & SLAB_RED_ZONE) { --+ objp -= BYTES_PER_WORD; --+ if ( *(unsigned long *)objp != RED_MAGIC2) --+ /* Either write before start, or a double free. */ --+ return 0; --+ if (*(unsigned long *)(objp+cachep->objsize - --+ BYTES_PER_WORD) != RED_MAGIC2) --+ /* Either write past end, or a double free. */ --+ return 0; --+ } --+#endif --+ --+ objnr = (objp-slabp->s_mem)/cachep->objsize; --+ if (objnr >= cachep->num) --+ return 0; --+ if (objp != slabp->s_mem + objnr*cachep->objsize) --+ return 0; --+ --+ /* Check slab's freelist to see if this obj is there. */ --+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { --+ if (i == objnr) --+ return 0; --+ } --+ return 1; --+} --+ --+ --+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) --+{ --+ struct page *page = check_get_page((unsigned long)objp); --+ --+ if (!VALID_PAGE(page)) --+ return 0; --+ --+ if (!PageSlab(page)) --+ return 0; --+ --+ /* XXX check for freed slab objects ? */ --+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) --+ return 0; --+ --+ return (cachep == GET_PAGE_CACHE(page)); --+} --+ -- #if DEBUG -- static int kmem_extra_free_checks (kmem_cache_t * cachep, -- slab_t *slabp, void * objp) diff --cc lustre/patches/patch-2.4.18-14 index 22029f1,e563f7b..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-14 +++ /dev/null @@@ -1,1369 -1,1369 +1,0 @@@ ----- linux-2.4.18-17.8.0-uml-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 - +++ linux-2.4.18-17.8.0-uml/include/linux/lustre_version.h Wed Nov 6 02:34:14 2002 -+++ linux-2.4.18-17.8.0-uml/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 --@@ -0,0 +1 @@ - +#define LUSTRE_KERNEL_VERSION 2 -+#define LUSTRE_KERNEL_VERSION 3 ----- linux-2.4.18-17.8.0-uml-pristine/arch/ia64/mm/init.c 2002-10-19 11:44:08.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/arch/ia64/mm/init.c 2002-10-19 11:44:51.000000000 -0600 --@@ -37,6 +37,12 @@ -- -- static unsigned long totalram_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int -- do_check_pgt_cache (int low, int high) -- { ----- linux-2.4.18-17.8.0-uml-pristine/arch/i386/mm/init.c 2002-10-19 11:44:04.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/arch/i386/mm/init.c 2002-10-19 11:44:51.000000000 -0600 --@@ -43,6 +43,12 @@ -- static unsigned long totalram_pages; -- static unsigned long totalhigh_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int do_check_pgt_cache(int low, int high) -- { -- int freed = 0; ----- linux-2.4.18-17.8.0-uml-pristine/drivers/block/blkpg.c 2002-10-19 11:43:55.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/drivers/block/blkpg.c 2002-10-19 11:44:51.000000000 -0600 --@@ -297,3 +297,38 @@ -- } -- -- EXPORT_SYMBOL(blk_ioctl); --+ --+#define NUM_DEV_NO_WRITE 16 --+static int dev_no_write[NUM_DEV_NO_WRITE]; --+ --+/* --+ * Debug code for turning block devices "read-only" (will discard writes --+ * silently). This is for filesystem crash/recovery testing. --+ */ --+void dev_set_rdonly(kdev_t dev, int no_write) --+{ --+ if (dev) { --+ printk(KERN_WARNING "Turning device %s read-only\n", --+ bdevname(dev)); --+ dev_no_write[no_write] = 0xdead0000 + dev; --+ } --+} --+ --+int dev_check_rdonly(kdev_t dev) { --+ int i; --+ --+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { --+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && --+ dev == (dev_no_write[i] & 0xffff)) --+ return 1; --+ } --+ return 0; --+} --+ --+void dev_clear_rdonly(int no_write) { --+ dev_no_write[no_write] = 0; --+} --+ --+EXPORT_SYMBOL(dev_set_rdonly); --+EXPORT_SYMBOL(dev_check_rdonly); --+EXPORT_SYMBOL(dev_clear_rdonly); ----- linux-2.4.18-17.8.0-uml-pristine/drivers/block/loop.c 2002-10-19 11:43:55.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/drivers/block/loop.c 2002-10-19 11:44:51.000000000 -0600 --@@ -491,6 +491,11 @@ -- spin_unlock_irq(&lo->lo_lock); -- -- if (rw == WRITE) { --+#ifdef CONFIG_DEV_RDONLY --+ if (dev_check_rdonly(rbh->b_rdev)) --+ goto err; --+#endif --+ -- if (lo->lo_flags & LO_FLAGS_READ_ONLY) -- goto err; -- } else if (rw == READA) { ----- linux-2.4.18-17.8.0-uml-pristine/drivers/ide/ide-disk.c 2002-10-19 11:43:58.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/drivers/ide/ide-disk.c 2002-10-19 11:44:51.000000000 -0600 --@@ -557,6 +557,12 @@ -- */ -- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) -- { --+#ifdef CONFIG_DEV_RDONLY --+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { --+ ide_end_request(1, HWGROUP(drive)); --+ return ide_stopped; --+ } --+#endif -- if (IDE_CONTROL_REG) -- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); -- ----- linux-2.4.18-17.8.0-uml-pristine/fs/ext3/Makefile 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/ext3/Makefile 2002-10-19 11:44:51.000000000 -0600 --@@ -9,6 +9,8 @@ -- -- O_TARGET := ext3.o -- --+export-objs := super.o --+ -- obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o -- obj-m := $(O_TARGET) ----- linux-2.4.18-17.8.0-uml-pristine/fs/ext3/super.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/ext3/super.c 2002-10-19 11:44:51.000000000 -0600 --@@ -1746,7 +1746,7 @@ -- unregister_filesystem(&ext3_fs_type); -- } -- ---EXPORT_NO_SYMBOLS; --+EXPORT_SYMBOL(ext3_bread); -- -- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ----- linux-2.4.18-17.8.0-uml-pristine/include/linux/slab.h 2002-10-19 11:43:54.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/include/linux/slab.h 2002-11-02 00:49:24.000000000 -0700 --@@ -57,6 +57,7 @@ -- extern int kmem_cache_shrink(kmem_cache_t *); -- extern void *kmem_cache_alloc(kmem_cache_t *, int); -- extern void kmem_cache_free(kmem_cache_t *, void *); --+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); -- -- extern void *kmalloc(size_t, int); -- extern void kfree(const void *); ----- linux-2.4.18-17.8.0-uml-pristine/kernel/ksyms.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/kernel/ksyms.c 2002-11-02 01:09:34.000000000 -0700 --@@ -292,6 +292,7 @@ -- EXPORT_SYMBOL(set_page_dirty); -- EXPORT_SYMBOL(vfs_readlink); -- EXPORT_SYMBOL(vfs_follow_link); --+EXPORT_SYMBOL(vfs_follow_link_it); -- EXPORT_SYMBOL(page_readlink); -- EXPORT_SYMBOL(page_follow_link); -- EXPORT_SYMBOL(page_symlink_inode_operations); --@@ -306,6 +307,12 @@ -- EXPORT_SYMBOL_GPL(nr_free_pages); -- EXPORT_SYMBOL_GPL(page_cache_size); -- --+/* lustre */ --+EXPORT_SYMBOL(panic_notifier_list); --+EXPORT_SYMBOL(pagecache_lock_cacheline); --+EXPORT_SYMBOL(do_kern_mount); --+EXPORT_SYMBOL(kmem_cache_validate); --+ -- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ -- EXPORT_SYMBOL(default_llseek); -- EXPORT_SYMBOL(dentry_open); ----- linux-2.4.18-17.8.0-uml-pristine/include/linux/dcache.h 2002-10-19 11:43:54.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/include/linux/dcache.h 2002-11-02 00:49:24.000000000 -0700 --@@ -6,6 +6,34 @@ -- #include -- #include -- --+#define IT_OPEN (1) --+#define IT_CREAT (1<<1) --+#define IT_MKDIR (1<<2) --+#define IT_LINK (1<<3) --+#define IT_LINK2 (1<<4) --+#define IT_SYMLINK (1<<5) --+#define IT_UNLINK (1<<6) --+#define IT_RMDIR (1<<7) --+#define IT_RENAME (1<<8) --+#define IT_RENAME2 (1<<9) --+#define IT_READDIR (1<<10) --+#define IT_GETATTR (1<<11) --+#define IT_SETATTR (1<<12) --+#define IT_READLINK (1<<13) --+#define IT_MKNOD (1<<14) --+#define IT_LOOKUP (1<<15) --+ --+struct lookup_intent { --+ int it_op; --+ int it_mode; --+ int it_disposition; --+ int it_status; --+ struct iattr *it_iattr; --+ __u64 it_lock_handle[2]; --+ int it_lock_mode; --+ void *it_data; --+}; --+ -- /* -- * linux/include/linux/dcache.h -- * --@@ -78,6 +106,7 @@ -- unsigned long d_time; /* used by d_revalidate */ -- struct dentry_operations *d_op; -- struct super_block * d_sb; /* The root of the dentry tree */ --+ struct lookup_intent *d_it; -- unsigned long d_vfs_flags; -- void * d_fsdata; /* fs-specific data */ -- void * d_extra_attributes; /* TUX-specific data */ --@@ -91,6 +120,8 @@ -- int (*d_delete)(struct dentry *); -- void (*d_release)(struct dentry *); -- void (*d_iput)(struct dentry *, struct inode *); --+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); --+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); -- }; -- -- /* the dentry parameter passed to d_hash and d_compare is the parent ----- linux-2.4.18-17.8.0-uml-pristine/include/linux/fs.h 2002-10-19 11:43:54.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/include/linux/fs.h 2002-11-02 00:49:24.000000000 -0700 --@@ -576,6 +576,7 @@ -- -- /* needed for tty driver, and maybe others */ -- void *private_data; --+ struct lookup_intent *f_intent; -- -- /* preallocated helper kiobuf to speedup O_DIRECT */ -- struct kiobuf *f_iobuf; --@@ -836,7 +837,9 @@ -- extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -- extern int vfs_rmdir(struct inode *, struct dentry *); -- extern int vfs_unlink(struct inode *, struct dentry *); ---extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); --+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it); -- -- /* -- * File types --@@ -897,6 +900,7 @@ -- struct inode_operations { -- int (*create) (struct inode *,struct dentry *,int); -- struct dentry * (*lookup) (struct inode *,struct dentry *); --+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); -- int (*link) (struct dentry *,struct inode *,struct dentry *); -- int (*unlink) (struct inode *,struct dentry *); -- int (*symlink) (struct inode *,struct dentry *,const char *); --@@ -907,6 +911,8 @@ -- struct inode *, struct dentry *); -- int (*readlink) (struct dentry *, char *,int); -- int (*follow_link) (struct dentry *, struct nameidata *); --+ int (*follow_link2) (struct dentry *, struct nameidata *, --+ struct lookup_intent *it); -- void (*truncate) (struct inode *); -- int (*permission) (struct inode *, int); -- int (*revalidate) (struct dentry *); --@@ -1046,6 +1052,7 @@ -- extern struct vfsmount *kern_mount(struct file_system_type *); -- extern int may_umount(struct vfsmount *); -- extern long do_mount(char *, char *, char *, unsigned long, void *); --+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); -- extern void umount_tree(struct vfsmount *); -- -- #define kern_umount mntput --@@ -1380,6 +1387,7 @@ -- extern loff_t default_llseek(struct file *file, loff_t offset, int origin); -- -- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); --+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); -- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); -- extern int FASTCALL(path_walk(const char *, struct nameidata *)); -- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); --@@ -1391,6 +1399,8 @@ -- extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -- #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) -- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) --+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) --+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) -- -- extern void inode_init_once(struct inode *); -- extern void iput(struct inode *); --@@ -1491,6 +1501,8 @@ -- -- extern int vfs_readlink(struct dentry *, char *, int, const char *); -- extern int vfs_follow_link(struct nameidata *, const char *); --+extern int vfs_follow_link_it(struct nameidata *, const char *, --+ struct lookup_intent *it); -- extern int page_readlink(struct dentry *, char *, int); -- extern int page_follow_link(struct dentry *, struct nameidata *); -- extern struct inode_operations page_symlink_inode_operations; ----- linux-2.4.18-17.8.0-uml-pristine/fs/dcache.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/dcache.c 2002-10-31 13:10:34.000000000 -0700 --@@ -150,6 +150,8 @@ -- unhash_it: -- list_del_init(&dentry->d_hash); -- --+ --+ -- kill_it: { -- struct dentry *parent; -- list_del(&dentry->d_child); --@@ -645,6 +647,7 @@ -- dentry->d_fsdata = NULL; -- dentry->d_extra_attributes = NULL; -- dentry->d_mounted = 0; --+ dentry->d_it = NULL; -- INIT_LIST_HEAD(&dentry->d_hash); -- INIT_LIST_HEAD(&dentry->d_lru); -- INIT_LIST_HEAD(&dentry->d_subdirs); ----- linux-2.4.18-17.8.0-uml-pristine/fs/nfsd/vfs.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/nfsd/vfs.c 2002-10-19 11:44:51.000000000 -0600 --@@ -1298,7 +1298,7 @@ -- err = nfserr_perm; -- } else -- #endif --- err = vfs_rename(fdir, odentry, tdir, ndentry); --+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); -- unlock_kernel(); -- if (!err && EX_ISSYNC(tfhp->fh_export)) { -- nfsd_sync_dir(tdentry); ----- linux-2.4.18-17.8.0-uml-pristine/fs/namei.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/namei.c 2002-11-02 01:02:26.000000000 -0700 --@@ -1,3 +1,6 @@ --+ --+ --+ -- /* -- * linux/fs/namei.c -- * --@@ -94,6 +97,14 @@ -- * XEmacs seems to be relying on it... -- */ -- --+void intent_release(struct dentry *de, struct lookup_intent *it) --+{ --+ if (de->d_op && de->d_op->d_intent_release) --+ de->d_op->d_intent_release(de, it); - + de->d_it = NULL; -+ --+} --+ --+ -- /* In order to reduce some races, while at the same time doing additional -- * checking and hopefully speeding things up, we copy filenames to the -- * kernel data space before using them.. --@@ -260,10 +271,19 @@ -- * Internal lookup() using the new generic dcache. -- * SMP-safe -- */ ---static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * dentry = d_lookup(parent, name); -- --+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { --+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && --+ !d_invalidate(dentry)) { --+ dput(dentry); --+ dentry = NULL; --+ } --+ return dentry; --+ } else -- if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { -- if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { -- dput(dentry); --@@ -281,7 +301,8 @@ -- * make sure that nobody added the entry to the dcache in the meantime.. -- * SMP-safe -- */ ---static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * result; -- struct inode *dir = parent->d_inode; --@@ -300,6 +321,9 @@ -- result = ERR_PTR(-ENOMEM); -- if (dentry) { -- lock_kernel(); --+ if (dir->i_op->lookup2) --+ result = dir->i_op->lookup2(dir, dentry, it); --+ else -- result = dir->i_op->lookup(dir, dentry); -- unlock_kernel(); -- if (result) --@@ -321,6 +345,12 @@ -- dput(result); -- result = ERR_PTR(-ENOENT); -- } --+ } else if (result->d_op && result->d_op->d_revalidate2) { --+ if (!result->d_op->d_revalidate2(result, flags, it) && --+ !d_invalidate(result)) { --+ dput(result); --+ result = ERR_PTR(-ENOENT); --+ } -- } -- return result; -- } --@@ -334,7 +364,8 @@ -- * Without that kind of total limit, nasty chains of consecutive -- * symlinks can cause almost arbitrarily long lookups. -- */ ---static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) --+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, --+ struct lookup_intent *it) -- { -- int err; -- if (current->link_count >= max_recursive_link) --@@ -348,10 +379,14 @@ -- current->link_count++; -- current->total_link_count++; -- UPDATE_ATIME(dentry->d_inode); --- err = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (dentry->d_inode->i_op->follow_link2) --+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); --+ else --+ err = dentry->d_inode->i_op->follow_link(dentry, nd); -- current->link_count--; -- return err; -- loop: --+ intent_release(dentry, it); -- path_release(nd); -- return -ELOOP; -- } --@@ -449,7 +484,8 @@ -- * -- * We expect 'base' to be positive and a directory. -- */ ---int link_path_walk(const char * name, struct nameidata *nd) --+int link_path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- struct inode *inode; --@@ -526,12 +562,12 @@ -- break; -- } -- /* This does the actual lookups.. */ --- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -548,8 +584,8 @@ -- if (!inode->i_op) -- goto out_dput; -- --- if (inode->i_op->follow_link) { --- err = do_follow_link(dentry, nd); --+ if (inode->i_op->follow_link || inode->i_op->follow_link2) { --+ err = do_follow_link(dentry, nd, it); -- dput(dentry); -- if (err) -- goto return_err; --@@ -565,7 +601,7 @@ -- nd->dentry = dentry; -- } -- err = -ENOTDIR; --- if (!inode->i_op->lookup) --+ if (!inode->i_op->lookup && !inode->i_op->lookup2) -- break; -- continue; -- /* here ends the main loop */ --@@ -592,12 +628,12 @@ -- if (err < 0) -- break; -- } --- dentry = cached_lookup(nd->dentry, &this, 0); --+ dentry = cached_lookup(nd->dentry, &this, 0, it); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, 0); --+ dentry = real_lookup(nd->dentry, &this, 0, it); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -606,8 +642,10 @@ -- ; -- inode = dentry->d_inode; -- if ((lookup_flags & LOOKUP_FOLLOW) --- && inode && inode->i_op && inode->i_op->follow_link) { --- err = do_follow_link(dentry, nd); --+ && inode && inode->i_op && --+ (inode->i_op->follow_link || --+ inode->i_op->follow_link2)) { --+ err = do_follow_link(dentry, nd, it); -- dput(dentry); -- if (err) -- goto return_err; --@@ -621,7 +659,8 @@ -- goto no_inode; -- if (lookup_flags & LOOKUP_DIRECTORY) { -- err = -ENOTDIR; --- if (!inode->i_op || !inode->i_op->lookup) --+ if (!inode->i_op || (!inode->i_op->lookup && --+ !inode->i_op->lookup2)) -- break; -- } -- goto return_base; --@@ -663,10 +702,21 @@ -- return err; -- } -- --+int link_path_walk(const char * name, struct nameidata *nd) --+{ --+ return link_path_walk_it(name, nd, NULL); --+} --+ --+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) --+{ --+ current->total_link_count = 0; --+ return link_path_walk_it(name, nd, it); --+} --+ -- int path_walk(const char * name, struct nameidata *nd) -- { -- current->total_link_count = 0; --- return link_path_walk(name, nd); --+ return link_path_walk_it(name, nd, NULL); -- } -- -- /* SMP-safe */ --@@ -751,6 +801,17 @@ -- } -- -- /* SMP-safe */ --+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ int error = 0; --+ if (path_init(path, flags, nd)) --+ error = path_walk_it(path, nd, it); --+ return error; --+} --+ --+ --+/* SMP-safe */ -- int path_lookup(const char *path, unsigned flags, struct nameidata *nd) -- { -- int error = 0; --@@ -779,7 +840,8 @@ -- * needs parent already locked. Doesn't follow mounts. -- * SMP-safe. -- */ ---struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, --+ struct lookup_intent *it) -- { -- struct dentry * dentry; -- struct inode *inode; --@@ -802,13 +864,16 @@ -- goto out; -- } -- --- dentry = cached_lookup(base, name, 0); --+ dentry = cached_lookup(base, name, 0, it); -- if (!dentry) { -- struct dentry *new = d_alloc(base, name); -- dentry = ERR_PTR(-ENOMEM); -- if (!new) -- goto out; -- lock_kernel(); --+ if (inode->i_op->lookup2) --+ dentry = inode->i_op->lookup2(inode, new, it); --+ else -- dentry = inode->i_op->lookup(inode, new); -- unlock_kernel(); -- if (!dentry) --@@ -820,6 +885,12 @@ -- return dentry; -- } -- --+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+{ --+ return lookup_hash_it(name, base, NULL); --+} --+ --+ -- /* SMP-safe */ -- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -- { --@@ -841,7 +912,7 @@ -- } -- this.hash = end_name_hash(hash); -- --- return lookup_hash(&this, base); --+ return lookup_hash_it(&this, base, NULL); -- access: -- return ERR_PTR(-EACCES); -- } --@@ -872,6 +943,23 @@ -- return err; -- } -- --+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ char *tmp; --+ int err; --+ --+ tmp = getname(name); --+ err = PTR_ERR(tmp); --+ if (!IS_ERR(tmp)) { --+ err = 0; --+ if (path_init(tmp, flags, nd)) --+ err = path_walk_it(tmp, nd, it); --+ putname(tmp); --+ } --+ return err; --+} --+ -- /* -- * It's inline, so penalty for filesystems that don't use sticky bit is -- * minimal. --@@ -1010,7 +1098,8 @@ -- * for symlinks (where the permissions are checked later). -- * SMP-safe -- */ ---int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) --+int open_namei_it(const char *pathname, int flag, int mode, --+ struct nameidata *nd, struct lookup_intent *it) -- { -- int acc_mode, error = 0; -- struct inode *inode; --@@ -1024,7 +1113,7 @@ -- * The simplest case - just a plain lookup. -- */ -- if (!(flag & O_CREAT)) { --- error = path_lookup(pathname, lookup_flags(flag), nd); --+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); -- if (error) -- return error; -- dentry = nd->dentry; --@@ -1034,6 +1123,10 @@ -- /* -- * Create - we need to know the parent. -- */ --+ if (it) { --+ it->it_mode = mode; --+ it->it_op |= IT_CREAT; --+ } -- error = path_lookup(pathname, LOOKUP_PARENT, nd); -- if (error) -- return error; --@@ -1049,7 +1142,7 @@ -- -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- -- do_last: -- error = PTR_ERR(dentry); --@@ -1058,6 +1151,7 @@ -- goto exit; -- } -- --+ it->it_mode = mode; -- /* Negative dentry, just create the file */ -- if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, --@@ -1091,7 +1185,8 @@ -- error = -ENOENT; -- if (!dentry->d_inode) -- goto exit_dput; --- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) --+ if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || --+ dentry->d_inode->i_op->follow_link2)) -- goto do_link; -- -- dput(nd->dentry); --@@ -1177,8 +1272,10 @@ -- return 0; -- -- exit_dput: --+ intent_release(dentry, it); -- dput(dentry); -- exit: --+ intent_release(nd->dentry, it); -- path_release(nd); -- return error; -- --@@ -1197,7 +1294,12 @@ -- * are done. Procfs-like symlinks just set LAST_BIND. -- */ -- UPDATE_ATIME(dentry->d_inode); --- error = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (dentry->d_inode->i_op->follow_link2) --+ error = dentry->d_inode->i_op->follow_link2(dentry, nd, it); --+ else --+ error = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (error) --+ intent_release(dentry, it); -- dput(dentry); -- if (error) -- return error; --@@ -1219,13 +1321,20 @@ -- } -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); - + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- putname(nd->last.name); -- goto do_last; -- } -- --+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) --+{ --+ return open_namei_it(pathname, flag, mode, nd, NULL); --+} --+ --+ -- /* SMP-safe */ ---static struct dentry *lookup_create(struct nameidata *nd, int is_dir) --+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- --@@ -1233,7 +1342,7 @@ -- dentry = ERR_PTR(-EEXIST); -- if (nd->last_type != LAST_NORM) -- goto fail; --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- if (IS_ERR(dentry)) -- goto fail; -- if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) --@@ -1279,6 +1388,7 @@ -- char * tmp; -- struct dentry * dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; -- -- if (S_ISDIR(mode)) -- return -EPERM; --@@ -1289,7 +1399,7 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- -- mode &= ~current->fs->umask; --@@ -1307,6 +1417,7 @@ -- default: -- error = -EINVAL; -- } --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1347,6 +1458,7 @@ -- { -- int error = 0; -- char * tmp; --+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; -- -- tmp = getname(pathname); -- error = PTR_ERR(tmp); --@@ -1357,11 +1469,12 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 1); --+ dentry = lookup_create(&nd, 1, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_mkdir(nd.dentry->d_inode, dentry, -- mode & ~current->fs->umask); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1445,6 +1558,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_RMDIR }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1466,10 +1580,11 @@ -- goto exit1; -- } -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_rmdir(nd.dentry->d_inode, dentry); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1513,6 +1628,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_UNLINK }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1525,7 +1641,7 @@ -- if (nd.last_type != LAST_NORM) -- goto exit1; -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- /* Why not before? Because we want correct error value */ --@@ -1533,6 +1649,7 @@ -- goto slashes; -- error = vfs_unlink(nd.dentry->d_inode, dentry); -- exit2: --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1579,6 +1696,7 @@ -- int error = 0; -- char * from; -- char * to; --+ struct lookup_intent it = { .it_op = IT_SYMLINK }; -- -- from = getname(oldname); -- if(IS_ERR(from)) --@@ -1592,10 +1710,12 @@ -- error = path_lookup(to, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ it.it_data = from; --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_symlink(nd.dentry->d_inode, dentry, from); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1660,6 +1780,7 @@ -- { -- int error; -- char * to; --+ struct lookup_intent it = { .it_op = IT_LINK }; -- -- to = getname(newname); -- error = PTR_ERR(to); --@@ -1667,7 +1788,7 @@ -- struct dentry *new_dentry; -- struct nameidata nd, old_nd; -- --- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); --+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it); -- if (error) -- goto exit; -- error = path_lookup(to, LOOKUP_PARENT, &nd); --@@ -1676,10 +1797,12 @@ -- error = -EXDEV; -- if (old_nd.mnt != nd.mnt) -- goto out_release; --- new_dentry = lookup_create(&nd, 0); --+ it.it_op = IT_LINK2; --+ new_dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(new_dentry); -- if (!IS_ERR(new_dentry)) { -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); --+ intent_release(new_dentry, &it); -- dput(new_dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1720,7 +1843,8 @@ -- * locking]. -- */ -- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- struct inode *target; --@@ -1778,6 +1902,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- if (target) { -- if (!error) -- target->i_flags |= S_DEAD; --@@ -1799,7 +1924,8 @@ -- } -- -- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- --@@ -1830,6 +1956,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- double_up(&old_dir->i_zombie, &new_dir->i_zombie); -- if (error) -- return error; --@@ -1841,13 +1968,14 @@ -- } -- -- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- if (S_ISDIR(old_dentry->d_inode->i_mode)) --- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); -- else --- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); -- if (!error) { -- if (old_dir == new_dir) -- inode_dir_notify(old_dir, DN_RENAME); --@@ -1864,6 +1992,7 @@ -- int error = 0; -- struct dentry * old_dir, * new_dir; -- struct dentry * old_dentry, *new_dentry; --+ struct lookup_intent it = { .it_op = IT_RENAME }; -- struct nameidata oldnd, newnd; -- -- error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); --@@ -1889,7 +2018,7 @@ -- -- double_lock(new_dir, old_dir); -- --- old_dentry = lookup_hash(&oldnd.last, old_dir); --+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); -- error = PTR_ERR(old_dentry); -- if (IS_ERR(old_dentry)) -- goto exit3; --@@ -1905,18 +2034,21 @@ -- if (newnd.last.name[newnd.last.len]) -- goto exit4; -- } --- new_dentry = lookup_hash(&newnd.last, new_dir); --+ it.it_op = IT_RENAME2; --+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); -- error = PTR_ERR(new_dentry); -- if (IS_ERR(new_dentry)) -- goto exit4; -- -- lock_kernel(); -- error = vfs_rename(old_dir->d_inode, old_dentry, --- new_dir->d_inode, new_dentry); --+ new_dir->d_inode, new_dentry, &it); -- unlock_kernel(); -- --+ intent_release(new_dentry, NULL); -- dput(new_dentry); -- exit4: --+ intent_release(old_dentry, &it); -- dput(old_dentry); -- exit3: -- double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); --@@ -1965,7 +2097,8 @@ -- } -- -- static inline int ---__vfs_follow_link(struct nameidata *nd, const char *link) --+__vfs_follow_link(struct nameidata *nd, const char *link, --+ struct lookup_intent *it) -- { -- int res = 0; -- char *name; --@@ -1978,7 +2111,7 @@ -- /* weird __emul_prefix() stuff did it */ -- goto out; -- } --- res = link_path_walk(link, nd); --+ res = link_path_walk_it(link, nd, it); -- out: -- if (current->link_count || res || nd->last_type!=LAST_NORM) -- return res; --@@ -2000,7 +2133,13 @@ -- -- int vfs_follow_link(struct nameidata *nd, const char *link) -- { --- return __vfs_follow_link(nd, link); --+ return __vfs_follow_link(nd, link, NULL); --+} --+ --+int vfs_follow_link_it(struct nameidata *nd, const char *link, --+ struct lookup_intent *it) --+{ --+ return __vfs_follow_link(nd, link, it); -- } -- -- /* get the link contents into pagecache */ --@@ -2042,7 +2181,7 @@ -- { -- struct page *page = NULL; -- char *s = page_getlink(dentry, &page); --- int res = __vfs_follow_link(nd, s); --+ int res = __vfs_follow_link(nd, s, NULL); -- if (page) { -- kunmap(page); -- page_cache_release(page); ----- linux-2.4.18-17.8.0-uml-pristine/fs/open.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/open.c 2002-10-19 11:44:51.000000000 -0600 --@@ -19,6 +19,9 @@ -- #include -- -- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) --+extern int path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it); --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- -- int vfs_statfs(struct super_block *sb, struct statfs *buf) -- { --@@ -118,12 +121,13 @@ -- struct nameidata nd; -- struct inode * inode; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- -- error = -EINVAL; -- if (length < 0) /* sorry, but loff_t says... */ -- goto out; -- --- error = user_path_walk(path, &nd); --+ error = user_path_walk_it(path, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -168,6 +172,7 @@ -- put_write_access(inode); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -259,8 +264,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -286,6 +292,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -303,8 +310,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- -- if (error) -- goto out; --@@ -331,6 +339,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -347,6 +356,7 @@ -- int old_fsuid, old_fsgid; -- kernel_cap_t old_cap; -- int res; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ -- return -EINVAL; --@@ -364,13 +374,14 @@ -- else -- current->cap_effective = current->cap_permitted; -- --- res = user_path_walk(filename, &nd); --+ res = user_path_walk_it(filename, &nd, &it); -- if (!res) { -- res = permission(nd.dentry->d_inode, mode); -- /* SuS v2 requires we report a read only fs too */ -- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) -- && !special_file(nd.dentry->d_inode->i_mode)) -- res = -EROFS; --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- --@@ -385,8 +396,11 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); --+ error = __user_walk_it(filename, --+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, --+ &nd, &it); -- if (error) -- goto out; -- --@@ -397,6 +411,7 @@ -- set_fs_pwd(current->fs, nd.mnt, nd.dentry); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -436,9 +451,10 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); --+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); -- if (error) -- goto out; -- --@@ -454,6 +470,7 @@ -- set_fs_altroot(); -- error = 0; -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -498,8 +515,9 @@ -- struct inode * inode; -- int error; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -519,6 +537,7 @@ -- error = notify_change(nd.dentry, &newattrs); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -588,10 +607,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -601,10 +622,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -638,10 +661,16 @@ -- * for the internal routines (ie open_namei()/follow_link() etc). 00 is -- * used by symlinks. -- */ --+extern int open_namei_it(const char *filename, int namei_flags, int mode, --+ struct nameidata *nd, struct lookup_intent *it); --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it); --+ -- struct file *filp_open(const char * filename, int flags, int mode) -- { -- int namei_flags, error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_OPEN }; -- -- namei_flags = flags; -- if ((namei_flags+1) & O_ACCMODE) --@@ -649,18 +678,19 @@ -- if (namei_flags & O_TRUNC) -- namei_flags |= 2; -- --- error = open_namei(filename, namei_flags, mode, &nd); --- if (!error) --- return dentry_open(nd.dentry, nd.mnt, flags); --+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); --+ if (error) --+ return ERR_PTR(error); -- --- return ERR_PTR(error); --+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); -- } -- -- extern ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr); -- /* for files over a certains size it doesn't pay to do readahead on open */ -- #define READAHEAD_CUTOFF 48000 -- ---struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it) -- { -- struct file * f; -- struct inode *inode; --@@ -711,6 +741,7 @@ -- do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT); -- -- --+ intent_release(dentry, it); -- return f; -- -- cleanup_all: --@@ -725,11 +756,17 @@ -- cleanup_file: -- put_filp(f); -- cleanup_dentry: --+ intent_release(dentry, it); -- dput(dentry); -- mntput(mnt); -- return ERR_PTR(error); -- } -- --+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+{ --+ return dentry_open_it(dentry, mnt, flags, NULL); --+} --+ -- /* -- * Find an empty file descriptor entry, and mark it busy. -- */ ----- linux-2.4.18-17.8.0-uml-pristine/fs/stat.c 2002-10-19 11:43:53.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/fs/stat.c 2002-10-19 11:44:51.000000000 -0600 --@@ -13,6 +13,7 @@ -- -- #include -- --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- /* -- * Revalidate the inode. This is required for proper NFS attribute caching. -- */ --@@ -104,10 +105,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk(name, &nd); --+ error = user_path_walk_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -117,10 +120,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk_link(name, &nd); --+ error = user_path_walk_link_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; ----- linux-2.4.18-17.8.0-uml-pristine/mm/slab.c 2002-10-19 11:43:54.000000000 -0600 --+++ linux-2.4.18-17.8.0-uml/mm/slab.c 2002-10-19 11:44:51.000000000 -0600 --@@ -1208,6 +1208,59 @@ -- * Called with the cache-lock held. -- */ -- --+extern struct page *check_get_page(unsigned long kaddr); --+struct page *page_mem_map(struct page *page); --+static int kmem_check_cache_obj (kmem_cache_t * cachep, --+ slab_t *slabp, void * objp) --+{ --+ int i; --+ unsigned int objnr; --+ --+#if DEBUG --+ if (cachep->flags & SLAB_RED_ZONE) { --+ objp -= BYTES_PER_WORD; --+ if ( *(unsigned long *)objp != RED_MAGIC2) --+ /* Either write before start, or a double free. */ --+ return 0; --+ if (*(unsigned long *)(objp+cachep->objsize - --+ BYTES_PER_WORD) != RED_MAGIC2) --+ /* Either write past end, or a double free. */ --+ return 0; --+ } --+#endif --+ --+ objnr = (objp-slabp->s_mem)/cachep->objsize; --+ if (objnr >= cachep->num) --+ return 0; --+ if (objp != slabp->s_mem + objnr*cachep->objsize) --+ return 0; --+ --+ /* Check slab's freelist to see if this obj is there. */ --+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { --+ if (i == objnr) --+ return 0; --+ } --+ return 1; --+} --+ --+ --+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) --+{ --+ struct page *page = check_get_page((unsigned long)objp); --+ --+ if (!VALID_PAGE(page)) --+ return 0; --+ --+ if (!PageSlab(page)) --+ return 0; --+ --+ /* XXX check for freed slab objects ? */ --+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) --+ return 0; --+ --+ return (cachep == GET_PAGE_CACHE(page)); --+} --+ -- #if DEBUG -- static int kmem_extra_free_checks (kmem_cache_t * cachep, -- slab_t *slabp, void * objp) diff --cc lustre/patches/patch-2.4.18-alpha index 59be47e,59be47e..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-alpha +++ /dev/null @@@ -1,16 -1,16 +1,0 @@@ --diff -ruN linux/arch/alpha/mm/init.c linux-2.4.18-lustre/arch/alpha/mm/init.c ----- linux/arch/alpha/mm/init.c Thu Sep 20 21:02:03 2001 --+++ linux-2.4.18-lustre/arch/alpha/mm/init.c Tue Aug 6 12:37:55 2002 --@@ -46,6 +46,12 @@ -- struct pgtable_cache_struct quicklists; -- #endif -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- pgd_t * -- get_pgd_slow(void) -- { diff --cc lustre/patches/patch-2.4.18-chaos12 index 57a6d09,57a6d09..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-chaos12 +++ /dev/null @@@ -1,1521 -1,1521 +1,0 @@@ ----- linux-2.4.18-lustre12-pristine/arch/ia64/mm/init.c Wed Jun 26 00:15:21 2002 --+++ linux-2.4.18-lustre12/arch/ia64/mm/init.c Tue Aug 13 11:13:09 2002 --@@ -37,6 +37,12 @@ -- -- static unsigned long totalram_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int -- do_check_pgt_cache (int low, int high) -- { ----- linux-2.4.18-lustre12-pristine/arch/i386/mm/init.c Wed Jun 26 00:15:21 2002 --+++ linux-2.4.18-lustre12/arch/i386/mm/init.c Tue Aug 13 11:13:09 2002 --@@ -43,6 +43,12 @@ -- static unsigned long totalram_pages; -- static unsigned long totalhigh_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int do_check_pgt_cache(int low, int high) -- { -- int freed = 0; ----- linux-2.4.18-lustre12-pristine/drivers/block/blkpg.c Tue May 7 20:33:10 2002 --+++ linux-2.4.18-lustre12/drivers/block/blkpg.c Tue Aug 13 11:13:08 2002 --@@ -295,3 +295,38 @@ -- } -- -- EXPORT_SYMBOL(blk_ioctl); --+ --+#define NUM_DEV_NO_WRITE 16 --+static int dev_no_write[NUM_DEV_NO_WRITE]; --+ --+/* --+ * Debug code for turning block devices "read-only" (will discard writes --+ * silently). This is for filesystem crash/recovery testing. --+ */ --+void dev_set_rdonly(kdev_t dev, int no_write) --+{ --+ if (dev) { --+ printk(KERN_WARNING "Turning device %s read-only\n", --+ bdevname(dev)); --+ dev_no_write[no_write] = 0xdead0000 + dev; --+ } --+} --+ --+int dev_check_rdonly(kdev_t dev) { --+ int i; --+ --+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { --+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && --+ dev == (dev_no_write[i] & 0xffff)) --+ return 1; --+ } --+ return 0; --+} --+ --+void dev_clear_rdonly(int no_write) { --+ dev_no_write[no_write] = 0; --+} --+ --+EXPORT_SYMBOL(dev_set_rdonly); --+EXPORT_SYMBOL(dev_check_rdonly); --+EXPORT_SYMBOL(dev_clear_rdonly); ----- linux-2.4.18-lustre12-pristine/drivers/block/loop.c Tue May 7 19:48:59 2002 --+++ linux-2.4.18-lustre12/drivers/block/loop.c Tue Aug 13 11:13:08 2002 --@@ -503,6 +503,11 @@ -- spin_unlock_irq(&lo->lo_lock); -- -- if (rw == WRITE) { --+#ifdef CONFIG_DEV_RDONLY --+ if (dev_check_rdonly(rbh->b_rdev)) --+ goto err; --+#endif --+ -- if (lo->lo_flags & LO_FLAGS_READ_ONLY) -- goto err; -- } else if (rw == READA) { ----- linux-2.4.18-lustre12-pristine/drivers/ide/ide-disk.c Tue May 7 18:43:35 2002 --+++ linux-2.4.18-lustre12/drivers/ide/ide-disk.c Tue Aug 13 11:13:08 2002 --@@ -557,6 +557,12 @@ -- */ -- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) -- { --+#ifdef CONFIG_DEV_RDONLY --+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { --+ ide_end_request(1, HWGROUP(drive)); --+ return ide_stopped; --+ } --+#endif -- if (IDE_CONTROL_REG) -- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); -- ----- linux-2.4.18-lustre12-pristine/fs/ext3/Makefile Tue May 7 17:53:46 2002 --+++ linux-2.4.18-lustre12/fs/ext3/Makefile Tue Aug 13 11:13:08 2002 --@@ -9,6 +9,8 @@ -- -- O_TARGET := ext3.o -- --+export-objs := super.o --+ -- obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o -- obj-m := $(O_TARGET) ----- linux-2.4.18-lustre12-pristine/fs/ext3/super.c Tue May 7 19:43:17 2002 --+++ linux-2.4.18-lustre12/fs/ext3/super.c Tue Aug 13 11:13:08 2002 --@@ -1746,7 +1746,7 @@ -- unregister_filesystem(&ext3_fs_type); -- } -- ---EXPORT_NO_SYMBOLS; --+EXPORT_SYMBOL(ext3_bread); -- -- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ----- linux-2.4.18-lustre12-pristine/fs/jbd/commit.c Tue May 7 18:39:35 2002 --+++ linux-2.4.18-lustre12/fs/jbd/commit.c Tue Aug 13 11:13:08 2002 --@@ -482,7 +482,7 @@ -- transaction's t_log_list queue, and metadata buffers are on -- the t_iobuf_list queue. -- --- Wait for the transactions in reverse order. That way we are --+ Wait for the buffers in reverse order. That way we are -- less likely to be woken up until all IOs have completed, and -- so we incur less scheduling load. -- */ --@@ -575,8 +575,10 @@ -- -- jbd_debug(3, "JBD: commit phase 6\n"); -- --- if (is_journal_aborted(journal)) --+ if (is_journal_aborted(journal)) { --+ unlock_journal(journal); -- goto skip_commit; --+ } -- -- /* Done it all: now write the commit record. We should have -- * cleaned up our previous buffers by now, so if we are in abort --@@ -586,9 +588,10 @@ -- descriptor = journal_get_descriptor_buffer(journal); -- if (!descriptor) { -- __journal_abort_hard(journal); --+ unlock_journal(journal); -- goto skip_commit; -- } --- --+ -- /* AKPM: buglet - add `i' to tmp! */ -- for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) { -- journal_header_t *tmp = --@@ -609,7 +612,6 @@ -- put_bh(bh); /* One for getblk() */ -- journal_unlock_journal_head(descriptor); -- } --- lock_journal(journal); -- -- /* End of a transaction! Finally, we can do checkpoint -- processing: any buffers committed as a result of this --@@ -618,6 +620,25 @@ -- -- skip_commit: -- --+ /* Call any callbacks that had been registered for handles in this --+ * transaction. It is up to the callback to free any allocated --+ * memory. --+ */ --+ if (!list_empty(&commit_transaction->t_jcb)) { --+ struct list_head *p, *n; --+ int error = is_journal_aborted(journal); --+ --+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { --+ struct journal_callback *jcb; --+ --+ jcb = list_entry(p, struct journal_callback, jcb_list); --+ list_del(p); --+ jcb->jcb_func(jcb, error); --+ } --+ } --+ --+ lock_journal(journal); --+ -- jbd_debug(3, "JBD: commit phase 7\n"); -- -- J_ASSERT(commit_transaction->t_sync_datalist == NULL); ----- linux-2.4.18-lustre12-pristine/fs/jbd/journal.c Wed Jun 26 00:16:17 2002 --+++ linux-2.4.18-lustre12/fs/jbd/journal.c Tue Aug 13 11:13:08 2002 --@@ -58,6 +58,7 @@ -- #endif -- EXPORT_SYMBOL(journal_flush); -- EXPORT_SYMBOL(journal_revoke); --+EXPORT_SYMBOL(journal_callback_set); -- -- EXPORT_SYMBOL(journal_init_dev); -- EXPORT_SYMBOL(journal_init_inode); ----- linux-2.4.18-lustre12-pristine/fs/jbd/transaction.c Tue Jun 18 15:53:27 2002 --+++ linux-2.4.18-lustre12/fs/jbd/transaction.c Tue Aug 13 11:13:08 2002 --@@ -57,6 +57,7 @@ -- transaction->t_state = T_RUNNING; -- transaction->t_tid = journal->j_transaction_sequence++; -- transaction->t_expires = jiffies + journal->j_commit_interval; --+ INIT_LIST_HEAD(&transaction->t_jcb); -- -- /* Set up the commit timer for the new transaction. */ -- J_ASSERT (!journal->j_commit_timer_active); --@@ -201,6 +202,20 @@ -- return 0; -- } -- --+/* Allocate a new handle. This should probably be in a slab... */ --+static handle_t *get_handle(int nblocks) --+{ --+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ if (!handle) --+ return NULL; --+ memset(handle, 0, sizeof (handle_t)); --+ handle->h_buffer_credits = nblocks; --+ handle->h_ref = 1; --+ INIT_LIST_HEAD(&handle->h_jcb); --+ --+ return handle; --+} --+ -- /* -- * Obtain a new handle. -- * --@@ -227,14 +242,11 @@ -- handle->h_ref++; -- return handle; -- } --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = get_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = start_this_handle(journal, handle); --@@ -333,14 +345,11 @@ -- -- if (is_journal_aborted(journal)) -- return ERR_PTR(-EIO); --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = get_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = try_start_this_handle(journal, handle); --@@ -1319,6 +1328,29 @@ -- #endif -- -- /* --+ * Register a callback function for this handle. The function will be --+ * called when the transaction that this handle is part of has been --+ * committed to disk with the original callback data struct and the --+ * error status of the journal as parameters. There is no guarantee of --+ * ordering between handles within a single transaction, nor between --+ * callbacks registered on the same handle. --+ * --+ * The caller is responsible for allocating the journal_callback struct. --+ * This is to allow the caller to add as much extra data to the callback --+ * as needed, but reduce the overhead of multiple allocations. The caller --+ * allocated struct must start with a struct journal_callback at offset 0, --+ * and has the caller-specific data afterwards. --+ */ --+void journal_callback_set(handle_t *handle, void (*func)(void *, int), --+ void *cb_data) --+{ --+ struct journal_callback *jcb = cb_data; --+ --+ list_add(&jcb->jcb_list, &handle->h_jcb); --+ jcb->jcb_func = func; --+} --+ --+/* -- * All done for a particular handle. -- * -- * There is not much action needed here. We just return any remaining --@@ -1383,7 +1415,10 @@ -- wake_up(&journal->j_wait_transaction_locked); -- } -- --- /* --+ /* Move callbacks from the handle to the transaction. */ --+ list_splice(&handle->h_jcb, &transaction->t_jcb); --+ --+ /* -- * If the handle is marked SYNC, we need to set another commit -- * going! We also want to force a commit if the current -- * transaction is occupying too much of the log, or if the ----- linux-2.4.18-lustre12-pristine/include/linux/blkdev.h Wed Jun 26 00:16:30 2002 --+++ linux-2.4.18-lustre12/include/linux/blkdev.h Tue Aug 13 11:13:08 2002 --@@ -228,4 +228,8 @@ -- return retval; -- } -- --+#define CONFIG_DEV_RDONLY --+void dev_set_rdonly(kdev_t, int); --+int dev_check_rdonly(kdev_t); --+void dev_clear_rdonly(int); -- #endif ----- linux-2.4.18-lustre12-pristine/include/linux/slab.h Wed Jun 26 00:16:34 2002 --+++ linux-2.4.18-lustre12/include/linux/slab.h Tue Aug 13 11:13:09 2002 --@@ -57,6 +57,7 @@ -- extern int kmem_cache_shrink(kmem_cache_t *); -- extern void *kmem_cache_alloc(kmem_cache_t *, int); -- extern void kmem_cache_free(kmem_cache_t *, void *); --+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); -- -- extern void *kmalloc(size_t, int); -- extern void kfree(const void *); ----- linux-2.4.18-lustre12-pristine/include/linux/jbd.h Tue May 7 19:43:17 2002 --+++ linux-2.4.18-lustre12/include/linux/jbd.h Tue Aug 13 11:13:08 2002 --@@ -257,6 +257,13 @@ -- return bh->b_private; -- } -- --+#define HAVE_JOURNAL_CALLBACK_STATUS --+struct journal_callback { --+ struct list_head jcb_list; --+ void (*jcb_func)(void *cb_data, int error); --+ /* user data goes here */ --+}; --+ -- struct jbd_revoke_table_s; -- -- /* The handle_t type represents a single atomic update being performed --@@ -287,6 +294,12 @@ -- operations */ -- int h_err; -- --+ /* List of application registered callbacks for this handle. --+ * The function(s) will be called after the transaction that --+ * this handle is part of has been committed to disk. --+ */ --+ struct list_head h_jcb; --+ -- /* Flags */ -- unsigned int h_sync: 1; /* sync-on-close */ -- unsigned int h_jdata: 1; /* force data journaling */ --@@ -406,6 +419,10 @@ -- -- /* How many handles used this transaction? */ -- int t_handle_count; --+ --+ /* List of registered callback functions for this transaction. --+ * Called when the transaction is committed. */ --+ struct list_head t_jcb; -- }; -- -- --@@ -654,6 +671,8 @@ -- extern int journal_try_to_free_buffers(journal_t *, struct page *, int); -- extern int journal_stop(handle_t *); -- extern int journal_flush (journal_t *); --+extern void journal_callback_set(handle_t *handle, void (*fn)(void *, int), --+ void *cb_data); -- -- extern void journal_lock_updates (journal_t *); -- extern void journal_unlock_updates (journal_t *); ----- linux-2.4.18-lustre12-pristine/kernel/ksyms.c Wed Jun 26 00:16:38 2002 --+++ linux-2.4.18-lustre12/kernel/ksyms.c Tue Aug 13 11:13:08 2002 --@@ -306,6 +306,12 @@ -- EXPORT_SYMBOL(lock_may_write); -- EXPORT_SYMBOL(dcache_readdir); -- --+/* lustre */ --+EXPORT_SYMBOL(panic_notifier_list); --+EXPORT_SYMBOL(pagecache_lock_cacheline); --+EXPORT_SYMBOL(do_kern_mount); --+EXPORT_SYMBOL(kmem_cache_validate); --+ -- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ -- EXPORT_SYMBOL(default_llseek); -- EXPORT_SYMBOL(dentry_open); ----- linux-2.4.18-lustre12-pristine/include/linux/dcache.h Tue May 7 18:22:37 2002 --+++ linux-2.4.18-lustre12/include/linux/dcache.h Tue Aug 13 11:13:09 2002 --@@ -6,6 +6,33 @@ -- #include -- #include -- --+#define IT_OPEN (1) --+#define IT_CREAT (1<<1) --+#define IT_MKDIR (1<<2) --+#define IT_LINK (1<<3) --+#define IT_SYMLINK (1<<4) --+#define IT_UNLINK (1<<5) --+#define IT_RMDIR (1<<6) --+#define IT_RENAME (1<<7) --+#define IT_RENAME2 (1<<8) --+#define IT_READDIR (1<<9) --+#define IT_GETATTR (1<<10) --+#define IT_SETATTR (1<<11) --+#define IT_READLINK (1<<12) --+#define IT_MKNOD (1<<13) --+#define IT_LOOKUP (1<<14) --+ --+struct lookup_intent { --+ int it_op; --+ int it_mode; --+ int it_disposition; --+ int it_status; --+ struct iattr *it_iattr; --+ __u64 it_lock_handle[2]; --+ int it_lock_mode; --+ void *it_data; --+}; --+ -- /* -- * linux/include/linux/dcache.h -- * --@@ -78,6 +105,7 @@ -- unsigned long d_time; /* used by d_revalidate */ -- struct dentry_operations *d_op; -- struct super_block * d_sb; /* The root of the dentry tree */ --+ struct lookup_intent *d_it; -- unsigned long d_vfs_flags; -- void * d_fsdata; /* fs-specific data */ -- void * d_extra_attributes; /* TUX-specific data */ --@@ -91,6 +119,8 @@ -- int (*d_delete)(struct dentry *); -- void (*d_release)(struct dentry *); -- void (*d_iput)(struct dentry *, struct inode *); --+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); --+ void (*d_intent_release)(struct dentry *); -- }; -- -- /* the dentry parameter passed to d_hash and d_compare is the parent ----- linux-2.4.18-lustre12-pristine/include/linux/fs.h Wed Jun 26 00:16:31 2002 --+++ linux-2.4.18-lustre12/include/linux/fs.h Tue Aug 13 11:13:09 2002 --@@ -572,6 +572,7 @@ -- -- /* needed for tty driver, and maybe others */ -- void *private_data; --+ struct lookup_intent *f_intent; -- -- /* preallocated helper kiobuf to speedup O_DIRECT */ -- struct kiobuf *f_iobuf; --@@ -829,7 +830,9 @@ -- extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -- extern int vfs_rmdir(struct inode *, struct dentry *); -- extern int vfs_unlink(struct inode *, struct dentry *); ---extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); --+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it); -- -- /* -- * File types --@@ -890,6 +893,7 @@ -- struct inode_operations { -- int (*create) (struct inode *,struct dentry *,int); -- struct dentry * (*lookup) (struct inode *,struct dentry *); --+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); -- int (*link) (struct dentry *,struct inode *,struct dentry *); -- int (*unlink) (struct inode *,struct dentry *); -- int (*symlink) (struct inode *,struct dentry *,const char *); --@@ -1036,6 +1040,7 @@ -- extern struct vfsmount *kern_mount(struct file_system_type *); -- extern int may_umount(struct vfsmount *); -- extern long do_mount(char *, char *, char *, unsigned long, void *); --+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); -- extern void umount_tree(struct vfsmount *); -- -- #define kern_umount mntput --@@ -1370,6 +1375,7 @@ -- extern loff_t default_llseek(struct file *file, loff_t offset, int origin); -- -- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); --+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); -- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); -- extern int FASTCALL(path_walk(const char *, struct nameidata *)); -- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); --@@ -1381,6 +1387,8 @@ -- extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -- #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) -- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) --+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) --+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) -- -- extern void iput(struct inode *); -- extern void force_delete(struct inode *); ----- linux-2.4.18-lustre12-pristine/fs/dcache.c Wed Jun 26 00:16:14 2002 --+++ linux-2.4.18-lustre12/fs/dcache.c Tue Aug 13 11:13:09 2002 --@@ -645,6 +645,7 @@ -- dentry->d_fsdata = NULL; -- dentry->d_extra_attributes = NULL; -- dentry->d_mounted = 0; --+ dentry->d_it = NULL; -- INIT_LIST_HEAD(&dentry->d_hash); -- INIT_LIST_HEAD(&dentry->d_lru); -- INIT_LIST_HEAD(&dentry->d_subdirs); ----- linux-2.4.18-lustre12-pristine/fs/nfsd/vfs.c Wed Jun 26 00:16:24 2002 --+++ linux-2.4.18-lustre12/fs/nfsd/vfs.c Tue Aug 13 11:13:09 2002 --@@ -1298,7 +1298,7 @@ -- err = nfserr_perm; -- } else -- #endif --- err = vfs_rename(fdir, odentry, tdir, ndentry); --+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); -- unlock_kernel(); -- if (!err && EX_ISSYNC(tfhp->fh_export)) { -- nfsd_sync_dir(tdentry); ----- linux-2.4.18-lustre12-pristine/fs/namei.c Wed Jun 26 00:16:14 2002 --+++ linux-2.4.18-lustre12/fs/namei.c Tue Aug 13 11:18:48 2002 --@@ -94,6 +94,14 @@ -- * XEmacs seems to be relying on it... -- */ -- --+void intent_release(struct dentry *de) --+{ --+ if (de->d_op && de->d_op->d_intent_release) --+ de->d_op->d_intent_release(de); --+ de->d_it = NULL; --+} --+ --+ -- /* In order to reduce some races, while at the same time doing additional -- * checking and hopefully speeding things up, we copy filenames to the -- * kernel data space before using them.. --@@ -260,10 +268,19 @@ -- * Internal lookup() using the new generic dcache. -- * SMP-safe -- */ ---static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * dentry = d_lookup(parent, name); -- --+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { --+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && --+ !d_invalidate(dentry)) { --+ dput(dentry); --+ dentry = NULL; --+ } --+ return dentry; --+ } else -- if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { -- if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { -- dput(dentry); --@@ -281,7 +298,8 @@ -- * make sure that nobody added the entry to the dcache in the meantime.. -- * SMP-safe -- */ ---static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * result; -- struct inode *dir = parent->d_inode; --@@ -300,6 +318,9 @@ -- result = ERR_PTR(-ENOMEM); -- if (dentry) { -- lock_kernel(); --+ if (dir->i_op->lookup2) --+ result = dir->i_op->lookup2(dir, dentry, it); --+ else -- result = dir->i_op->lookup(dir, dentry); -- unlock_kernel(); -- if (result) --@@ -321,6 +342,12 @@ -- dput(result); -- result = ERR_PTR(-ENOENT); -- } --+ } else if (result->d_op && result->d_op->d_revalidate2) { --+ if (!result->d_op->d_revalidate2(result, flags, it) && --+ !d_invalidate(result)) { --+ dput(result); --+ result = ERR_PTR(-ENOENT); --+ } -- } -- return result; -- } --@@ -447,7 +475,8 @@ -- * -- * We expect 'base' to be positive and a directory. -- */ ---int link_path_walk(const char * name, struct nameidata *nd) --+int link_path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- struct inode *inode; --@@ -524,12 +553,12 @@ -- break; -- } -- /* This does the actual lookups.. */ --- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -563,7 +592,7 @@ -- nd->dentry = dentry; -- } -- err = -ENOTDIR; --- if (!inode->i_op->lookup) --+ if (!inode->i_op->lookup && !inode->i_op->lookup2) -- break; -- continue; -- /* here ends the main loop */ --@@ -590,12 +619,12 @@ -- if (err < 0) -- break; -- } --- dentry = cached_lookup(nd->dentry, &this, 0); --+ dentry = cached_lookup(nd->dentry, &this, 0, it); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, 0); --+ dentry = real_lookup(nd->dentry, &this, 0, it); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -619,7 +648,8 @@ -- goto no_inode; -- if (lookup_flags & LOOKUP_DIRECTORY) { -- err = -ENOTDIR; --- if (!inode->i_op || !inode->i_op->lookup) --+ if (!inode->i_op || (!inode->i_op->lookup && --+ !inode->i_op->lookup2)) -- break; -- } -- goto return_base; --@@ -651,6 +681,7 @@ -- } -- } -- return_base: --+ nd->dentry->d_it = it; -- return 0; -- out_dput: -- dput(dentry); --@@ -658,15 +689,29 @@ -- } -- path_release(nd); -- return_err: --+ if (!err) --+ nd->dentry->d_it = it; -- return err; -- } -- --+int link_path_walk(const char * name, struct nameidata *nd) --+{ --+ return link_path_walk_it(name, nd, NULL); --+} --+ --+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) --+{ --+ current->total_link_count = 0; --+ return link_path_walk_it(name, nd, it); --+} --+ -- int path_walk(const char * name, struct nameidata *nd) -- { -- current->total_link_count = 0; --- return link_path_walk(name, nd); --+ return link_path_walk_it(name, nd, NULL); -- } -- --+ -- /* SMP-safe */ -- /* returns 1 if everything is done */ -- static int __emul_lookup_dentry(const char *name, struct nameidata *nd) --@@ -749,6 +794,17 @@ -- } -- -- /* SMP-safe */ --+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ int error = 0; --+ if (path_init(path, flags, nd)) --+ error = path_walk_it(path, nd, it); --+ return error; --+} --+ --+ --+/* SMP-safe */ -- int path_lookup(const char *path, unsigned flags, struct nameidata *nd) -- { -- int error = 0; --@@ -777,7 +833,8 @@ -- * needs parent already locked. Doesn't follow mounts. -- * SMP-safe. -- */ ---struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, --+ struct lookup_intent *it) -- { -- struct dentry * dentry; -- struct inode *inode; --@@ -800,13 +857,16 @@ -- goto out; -- } -- --- dentry = cached_lookup(base, name, 0); --+ dentry = cached_lookup(base, name, 0, it); -- if (!dentry) { -- struct dentry *new = d_alloc(base, name); -- dentry = ERR_PTR(-ENOMEM); -- if (!new) -- goto out; -- lock_kernel(); --+ if (inode->i_op->lookup2) --+ dentry = inode->i_op->lookup2(inode, new, it); --+ else -- dentry = inode->i_op->lookup(inode, new); -- unlock_kernel(); -- if (!dentry) --@@ -818,6 +878,12 @@ -- return dentry; -- } -- --+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+{ --+ return lookup_hash_it(name, base, NULL); --+} --+ --+ -- /* SMP-safe */ -- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -- { --@@ -839,7 +905,7 @@ -- } -- this.hash = end_name_hash(hash); -- --- return lookup_hash(&this, base); --+ return lookup_hash_it(&this, base, NULL); -- access: -- return ERR_PTR(-EACCES); -- } --@@ -870,6 +936,23 @@ -- return err; -- } -- --+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ char *tmp; --+ int err; --+ --+ tmp = getname(name); --+ err = PTR_ERR(tmp); --+ if (!IS_ERR(tmp)) { --+ err = 0; --+ if (path_init(tmp, flags, nd)) --+ err = path_walk_it(tmp, nd, it); --+ putname(tmp); --+ } --+ return err; --+} --+ -- /* -- * It's inline, so penalty for filesystems that don't use sticky bit is -- * minimal. --@@ -1008,7 +1091,8 @@ -- * for symlinks (where the permissions are checked later). -- * SMP-safe -- */ ---int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) --+int open_namei_it(const char *pathname, int flag, int mode, --+ struct nameidata *nd, struct lookup_intent *it) -- { -- int acc_mode, error = 0; -- struct inode *inode; --@@ -1022,16 +1106,21 @@ -- * The simplest case - just a plain lookup. -- */ -- if (!(flag & O_CREAT)) { --- error = path_lookup(pathname, lookup_flags(flag), nd); --+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); -- if (error) -- return error; -- dentry = nd->dentry; --+ dentry->d_it = it; -- goto ok; -- } -- -- /* -- * Create - we need to know the parent. -- */ --+ if (it) { --+ it->it_mode = mode; --+ it->it_op |= IT_CREAT; --+ } -- error = path_lookup(pathname, LOOKUP_PARENT, nd); -- if (error) -- return error; --@@ -1047,7 +1136,7 @@ -- -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- -- do_last: -- error = PTR_ERR(dentry); --@@ -1056,6 +1145,8 @@ -- goto exit; -- } -- --+ dentry->d_it = it; --+ dentry->d_it->it_mode = mode; -- /* Negative dentry, just create the file */ -- if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, --@@ -1175,8 +1266,10 @@ -- return 0; -- -- exit_dput: --+ intent_release(dentry); -- dput(dentry); -- exit: --+ intent_release(nd->dentry); -- path_release(nd); -- return error; -- --@@ -1196,6 +1289,8 @@ -- */ -- UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (error) --+ intent_release(dentry); -- dput(dentry); -- if (error) -- return error; --@@ -1217,13 +1312,20 @@ -- } -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, NULL); -- putname(nd->last.name); -- goto do_last; -- } -- --+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) --+{ --+ return open_namei_it(pathname, flag, mode, nd, NULL); --+} --+ --+ -- /* SMP-safe */ ---static struct dentry *lookup_create(struct nameidata *nd, int is_dir) --+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- --@@ -1231,7 +1333,7 @@ -- dentry = ERR_PTR(-EEXIST); -- if (nd->last_type != LAST_NORM) -- goto fail; --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- if (IS_ERR(dentry)) -- goto fail; -- if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) --@@ -1277,6 +1379,7 @@ -- char * tmp; -- struct dentry * dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; -- -- if (S_ISDIR(mode)) -- return -EPERM; --@@ -1287,11 +1390,12 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- -- mode &= ~current->fs->umask; -- if (!IS_ERR(dentry)) { --+ dentry->d_it = ⁢ -- switch (mode & S_IFMT) { -- case 0: case S_IFREG: -- error = vfs_create(nd.dentry->d_inode,dentry,mode); --@@ -1305,6 +1409,7 @@ -- default: -- error = -EINVAL; -- } --+ intent_release(dentry); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1345,6 +1450,7 @@ -- { -- int error = 0; -- char * tmp; --+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; -- -- tmp = getname(pathname); -- error = PTR_ERR(tmp); --@@ -1355,11 +1461,13 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 1); --+ dentry = lookup_create(&nd, 1, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { --+ dentry->d_it = ⁢ -- error = vfs_mkdir(nd.dentry->d_inode, dentry, -- mode & ~current->fs->umask); --+ intent_release(dentry); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1439,6 +1547,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_RMDIR }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1460,10 +1569,12 @@ -- goto exit1; -- } -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { --+ dentry->d_it = ⁢ -- error = vfs_rmdir(nd.dentry->d_inode, dentry); --+ intent_release(dentry); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1507,6 +1618,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_UNLINK }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1519,14 +1631,16 @@ -- if (nd.last_type != LAST_NORM) -- goto exit1; -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { --+ dentry->d_it = ⁢ -- /* Why not before? Because we want correct error value */ -- if (nd.last.name[nd.last.len]) -- goto slashes; -- error = vfs_unlink(nd.dentry->d_inode, dentry); -- exit2: --+ intent_release(dentry); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1573,6 +1687,7 @@ -- int error = 0; -- char * from; -- char * to; --+ struct lookup_intent it = { .it_op = IT_SYMLINK }; -- -- from = getname(oldname); -- if(IS_ERR(from)) --@@ -1586,10 +1701,13 @@ -- error = path_lookup(to, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ it.it_data = from; --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { --+ dentry->d_it = ⁢ -- error = vfs_symlink(nd.dentry->d_inode, dentry, from); --+ intent_release(dentry); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1654,6 +1771,7 @@ -- { -- int error; -- char * to; --+ struct lookup_intent it = { .it_op = IT_LINK }; -- -- to = getname(newname); -- error = PTR_ERR(to); --@@ -1670,10 +1788,12 @@ -- error = -EXDEV; -- if (old_nd.mnt != nd.mnt) -- goto out_release; --- new_dentry = lookup_create(&nd, 0); --+ new_dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(new_dentry); -- if (!IS_ERR(new_dentry)) { --+ new_dentry->d_it = ⁢ -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); --+ intent_release(new_dentry); -- dput(new_dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1714,7 +1834,8 @@ -- * locking]. -- */ -- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- struct inode *target; --@@ -1768,10 +1889,12 @@ -- } else -- double_down(&old_dir->i_zombie, -- &new_dir->i_zombie); --+ new_dentry->d_it = it; -- if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry); -- if (target) { -- if (!error) -- target->i_flags |= S_DEAD; --@@ -1793,7 +1916,8 @@ -- } -- -- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- --@@ -1820,10 +1944,12 @@ -- DQUOT_INIT(old_dir); -- DQUOT_INIT(new_dir); -- double_down(&old_dir->i_zombie, &new_dir->i_zombie); --+ new_dentry->d_it = it; -- if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry); -- double_up(&old_dir->i_zombie, &new_dir->i_zombie); -- if (error) -- return error; --@@ -1835,13 +1961,14 @@ -- } -- -- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- if (S_ISDIR(old_dentry->d_inode->i_mode)) --- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); -- else --- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); -- if (!error) { -- if (old_dir == new_dir) -- inode_dir_notify(old_dir, DN_RENAME); --@@ -1858,6 +1985,7 @@ -- int error = 0; -- struct dentry * old_dir, * new_dir; -- struct dentry * old_dentry, *new_dentry; --+ struct lookup_intent it = { .it_op = IT_RENAME }; -- struct nameidata oldnd, newnd; -- -- error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); --@@ -1883,7 +2011,7 @@ -- -- double_lock(new_dir, old_dir); -- --- old_dentry = lookup_hash(&oldnd.last, old_dir); --+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); -- error = PTR_ERR(old_dentry); -- if (IS_ERR(old_dentry)) -- goto exit3; --@@ -1899,18 +2027,21 @@ -- if (newnd.last.name[newnd.last.len]) -- goto exit4; -- } --- new_dentry = lookup_hash(&newnd.last, new_dir); --+ it.it_op = IT_RENAME2; --+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); -- error = PTR_ERR(new_dentry); -- if (IS_ERR(new_dentry)) -- goto exit4; -- -- lock_kernel(); -- error = vfs_rename(old_dir->d_inode, old_dentry, --- new_dir->d_inode, new_dentry); --+ new_dir->d_inode, new_dentry, &it); -- unlock_kernel(); -- --+ intent_release(new_dentry); -- dput(new_dentry); -- exit4: --+ intent_release(old_dentry); -- dput(old_dentry); -- exit3: -- double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ----- linux-2.4.18-lustre12-pristine/fs/open.c Wed Jun 26 00:16:14 2002 --+++ linux-2.4.18-lustre12/fs/open.c Tue Aug 13 11:19:36 2002 --@@ -19,6 +19,9 @@ -- #include -- -- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) --+extern int path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it); --+extern void intent_release(struct dentry *de); -- -- int vfs_statfs(struct super_block *sb, struct statfs *buf) -- { --@@ -118,14 +120,16 @@ -- struct nameidata nd; -- struct inode * inode; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- -- error = -EINVAL; -- if (length < 0) /* sorry, but loff_t says... */ -- goto out; -- --- error = user_path_walk(path, &nd); --+ error = user_path_walk_it(path, &nd, &it); -- if (error) -- goto out; --+ nd.dentry->d_it = ⁢ -- inode = nd.dentry->d_inode; -- -- /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ --@@ -168,6 +172,7 @@ -- put_write_access(inode); -- -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -259,10 +264,12 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; --+ nd.dentry->d_it = ⁢ -- inode = nd.dentry->d_inode; -- -- error = -EROFS; --@@ -286,6 +293,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -303,11 +311,13 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- -- if (error) -- goto out; --+ nd.dentry->d_it = ⁢ -- inode = nd.dentry->d_inode; -- -- error = -EROFS; --@@ -330,6 +340,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -346,6 +357,7 @@ -- int old_fsuid, old_fsgid; -- kernel_cap_t old_cap; -- int res; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ -- return -EINVAL; --@@ -363,13 +375,14 @@ -- else -- current->cap_effective = current->cap_permitted; -- --- res = user_path_walk(filename, &nd); --+ res = user_path_walk_it(filename, &nd, &it); -- if (!res) { -- res = permission(nd.dentry->d_inode, mode); -- /* SuS v2 requires we report a read only fs too */ -- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) -- && !special_file(nd.dentry->d_inode->i_mode)) -- res = -EROFS; --+ intent_release(nd.dentry); -- path_release(&nd); -- } -- --@@ -384,11 +397,15 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); --+ error = __user_walk_it(filename, --+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, --+ &nd, &it); -- if (error) -- goto out; -- --+ nd.dentry->d_it = ⁢ -- error = permission(nd.dentry->d_inode,MAY_EXEC); -- if (error) -- goto dput_and_out; --@@ -396,6 +411,7 @@ -- set_fs_pwd(current->fs, nd.mnt, nd.dentry); -- -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -435,12 +451,14 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); --+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); -- if (error) -- goto out; -- --+ nd.dentry->d_it = ⁢ -- error = permission(nd.dentry->d_inode,MAY_EXEC); -- if (error) -- goto dput_and_out; --@@ -453,6 +471,7 @@ -- set_fs_altroot(); -- error = 0; -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -497,12 +516,14 @@ -- struct inode * inode; -- int error; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; -- --+ nd.dentry->d_it = ⁢ -- error = -EROFS; -- if (IS_RDONLY(inode)) -- goto dput_and_out; --@@ -518,6 +539,7 @@ -- error = notify_change(nd.dentry, &newattrs); -- -- dput_and_out: --+ intent_release(nd.dentry); -- path_release(&nd); -- out: -- return error; --@@ -587,10 +609,13 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { --+ nd.dentry->d_it = ⁢ -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry); -- path_release(&nd); -- } -- return error; --@@ -600,10 +625,13 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { --+ nd.dentry->d_it = ⁢ -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry); -- path_release(&nd); -- } -- return error; --@@ -637,10 +665,16 @@ -- * for the internal routines (ie open_namei()/follow_link() etc). 00 is -- * used by symlinks. -- */ --+extern int open_namei_it(const char *filename, int namei_flags, int mode, --+ struct nameidata *nd, struct lookup_intent *it); --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it); --+ -- struct file *filp_open(const char * filename, int flags, int mode) -- { -- int namei_flags, error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_OPEN }; -- -- namei_flags = flags; -- if ((namei_flags+1) & O_ACCMODE) --@@ -648,14 +681,15 @@ -- if (namei_flags & O_TRUNC) -- namei_flags |= 2; -- --- error = open_namei(filename, namei_flags, mode, &nd); --- if (!error) --- return dentry_open(nd.dentry, nd.mnt, flags); --+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); --+ if (error) --+ return ERR_PTR(error); -- --- return ERR_PTR(error); --+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); -- } -- ---struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it) -- { -- struct file * f; -- struct inode *inode; --@@ -698,6 +731,7 @@ -- } -- f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); -- --+ intent_release(dentry); -- return f; -- -- cleanup_all: --@@ -712,11 +746,17 @@ -- cleanup_file: -- put_filp(f); -- cleanup_dentry: --+ intent_release(dentry); -- dput(dentry); -- mntput(mnt); -- return ERR_PTR(error); -- } -- --+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+{ --+ return dentry_open_it(dentry, mnt, flags, NULL); --+} --+ -- /* -- * Find an empty file descriptor entry, and mark it busy. -- */ ----- linux-2.4.18-lustre12-pristine/fs/stat.c Tue May 7 19:40:30 2002 --+++ linux-2.4.18-lustre12/fs/stat.c Tue Aug 13 11:13:09 2002 --@@ -13,6 +13,7 @@ -- -- #include -- --+extern void intent_release(struct dentry *de); -- /* -- * Revalidate the inode. This is required for proper NFS attribute caching. -- */ --@@ -104,10 +106,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk(name, &nd); --+ error = user_path_walk_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry); -- path_release(&nd); -- } -- return error; --@@ -117,10 +121,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk_link(name, &nd); --+ error = user_path_walk_link_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry); -- path_release(&nd); -- } -- return error; ----- linux-2.4.18-lustre12-pristine/mm/slab.c Wed Jun 26 00:16:40 2002 --+++ linux-2.4.18-lustre12/mm/slab.c Tue Aug 13 11:13:09 2002 --@@ -1207,6 +1207,59 @@ -- * Called with the cache-lock held. -- */ -- --+extern struct page *check_get_page(unsigned long kaddr); --+struct page *page_mem_map(struct page *page); --+static int kmem_check_cache_obj (kmem_cache_t * cachep, --+ slab_t *slabp, void * objp) --+{ --+ int i; --+ unsigned int objnr; --+ --+#if DEBUG --+ if (cachep->flags & SLAB_RED_ZONE) { --+ objp -= BYTES_PER_WORD; --+ if ( *(unsigned long *)objp != RED_MAGIC2) --+ /* Either write before start, or a double free. */ --+ return 0; --+ if (*(unsigned long *)(objp+cachep->objsize - --+ BYTES_PER_WORD) != RED_MAGIC2) --+ /* Either write past end, or a double free. */ --+ return 0; --+ } --+#endif --+ --+ objnr = (objp-slabp->s_mem)/cachep->objsize; --+ if (objnr >= cachep->num) --+ return 0; --+ if (objp != slabp->s_mem + objnr*cachep->objsize) --+ return 0; --+ --+ /* Check slab's freelist to see if this obj is there. */ --+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { --+ if (i == objnr) --+ return 0; --+ } --+ return 1; --+} --+ --+ --+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) --+{ --+ struct page *page = check_get_page((unsigned long)objp); --+ --+ if (!VALID_PAGE(page)) --+ return 0; --+ --+ if (!PageSlab(page)) --+ return 0; --+ --+ /* XXX check for freed slab objects ? */ --+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) --+ return 0; --+ --+ return (cachep == GET_PAGE_CACHE(page)); --+} --+ -- #if DEBUG -- static int kmem_extra_free_checks (kmem_cache_t * cachep, -- slab_t *slabp, void * objp) ----- linux-2.4.18-lustre12-pristine/scripts/mkspec Wed Jun 26 00:16:49 2002 --+++ linux-2.4.18-lustre12/scripts/mkspec Tue Aug 13 11:13:09 2002 --@@ -64,6 +64,7 @@ -- fi -- # Back on track, again -- echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" --+echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" -- echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" -- echo "" -- echo "%clean" diff --cc lustre/patches/patch-2.4.18-chaos13 index d193e4d,d193e4d..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-chaos13 +++ /dev/null @@@ -1,12 -1,12 +1,0 @@@ ----- linux-2.4.18-lustre13-3/drivers/qsnet1/qsw/kernel_linux.c Wed Jun 26 15:40:06 2002 --+++ linux-2.4.18-lustre13-4/drivers/qsnet1/qsw/kernel_linux.c Fri Aug 23 08:42:57 2002 --@@ -225,7 +225,8 @@ kmem_to_phys(void *ptr) -- uintptr_t phys, virt = (uintptr_t)ptr; -- pte_t *pte; -- --- if ((((unsigned long) ptr) >= VMALLOC_START && ((unsigned long) ptr) < VMALLOC_END)) --+ if (((((unsigned long) ptr) >= VMALLOC_START && ((unsigned long) ptr) < VMALLOC_END)) || --+ ((((unsigned long) ptr) >= PKMAP_BASE && ((unsigned long) ptr) < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)))) -- { -- pte = find_pte_k(virt); -- ASSERT(pte && !pte_none(*pte)); diff --cc lustre/patches/patch-2.4.18-chaos22 index c40d4ea,c40d4ea..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-chaos22 +++ /dev/null @@@ -1,165 -1,165 +1,0 @@@ --diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c ----- lum-2.4.18-um30/fs/ext3/balloc.c Mon Feb 25 12:38:08 2002 --+++ uml-2.4.18-12.5/fs/ext3/balloc.c Thu Sep 19 13:40:11 2002 --@@ -276,7 +276,8 @@ -- } -- lock_super (sb); -- es = sb->u.ext3_sb.s_es; --- if (block < le32_to_cpu(es->s_first_data_block) || --+ if (block < le32_to_cpu(es->s_first_data_block) || --+ block + count < block || -- (block + count) > le32_to_cpu(es->s_blocks_count)) { -- ext3_error (sb, "ext3_free_blocks", -- "Freeing blocks not in datazone - " --@@ -309,17 +310,6 @@ -- if (!gdp) -- goto error_return; -- --- if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) || --- in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) || --- in_range (block, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group) || --- in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group)) --- ext3_error (sb, "ext3_free_blocks", --- "Freeing blocks in system zones - " --- "Block = %lu, count = %lu", --- block, count); --- -- /* -- * We are about to start releasing blocks in the bitmap, -- * so we need undo access. --@@ -345,14 +335,24 @@ -- if (err) -- goto error_return; -- --- for (i = 0; i < count; i++) { --+ for (i = 0; i < count; i++, block++) { --+ if (block == le32_to_cpu(gdp->bg_block_bitmap) || --+ block == le32_to_cpu(gdp->bg_inode_bitmap) || --+ in_range(block, le32_to_cpu(gdp->bg_inode_table), --+ sb->u.ext2_sb.s_itb_per_group)) { --+ ext3_error(sb, __FUNCTION__, --+ "Freeing block in system zone - block = %lu", --+ block); --+ continue; --+ } --+ -- /* -- * An HJ special. This is expensive... -- */ -- #ifdef CONFIG_JBD_DEBUG -- { -- struct buffer_head *debug_bh; --- debug_bh = sb_get_hash_table(sb, block + i); --+ debug_bh = sb_get_hash_table(sb, block); -- if (debug_bh) { -- BUFFER_TRACE(debug_bh, "Deleted!"); -- if (!bh2jh(bitmap_bh)->b_committed_data) --@@ -365,9 +365,8 @@ -- #endif -- BUFFER_TRACE(bitmap_bh, "clear bit"); -- if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) { --- ext3_error (sb, __FUNCTION__, --- "bit already cleared for block %lu", --- block + i); --+ ext3_error(sb, __FUNCTION__, --+ "bit already cleared for block %lu", block); -- BUFFER_TRACE(bitmap_bh, "bit already cleared"); -- } else { -- dquot_freed_blocks++; --@@ -415,7 +417,6 @@ -- if (!err) err = ret; -- -- if (overflow && !err) { --- block += count; -- count = overflow; -- goto do_more; -- } --@@ -575,6 +577,7 @@ -- -- ext3_debug ("goal=%lu.\n", goal); -- --+repeat: -- /* -- * First, test whether the goal block is free. -- */ --@@ -684,10 +686,21 @@ -- if (tmp == le32_to_cpu(gdp->bg_block_bitmap) || -- tmp == le32_to_cpu(gdp->bg_inode_bitmap) || -- in_range (tmp, le32_to_cpu(gdp->bg_inode_table), --- sb->u.ext3_sb.s_itb_per_group)) --- ext3_error (sb, "ext3_new_block", --- "Allocating block in system zone - " --- "block = %u", tmp); --+ EXT3_SB(sb)->s_itb_per_group)) { --+ ext3_error(sb, __FUNCTION__, --+ "Allocating block in system zone - block = %u", tmp); --+ --+ /* Note: This will potentially use up one of the handle's --+ * buffer credits. Normally we have way too many credits, --+ * so that is OK. In _very_ rare cases it might not be OK. --+ * We will trigger an assertion if we run out of credits, --+ * and we will have to do a full fsck of the filesystem - --+ * better than randomly corrupting filesystem metadata. --+ */ --+ ext3_set_bit(j, bh->b_data); --+ goto repeat; --+ } --+ -- -- /* The superblock lock should guard against anybody else beating -- * us to this point! */ --diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c ----- lum-2.4.18-um30/fs/ext3/namei.c Fri Nov 9 15:25:04 2001 --+++ uml-2.4.18-12.5/fs/ext3/namei.c Thu Sep 19 13:40:11 2002 --@@ -354,8 +355,8 @@ -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; --- ext3_mark_inode_dirty(handle, dir); -- dir->i_version = ++event; --+ ext3_mark_inode_dirty(handle, dir); -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -- brelse(bh); --@@ -464,8 +465,8 @@ -- inode->i_op = &ext3_file_inode_operations; -- inode->i_fop = &ext3_file_operations; -- inode->i_mapping->a_ops = &ext3_aops; --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); -- return err; --@@ -489,8 +490,8 @@ -- err = PTR_ERR(inode); -- if (!IS_ERR(inode)) { -- init_special_inode(inode, mode, rdev); --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- } -- ext3_journal_stop(handle, dir); -- return err; --@@ -933,8 +934,8 @@ -- inode->i_size = l-1; -- } -- inode->u.ext3_i.i_disksize = inode->i_size; --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- out_stop: -- ext3_journal_stop(handle, dir); -- return err; --@@ -970,8 +971,8 @@ -- ext3_inc_count(handle, inode); -- atomic_inc(&inode->i_count); -- --- ext3_mark_inode_dirty(handle, inode); -- err = ext3_add_nondir(handle, dentry, inode); --+ ext3_mark_inode_dirty(handle, inode); -- ext3_journal_stop(handle, dir); -- return err; -- } diff --cc lustre/patches/patch-2.4.18-chaos25 index 6dac001,2d534f5..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-chaos25 +++ /dev/null @@@ -1,1443 -1,1447 +1,0 @@@ ---- linux-2.4.18-17.8.0-uml-pristine/include/linux/lustre_version.h Wed Dec 31 19:00:00 1969 -+++ linux-2.4.18-17.8.0-uml/include/linux/lustre_version.h Tue Nov 26 07:02:14 2002 -@@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 3 ----- kernel-2.4.18-pristine/arch/ia64/mm/init.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/arch/ia64/mm/init.c 2002-10-14 14:08:23.000000000 -0600 --@@ -37,6 +37,12 @@ -- -- static unsigned long totalram_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int -- do_check_pgt_cache (int low, int high) -- { ----- kernel-2.4.18-pristine/arch/i386/mm/init.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/arch/i386/mm/init.c 2002-10-14 14:08:23.000000000 -0600 --@@ -43,6 +43,12 @@ -- static unsigned long totalram_pages; -- static unsigned long totalhigh_pages; -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+#warning FIXME: Lustre team, is this solid? --+ return virt_to_page(kaddr); --+} --+ -- int do_check_pgt_cache(int low, int high) -- { -- int freed = 0; ----- kernel-2.4.18-pristine/drivers/block/blkpg.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/drivers/block/blkpg.c 2002-10-14 14:08:23.000000000 -0600 --@@ -295,3 +295,38 @@ -- } -- -- EXPORT_SYMBOL(blk_ioctl); --+ --+#define NUM_DEV_NO_WRITE 16 --+static int dev_no_write[NUM_DEV_NO_WRITE]; --+ --+/* --+ * Debug code for turning block devices "read-only" (will discard writes --+ * silently). This is for filesystem crash/recovery testing. --+ */ --+void dev_set_rdonly(kdev_t dev, int no_write) --+{ --+ if (dev) { --+ printk(KERN_WARNING "Turning device %s read-only\n", --+ bdevname(dev)); --+ dev_no_write[no_write] = 0xdead0000 + dev; --+ } --+} --+ --+int dev_check_rdonly(kdev_t dev) { --+ int i; --+ --+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { --+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && --+ dev == (dev_no_write[i] & 0xffff)) --+ return 1; --+ } --+ return 0; --+} --+ --+void dev_clear_rdonly(int no_write) { --+ dev_no_write[no_write] = 0; --+} --+ --+EXPORT_SYMBOL(dev_set_rdonly); --+EXPORT_SYMBOL(dev_check_rdonly); --+EXPORT_SYMBOL(dev_clear_rdonly); ----- kernel-2.4.18-pristine/drivers/block/loop.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/drivers/block/loop.c 2002-10-14 14:08:23.000000000 -0600 --@@ -503,6 +503,11 @@ -- spin_unlock_irq(&lo->lo_lock); -- -- if (rw == WRITE) { --+#ifdef CONFIG_DEV_RDONLY --+ if (dev_check_rdonly(rbh->b_rdev)) --+ goto err; --+#endif --+ -- if (lo->lo_flags & LO_FLAGS_READ_ONLY) -- goto err; -- } else if (rw == READA) { ----- kernel-2.4.18-pristine/drivers/ide/ide-disk.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/drivers/ide/ide-disk.c 2002-10-14 14:08:23.000000000 -0600 --@@ -557,6 +557,12 @@ -- */ -- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) -- { --+#ifdef CONFIG_DEV_RDONLY --+ if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) { --+ ide_end_request(1, HWGROUP(drive)); --+ return ide_stopped; --+ } --+#endif -- if (IDE_CONTROL_REG) -- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); -- ----- kernel-2.4.18-pristine/fs/ext3/Makefile 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/fs/ext3/Makefile 2002-10-14 14:08:23.000000000 -0600 --@@ -9,6 +9,8 @@ -- -- O_TARGET := ext3.o -- --+export-objs := super.o --+ -- obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o -- obj-m := $(O_TARGET) ----- kernel-2.4.18-pristine/fs/ext3/super.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/fs/ext3/super.c 2002-10-14 14:08:23.000000000 -0600 --@@ -1746,7 +1746,7 @@ -- unregister_filesystem(&ext3_fs_type); -- } -- ---EXPORT_NO_SYMBOLS; --+EXPORT_SYMBOL(ext3_bread); -- -- MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -- MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ----- kernel-2.4.18-pristine/include/linux/slab.h 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/include/linux/slab.h 2002-10-14 14:08:23.000000000 -0600 --@@ -57,6 +57,7 @@ -- extern int kmem_cache_shrink(kmem_cache_t *); -- extern void *kmem_cache_alloc(kmem_cache_t *, int); -- extern void kmem_cache_free(kmem_cache_t *, void *); --+extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp); -- -- extern void *kmalloc(size_t, int); -- extern void kfree(const void *); ----- kernel-2.4.18-pristine/kernel/ksyms.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/kernel/ksyms.c 2002-10-14 14:08:23.000000000 -0600 --@@ -306,6 +306,12 @@ -- EXPORT_SYMBOL(lock_may_write); -- EXPORT_SYMBOL(dcache_readdir); -- --+/* lustre */ --+EXPORT_SYMBOL(panic_notifier_list); --+EXPORT_SYMBOL(pagecache_lock_cacheline); --+EXPORT_SYMBOL(do_kern_mount); --+EXPORT_SYMBOL(kmem_cache_validate); --+ -- /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ -- EXPORT_SYMBOL(default_llseek); -- EXPORT_SYMBOL(dentry_open); ----- kernel-2.4.18-pristine/include/linux/dcache.h 2002-10-14 13:51:28.000000000 -0600 --+++ kernel-2.4.18/include/linux/dcache.h 2002-10-14 14:08:23.000000000 -0600 --@@ -6,6 +6,34 @@ -- #include -- #include -- --+#define IT_OPEN (1) --+#define IT_CREAT (1<<1) --+#define IT_MKDIR (1<<2) --+#define IT_LINK (1<<3) --+#define IT_LINK2 (1<<4) --+#define IT_SYMLINK (1<<5) --+#define IT_UNLINK (1<<6) --+#define IT_RMDIR (1<<7) --+#define IT_RENAME (1<<8) --+#define IT_RENAME2 (1<<9) --+#define IT_READDIR (1<<10) --+#define IT_GETATTR (1<<11) --+#define IT_SETATTR (1<<12) --+#define IT_READLINK (1<<13) --+#define IT_MKNOD (1<<14) --+#define IT_LOOKUP (1<<15) --+ --+struct lookup_intent { --+ int it_op; --+ int it_mode; --+ int it_disposition; --+ int it_status; --+ struct iattr *it_iattr; --+ __u64 it_lock_handle[2]; --+ int it_lock_mode; --+ void *it_data; --+}; --+ -- /* -- * linux/include/linux/dcache.h -- * --@@ -79,6 +107,7 @@ -- unsigned long d_time; /* used by d_revalidate */ -- struct dentry_operations *d_op; -- struct super_block * d_sb; /* The root of the dentry tree */ --+ struct lookup_intent *d_it; -- unsigned long d_vfs_flags; -- void * d_fsdata; /* fs-specific data */ -- void * d_extra_attributes; /* TUX-specific data */ --@@ -92,6 +121,8 @@ -- int (*d_delete)(struct dentry *); -- void (*d_release)(struct dentry *); -- void (*d_iput)(struct dentry *, struct inode *); --+ int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *); --+ void (*d_intent_release)(struct dentry *, struct lookup_intent *); -- }; -- -- /* the dentry parameter passed to d_hash and d_compare is the parent ----- kernel-2.4.18-pristine/include/linux/fs.h 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/include/linux/fs.h 2002-10-14 14:08:23.000000000 -0600 --@@ -572,6 +572,7 @@ -- -- /* needed for tty driver, and maybe others */ -- void *private_data; --+ struct lookup_intent *f_intent; -- -- /* preallocated helper kiobuf to speedup O_DIRECT */ -- struct kiobuf *f_iobuf; --@@ -829,7 +830,9 @@ -- extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -- extern int vfs_rmdir(struct inode *, struct dentry *); -- extern int vfs_unlink(struct inode *, struct dentry *); ---extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); --+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it); -- -- /* -- * File types --@@ -890,6 +893,7 @@ -- struct inode_operations { -- int (*create) (struct inode *,struct dentry *,int); -- struct dentry * (*lookup) (struct inode *,struct dentry *); --+ struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *); -- int (*link) (struct dentry *,struct inode *,struct dentry *); -- int (*unlink) (struct inode *,struct dentry *); -- int (*symlink) (struct inode *,struct dentry *,const char *); --@@ -1036,6 +1040,7 @@ -- extern struct vfsmount *kern_mount(struct file_system_type *); -- extern int may_umount(struct vfsmount *); -- extern long do_mount(char *, char *, char *, unsigned long, void *); --+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); -- extern void umount_tree(struct vfsmount *); -- -- #define kern_umount mntput --@@ -1370,6 +1375,7 @@ -- extern loff_t default_llseek(struct file *file, loff_t offset, int origin); -- -- extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); --+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); -- extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); -- extern int FASTCALL(path_walk(const char *, struct nameidata *)); -- extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); --@@ -1381,6 +1387,8 @@ -- extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -- #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) -- #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) --+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) --+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) -- -- extern void iput(struct inode *); -- extern void force_delete(struct inode *); ----- kernel-2.4.18-pristine/fs/dcache.c 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/fs/dcache.c 2002-10-14 14:08:23.000000000 -0600 --@@ -645,6 +645,7 @@ -- dentry->d_fsdata = NULL; -- dentry->d_extra_attributes = NULL; -- dentry->d_mounted = 0; --+ dentry->d_it = NULL; -- INIT_LIST_HEAD(&dentry->d_hash); -- INIT_LIST_HEAD(&dentry->d_lru); -- INIT_LIST_HEAD(&dentry->d_subdirs); ----- kernel-2.4.18-pristine/fs/nfsd/vfs.c 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/fs/nfsd/vfs.c 2002-10-14 14:08:23.000000000 -0600 --@@ -1298,7 +1298,7 @@ -- err = nfserr_perm; -- } else -- #endif --- err = vfs_rename(fdir, odentry, tdir, ndentry); --+ err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); -- unlock_kernel(); -- if (!err && EX_ISSYNC(tfhp->fh_export)) { -- nfsd_sync_dir(tdentry); ----- kernel-2.4.18-pristine/fs/namei.c 2002-10-14 13:56:44.000000000 -0600 --+++ kernel-2.4.18/fs/namei.c 2002-10-14 14:08:23.000000000 -0600 --@@ -94,6 +94,14 @@ -- * XEmacs seems to be relying on it... -- */ -- --+void intent_release(struct dentry *de, struct lookup_intent *it) --+{ --+ if (de->d_op && de->d_op->d_intent_release) --+ de->d_op->d_intent_release(de, it); - + de->d_it = NULL; -+ --+} --+ --+ -- /* In order to reduce some races, while at the same time doing additional -- * checking and hopefully speeding things up, we copy filenames to the -- * kernel data space before using them.. --@@ -260,10 +268,19 @@ -- * Internal lookup() using the new generic dcache. -- * SMP-safe -- */ ---static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * dentry = d_lookup(parent, name); -- --+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) { --+ if (!dentry->d_op->d_revalidate2(dentry, flags, it) && --+ !d_invalidate(dentry)) { --+ dput(dentry); --+ dentry = NULL; --+ } --+ return dentry; --+ } else -- if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { -- if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { -- dput(dentry); --@@ -281,7 +298,8 @@ -- * make sure that nobody added the entry to the dcache in the meantime.. -- * SMP-safe -- */ ---static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) --+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, --+ int flags, struct lookup_intent *it) -- { -- struct dentry * result; -- struct inode *dir = parent->d_inode; --@@ -300,6 +318,9 @@ -- result = ERR_PTR(-ENOMEM); -- if (dentry) { -- lock_kernel(); --+ if (dir->i_op->lookup2) --+ result = dir->i_op->lookup2(dir, dentry, it); --+ else -- result = dir->i_op->lookup(dir, dentry); -- unlock_kernel(); -- if (result) --@@ -321,6 +342,12 @@ -- dput(result); -- result = ERR_PTR(-ENOENT); -- } --+ } else if (result->d_op && result->d_op->d_revalidate2) { --+ if (!result->d_op->d_revalidate2(result, flags, it) && --+ !d_invalidate(result)) { --+ dput(result); --+ result = ERR_PTR(-ENOENT); --+ } -- } -- return result; -- } --@@ -447,7 +474,8 @@ -- * -- * We expect 'base' to be positive and a directory. -- */ ---int link_path_walk(const char * name, struct nameidata *nd) --+int link_path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- struct inode *inode; --@@ -524,12 +552,12 @@ -- break; -- } -- /* This does the actual lookups.. */ --- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); --+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -563,7 +591,7 @@ -- nd->dentry = dentry; -- } -- err = -ENOTDIR; --- if (!inode->i_op->lookup) --+ if (!inode->i_op->lookup && !inode->i_op->lookup2) -- break; -- continue; -- /* here ends the main loop */ --@@ -590,12 +618,12 @@ -- if (err < 0) -- break; -- } --- dentry = cached_lookup(nd->dentry, &this, 0); --+ dentry = cached_lookup(nd->dentry, &this, 0, it); -- if (!dentry) { -- err = -EWOULDBLOCKIO; -- if (atomic) -- break; --- dentry = real_lookup(nd->dentry, &this, 0); --+ dentry = real_lookup(nd->dentry, &this, 0, it); -- err = PTR_ERR(dentry); -- if (IS_ERR(dentry)) -- break; --@@ -619,7 +647,8 @@ -- goto no_inode; -- if (lookup_flags & LOOKUP_DIRECTORY) { -- err = -ENOTDIR; --- if (!inode->i_op || !inode->i_op->lookup) --+ if (!inode->i_op || (!inode->i_op->lookup && --+ !inode->i_op->lookup2)) -- break; -- } -- goto return_base; --@@ -661,10 +690,21 @@ -- return err; -- } -- --+int link_path_walk(const char * name, struct nameidata *nd) --+{ --+ return link_path_walk_it(name, nd, NULL); --+} --+ --+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) --+{ --+ current->total_link_count = 0; --+ return link_path_walk_it(name, nd, it); --+} --+ -- int path_walk(const char * name, struct nameidata *nd) -- { -- current->total_link_count = 0; --- return link_path_walk(name, nd); --+ return link_path_walk_it(name, nd, NULL); -- } -- -- /* SMP-safe */ --@@ -749,6 +789,17 @@ -- } -- -- /* SMP-safe */ --+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ int error = 0; --+ if (path_init(path, flags, nd)) --+ error = path_walk_it(path, nd, it); --+ return error; --+} --+ --+ --+/* SMP-safe */ -- int path_lookup(const char *path, unsigned flags, struct nameidata *nd) -- { -- int error = 0; --@@ -777,7 +828,8 @@ -- * needs parent already locked. Doesn't follow mounts. -- * SMP-safe. -- */ ---struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, --+ struct lookup_intent *it) -- { -- struct dentry * dentry; -- struct inode *inode; --@@ -800,13 +852,16 @@ -- goto out; -- } -- --- dentry = cached_lookup(base, name, 0); --+ dentry = cached_lookup(base, name, 0, it); -- if (!dentry) { -- struct dentry *new = d_alloc(base, name); -- dentry = ERR_PTR(-ENOMEM); -- if (!new) -- goto out; -- lock_kernel(); --+ if (inode->i_op->lookup2) --+ dentry = inode->i_op->lookup2(inode, new, it); --+ else -- dentry = inode->i_op->lookup(inode, new); -- unlock_kernel(); -- if (!dentry) --@@ -818,6 +873,12 @@ -- return dentry; -- } -- --+struct dentry * lookup_hash(struct qstr *name, struct dentry * base) --+{ --+ return lookup_hash_it(name, base, NULL); --+} --+ --+ -- /* SMP-safe */ -- struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -- { --@@ -839,7 +900,7 @@ -- } -- this.hash = end_name_hash(hash); -- --- return lookup_hash(&this, base); --+ return lookup_hash_it(&this, base, NULL); -- access: -- return ERR_PTR(-EACCES); -- } --@@ -870,6 +931,23 @@ -- return err; -- } -- --+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, --+ struct lookup_intent *it) --+{ --+ char *tmp; --+ int err; --+ --+ tmp = getname(name); --+ err = PTR_ERR(tmp); --+ if (!IS_ERR(tmp)) { --+ err = 0; --+ if (path_init(tmp, flags, nd)) --+ err = path_walk_it(tmp, nd, it); --+ putname(tmp); --+ } --+ return err; --+} --+ -- /* -- * It's inline, so penalty for filesystems that don't use sticky bit is -- * minimal. --@@ -1008,7 +1086,8 @@ -- * for symlinks (where the permissions are checked later). -- * SMP-safe -- */ ---int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) --+int open_namei_it(const char *pathname, int flag, int mode, --+ struct nameidata *nd, struct lookup_intent *it) -- { -- int acc_mode, error = 0; -- struct inode *inode; --@@ -1022,7 +1101,7 @@ -- * The simplest case - just a plain lookup. -- */ -- if (!(flag & O_CREAT)) { --- error = path_lookup(pathname, lookup_flags(flag), nd); --+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); -- if (error) -- return error; -- dentry = nd->dentry; --@@ -1032,6 +1111,10 @@ -- /* -- * Create - we need to know the parent. -- */ --+ if (it) { --+ it->it_mode = mode; --+ it->it_op |= IT_CREAT; --+ } -- error = path_lookup(pathname, LOOKUP_PARENT, nd); -- if (error) -- return error; --@@ -1047,7 +1130,7 @@ -- -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- -- do_last: -- error = PTR_ERR(dentry); --@@ -1056,6 +1139,7 @@ -- goto exit; -- } -- --+ it->it_mode = mode; -- /* Negative dentry, just create the file */ -- if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, --@@ -1175,8 +1259,10 @@ -- return 0; -- -- exit_dput: --+ intent_release(dentry, it); -- dput(dentry); -- exit: --+ intent_release(nd->dentry, it); -- path_release(nd); -- return error; -- --@@ -1196,6 +1282,8 @@ -- */ -- UPDATE_ATIME(dentry->d_inode); -- error = dentry->d_inode->i_op->follow_link(dentry, nd); --+ if (error) --+ intent_release(dentry, it); -- dput(dentry); -- if (error) -- return error; --@@ -1217,13 +1305,20 @@ -- } -- dir = nd->dentry; -- down(&dir->d_inode->i_sem); --- dentry = lookup_hash(&nd->last, nd->dentry); - + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- putname(nd->last.name); -- goto do_last; -- } -- --+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) --+{ --+ return open_namei_it(pathname, flag, mode, nd, NULL); --+} --+ --+ -- /* SMP-safe */ ---static struct dentry *lookup_create(struct nameidata *nd, int is_dir) --+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, --+ struct lookup_intent *it) -- { -- struct dentry *dentry; -- --@@ -1231,7 +1326,7 @@ -- dentry = ERR_PTR(-EEXIST); -- if (nd->last_type != LAST_NORM) -- goto fail; --- dentry = lookup_hash(&nd->last, nd->dentry); --+ dentry = lookup_hash_it(&nd->last, nd->dentry, it); -- if (IS_ERR(dentry)) -- goto fail; -- if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) --@@ -1277,6 +1372,7 @@ -- char * tmp; -- struct dentry * dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode }; -- -- if (S_ISDIR(mode)) -- return -EPERM; --@@ -1287,7 +1383,7 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- -- mode &= ~current->fs->umask; --@@ -1305,6 +1401,7 @@ -- default: -- error = -EINVAL; -- } --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1345,6 +1442,7 @@ -- { -- int error = 0; -- char * tmp; --+ struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode }; -- -- tmp = getname(pathname); -- error = PTR_ERR(tmp); --@@ -1355,11 +1453,12 @@ -- error = path_lookup(tmp, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 1); --+ dentry = lookup_create(&nd, 1, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_mkdir(nd.dentry->d_inode, dentry, -- mode & ~current->fs->umask); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1439,6 +1538,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_RMDIR }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1460,10 +1560,11 @@ -- goto exit1; -- } -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_rmdir(nd.dentry->d_inode, dentry); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1507,6 +1608,7 @@ -- char * name; -- struct dentry *dentry; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_UNLINK }; -- -- name = getname(pathname); -- if(IS_ERR(name)) --@@ -1519,7 +1621,7 @@ -- if (nd.last_type != LAST_NORM) -- goto exit1; -- down(&nd.dentry->d_inode->i_sem); --- dentry = lookup_hash(&nd.last, nd.dentry); --+ dentry = lookup_hash_it(&nd.last, nd.dentry, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- /* Why not before? Because we want correct error value */ --@@ -1527,6 +1629,7 @@ -- goto slashes; -- error = vfs_unlink(nd.dentry->d_inode, dentry); -- exit2: --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1573,6 +1676,7 @@ -- int error = 0; -- char * from; -- char * to; --+ struct lookup_intent it = { .it_op = IT_SYMLINK }; -- -- from = getname(oldname); -- if(IS_ERR(from)) --@@ -1586,10 +1690,12 @@ -- error = path_lookup(to, LOOKUP_PARENT, &nd); -- if (error) -- goto out; --- dentry = lookup_create(&nd, 0); --+ it.it_data = from; --+ dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(dentry); -- if (!IS_ERR(dentry)) { -- error = vfs_symlink(nd.dentry->d_inode, dentry, from); --+ intent_release(dentry, &it); -- dput(dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1654,6 +1760,7 @@ -- { -- int error; -- char * to; --+ struct lookup_intent it = { .it_op = IT_LINK }; -- -- to = getname(newname); -- error = PTR_ERR(to); --@@ -1661,7 +1768,7 @@ -- struct dentry *new_dentry; -- struct nameidata nd, old_nd; -- --- error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd); --+ error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it); -- if (error) -- goto exit; -- error = path_lookup(to, LOOKUP_PARENT, &nd); --@@ -1670,10 +1778,12 @@ -- error = -EXDEV; -- if (old_nd.mnt != nd.mnt) -- goto out_release; --- new_dentry = lookup_create(&nd, 0); --+ it.it_op = IT_LINK2; --+ new_dentry = lookup_create(&nd, 0, &it); -- error = PTR_ERR(new_dentry); -- if (!IS_ERR(new_dentry)) { -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); --+ intent_release(new_dentry, &it); -- dput(new_dentry); -- } -- up(&nd.dentry->d_inode->i_sem); --@@ -1715,7 +1822,8 @@ -- * locking]. -- */ -- int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- struct inode *target; --@@ -1773,6 +1881,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- if (target) { -- if (!error) -- target->i_flags |= S_DEAD; --@@ -1794,7 +1903,8 @@ -- } -- -- int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- --@@ -1825,6 +1935,7 @@ -- error = -EBUSY; -- else -- error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); --+ intent_release(new_dentry, it); -- double_up(&old_dir->i_zombie, &new_dir->i_zombie); -- if (error) -- return error; --@@ -1836,13 +1947,14 @@ -- } -- -- int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, --- struct inode *new_dir, struct dentry *new_dentry) --+ struct inode *new_dir, struct dentry *new_dentry, --+ struct lookup_intent *it) -- { -- int error; -- if (S_ISDIR(old_dentry->d_inode->i_mode)) --- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it); -- else --- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); --+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it); -- if (!error) { -- if (old_dir == new_dir) -- inode_dir_notify(old_dir, DN_RENAME); --@@ -1859,6 +1971,7 @@ -- int error = 0; -- struct dentry * old_dir, * new_dir; -- struct dentry * old_dentry, *new_dentry; --+ struct lookup_intent it = { .it_op = IT_RENAME }; -- struct nameidata oldnd, newnd; -- -- error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); --@@ -1884,7 +1997,7 @@ -- -- double_lock(new_dir, old_dir); -- --- old_dentry = lookup_hash(&oldnd.last, old_dir); --+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it); -- error = PTR_ERR(old_dentry); -- if (IS_ERR(old_dentry)) -- goto exit3; --@@ -1900,18 +2013,21 @@ -- if (newnd.last.name[newnd.last.len]) -- goto exit4; -- } --- new_dentry = lookup_hash(&newnd.last, new_dir); --+ it.it_op = IT_RENAME2; --+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &it); -- error = PTR_ERR(new_dentry); -- if (IS_ERR(new_dentry)) -- goto exit4; -- -- lock_kernel(); -- error = vfs_rename(old_dir->d_inode, old_dentry, --- new_dir->d_inode, new_dentry); --+ new_dir->d_inode, new_dentry, &it); -- unlock_kernel(); -- --+ intent_release(new_dentry, &it); -- dput(new_dentry); -- exit4: --+ intent_release(old_dentry, &it); // FIXME: release same intent twice!!! -- dput(old_dentry); -- exit3: -- double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem); ----- kernel-2.4.18-pristine/fs/open.c 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/fs/open.c 2002-10-14 14:08:23.000000000 -0600 --@@ -19,6 +19,9 @@ -- #include -- -- #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) --+extern int path_walk_it(const char *name, struct nameidata *nd, --+ struct lookup_intent *it); --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- -- int vfs_statfs(struct super_block *sb, struct statfs *buf) -- { --@@ -118,12 +121,13 @@ -- struct nameidata nd; -- struct inode * inode; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- -- error = -EINVAL; -- if (length < 0) /* sorry, but loff_t says... */ -- goto out; -- --- error = user_path_walk(path, &nd); --+ error = user_path_walk_it(path, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -168,6 +172,7 @@ -- put_write_access(inode); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -259,8 +264,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -286,6 +292,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -303,8 +310,9 @@ -- struct nameidata nd; -- struct inode * inode; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- -- if (error) -- goto out; --@@ -330,6 +338,7 @@ -- } -- error = notify_change(nd.dentry, &newattrs); -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -346,6 +355,7 @@ -- int old_fsuid, old_fsgid; -- kernel_cap_t old_cap; -- int res; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- -- if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ -- return -EINVAL; --@@ -363,13 +373,14 @@ -- else -- current->cap_effective = current->cap_permitted; -- --- res = user_path_walk(filename, &nd); --+ res = user_path_walk_it(filename, &nd, &it); -- if (!res) { -- res = permission(nd.dentry->d_inode, mode); -- /* SuS v2 requires we report a read only fs too */ -- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) -- && !special_file(nd.dentry->d_inode->i_mode)) -- res = -EROFS; --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- --@@ -384,8 +395,11 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); --+ error = __user_walk_it(filename, --+ LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, --+ &nd, &it); -- if (error) -- goto out; -- --@@ -396,6 +410,7 @@ -- set_fs_pwd(current->fs, nd.mnt, nd.dentry); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -435,9 +450,10 @@ -- { -- int error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); --+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | --+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); -- if (error) -- goto out; -- --@@ -453,6 +469,7 @@ -- set_fs_altroot(); -- error = 0; -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -497,8 +514,9 @@ -- struct inode * inode; -- int error; -- struct iattr newattrs; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (error) -- goto out; -- inode = nd.dentry->d_inode; --@@ -518,6 +536,7 @@ -- error = notify_change(nd.dentry, &newattrs); -- -- dput_and_out: --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- out: -- return error; --@@ -587,10 +606,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk(filename, &nd); --+ error = user_path_walk_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -600,10 +621,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_SETATTR }; -- --- error = user_path_walk_link(filename, &nd); --+ error = user_path_walk_link_it(filename, &nd, &it); -- if (!error) { -- error = chown_common(nd.dentry, user, group); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -637,10 +660,16 @@ -- * for the internal routines (ie open_namei()/follow_link() etc). 00 is -- * used by symlinks. -- */ --+extern int open_namei_it(const char *filename, int namei_flags, int mode, --+ struct nameidata *nd, struct lookup_intent *it); --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it); --+ -- struct file *filp_open(const char * filename, int flags, int mode) -- { -- int namei_flags, error; -- struct nameidata nd; --+ struct lookup_intent it = { .it_op = IT_OPEN }; -- -- namei_flags = flags; -- if ((namei_flags+1) & O_ACCMODE) --@@ -648,14 +677,15 @@ -- if (namei_flags & O_TRUNC) -- namei_flags |= 2; -- --- error = open_namei(filename, namei_flags, mode, &nd); --- if (!error) --- return dentry_open(nd.dentry, nd.mnt, flags); --- --- return ERR_PTR(error); --+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); --+ if (error) --+ return ERR_PTR(error); --+ --+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); -- } -- ---struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, --+ int flags, struct lookup_intent *it) -- { -- struct file * f; -- struct inode *inode; --@@ -698,6 +728,7 @@ -- } -- f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); -- --+ intent_release(dentry, it); -- return f; -- -- cleanup_all: --@@ -712,11 +743,17 @@ -- cleanup_file: -- put_filp(f); -- cleanup_dentry: --+ intent_release(dentry, it); -- dput(dentry); -- mntput(mnt); -- return ERR_PTR(error); -- } -- --+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) --+{ --+ return dentry_open_it(dentry, mnt, flags, NULL); --+} --+ -- /* -- * Find an empty file descriptor entry, and mark it busy. -- */ ----- kernel-2.4.18-pristine/fs/stat.c 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/fs/stat.c 2002-10-14 14:08:23.000000000 -0600 --@@ -13,6 +13,7 @@ -- -- #include -- --+extern void intent_release(struct dentry *de, struct lookup_intent *it); -- /* -- * Revalidate the inode. This is required for proper NFS attribute caching. -- */ --@@ -104,10 +105,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk(name, &nd); --+ error = user_path_walk_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; --@@ -117,10 +120,12 @@ -- { -- struct nameidata nd; -- int error; --+ struct lookup_intent it = { .it_op = IT_GETATTR }; -- --- error = user_path_walk_link(name, &nd); --+ error = user_path_walk_link_it(name, &nd, &it); -- if (!error) { -- error = do_getattr(nd.mnt, nd.dentry, stat); --+ intent_release(nd.dentry, &it); -- path_release(&nd); -- } -- return error; ----- kernel-2.4.18-pristine/mm/slab.c 2002-10-14 13:47:27.000000000 -0600 --+++ kernel-2.4.18/mm/slab.c 2002-10-14 14:08:23.000000000 -0600 --@@ -1207,6 +1207,59 @@ -- * Called with the cache-lock held. -- */ -- --+extern struct page *check_get_page(unsigned long kaddr); --+struct page *page_mem_map(struct page *page); --+static int kmem_check_cache_obj (kmem_cache_t * cachep, --+ slab_t *slabp, void * objp) --+{ --+ int i; --+ unsigned int objnr; --+ --+#if DEBUG --+ if (cachep->flags & SLAB_RED_ZONE) { --+ objp -= BYTES_PER_WORD; --+ if ( *(unsigned long *)objp != RED_MAGIC2) --+ /* Either write before start, or a double free. */ --+ return 0; --+ if (*(unsigned long *)(objp+cachep->objsize - --+ BYTES_PER_WORD) != RED_MAGIC2) --+ /* Either write past end, or a double free. */ --+ return 0; --+ } --+#endif --+ --+ objnr = (objp-slabp->s_mem)/cachep->objsize; --+ if (objnr >= cachep->num) --+ return 0; --+ if (objp != slabp->s_mem + objnr*cachep->objsize) --+ return 0; --+ --+ /* Check slab's freelist to see if this obj is there. */ --+ for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { --+ if (i == objnr) --+ return 0; --+ } --+ return 1; --+} --+ --+ --+int kmem_cache_validate(kmem_cache_t *cachep, void *objp) --+{ --+ struct page *page = check_get_page((unsigned long)objp); --+ --+ if (!VALID_PAGE(page)) --+ return 0; --+ --+ if (!PageSlab(page)) --+ return 0; --+ --+ /* XXX check for freed slab objects ? */ --+ if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp)) --+ return 0; --+ --+ return (cachep == GET_PAGE_CACHE(page)); --+} --+ -- #if DEBUG -- static int kmem_extra_free_checks (kmem_cache_t * cachep, -- slab_t *slabp, void * objp) ----- kernel-2.4.18-pristine/fs/jbd/commit.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/fs/jbd/commit.c 2002-10-14 14:08:23.000000000 -0600 --@@ -482,7 +482,7 @@ -- transaction's t_log_list queue, and metadata buffers are on -- the t_iobuf_list queue. -- --- Wait for the transactions in reverse order. That way we are --+ Wait for the buffers in reverse order. That way we are -- less likely to be woken up until all IOs have completed, and -- so we incur less scheduling load. -- */ --@@ -575,8 +575,10 @@ -- -- jbd_debug(3, "JBD: commit phase 6\n"); -- --- if (is_journal_aborted(journal)) --+ if (is_journal_aborted(journal)) { --+ unlock_journal(journal); -- goto skip_commit; --+ } -- -- /* Done it all: now write the commit record. We should have -- * cleaned up our previous buffers by now, so if we are in abort --@@ -586,6 +588,7 @@ -- descriptor = journal_get_descriptor_buffer(journal); -- if (!descriptor) { -- __journal_abort_hard(journal); --+ unlock_journal(journal); -- goto skip_commit; -- } -- --@@ -609,7 +612,6 @@ -- put_bh(bh); /* One for getblk() */ -- journal_unlock_journal_head(descriptor); -- } --- lock_journal(journal); -- -- /* End of a transaction! Finally, we can do checkpoint -- processing: any buffers committed as a result of this --@@ -618,6 +620,25 @@ -- -- skip_commit: -- --+ /* Call any callbacks that had been registered for handles in this --+ * transaction. It is up to the callback to free any allocated --+ * memory. --+ */ --+ if (!list_empty(&commit_transaction->t_jcb)) { --+ struct list_head *p, *n; --+ int error = is_journal_aborted(journal); --+ --+ list_for_each_safe(p, n, &commit_transaction->t_jcb) { --+ struct journal_callback *jcb; --+ --+ jcb = list_entry(p, struct journal_callback, jcb_list); --+ list_del(p); --+ jcb->jcb_func(jcb, error); --+ } --+ } --+ --+ lock_journal(journal); --+ -- jbd_debug(3, "JBD: commit phase 7\n"); -- -- J_ASSERT(commit_transaction->t_sync_datalist == NULL); ----- kernel-2.4.18-pristine/fs/jbd/journal.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/fs/jbd/journal.c 2002-10-14 14:08:23.000000000 -0600 --@@ -58,6 +58,7 @@ -- #endif -- EXPORT_SYMBOL(journal_flush); -- EXPORT_SYMBOL(journal_revoke); --+EXPORT_SYMBOL(journal_callback_set); -- -- EXPORT_SYMBOL(journal_init_dev); -- EXPORT_SYMBOL(journal_init_inode); ----- kernel-2.4.18-pristine/fs/jbd/transaction.c 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/fs/jbd/transaction.c 2002-10-14 14:08:23.000000000 -0600 --@@ -57,6 +57,7 @@ -- transaction->t_state = T_RUNNING; -- transaction->t_tid = journal->j_transaction_sequence++; -- transaction->t_expires = jiffies + journal->j_commit_interval; --+ INIT_LIST_HEAD(&transaction->t_jcb); -- -- /* Set up the commit timer for the new transaction. */ -- J_ASSERT (!journal->j_commit_timer_active); --@@ -201,6 +202,20 @@ -- return 0; -- } -- --+/* Allocate a new handle. This should probably be in a slab... */ --+static handle_t *new_handle(int nblocks) --+{ --+ handle_t *handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ if (!handle) --+ return NULL; --+ memset(handle, 0, sizeof (handle_t)); --+ handle->h_buffer_credits = nblocks; --+ handle->h_ref = 1; --+ INIT_LIST_HEAD(&handle->h_jcb); --+ --+ return handle; --+} --+ -- /* -- * Obtain a new handle. -- * --@@ -227,14 +242,11 @@ -- handle->h_ref++; -- return handle; -- } --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = new_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = start_this_handle(journal, handle); --@@ -333,14 +345,11 @@ -- -- if (is_journal_aborted(journal)) -- return ERR_PTR(-EIO); --- --- handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); --+ --+ handle = new_handle(nblocks); -- if (!handle) -- return ERR_PTR(-ENOMEM); --- memset (handle, 0, sizeof (handle_t)); -- --- handle->h_buffer_credits = nblocks; --- handle->h_ref = 1; -- current->journal_info = handle; -- -- err = try_start_this_handle(journal, handle); --@@ -1319,6 +1328,28 @@ -- #endif -- -- /* --+ * Register a callback function for this handle. The function will be --+ * called when the transaction that this handle is part of has been --+ * committed to disk with the original callback data struct and the --+ * error status of the journal as parameters. There is no guarantee of --+ * ordering between handles within a single transaction, nor between --+ * callbacks registered on the same handle. --+ * --+ * The caller is responsible for allocating the journal_callback struct. --+ * This is to allow the caller to add as much extra data to the callback --+ * as needed, but reduce the overhead of multiple allocations. The caller --+ * allocated struct must start with a struct journal_callback at offset 0, --+ * and has the caller-specific data afterwards. --+ */ --+void journal_callback_set(handle_t *handle, --+ void (*func)(struct journal_callback *jcb, int error), --+ struct journal_callback *jcb) --+{ --+ list_add(&jcb->jcb_list, &handle->h_jcb); --+ jcb->jcb_func = func; --+} --+ --+/* -- * All done for a particular handle. -- * -- * There is not much action needed here. We just return any remaining --@@ -1383,7 +1414,10 @@ -- wake_up(&journal->j_wait_transaction_locked); -- } -- --- /* --+ /* Move callbacks from the handle to the transaction. */ --+ list_splice(&handle->h_jcb, &transaction->t_jcb); --+ --+ /* -- * If the handle is marked SYNC, we need to set another commit -- * going! We also want to force a commit if the current -- * transaction is occupying too much of the log, or if the ----- kernel-2.4.18-pristine/include/linux/jbd.h 2002-10-14 13:47:20.000000000 -0600 --+++ kernel-2.4.18/include/linux/jbd.h 2002-10-14 14:08:23.000000000 -0600 --@@ -257,6 +257,13 @@ -- return bh->b_private; -- } -- --+#define HAVE_JOURNAL_CALLBACK_STATUS --+struct journal_callback { --+ struct list_head jcb_list; --+ void (*jcb_func)(struct journal_callback *jcb, int error); --+ /* user data goes here */ --+}; --+ -- struct jbd_revoke_table_s; -- -- /* The handle_t type represents a single atomic update being performed --@@ -287,6 +294,12 @@ -- operations */ -- int h_err; -- --+ /* List of application registered callbacks for this handle. --+ * The function(s) will be called after the transaction that --+ * this handle is part of has been committed to disk. --+ */ --+ struct list_head h_jcb; --+ -- /* Flags */ -- unsigned int h_sync: 1; /* sync-on-close */ -- unsigned int h_jdata: 1; /* force data journaling */ --@@ -406,6 +419,10 @@ -- -- /* How many handles used this transaction? */ -- int t_handle_count; --+ --+ /* List of registered callback functions for this transaction. --+ * Called when the transaction is committed. */ --+ struct list_head t_jcb; -- }; -- -- --@@ -654,6 +671,9 @@ -- extern int journal_try_to_free_buffers(journal_t *, struct page *, int); -- extern int journal_stop(handle_t *); -- extern int journal_flush (journal_t *); --+extern void journal_callback_set(handle_t *handle, --+ void (*fn)(struct journal_callback *,int), --+ struct journal_callback *jcb); -- -- extern void journal_lock_updates (journal_t *); -- extern void journal_unlock_updates (journal_t *); diff --cc lustre/patches/patch-2.4.18-um index 6e1e345,6e1e345..0000000 deleted file mode 100644,100644 --- a/lustre/patches/patch-2.4.18-um +++ /dev/null @@@ -1,49 -1,49 +1,0 @@@ ----- lum-pristine/arch/um/kernel/mem.c Mon Aug 12 11:05:20 2002 --+++ lum/arch/um/kernel/mem.c Thu Aug 1 18:07:35 2002 --@@ -527,6 +527,21 @@ -- return(phys_mem_map(pte_val(pte))); -- } -- --+struct page *check_get_page(unsigned long kaddr) --+{ --+ struct page *page; --+ struct mem_region *mr; --+ unsigned long phys = __pa(kaddr); --+ unsigned int n = phys_region_index(phys); --+ --+ if (regions[n] == NULL) --+ return NULL; --+ --+ mr = regions[n]; --+ page = (struct page *) mr->mem_map; --+ return page + ((phys_addr(phys)) >> PAGE_SHIFT); --+} --+ -- struct mem_region *page_region(struct page *page, int *index_out) -- { -- int i; --@@ -542,12 +558,14 @@ -- return(region); -- } -- } --- panic("No region found for page"); --+ //panic("No region found for page"); -- return(NULL); -- } -- -- struct page *page_mem_map(struct page *page) -- { --+ if (!page_region(page, NULL)) --+ return NULL; -- return((struct page *) page_region(page, NULL)->mem_map); -- } -- --@@ -564,7 +582,7 @@ -- (addr <= region->start + region->len)) -- return(mk_phys(addr - region->start, i)); -- } --- panic("region_pa : no region for virtual address"); --+ //panic("region_pa : no region for virtual address"); -- return(0); -- } -- diff --cc lustre/patches/ubd-io-fail-2.4.18 index 56c3742,56c3742..0000000 deleted file mode 100644,100644 --- a/lustre/patches/ubd-io-fail-2.4.18 +++ /dev/null @@@ -1,34 -1,34 +1,0 @@@ ----- lum/arch/um/drivers/ubd.c.orig Wed Mar 13 14:04:59 2002 --+++ lum/arch/um/drivers/ubd.c Thu Mar 28 23:39:15 2002 --@@ -693,14 +697,23 @@ -- spin_unlock(&io_request_lock); -- return(1); -- } --- if((req->cmd == WRITE) && --- ((dev->openflags & O_ACCMODE) == O_RDONLY)){ --- printk("Write attempted on readonly ubd device %d\n", --- minor(req->rq_dev)); --- spin_lock(&io_request_lock); --- end_request(0); --- spin_unlock(&io_request_lock); --- return(1); --+ if (req->cmd == WRITE) { --+#ifdef CONFIG_DEV_RDONLY --+ if (dev_check_rdonly(req->rq_dev)) { --+ spin_lock(&io_request_lock); --+ end_request(1); --+ spin_unlock(&io_request_lock); --+ return(0); --+ } --+#endif --+ if ((dev->openflags & O_ACCMODE) == O_RDONLY) { --+ printk("Write attempted on readonly ubd device %d\n", --+ minor(req->rq_dev)); --+ spin_lock(&io_request_lock); --+ end_request(0); --+ spin_unlock(&io_request_lock); --+ return(1); --+ } -- } -- -- block = req->sector; diff --cc lustre/ptlrpc/.cvsignore index 067f05c,067f05c..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/.cvsignore +++ /dev/null @@@ -1,9 -1,9 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --tags --TAGS diff --cc lustre/ptlrpc/Makefile.am index dd3f9d8,dd3f9d8..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/Makefile.am +++ /dev/null @@@ -1,14 -1,14 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --DEFS= -- --MODULE = ptlrpc --modulefs_DATA = ptlrpc.o --EXTRA_PROGRAMS = ptlrpc -- --ptlrpc_SOURCES = recovd.c recover.c connection.c rpc.c events.c service.c client.c niobuf.c pack_generic.c lproc_ptlrpc.c -- --include $(top_srcdir)/Rules diff --cc lustre/ptlrpc/client.c index 1425498,4ab7903..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/client.c +++ /dev/null @@@ -1,753 -1,812 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include --#include --#include -- --void ptlrpc_init_client(int req_portal, int rep_portal, char *name, -- struct ptlrpc_client *cl) --{ -- cl->cli_request_portal = req_portal; -- cl->cli_reply_portal = rep_portal; -- cl->cli_name = name; --} -- --__u8 *ptlrpc_req_to_uuid(struct ptlrpc_request *req) --{ -- return req->rq_connection->c_remote_uuid; --} -- --struct ptlrpc_connection *ptlrpc_uuid_to_connection(obd_uuid_t uuid) --{ -- struct ptlrpc_connection *c; -- struct lustre_peer peer; -- int err; -- -- err = kportal_uuid_to_peer(uuid, &peer); -- if (err != 0) { -- CERROR("cannot find peer %s!\n", uuid); -- return NULL; -- } -- -- c = ptlrpc_get_connection(&peer, uuid); -- if (c) { -- memcpy(c->c_remote_uuid, uuid, sizeof(c->c_remote_uuid)); -- c->c_epoch++; -- } -- -- CDEBUG(D_INFO, "%s -> %p\n", uuid, c); -- -- return c; --} -- --void ptlrpc_readdress_connection(struct ptlrpc_connection *conn,obd_uuid_t uuid) --{ -- struct lustre_peer peer; -- int err; -- -- err = kportal_uuid_to_peer(uuid, &peer); -- if (err != 0) { -- CERROR("cannot find peer %s!\n", uuid); -- return; -- } -- -- memcpy(&conn->c_peer, &peer, sizeof(peer)); -- return; --} -- --struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct ptlrpc_connection *conn) --{ -- struct ptlrpc_bulk_desc *desc; -- -- OBD_ALLOC(desc, sizeof(*desc)); -- if (desc != NULL) { -- desc->bd_connection = ptlrpc_connection_addref(conn); -- atomic_set(&desc->bd_refcount, 1); -- init_waitqueue_head(&desc->bd_waitq); -- INIT_LIST_HEAD(&desc->bd_page_list); - INIT_LIST_HEAD(&desc->bd_set_chain); -- ptl_set_inv_handle(&desc->bd_md_h); -- ptl_set_inv_handle(&desc->bd_me_h); -- } -- -- return desc; -} - -int ptlrpc_bulk_error(struct ptlrpc_bulk_desc *desc) -{ - int rc = 0; - if (desc->bd_flags & PTL_RPC_FL_TIMEOUT) { - rc = (desc->bd_flags & PTL_RPC_FL_INTR ? -ERESTARTSYS : - -ETIMEDOUT); - } - return rc; --} -- --struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc) --{ -- struct ptlrpc_bulk_page *bulk; -- -- OBD_ALLOC(bulk, sizeof(*bulk)); -- if (bulk != NULL) { -- bulk->bp_desc = desc; -- list_add_tail(&bulk->bp_link, &desc->bd_page_list); -- desc->bd_page_count++; -- } -- return bulk; --} -- --void ptlrpc_free_bulk(struct ptlrpc_bulk_desc *desc) --{ -- struct list_head *tmp, *next; -- ENTRY; -- if (desc == NULL) { -- EXIT; -- return; -- } - - LASSERT(list_empty(&desc->bd_set_chain)); -- -- list_for_each_safe(tmp, next, &desc->bd_page_list) { -- struct ptlrpc_bulk_page *bulk; -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); -- ptlrpc_free_bulk_page(bulk); -- } -- -- ptlrpc_put_connection(desc->bd_connection); -- -- OBD_FREE(desc, sizeof(*desc)); -- EXIT; --} -- --void ptlrpc_free_bulk_page(struct ptlrpc_bulk_page *bulk) --{ -- ENTRY; -- if (bulk == NULL) { -- EXIT; -- return; -- } -- -- list_del(&bulk->bp_link); -- bulk->bp_desc->bd_page_count--; -- OBD_FREE(bulk, sizeof(*bulk)); -- EXIT; -} - -static int ll_sync_brw_timeout(void *data) -{ - struct obd_brw_set *set = data; - struct list_head *tmp; - int failed = 0; - ENTRY; - - LASSERT(set); - - set->brw_flags |= PTL_RPC_FL_TIMEOUT; - - list_for_each(tmp, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, bd_set_chain); - - /* Skip descriptors that were completed successfully. */ - if (desc->bd_flags & (PTL_BULK_FL_RCVD | PTL_BULK_FL_SENT)) - continue; - - LASSERT(desc->bd_connection); - - /* If PtlMDUnlink succeeds, then it hasn't completed yet. If it - * fails, the bulk finished _just_ in time (after the timeout - * fired but before we got this far) and we'll let it live. - */ - if (PtlMDUnlink(desc->bd_md_h) != 0) { - CERROR("Near-miss on OST %s -- need to adjust " - "obd_timeout?\n", - desc->bd_connection->c_remote_uuid); - continue; - } - - CERROR("IO of %d pages to/from %s:%d (conn %p) timed out\n", - desc->bd_page_count, desc->bd_connection->c_remote_uuid, - desc->bd_portal, desc->bd_connection); - - /* This one will "never" arrive, don't wait for it. */ - if (atomic_dec_and_test(&set->brw_refcount)) - wake_up(&set->brw_waitq); - - if (class_signal_connection_failure) - class_signal_connection_failure(desc->bd_connection); - else - failed = 1; - } - - /* 0 = We go back to sleep, until we're resumed or interrupted */ - /* 1 = We can't be recovered, just abort the syscall with -ETIMEDOUT */ - RETURN(failed); -} - -static int ll_sync_brw_intr(void *data) -{ - struct obd_brw_set *set = data; - - ENTRY; - set->brw_flags |= PTL_RPC_FL_INTR; - RETURN(1); /* ignored, as of this writing */ -} - -int ll_brw_sync_wait(struct obd_brw_set *set, int phase) -{ - struct l_wait_info lwi; - struct list_head *tmp, *next; - int rc = 0; - ENTRY; - - switch(phase) { - case CB_PHASE_START: - lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, ll_sync_brw_timeout, - ll_sync_brw_intr, set); - rc = l_wait_event(set->brw_waitq, - atomic_read(&set->brw_refcount) == 0, &lwi); - - list_for_each_safe(tmp, next, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, - bd_set_chain); - list_del_init(&desc->bd_set_chain); - ptlrpc_bulk_decref(desc); - } - break; - case CB_PHASE_FINISH: - if (atomic_dec_and_test(&set->brw_refcount)) - wake_up(&set->brw_waitq); - break; - default: - LBUG(); - } - - RETURN(rc); --} -- --struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, int opcode, -- int count, int *lengths, char **bufs) --{ -- struct ptlrpc_connection *conn = imp->imp_connection; -- struct ptlrpc_request *request; -- int rc; -- ENTRY; -- -- OBD_ALLOC(request, sizeof(*request)); -- if (!request) { -- CERROR("request allocation out of memory\n"); -- RETURN(NULL); -- } -- -- rc = lustre_pack_msg(count, lengths, bufs, -- &request->rq_reqlen, &request->rq_reqmsg); -- if (rc) { -- CERROR("cannot pack request %d\n", rc); -- OBD_FREE(request, sizeof(*request)); -- RETURN(NULL); -- } -- -- request->rq_level = LUSTRE_CONN_FULL; -- request->rq_type = PTL_RPC_MSG_REQUEST; -- request->rq_import = imp; -- -- /* XXX FIXME bug 625069 */ -- request->rq_request_portal = imp->imp_client->cli_request_portal; -- request->rq_reply_portal = imp->imp_client->cli_reply_portal; -- -- request->rq_connection = ptlrpc_connection_addref(conn); -- -- INIT_LIST_HEAD(&request->rq_list); - /* - * This will be reduced once when the sender is finished (waiting for - * reply, f.e.), and once when the request has been committed and is - * removed from the to-be-committed list. - * - * Also, the refcount will be increased in ptl_send_rpc immediately - * before we hand it off to portals, and there will be a corresponding - * decrease in request_out_cb (which is called to indicate that portals - * is finished with the request, and it can be safely freed). - * - * (Except in the DLM server case, where it will be dropped twice - * by the sender, and then the last time by request_out_callback.) - */ - atomic_set(&request->rq_refcount, 2); - atomic_set(&request->rq_refcount, 1); -- - spin_lock(&conn->c_lock); - request->rq_xid = HTON__u32(++conn->c_xid_out); - spin_unlock(&conn->c_lock); - spin_lock(&imp->imp_lock); - request->rq_xid = HTON__u32(++imp->imp_last_xid); - spin_unlock(&imp->imp_lock); -- -- request->rq_reqmsg->magic = PTLRPC_MSG_MAGIC; -- request->rq_reqmsg->version = PTLRPC_MSG_VERSION; -- request->rq_reqmsg->opc = HTON__u32(opcode); -- request->rq_reqmsg->flags = 0; -- -- ptlrpc_hdl2req(request, &imp->imp_handle); -- RETURN(request); - } - - void ptlrpc_req_finished(struct ptlrpc_request *request) - { - if (request == NULL) - return; - - if (atomic_dec_and_test(&request->rq_refcount)) - ptlrpc_free_req(request); - else - DEBUG_REQ(D_INFO, request, "refcount now %u", - atomic_read(&request->rq_refcount)); --} -- - void ptlrpc_free_req(struct ptlrpc_request *request) -static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) --{ -- ENTRY; -- if (request == NULL) { -- EXIT; -- return; -- } -- -- if (atomic_read(&request->rq_refcount) != 0) { -- CERROR("freeing request %p (%d->%s:%d) with refcount %d\n", -- request, request->rq_reqmsg->opc, -- request->rq_connection->c_remote_uuid, -- request->rq_import->imp_client->cli_request_portal, -- request->rq_refcount); -- /* LBUG(); */ -- } -- -- if (request->rq_repmsg != NULL) { -- OBD_FREE(request->rq_repmsg, request->rq_replen); -- request->rq_repmsg = NULL; -- request->rq_reply_md.start = NULL; -- } -- if (request->rq_reqmsg != NULL) { -- OBD_FREE(request->rq_reqmsg, request->rq_reqlen); -- request->rq_reqmsg = NULL; -- } -- - if (request->rq_connection) { - spin_lock(&request->rq_connection->c_lock); - if (request->rq_import) { - if (!locked) - spin_lock(&request->rq_import->imp_lock); -- list_del_init(&request->rq_list); - spin_unlock(&request->rq_connection->c_lock); - if (!locked) - spin_unlock(&request->rq_import->imp_lock); -- } -- -- ptlrpc_put_connection(request->rq_connection); -- OBD_FREE(request, sizeof(*request)); -- EXIT; -} - -void ptlrpc_free_req(struct ptlrpc_request *request) -{ - __ptlrpc_free_req(request, 0); -} - -static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked) -{ - ENTRY; - if (request == NULL) - RETURN(1); - - if (atomic_dec_and_test(&request->rq_refcount)) { - __ptlrpc_free_req(request, locked); - RETURN(1); - } - - DEBUG_REQ(D_INFO, request, "refcount now %u", - atomic_read(&request->rq_refcount)); - RETURN(0); -} - -void ptlrpc_req_finished(struct ptlrpc_request *request) -{ - __ptlrpc_req_finished(request, 0); --} -- --static int ptlrpc_check_reply(struct ptlrpc_request *req) --{ -- int rc = 0; -- - ENTRY; -- if (req->rq_repmsg != NULL) { - struct ptlrpc_connection *conn = req->rq_import->imp_connection; - if (req->rq_level > conn->c_level) { - CDEBUG(D_HA, - "rep to xid "LPD64" op %d to %s:%d: " - "recovery started, ignoring (%d > %d)\n", - (unsigned long long)req->rq_xid, - req->rq_reqmsg->opc, conn->c_remote_uuid, - req->rq_import->imp_client->cli_request_portal, - req->rq_level, conn->c_level); - req->rq_repmsg = NULL; - GOTO(out, rc = 0); - } -- req->rq_transno = NTOH__u64(req->rq_repmsg->transno); -- req->rq_flags |= PTL_RPC_FL_REPLIED; -- GOTO(out, rc = 1); -- } -- -- if (req->rq_flags & PTL_RPC_FL_RESEND) { - CERROR("-- RESTART --\n"); - ENTRY; - DEBUG_REQ(D_ERROR, req, "RESEND:"); -- GOTO(out, rc = 1); -- } -- -- if (req->rq_flags & PTL_RPC_FL_ERR) { - CERROR("-- ABORTED --\n"); - ENTRY; - DEBUG_REQ(D_ERROR, req, "ABORTED:"); -- GOTO(out, rc = 1); -- } -- - if (req->rq_flags & PTL_RPC_FL_RESTART) { - DEBUG_REQ(D_ERROR, req, "RESTART:"); - GOTO(out, rc = 1); - } - EXIT; -- out: - CDEBUG(D_NET, "req = %p, rc = %d\n", req, rc); - DEBUG_REQ(D_NET, req, "rc = %d for", rc); -- return rc; --} -- - int ptlrpc_check_status(struct ptlrpc_request *req, int err) -static int ptlrpc_check_status(struct ptlrpc_request *req) --{ - int err; -- ENTRY; - - if (err != 0) { - CERROR("err is %d\n", err); - RETURN(err); - } - - if (req == NULL) { - CERROR("req == NULL\n"); - RETURN(-ENOMEM); - } - - if (req->rq_repmsg == NULL) { - CERROR("req->rq_repmsg == NULL\n"); - RETURN(-ENOMEM); - } -- -- err = req->rq_repmsg->status; -- if (req->rq_repmsg->type == NTOH__u32(PTL_RPC_MSG_ERR)) { - CERROR("req->rq_repmsg->type == PTL_RPC_MSG_ERR\n"); - DEBUG_REQ(D_ERROR, req, "type == PTL_RPC_MSG_ERR"); -- RETURN(err ? err : -EINVAL); -- } -- - if (err != 0) { - if (err < 0) - CERROR("req->rq_repmsg->status is %d\n", err); - else - CDEBUG(D_INFO, "req->rq_repmsg->status is %d\n", err); - if (err < 0) { - DEBUG_REQ(D_ERROR, req, "status is %d", err); - } else if (err > 0) { -- /* XXX: translate this error from net to host */ - RETURN(err); - DEBUG_REQ(D_INFO, req, "status is %d", err); -- } -- - RETURN(0); - RETURN(err); --} -- --static void ptlrpc_cleanup_request_buf(struct ptlrpc_request *request) --{ -- OBD_FREE(request->rq_reqmsg, request->rq_reqlen); -- request->rq_reqmsg = NULL; -- request->rq_reqlen = 0; --} -- --/* Abort this request and cleanup any resources associated with it. */ --static int ptlrpc_abort(struct ptlrpc_request *request) --{ -- /* First remove the ME for the reply; in theory, this means -- * that we can tear down the buffer safely. */ -- PtlMEUnlink(request->rq_reply_me_h); -- OBD_FREE(request->rq_reply_md.start, request->rq_replen); -- request->rq_repmsg = NULL; -- request->rq_replen = 0; -- return 0; --} -- - /* caller must hold conn->c_lock */ - void ptlrpc_free_committed(struct ptlrpc_connection *conn) -/* caller must hold imp->imp_lock */ -void ptlrpc_free_committed(struct obd_import *imp) --{ -- struct list_head *tmp, *saved; -- struct ptlrpc_request *req; - ENTRY; -- - restart: - list_for_each_safe(tmp, saved, &conn->c_sending_head) { -#ifndef __arch_um__ - LASSERT(spin_is_locked(&imp->imp_lock)); -#endif - - CDEBUG(D_HA, "committing for xid "LPU64", last_committed "LPU64"\n", - imp->imp_peer_last_xid, imp->imp_peer_committed_transno); - - list_for_each_safe(tmp, saved, &imp->imp_replay_list) { -- req = list_entry(tmp, struct ptlrpc_request, rq_list); -- -- if (req->rq_flags & PTL_RPC_FL_REPLAY) { -- DEBUG_REQ(D_HA, req, "keeping (FL_REPLAY)"); - continue; - } - - if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) { - DEBUG_REQ(D_HA, req, "keeping (in-flight)"); -- continue; -- } -- -- /* not yet committed */ - if (req->rq_transno > conn->c_last_committed) - if (req->rq_transno > imp->imp_peer_committed_transno) { - DEBUG_REQ(D_HA, req, "stopping search"); -- break; - - DEBUG_REQ(D_HA, req, "committing (last_committed %Lu)", - (long long)conn->c_last_committed); - if (atomic_dec_and_test(&req->rq_refcount)) { - /* We do this to prevent free_req deadlock. Restarting - * after each removal is not so bad, as we are almost - * always deleting the first item in the list. - * - * If we use a recursive lock here, we can skip the - * unlock/lock/restart sequence. - */ - spin_unlock(&conn->c_lock); - ptlrpc_free_req(req); - spin_lock(&conn->c_lock); - goto restart; - } else { - list_del(&req->rq_list); - list_add(&req->rq_list, &conn->c_dying_head); -- } - - DEBUG_REQ(D_HA, req, "committing (last_committed "LPU64")", - imp->imp_peer_committed_transno); - __ptlrpc_req_finished(req, 1); -- } -- -- EXIT; -- return; --} -- --void ptlrpc_cleanup_client(struct obd_import *imp) --{ -- struct list_head *tmp, *saved; -- struct ptlrpc_request *req; -- struct ptlrpc_connection *conn = imp->imp_connection; -- ENTRY; -- -- LASSERT(conn); -- - restart1: - spin_lock(&conn->c_lock); - list_for_each_safe(tmp, saved, &conn->c_sending_head) { - spin_lock(&imp->imp_lock); - list_for_each_safe(tmp, saved, &imp->imp_replay_list) { -- req = list_entry(tmp, struct ptlrpc_request, rq_list); - if (req->rq_import != imp) - continue; - -- /* XXX we should make sure that nobody's sleeping on these! */ -- DEBUG_REQ(D_HA, req, "cleaning up from sending list"); - list_del_init(&req->rq_list); - req->rq_import = NULL; - spin_unlock(&conn->c_lock); - ptlrpc_req_finished(req); - goto restart1; - } - restart2: - list_for_each_safe(tmp, saved, &conn->c_dying_head) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - if (req->rq_import != imp) - continue; - DEBUG_REQ(D_ERROR, req, "on dying list at cleanup"); -- list_del_init(&req->rq_list); -- req->rq_import = NULL; - spin_unlock(&conn->c_lock); - ptlrpc_req_finished(req); - spin_lock(&conn->c_lock); - goto restart2; - __ptlrpc_req_finished(req, 0); -- } - spin_unlock(&conn->c_lock); - - spin_unlock(&imp->imp_lock); - -- EXIT; -- return; --} -- --void ptlrpc_continue_req(struct ptlrpc_request *req) --{ -- ENTRY; - CDEBUG(D_HA, "continue delayed request "LPD64" opc %d\n", - req->rq_xid, req->rq_reqmsg->opc); - DEBUG_REQ(D_HA, req, "continuing delayed request"); -- req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; -- req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; -- wake_up(&req->rq_wait_for_rep); -- EXIT; --} -- --void ptlrpc_resend_req(struct ptlrpc_request *req) --{ -- ENTRY; - CDEBUG(D_HA, "resend request "LPD64", opc %d\n", - req->rq_xid, req->rq_reqmsg->opc); - DEBUG_REQ(D_HA, req, "resending"); -- req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; -- req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; -- req->rq_status = -EAGAIN; -- req->rq_level = LUSTRE_CONN_RECOVD; -- req->rq_flags |= PTL_RPC_FL_RESEND; -- req->rq_flags &= ~PTL_RPC_FL_TIMEOUT; -- wake_up(&req->rq_wait_for_rep); -- EXIT; --} -- --void ptlrpc_restart_req(struct ptlrpc_request *req) --{ -- ENTRY; - CDEBUG(D_HA, "restart completed request "LPD64", opc %d\n", - req->rq_xid, req->rq_reqmsg->opc); - DEBUG_REQ(D_HA, req, "restarting (possibly-)completed request"); -- req->rq_status = -ERESTARTSYS; - req->rq_flags |= PTL_RPC_FL_RECOVERY; - req->rq_flags |= PTL_RPC_FL_RESTART; -- req->rq_flags &= ~PTL_RPC_FL_TIMEOUT; -- wake_up(&req->rq_wait_for_rep); -- EXIT; --} -- --static int expired_request(void *data) --{ -- struct ptlrpc_request *req = data; -- -- ENTRY; -- if (!req) { -- CERROR("NULL req!"); -- LBUG(); -- RETURN(0); -- } -- -- DEBUG_REQ(D_ERROR, req, "timeout"); -- req->rq_flags |= PTL_RPC_FL_TIMEOUT; -- -- if (!req->rq_import) { -- DEBUG_REQ(D_ERROR, req, "NULL import"); -- LBUG(); -- RETURN(0); -- } -- -- if (!req->rq_import->imp_connection) { -- DEBUG_REQ(D_ERROR, req, "NULL connection"); -- LBUG(); -- RETURN(0); -- } -- -- if (!req->rq_import->imp_connection->c_recovd_data.rd_recovd) -- RETURN(1); -- -- req->rq_timeout = 0; - req->rq_connection->c_level = LUSTRE_CONN_RECOVD; -- recovd_conn_fail(req->rq_import->imp_connection); -- -#if 0 -- /* If this request is for recovery or other primordial tasks, -- * don't go back to sleep. -- */ -- if (req->rq_level < LUSTRE_CONN_FULL) -- RETURN(1); -#endif -- RETURN(0); --} -- --static int interrupted_request(void *data) --{ -- struct ptlrpc_request *req = data; -- ENTRY; -- req->rq_flags |= PTL_RPC_FL_INTR; -- RETURN(1); /* ignored, as of this writing */ --} -- - /* If we're being torn down by umount -f, or the import has been - * invalidated (such as by an OST failure), the request must fail with - * -EIO. - * - * Must be called with conn->c_lock held, will drop it if it returns -EIO. -/* If the import has been invalidated (such as by an OST failure), the - * request must fail with -EIO. -- * - * XXX this should just be testing the import, and umount_begin shouldn't touch - * XXX the connection. - * Must be called with imp_lock held, will drop it if it returns -EIO. -- */ - #define EIO_IF_INVALID(conn, req) \ - if ((conn->c_flags & CONN_INVALID) || \ - (req->rq_import->imp_flags & IMP_INVALID)) { \ - DEBUG_REQ(D_ERROR, req, "%s_INVALID:", \ - (conn->c_flags & CONN_INVALID) ? "CONN" : "IMP"); \ - spin_unlock(&conn->c_lock); \ -#define EIO_IF_INVALID(req) \ -if (req->rq_import->imp_flags & IMP_INVALID) { \ - DEBUG_REQ(D_ERROR, req, "IMP_INVALID:"); \ - spin_unlock(&imp->imp_lock); \ -- RETURN(-EIO); \ --} -- --int ptlrpc_queue_wait(struct ptlrpc_request *req) --{ -- int rc = 0; -- struct l_wait_info lwi; - //struct ptlrpc_client *cli = req->rq_import->imp_client; - struct ptlrpc_connection *conn = req->rq_import->imp_connection; - struct obd_import *imp = req->rq_import; - struct ptlrpc_connection *conn = imp->imp_connection; -- ENTRY; -- -- init_waitqueue_head(&req->rq_wait_for_rep); - //DEBUG_REQ(D_HA, req, "subsys: %s:", cli->cli_name); -- - /* XXX probably both an import and connection level are needed */ - if (req->rq_level > conn->c_level) { - spin_lock(&conn->c_lock); - EIO_IF_INVALID(conn, req); - /* for distributed debugging */ - req->rq_reqmsg->status = HTON__u32(current->pid); - CDEBUG(D_RPCTRACE, "Sending RPC pid:xid:nid:opc %d:"LPU64":%x:%d\n", - NTOH__u32(req->rq_reqmsg->status), req->rq_xid, - conn->c_peer.peer_nid, NTOH__u32(req->rq_reqmsg->opc)); - - if (req->rq_level > imp->imp_level) { - spin_lock(&imp->imp_lock); - EIO_IF_INVALID(req); -- list_del(&req->rq_list); - list_add_tail(&req->rq_list, &conn->c_delayed_head); - spin_unlock(&conn->c_lock); - list_add_tail(&req->rq_list, &imp->imp_delayed_list); - spin_unlock(&imp->imp_lock); -- - DEBUG_REQ(D_HA, req, "waiting for recovery: (%d < %d)", - req->rq_level, conn->c_level); - DEBUG_REQ(D_HA, req, "\"%s\" waiting for recovery: (%d < %d)", - current->comm, req->rq_level, imp->imp_level); -- lwi = LWI_INTR(NULL, NULL); -- rc = l_wait_event(req->rq_wait_for_rep, - (req->rq_level <= conn->c_level) || - (req->rq_level <= imp->imp_level) || -- (req->rq_flags & PTL_RPC_FL_ERR), &lwi); -- - spin_lock(&conn->c_lock); - spin_lock(&imp->imp_lock); -- list_del_init(&req->rq_list); - spin_unlock(&conn->c_lock); - spin_unlock(&imp->imp_lock); -- -- if (req->rq_flags & PTL_RPC_FL_ERR) -- RETURN(-EIO); -- -- if (rc) -- RETURN(rc); -- -- CERROR("process %d resumed\n", current->pid); -- } -- resend: -- req->rq_timeout = obd_timeout; - spin_lock(&conn->c_lock); - EIO_IF_INVALID(conn, req); - spin_lock(&imp->imp_lock); - EIO_IF_INVALID(req); -- - list_del(&req->rq_list); - list_add_tail(&req->rq_list, &conn->c_sending_head); - spin_unlock(&conn->c_lock); - LASSERT(list_empty(&req->rq_list)); - list_add_tail(&req->rq_list, &imp->imp_sending_list); - spin_unlock(&imp->imp_lock); -- rc = ptl_send_rpc(req); -- if (rc) { -- CDEBUG(D_HA, "error %d, opcode %d, need recovery\n", rc, -- req->rq_reqmsg->opc); - /* the sleep below will time out, triggering recovery */ - /* sleep for a jiffy, then trigger recovery */ - lwi = LWI_TIMEOUT_INTR(1, expired_request, - interrupted_request, req); - } else { - DEBUG_REQ(D_NET, req, "-- sleeping"); - lwi = LWI_TIMEOUT_INTR(req->rq_timeout * HZ, expired_request, - interrupted_request, req); -- } - - DEBUG_REQ(D_NET, req, "-- sleeping"); - lwi = LWI_TIMEOUT_INTR(req->rq_timeout * HZ, expired_request, - interrupted_request, req); -- l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi); -- DEBUG_REQ(D_NET, req, "-- done sleeping"); - - spin_lock(&imp->imp_lock); - list_del_init(&req->rq_list); - spin_unlock(&imp->imp_lock); -- -- if (req->rq_flags & PTL_RPC_FL_ERR) { -- ptlrpc_abort(req); -- GOTO(out, rc = -EIO); -- } -- -- /* Don't resend if we were interrupted. */ -- if ((req->rq_flags & (PTL_RPC_FL_RESEND | PTL_RPC_FL_INTR)) == -- PTL_RPC_FL_RESEND) { -- req->rq_flags &= ~PTL_RPC_FL_RESEND; -- DEBUG_REQ(D_HA, req, "resending: "); -- goto resend; -- } -- - // up(&cli->cli_rpc_sem); -- if (req->rq_flags & PTL_RPC_FL_INTR) { -- if (!(req->rq_flags & PTL_RPC_FL_TIMEOUT)) -- LBUG(); /* should only be interrupted if we timed out */ -- /* Clean up the dangling reply buffers */ -- ptlrpc_abort(req); -- GOTO(out, rc = -EINTR); -- } -- -- if (req->rq_flags & PTL_RPC_FL_TIMEOUT) -- GOTO(out, rc = -ETIMEDOUT); -- -- if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) -- GOTO(out, rc = req->rq_status); -- -- rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); -- if (rc) { -- CERROR("unpack_rep failed: %d\n", rc); -- GOTO(out, rc); -- } --#if 0 -- /* FIXME: Enable when BlueArc makes new release */ -- if (req->rq_repmsg->type != PTL_RPC_MSG_REPLY && -- req->rq_repmsg->type != PTL_RPC_MSG_ERR) { -- CERROR("invalid packet type received (type=%u)\n", -- req->rq_repmsg->type); -- LBUG(); -- GOTO(out, rc = -EINVAL); -- } --#endif - CDEBUG(D_NET, "got rep "LPD64"\n", req->rq_xid); - CDEBUG(D_NET, "got rep "LPU64"\n", req->rq_xid); -- if (req->rq_repmsg->status == 0) -- CDEBUG(D_NET, "--> buf %p len %d status %d\n", req->rq_repmsg, -- req->rq_replen, req->rq_repmsg->status); -- - spin_lock(&conn->c_lock); -- - /* Requests that aren't from replayable imports, or which don't have - * transno information, can be "committed" early. - */ - if (req->rq_import->imp_flags & IMP_REPLAYABLE) { - spin_lock(&imp->imp_lock); - if (req->rq_flags & PTL_RPC_FL_REPLAY || req->rq_transno != 0) { - /* Balanced in ptlrpc_free_committed, usually. */ - atomic_inc(&req->rq_refcount); - list_add_tail(&req->rq_list, &imp->imp_replay_list); - } -- - if ((req->rq_import->imp_flags & IMP_REPLAYABLE) == 0 || - req->rq_repmsg->transno == 0) { - /* This import doesn't support replay, so we can just "commit" - * this request now. - */ - DEBUG_REQ(D_HA, req, "not replayable, committing:"); - list_del_init(&req->rq_list); - spin_unlock(&conn->c_lock); - ptlrpc_req_finished(req); /* Must be called unlocked. */ - spin_lock(&conn->c_lock); - } - if (req->rq_transno > imp->imp_max_transno) { - imp->imp_max_transno = req->rq_transno; - } else if (req->rq_transno != 0 && - imp->imp_level == LUSTRE_CONN_FULL) { - CERROR("got transno "LPD64" after "LPD64": recovery " - "may not work\n", req->rq_transno, - imp->imp_max_transno); - } -- - /* Replay-enabled imports return commit-status information. */ - if (req->rq_import->imp_flags & IMP_REPLAYABLE) { - /* XXX this needs to be per-import, or multiple MDS services on - * XXX the same system are going to interfere messily with each - * XXX others' transno spaces. - */ - conn->c_last_xid = req->rq_repmsg->last_xid; - conn->c_last_committed = req->rq_repmsg->last_committed; - ptlrpc_free_committed(conn); - /* Replay-enabled imports return commit-status information. */ - imp->imp_peer_last_xid = req->rq_repmsg->last_xid; - imp->imp_peer_committed_transno = - req->rq_repmsg->last_committed; - ptlrpc_free_committed(imp); - spin_unlock(&imp->imp_lock); -- } -- - spin_unlock(&conn->c_lock); - rc = ptlrpc_check_status(req); -- -- EXIT; -- out: -- return rc; --} -- --#undef EIO_IF_INVALID -- --int ptlrpc_replay_req(struct ptlrpc_request *req) --{ -- int rc = 0, old_level, old_status = 0; -- // struct ptlrpc_client *cli = req->rq_import->imp_client; -- struct l_wait_info lwi; -- ENTRY; -- -- init_waitqueue_head(&req->rq_wait_for_rep); -- DEBUG_REQ(D_NET, req, ""); -- -- req->rq_timeout = obd_timeout; -- req->rq_reqmsg->addr = req->rq_import->imp_handle.addr; -- req->rq_reqmsg->cookie = req->rq_import->imp_handle.cookie; -- -- /* temporarily set request to RECOVD level (reset at out:) */ -- old_level = req->rq_level; -- if (req->rq_flags & PTL_RPC_FL_REPLIED) -- old_status = req->rq_repmsg->status; -- req->rq_level = LUSTRE_CONN_RECOVD; -- rc = ptl_send_rpc(req); -- if (rc) { -- CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc); -- ptlrpc_cleanup_request_buf(req); -- // up(&cli->cli_rpc_sem); -- GOTO(out, rc = -rc); -- } -- -- CDEBUG(D_OTHER, "-- sleeping\n"); -- lwi = LWI_INTR(NULL, NULL); /* XXX needs timeout, nested recovery */ -- l_wait_event(req->rq_wait_for_rep, ptlrpc_check_reply(req), &lwi); -- CDEBUG(D_OTHER, "-- done\n"); -- -- // up(&cli->cli_rpc_sem); -- -- if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) { -- CERROR("Unknown reason for wakeup\n"); -- /* XXX Phil - I end up here when I kill obdctl */ -- ptlrpc_abort(req); -- GOTO(out, rc = -EINTR); -- } -- -- rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); -- if (rc) { -- CERROR("unpack_rep failed: %d\n", rc); -- GOTO(out, rc); -- } -- -- CDEBUG(D_NET, "got rep "LPD64"\n", req->rq_xid); -- -- /* let the callback do fixups, possibly including in the request */ -- if (req->rq_replay_cb) -- req->rq_replay_cb(req); -- -- if ((req->rq_flags & PTL_RPC_FL_REPLIED) && -- req->rq_repmsg->status != old_status) { -- DEBUG_REQ(D_HA, req, "status %d, old was %d", -- req->rq_repmsg->status, old_status); -- } -- -- out: -- req->rq_level = old_level; -- RETURN(rc); --} diff --cc lustre/ptlrpc/connection.c index df2a2c2,2182591..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/connection.c +++ /dev/null @@@ -1,174 -1,169 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include -- --static spinlock_t conn_lock; --static struct list_head conn_list; --static struct list_head conn_unused_list; -- --/* If UUID is NULL, c->c_remote_uuid must be all zeroes -- * If UUID is non-NULL, c->c_remote_uuid must match. */ --static int match_connection_uuid(struct ptlrpc_connection *c, obd_uuid_t uuid) --{ -- obd_uuid_t zero_uuid = {0}; -- -- if (uuid) -- return memcmp(c->c_remote_uuid, uuid, sizeof(uuid)); -- -- return memcmp(c->c_remote_uuid, zero_uuid, sizeof(zero_uuid)); --} -- --struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer, -- obd_uuid_t uuid) --{ -- struct list_head *tmp, *pos; -- struct ptlrpc_connection *c; -- ENTRY; -- -- CDEBUG(D_INFO, "peer is %08x %08lx %08lx\n", -- peer->peer_nid, peer->peer_ni.nal_idx, peer->peer_ni.handle_idx); -- -- spin_lock(&conn_lock); -- list_for_each(tmp, &conn_list) { -- c = list_entry(tmp, struct ptlrpc_connection, c_link); -- if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0 && -- !match_connection_uuid(c, uuid)) { -- ptlrpc_connection_addref(c); -- GOTO(out, c); -- } -- } -- -- list_for_each_safe(tmp, pos, &conn_unused_list) { -- c = list_entry(tmp, struct ptlrpc_connection, c_link); -- if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0 && -- !match_connection_uuid(c, uuid)) { -- ptlrpc_connection_addref(c); -- list_del(&c->c_link); -- list_add(&c->c_link, &conn_list); -- GOTO(out, c); -- } -- } -- -- /* FIXME: this should be a slab once we can validate slab addresses -- * without OOPSing */ -- OBD_ALLOC(c, sizeof(*c)); -- if (c == NULL) -- GOTO(out, c); -- - c->c_level = LUSTRE_CONN_NEW; - c->c_xid_in = 1; - c->c_xid_out = 1; -- c->c_generation = 1; -- c->c_epoch = 1; -- c->c_bootcount = 0; -- c->c_flags = 0; -- if (uuid) -- strcpy(c->c_remote_uuid, uuid); - INIT_LIST_HEAD(&c->c_delayed_head); - INIT_LIST_HEAD(&c->c_sending_head); - INIT_LIST_HEAD(&c->c_dying_head); -- INIT_LIST_HEAD(&c->c_imports); -- INIT_LIST_HEAD(&c->c_exports); -- INIT_LIST_HEAD(&c->c_sb_chain); -- INIT_LIST_HEAD(&c->c_recovd_data.rd_managed_chain); - INIT_LIST_HEAD(&c->c_delayed_head); -- atomic_set(&c->c_refcount, 0); -- ptlrpc_connection_addref(c); -- spin_lock_init(&c->c_lock); -- -- memcpy(&c->c_peer, peer, sizeof(c->c_peer)); -- list_add(&c->c_link, &conn_list); -- -- EXIT; -- out: -- spin_unlock(&conn_lock); -- return c; --} -- --int ptlrpc_put_connection(struct ptlrpc_connection *c) --{ -- int rc = 0; -- ENTRY; -- -- if (c == NULL) { -- CERROR("NULL connection\n"); -- RETURN(0); -- } -- -- CDEBUG(D_INFO, "connection=%p refcount %d\n", -- c, atomic_read(&c->c_refcount) - 1); -- if (atomic_dec_and_test(&c->c_refcount)) { -- recovd_conn_unmanage(c); -- spin_lock(&conn_lock); -- list_del(&c->c_link); -- list_add(&c->c_link, &conn_unused_list); -- spin_unlock(&conn_lock); -- rc = 1; -- } -- if (atomic_read(&c->c_refcount) < 0) -- CERROR("connection %p refcount %d!\n", -- c, atomic_read(&c->c_refcount)); -- -- RETURN(rc); --} -- --struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *c) --{ -- ENTRY; -- CDEBUG(D_INFO, "connection=%p refcount %d\n", -- c, atomic_read(&c->c_refcount) + 1); -- atomic_inc(&c->c_refcount); -- RETURN(c); --} -- --void ptlrpc_init_connection(void) --{ -- INIT_LIST_HEAD(&conn_list); -- INIT_LIST_HEAD(&conn_unused_list); -- conn_lock = SPIN_LOCK_UNLOCKED; --} -- --void ptlrpc_cleanup_connection(void) --{ -- struct list_head *tmp, *pos; -- struct ptlrpc_connection *c; -- -- spin_lock(&conn_lock); -- list_for_each_safe(tmp, pos, &conn_unused_list) { -- c = list_entry(tmp, struct ptlrpc_connection, c_link); -- list_del(&c->c_link); -- OBD_FREE(c, sizeof(*c)); -- } -- list_for_each_safe(tmp, pos, &conn_list) { -- c = list_entry(tmp, struct ptlrpc_connection, c_link); - CERROR("Connection %p has refcount %d at cleanup (nid=%lu)!\n", - c, atomic_read(&c->c_refcount), - CERROR("Connection %p/%s has refcount %d (nid=%lu)\n", - c, c->c_remote_uuid, atomic_read(&c->c_refcount), -- (unsigned long)c->c_peer.peer_nid); -- list_del(&c->c_link); -- OBD_FREE(c, sizeof(*c)); -- } -- spin_unlock(&conn_lock); --} diff --cc lustre/ptlrpc/events.c index f162dfa,0bdf0d8..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/events.c +++ /dev/null @@@ -1,284 -1,288 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include -- --ptl_handle_eq_t request_out_eq, reply_in_eq, reply_out_eq, bulk_source_eq, -- bulk_sink_eq; --static const ptl_handle_ni_t *socknal_nip = NULL, *toenal_nip = NULL, -- *qswnal_nip = NULL, *gmnal_nip = NULL; -- --/* -- * Free the packet when it has gone out -- */ --static int request_out_callback(ptl_event_t *ev) --{ -- struct ptlrpc_request *req = ev->mem_desc.user_ptr; -- ENTRY; -- - LASSERT ((ev->mem_desc.options & PTL_MD_IOV) == 0); /* requests always contiguous */ - /* requests always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); -- -- if (ev->type != PTL_EVENT_SENT) { -- // XXX make sure we understand all events, including ACK's -- CERROR("Unknown event %d\n", ev->type); -- LBUG(); -- } -- -- /* this balances the atomic_inc in ptl_send_rpc */ -- ptlrpc_req_finished(req); -- RETURN(1); --} -- -- --/* -- * Free the packet when it has gone out -- */ --static int reply_out_callback(ptl_event_t *ev) --{ -- ENTRY; -- - LASSERT ((ev->mem_desc.options & PTL_MD_IOV) == 0); /* replies always contiguous */ - /* replies always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); -- -- if (ev->type == PTL_EVENT_SENT) { -- OBD_FREE(ev->mem_desc.start, ev->mem_desc.length); -- } else { -- // XXX make sure we understand all events, including ACK's -- CERROR("Unknown event %d\n", ev->type); -- LBUG(); -- } -- -- RETURN(1); --} -- --/* -- * Wake up the thread waiting for the reply once it comes in. -- */ --static int reply_in_callback(ptl_event_t *ev) --{ -- struct ptlrpc_request *req = ev->mem_desc.user_ptr; -- ENTRY; -- - LASSERT ((ev->mem_desc.options & PTL_MD_IOV) == 0); /* replies always contiguous */ - /* replies always contiguous */ - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); -- -- if (req->rq_xid == 0x5a5a5a5a5a5a5a5a) { -- CERROR("Reply received for freed request! Probably a missing " -- "ptlrpc_abort()\n"); -- LBUG(); -- } -- -- if (req->rq_xid != ev->match_bits) { -- CERROR("Reply packet for wrong request\n"); -- LBUG(); -- } -- -- if (ev->type == PTL_EVENT_PUT) { -- req->rq_repmsg = ev->mem_desc.start + ev->offset; -- barrier(); -- wake_up(&req->rq_wait_for_rep); -- } else { -- // XXX make sure we understand all events, including ACK's -- CERROR("Unknown event %d\n", ev->type); -- LBUG(); -- } -- -- RETURN(1); --} -- --int request_in_callback(ptl_event_t *ev) --{ -- struct ptlrpc_request_buffer_desc *rqbd = ev->mem_desc.user_ptr; -- struct ptlrpc_service *service = rqbd->rqbd_service; -- -- /* requests always contiguous */ - LASSERT ((ev->mem_desc.options & PTL_MD_IOV) == 0); - LASSERT((ev->mem_desc.options & PTL_MD_IOV) == 0); -- /* we only enable puts */ - LASSERT (ev->type == PTL_EVENT_PUT); - LASSERT (atomic_read (&service->srv_nrqbds_receiving) > 0); - LASSERT (atomic_read (&rqbd->rqbd_refcount) > 0); - LASSERT(ev->type == PTL_EVENT_PUT); - LASSERT(atomic_read(&service->srv_nrqbds_receiving) > 0); - LASSERT(atomic_read(&rqbd->rqbd_refcount) > 0); -- -- if (ev->rlength != ev->mlength) -- CERROR("Warning: Possibly truncated rpc (%d/%d)\n", -- ev->mlength, ev->rlength); -- - if (ptl_is_valid_handle (&ev->unlinked_me)) { - if (ptl_is_valid_handle(&ev->unlinked_me)) { -- /* This is the last request to be received into this -- * request buffer. We don't bump the refcount, since the -- * thread servicing this event is effectively taking over -- * portals' reference. -- */ --#warning ev->unlinked_me.nal_idx is not set properly in a callback - LASSERT (ev->unlinked_me.handle_idx == rqbd->rqbd_me_h.handle_idx); - LASSERT(ev->unlinked_me.handle_idx==rqbd->rqbd_me_h.handle_idx); -- -- /* we're off the air */ - if (atomic_dec_and_test (&service->srv_nrqbds_receiving)) { - CERROR ("All request buffers busy\n"); - /* we'll probably start dropping packets in portals soon */ - } - /* we'll probably start dropping packets in portals soon */ - if (atomic_dec_and_test(&service->srv_nrqbds_receiving)) - CERROR("All request buffers busy\n"); -- } else { -- /* +1 ref for service thread */ -- atomic_inc(&rqbd->rqbd_refcount); -- } -- -- wake_up(&service->srv_waitq); -- -- return 0; --} -- --static int bulk_source_callback(ptl_event_t *ev) --{ -- struct ptlrpc_bulk_desc *desc = ev->mem_desc.user_ptr; -- struct ptlrpc_bulk_page *bulk; -- struct list_head *tmp; -- struct list_head *next; -- ENTRY; -- -- CDEBUG(D_NET, "got %s event %d\n", -- (ev->type == PTL_EVENT_SENT) ? "SENT" : -- (ev->type == PTL_EVENT_ACK) ? "ACK" : "UNEXPECTED", ev->type); -- - LASSERT (ev->type == PTL_EVENT_SENT || ev->type == PTL_EVENT_ACK); - LASSERT(ev->type == PTL_EVENT_SENT || ev->type == PTL_EVENT_ACK); -- - LASSERT (atomic_read (&desc->bd_source_callback_count) > 0 && - atomic_read (&desc->bd_source_callback_count) <= 2); - LASSERT(atomic_read(&desc->bd_source_callback_count) > 0 && - atomic_read(&desc->bd_source_callback_count) <= 2); -- -- /* 1 fragment for each page always */ - LASSERT (ev->mem_desc.niov == desc->bd_page_count); - LASSERT(ev->mem_desc.niov == desc->bd_page_count); -- - if (atomic_dec_and_test (&desc->bd_source_callback_count)) { - if (atomic_dec_and_test(&desc->bd_source_callback_count)) { -- list_for_each_safe(tmp, next, &desc->bd_page_list) { -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, -- bp_link); -- -- if (bulk->bp_cb != NULL) -- bulk->bp_cb(bulk); -- } -- desc->bd_flags |= PTL_BULK_FL_SENT; -- wake_up(&desc->bd_waitq); -- if (desc->bd_ptl_ev_hdlr != NULL) - desc->bd_ptl_ev_hdlr(desc, desc->bd_ptl_ev_data); - desc->bd_ptl_ev_hdlr(desc); -- } -- -- RETURN(0); --} -- --static int bulk_sink_callback(ptl_event_t *ev) --{ -- struct ptlrpc_bulk_desc *desc = ev->mem_desc.user_ptr; -- struct ptlrpc_bulk_page *bulk; -- struct list_head *tmp; -- struct list_head *next; -- ptl_size_t total = 0; -- ENTRY; -- -- if (ev->type == PTL_EVENT_PUT) { -- /* put with zero offset */ - LASSERT (ev->offset == 0); - LASSERT(ev->offset == 0); -- /* used iovs */ - LASSERT ((ev->mem_desc.options & PTL_MD_IOV) != 0); - LASSERT((ev->mem_desc.options & PTL_MD_IOV) != 0); -- /* 1 fragment for each page always */ - LASSERT (ev->mem_desc.niov == desc->bd_page_count); - LASSERT(ev->mem_desc.niov == desc->bd_page_count); -- -- list_for_each_safe (tmp, next, &desc->bd_page_list) { -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, -- bp_link); -- -- total += bulk->bp_buflen; -- -- if (bulk->bp_cb != NULL) -- bulk->bp_cb(bulk); -- } -- - LASSERT (ev->mem_desc.length == total); - LASSERT(ev->mem_desc.length == total); -- -- desc->bd_flags |= PTL_BULK_FL_RCVD; -- wake_up(&desc->bd_waitq); -- if (desc->bd_ptl_ev_hdlr != NULL) - desc->bd_ptl_ev_hdlr(desc, desc->bd_ptl_ev_data); - desc->bd_ptl_ev_hdlr(desc); -- } else { -- CERROR("Unexpected event type!\n"); -- LBUG(); -- } -- -- RETURN(1); --} -- --int ptlrpc_init_portals(void) --{ -- int rc; -- ptl_handle_ni_t ni; -- -- /* Use the qswnal if it's there */ -- if ((qswnal_nip = inter_module_get("kqswnal_ni")) != NULL) -- ni = *qswnal_nip; -- else if ((gmnal_nip = inter_module_get("kgmnal_ni")) != NULL) -- ni = *gmnal_nip; -- else if ((socknal_nip = inter_module_get("ksocknal_ni")) != NULL) -- ni = *socknal_nip; -- else if ((toenal_nip = inter_module_get("ktoenal_ni")) != NULL) -- ni = *toenal_nip; -- else { -- CERROR("get_ni failed: is a NAL module loaded?\n"); -- return -EIO; -- } -- -- rc = PtlEQAlloc(ni, 1024, request_out_callback, &request_out_eq); -- if (rc != PTL_OK) -- CERROR("PtlEQAlloc failed: %d\n", rc); -- -- rc = PtlEQAlloc(ni, 1024, reply_out_callback, &reply_out_eq); -- if (rc != PTL_OK) -- CERROR("PtlEQAlloc failed: %d\n", rc); -- -- rc = PtlEQAlloc(ni, 1024, reply_in_callback, &reply_in_eq); -- if (rc != PTL_OK) -- CERROR("PtlEQAlloc failed: %d\n", rc); -- -- rc = PtlEQAlloc(ni, 1024, bulk_source_callback, &bulk_source_eq); -- if (rc != PTL_OK) -- CERROR("PtlEQAlloc failed: %d\n", rc); -- -- rc = PtlEQAlloc(ni, 1024, bulk_sink_callback, &bulk_sink_eq); -- if (rc != PTL_OK) -- CERROR("PtlEQAlloc failed: %d\n", rc); -- -- return rc; --} -- --void ptlrpc_exit_portals(void) --{ -- PtlEQFree(request_out_eq); -- PtlEQFree(reply_out_eq); -- PtlEQFree(reply_in_eq); -- PtlEQFree(bulk_source_eq); -- PtlEQFree(bulk_sink_eq); -- -- if (qswnal_nip != NULL) -- inter_module_put("kqswnal_ni"); -- if (socknal_nip != NULL) -- inter_module_put("ksocknal_ni"); -- if (gmnal_nip != NULL) -- inter_module_put("kgmnal_ni"); - if (toenal_nip != NULL) - inter_module_put("ktoenal_ni"); --} diff --cc lustre/ptlrpc/lproc_ptlrpc.c index a778b57,a778b57..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ /dev/null @@@ -1,52 -1,52 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#define DEBUG_SUBSYSTEM S_CLASS -- --#include --#include -- --int rd_uuid(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- int len = 0; -- len += snprintf(page, count, "%s\n", -- ((struct obd_device*)data)->obd_uuid); -- return len; --} -- --struct lprocfs_vars status_var_nm_1[] = { -- {"status/uuid", rd_uuid, 0, 0}, -- {0} --}; --int rd_numrefs(char* page, char **start, off_t off, int count, int *eof, -- void *data) --{ -- struct obd_type* class = (struct obd_type*)data; -- int len = 0; -- len += snprintf(page, count, "%d\n", class->typ_refcnt); -- return len; --} -- --struct lprocfs_vars status_class_var[] = { -- {"status/num_refs", rd_numrefs, 0, 0}, -- {0} --}; diff --cc lustre/ptlrpc/niobuf.c index c5777764,c2c2b32..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/niobuf.c +++ /dev/null @@@ -1,442 -1,488 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include --#include -- --extern ptl_handle_eq_t request_out_eq, reply_in_eq, reply_out_eq, -- bulk_source_eq, bulk_sink_eq; -- --static int ptl_send_buf(struct ptlrpc_request *request, -- struct ptlrpc_connection *conn, int portal) --{ -- int rc; -- ptl_process_id_t remote_id; -- ptl_handle_md_t md_h; -- -- LASSERT(conn); -- -- request->rq_req_md.user_ptr = request; -- -- switch (request->rq_type) { -- case PTL_RPC_MSG_REQUEST: -- request->rq_reqmsg->type = HTON__u32(request->rq_type); -- request->rq_req_md.start = request->rq_reqmsg; -- request->rq_req_md.length = request->rq_reqlen; -- request->rq_req_md.eventq = request_out_eq; -- break; -- case PTL_RPC_MSG_ERR: -- case PTL_RPC_MSG_REPLY: -- request->rq_repmsg->type = HTON__u32(request->rq_type); -- request->rq_req_md.start = request->rq_repmsg; -- request->rq_req_md.length = request->rq_replen; -- request->rq_req_md.eventq = reply_out_eq; -- break; -- default: -- LBUG(); -- return -1; /* notreached */ -- } -- request->rq_req_md.threshold = 1; -- request->rq_req_md.options = PTL_MD_OP_PUT; -- request->rq_req_md.user_ptr = request; -- -- rc = PtlMDBind(conn->c_peer.peer_ni, request->rq_req_md, &md_h); -- if (rc != 0) { -- CERROR("PtlMDBind failed: %d\n", rc); -- LBUG(); -- return rc; -- } -- -- remote_id.nid = conn->c_peer.peer_nid; -- remote_id.pid = 0; -- -- CDEBUG(D_NET, "Sending %d bytes to portal %d, xid "LPD64"\n", -- request->rq_req_md.length, portal, request->rq_xid); -- -- if (!portal) -- LBUG(); -- rc = PtlPut(md_h, PTL_NOACK_REQ, remote_id, portal, 0, request->rq_xid, -- 0, 0); -- if (rc != PTL_OK) { -- CERROR("PtlPut("LPU64", %d, "LPD64") failed: %d\n", -- remote_id.nid, portal, request->rq_xid, rc); -- PtlMDUnlink(md_h); -- } -- -- return rc; --} -- --static inline struct iovec * --ptlrpc_get_bulk_iov (struct ptlrpc_bulk_desc *desc) --{ -- struct iovec *iov; -- -- if (desc->bd_page_count <= sizeof (desc->bd_iov)/sizeof (struct iovec)) -- return (desc->bd_iov); -- -- OBD_ALLOC (iov, desc->bd_page_count * sizeof (struct iovec)); -- if (iov == NULL) -- LBUG(); -- -- return (iov); --} -- --static inline void --ptlrpc_put_bulk_iov (struct ptlrpc_bulk_desc *desc, struct iovec *iov) --{ -- if (desc->bd_page_count <= sizeof (desc->bd_iov)/sizeof (struct iovec)) -- return; -- -- OBD_FREE (iov, desc->bd_page_count * sizeof (struct iovec)); --} -- --int ptlrpc_send_bulk(struct ptlrpc_bulk_desc *desc) --{ -- int rc; -- struct list_head *tmp, *next; -- ptl_process_id_t remote_id; -- __u32 xid = 0; -- struct iovec *iov; -- ENTRY; -- -- iov = ptlrpc_get_bulk_iov (desc); -- if (iov == NULL) -- RETURN (-ENOMEM); -- -- desc->bd_md.start = iov; -- desc->bd_md.niov = 0; -- desc->bd_md.length = 0; -- desc->bd_md.eventq = bulk_source_eq; -- desc->bd_md.threshold = 2; /* SENT and ACK */ -- desc->bd_md.options = PTL_MD_OP_PUT | PTL_MD_IOV; -- desc->bd_md.user_ptr = desc; -- - atomic_set (&desc->bd_source_callback_count, 2); - atomic_set(&desc->bd_source_callback_count, 2); -- -- list_for_each_safe(tmp, next, &desc->bd_page_list) { -- struct ptlrpc_bulk_page *bulk; -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); -- - LASSERT (desc->bd_md.niov < desc->bd_page_count); - LASSERT(desc->bd_md.niov < desc->bd_page_count); -- -- if (desc->bd_md.niov == 0) -- xid = bulk->bp_xid; - LASSERT (xid == bulk->bp_xid); /* should all be the same */ - LASSERT(xid == bulk->bp_xid); /* should all be the same */ -- -- iov[desc->bd_md.niov].iov_base = bulk->bp_buf; -- iov[desc->bd_md.niov].iov_len = bulk->bp_buflen; -- desc->bd_md.niov++; -- desc->bd_md.length += bulk->bp_buflen; -- } -- - LASSERT (desc->bd_md.niov == desc->bd_page_count); - LASSERT (desc->bd_md.niov != 0); - LASSERT(desc->bd_md.niov == desc->bd_page_count); - LASSERT(desc->bd_md.niov != 0); -- -- rc = PtlMDBind(desc->bd_connection->c_peer.peer_ni, desc->bd_md, -- &desc->bd_md_h); -- -- ptlrpc_put_bulk_iov (desc, iov); /*move down to reduce latency to send*/ -- -- if (rc != PTL_OK) { -- CERROR("PtlMDBind failed: %d\n", rc); -- LBUG(); -- RETURN(rc); -- } -- -- remote_id.nid = desc->bd_connection->c_peer.peer_nid; -- remote_id.pid = 0; -- -- CDEBUG(D_NET, "Sending %u pages %u bytes to portal %d nid "LPX64" pid " -- "%d xid %d\n", desc->bd_md.niov, desc->bd_md.length, -- desc->bd_portal, remote_id.nid, remote_id.pid, xid); -- -- rc = PtlPut(desc->bd_md_h, PTL_ACK_REQ, remote_id, -- desc->bd_portal, 0, xid, 0, 0); -- if (rc != PTL_OK) { -- CERROR("PtlPut("LPU64", %d, %d) failed: %d\n", -- remote_id.nid, desc->bd_portal, xid, rc); -- PtlMDUnlink(desc->bd_md_h); -- LBUG(); -- RETURN(rc); -- } -- -- RETURN(0); --} -- --int ptlrpc_register_bulk(struct ptlrpc_bulk_desc *desc) --{ -- struct list_head *tmp, *next; -- int rc; -- __u32 xid = 0; -- struct iovec *iov; -- ptl_process_id_t source_id; -- ENTRY; -- -- if (desc->bd_page_count > PTL_MD_MAX_IOV) { -- CERROR("iov longer than %d pages not supported (count=%d)\n", -- PTL_MD_MAX_IOV, desc->bd_page_count); -- RETURN(-EINVAL); -- } -- -- iov = ptlrpc_get_bulk_iov (desc); -- if (iov == NULL) -- return (-ENOMEM); -- -- desc->bd_md.start = iov; -- desc->bd_md.niov = 0; -- desc->bd_md.length = 0; -- desc->bd_md.threshold = 1; -- desc->bd_md.options = PTL_MD_OP_PUT | PTL_MD_IOV; -- desc->bd_md.user_ptr = desc; -- desc->bd_md.eventq = bulk_sink_eq; -- -- list_for_each_safe(tmp, next, &desc->bd_page_list) { -- struct ptlrpc_bulk_page *bulk; -- bulk = list_entry(tmp, struct ptlrpc_bulk_page, bp_link); -- - LASSERT (desc->bd_md.niov < desc->bd_page_count); - LASSERT(desc->bd_md.niov < desc->bd_page_count); -- -- if (desc->bd_md.niov == 0) -- xid = bulk->bp_xid; - LASSERT (xid == bulk->bp_xid); /* should all be the same */ - LASSERT(xid == bulk->bp_xid); /* should all be the same */ -- -- iov[desc->bd_md.niov].iov_base = bulk->bp_buf; -- iov[desc->bd_md.niov].iov_len = bulk->bp_buflen; -- desc->bd_md.niov++; -- desc->bd_md.length += bulk->bp_buflen; -- } -- - LASSERT (desc->bd_md.niov == desc->bd_page_count); - LASSERT (desc->bd_md.niov != 0); - LASSERT(desc->bd_md.niov == desc->bd_page_count); - LASSERT(desc->bd_md.niov != 0); -- -- source_id.nid = desc->bd_connection->c_peer.peer_nid; -- source_id.pid = PTL_PID_ANY; -- -- rc = PtlMEAttach(desc->bd_connection->c_peer.peer_ni, -- desc->bd_portal, source_id, xid, 0, -- PTL_UNLINK, PTL_INS_AFTER, &desc->bd_me_h); -- -- if (rc != PTL_OK) { -- CERROR("PtlMEAttach failed: %d\n", rc); -- LBUG(); -- GOTO(cleanup, rc); -- } -- -- rc = PtlMDAttach(desc->bd_me_h, desc->bd_md, PTL_UNLINK, -- &desc->bd_md_h); -- if (rc != PTL_OK) { -- CERROR("PtlMDAttach failed: %d\n", rc); -- LBUG(); -- GOTO(cleanup, rc); -- } -- -- ptlrpc_put_bulk_iov (desc, iov); -- -- CDEBUG(D_NET, "Setup bulk sink buffers: %u pages %u bytes, xid %u, " -- "portal %u\n", desc->bd_md.niov, desc->bd_md.length, -- xid, desc->bd_portal); -- -- RETURN(0); -- -- cleanup: -- ptlrpc_put_bulk_iov (desc, iov); -- ptlrpc_abort_bulk(desc); -- -- return rc; --} -- --int ptlrpc_abort_bulk(struct ptlrpc_bulk_desc *desc) --{ -- /* This should be safe: these handles are initialized to be -- * invalid in ptlrpc_prep_bulk() */ -- PtlMDUnlink(desc->bd_md_h); -- PtlMEUnlink(desc->bd_me_h); -- -- return 0; -} - -void obd_brw_set_add(struct obd_brw_set *set, struct ptlrpc_bulk_desc *desc) -{ - atomic_inc(&desc->bd_refcount); - atomic_inc(&set->brw_refcount); - desc->bd_brw_set = set; - list_add(&desc->bd_set_chain, &set->brw_desc_head); -} - -struct obd_brw_set *obd_brw_set_new(void) -{ - struct obd_brw_set *set; - - OBD_ALLOC(set, sizeof(*set)); - - if (set != NULL) { - init_waitqueue_head(&set->brw_waitq); - INIT_LIST_HEAD(&set->brw_desc_head); - atomic_set(&set->brw_refcount, 0); - } - - return set; -} - -void obd_brw_set_free(struct obd_brw_set *set) -{ - struct list_head *tmp, *next; - ENTRY; - - if (!list_empty(&set->brw_desc_head)) { - EXIT; - return; - } - - list_for_each_safe(tmp, next, &set->brw_desc_head) { - struct ptlrpc_bulk_desc *desc = - list_entry(tmp, struct ptlrpc_bulk_desc, bd_set_chain); - - CERROR("Unfinished bulk descriptor: %p\n", desc); - - ptlrpc_abort_bulk(desc); - } - OBD_FREE(set, sizeof(*set)); - EXIT; - return; --} -- --int ptlrpc_reply(struct ptlrpc_service *svc, struct ptlrpc_request *req) --{ -- if (req->rq_repmsg == NULL) { -- CERROR("bad: someone called ptlrpc_reply when they meant " -- "ptlrpc_error\n"); -- return -EINVAL; -- } -- -- /* FIXME: we need to increment the count of handled events */ -- if (req->rq_type != PTL_RPC_MSG_ERR) -- req->rq_type = PTL_RPC_MSG_REPLY; -- //req->rq_repmsg->conn = req->rq_connection->c_remote_conn; -- //req->rq_repmsg->token = req->rq_connection->c_remote_token; -- req->rq_repmsg->status = HTON__u32(req->rq_status); -- return ptl_send_buf(req, req->rq_connection, svc->srv_rep_portal); --} -- --int ptlrpc_error(struct ptlrpc_service *svc, struct ptlrpc_request *req) --{ -- int rc; -- ENTRY; -- -- if (req->rq_repmsg) { -- CERROR("req already has repmsg\n"); -- LBUG(); -- } -- -- rc = lustre_pack_msg(0, NULL, NULL, &req->rq_replen, &req->rq_repmsg); -- if (rc) -- RETURN(rc); -- -- req->rq_type = PTL_RPC_MSG_ERR; -- -- rc = ptlrpc_reply(svc, req); -- RETURN(rc); --} -- --int ptl_send_rpc(struct ptlrpc_request *request) --{ -- int rc; -- char *repbuf; -- ptl_process_id_t source_id; -- -- ENTRY; -- -- if (request->rq_type != PTL_RPC_MSG_REQUEST) { -- CERROR("wrong packet type sent %d\n", -- NTOH__u32(request->rq_reqmsg->type)); -- LBUG(); -- RETURN(EINVAL); -- } -- -- source_id.nid = request->rq_connection->c_peer.peer_nid; -- source_id.pid = PTL_PID_ANY; -- -- /* add a ref, which will be balanced in request_out_callback */ -- atomic_inc(&request->rq_refcount); -- if (request->rq_replen != 0) { -- /* request->rq_repmsg is set only when the reply comes in, in -- * client_packet_callback() */ -- if (request->rq_reply_md.start) { -- PtlMEUnlink(request->rq_reply_me_h); -- OBD_FREE(request->rq_reply_md.start, -- request->rq_replen); -- /* If we're resending, rq_repmsg needs to be NULLed out -- * again so that ptlrpc_check_reply doesn't trip early. -- */ -- request->rq_repmsg = NULL; -- } -- OBD_ALLOC(repbuf, request->rq_replen); -- if (!repbuf) { -- LBUG(); -- RETURN(ENOMEM); -- } -- -- rc = PtlMEAttach(request->rq_connection->c_peer.peer_ni, -- request->rq_reply_portal,/* XXX FIXME bug 625069 */ -- source_id, request->rq_xid, 0, PTL_UNLINK, -- PTL_INS_AFTER, &request->rq_reply_me_h); -- if (rc != PTL_OK) { -- CERROR("PtlMEAttach failed: %d\n", rc); -- LBUG(); -- GOTO(cleanup, rc); -- } -- -- request->rq_reply_md.start = repbuf; -- request->rq_reply_md.length = request->rq_replen; -- request->rq_reply_md.threshold = 1; -- request->rq_reply_md.options = PTL_MD_OP_PUT; -- request->rq_reply_md.user_ptr = request; -- request->rq_reply_md.eventq = reply_in_eq; -- -- rc = PtlMDAttach(request->rq_reply_me_h, request->rq_reply_md, -- PTL_UNLINK, NULL); -- if (rc != PTL_OK) { -- CERROR("PtlMDAttach failed: %d\n", rc); -- LBUG(); -- GOTO(cleanup2, rc); -- } -- -- CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid "LPU64 -- ", portal %u\n", -- request->rq_replen, request->rq_xid, -- request->rq_reply_portal); -- } -- -- /* Clear any flags that may be present from previous sends, -- * except for REPLAY. */ -- request->rq_flags &= PTL_RPC_FL_REPLAY; -- rc = ptl_send_buf(request, request->rq_connection, -- request->rq_request_portal); -- RETURN(rc); -- -- cleanup2: -- PtlMEUnlink(request->rq_reply_me_h); -- cleanup: -- OBD_FREE(repbuf, request->rq_replen); -- // up(&request->rq_client->cli_rpc_sem); -- -- return rc; --} -- --void ptlrpc_link_svc_me(struct ptlrpc_request_buffer_desc *rqbd) --{ -- struct ptlrpc_service *service = rqbd->rqbd_service; -- static ptl_process_id_t match_id = {PTL_NID_ANY, PTL_PID_ANY}; -- int rc; -- ptl_md_t dummy; -- ptl_handle_md_t md_h; -- - LASSERT (atomic_read (&rqbd->rqbd_refcount) == 0); - LASSERT(atomic_read(&rqbd->rqbd_refcount) == 0); -- -- /* Attach the leading ME on which we build the ring */ -- rc = PtlMEAttach(service->srv_self.peer_ni, service->srv_req_portal, -- match_id, 0, ~0, -- PTL_UNLINK, PTL_INS_AFTER, &rqbd->rqbd_me_h); -- if (rc != PTL_OK) { -- CERROR("PtlMEAttach failed: %d\n", rc); -- LBUG(); -- } -- -- dummy.start = rqbd->rqbd_buffer; -- dummy.length = service->srv_buf_size; -- dummy.max_size = service->srv_max_req_size; -- dummy.threshold = PTL_MD_THRESH_INF; -- dummy.options = PTL_MD_OP_PUT | PTL_MD_MAX_SIZE | PTL_MD_AUTO_UNLINK; -- dummy.user_ptr = rqbd; -- dummy.eventq = service->srv_eq_h; -- - atomic_inc (&service->srv_nrqbds_receiving); - atomic_set (&rqbd->rqbd_refcount, 1); /* 1 ref for portals */ - atomic_inc(&service->srv_nrqbds_receiving); - atomic_set(&rqbd->rqbd_refcount, 1); /* 1 ref for portals */ -- -- rc = PtlMDAttach(rqbd->rqbd_me_h, dummy, PTL_UNLINK, &md_h); -- if (rc != PTL_OK) { -- CERROR("PtlMDAttach failed: %d\n", rc); -- LBUG(); --#warning proper cleanup required -- PtlMEUnlink (rqbd->rqbd_me_h); - atomic_set (&rqbd->rqbd_refcount, 0); - atomic_dec (&service->srv_nrqbds_receiving); - atomic_set(&rqbd->rqbd_refcount, 0); - atomic_dec(&service->srv_nrqbds_receiving); -- } --} diff --cc lustre/ptlrpc/pack_generic.c index dc537ec,49d79dc..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/pack_generic.c +++ /dev/null @@@ -1,137 -1,138 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * (Un)packing of OST requests -- * -- */ -- - #define DEBUG_SUBSYSTEM S_CLASS -#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include -- --int lustre_pack_msg(int count, int *lens, char **bufs, int *len, -- struct lustre_msg **msg) --{ -- char *ptr; -- struct lustre_msg *m; -- int size = 0, i; -- -- for (i = 0; i < count; i++) -- size += size_round(lens[i]); -- -- *len = size_round(sizeof(*m) + count * sizeof(__u32)) + size; -- -- OBD_ALLOC(*msg, *len); -- if (!*msg) -- RETURN(-ENOMEM); -- -- m = *msg; -- m->bufcount = HTON__u32(count); -- for (i = 0; i < count; i++) -- m->buflens[i] = HTON__u32(lens[i]); -- -- ptr = (char *)m + size_round(sizeof(*m) + count * sizeof(__u32)); -- for (i = 0; i < count; i++) { -- char *tmp = NULL; -- if (bufs) -- tmp = bufs[i]; -- LOGL(tmp, lens[i], ptr); -- } -- -- return 0; --} -- --/* This returns the size of the buffer that is required to hold a lustre_msg -- * with the given sub-buffer lengths. */ --int lustre_msg_size(int count, int *lengths) --{ -- int size = 0, i; -- -- for (i = 0; i < count; i++) -- size += size_round(lengths[i]); -- -- size += size_round(sizeof(struct lustre_msg) + count * sizeof(__u32)); -- -- return size; --} -- --int lustre_unpack_msg(struct lustre_msg *m, int len) --{ -- int required_len, i; - ENTRY; -- -- required_len = size_round(sizeof(*m)); -- if (len < required_len) -- RETURN(-EINVAL); -- -- m->opc = NTOH__u32(m->opc); -- m->status = NTOH__u32(m->status); -- m->type = NTOH__u32(m->type); -- m->bufcount = NTOH__u32(m->bufcount); -- m->last_xid = NTOH__u64(m->last_xid); -- m->last_committed = NTOH__u64(m->last_committed); -- -- required_len = size_round(sizeof(*m) + m->bufcount * sizeof(__u32)); -- if (len < required_len) -- RETURN(-EINVAL); -- -- for (i = 0; i < m->bufcount; i++) { -- m->buflens[i] = NTOH__u32(m->buflens[i]); -- required_len += size_round(m->buflens[i]); -- } -- -- if (len < required_len) { -- CERROR("len: %d, required_len %d\n", len, required_len); -- RETURN(-EINVAL); -- } -- -- RETURN(0); --} -- --void *lustre_msg_buf(struct lustre_msg *m, int n) --{ -- int i, offset; -- -- if (!m) { -- CERROR("no message buffer!\n"); -- LBUG(); -- return NULL; -- } -- -- if (n < 0 || n >= m->bufcount) { -- CERROR("referencing bad sub buffer in %p (want %d, count %d)!\n", -- m, n, m->bufcount); -- LBUG(); -- return NULL; -- } -- -- if (m->buflens[n] == 0) { -- CERROR("zero-length buffer requested for buffer %d in %p\n", n, -- m); -- return NULL; -- } -- -- offset = size_round(sizeof(*m) + m->bufcount * sizeof(__u32)); -- -- for (i = 0; i < n; i++) -- offset += size_round(m->buflens[i]); -- -- return (char *)m + offset; --} diff --cc lustre/ptlrpc/recovd.c index 1520cf9,0bbc4b0..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/recovd.c +++ /dev/null @@@ -1,361 -1,361 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * obd/rpc/recovd.c -- * -- * Lustre High Availability Daemon -- * -- * Copyright (C) 2001, 2002 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * -- * by Peter Braam -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include -- --/* dump_connection_list, but shorter for nicer debugging logs */ --static void d_c_l(struct list_head *head) --{ -- int sanity = 0; -- struct list_head *tmp; -- -- list_for_each(tmp, head) { -- struct ptlrpc_connection *conn = -- list_entry(tmp, struct ptlrpc_connection, -- c_recovd_data.rd_managed_chain); -- CDEBUG(D_HA, " %p = %s (%d/%d)\n", conn, conn->c_remote_uuid, -- conn->c_recovd_data.rd_phase, -- conn->c_recovd_data.rd_next_phase); -- if (sanity++ > 1000) -- LBUG(); -- } --} -- --static void dump_lists(struct recovd_obd *recovd) --{ -- CDEBUG(D_HA, "managed: \n"); -- d_c_l(&recovd->recovd_managed_items); -- CDEBUG(D_HA, "troubled: \n"); -- d_c_l(&recovd->recovd_troubled_items); --} -- --void recovd_conn_manage(struct ptlrpc_connection *conn, -- struct recovd_obd *recovd, ptlrpc_recovery_cb_t recover) --{ -- struct recovd_data *rd = &conn->c_recovd_data; -- ENTRY; -- if (!recovd || !recover) { -- EXIT; -- return; -- } -- -- if (!list_empty(&rd->rd_managed_chain)) { -- if (rd->rd_recovd == recovd && rd->rd_recover == recover) { -- CDEBUG(D_HA, "conn %p/%s already setup for recovery\n", -- conn, conn->c_remote_uuid); -- EXIT; -- return; -- } -- CDEBUG(D_HA, -- "conn %p/%s has recovery items %p/%p, making %p/%p\n", -- conn, conn->c_remote_uuid, rd->rd_recovd, rd->rd_recover, -- recovd, recover); -- spin_lock(&rd->rd_recovd->recovd_lock); -- list_del_init(&rd->rd_managed_chain); -- spin_unlock(&rd->rd_recovd->recovd_lock); -- } -- -- rd->rd_recovd = recovd; -- rd->rd_recover = recover; -- rd->rd_phase = RD_IDLE; -- rd->rd_next_phase = RD_TROUBLED; -- -- spin_lock(&recovd->recovd_lock); -- list_add(&rd->rd_managed_chain, &recovd->recovd_managed_items); -- dump_lists(recovd); -- spin_unlock(&recovd->recovd_lock); -- -- EXIT; --} -- --void recovd_conn_unmanage(struct ptlrpc_connection *conn) --{ -- struct recovd_data *rd = &conn->c_recovd_data; -- struct recovd_obd *recovd = rd->rd_recovd; -- ENTRY; -- -- if (recovd) { -- spin_lock(&recovd->recovd_lock); -- list_del_init(&rd->rd_managed_chain); -- rd->rd_recovd = NULL; -- spin_unlock(&recovd->recovd_lock); -- } -- /* should be safe enough, right? */ -- rd->rd_recover = NULL; -- rd->rd_next_phase = RD_IDLE; -- rd->rd_next_phase = RD_TROUBLED; --} -- --void recovd_conn_fail(struct ptlrpc_connection *conn) --{ -- struct recovd_data *rd = &conn->c_recovd_data; -- struct recovd_obd *recovd = rd->rd_recovd; -- ENTRY; -- -- if (!recovd) { -- CERROR("no recovd for connection %p\n", conn); -- EXIT; -- return; -- } -- -- spin_lock(&recovd->recovd_lock); -- if (rd->rd_phase == RD_TROUBLED || rd->rd_phase == RD_PREPARING) { -- CDEBUG(D_HA, "connection %p to %s already in recovery\n", -- conn, conn->c_remote_uuid); -- spin_unlock(&recovd->recovd_lock); -- EXIT; -- return; -- } -- - CERROR("connection %p to %s failed\n", conn, conn->c_remote_uuid); - CERROR("peer is %08x %08lx %08lx\n", conn->c_peer.peer_nid, - CERROR("connection %p to %s (%08x %08lx %08lx) failed\n", conn, - conn->c_remote_uuid, conn->c_peer.peer_nid, -- conn->c_peer.peer_ni.nal_idx, conn->c_peer.peer_ni.handle_idx); -- list_del(&rd->rd_managed_chain); -- list_add_tail(&rd->rd_managed_chain, &recovd->recovd_troubled_items); -- if (rd->rd_phase != RD_IDLE) { -- CDEBUG(D_HA, -- "connection %p to %s failed in recovery: restarting\n", -- conn, conn->c_remote_uuid); -- /* XXX call callback with PHASE_FAILED? */ -- rd->rd_next_phase = RD_TROUBLED; -- } -- rd->rd_phase = RD_TROUBLED; -- dump_lists(recovd); -- spin_unlock(&recovd->recovd_lock); -- -- wake_up(&recovd->recovd_waitq); -- -- EXIT; --} -- --void recovd_conn_fixed(struct ptlrpc_connection *conn) --{ -- struct recovd_data *rd = &conn->c_recovd_data; -- ENTRY; -- -- CDEBUG(D_HA, "connection %p (now to %s) fixed\n", -- conn, conn->c_remote_uuid); -- spin_lock(&rd->rd_recovd->recovd_lock); -- list_del(&rd->rd_managed_chain); -- rd->rd_phase = RD_IDLE; -- rd->rd_next_phase = RD_TROUBLED; -- list_add(&rd->rd_managed_chain, &rd->rd_recovd->recovd_managed_items); -- dump_lists(rd->rd_recovd); -- spin_unlock(&rd->rd_recovd->recovd_lock); -- -- EXIT; --} -- --static int recovd_check_event(struct recovd_obd *recovd) --{ -- int rc = 0; -- struct list_head *tmp; -- -- ENTRY; -- -- spin_lock(&recovd->recovd_lock); -- -- if (recovd->recovd_state == RECOVD_STOPPING) -- GOTO(out, rc = 1); -- -- list_for_each(tmp, &recovd->recovd_troubled_items) { -- -- struct recovd_data *rd = list_entry(tmp, struct recovd_data, -- rd_managed_chain); -- -- if (rd->rd_phase == rd->rd_next_phase || -- rd->rd_phase == RD_FAILED) -- GOTO(out, rc = 1); -- } -- -- out: -- spin_unlock(&recovd->recovd_lock); -- RETURN(rc); --} -- --static int recovd_handle_event(struct recovd_obd *recovd) --{ -- struct list_head *tmp, *n; -- int rc = 0; -- ENTRY; -- -- spin_lock(&recovd->recovd_lock); -- -- dump_lists(recovd); -- -- /* -- * We use _safe here because one of the callbacks, expecially -- * FAILURE or PREPARED, could move list items around. -- */ -- list_for_each_safe(tmp, n, &recovd->recovd_troubled_items) { -- struct recovd_data *rd = list_entry(tmp, struct recovd_data, -- rd_managed_chain); -- -- if (rd->rd_phase != RD_FAILED && -- rd->rd_phase != rd->rd_next_phase) -- continue; -- -- switch (rd->rd_phase) { -- case RD_FAILED: -- cb_failed: /* must always reach here with recovd_lock held! */ -- CERROR("recovery FAILED for rd %p (conn %p): %d\n", -- rd, class_rd2conn(rd), rc); -- -- spin_unlock(&recovd->recovd_lock); -- (void)rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_FAILURE); -- spin_lock(&recovd->recovd_lock); -- break; -- -- case RD_TROUBLED: -- if (!rd->rd_recover) { -- CERROR("no rd_recover for rd %p (conn %p)\n", -- rd, class_rd2conn(rd)); -- rc = -EINVAL; -- break; -- } -- CERROR("starting recovery for rd %p (conn %p)\n", -- rd, class_rd2conn(rd)); -- rd->rd_phase = RD_PREPARING; -- rd->rd_next_phase = RD_PREPARED; -- -- spin_unlock(&recovd->recovd_lock); -- rc = rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_PREPARE); -- spin_lock(&recovd->recovd_lock); -- if (rc) -- goto cb_failed; -- -- break; -- -- case RD_PREPARED: -- -- CERROR("recovery prepared for rd %p (conn %p)\n", -- rd, class_rd2conn(rd)); -- rd->rd_phase = RD_RECOVERING; -- rd->rd_next_phase = RD_RECOVERED; -- -- spin_unlock(&recovd->recovd_lock); -- rc = rd->rd_recover(rd, PTLRPC_RECOVD_PHASE_RECOVER); -- spin_lock(&recovd->recovd_lock); -- if (rc) -- goto cb_failed; -- -- break; -- -- case RD_RECOVERED: -- rd->rd_phase = RD_IDLE; -- rd->rd_next_phase = RD_TROUBLED; -- -- CERROR("recovery complete for rd %p (conn %p)\n", -- rd, class_rd2conn(rd)); -- break; -- -- default: -- break; -- } -- } -- spin_unlock(&recovd->recovd_lock); -- RETURN(0); --} -- --static int recovd_main(void *arg) --{ -- struct recovd_obd *recovd = (struct recovd_obd *)arg; -- -- ENTRY; -- -- lock_kernel(); -- daemonize(); -- --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -- sigfillset(¤t->blocked); -- recalc_sigpending(); --#else -- spin_lock_irq(¤t->sigmask_lock); -- sigfillset(¤t->blocked); -- recalc_sigpending(current); -- spin_unlock_irq(¤t->sigmask_lock); --#endif -- -- sprintf(current->comm, "lustre_recovd"); -- unlock_kernel(); -- -- /* Signal that the thread is running. */ -- recovd->recovd_thread = current; -- recovd->recovd_state = RECOVD_READY; -- wake_up(&recovd->recovd_ctl_waitq); -- -- /* And now, loop forever on requests. */ -- while (1) { -- wait_event(recovd->recovd_waitq, recovd_check_event(recovd)); -- if (recovd->recovd_state == RECOVD_STOPPING) -- break; -- recovd_handle_event(recovd); -- } -- -- recovd->recovd_thread = NULL; -- recovd->recovd_state = RECOVD_STOPPED; -- wake_up(&recovd->recovd_ctl_waitq); -- CDEBUG(D_HA, "mgr exiting process %d\n", current->pid); -- RETURN(0); --} -- --int recovd_setup(struct recovd_obd *recovd) --{ -- int rc; -- -- ENTRY; -- -- INIT_LIST_HEAD(&recovd->recovd_managed_items); -- INIT_LIST_HEAD(&recovd->recovd_troubled_items); -- spin_lock_init(&recovd->recovd_lock); -- -- init_waitqueue_head(&recovd->recovd_waitq); -- init_waitqueue_head(&recovd->recovd_recovery_waitq); -- init_waitqueue_head(&recovd->recovd_ctl_waitq); -- -- rc = kernel_thread(recovd_main, (void *)recovd, -- CLONE_VM | CLONE_FS | CLONE_FILES); -- if (rc < 0) { -- CERROR("cannot start thread\n"); -- RETURN(-EINVAL); -- } -- wait_event(recovd->recovd_ctl_waitq, -- recovd->recovd_state == RECOVD_READY); -- -- ptlrpc_recovd = recovd; -- class_signal_connection_failure = recovd_conn_fail; -- -- RETURN(0); --} -- --int recovd_cleanup(struct recovd_obd *recovd) --{ -- ENTRY; -- spin_lock(&recovd->recovd_lock); -- recovd->recovd_state = RECOVD_STOPPING; -- wake_up(&recovd->recovd_waitq); -- spin_unlock(&recovd->recovd_lock); -- -- wait_event(recovd->recovd_ctl_waitq, -- (recovd->recovd_state == RECOVD_STOPPED)); -- RETURN(0); --} -- --struct recovd_obd *ptlrpc_recovd; diff --cc lustre/ptlrpc/recover.c index 060258f,acdecf8..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/recover.c +++ /dev/null @@@ -1,264 -1,277 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Portal-RPC reconnection and replay operations, for use in recovery. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- * - * Copryright (C) 1996 Peter J. Braam - * Copryright (C) 1999 Stelias Computing Inc. - * Copryright (C) 1999 Seagate Technology Inc. - * Copryright (C) 2001 Mountain View Data, Inc. - * Copryright (C) 2002 Cluster File Systems, Inc. - * Copyright (C) 1996 Peter J. Braam - * Copyright (C) 1999 Stelias Computing Inc. - * Copyright (C) 1999 Seagate Technology Inc. - * Copyright (C) 2001 Mountain View Data, Inc. - * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- */ -- --#include --#include --#include -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include -- --int ptlrpc_reconnect_import(struct obd_import *imp, int rq_opc) --{ -- struct obd_device *obd = imp->imp_obd; -- struct client_obd *cli = &obd->u.cli; -- int size[] = { sizeof(cli->cl_target_uuid), sizeof(obd->obd_uuid) }; -- char *tmp[] = {cli->cl_target_uuid, obd->obd_uuid }; -- struct ptlrpc_connection *conn = imp->imp_connection; -- struct lustre_handle old_hdl; - struct ptlrpc_request *request; - struct ptlrpc_request *request; -- struct obd_export *ldlmexp; -- int rc; -- -- request = ptlrpc_prep_req(imp, rq_opc, 2, size, tmp); -- request->rq_level = LUSTRE_CONN_NEW; -- request->rq_replen = lustre_msg_size(0, NULL); -- /* - -- * This address is the export that represents our client-side LDLM -- * service (for ASTs). We should only have one on this list, so we -- * just grab the first one. -- * -- * XXX tear down export, call class_obd_connect? -- */ -- ldlmexp = list_entry(obd->obd_exports.next, struct obd_export, -- exp_obd_chain); -- request->rq_reqmsg->addr = (__u64)(unsigned long)ldlmexp; -- request->rq_reqmsg->cookie = ldlmexp->exp_cookie; -- rc = ptlrpc_queue_wait(request); - rc = ptlrpc_check_status(request, rc); - if (rc) { - switch (rc) { - case EALREADY: - case -EALREADY: - /* already connected! */ - memset(&old_hdl, 0, sizeof(old_hdl)); - if (!memcmp(&old_hdl.addr, &request->rq_repmsg->addr, - sizeof (old_hdl.addr)) && - !memcmp(&old_hdl.cookie, &request->rq_repmsg->cookie, - sizeof (old_hdl.cookie))) { - CERROR("%s@%s didn't like our handle %Lx/%Lx, failed\n", - cli->cl_target_uuid, conn->c_remote_uuid, - (__u64)(unsigned long)ldlmexp, - ldlmexp->exp_cookie); - GOTO(out_disc, rc = -ENOTCONN); - } - - old_hdl.addr = request->rq_repmsg->addr; - old_hdl.cookie = request->rq_repmsg->cookie; - if (memcmp(&imp->imp_handle, &old_hdl, sizeof(old_hdl))) { - CERROR("%s@%s changed handle from %Lx/%Lx to %Lx/%Lx; " - "copying, but this may foreshadow disaster\n", - cli->cl_target_uuid, conn->c_remote_uuid, - old_hdl.addr, old_hdl.cookie, - imp->imp_handle.addr, imp->imp_handle.cookie); - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - GOTO(out_disc, rc = EALREADY); - } - - CERROR("reconnected to %s@%s after partition\n", - cli->cl_target_uuid, conn->c_remote_uuid); - GOTO(out_disc, rc = EALREADY); - case 0: - old_hdl = imp->imp_handle; - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - CERROR("now connected to %s@%s (%Lx/%Lx, was %Lx/%Lx)!\n", - cli->cl_target_uuid, conn->c_remote_uuid, - imp->imp_handle.addr, imp->imp_handle.cookie, - old_hdl.addr, old_hdl.cookie); - GOTO(out_disc, rc = 0); - default: -- CERROR("cannot connect to %s@%s: rc = %d\n", -- cli->cl_target_uuid, conn->c_remote_uuid, rc); - ptlrpc_free_req(request); - GOTO(out_disc, rc = -ENOTCONN); - GOTO(out_disc, rc = -ENOTCONN); /* XXX preserve rc? */ -- } - - old_hdl = imp->imp_handle; - imp->imp_handle.addr = request->rq_repmsg->addr; - imp->imp_handle.cookie = request->rq_repmsg->cookie; - CERROR("reconnected to %s@%s (%Lx/%Lx, was %Lx/%Lx)!\n", - cli->cl_target_uuid, conn->c_remote_uuid, - imp->imp_handle.addr, imp->imp_handle.cookie, - old_hdl.addr, old_hdl.cookie); - ptlrpc_req_finished(request); -- -- out_disc: - ptlrpc_req_finished(request); -- return rc; --} -- --int ptlrpc_run_recovery_upcall(struct ptlrpc_connection *conn) --{ -- char *argv[3]; -- char *envp[3]; -- int rc; -- -- ENTRY; - conn->c_level = LUSTRE_CONN_RECOVD; - -- argv[0] = obd_recovery_upcall; -- argv[1] = conn->c_remote_uuid; -- argv[2] = NULL; -- -- envp[0] = "HOME=/"; -- envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; -- envp[2] = NULL; -- -- rc = call_usermodehelper(argv[0], argv, envp); -- if (rc < 0) { -- CERROR("Error invoking recovery upcall %s for %s: %d\n", -- argv[0], argv[1], rc); -- CERROR("Check /proc/sys/lustre/recovery_upcall?\n"); -- } else { -- CERROR("Invoked upcall %s for connection %s\n", -- argv[0], argv[1]); -- } -- -- /* -- * We don't want to make this a "failed" recovery, because the system -- * administrator -- or, perhaps, tester -- may well be able to rescue -- * things by running the correct upcall. -- */ -- RETURN(0); --} - - #define REPLAY_COMMITTED 0 /* Fully processed (commit + reply). */ - #define REPLAY_REPLAY 1 /* Forced-replay (e.g. open). */ - #define REPLAY_RESEND 2 /* Resend required. */ - #define REPLAY_RESEND_IGNORE 3 /* Resend, ignore the reply (already saw it). */ - #define REPLAY_RESTART 4 /* Have to restart the call, sorry! */ - #define REPLAY_NO_STATE 5 /* Request doesn't change MDS state: skip. */ -- - static int replay_state(struct ptlrpc_request *req, __u64 last_xid) -int ptlrpc_replay(struct obd_import *imp, int send_last_flag) --{ - /* This request must always be replayed. */ - if (req->rq_flags & PTL_RPC_FL_REPLAY) - return REPLAY_REPLAY; - int rc = 0; - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - __u64 committed = imp->imp_peer_committed_transno; - ENTRY; -- - /* Uncommitted request */ - if (req->rq_xid > last_xid) { - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - if (req->rq_transno == 0) { - /* If no transno was returned, no state was - altered on the MDS. */ - return REPLAY_NO_STATE; - } - /* It might have committed some after we last spoke, so make sure we - * get rid of them now. - */ - spin_lock(&imp->imp_lock); -- - /* Saw reply, so resend and ignore new reply. */ - return REPLAY_RESEND_IGNORE; - } - ptlrpc_free_committed(imp); -- - /* Didn't see reply either, so resend. */ - return REPLAY_RESEND; - CDEBUG(D_HA, "import %p from %s has committed "LPD64"\n", - imp, imp->imp_obd->u.cli.cl_target_uuid, committed); - - list_for_each(tmp, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "RETAINED: "); -- } -- - /* This request has been committed and we saw the reply. Goodbye! */ - if (req->rq_flags & PTL_RPC_FL_REPLIED) - return REPLAY_COMMITTED; - list_for_each_safe(tmp, pos, &imp->imp_replay_list) { - req = list_entry(tmp, struct ptlrpc_request, rq_list); -- - /* Request committed, but we didn't see the reply: have to restart. */ - return REPLAY_RESTART; - if (req->rq_transno == imp->imp_max_transno && - send_last_flag) { - req->rq_reqmsg->flags |= MSG_LAST_REPLAY; - DEBUG_REQ(D_HA, req, "LAST_REPLAY:"); - } else { - DEBUG_REQ(D_HA, req, "REPLAY:"); - } - - rc = ptlrpc_replay_req(req); - req->rq_reqmsg->flags &= ~MSG_LAST_REPLAY; - - if (rc) { - CERROR("recovery replay error %d for req %Ld\n", - rc, req->rq_xid); - GOTO(out, rc); - } - } - - out: - spin_unlock(&imp->imp_lock); - return rc; --} -- - static char *replay_state2str(int state) { - static char *state_strings[] = { - "COMMITTED", "REPLAY", "RESEND", "RESEND_IGNORE", "RESTART", - "NO_STATE" - }; - static char *unknown_state = "UNKNOWN"; -#define NO_RESEND 0 /* No action required. */ -#define RESEND 1 /* Resend required. */ -#define RESEND_IGNORE 2 /* Resend, ignore the reply (already saw it). */ -#define RESTART 3 /* Have to restart the call, sorry! */ -- - if (state < 0 || - state > (sizeof(state_strings) / sizeof(state_strings[0]))) { - return unknown_state; -static int resend_type(struct ptlrpc_request *req, __u64 committed) -{ - if (req->rq_transno < committed) { - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - /* Saw the reply and it was committed, no biggie. */ - DEBUG_REQ(D_HA, req, "NO_RESEND"); - return NO_RESEND; - } - /* Request committed, but no reply: have to restart. */ - return RESTART; -- } -- - return state_strings[state]; - if (req->rq_flags & PTL_RPC_FL_REPLIED) { - /* Saw reply, so resend and ignore new reply. */ - return RESEND_IGNORE; - } - - /* Didn't see reply either, so resend. */ - return RESEND; - --} -- - int ptlrpc_replay(struct ptlrpc_connection *conn) -int ptlrpc_resend(struct obd_import *imp) --{ -- int rc = 0; -- struct list_head *tmp, *pos; -- struct ptlrpc_request *req; - ENTRY; - - spin_lock(&conn->c_lock); - - CDEBUG(D_HA, "connection %p to %s has last_xid "LPD64"\n", - conn, conn->c_remote_uuid, conn->c_last_xid); - __u64 committed = imp->imp_peer_committed_transno; -- - list_for_each(tmp, &conn->c_sending_head) { - int state; - req = list_entry(tmp, struct ptlrpc_request, rq_list); - state = replay_state(req, conn->c_last_xid); - DEBUG_REQ(D_HA, req, "SENDING: %s: ", replay_state2str(state)); - } - ENTRY; -- - list_for_each(tmp, &conn->c_delayed_head) { - int state; - spin_lock(&imp->imp_lock); - list_for_each(tmp, &imp->imp_sending_list) { -- req = list_entry(tmp, struct ptlrpc_request, rq_list); - state = replay_state(req, conn->c_last_xid); - DEBUG_REQ(D_HA, req, "DELAYED: "); - DEBUG_REQ(D_HA, req, "SENDING: "); -- } -- - list_for_each_safe(tmp, pos, &conn->c_sending_head) { - list_for_each_safe(tmp, pos, &imp->imp_sending_list) { -- req = list_entry(tmp, struct ptlrpc_request, rq_list); - - switch (replay_state(req, conn->c_last_xid)) { - case REPLAY_REPLAY: - DEBUG_REQ(D_HA, req, "REPLAY:"); - rc = ptlrpc_replay_req(req); - #if 0 - #error We should not hold a spinlock over such a lengthy operation. - #error If necessary, drop spinlock, do operation, re-get spinlock, restart loop. - #error If we need to avoid re-processint items, then delete them from the list - #error as they are replayed and re-add at the tail of this list, so the next - #error item to process will always be at the head of the list. - #endif - if (rc) { - CERROR("recovery replay error %d for req %Ld\n", - rc, req->rq_xid); - GOTO(out, rc); - } - break; - -- - case REPLAY_COMMITTED: - DEBUG_REQ(D_HA, req, "COMMITTED:"); - /* XXX commit now? */ - switch(resend_type(req, committed)) { - case NO_RESEND: -- break; -- - case REPLAY_NO_STATE: - DEBUG_REQ(D_HA, req, "NO_STATE:"); - /* XXX commit now? */ - case RESTART: - DEBUG_REQ(D_HA, req, "RESTART:"); - ptlrpc_restart_req(req); -- break; -- - case REPLAY_RESEND_IGNORE: - case RESEND_IGNORE: -- DEBUG_REQ(D_HA, req, "RESEND_IGNORE:"); - rc = ptlrpc_replay_req(req); - rc = ptlrpc_replay_req(req); -- if (rc) { - CERROR("request resend error %d for req %Ld\n", - rc, req->rq_xid); - GOTO(out, rc); - DEBUG_REQ(D_ERROR, req, "error %d resending:", - rc); - ptlrpc_restart_req(req); /* might as well */ -- } - break; - - case REPLAY_RESTART: - DEBUG_REQ(D_HA, req, "RESTART:"); - ptlrpc_restart_req(req); -- break; -- - case REPLAY_RESEND: - case RESEND: -- DEBUG_REQ(D_HA, req, "RESEND:"); -- ptlrpc_resend_req(req); -- break; -- -- default: -- LBUG(); -- } - -- } -- - conn->c_level = LUSTRE_CONN_FULL; - recovd_conn_fixed(conn); - RETURN(rc); -} -- - CERROR("recovery complete on conn %p(%s), waking delayed reqs\n", - conn, conn->c_remote_uuid); - /* Finally, continue processing requests that blocked for recovery. */ - list_for_each_safe(tmp, pos, &conn->c_delayed_head) { -void ptlrpc_wake_delayed(struct obd_import *imp) -{ - struct list_head *tmp, *pos; - struct ptlrpc_request *req; - - spin_lock(&imp->imp_lock); - list_for_each_safe(tmp, pos, &imp->imp_delayed_list) { -- req = list_entry(tmp, struct ptlrpc_request, rq_list); - DEBUG_REQ(D_HA, req, "WAKING: "); - ptlrpc_continue_req(req); - DEBUG_REQ(D_HA, req, "waking:"); - wake_up(&req->rq_wait_for_rep); -- } - - EXIT; - out: - spin_unlock(&conn->c_lock); - return rc; - spin_unlock(&imp->imp_lock); --} diff --cc lustre/ptlrpc/rpc.c index b4cd0be,eb6acb1..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/rpc.c +++ /dev/null @@@ -1,277 -1,283 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define EXPORT_SYMTAB --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include --#include --#include --#include --#include --#include -- -- -- --extern int ptlrpc_init_portals(void); --extern void ptlrpc_exit_portals(void); -- --extern struct lprocfs_vars status_var_nm_1[]; --extern struct lprocfs_vars status_class_var[]; -- --int connmgr_setup(struct obd_device *obddev, obd_count len, void *buf) --{ -- struct recovd_obd *recovd = &obddev->u.recovd; -- int err; -- ENTRY; -- -- MOD_INC_USE_COUNT; -- memset(recovd, 0, sizeof(*recovd)); -- -- err = recovd_setup(recovd); -- if (err) { -- MOD_DEC_USE_COUNT; -- RETURN(err); -- } -- -- RETURN(0); --} -- --int connmgr_cleanup(struct obd_device *dev) --{ -- struct recovd_obd *recovd = &dev->u.recovd; -- int err; -- -- err = recovd_cleanup(recovd); -- if (err) -- LBUG(); -- -- MOD_DEC_USE_COUNT; -- RETURN(0); --} -- - int connmgr_iocontrol(long cmd, struct lustre_handle *hdl, int len, void *karg, -int connmgr_iocontrol(unsigned int cmd, struct lustre_handle *hdl, int len, void *karg, -- void *uarg) --{ -- struct ptlrpc_connection *conn = NULL; -- struct obd_device *obd = class_conn2obd(hdl); -- struct recovd_obd *recovd = &obd->u.recovd; -- struct obd_ioctl_data *data = karg; -- struct list_head *tmp; -- int rc = 0; -- -- ENTRY; -- -- if (cmd != OBD_IOC_RECOVD_NEWCONN && cmd != OBD_IOC_RECOVD_FAILCONN) -- RETURN(-EINVAL); /* XXX ENOSYS? */ -- -- /* Find the connection that's been rebuilt or has failed. */ -- spin_lock(&recovd->recovd_lock); -- list_for_each(tmp, &recovd->recovd_troubled_items) { -- conn = list_entry(tmp, struct ptlrpc_connection, -- c_recovd_data.rd_managed_chain); -- -- LASSERT(conn->c_recovd_data.rd_recovd == recovd); /* sanity */ -- -- if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1)) -- break; -- conn = NULL; -- } -- -- if (!conn) { -- if (cmd == OBD_IOC_RECOVD_NEWCONN) -- GOTO(out, rc = -EINVAL); -- /* XXX macroize/inline and share with loop above */ -- list_for_each(tmp, &recovd->recovd_managed_items) { -- conn = list_entry(tmp, struct ptlrpc_connection, -- c_recovd_data.rd_managed_chain); -- -- LASSERT(conn->c_recovd_data.rd_recovd == recovd); -- -- if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1)) -- break; -- conn = NULL; -- } -- if (!conn) -- GOTO(out, rc = -EINVAL); -- } -- -- if (cmd == OBD_IOC_RECOVD_FAILCONN) { -- spin_unlock(&recovd->recovd_lock); -- recovd_conn_fail(conn); -- spin_lock(&recovd->recovd_lock); -- -- /* Jump straight to the "failed" phase of recovery. */ -- conn->c_recovd_data.rd_phase = RD_FAILED; -- goto out; -- } -- -- -- /* else (NEWCONN) */ -- spin_lock(&conn->c_lock); -- -- /* whatever happens, reset the INVALID flag */ -- conn->c_flags &= ~CONN_INVALID; -- -- /* XXX is this a good check? should we allow readdressing of -- * XXX conns that aren't in recovery? -- */ -- if (conn->c_recovd_data.rd_phase != RD_PREPARING) { -- spin_unlock(&conn->c_lock); -- GOTO(out, rc = -EALREADY); -- } -- -- if (data->ioc_inllen2) { -- CERROR("conn %p UUID change %s -> %s\n", -- conn, conn->c_remote_uuid, data->ioc_inlbuf2); -- strcpy(conn->c_remote_uuid, data->ioc_inlbuf2); -- } else { -- CERROR("conn %p UUID %s reconnected\n", conn, -- conn->c_remote_uuid); -- } -- ptlrpc_readdress_connection(conn, conn->c_remote_uuid); -- spin_unlock(&conn->c_lock); -- -- conn->c_recovd_data.rd_phase = RD_PREPARED; -- wake_up(&recovd->recovd_waitq); -- out: -- spin_unlock(&recovd->recovd_lock); -- RETURN(rc); --} -- --static int connmgr_connect(struct lustre_handle *conn, struct obd_device *src, -- obd_uuid_t cluuid, struct recovd_obd *recovd, -- ptlrpc_recovery_cb_t recover) --{ -- return class_connect(conn, src, cluuid); --} - --int connmgr_attach(struct obd_device *dev, obd_count len, void *data) --{ -- return lprocfs_reg_obd(dev, status_var_nm_1, dev); --} -- --int conmgr_detach(struct obd_device *dev) --{ -- return lprocfs_dereg_obd(dev); --} --/* use obd ops to offer management infrastructure */ --static struct obd_ops recovd_obd_ops = { -- o_attach: connmgr_attach, -- o_detach: conmgr_detach, -- o_setup: connmgr_setup, -- o_cleanup: connmgr_cleanup, -- o_iocontrol: connmgr_iocontrol, -- o_connect: connmgr_connect, -- o_disconnect: class_disconnect --}; -- --static int __init ptlrpc_init(void) --{ -- int rc; -- rc = ptlrpc_init_portals(); -- if (rc) -- RETURN(rc); -- ptlrpc_init_connection(); -- rc = class_register_type(&recovd_obd_ops, status_class_var, -- LUSTRE_HA_NAME); -- if (rc) -- RETURN(rc); -- ptlrpc_put_connection_superhack = ptlrpc_put_connection; -- return 0; --} -- --static void __exit ptlrpc_exit(void) --{ -- class_unregister_type(LUSTRE_HA_NAME); -- ptlrpc_exit_portals(); -- ptlrpc_cleanup_connection(); --} -- --/* recovd.c */ --EXPORT_SYMBOL(ptlrpc_recovd); --EXPORT_SYMBOL(recovd_conn_fail); --EXPORT_SYMBOL(recovd_conn_manage); --EXPORT_SYMBOL(recovd_conn_fixed); --EXPORT_SYMBOL(recovd_setup); --EXPORT_SYMBOL(recovd_cleanup); -- --/* connection.c */ --EXPORT_SYMBOL(ptlrpc_readdress_connection); --EXPORT_SYMBOL(ptlrpc_get_connection); --EXPORT_SYMBOL(ptlrpc_put_connection); --EXPORT_SYMBOL(ptlrpc_connection_addref); --EXPORT_SYMBOL(ptlrpc_init_connection); --EXPORT_SYMBOL(ptlrpc_cleanup_connection); -- --/* niobuf.c */ --EXPORT_SYMBOL(ptlrpc_send_bulk); --EXPORT_SYMBOL(ptlrpc_register_bulk); --EXPORT_SYMBOL(ptlrpc_abort_bulk); --EXPORT_SYMBOL(ptlrpc_reply); --EXPORT_SYMBOL(ptlrpc_error); --EXPORT_SYMBOL(ptlrpc_resend_req); --EXPORT_SYMBOL(ptl_send_rpc); --EXPORT_SYMBOL(ptlrpc_link_svc_me); -EXPORT_SYMBOL(obd_brw_set_free); -EXPORT_SYMBOL(obd_brw_set_new); -EXPORT_SYMBOL(obd_brw_set_add); -- --/* client.c */ --EXPORT_SYMBOL(ptlrpc_init_client); --EXPORT_SYMBOL(ptlrpc_cleanup_client); --EXPORT_SYMBOL(ptlrpc_req_to_uuid); --EXPORT_SYMBOL(ptlrpc_uuid_to_connection); --EXPORT_SYMBOL(ptlrpc_queue_wait); --EXPORT_SYMBOL(ptlrpc_continue_req); --EXPORT_SYMBOL(ptlrpc_replay_req); --EXPORT_SYMBOL(ptlrpc_restart_req); --EXPORT_SYMBOL(ptlrpc_prep_req); --EXPORT_SYMBOL(ptlrpc_free_req); --EXPORT_SYMBOL(ptlrpc_req_finished); --EXPORT_SYMBOL(ptlrpc_prep_bulk); --EXPORT_SYMBOL(ptlrpc_free_bulk); --EXPORT_SYMBOL(ptlrpc_prep_bulk_page); --EXPORT_SYMBOL(ptlrpc_free_bulk_page); - EXPORT_SYMBOL(ptlrpc_check_status); -EXPORT_SYMBOL(ll_brw_sync_wait); -- --/* service.c */ --EXPORT_SYMBOL(ptlrpc_init_svc); --EXPORT_SYMBOL(ptlrpc_stop_all_threads); --EXPORT_SYMBOL(ptlrpc_start_thread); --EXPORT_SYMBOL(ptlrpc_unregister_service); -- --/* pack_generic.c */ --EXPORT_SYMBOL(lustre_pack_msg); --EXPORT_SYMBOL(lustre_msg_size); --EXPORT_SYMBOL(lustre_unpack_msg); --EXPORT_SYMBOL(lustre_msg_buf); -- --/* recover.c */ --EXPORT_SYMBOL(ptlrpc_run_recovery_upcall); --EXPORT_SYMBOL(ptlrpc_reconnect_import); --EXPORT_SYMBOL(ptlrpc_replay); -EXPORT_SYMBOL(ptlrpc_resend); -EXPORT_SYMBOL(ptlrpc_wake_delayed); -- --MODULE_AUTHOR("Cluster File Systems, Inc "); --MODULE_DESCRIPTION("Lustre Request Processor v1.0"); --MODULE_LICENSE("GPL"); -- --module_init(ptlrpc_init); --module_exit(ptlrpc_exit); diff --cc lustre/ptlrpc/service.c index 5e6a626,1688ff9..0000000 deleted file mode 100644,100644 --- a/lustre/ptlrpc/service.c +++ /dev/null @@@ -1,425 -1,442 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#define DEBUG_SUBSYSTEM S_RPC -- --#include --#include --#include -- --extern int request_in_callback(ptl_event_t *ev); -- --static int ptlrpc_check_event(struct ptlrpc_service *svc, -- struct ptlrpc_thread *thread, ptl_event_t *event) --{ -- int rc; -- ENTRY; -- -- spin_lock(&svc->srv_lock); -- -- if (thread->t_flags & SVC_STOPPING) -- GOTO(out, rc = 1); -- -- LASSERT ((thread->t_flags & SVC_EVENT) == 0); -- LASSERT (ptl_is_valid_handle (&svc->srv_eq_h)); -- -- rc = PtlEQGet(svc->srv_eq_h, event); -- switch (rc) -- { -- case PTL_OK: -- thread->t_flags |= SVC_EVENT; -- GOTO(out, rc = 1); - - -- case PTL_EQ_EMPTY: -- GOTO(out, rc = 0); - - -- default: -- CERROR("BUG: PtlEQGet returned %d\n", rc); -- LBUG(); -- } -- out: -- spin_unlock(&svc->srv_lock); -- return rc; --} -- --struct ptlrpc_service * --ptlrpc_init_svc(__u32 nevents, __u32 nbufs, -- __u32 bufsize, __u32 max_req_size, -- int req_portal, int rep_portal, -- obd_uuid_t uuid, svc_handler_t handler, char *name) --{ -- int err; -- int rc, i; -- struct ptlrpc_service *service; -- ENTRY; -- -- OBD_ALLOC(service, sizeof(*service)); -- if (!service) -- RETURN(NULL); -- -- service->srv_name = name; -- spin_lock_init(&service->srv_lock); -- INIT_LIST_HEAD(&service->srv_threads); -- init_waitqueue_head(&service->srv_waitq); -- -- service->srv_max_req_size = max_req_size; -- service->srv_buf_size = bufsize; -- INIT_LIST_HEAD(&service->srv_rqbds); -- service->srv_nrqbds = 0; -- atomic_set(&service->srv_nrqbds_receiving, 0); -- -- service->srv_rep_portal = rep_portal; -- service->srv_req_portal = req_portal; -- service->srv_handler = handler; -- -- err = kportal_uuid_to_peer(uuid, &service->srv_self); -- if (err) { -- CERROR("%s: cannot get peer for uuid '%s'\n", name, uuid); -- OBD_FREE(service, sizeof(*service)); -- RETURN(NULL); -- } -- -- rc = PtlEQAlloc(service->srv_self.peer_ni, nevents, -- request_in_callback, &(service->srv_eq_h)); -- -- if (rc != PTL_OK) { -- CERROR("%s: PtlEQAlloc failed: %d\n", name, rc); -- OBD_FREE(service, sizeof(*service)); -- RETURN(NULL); -- } -- -- for (i = 0; i < nbufs; i++) { -- struct ptlrpc_request_buffer_desc *rqbd; -- -- OBD_ALLOC(rqbd, sizeof(*rqbd)); -- if (rqbd == NULL) -- GOTO(failed, NULL); -- -- rqbd->rqbd_service = service; -- ptl_set_inv_handle(&rqbd->rqbd_me_h); -- atomic_set(&rqbd->rqbd_refcount, 0); -- OBD_ALLOC(rqbd->rqbd_buffer, service->srv_buf_size); -- if (rqbd->rqbd_buffer == NULL) { -- OBD_FREE(rqbd, sizeof(*rqbd)); -- GOTO(failed, NULL); -- } -- list_add(&rqbd->rqbd_list, &service->srv_rqbds); -- service->srv_nrqbds++; -- -- ptlrpc_link_svc_me(rqbd); -- } -- -- CDEBUG(D_NET, "Starting service listening on portal %d (eq: %p)\n", -- service->srv_req_portal, service->srv_eq_h.handle_idx); -- -- RETURN(service); --failed: -- ptlrpc_unregister_service(service); -- return NULL; --} -- --static int handle_incoming_request(struct obd_device *obddev, -- struct ptlrpc_service *svc, -- ptl_event_t *event, -- struct ptlrpc_request *request) --{ -- struct ptlrpc_request_buffer_desc *rqbd = event->mem_desc.user_ptr; -- int rc; -- -- /* FIXME: If we move to an event-driven model, we should put the request -- * on the stack of mds_handle instead. */ -- -- LASSERT (atomic_read (&rqbd->rqbd_refcount) > 0); -- LASSERT ((event->mem_desc.options & PTL_MD_IOV) == 0); -- LASSERT (rqbd->rqbd_service == svc); -- LASSERT (rqbd->rqbd_buffer == event->mem_desc.start); -- LASSERT (event->offset + event->mlength <= svc->srv_buf_size); -- -- memset(request, 0, sizeof(*request)); -- request->rq_svc = svc; -- request->rq_obd = obddev; -- request->rq_xid = event->match_bits; -- request->rq_reqmsg = event->mem_desc.start + event->offset; -- request->rq_reqlen = event->mlength; -- -- rc = -EINVAL; -- -- if (request->rq_reqlen < sizeof(struct lustre_msg)) { -- CERROR("incomplete request (%d): ptl %d from "LPX64" xid " -- LPD64"\n", -- request->rq_reqlen, svc->srv_req_portal, -- event->initiator.nid, request->rq_xid); -- goto out; -- } - - CDEBUG(D_RPCTRACE, "Handling RPC pid:xid:nid:opc %d:" - LPX64":%x:%d\n", - NTOH__u32(request->rq_reqmsg->status), - request->rq_xid, - event->initiator.nid, - NTOH__u32(request->rq_reqmsg->opc)); -- -- if (NTOH__u32(request->rq_reqmsg->type) != PTL_RPC_MSG_REQUEST) { -- CERROR("wrong packet type received (type=%u)\n", -- request->rq_reqmsg->type); -- goto out; -- } -- -- if (request->rq_reqmsg->magic != PTLRPC_MSG_MAGIC) { -- CERROR("wrong lustre_msg magic %d: ptl %d from "LPX64" xid " -- LPD64"\n", -- request->rq_reqmsg->magic, svc->srv_req_portal, -- event->initiator.nid, request->rq_xid); -- goto out; -- } -- -- if (request->rq_reqmsg->version != PTLRPC_MSG_VERSION) { -- CERROR("wrong lustre_msg version %d: ptl %d from "LPX64" xid " -- LPD64"\n", -- request->rq_reqmsg->version, svc->srv_req_portal, -- event->initiator.nid, request->rq_xid); -- goto out; -- } -- -- CDEBUG(D_NET, "got req "LPD64" (md: %p + %d)\n", request->rq_xid, -- event->mem_desc.start, event->offset); -- -- request->rq_peer.peer_nid = event->initiator.nid; -- /* FIXME: this NI should be the incoming NI. -- * We don't know how to find that from here. */ -- request->rq_peer.peer_ni = svc->srv_self.peer_ni; -- -- request->rq_export = class_conn2export((struct lustre_handle *) -- request->rq_reqmsg); -- -- if (request->rq_export) { -- request->rq_connection = request->rq_export->exp_connection; -- ptlrpc_connection_addref(request->rq_connection); -- } else { -- /* create a (hopefully temporary) connection that will be used -- * to send the reply if this call doesn't create an export. -- * XXX revisit this when we revamp ptlrpc */ -- request->rq_connection = -- ptlrpc_get_connection(&request->rq_peer, NULL); -- } -- -- rc = svc->srv_handler(request); -- ptlrpc_put_connection(request->rq_connection); -- -- out: -- if (atomic_dec_and_test (&rqbd->rqbd_refcount)) /* last reference? */ -- ptlrpc_link_svc_me (rqbd); -- -- return rc; -} - -/* Don't use daemonize, it removes fs struct from new thread (bug 418) */ -static void ptlrpc_daemonize(void) -{ - exit_mm(current); - - current->session = 1; - current->pgrp = 1; - current->tty = NULL; - - exit_files(current); --} -- --static int ptlrpc_main(void *arg) --{ -- struct ptlrpc_svc_data *data = (struct ptlrpc_svc_data *)arg; -- struct obd_device *obddev = data->dev; -- struct ptlrpc_service *svc = data->svc; -- struct ptlrpc_thread *thread = data->thread; -- struct ptlrpc_request *request; -- ptl_event_t *event; -- int rc = 0; -- -- ENTRY; -- -- lock_kernel(); - daemonize(); - ptlrpc_daemonize(); - --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -- sigfillset(¤t->blocked); -- recalc_sigpending(); --#else -- spin_lock_irq(¤t->sigmask_lock); -- sigfillset(¤t->blocked); -- recalc_sigpending(current); -- spin_unlock_irq(¤t->sigmask_lock); --#endif -- --#ifdef __arch_um__ - sprintf(current->comm, "%s|%d", - data->name, current->thread.extern_pid); - sprintf(current->comm, "%s|%d", data->name,current->thread.extern_pid); --#else -- strcpy(current->comm, data->name); --#endif -- unlock_kernel(); -- -- OBD_ALLOC(event, sizeof(*event)); -- if (!event) -- GOTO(out, rc = -ENOMEM); -- OBD_ALLOC(request, sizeof(*request)); -- if (!request) -- GOTO(out_event, rc = -ENOMEM); -- -- /* Record that the thread is running */ -- thread->t_flags = SVC_RUNNING; -- wake_up(&thread->t_ctl_waitq); -- -- /* XXX maintain a list of all managed devices: insert here */ -- -- /* And now, loop forever on requests */ -- while (1) { -- wait_event(svc->srv_waitq, -- ptlrpc_check_event(svc, thread, event)); -- -- if (thread->t_flags & SVC_STOPPING) { -- spin_lock(&svc->srv_lock); -- thread->t_flags &= ~SVC_STOPPING; -- spin_unlock(&svc->srv_lock); -- -- EXIT; -- break; -- } -- -- if (thread->t_flags & SVC_EVENT) { -- spin_lock(&svc->srv_lock); -- thread->t_flags &= ~SVC_EVENT; -- spin_unlock(&svc->srv_lock); -- -- rc = handle_incoming_request(obddev, svc, event, -- request); -- continue; -- } -- -- CERROR("unknown break in service"); -- LBUG(); -- EXIT; -- break; -- } -- -- OBD_FREE(request, sizeof(*request)); --out_event: -- OBD_FREE(event, sizeof(*event)); --out: -- thread->t_flags = SVC_STOPPED; -- wake_up(&thread->t_ctl_waitq); -- -- CDEBUG(D_NET, "service thread exiting, process %d: rc = %d\n", -- current->pid, rc); -- return rc; --} -- --static void ptlrpc_stop_thread(struct ptlrpc_service *svc, -- struct ptlrpc_thread *thread) --{ -- spin_lock(&svc->srv_lock); -- thread->t_flags = SVC_STOPPING; -- spin_unlock(&svc->srv_lock); -- -- wake_up(&svc->srv_waitq); -- wait_event(thread->t_ctl_waitq, (thread->t_flags & SVC_STOPPED)); --} -- --void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) --{ -- spin_lock(&svc->srv_lock); -- while (!list_empty(&svc->srv_threads)) { -- struct ptlrpc_thread *thread; -- thread = list_entry(svc->srv_threads.next, struct ptlrpc_thread, -- t_link); -- spin_unlock(&svc->srv_lock); -- ptlrpc_stop_thread(svc, thread); -- spin_lock(&svc->srv_lock); -- list_del(&thread->t_link); -- OBD_FREE(thread, sizeof(*thread)); -- } -- spin_unlock(&svc->srv_lock); --} -- --int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, -- char *name) --{ -- struct ptlrpc_svc_data d; -- struct ptlrpc_thread *thread; -- int rc; -- ENTRY; -- -- OBD_ALLOC(thread, sizeof(*thread)); -- if (thread == NULL) { -- LBUG(); -- RETURN(-ENOMEM); -- } -- init_waitqueue_head(&thread->t_ctl_waitq); -- -- d.dev = dev; -- d.svc = svc; -- d.name = name; -- d.thread = thread; -- -- spin_lock(&svc->srv_lock); -- list_add(&thread->t_link, &svc->srv_threads); -- spin_unlock(&svc->srv_lock); -- - /* XXX should we really be cloning open file handles here? */ - rc = kernel_thread(ptlrpc_main, (void *) &d, - CLONE_VM | CLONE_FS | CLONE_FILES); - rc = kernel_thread(ptlrpc_main, (void *) &d, CLONE_VM | CLONE_FILES); -- if (rc < 0) { -- CERROR("cannot start thread\n"); -- OBD_FREE(thread, sizeof(*thread)); -- RETURN(rc); -- } -- wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_RUNNING); -- -- RETURN(0); --} -- --int ptlrpc_unregister_service(struct ptlrpc_service *service) --{ -- int rc; -- -- LASSERT (list_empty (&service->srv_threads)); -- -- /* XXX We could reply (with failure) to all buffered requests -- * _after_ unlinking _all_ the request buffers, but _before_ -- * freeing them. -- */ -- -- while (!list_empty (&service->srv_rqbds)) { -- struct ptlrpc_request_buffer_desc *rqbd = -- list_entry (service->srv_rqbds.next, -- struct ptlrpc_request_buffer_desc, -- rqbd_list); -- -- list_del (&rqbd->rqbd_list); -- -- LASSERT (atomic_read (&rqbd->rqbd_refcount) > 0); -- /* refcount could be anything; it's possible for the -- * buffers to continued to get filled after all the server -- * threads exited. But we know they _have_ exited. -- */ -- -- (void) PtlMEUnlink(rqbd->rqbd_me_h); -- /* The callback handler could have unlinked this ME already -- * (we're racing with her) but it's safe to ensure it _has_ -- * been unlinked. -- */ -- -- OBD_FREE (rqbd->rqbd_buffer, service->srv_buf_size); -- OBD_FREE (rqbd, sizeof (*rqbd)); -- service->srv_nrqbds--; -- } -- -- LASSERT (service->srv_nrqbds == 0); -- -- rc = PtlEQFree(service->srv_eq_h); -- if (rc) -- CERROR("PtlEQFree failed: %d\n", rc); -- -- OBD_FREE(service, sizeof(*service)); -- if (rc) -- LBUG(); -- return rc; --} diff --cc lustre/scripts/.cvsignore index 104ddf7,104ddf7..0000000 deleted file mode 100644,100644 --- a/lustre/scripts/.cvsignore +++ /dev/null @@@ -1,9 -1,9 +1,0 @@@ --.Xrefs --lustre.spec --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS diff --cc lustre/scripts/Makefile.am index a33c1e5,199f5be..0000000 deleted file mode 100644,100644 --- a/lustre/scripts/Makefile.am +++ /dev/null @@@ -1,10 -1,10 +1,0 @@@ --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- - EXTRA_DIST = license-status maketags.sh lustre.spec $(initd_SCRIPTS) -EXTRA_DIST = license-status maketags.sh lustre.spec version_tag.pl $(initd_SCRIPTS) --initddir = $(sysconfdir)/init.d --initd_SCRIPTS = lustre --include $(top_srcdir)/Rules -- diff --cc lustre/scripts/dodiff.sh index 899415d,899415d..0000000 deleted file mode 100755,100755 --- a/lustre/scripts/dodiff.sh +++ /dev/null @@@ -1,5 -1,5 +1,0 @@@ --#!/bin/sh -- --for f in `cat $1` ; do -- diff -u $2-pristine/$f $2/$f --done diff --cc lustre/scripts/license-status index 5407b91,5407b91..0000000 deleted file mode 100755,100755 --- a/lustre/scripts/license-status +++ /dev/null @@@ -1,26 -1,26 +1,0 @@@ --#! /bin/sh --# license-status - Display the status of files in the current directory --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution --# --# Gordon Matzigkeit , 2001-09-27 -- --for f in `find . -type f | sort`; do -- case "$f" in -- *~ | *.orig | *.gz | */config.* | *.o | \ -- */CVS/* | */.cvsignore | */.depfiles/* | \ -- */COPYING | */ChangeLog) -- continue -- ;; -- esac -- -- if head -20 "$f" | egrep -e 'GNU' > /dev/null; then -- echo "gpled $f" -- elif head -20 "$f" | egrep -e '\([Cc]\)' > /dev/null; then -- echo "copyrighted $f" -- else -- echo "bare $f" -- fi --done | sort diff --cc lustre/scripts/lustre index b62dc4c,b62dc4c..0000000 deleted file mode 100755,100755 --- a/lustre/scripts/lustre +++ /dev/null @@@ -1,77 -1,77 +1,0 @@@ --#!/bin/sh --# --# lustre This shell script takes care of starting and stopping Lustre --# --# chkconfig: 345 99 1 --# description: Lustre Lite network File System. \ --# This starts both Lustre client and server functions. --# processname: lconf --# config: /etc/lustre/config.xml --# pidfile: /var/run/lustre.pid -- --SERVICE=lustre --LOCK=/var/lock/subsys/$SERVICE -- --: ${LUSTRE_CFG:=/etc/lustre/lustre.cfg} --[ -f ${LUSTRE_CFG} ] && . ${LUSTRE_CFG} -- --: ${LUSTRE_CONFIG_XML:=/etc/lustre/config.xml} --: ${LCONF:=/usr/sbin/lconf} --: ${LCONF_START_ARGS:="${LUSTRE_CONFIG_XML}"} --: ${LCONF_STOP_ARGS:="--force --cleanup ${LUSTRE_CONFIG_XML}"} -- --# Source function library. --if [ -f /etc/init.d/functions ] ; then -- . /etc/init.d/functions --fi -- --# Source networking configuration. --if [ -f /etc/sysconfig/network ] ; then -- . /etc/sysconfig/network --fi -- --# Check that networking is up. --[ "${NETWORKING}" = "no" ] && exit 0 -- --[ -x ${LCONF} -a -f ${LUSTRE_CONFIG_XML} ] || exit 0 -- --start() { -- echo -n "Starting $SERVICE: " -- ${LCONF} ${LCONF_START_ARGS} -- RETVAL=$? -- echo $SERVICE -- [ $RETVAL -eq 0 ] && touch $LOCK --} -- --stop() { -- echo -n "Shutting down $SERVICE: " -- ${LCONF} ${LCONF_STOP_ARGS} -- echo $SERVICE -- rm -f $LOCK --} -- --restart() { -- stop -- start --} -- --# See how we were called. --case "$1" in -- start) -- start -- ;; -- stop) -- stop -- ;; -- restart) -- restart -- ;; -- status) -- status $SERVICE -- ;; -- *) -- echo "Usage: $SERVICE {start|stop|restart|status}" -- exit 1 --esac -- --exit $RETVAL diff --cc lustre/scripts/lustre.spec.in index 2b5b786,2b5b786..0000000 deleted file mode 100644,100644 --- a/lustre/scripts/lustre.spec.in +++ /dev/null @@@ -1,128 -1,128 +1,0 @@@ --# lustre.spec --%define version HEAD --%define kversion @RELEASE@ --%define linuxdir @LINUX@ --%define portalsdir @PORTALS@ --%define portalslibdir @PORTALSLIB@ --Release: 0208282230chaos -- --Summary: Lustre Lite File System --Name: lustre-lite --Version: %{version} --Copyright: GPL --Group: Utilities/System --Requires: lustre-modules, PyXML --BuildRoot: /var/tmp/lustre-%{version}-root --Source: ftp://ftp.lustre.com/pub/lustre/lustre-%{version}.tar.gz -- --%description --The Lustre Lite Cluster File System: kernel drivers for file system, --servers and utilities. -- --%package -n lustre-modules --Summary: Kernel Lustre drivers for Linux %{kversion} --Requires: portals-modules --Group: Development/Kernel -- --%description -n lustre-modules --Lustre file System, server and network drivers for Linux %{kversion}. -- --%package -n lustre-source --Summary: Object-Based Disk storage driver source --Group: Development/Kernel -- --%description -n lustre-source --Lustre Lite Source for further development -- --%package -n lustre-doc --Summary: Documentation and sample configuration files --Group: Documentation --# FIXME: BuildArch overrides all the packages in rpm 4.0.4-7x --#BuildArch: noarch -- --%description -n lustre-doc --Documentation and sample configuration files for Lustre -- --%prep --%setup -qn lustre-%{version} -- --%build --rm -rf $RPM_BUILD_ROOT -- --# Set an explicit path to our Linux tree, if we can. --./configure --with-linux='%{linuxdir}' --with-portals='%{portalsdir}' --with-portalslib='%{portalslibdir}' --make -- --%install --make install prefix=$RPM_BUILD_ROOT -- --# Create the pristine source directory. --mkdir -p $RPM_BUILD_ROOT/usr/src --rm -f lustre-source --ln -s $RPM_BUILD_ROOT/usr/src lustre-source --make distdir distdir=lustre-source/lustre-%{version} -- --%files --%attr(-, root, root) /usr/sbin/lmc --%attr(-, root, root) /usr/sbin/lctl --%attr(-, root, root) /usr/sbin/lconf --%attr(-, root, root) /usr/lib/lustre/examples/llmount.sh --%attr(-, root, root) /usr/lib/lustre/examples/llmountcleanup.sh --%attr(-, root, root) /usr/lib/lustre/examples/llecho.sh --%attr(-, root, root) /usr/lib/lustre/examples/local.sh --%attr(-, root, root) /usr/lib/lustre/examples/uml.sh --%attr(-, root, root) /usr/lib/lustre/examples/lov.sh --%attr(-, root, root) /etc/init.d/lustre -- --%files -n lustre-doc --%attr(-, root, root) %doc COPYING FDL --%attr(-, root, root) %doc doc/lustre.pdf doc/lustre-HOWTO.txt --%attr(-, root, root) %doc tests/client-echo.cfg tests/client-mount.cfg --%attr(-, root, root) %doc tests/client-mount2.cfg --%attr(-, root, root) %doc tests/elan-client.cfg tests/elan-server.cfg --%attr(-, root, root) %doc tests/ldlm.cfg tests/lustre.cfg --%attr(-, root, root) %doc tests/mds.cfg tests/net-client.cfg --%attr(-, root, root) %doc tests/net-local.cfg tests/net-server.cfg --%attr(-, root, root) %doc tests/obdecho.cfg tests/obdfilter.cfg -- --%files -n lustre-modules --%attr(-, root, root) %doc COPYING --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/extN.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ldlm.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/llite.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mdc.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mds.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/mds_extN.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdclass.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdecho.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/obdfilter.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/lov.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/osc.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ost.o --%attr(-, root, root) /lib/modules/%{kversion}/kernel/fs/lustre/ptlrpc.o -- --%files -n lustre-source --%attr(-, root, root) /usr/src/lustre-%{version} -- --%post --if [ ! -e /dev/obd ]; then -- mknod /dev/obd c 10 241 --fi --depmod -ae || exit 0 -- --grep -q obdclass /etc/modules.conf || \ -- echo 'alias char-major-10-241 obdclass' >> /etc/modules.conf -- --grep -q '/dev/obd' /etc/modules.conf || \ -- echo 'alias /dev/obd obdclass' >> /etc/modules.conf -- --grep -q '/dev/lustre' /etc/modules.conf || \ -- echo 'alias /dev/lustre obdclass' >> /etc/modules.conf -- --%postun --depmod -ae || exit 0 -- --%clean --#rm -rf $RPM_BUILD_ROOT -- --# end of file diff --cc lustre/scripts/maketags.sh index 9bd9f87,9bd9f87..0000000 deleted file mode 100755,100755 --- a/lustre/scripts/maketags.sh +++ /dev/null @@@ -1,8 -1,8 +1,0 @@@ --#!/bin/sh --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution --set -vx --rm -f TAGS ; find . -name '*.h' -or -name '*.c' | xargs etags --rm -f ctags; find . -name '*.h' -or -name '*.c' | xargs ctags diff --cc lustre/scripts/nodelustre index b5e6540,b5e6540..0000000 deleted file mode 100755,100755 --- a/lustre/scripts/nodelustre +++ /dev/null @@@ -1,46 -1,46 +1,0 @@@ --#! /bin/sh --# nodelustre - Start and stop Lustre on MCR nodes --# Copyright (C) 2002 Cluster File Systems, Inc. --# Gord Eagle , 2002-09-10 -- --# Set this to the shared config file. --MASTER_CONFIG=http://emcri/lustre.xml --CONFIG=/etc/lustre/lustre.xml --COMPUTE_NODE=client -- --LCONF=/usr/local/cfs/lustre/utils/lconf --WGET=wget -- --case "$1" in --start | stop) -- # Fetch the config file. We can't use --output-document because it -- # makes Wget ignore timestamping. -- if test -n "$MASTER_CONFIG"; then -- (cd `echo "$CONFIG" | sed 's%/[^/]*$%%'` && \ -- $WGET --timestamping "$MASTER_CONFIG") || exit $? -- fi -- -- # Map all client nodes to the COMPUTE_NODE virtual node. -- if test -n "$COMPUTE_NODE" && nodeattr compute; then -- node=" --node $COMPUTE_NODE" -- else -- node= -- fi -- -- # If we're stopping, do the lconf cleanup. -- if test "$1" = stop; then -- cleanup=' --cleanup' -- else -- cleanup= -- fi -- -- $LCONF$cleanup$node "$CONFIG" -- ;; -- --*) -- echo "$0 {start|stop}" 1>&2 -- exit 1 -- ;; --esac -- --exit 0 diff --cc lustre/tests/.cvsignore index a7be7c7,5563923..0000000 deleted file mode 100644,100644 --- a/lustre/tests/.cvsignore +++ /dev/null @@@ -1,26 -1,29 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --TAGS --openunlink --testreq --truncate --directio --openme --writeme --mcreate --munlink --tchmod --toexcl --fsx --test_brw --newfile --openclose --createdestroy -createmany -mkdirmany --lovstripe - echo.xml - local.xml -*.xml -stat -setuid diff --cc lustre/tests/Makefile.am index 034f12d,f09b85c..0000000 deleted file mode 100644,100644 --- a/lustre/tests/Makefile.am +++ /dev/null @@@ -1,47 -1,50 +1,0 @@@ --# Lustre test Makefile --DEFS= --CPPFLAGS = -I. -I$(PORTALS)/include -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE --CFLAGS := -g -Wall --# LDADD = -lldap --# LDADD := -lreadline -ltermcap # -lefence --EXTRA_DIST = $(pkgexample_SCRIPTS) $(noinst_SCRIPTS) $(noinst_DATA) \ -- common.sh lustre.cfg \ -- client-echo.cfg elan-server.cfg net-client.cfg obdecho.cfg \ -- client-mount.cfg ldlm.cfg net-local.cfg obdfilter.cfg \ - client-mount2.cfg lustre.cfg net-server.cfg \ - client-mount2.cfg lustre.cfg net-server.cfg sanity.sh \ - rundbench \ -- elan-client.cfg mds.cfg trivial.sh --pkgexampledir = '${exec_prefix}/usr/lib/$(PACKAGE)/examples' --pkgexample_SCRIPTS = llmount.sh llmountcleanup.sh llecho.sh local.sh uml.sh lov.sh --noinst_SCRIPTS = llsetup.sh llrsetup.sh llcleanup.sh - noinst_DATA = ext2_10000.gz ext2_25000.gz ext3_10000.gz lov.xml lustre.cfg -noinst_DATA = lustre.cfg --noinst_SCRIPTS += fs.sh intent-test.sh intent-test2.sh leak_finder.pl \ -- lldlm.sh llecho.sh llext3.sh llmodules.sh llmount-client.sh \ -- llmount-server.sh llmount.sh llmountcleanup.sh llrext3.sh \ -- llrmount.sh llsimple.sh mdcreq.sh mdcreqcleanup.sh \ -- ostreq.sh runfailure-client-mds-recover.sh runfailure-mds \ -- runfailure-net runfailure-ost runiozone runregression-net.sh \ -- runtests runvmstat snaprun.sh tbox.sh common.sh --noinst_PROGRAMS = openunlink testreq truncate directio openme writeme mcreate --noinst_PROGRAMS += munlink tchmod toexcl fsx test_brw openclose createdestroy - noinst_PROGRAMS += lovstripe stat createmany # ldaptest -noinst_PROGRAMS += lovstripe stat createmany mkdirmany setuid # ldaptest -- --# ldaptest_SOURCES = ldaptest.c --tchmod_SOURCES = tchmod.c --toexcl_SOURCES = toexcl.c --testreq_SOURCES = testreq.c --mcreate_SOURCES = mcreate.c --munlink_SOURCES = munlink.c --truncate_SOURCES = truncate.c --directio_SOURCES = directio.c --openunlink_SOURCES = openunlink.c --openme_SOURCES = openme.c --writeme_SOURCES = writeme.c --fsx_SOURCES = fsx.c --test_brw_SOURCES = test_brw.c --openclose_SOURCES = openclose.c --createdestroy_SOURCES = createdestroy.c --lovstripe_SOURCES = lovstripe.c --stat_SOURCES = stat.c --createmany_SOURCES = createmany.c -mkdirmany_SOURCES = mkdirmany.c -setuid_SOURCES = setuid.c -- --include $(top_srcdir)/Rules diff --cc lustre/tests/README index 00634a7,00634a7..0000000 deleted file mode 100644,100644 --- a/lustre/tests/README +++ /dev/null @@@ -1,85 -1,85 +1,0 @@@ --1. How to build .xml configs: --The various .xml configs in the tests/ directory are built by running the --corresponding .sh script. The .sh script runs a series of lmc (Lustre make --config) commands in order to build up an XML file. It is much easier to --simply edit a .sh script and rebuild your XML config file than trying to --edit the XML directly. -- --For a loopback setup with a mounted filesystem, you could do something like: -- -- sh local.sh -- ../utils/lconf --reformat local.xml -- --This will configure an MDS, an OBD/OST, and a filesystem client all running --on the same system and communicating over the TCP loopback interface. If --the --reformat option is given, then the OST and MDS devices will be --formatted. This is required the first time you set up the system, or if --you think you have corrupted the filesystems after you hit a bug. -- --A more complex configuration, using a separate host for each of the MDS, --OBD/OST, and filesystem client functions is in uml.sh. It configures 3 --systems, and the OST system (uml2) serves up multiple OST devices, and --the client accesses these via a logical object volume (LOV) driver (which --essentially stripes both of the OST devices into a single storage device. -- --This configuration could be run on any 3 systems with the following commands: -- -- sh uml.sh -- system1# ../utils/lconf --reformat --node uml1 uml.xml -- system2# ../utils/lconf --reformat --node uml2 uml.xml -- system3# ../utils/lconf --node uml3 uml.xml -- --The "--node " parameter tells lconf to use the configuration for --the node "name" in the XML configuration file. If the hostnames were --already "uml1", "uml2", and "uml3", then the "--node" parameter would --not need to be given. The internals of lconf and portals handle the --configuration details for setting up netowrking. -- --2. runregression-net.sh and runregression-brw.sh -- --This test performs raw block and attribute requests against a real or --"null" OST device. It is useful for generating isolated load on the --OST device, while avoiding the need to run tests through the filesystem. --This can be useful for testing the network part of Lustre in isolation, --or doing RPC and bulk I/O performance tests against an OST. -- --If things are alright it goes through a series of tests single threaded, --multithreaded, using getattr and brw (both read and write, with single --page and vector I/O, doing basic data checking of each page). -- --You can create a simple echo client by running the "llecho.sh" to --run the tests locally (over TCP loopback), or edit llecho.sh to --specify the SERVER and CLIENT names. You would then set up as normal: -- -- # if you are using a remote server, first run: -- server# ../utils/lconf echo.xml -- --Configure the client (or if you are running a single system only): -- -- client# ../utils/lconf echo.xml -- client# sh runregression-net.sh -- --3. runtests -- --The runtests script does a series of simple file-based tests using a --filesystem. You need to have an XML file as appropriate for your setup --(one or more hosts, including an MDS, one or more OSTs, and a mountpoint). --If the MDS and/or OST is on a remote machine, configure them first: -- -- ../utils/lconf --reformat .xml -- --On the client machine, the runtests script needs the XML configuration --file as a command-line parameter, as it mounts and unmounts the filesystem --several times during the test in order to verify that the data is still --there as expected (ensures that it makes it to disk instead of just into --the filesystem cache). If you are running on only a single machine, you --can just use runtests directly. If this is only a client machine, the ----reformat parameter is not needed (it will not do anything). -- -- sh runtests [--reformat] .xml -- --This creates a few simple files and directories first, and then untars --a copy of the /etc filesystem into the Lustre filesystem. It then does --data verification both before and after the filesystem is remounted, and --finally deletes all of the files and verifies that the amount of space --left in the filesystem is (nearly) the same as it was before the test. diff --cc lustre/tests/acceptance-small.sh index 6ba9864,06c4a84..0000000 deleted file mode 100755,100755 --- a/lustre/tests/acceptance-small.sh +++ /dev/null @@@ -1,28 -1,84 +1,0 @@@ --#!/bin/sh --# script which _must_ complete successfully (at minimum) before checkins to --# the CVS HEAD are allowed. --set -vxe -- - if [ "$RUNTESTS" != "no" ]; then - sh local.sh - sh runtests --reformat local.xml -[ "$CONFIGS" ] || CONFIGS="local lov" -[ "$THREADS" ] || THREADS=1 -[ "$SIZE" ] || SIZE=20480 -[ "$RSIZE" ] || RSIZE=64 -[ "$UID" ] || UID=1000 -[ "$MNT" ] || MNT=/mnt/lustre -[ "$TMP" ] || TMP=/tmp -[ "$COUNT" ] || COUNT=1000 -[ "$DEBUG_OFF" ] || DEBUG_OFF="eval echo 0 > /proc/sys/portals/debug" -- - sh lov.sh - sh runtests --reformat lov.xml - fi -for NAME in $CONFIGS; do - export NAME - [ -e $NAME.sh ] && sh $NAME.sh - [ ! -e $NAME.xml ] && echo "no config '$NAME.xml'" 1>&2 && exit 1 -- - export NAME=local - sh llmount.sh - [ "$SANITY" != "no" ] && sh sanity.sh - [ "$DBENCH" != "no" ] && sh rundbench 1 - [ "$BONNIE" != "no" ] && bonnie++ -s 0 -n 10 -u 0 -d /mnt/lustre - sync; sync - sh llmountcleanup.sh - if [ "$RUNTESTS" != "no" ]; then - sh runtests - fi -- - export NAME=lov - llmount.sh - [ "$SANITY" != "no" ] && sh sanity.sh - [ "$DBENCH" != "no" ] && sh rundbench 1 - [ "$BONNIE" != "no" ] && bonnie++ -s 0 -n 10 -u 0 -d /mnt/lustre - sync; sync - sh llmountcleanup.sh - mount | grep $MNT || sh llmount.sh - [ "$SANITY" != "no" ] && sh sanity.sh - if [ "$DBENCH" != "no" ]; then - $DEBUG_OFF - sh rundbench 1 - sh llmountcleanup.sh - sh llrmount.sh - if [ $THREADS -gt 1 ]; then - sh rundbench $THREADS - sh llmountcleanup.sh - sh llrmount.sh - fi - rm -f /mnt/lustre/client.txt - fi - chown $UID $MNT && chmod 700 $MNT - if [ "$BONNIE" != "no" ]; then - $DEBUG_OFF - bonnie++ -s 0 -n 10 -u $UID -d $MNT - sh llmountcleanup.sh - sh llrmount.sh - fi - IOZONE_OPTS="-i 0 -i 1 -i 2 -+d -r $RSIZE -s $SIZE" - IOZONE_FILE="-f $MNT/iozone" - if [ "$IOZONE" != "no" ]; then - $DEBUG_OFF - iozone $IOZONE_OPTS $IOZONE_FILE - sh llmountcleanup.sh - sh llrmount.sh - fi - if [ "$IOZONE_DIR" != "no" ]; then - $DEBUG_OFF - iozone -I $IOZONE_OPTS $IOZONE_FILE.odir - IOZVER=`iozone -v | awk '/Revision:/ { print $3 }' | tr -d '.'` - sh llmountcleanup.sh - sh llrmount.sh - if [ "$THREADS" -gt 1 -a "$IOZVER" -ge 3145 ]; then - $DEBUG_OFF - THREAD=1 - IOZONE_FILE="-F " - SIZE=`expr $SIZE / $THREADS` - while [ $THREAD -le $THREADS ]; do - IOZONE_FILE="$IOZONE_FILE $MNT/iozone.$THREAD" - THREAD=`expr $THREAD + 1` - done - iozone -I $IOZONE_OPTS -t $THREADS $IOZONE_FILE - sh llmountcleanup.sh - sh llrmount.sh - elif [ $IOZVER -lt 3145 ]; then - VER=`iozone -v | awk '/Revision:/ { print $3 }'` - echo "iozone $VER too old for multi-threaded tests" - fi - fi - if [ "$FSX" != "no" ]; then - $DEBUG_OFF - ./fsx -c 50 -p 1000 -P $TMP -l 1024000 -N $(($COUNT * 100)) $MNT/fsxfile - sh llmountcleanup.sh - #sh llrmount.sh - fi - mount | grep $MNT && sh llmountcleanup.sh -done diff --cc lustre/tests/ba-echo.sh index d971016,a3b97cd..0000000 deleted file mode 100644,100644 --- a/lustre/tests/ba-echo.sh +++ /dev/null @@@ -1,39 -1,38 +1,0 @@@ --#!/bin/bash -- --config=${1:-ba-echo.xml} -- --LMC="save_cmd" --LMC_REAL="../../lustre/utils/lmc -m $config" -- - PORT=988 --TCPBUF=1048576 --OST=ba-ost-1 --CLIENT=client -- --UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} -- --h2ip () { -- echo "${1}" --} --BATCH=/tmp/lmc-batch.$$ --save_cmd() { -- echo "$@" >> $BATCH --} -- --[ -f $config ] && rm $config -- --# Client node - ${LMC} --node $CLIENT --tcpbuf $TCPBUF --net '*' tcp $PORT -${LMC} --node $CLIENT --tcpbuf $TCPBUF --net '*' tcp -- --OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` --[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID" -- --# server node - ${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT -${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp --${LMC} --node $OST --obdtype=obdecho $OBD_UUID --ost -- --# osc on client --${LMC} --node $CLIENT --osc OSC_$OST -- --$LMC_REAL --batch $BATCH --rm -f $BATCH diff --cc lustre/tests/ba-mount.sh index 2a2ff3d,b81455f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/ba-mount.sh +++ /dev/null @@@ -1,54 -1,53 +1,0 @@@ --#!/bin/bash -- --# There are configurations for three machines in this config file: the OST, --# the MDS/client, other clients --# --# To start your cluster using the ba-mount.xml file that this produces, first --# run: --# > lconf ba-mount.xml --# on the MDS/client, and then run: --# > lconf --node client ba-mount.xml --# on any other clients. -- --config=${1:-ba-mount.xml} -- - LMC_REAL="${LMC:-../utils/lmc} -m config" -LMC_REAL="${LMC:-../utils/lmc} -m $config" --LMC="save_cmd" -- - PORT=988 --TCPBUF=1048576 - OST=ba-ost-1 - MDS=mds-hostname -OST=${OST:-ba-ost-1} -MDS=`hostname` -- --UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} -- --h2ip () { -- echo "${1}" --} --BATCH=/tmp/lmc-batch.$$ --save_cmd() { -- echo "$@" >> $BATCH --} -- --[ -f $config ] && rm $config -- --# MDS/client node - ${LMC} --node $MDS --tcpbuf $TCPBUF --net '*' tcp $PORT -${LMC} --node $MDS --tcpbuf $TCPBUF --net $MDS tcp --${LMC} --node $MDS --mds mds1 /tmp/mds1 50000 -- --OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` --[ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID" -- --# server node - ${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp $PORT -${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp --${LMC} --node $OST $OBD_UUID --ost bluearc -- --# mount point on the MDS/client --${LMC} --node $MDS --mtpt /mnt/lustre mds1 OSC_$OST -- --# other clients - ${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT -${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp --${LMC} --node client --mtpt /mnt/lustre mds1 OSC_$OST -- --$LMC_REAL --batch $BATCH --rm -f $BATCH diff --cc lustre/tests/client-echo.cfg index 83856ec,83856ec..0000000 deleted file mode 100644,100644 --- a/lustre/tests/client-echo.cfg +++ /dev/null @@@ -1,3 -1,3 +1,0 @@@ --#!/bin/sh --# Config file for setting up a client to talk to an echo OST --SETUP_OSC=y diff --cc lustre/tests/client-mount.cfg index 6f2addb,6f2addb..0000000 deleted file mode 100644,100644 --- a/lustre/tests/client-mount.cfg +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh --# Config file for mounting a client Lustre filesystem --SETUP_MDC=y --SETUP_OSC=y --OSCMT=/mnt/lustre --SETUP_MOUNT=y diff --cc lustre/tests/client-mount2.cfg index cb210c8,cb210c8..0000000 deleted file mode 100644,100644 --- a/lustre/tests/client-mount2.cfg +++ /dev/null @@@ -1,10 -1,10 +1,0 @@@ --#!/bin/sh --# Config file for mounting a client Lustre filesystem --MDC_NAMES="MDCDEV1 MDCDEV2" --OSC_NAMES="OSCDEV1 OSCDEV2" --SETUP_MDC=y --SETUP_OSC=y --MT1="/mnt/lustre1 OSCDEV1 MDCDEV1" --MT2="/mnt/lustre2 OSCDEV2 MDCDEV2" --MOUNT_LIST="MT1 MT2" --SETUP_MOUNT=y diff --cc lustre/tests/common.sh index 34e3b83,34e3b83..0000000 deleted file mode 100644,100644 --- a/lustre/tests/common.sh +++ /dev/null @@@ -1,713 -1,713 +1,0 @@@ --#!/bin/sh --export PATH=$PATH:/sbin:/usr/sbin -- --[ -d /r ] && R=/r -- --# check if running in source directory --# will probably need to create variable for each module. --if [ -f $SRCDIR/Makefile.am ]; then -- USEDEV=yes -- PORTALS=$SRCDIR/../../portals -- LUSTRE=$SRCDIR/.. -- -- PTLCTL=$LUSTRE/utils/lctl -- DBGCTL=$LUSTRE/utils/lctl -- ACCEPTOR=$PORTALS/linux/utils/acceptor -- -- OBDCTL=$LUSTRE/utils/lctl --else -- USEDEV=no -- # should have configure set the paths here -- BINDIR=/usr/sbin -- PORTALS=/lib/modules -- LUSTRE=/lib/modules -- -- PTLCTL=$BINDIR/lctl -- DBGCTL=$BINDIR/lctl -- ACCEPTOR=$BINDIR/acceptor -- OBDCTL=$BINDIR/lctl --fi -- --LOOPNUM=0; export LOOPNUM --if [ -b /dev/loop0 ]; then -- LOOP=/dev/loop --elif [ -b /dev/loop/0 ]; then -- LOOP=/dev/loop/ --else -- echo "Cannot find /dev/loop0 or /dev/loop/0" 1>&2 && exit -1 --fi -- --do_insmod() { -- MODULE=$1 -- BASE=`echo $MODULE | sed -e "s^.*/^^" -e "s/\.o$//"` -- -- lsmod | grep -q "\<$BASE\>" && return 0 -- [ "$MODULE" ] || fail "usage: $0 " -- -- if [ "$USEDEV" = "yes" ]; then -- [ -f $MODULE ] || echo "$0: module '$MODULE' not found" 1>&2 -- insmod $MODULE -- else -- modprobe $BASE -- fi --} -- --do_rmmod() { -- MODULE=$1 -- [ "$MODULE" ] || fail "usage: $0 " -- lsmod | grep -q $MODULE || return 0 -- rmmod $MODULE || lsmod | sed "s/^/$MODULE failed: /" --} -- --# Return the next unused loop device on stdout and in the $LOOPDEV --# environment variable. --next_loop_dev() { -- NEXT= -- while [ -b ${LOOP}${LOOPNUM} ]; do -- LOOPDEV=${LOOP}${LOOPNUM} -- losetup ${LOOPDEV} > /dev/null 2>&1 || NEXT=${LOOPDEV} -- LOOPNUM=`expr ${LOOPNUM} + 1` -- [ "$NEXT" ] && echo ${NEXT} && break -- done --} -- --# Create a new filesystem. If we are using a loopback device, we check --# for existing "template" filesystems instead of creating a new one, --# because it is _much_ faster to gunzip the empty filesystem instead of --# creating a new one from scratch. Conversely, if we are creating a --# filesystem on a device we use mkfs, because that only writes sparsely --# to the device. The empty filesystems are also highly compressed (1000:1) --# so they don't take too much space. --# --new_fs_usage() { -- echo "new_fs {device | file} [size]" 1>&2 -- exit -1 --} --new_fs () { -- EFILE="$1_$3.gz" -- MKFS="mkfs.$1" -- MKFSOPT="-b 4096" -- -- [ "$1" = "ext3" ] && MKFS="mkfs.ext2 -j" -- if [ "$1" = "extN" ]; then -- MKFS="mkfs.ext2 -j" -- EFILE="ext3_$3.gz" -- fi -- -- if [ -b "$2" ]; then -- [ $# -lt 2 -o $# -gt 3 ] && new_fs_usage -- -- PM="/proc/mounts" -- [ -r "$PM" ] || PM="/etc/mtab" -- -- grep "$2 " $PM 1>&2 && echo "$0: $2 is in $PM!" 1>&2 && exit -1 -- -- $MKFS $MKFSOPT $2 $3 || exit -1 -- LOOPDEV=$2 # Not really a loop device -- else -- [ $# -ne 3 ] && new_fs_usage -- -- if [ -r "$EFILE" ]; then -- echo "using prepared filesystem $EFILE for $2" -- zcat "$EFILE" > $2 || exit -1 -- sync -- else -- echo "creating new sparse filesystem on $2" -- dd if=/dev/zero of=$2 bs=1k seek=$3 count=1 1>&2 || exit -1 -- $MKFS $MKFSOPT -F $2 1>&2 || exit -1 -- fi -- LOOPDEV=`next_loop_dev` -- losetup ${LOOPDEV} $2 1>&2 || exit -1 -- fi -- -- # Enable hash-indexed directories for extN filesystems -- [ "$1" = "extN" ] && echo "feature FEATURE_C5" | debugfs -w $2 --} -- --# Set up to use an existing filesystem. We take the same parameters as --# new_fs, even though we only use the and parameters, to --# make it easy to convert between new_fs and old_fs in testing scripts. --old_fs () { -- [ -e $2 ] || exit -1 -- -- if [ -b "$2" ]; then -- LOOPDEV=$2 # Not really a loop device -- else -- LOOPDEV=`next_loop_dev` -- losetup ${LOOPDEV} $2 1>&2 || exit -1 -- fi --} -- --list_mods() { -- $DBGCTL modules > $R/tmp/ogdb -- echo "The GDB module script is in $R/tmp/ogdb" -- [ "$DEBUG_WAIT" = "yes" ] && echo -n "Press ENTER to continue" && read < /dev/tty -- return 0 --} -- --# start acceptor for a given network and port. --# not all networks need an acceptor --start_acceptor() { -- case $NETWORK in -- elan) [ "$PORT" ] && fail "$0: NETWORK is elan but PORT is set" -- ;; -- tcp) [ "$PORT" ] || fail "$0: NETWORK is tcp but PORT is not set" -- $ACCEPTOR -r 1048576 -s 1048576 $PORT -- ;; -- *) fail "$0: unknown NETWORK '$NETWORK'" ;; -- esac -- --} -- --# We need at least one setup file to be given. It can be passed on --# the command-line, or it can be found in the home directory, or it --# can even be sourced into the current shell environment. --setup_opts() { -- DEF=/etc/lustre/lustre.cfg -- if [ "$#" = 0 -a -r $DEF ]; then -- . $DEF && SETUP=y -- fi -- -- for CFG in "$@" ; do -- case $CFG in -- *.cfg) [ -r "$CFG" ] && . $CFG && SETUP=y ;; -- *) echo "unknown option '$CFG'" 1>&2 -- esac -- done -- -- if [ "$SETUP" != "y" ]; then -- echo "error: no config file on command-line and no $DEF" 1>&2 -- exit -1 -- fi -- -- [ "$MDC_NAMES" ] || export MDC_NAMES=MDCDEV -- [ "$OSC_NAMES" ] || export OSC_NAMES=OSCDEV -- [ -z "$MOUNT_LIST" -a "$OSCMT" ] && export MOUNT_LIST="MT" && export MT="$OSCMT OSCDEV MDCDEV" --} -- --setup_variables() { -- [ -z "$OSTNODE" ] && OSTNODE=$SERVER -- [ -z "$MDSNODE" ] && MDSNODE=$SERVER -- [ -z "$DLM" ] && DLM=$SERVER --} -- --setup_portals() { -- setup_variables -- -- if egrep -q "ksocknal|kqswnal" /proc/modules; then -- echo "$0: portals already appears to be set up, skipping" -- return 0 -- fi -- -- if [ -z "$NETWORK" -o -z "$LOCALHOST" ]; then -- echo "$0: NETWORK or LOCALHOST is not set" 1>&2 -- exit -1 -- fi -- -- if [ -z "$OSTNODE" -a -z "$MDSNODE" -a -z "$DLM" ]; then -- echo "$0: SERVER (or OSTNODE and MDSNODE and DLM) not set" 1>&2 -- exit -1 -- fi -- -- [ -c /dev/portals ] || mknod /dev/portals c 10 240 -- -- do_insmod $PORTALS/linux/oslib/portals.o || exit -1 -- #do_insmod $PORTALS/linux/router/kptlrouter.o || exit -1 -- -- case $NETWORK in -- elan) do_insmod $PORTALS/linux/rqswnal/kqswnal.o || exit -1 -- MYNID= -- RECV_MEM= -- SEND_MEM= -- ;; -- tcp) do_insmod $PORTALS/linux/socknal/ksocknal.o || exit -1 -- MYNID="mynid $LOCALHOST" -- RECV_MEM="recv_mem 1048576" -- SEND_MEM="send_mem 1048576" -- ;; -- *) fail "$0: unknown NETWORK '$NETWORK'" ;; -- esac -- -- start_acceptor -- -- $PTLCTL <<- EOF -- network $NETWORK -- $SEND_MEM -- $RECV_MEM -- $MYNID -- connect $DLM $PORT -- add_uuid $DLM $DLM -- add_uuid self $LOCALHOST -- quit -- EOF -- -- if [ "$SETUP_MDS" -o "$SETUP_MDC" ]; then -- $PTLCTL <<- EOF -- network $NETWORK -- connect $MDSNODE $PORT -- add_uuid $MDSNODE $MDSNODE -- quit -- EOF -- fi -- -- -- if [ "$SETUP_OST" -o "$SETUP_OSC" ]; then -- $PTLCTL <<- EOF -- network $NETWORK -- connect $OSTNODE $PORT -- add_uuid $OSTNODE $OSTNODE -- quit -- EOF -- fi --} -- --setup_lustre() { -- [ -c /dev/obd ] || mknod /dev/obd c 10 241 -- -- do_insmod $LUSTRE/obdclass/obdclass.o || exit -1 -- do_insmod $LUSTRE/ptlrpc/ptlrpc.o || exit -1 -- do_insmod $LUSTRE/ldlm/ldlm.o || exit -1 -- do_insmod $LUSTRE/extN/extN.o || \ -- echo "info: can't load extN.o module, not fatal if using ext3" -- do_insmod $LUSTRE/mds/mds.o || exit -1 -- #do_insmod $LUSTRE/mds/mds_ext2.o || exit -1 -- #do_insmod $LUSTRE/mds/mds_ext3.o || exit -1 -- do_insmod $LUSTRE/mds/mds_extN.o || \ -- echo "info: can't load mds_extN.o module, needs extN.o" -- do_insmod $LUSTRE/obdecho/obdecho.o || exit -1 -- #do_insmod $LUSTRE/obdext2/obdext2.o || exit -1 -- do_insmod $LUSTRE/obdfilter/obdfilter.o || exit -1 -- do_insmod $LUSTRE/ost/ost.o || exit -1 -- do_insmod $LUSTRE/osc/osc.o || exit -1 -- do_insmod $LUSTRE/mdc/mdc.o || exit -1 -- do_insmod $LUSTRE/lov/lov.o || exit -1 -- do_insmod $LUSTRE/llite/llite.o || exit -1 -- -- echo "$R/tmp/lustre-log" > /proc/sys/portals/debug_path -- -- if $OBDCTL name2dev RPCDEV > /dev/null 2>&1; then -- echo "$0: RPCDEV is already configured, skipping" -- return 0 -- fi -- list_mods -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach ptlrpc RPCDEV -- setup -- quit -- EOF -- -- [ -d /mnt/lustre ] || mkdir /mnt/lustre --} -- --setup_ldlm() { -- [ "$SETUP_LDLM" = "y" ] || return 0 -- -- [ -c /dev/portals ] || mknod /dev/portals c 10 240 -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach ldlm LDLMDEV LDLMUUID -- setup -- quit -- EOF --} -- --find_devno() { -- if [ -z "$1" ]; then -- echo "usage: $0 " 1>&2 -- return -1 -- fi -- -- $OBDCTL name2dev $1 --} -- --setup_mds() { -- [ "$SETUP_MDS" = "y" ] || return 0 -- -- if [ -z "$MDSFS" -o -z "$MDSDEV" ]; then -- echo "error: setup_mds: MDSFS or MDSDEV unset" 1>&2 -- return -1 -- fi -- -- [ "$1" ] && DO_FS=$1 -- if [ "$DO_FS" != "new_fs" -a "$DO_FS" != "old_fs" ]; then -- echo "usage: setup_mds {new_fs|old_fs}" 1>&2 -- return -1 -- fi -- -- if $OBDCTL name2dev MDSDEV > /dev/null 2>&1; then -- echo "$0: MDSDEV is already configured" -- return 0 -- fi -- -- $DO_FS ${MDSFS} ${MDSDEV} ${MDSSIZE} -- MDS=${LOOPDEV} -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach mds MDSDEV MDSUUID -- setup ${MDS} ${MDSFS} -- quit -- EOF --} -- --setup_mds_lov() { -- [ "$SETUP_MDS" = "y" ] || return 0 -- -- if [ -z "$LOVUUID" ]; then -- echo "No LOV configured" -- return -- fi -- -- $OBDCTL <<- EOF || return $? -- name2dev MDSDEV -- connect -- lov_setconfig ${LOVUUID} 1 65536 0 OSCDEV-`hostname` -- disconnect -- quit -- EOF --} -- -- --setup_ost() { -- [ "$SETUP_OST" = "y" ] || return 0 -- -- if [ -z "$OSTTYPE" ]; then -- echo "error: setup_ost: OSTTYPE unset" 1>&2 -- return -1 -- fi -- -- case $OSTTYPE in -- obdecho) OBD= -- OBDARG= -- NEED_FS=n -- ;; -- obdext2) OBDARG= -- NEED_FS=y -- ;; -- obdfilter) OBDARG=$OSTFS -- NEED_FS=y -- ;; -- *) echo "error: setup_ost: unknown OSTTYPE '$OSTTYPE'" 1>&2 -- return -1 -- ;; -- esac -- -- if $OBDCTL name2dev OBDDEV > /dev/null 2>&1; then -- echo "$0: OBDDEV is already configured" -- return 0 -- fi -- -- if [ "$NEED_FS" = "y" ]; then -- [ "$1" ] && DO_FS=$1 -- if [ -z "$OSTFS" -o -z "$OSTDEV" ]; then -- echo "error: setup_ost: OSTFS or OSTDEV unset" 1>&2 -- return -1 -- fi -- -- if [ "$DO_FS" != "new_fs" -a "$DO_FS" != "old_fs" ]; then -- echo "usage: setup_ost {new_fs|old_fs}" 1>&2 -- return -1 -- fi -- -- $DO_FS ${OSTFS} ${OSTDEV} ${OSTSIZE} -- OBD=${LOOPDEV} -- fi -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach ${OSTTYPE} OBDDEV OBDUUID -- setup ${OBD} ${OBDARG} -- quit -- EOF -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach ost OSTDEV OSTUUID -- setup OBDUUID -- quit -- EOF --} -- --setup_server() { -- #setup_mds $1 && setup_mds_lov $1 && setup_ost $1 -- setup_mds $1 && setup_ost $1 --} -- --setup_osc() { -- [ "$SETUP_OSC" != "y" ] && return 0 -- [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV -- -- for THEOSC in $OSC_NAMES ; do -- if $OBDCTL name2dev $THEOSC > /dev/null 2>&1; then -- echo "$0: OSCDEV is already configured" -- continue -- fi -- -- [ -z "$OBD_UUID" ] && OBD_UUID="OBDUUID" -- $OBDCTL <<- EOF || return $rc -- newdev -- attach osc $THEOSC ${THEOSC}-`hostname` -- setup $OBD_UUID $OSTNODE -- quit -- EOF -- done --} -- --setup_mdc() { -- [ "$SETUP_MDC" != "y" ] && return 0 -- [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV -- -- for THEMDC in $MDC_NAMES ; do -- if $OBDCTL name2dev $THEMDC > /dev/null 2>&1; then -- echo "$0: MDCDEV is already configured" -- continue -- fi -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach mdc $THEMDC ${THEMDC}-`hostname` -- setup MDSUUID $MDSNODE -- quit -- EOF -- done --} -- --setup_lov () { -- [ "$SETUP_MDC" != "y" ] && return 0 -- -- if [ -z "$LOVUUID" ]; then -- echo "No LOV configured" -- return -- fi -- -- $OBDCTL <<- EOF || return $? -- newdev -- attach lov LOVNAME ${LOVUUID} -- setup MDCDEV-`hostname` -- quit -- EOF --} -- -- --setup_mount() { -- [ "$SETUP_MOUNT" != "y" ] && return 0 -- -- [ "$MOUNT_LIST" ] || fail "error: $0: MOUNT_LIST unset" -- -- for THEMOUNT in $MOUNT_LIST; do -- eval "echo \$$THEMOUNT" | while read MTPT THEOSC THEMDC; do -- if mount | grep -q $MTPT; then -- echo "$0: $MTPT is already mounted" -- return 0 -- fi -- -- [ ! -d $MTPT ] && mkdir $MTPT -- echo mount -t lustre_lite -o osc=${THEOSC}-`hostname`,mdc=${THEMDC}-`hostname` none $MTPT -- mount -t lustre_lite -o osc=${THEOSC}-`hostname`,mdc=${THEMDC}-`hostname` none $MTPT -- done -- done --} -- --setup_client() { -- # setup_osc && setup_mdc && setup_lov && setup_mount -- setup_osc && setup_mdc && setup_mount --} -- --DEBUG_ON="echo 0xffffffff > /proc/sys/portals/debug" --DEBUG_OFF="echo 0 > /proc/sys/portals/debug" -- --debug_server_off() { -- echo "Turn OFF debug" && eval "$DEBUG_OFF" --} -- --debug_server_on() { -- echo "Turn ON debug" && eval "$DEBUG_ON" --} -- --debug_client_off() { -- echo "Turning OFF debug on client" && eval "$DEBUG_OFF" --} -- --debug_client_on() { -- echo "Turning ON debug on client" && eval "$DEBUG_ON" --} -- --cleanup_portals() { -- [ -z "$NETWORK" ] && NETWORK=tcp -- -- setup_variables -- -- $PTLCTL <<- EOF -- network $NETWORK -- disconnect -- del_uuid self -- del_uuid $MDSNODE -- del_uuid $OSTNODE -- del_uuid $DLM -- quit -- EOF -- -- do_rmmod ldlm -- do_rmmod ptlrpc -- do_rmmod obdclass -- -- do_rmmod kqswnal -- do_rmmod ksocknal -- do_rmmod kptlrouter -- -- [ "$TIME" ] && $DBGCTL debug_kernel $R/tmp/debug.5.$TIME -- -- do_rmmod portals --} -- --cleanup_lustre() { -- killall acceptor -- -- do_rmmod llite -- do_rmmod lov -- do_rmmod mdc -- do_rmmod osc -- -- do_rmmod mds_extN -- do_rmmod mds_ext3 -- do_rmmod mds_ext2 -- do_rmmod mds -- do_rmmod ost -- do_rmmod obdecho -- do_rmmod obdfilter -- do_rmmod obdext2 -- do_rmmod extN -- -- losetup -d ${LOOP}0 -- losetup -d ${LOOP}1 -- losetup -d ${LOOP}2 --} -- --cleanup_ldlm() { -- [ "$SETUP" -a -z "$SETUP_LDLM" ] && return 0 -- -- LDLMDEVNO=`find_devno LDLMDEV` -- if [ "$LDLMDEVNO" ]; then -- $OBDCTL <<- EOF -- device $LDLMDEVNO -- cleanup -- detach -- quit -- EOF -- fi --} -- --cleanup_mds() { -- [ "$SETUP" -a -z "$SETUP_MDS" ] && return 0 -- -- MDSDEVNO=`find_devno MDSDEV` -- if [ "$MDSDEVNO" ]; then -- $OBDCTL <<- EOF -- device $MDSDEVNO -- cleanup -- detach -- quit -- EOF -- fi --} -- --cleanup_ost() { -- [ "$SETUP" -a -z "$SETUP_OST" ] && return 0 -- -- OSTDEVNO=`find_devno OSTDEV` -- if [ "$OSTDEVNO" ]; then -- $OBDCTL <<- EOF -- device $OSTDEVNO -- cleanup -- detach -- quit -- EOF -- fi -- -- OBDDEVNO=`find_devno OBDDEV` -- if [ "$OBDDEVNO" ]; then -- $OBDCTL <<- EOF -- device $OBDDEVNO -- cleanup -- detach -- quit -- EOF -- fi --} -- --cleanup_server() { -- cleanup_ost && cleanup_mds --} -- --cleanup_mount() { -- [ "$SETUP_MOUNT" != "y" ] && return 0 -- -- [ "$MOUNT_LIST" ] || fail "error: $0: MOUNT_LIST unset" -- -- for THEMOUNT in $MOUNT_LIST; do -- eval "echo \$$THEMOUNT" | while read MTPT THEOSC THEMDC; do -- if [ "`mount | grep $MTPT`" ]; then -- umount $MTPT || fail "unable to unmount $MTPT" -- fi -- done -- done --} -- --cleanup_osc() { -- [ "$SETUP" -a -z "$SETUP_OSC" ] && return 0 -- [ "$OSC_NAMES" ] || OSC_NAMES=OSCDEV -- -- for THEOSC in $OSC_NAMES ; do -- OSCDEVNO=`find_devno $THEOSC` -- if [ "$OSCDEVNO" ]; then -- $OBDCTL <<- EOF -- device $OSCDEVNO -- cleanup -- detach -- quit -- EOF -- fi -- done --} -- --cleanup_mdc() { -- [ "$SETUP" -a -z "$SETUP_MDC" ] && return 0 -- [ "$MDC_NAMES" ] || MDC_NAMES=MDCDEV -- -- for THEMDC in $MDC_NAMES ; do -- MDCDEVNO=`find_devno $THEMDC` -- if [ "$MDCDEVNO" ]; then -- $OBDCTL <<- EOF -- device $MDCDEVNO -- cleanup -- detach -- quit -- EOF -- fi -- done --} -- --cleanup_rpc() { -- RPCDEVNO=`find_devno RPCDEV` -- if [ "$RPCDEVNO" ]; then -- $OBDCTL <<- EOF -- device $RPCDEVNO -- cleanup -- detach -- quit -- EOF -- fi --} -- --cleanup_client() { -- cleanup_mount && cleanup_osc && cleanup_mdc && cleanup_rpc --} -- --fail() { -- echo "ERROR: $1" 1>&2 -- [ $2 ] && RC=$2 || RC=1 -- exit $RC --} diff --cc lustre/tests/create.pl index 952dac5,341d31b..0000000 deleted file mode 100644,100644 --- a/lustre/tests/create.pl +++ /dev/null @@@ -1,55 -1,61 +1,0 @@@ --#!/usr/bin/perl -use Getopt::Long; - -GetOptions("silent!"=> \$silent); -- --my $mtpt = shift || usage(); --my $mount_count = shift || usage(); --my $i = shift || usage(); --my $files = 5; --my $mcreate = 0; # should we use mcreate or open? -- --sub usage () { -- print "Usage: $0 \n"; -- print "example: $0 /mnt/lustre 2 50\n"; -- print " will test in /mnt/lustre1 and /mnt/lustre2\n"; -- print " $0 /mnt/lustre -1 50\n"; -- print " will test in /mnt/lustre only\n"; -- exit; --} -- --sub do_open($) { -- my $path = shift; -- -- if ($mcreate) { -- my $tmp = `./mcreate $path`; -- if ($tmp) { - print "Creating $path [" . $$."]...\n" if !$silent; -- $tmp =~ /.*error: (.*)\n/; - print "Created $path: $1\n"; - print "Create done [$$] $path: $!\n" if !$silent; -- } else { - print "Created $path: Success\n"; - print "Create done [$$] $path: Success\n"if !$silent; -- } -- } else { - print "Opening $path [" . $$."]...\n"if !$silent; -- open(FH, ">$path") || die "open($PATH): $!"; - print "Opened $path: Success\n"; - print "Open done [$$] $path: Success\n"if !$silent; -- close(FH) || die; -- } --} -- --while ($i--) { -- my $which = ""; -- if ($mount_count > 0) { -- $which = int(rand() * $mount_count) + 1; -- } -- $d = int(rand() * $files); -- do_open("$mtpt$which/$d"); -- -- if ($mount_count > 0) { -- $which = int(rand() * $mount_count) + 1; -- } -- $d = int(rand() * $files); -- $path = "$mtpt$which/$d"; - print "Unlink $path start [" . $$."]...\n"if !$silent; -- if (unlink($path)) { - print "Unlinked $path: Success\n"; - print "Unlink done [$$] $path: Success\n"if !$silent; -- } else { - print "Unlinked $path: $!\n"; - print "Unlink done [$$] $path: $!\n"if !$silent; -- } --} --print "Done.\n"; diff --cc lustre/tests/createdestroy.c index f1e7f4b,f1e7f4b..0000000 deleted file mode 100644,100644 --- a/lustre/tests/createdestroy.c +++ /dev/null @@@ -1,224 -1,224 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --int thread; -- --#define BAD_VERBOSE (-999999999) -- --#define difftime(a, b) \ -- ((double)(a)->tv_sec - (b)->tv_sec + \ -- ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) -- --static char *cmdname(char *func) --{ -- static char buf[512]; -- -- if (thread) { -- sprintf(buf, "%s-%d", func, thread); -- return buf; -- } -- -- return func; --} -- --static int be_verbose(int verbose, struct timeval *next_time, -- unsigned long num, unsigned long *next_num, int num_total) --{ -- struct timeval now; -- -- if (!verbose) -- return 0; -- -- if (next_time != NULL) -- gettimeofday(&now, NULL); -- -- /* A positive verbosity means to print every X iterations */ -- if (verbose > 0 && -- (next_num == NULL || num >= *next_num || num >= num_total)) { -- *next_num += verbose; -- if (next_time) { -- next_time->tv_sec = now.tv_sec - verbose; -- next_time->tv_usec = now.tv_usec; -- } -- return 1; -- } -- -- /* A negative verbosity means to print at most each X seconds */ -- if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){ -- next_time->tv_sec = now.tv_sec - verbose; -- next_time->tv_usec = now.tv_usec; -- if (next_num) -- *next_num = num; -- return 1; -- } -- -- return 0; --} -- --static int get_verbose(char *func, const char *arg) --{ -- int verbose; -- char *end; -- -- if (!arg || arg[0] == 'v') -- verbose = 1; -- else if (arg[0] == 's' || arg[0] == 'q') -- verbose = 0; -- else { -- verbose = (int)strtoul(arg, &end, 0); -- if (*end) { -- fprintf(stderr, "%s: error: bad verbose option '%s'\n", -- func, arg); -- return BAD_VERBOSE; -- } -- } -- -- if (verbose < 0) -- printf("Print status every %d seconds\n", -verbose); -- else if (verbose == 1) -- printf("Print status every operation\n"); -- else if (verbose > 1) -- printf("Print status every %d operations\n", verbose); -- -- return verbose; --} -- --int main(int argc, char *argv[]) --{ -- char filename[1024]; -- int verbose = 0; -- unsigned long count, i; -- int threads = 0; -- char *end; -- int rc; -- -- if (argc < 3 || argc > 5) { -- fprintf(stderr, -- "usage: %s [verbose [threads]]\n", -- argv[0]); -- exit(1); -- } -- -- count = strtoul(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, "%s: error: bad iteration count '%s'\n", -- argv[0], argv[1]); -- exit(2); -- } -- if (argc == 4) { -- verbose = get_verbose(argv[0], argv[3]); -- if (verbose == BAD_VERBOSE) -- exit(2); -- } -- if (argc == 5) { -- threads = strtoul(argv[4], &end, 0); -- if (*end) { -- fprintf(stderr, "%s: error: bad thread count '%s'\n", -- argv[0], argv[1]); -- exit(2); -- } -- } -- -- for (i = 1; i <= threads; i++) { -- rc = fork(); -- if (rc < 0) { -- fprintf(stderr, "%s: error: #%ld - %s\n", -- cmdname(argv[0]), i, strerror(rc = errno)); -- break; -- } else if (rc == 0) { -- thread = i; -- break; -- } else -- printf("%s: thread #%ld (PID %d) started\n", -- cmdname(argv[0]), i, rc); -- rc = 0; -- } -- -- if (threads && thread == 0) { /* parent process */ -- int live_threads = threads; -- -- while (live_threads > 0) { -- int status; -- pid_t ret; -- -- ret = waitpid(0, &status, 0); -- if (ret == 0) { -- continue; -- } -- -- if (ret < 0) { -- fprintf(stderr, "%s: error: wait - %s\n", -- argv[0], strerror(errno)); -- if (!rc) -- rc = errno; -- } else { -- /* -- * This is a hack. We _should_ be able to use -- * WIFEXITED(status) to see if there was an -- * error, but it appears to be broken and it -- * always returns 1 (OK). See wait(2). -- */ -- int err = WEXITSTATUS(status); -- if (err || WIFSIGNALED(status)) -- fprintf(stderr, -- "%s: error: PID %d had rc=%d\n", -- argv[0], ret, err); -- if (!rc) -- rc = err; -- -- live_threads--; -- } -- } -- } else { -- struct timeval start, end, next_time; -- unsigned long next_count; -- double diff; -- -- gettimeofday(&start, NULL); -- next_time.tv_sec = start.tv_sec - verbose; -- next_time.tv_usec = start.tv_usec; -- -- for (i = 0, next_count = verbose; i < count; i++) { -- if (threads) -- sprintf(filename, "%s-%d-%ld", -- argv[1], thread, i); -- else -- sprintf(filename, "%s-%ld", argv[1], i); -- -- rc = mknod(filename, S_IFREG, 0); -- if (rc < 0) { -- fprintf(stderr, "%s: error: mknod(%s): %s\n", -- cmdname(argv[0]), filename, -- strerror(errno)); -- rc = errno; -- break; -- } -- if (unlink(filename) < 0) { -- fprintf(stderr, "%s: error: unlink(%s): %s\n", -- cmdname(argv[0]), filename, -- strerror(errno)); -- rc = errno; -- break; -- } -- if (be_verbose(verbose, &next_time,i,&next_count,count)) -- printf("%s: number %ld\n", cmdname(argv[0]), i); -- } -- -- gettimeofday(&end, NULL); -- diff = difftime(&end, &start); -- -- printf("%s: %ldx2 files in %.4gs (%.4g ops/s): rc = %d: %s", -- cmdname(argv[0]), i, diff, (double)i * 2 / diff, -- rc, ctime(&end.tv_sec)); -- } -- return rc; --} diff --cc lustre/tests/createmany.c index 77015a6,77015a6..0000000 deleted file mode 100644,100644 --- a/lustre/tests/createmany.c +++ /dev/null @@@ -1,40 -1,40 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --int main(int argc, char ** argv) --{ -- int i, rc, count; -- char filename[4096]; -- -- if (argc < 3) { -- printf("Usage %s filenamebase count\n", argv[0]); -- return 1; -- } -- -- if (strlen(argv[1]) > 4080) { -- printf("name too long\n"); -- return 1; -- } -- -- count = strtoul(argv[2], NULL, 0); -- -- for (i=0 ; i < count ; i++) { -- sprintf(filename, "%s-%d", argv[1], i); -- rc = mknod(filename, S_IFREG| 0444, 0); -- if (rc) { -- printf("mknod(%s) error: %s\n", -- filename, strerror(errno)); -- break; -- } -- if ((i % 10000) == 0) -- printf(" - created %d (time %ld)\n", i, time(0)); -- } -- return rc; --} diff --cc lustre/tests/directio.c index e495517,e495517..0000000 deleted file mode 100644,100644 --- a/lustre/tests/directio.c +++ /dev/null @@@ -1,62 -1,62 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --// not correctly in the headers yet!! --#ifndef O_DIRECT --#define O_DIRECT 040000 /* direct disk access hint */ --#endif -- --#define BLOCKSIZE 4096 -- --int main(int argc, char **argv) --{ -- int fd; -- char *buf; -- int pages; -- int rc; -- -- if (argc != 3) { -- printf("Usage: %s file nr_pages\n", argv[0]); -- return 1; -- } -- -- pages = strtoul(argv[2], 0, 0); -- printf("directio on %s for %d pages \n", argv[1], pages); -- -- buf = mmap(0, pages * BLOCKSIZE, PROT_READ|PROT_WRITE, -- MAP_PRIVATE|MAP_ANON, 0, 0); -- if (!buf) { -- printf("No memory %s\n", strerror(errno)); -- return 1; -- } -- -- fd = open(argv[1], O_DIRECT | O_RDWR | O_CREAT); -- if (fd == -1) { -- printf("Cannot open %s: %s\n", argv[1], strerror(errno)); -- return 1; -- } -- -- rc = read(fd, buf, pages * BLOCKSIZE); -- if (rc != pages * BLOCKSIZE) { -- printf("Read error: %s, rc %d\n", strerror(errno), rc); -- return 1; -- } -- -- if ( lseek(fd, 0, SEEK_SET) != 0 ) { -- printf("Cannot seek %s\n", strerror(errno)); -- return 1; -- } -- -- rc = write(fd, buf, pages * BLOCKSIZE); -- if (rc != pages * BLOCKSIZE) { -- printf("Write error %s\n", strerror(errno)); -- return 1; -- } -- -- return 0; --} diff --cc lustre/tests/elan-client.cfg index 120b605,120b605..0000000 deleted file mode 100644,100644 --- a/lustre/tests/elan-client.cfg +++ /dev/null @@@ -1,5 -1,5 +1,0 @@@ --#!/bin/sh --# Config file for setting up a remote server with a real OST --NETWORK=elan --LOCALHOST=5 --SERVER=4 diff --cc lustre/tests/elan-server.cfg index 7520840,7520840..0000000 deleted file mode 100644,100644 --- a/lustre/tests/elan-server.cfg +++ /dev/null @@@ -1,5 -1,5 +1,0 @@@ --#!/bin/sh --# Config file for setting up a remote server with a real OST --NETWORK=elan --LOCALHOST=4 --SERVER=4 diff --cc lustre/tests/ext2_10000.gz index e700ad0,e700ad0..0000000 deleted file mode 100644,100644 Binary files differ diff --cc lustre/tests/ext2_25000.gz index 122ed79,122ed79..0000000 deleted file mode 100644,100644 Binary files differ diff --cc lustre/tests/ext3_10000.gz index b372fbd,b372fbd..0000000 deleted file mode 100644,100644 Binary files differ diff --cc lustre/tests/fs.sh index b158c6e,b158c6e..0000000 deleted file mode 100644,100644 --- a/lustre/tests/fs.sh +++ /dev/null @@@ -1,27 -1,27 +1,0 @@@ --#! /bin/bash --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution --#!/bin/sh -- --R=/r -- --insmod /lib/modules/2.4.17/kernel/drivers/block/loop.o --dd if=/dev/zero of=/tmp/fs bs=1024 count=10000 --mke2fs -b 4096 -F /tmp/fs --losetup /dev/loop/0 /tmp/fs -- --insmod $R/usr/src/lustre/obdclass/obdclass.o --insmod $R/usr/src/lustre/obdext2/obdext2.o --mknod /dev/obd c 10 241 -- --$R/usr/src/lustre/utils/obdctl < --#include --#if defined(_UWIN) || defined(__linux__) --# include --# include --# include --# include -# include --#endif --#include --#include --#ifndef MAP_FILE --# define MAP_FILE 0 --#endif --#include --#include --#include --#include --#include --#include --#include --#include -- --#define NUMPRINTCOLUMNS 32 /* # columns of data to print on each line */ -- --/* -- * A log entry is an operation and a bunch of arguments. -- */ -- --struct log_entry { -- int operation; - struct timeval tv; -- int args[3]; --}; -- --#define LOGSIZE 1000 -- --struct log_entry oplog[LOGSIZE]; /* the log */ --int logptr = 0; /* current position in log */ --int logcount = 0; /* total ops */ -- --/* -- * Define operations -- */ -- --#define OP_READ 1 --#define OP_WRITE 2 --#define OP_TRUNCATE 3 --#define OP_CLOSEOPEN 4 --#define OP_MAPREAD 5 --#define OP_MAPWRITE 6 --#define OP_SKIPPED 7 -- --int page_size; --int page_mask; -- --char *original_buf; /* a pointer to the original data */ --char *good_buf; /* a pointer to the correct data */ --char *temp_buf; /* a pointer to the current data */ --char *fname; /* name of our test file */ -char logfile[1024]; /* name of our log file */ -char goodfile[1024]; /* name of our test file */ --int fd; /* fd for our test file */ -- --off_t file_size = 0; --off_t biggest = 0; --char state[256]; --unsigned long testcalls = 0; /* calls to function "test" */ -- --unsigned long simulatedopcount = 0; /* -b flag */ --int closeprob = 0; /* -c flag */ --int debug = 0; /* -d flag */ --unsigned long debugstart = 0; /* -D flag */ --unsigned long maxfilelen = 256 * 1024; /* -l flag */ --int sizechecks = 1; /* -n flag disables them */ --int maxoplen = 64 * 1024; /* -o flag */ --int quiet = 0; /* -q flag */ --unsigned long progressinterval = 0; /* -p flag */ --int readbdy = 1; /* -r flag */ --int style = 0; /* -s flag */ --int truncbdy = 1; /* -t flag */ --int writebdy = 1; /* -w flag */ --long monitorstart = -1; /* -m flag */ --long monitorend = -1; /* -m flag */ --int lite = 0; /* -L flag */ --long numops = -1; /* -N flag */ --int randomoplen = 1; /* -O flag disables it */ --int seed = 1; /* -S flag */ --int mapped_writes = 1; /* -W flag disables */ --int mapped_reads = 1; /* -R flag disables it */ --int fsxgoodfd = 0; --FILE * fsxlogf = NULL; --int badoff = -1; --int closeopen = 0; -- -- --void --vwarnc(code, fmt, ap) -- int code; -- const char *fmt; -- va_list ap; --{ -- fprintf(stderr, "fsx: "); -- if (fmt != NULL) { -- vfprintf(stderr, fmt, ap); -- fprintf(stderr, ": "); -- } -- fprintf(stderr, "%s\n", strerror(code)); --} -- -- --void --warn(const char * fmt, ...) --{ -- va_list ap; -- va_start(ap, fmt); -- vwarnc(errno, fmt, ap); -- va_end(ap); --} -- -- --void --prt(char *fmt, ...) --{ -- va_list args; -- -- va_start(args, fmt); -- vfprintf(stdout, fmt, args); -- if (fsxlogf) -- vfprintf(fsxlogf, fmt, args); -- va_end(args); --} -- --void --prterr(char *prefix) --{ -- prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno)); --} -- -- --void - log4(int operation, int arg0, int arg1, int arg2) -log4(int operation, int arg0, int arg1, int arg2, struct timeval *tv) --{ -- struct log_entry *le; -- -- le = &oplog[logptr]; - le->tv = *tv; -- le->operation = operation; -- if (closeopen) -- le->operation = ~ le->operation; -- le->args[0] = arg0; -- le->args[1] = arg1; -- le->args[2] = arg2; -- logptr++; -- logcount++; -- if (logptr >= LOGSIZE) -- logptr = 0; --} -- -- --void --logdump(void) --{ -- int i, count, down; -- struct log_entry *lp; -- -- prt("LOG DUMP (%d total operations):\n", logcount); -- if (logcount < LOGSIZE) { -- i = 0; -- count = logcount; -- } else { -- i = logptr; -- count = LOGSIZE; -- } -- for ( ; count > 0; count--) { -- int opnum; -- -- opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE; - prt("%d(%d mod 256): ", opnum, opnum%256); -- lp = &oplog[i]; - prt("%d(%d mod 256): %lu.%lu ", opnum, opnum%256, - lp->tv.tv_sec, lp->tv.tv_usec); -- if ((closeopen = lp->operation < 0)) -- lp->operation = ~ lp->operation; -- -- switch (lp->operation) { -- case OP_MAPREAD: -- prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)", -- lp->args[0], lp->args[0] + lp->args[1] - 1, -- lp->args[1]); -- if (badoff >= lp->args[0] && badoff < -- lp->args[0] + lp->args[1]) -- prt("\t***RRRR***"); -- break; -- case OP_MAPWRITE: -- prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)", -- lp->args[0], lp->args[0] + lp->args[1] - 1, -- lp->args[1]); -- if (badoff >= lp->args[0] && badoff < -- lp->args[0] + lp->args[1]) -- prt("\t******WWWW"); -- break; -- case OP_READ: -- prt("READ\t0x%x thru 0x%x\t(0x%x bytes)", -- lp->args[0], lp->args[0] + lp->args[1] - 1, -- lp->args[1]); -- if (badoff >= lp->args[0] && -- badoff < lp->args[0] + lp->args[1]) -- prt("\t***RRRR***"); -- break; -- case OP_WRITE: -- prt("WRITE\t0x%x thru 0x%x\t(0x%x bytes)", -- lp->args[0], lp->args[0] + lp->args[1] - 1, -- lp->args[1]); -- if (lp->args[0] > lp->args[2]) -- prt(" HOLE"); -- else if (lp->args[0] + lp->args[1] > lp->args[2]) -- prt(" EXTEND"); -- if ((badoff >= lp->args[0] || badoff >=lp->args[2]) && -- badoff < lp->args[0] + lp->args[1]) -- prt("\t***WWWW"); -- break; -- case OP_TRUNCATE: -- down = lp->args[0] < lp->args[1]; -- prt("TRUNCATE %s\tfrom 0x%x to 0x%x", -- down ? "DOWN" : "UP", lp->args[1], lp->args[0]); -- if (badoff >= lp->args[!down] && -- badoff < lp->args[!!down]) -- prt("\t******WWWW"); -- break; -- case OP_SKIPPED: -- prt("SKIPPED (no operation)"); -- break; -- default: -- prt("BOGUS LOG ENTRY (operation code = %d)!", -- lp->operation); -- } -- if (closeopen) -- prt("\n\t\tCLOSE/OPEN"); -- prt("\n"); -- i++; -- if (i == LOGSIZE) -- i = 0; -- } --} -- -- --void --save_buffer(char *buffer, off_t bufferlength, int fd) --{ -- off_t ret; -- ssize_t byteswritten; -- -- if (fd <= 0 || bufferlength == 0) -- return; -- -- if (bufferlength > SSIZE_MAX) { -- prt("fsx flaw: overflow in save_buffer\n"); -- exit(67); -- } -- if (lite) { -- off_t size_by_seek = lseek(fd, (off_t)0, SEEK_END); -- if (size_by_seek == (off_t)-1) -- prterr("save_buffer: lseek eof"); -- else if (bufferlength > size_by_seek) { -- warn("save_buffer: .fsxgood file too short... will --save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek, -- (unsigned long long)bufferlength); -- bufferlength = size_by_seek; -- } -- } -- -- ret = lseek(fd, (off_t)0, SEEK_SET); -- if (ret == (off_t)-1) -- prterr("save_buffer: lseek 0"); -- -- byteswritten = write(fd, buffer, (size_t)bufferlength); -- if (byteswritten != bufferlength) { -- if (byteswritten == -1) -- prterr("save_buffer write"); -- else -- warn("save_buffer: short write, 0x%x bytes instead --of 0x%llx\n", -- (unsigned)byteswritten, -- (unsigned long long)bufferlength); -- } --} -- -- --void --report_failure(int status) --{ -- logdump(); -- -- if (fsxgoodfd) { -- if (good_buf) { -- save_buffer(good_buf, file_size, fsxgoodfd); -- prt("Correct content saved for comparison\n"); - prt("(maybe hexdump \"%s\" vs \"%s.fsxgood\")\n", - fname, fname); - prt("(maybe hexdump \"%s\" vs \"%s\")\n", - fname, goodfile); -- } -- close(fsxgoodfd); -- } -- exit(status); --} -- -- --#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \ -- *(((unsigned char *)(cp)) + 1))) -- --void --check_buffers(unsigned offset, unsigned size) --{ -- unsigned char c, t; -- unsigned i = 0; -- unsigned n = 0; -- unsigned op = 0; -- unsigned bad = 0; -- -- if (memcmp(good_buf + offset, temp_buf, size) != 0) { -- prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n", -- offset, size); -- prt("OFFSET\tGOOD\tBAD\tRANGE\n"); -- while (size > 0) { -- c = good_buf[offset]; -- t = temp_buf[i]; -- if (c != t) { -- if (n == 0) { -- bad = short_at(&temp_buf[i]); -- prt("0x%5x\t0x%04x\t0x%04x", offset, -- short_at(&good_buf[offset]), bad); -- op = temp_buf[offset & 1 ? i+1 : i]; -- } -- n++; -- badoff = offset; -- } -- offset++; -- i++; -- size--; -- } -- if (n) { -- prt("\t0x%5x\n", n); -- if (bad) -- prt("operation# (mod 256) for the bad data --may be %u\n", ((unsigned)op & 0xff)); -- else -- prt("operation# (mod 256) for the bad data --unknown, check HOLE and EXTEND ops\n"); -- } else -- prt("????????????????\n"); -- report_failure(110); -- } --} -- -- --void --check_size(void) --{ -- struct stat statbuf; -- off_t size_by_seek; -- -- if (fstat(fd, &statbuf)) { -- prterr("check_size: fstat"); -- statbuf.st_size = -1; -- } -- size_by_seek = lseek(fd, (off_t)0, SEEK_END); -- if (file_size != statbuf.st_size || file_size != size_by_seek) { -- prt("Size error: expected 0x%llx stat 0x%llx seek 0x%llx\n", -- (unsigned long long)file_size, -- (unsigned long long)statbuf.st_size, -- (unsigned long long)size_by_seek); -- report_failure(120); -- } --} -- -- --void --check_trunc_hack(void) --{ -- struct stat statbuf; -- -- ftruncate(fd, (off_t)0); -- ftruncate(fd, (off_t)100000); -- fstat(fd, &statbuf); -- if (statbuf.st_size != (off_t)100000) { -- prt("no extend on truncate! not posix!\n"); -- exit(130); -- } -- ftruncate(fd, 0); --} -- -- --void --doread(unsigned offset, unsigned size) --{ - struct timeval t; -- off_t ret; -- unsigned iret; -- -- offset -= offset % readbdy; - gettimeofday(&t, NULL); -- if (size == 0) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping zero size read\n"); - log4(OP_SKIPPED, OP_READ, offset, size); - log4(OP_SKIPPED, OP_READ, offset, size, &t); -- return; -- } -- if (size + offset > file_size) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping seek/read past end of file\n"); - log4(OP_SKIPPED, OP_READ, offset, size); - log4(OP_SKIPPED, OP_READ, offset, size, &t); -- return; -- } -- - log4(OP_READ, offset, size, 0); - log4(OP_READ, offset, size, 0, &t); -- -- if (testcalls <= simulatedopcount) -- return; -- -- if (!quiet && ((progressinterval && -- testcalls % progressinterval == 0) || -- (debug && -- (monitorstart == -1 || -- (offset + size > monitorstart && -- (monitorend == -1 || offset <= monitorend)))))) - prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, - offset, offset + size - 1, size); - prt("%lu %lu.%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); -- ret = lseek(fd, (off_t)offset, SEEK_SET); -- if (ret == (off_t)-1) { -- prterr("doread: lseek"); -- report_failure(140); -- } -- iret = read(fd, temp_buf, size); -- if (iret != size) { -- if (iret == -1) -- prterr("doread: read"); -- else -- prt("short read: 0x%x bytes instead of 0x%x\n", -- iret, size); -- report_failure(141); -- } -- check_buffers(offset, size); --} -- -- --void --domapread(unsigned offset, unsigned size) --{ - struct timeval t; -- unsigned pg_offset; -- unsigned map_size; -- char *p; -- -- offset -= offset % readbdy; - gettimeofday(&t, NULL); -- if (size == 0) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping zero size read\n"); - log4(OP_SKIPPED, OP_MAPREAD, offset, size); - log4(OP_SKIPPED, OP_MAPREAD, offset, size, &t); -- return; -- } -- if (size + offset > file_size) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping seek/read past end of file\n"); - log4(OP_SKIPPED, OP_MAPREAD, offset, size); - log4(OP_SKIPPED, OP_MAPREAD, offset, size, &t); -- return; -- } -- - log4(OP_MAPREAD, offset, size, 0); - log4(OP_MAPREAD, offset, size, 0, &t); -- -- if (testcalls <= simulatedopcount) -- return; -- -- if (!quiet && ((progressinterval && -- testcalls % progressinterval == 0) || -- (debug && -- (monitorstart == -1 || -- (offset + size > monitorstart && -- (monitorend == -1 || offset <= monitorend)))))) - prt("%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, - offset, offset + size - 1, size); - prt("%lu %lu.%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); -- -- pg_offset = offset & page_mask; -- map_size = pg_offset + size; -- - if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE | - MAP_SHARED, fd, - if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd, -- (off_t)(offset - pg_offset))) == (char *)-1) { -- prterr("domapread: mmap"); -- report_failure(190); -- } -- memcpy(temp_buf, p + pg_offset, size); -- if (munmap(p, map_size) != 0) { -- prterr("domapread: munmap"); -- report_failure(191); -- } -- -- check_buffers(offset, size); --} -- -- --void --gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size) --{ -- while (size--) { -- good_buf[offset] = testcalls % 256; -- if (offset % 2) -- good_buf[offset] += original_buf[offset]; -- offset++; -- } --} -- -- --void --dowrite(unsigned offset, unsigned size) --{ - struct timeval t; -- off_t ret; -- unsigned iret; -- -- offset -= offset % writebdy; - gettimeofday(&t, NULL); -- if (size == 0) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping zero size write\n"); - log4(OP_SKIPPED, OP_WRITE, offset, size); - log4(OP_SKIPPED, OP_WRITE, offset, size, &t); -- return; -- } -- - log4(OP_WRITE, offset, size, file_size); - log4(OP_WRITE, offset, size, file_size, &t); -- -- gendata(original_buf, good_buf, offset, size); -- if (file_size < offset + size) { -- if (file_size < offset) -- memset(good_buf + file_size, '\0', offset - file_size); -- file_size = offset + size; -- if (lite) { -- warn("Lite file size bug in fsx!"); -- report_failure(149); -- } -- } -- -- if (testcalls <= simulatedopcount) -- return; -- -- if (!quiet && ((progressinterval && -- testcalls % progressinterval == 0) || -- (debug && -- (monitorstart == -1 || -- (offset + size > monitorstart && -- (monitorend == -1 || offset <= monitorend)))))) - prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, - offset, offset + size - 1, size); - prt("%lu %lu.%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); -- ret = lseek(fd, (off_t)offset, SEEK_SET); -- if (ret == (off_t)-1) { -- prterr("dowrite: lseek"); -- report_failure(150); -- } -- iret = write(fd, good_buf + offset, size); -- if (iret != size) { -- if (iret == -1) -- prterr("dowrite: write"); -- else -- prt("short write: 0x%x bytes instead of 0x%x\n", -- iret, size); -- report_failure(151); -- } --} -- -- --void --domapwrite(unsigned offset, unsigned size) --{ - struct timeval t; -- unsigned pg_offset; -- unsigned map_size; -- off_t cur_filesize; -- char *p; -- -- offset -= offset % writebdy; - gettimeofday(&t, NULL); -- if (size == 0) { -- if (!quiet && testcalls > simulatedopcount) -- prt("skipping zero size write\n"); - log4(OP_SKIPPED, OP_MAPWRITE, offset, size); - log4(OP_SKIPPED, OP_MAPWRITE, offset, size, &t); -- return; -- } -- cur_filesize = file_size; -- - log4(OP_MAPWRITE, offset, size, 0); - log4(OP_MAPWRITE, offset, size, 0, &t); -- -- gendata(original_buf, good_buf, offset, size); -- if (file_size < offset + size) { -- if (file_size < offset) -- memset(good_buf + file_size, '\0', offset - file_size); -- file_size = offset + size; -- if (lite) { -- warn("Lite file size bug in fsx!"); -- report_failure(200); -- } -- } -- -- if (testcalls <= simulatedopcount) -- return; -- -- if (!quiet && ((progressinterval && -- testcalls % progressinterval == 0) || -- (debug && -- (monitorstart == -1 || -- (offset + size > monitorstart && -- (monitorend == -1 || offset <= monitorend)))))) - prt("%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, - offset, offset + size - 1, size); - prt("%lu %lu.%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", - testcalls, t.tv_sec, t.tv_usec, offset, offset + size - 1, - size); -- -- if (file_size > cur_filesize) { -- if (ftruncate(fd, file_size) == -1) { -- prterr("domapwrite: ftruncate"); -- exit(201); -- } -- } -- pg_offset = offset & page_mask; -- map_size = pg_offset + size; -- -- if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE, -- MAP_FILE | MAP_SHARED, fd, -- (off_t)(offset - pg_offset))) == (char *)-1) { -- prterr("domapwrite: mmap"); -- report_failure(202); -- } -- memcpy(p + pg_offset, good_buf + offset, size); -- if (msync(p, map_size, 0) != 0) { -- prterr("domapwrite: msync"); -- report_failure(203); -- } -- if (munmap(p, map_size) != 0) { -- prterr("domapwrite: munmap"); -- report_failure(204); -- } --} -- -- --void --dotruncate(unsigned size) --{ - struct timeval t; -- int oldsize = file_size; -- -- size -= size % truncbdy; - gettimeofday(&t, NULL); -- if (size > biggest) { -- biggest = size; -- if (!quiet && testcalls > simulatedopcount) -- prt("truncating to largest ever: 0x%x\n", size); -- } -- - log4(OP_TRUNCATE, size, (unsigned)file_size, 0); - log4(OP_TRUNCATE, size, (unsigned)file_size, 0, &t); -- -- if (size > file_size) -- memset(good_buf + file_size, '\0', size - file_size); -- file_size = size; -- -- if (testcalls <= simulatedopcount) -- return; -- -- if ((progressinterval && testcalls % progressinterval == 0) || -- (debug && (monitorstart == -1 || monitorend == -1 || -- size <= monitorend))) - prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, - size); - prt("%lu %lu.%lu trunc\tfrom 0x%x to 0x%x\n", - testcalls, t.tv_sec, t.tv_usec, oldsize, size); -- if (ftruncate(fd, (off_t)size) == -1) { -- prt("ftruncate1: %x\n", size); -- prterr("dotruncate: ftruncate"); -- report_failure(160); -- } --} -- -- --void --writefileimage() --{ -- ssize_t iret; -- -- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { -- prterr("writefileimage: lseek"); -- report_failure(171); -- } -- iret = write(fd, good_buf, file_size); -- if ((off_t)iret != file_size) { -- if (iret == -1) -- prterr("writefileimage: write"); -- else -- prt("short write: 0x%x bytes instead of 0x%llx\n", -- iret, (unsigned long long)file_size); -- report_failure(172); -- } -- if (lite ? 0 : ftruncate(fd, file_size) == -1) { -- prt("ftruncate2: %llx\n", (unsigned long long)file_size); -- prterr("writefileimage: ftruncate"); -- report_failure(173); -- } --} -- -- --void --docloseopen(void) --{ - struct timeval t; - -- if (testcalls <= simulatedopcount) -- return; - - log4(OP_CLOSEOPEN, file_size, (unsigned)file_size, 0, &t); -- - gettimeofday(&t, NULL); -- if (debug) - prt("%lu close/open\n", testcalls); - prt("%lu %lu.%lu close/open\n", testcalls, t.tv_sec, t.tv_usec); -- if (close(fd)) { -- prterr("docloseopen: close"); -- report_failure(180); -- } -- fd = open(fname, O_RDWR, 0); -- if (fd < 0) { -- prterr("docloseopen: open"); -- report_failure(181); -- } --} -- -- --void --test(void) --{ -- unsigned long offset; -- unsigned long size = maxoplen; -- unsigned long rv = random(); -- unsigned long op = rv % (3 + !lite + mapped_writes); -- -- /* turn off the map read if necessary */ -- -- if (op == 2 && !mapped_reads) -- op = 0; -- -- if (simulatedopcount > 0 && testcalls == simulatedopcount) -- writefileimage(); -- -- testcalls++; -- -- if (closeprob) -- closeopen = (rv >> 3) < (1 << 28) / closeprob; -- -- if (debugstart > 0 && testcalls >= debugstart) -- debug = 1; -- -- if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0) -- prt("%lu...\n", testcalls); -- -- /* -- * READ: op = 0 -- * WRITE: op = 1 -- * MAPREAD: op = 2 -- * TRUNCATE: op = 3 -- * MAPWRITE: op = 3 or 4 -- */ -- if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */ -- dotruncate(random() % maxfilelen); -- else { -- if (randomoplen) -- size = random() % (maxoplen+1); -- if (lite ? 0 : op == 3) -- dotruncate(size); -- else { -- offset = random(); -- if (op == 1 || op == (lite ? 3 : 4)) { -- offset %= maxfilelen; -- if (offset + size > maxfilelen) -- size = maxfilelen - offset; -- if (op != 1) -- domapwrite(offset, size); -- else -- dowrite(offset, size); -- } else { -- if (file_size) -- offset %= file_size; -- else -- offset = 0; -- if (offset + size > file_size) -- size = file_size - offset; -- if (op != 0) -- domapread(offset, size); -- else -- doread(offset, size); -- } -- } -- } -- if (sizechecks && testcalls > simulatedopcount) -- check_size(); -- if (closeopen) -- docloseopen(); --} -- -- --void --cleanup(sig) -- int sig; --{ -- if (sig) -- prt("signal %d\n", sig); -- prt("testcalls = %lu\n", testcalls); -- exit(sig); --} -- -- --void --usage(void) --{ -- fprintf(stdout, "usage: %s", -- "fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m --start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t --truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] --fname\n\ -- -b opnum: beginning operation number (default 1)\n\ -- -c P: 1 in P chance of file close+open at each op (default infinity)\n\ -- -d: debug output for all operations\n\ -- -l flen: the upper bound on file size (default 262144)\n\ -- -m startop:endop: monitor (print debug output) specified byte range --(default 0:infinity)\n\ -- -n: no verifications of file size\n\ -- -o oplen: the upper bound on operation size (default 65536)\n\ -- -p progressinterval: debug output at specified operation interval\n\ -- -q: quieter operation\n\ -- -r readbdy: 4096 would make reads page aligned (default 1)\n\ -- -s style: 1 gives smaller truncates (default 0)\n\ -- -t truncbdy: 4096 would make truncates page aligned (default 1)\n\ -- -w writebdy: 4096 would make writes page aligned (default 1)\n\ -- -D startingop: debug output starting at specified operation\n\ -- -L: fsxLite - no file creations & no file size changes\n\ -- -N numops: total # operations to do (default infinity)\n\ -- -O: use oplen (see -o flag) for every op (default random)\n\ -- -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ -- -S seed: for random # generator (default 1) 0 gets timestamp\n\ -- -W: mapped write operations DISabled\n\ -- -R: read() system calls only (mapped reads disabled)\n\ -- fname: this filename is REQUIRED (no default)\n"); -- exit(90); --} -- -- --int --getnum(char *s, char **e) --{ -- int ret = -1; -- -- *e = (char *) 0; -- ret = strtol(s, e, 0); -- if (*e) -- switch (**e) { -- case 'b': -- case 'B': -- ret *= 512; -- *e = *e + 1; -- break; -- case 'k': -- case 'K': -- ret *= 1024; -- *e = *e + 1; -- break; -- case 'm': -- case 'M': -- ret *= 1024*1024; -- *e = *e + 1; -- break; -- case 'w': -- case 'W': -- ret *= 4; -- *e = *e + 1; -- break; -- } -- return (ret); --} - - -static const char *basename(const char *path) -{ - char *c = strrchr(path, '/'); -- - return c ? c++ : path; -} -- --int --main(int argc, char **argv) --{ -- int i, style, ch; -- char *endp; - char goodfile[1024]; - char logfile[1024]; - int dirpath = 0; -- -- goodfile[0] = 0; -- logfile[0] = 0; -- -- page_size = getpagesize(); -- page_mask = page_size - 1; -- -- setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */ -- -- while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:LN:OP:RS:W")) -- != EOF) -- switch (ch) { -- case 'b': -- simulatedopcount = getnum(optarg, &endp); -- if (!quiet) -- fprintf(stdout, "Will begin at operation --%ld\n", -- simulatedopcount); -- if (simulatedopcount == 0) -- usage(); -- simulatedopcount -= 1; -- break; -- case 'c': -- closeprob = getnum(optarg, &endp); -- if (!quiet) -- fprintf(stdout, -- "Chance of close/open is 1 in %d\n", -- closeprob); -- if (closeprob <= 0) -- usage(); -- break; -- case 'd': -- debug = 1; -- break; -- case 'l': -- maxfilelen = getnum(optarg, &endp); -- if (maxfilelen <= 0) -- usage(); -- break; -- case 'm': -- monitorstart = getnum(optarg, &endp); -- if (monitorstart < 0) -- usage(); -- if (!endp || *endp++ != ':') -- usage(); -- monitorend = getnum(endp, &endp); -- if (monitorend < 0) -- usage(); -- if (monitorend == 0) -- monitorend = -1; /* aka infinity */ -- debug = 1; -- case 'n': -- sizechecks = 0; -- break; -- case 'o': -- maxoplen = getnum(optarg, &endp); -- if (maxoplen <= 0) -- usage(); -- break; -- case 'p': -- progressinterval = getnum(optarg, &endp); -- if (progressinterval < 0) -- usage(); -- break; -- case 'q': -- quiet = 1; -- break; -- case 'r': -- readbdy = getnum(optarg, &endp); -- if (readbdy <= 0) -- usage(); -- break; -- case 's': -- style = getnum(optarg, &endp); -- if (style < 0 || style > 1) -- usage(); -- break; -- case 't': -- truncbdy = getnum(optarg, &endp); -- if (truncbdy <= 0) -- usage(); -- break; -- case 'w': -- writebdy = getnum(optarg, &endp); -- if (writebdy <= 0) -- usage(); -- break; -- case 'D': -- debugstart = getnum(optarg, &endp); -- if (debugstart < 1) -- usage(); -- break; -- case 'L': -- lite = 1; -- break; -- case 'N': -- numops = getnum(optarg, &endp); -- if (numops < 0) -- usage(); -- break; -- case 'O': -- randomoplen = 0; -- break; -- case 'P': -- strncpy(goodfile, optarg, sizeof(goodfile)); -- strcat(goodfile, "/"); -- strncpy(logfile, optarg, sizeof(logfile)); -- strcat(logfile, "/"); - dirpath = 1; -- break; -- case 'R': -- mapped_reads = 0; -- break; -- case 'S': -- seed = getnum(optarg, &endp); -- if (seed == 0) -- seed = time(0) % 10000; -- if (!quiet) -- fprintf(stdout, "Seed set to %d\n", seed); -- if (seed < 0) -- usage(); -- break; -- case 'W': -- mapped_writes = 0; -- if (!quiet) -- fprintf(stdout, "mapped writes DISABLED\n"); -- break; -- -- default: -- usage(); -- /* NOTREACHED */ -- } -- argc -= optind; -- argv += optind; -- if (argc != 1) -- usage(); -- fname = argv[0]; -- -- signal(SIGHUP, cleanup); -- signal(SIGINT, cleanup); -- signal(SIGPIPE, cleanup); -- signal(SIGALRM, cleanup); -- signal(SIGTERM, cleanup); -- signal(SIGXCPU, cleanup); -- signal(SIGXFSZ, cleanup); -- signal(SIGVTALRM, cleanup); -- signal(SIGUSR1, cleanup); -- signal(SIGUSR2, cleanup); -- -- initstate(seed, state, 256); -- setstate(state); -- fd = open(fname, O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC), 0666); -- if (fd < 0) { -- prterr(fname); -- exit(91); -- } - strncat(goodfile, fname, 256); - strncat(goodfile, dirpath ? basename(fname) : fname, 256); -- strcat (goodfile, ".fsxgood"); -- fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666); -- if (fsxgoodfd < 0) { -- prterr(goodfile); -- exit(92); -- } - strncat(logfile, fname, 256); - strncat(logfile, dirpath ? basename(fname) : fname, 256); -- strcat (logfile, ".fsxlog"); -- fsxlogf = fopen(logfile, "w"); -- if (fsxlogf == NULL) { -- prterr(logfile); -- exit(93); -- } -- if (lite) { -- off_t ret; -- file_size = maxfilelen = lseek(fd, (off_t)0, SEEK_END); -- if (file_size == (off_t)-1) { -- prterr(fname); -- warn("main: lseek eof"); -- exit(94); -- } -- ret = lseek(fd, (off_t)0, SEEK_SET); -- if (ret == (off_t)-1) { -- prterr(fname); -- warn("main: lseek 0"); -- exit(95); -- } -- } -- original_buf = (char *) malloc(maxfilelen); -- for (i = 0; i < maxfilelen; i++) -- original_buf[i] = random() % 256; -- good_buf = (char *) malloc(maxfilelen); -- memset(good_buf, '\0', maxfilelen); -- temp_buf = (char *) malloc(maxoplen); -- memset(temp_buf, '\0', maxoplen); -- if (lite) { /* zero entire existing file */ -- ssize_t written; -- -- written = write(fd, good_buf, (size_t)maxfilelen); -- if (written != maxfilelen) { -- if (written == -1) { -- prterr(fname); -- warn("main: error on write"); -- } else -- warn("main: short write, 0x%x bytes instead --of 0x%x\n", -- (unsigned)written, maxfilelen); -- exit(98); -- } -- } else -- check_trunc_hack(); -- -- while (numops == -1 || numops--) -- test(); -- -- if (close(fd)) { -- prterr("close"); -- report_failure(99); -- } -- prt("All operations completed A-OK!\n"); -- -- exit(0); -- return 0; --} diff --cc lustre/tests/intent-test.sh index 9113f17,9113f17..0000000 deleted file mode 100755,100755 --- a/lustre/tests/intent-test.sh +++ /dev/null @@@ -1,122 -1,122 +1,0 @@@ --#!/bin/bash -x -- --MTPT=/mnt/lustre -- --remount() { -- umount $MTPT || exit -1 -- debugctl clear -- mount -t lustre_lite -o osc=OSCDEV-UUID,mdc=MDCDEV-UUID none $MTPT --} -- --# Test mkdir --mkdir $MTPT/dir --mkdir $MTPT/dir2 -- --# Test mkdir on existing directory --mkdir $MTPT/dir -- --remount -- --# Test mkdir on existing directory with no locks already held --mkdir $MTPT/dir -- --remount -- --# Use mknod to create a file --./mcreate $MTPT/file --# ...on an existing file. --./mcreate $MTPT/file -- --remount -- --# Use mknod to create a file with no locks already held --./mcreate $MTPT/file -- --remount -- --ls -l $MTPT/file -- --remount -- --cat $MTPT/file --./mcreate $MTPT/file2 --cat $MTPT/file2 --./mcreate $MTPT/file3 -- --remount -- --./tchmod 777 $MTPT/file3 -- --remount -- --./mcreate $MTPT/file4 --./tchmod 777 $MTPT/file4 -- --remount -- --ls -l $MTPT/file4 --./tchmod 777 $MTPT/file4 -- --remount -- --cat $MTPT/file4 --./tchmod 777 $MTPT/file4 -- --remount -- --touch $MTPT/file5 --touch $MTPT/file6 --touch $MTPT/file5 -- --remount -- --touch $MTPT/file5 -- --remount -- --echo foo >> $MTPT/file --cat $MTPT/file -- --remount -- --cat $MTPT/file -- --echo foo >> $MTPT/iotest --echo bar >> $MTPT/iotest --cat $MTPT/iotest -- --remount -- --cat $MTPT/iotest --echo baz >> $MTPT/iotest -- --remount -- --ls $MTPT -- --remount -- --mkdir $MTPT/new --ls $MTPT -- --remount -- --ls $MTPT --mkdir $MTPT/newer --ls $MTPT -- --remount -- --cat $MTPT/iotest --echo "Testing truncation..." --echo foo > $MTPT/iotest --echo bar >> $MTPT/iotest --cat $MTPT/iotest --echo "trucating to 4 bytes now..." --./truncate $MTPT/iotest 4 --cat $MTPT/iotest -- --remount -- --ls $MTPT --rmdir $MTPT/foo diff --cc lustre/tests/intent-test2.sh index 428039c,428039c..0000000 deleted file mode 100644,100644 --- a/lustre/tests/intent-test2.sh +++ /dev/null @@@ -1,70 -1,70 +1,0 @@@ --#!/bin/bash -- --SRCDIR="`dirname $0`" --. $SRCDIR/common.sh -- --setup_opts "$@" -- --set -vx -- --MTPT1=/mnt/lustre1 --MTPT2=/mnt/lustre2 -- --remount() { -- umount $MTPT1 || exit -1 -- umount $MTPT2 || exit -1 -- debugctl clear -- setup_mount || fail "cannot remount /mnt/lustre" --} -- --fail() { -- echo "unexpected failure" -- exit -1 --} -- --[ "`mount | grep $MTPT1`" ] || . llsetup.sh "$@" || exit -1 -- --mkdir $MTPT1/dir1 || fail --echo "Next mkdir should fail" --mkdir $MTPT2/dir1 && fail --mkdir $MTPT2/dir2 || fail --echo "Next mkdirs should fail" --mkdir $MTPT1/dir2 && fail -- --remount -- --echo "Next 2 mkdir should fail" --mkdir $MTPT2/dir1 && fail --mkdir $MTPT1/dir2 && fail -- --./mcreate $MTPT2/file1 --echo "Next mcreate should fail" --./mcreate $MTPT2/file1 && fail --./mcreate $MTPT2/file2 || fail --echo "Next mcreate should fail" --./mcreate $MTPT1/file2 && fail -- --remount -- --echo "Next 2 mcreates should fail" --./mcreate $MTPT2/file1 && fail --./mcreate $MTPT1/file2 && fail -- --rmdir $MTPT1/dir2 || fail --echo "Next rmdir should fail" --rmdir $MTPT2/dir2 && fail --rmdir $MTPT2/dir1 || fail -- --remount -- --echo "Next rpmdir should fail" -- --echo "File I/O: you should see increasing sequences of contiguous numbers" --echo 1 >> $MTPT1/file1 --cat $MTPT2/file1 --echo 2 >> $MTPT2/file1 --cat $MTPT1/file1 --echo 3 >> $MTPT2/file1 --cat $MTPT1/file1 --echo 4 >> $MTPT1/file1 --cat $MTPT1/file1 diff --cc lustre/tests/ldaptest.c index c1a7499,c1a7499..0000000 deleted file mode 100644,100644 --- a/lustre/tests/ldaptest.c +++ /dev/null @@@ -1,27 -1,27 +1,0 @@@ --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- LDAP *ld; -- int err; -- -- ld = ldap_init("localhost", 389); -- if (!ld) { -- fprintf(stderr, "ldap_init: %s\n", strerror(errno)); -- exit(1); -- } -- -- err = ldap_bind_s(ld, "cn=Manager,dc=lustre,dc=cfs", "secret", -- LDAP_AUTH_SIMPLE); -- if (err) { -- fprintf(stderr, "ldap_bind: %s\n", ldap_err2string(err)); -- exit(1); -- } -- -- -- -- --} diff --cc lustre/tests/ldlm.cfg index 054f983,054f983..0000000 deleted file mode 100644,100644 --- a/lustre/tests/ldlm.cfg +++ /dev/null @@@ -1,3 -1,3 +1,0 @@@ --#!/bin/sh --# Config file for setting up the lock manager --SETUP_LDLM=y diff --cc lustre/tests/leak_finder.pl index 4290b62,fbf1d00..0000000 deleted file mode 100644,100644 --- a/lustre/tests/leak_finder.pl +++ /dev/null @@@ -1,53 -1,63 +1,0 @@@ --#!/usr/bin/perl -w - -use IO::Handle; - -STDOUT->autoflush(1); -STDERR->autoflush(1); -- --my ($line, $memory); --my $debug_line = 0; -- --while ($line = <>) { -- $debug_line++; -- my ($file, $func, $lno, $name, $size, $addr, $type); - if ($line =~ m/^.*\((.*):(.*)\,l\. (\d+) .* k(.*) '(.*)': (\d+) at (.*) \(tot .*$/) { - if ($line =~ m/^.*\((.*):(\d+):(.*)\(\) (\d+ \| )?\d+\+\d+\): [vk](.*) '(.*)': (\d+) at (.*) \(tot .*$/) { -- $file = $1; - $func = $2; - $lno = $3; - $type = $4; - $name = $5; - $size = $6; - $addr = $7; - $lno = $2; - $func = $3; - $type = $5; - $name = $6; - $size = $7; - $addr = $8; -- printf("%8s %6d bytes at %s called %s (%s:%s:%d)\n", $type, $size, -- $addr, $name, $file, $func, $lno); -- } else { -- next; -- } -- -- if ($type eq 'malloced') { -- $memory->{$addr}->{name} = $name; -- $memory->{$addr}->{size} = $size; -- $memory->{$addr}->{file} = $file; -- $memory->{$addr}->{func} = $func; -- $memory->{$addr}->{lno} = $lno; -- $memory->{$addr}->{debug_line} = $debug_line; -- } else { -- if (!defined($memory->{$addr})) { - print "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n"; - print STDERR "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n"; -- next; -- } -- my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$addr}; -- -- if ($memory->{$addr}->{size} != $size) { - print "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n"; - print " malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n"; - print STDERR "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n"; - print STDERR " malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n"; -- next; -- } -- -- delete $memory->{$addr}; -- } --} - -# Sort leak output by allocation time -my @sorted = sort { - return $memory->{$a}->{debug_line} <=> $memory->{$b}->{debug_line}; -} keys(%{$memory}); -- --my $key; - foreach $key (keys(%{$memory})) { -foreach $key (@sorted) { -- my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$key}; - print "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n"; - print STDERR "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n"; --} -- --print "Done.\n"; diff --cc lustre/tests/llcleanup.sh index b718e93,b718e93..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llcleanup.sh +++ /dev/null @@@ -1,19 -1,19 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" -- --. $SRCDIR/common.sh -- --setup_opts "$@" -- --TIME=`date +'%s'` -- --$DBGCTL debug_kernel /tmp/debug.1.$TIME --cleanup_client --$DBGCTL debug_kernel /tmp/debug.2.$TIME --cleanup_server -- --cleanup_ldlm --cleanup_lustre --cleanup_portals diff --cc lustre/tests/lldlm.sh index 58da470,58da470..0000000 deleted file mode 100755,100755 --- a/lustre/tests/lldlm.sh +++ /dev/null @@@ -1,40 -1,40 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- --export DEBUG_WAIT=yes --. $SRCDIR/llsetup.sh $SRCDIR/net-local.cfg $SRCDIR/ldlm.cfg $SRCDIR/obdecho.cfg $SRCDIR/client-echo.cfg || exit 2 -- --cat < /proc/sys/portals/debug_path -- --list_mods -- -- diff --cc lustre/tests/llmount-client.sh index 503f93f,503f93f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/llmount-client.sh +++ /dev/null @@@ -1,9 -1,9 +1,0 @@@ --#!/bin/sh --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- --export DEBUG_WAIT=yes --. $SRCDIR/llsetup.sh $SRCDIR/net-client.cfg $SRCDIR/ldlm.cfg $SRCDIR/client-mount.cfg || exit 2 -- --debug_client_on --#debug_client_off diff --cc lustre/tests/llmount-server.sh index d31f033,d31f033..0000000 deleted file mode 100644,100644 --- a/lustre/tests/llmount-server.sh +++ /dev/null @@@ -1,9 -1,9 +1,0 @@@ --#!/bin/sh --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- --export DEBUG_WAIT=yes --. $SRCDIR/llsetup.sh $SRCDIR/net-server.cfg $SRCDIR/ldlm.cfg $SRCDIR/mds.cfg $SRCDIR/obdfilter.cfg || exit 2 -- --debug_client_on --#debug_client_off diff --cc lustre/tests/llmount.sh index f7c2430,eb4618b..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llmount.sh +++ /dev/null @@@ -1,15 -1,14 +1,0 @@@ --#!/bin/sh --# suggested boilerplate for test script -- --LCONF=${LCONF:-../utils/lconf} --NAME=${NAME:-local} -- --config=$NAME.xml --mkconfig=./$NAME.sh -- --if [ ! -f $config -o $mkconfig -nt $config ]; then -- sh $mkconfig $config || exit 1 --fi -- --${LCONF} --reformat --gdb $config || exit 2 - diff --cc lustre/tests/llmountcleanup.sh index 98f3510,82f2a17..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llmountcleanup.sh +++ /dev/null @@@ -1,14 -1,26 +1,0 @@@ --#!/bin/sh -- --LCONF=${LCONF:-../utils/lconf} --NAME=${NAME:-local} -TMP=${TMP:-/tmp} -- --config=$NAME.xml --mkconfig=./$NAME.sh -- - if [ ! -f $config -o $mkconfig -nt $config ]; then -if [ ! -f $config ]; then -- sh $mkconfig $config || exit 1 --fi - - ${LCONF} --cleanup --dump /tmp/debug $config -- -sync; sleep 2; sync -${LCONF} --cleanup --dump $TMP/debug $config -LEAK=`dmesg | grep -v " 0 bytes" | grep leaked` -if [ "$LEAK" ]; then - echo "$LEAK" 1>&2 - mv $TMP/debug $TMP/debug.`date +%s` - #exit -1 -fi -BUSY=`dmesg | grep -i destruct` -if [ "$BUSY" ]; then - echo "$BUSY" 1>&2 - #exit -2 -fi diff --cc lustre/tests/llrext3.sh index c47fe9b,c47fe9b..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llrext3.sh +++ /dev/null @@@ -1,10 -1,10 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- --export DEBUG_WAIT=yes --. $SRCDIR/llrsetup.sh $SRCDIR/net-local.cfg $SRCDIR/client-mount.cfg $SRCDIR/mds.cfg $SRCDIR/obdext2.cfg || exit 2 -- --debug_client_on --#debug_client_off diff --cc lustre/tests/llrmount.sh index ae244c1,ae244c1..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llrmount.sh +++ /dev/null @@@ -1,13 -1,13 +1,0 @@@ --#!/bin/sh -- --LCONF=${LCONF:-../utils/lconf} --NAME=${NAME:-local} -- --config=$NAME.xml --mkconfig=./$NAME.sh -- --if [ ! -f $config -o $mkconfig -nt $config ]; then -- sh $mkconfig $config || exit 1 --fi -- --${LCONF} --gdb $config || exit 2 diff --cc lustre/tests/llrsetup.sh index 44bfcae,44bfcae..0000000 deleted file mode 100644,100644 --- a/lustre/tests/llrsetup.sh +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" -- --. $SRCDIR/common.sh -- --setup_opts "$@" -- --setup_portals --setup_lustre --setup_ldlm -- --setup_server old_fs --setup_client diff --cc lustre/tests/llsetup.sh index 4828f26,4828f26..0000000 deleted file mode 100644,100644 --- a/lustre/tests/llsetup.sh +++ /dev/null @@@ -1,15 -1,15 +1,0 @@@ --#!/bin/sh -vx -- --SRCDIR="`dirname $0`/" --[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" -- --. $SRCDIR/common.sh -- --setup_opts "$@" -- --setup_portals || exit $? --setup_lustre || exit $? --setup_ldlm || exit $? -- --setup_server new_fs || exit $? --setup_client || exit $? diff --cc lustre/tests/llsimple.sh index d22ddc6,d22ddc6..0000000 deleted file mode 100755,100755 --- a/lustre/tests/llsimple.sh +++ /dev/null @@@ -1,11 -1,11 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --[ -f $SRCDIR/common.sh ] || SRCDIR="/lib/lustre" -- --. $SRCDIR/common.sh -- --setup_opts "$@" -- --setup_portals || exit $? --setup_lustre || exit $? diff --cc lustre/tests/local.sh index c56d3a8,40fcc74..0000000 deleted file mode 100755,100755 --- a/lustre/tests/local.sh +++ /dev/null @@@ -1,34 -1,35 +1,0 @@@ --#!/bin/bash -- --config=${1:-local.xml} -- --LMC=${LMC:-../utils/lmc} --TMP=${TMP:-/tmp} -- --MDSDEV=$TMP/mds1 - MDSSIZE=50000 -MDSSIZE=100000 -- --OSTDEV=$TMP/ost1 - OSTSIZE=50000 -OSTSIZE=400000 -- --kver=`uname -r | cut -d "." -f 1,2` -- --case $kver in -- 2.4) FSTYPE="--fstype=extN" ;; -- 2.5) FSTYPE="--fstype=ext3" ;; -- *) echo "Kernel version $kver not supported" -- exit 1 -- ;; --esac - -- --# create nodes --${LMC} -o $config --node localhost --net localhost tcp || exit 1 -- --# configure mds server --${LMC} -m $config --format --node localhost $FSTYPE --mds mds1 $MDSDEV $MDSSIZE || exit 2 -- --# configure ost --${LMC} -m $config --format --node localhost $FSTYPE --ost $OSTDEV $OSTSIZE || exit 3 -- --# create client config --${LMC} -m $config --node localhost --mtpt /mnt/lustre mds1 OSC_localhost || exit 4 diff --cc lustre/tests/lov.sh index 17e0d75,76f8374..0000000 deleted file mode 100755,100755 --- a/lustre/tests/lov.sh +++ /dev/null @@@ -1,30 -1,32 +1,0 @@@ --#!/bin/bash -- --config=${1:-lov.xml} -- - LMC=../utils/lmc -LMC=${LMC:-../utils/lmc} --TMP=${TMP:-/tmp} -- --MDSDEV=$TMP/mds1 --MDSSIZE=50000 -- --OSTDEV1=$TMP/ost1 --OSTDEV2=$TMP/ost2 -OSTDEV3=$TMP/ost3 --OSTSIZE=100000 -- --STRIPE_BYTES=65536 - STRIPES_PER_OBJ=0 # 0 means stripe over all OSTs -STRIPES_PER_OBJ=2 # 0 means stripe over all OSTs -- --# create nodes --${LMC} -o $config --node localhost --net localhost tcp || exit 1 -- --# configure mds server --${LMC} -m $config --format --node localhost --mds mds1 $MDSDEV $MDSSIZE || exit 10 -- --# configure ost --${LMC} -m $config --lov lov1 mds1 $STRIPE_BYTES $STRIPES_PER_OBJ 0 || exit 20 --${LMC} -m $config --node localhost --lov lov1 --ost $OSTDEV1 $OSTSIZE || exit 21 --${LMC} -m $config --node localhost --lov lov1 --ost $OSTDEV2 $OSTSIZE || exit 22 -${LMC} -m $config --node localhost --lov lov1 --ost $OSTDEV3 $OSTSIZE || exit 23 -- --# create client config --${LMC} -m $config --node localhost --mtpt /mnt/lustre mds1 lov1 || exit 30 diff --cc lustre/tests/lovstripe.c index 14aa2cf,29769f1..0000000 deleted file mode 100644,100644 --- a/lustre/tests/lovstripe.c +++ /dev/null @@@ -1,162 -1,164 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- -- --/****************** Custom includes ********************/ --#include -#include -- -- --/****************** Functions ******************/ - int write_file(char *name, struct lov_user_md *striping, int bufsize, -int write_file(char *name, struct lov_mds_md *striping, int bufsize, -- char *buf1, char *buf2); -- -- --/************************ Main **********************/ -- --#define STRIPE_SIZE 128 * 1024 -- --int main(int argc, char *argv[]) --{ - struct lov_user_md a_striping; - struct lov_mds_md a_striping; -- long bufsize = sizeof(long) * STRIPE_SIZE; -- char *rbuf, *wbuf; -- int data, *dp; -- int result; -- -- rbuf = malloc(bufsize); -- wbuf = malloc(bufsize); -- if (!rbuf || !wbuf) { -- fprintf(stderr, "%s: unable to allocate buffers\n", argv[0]); -- return 1; -- } -- -- /* Initialize to an easily-verified pattern */ -- for (data = 0, dp = (int *)wbuf; data < STRIPE_SIZE; data++, dp++) -- *dp = data; -- -- /* Init defaults on striping info */ - a_striping.lum_stripe_size = STRIPE_SIZE; - a_striping.lum_stripe_pattern = 0; - a_striping.lmm_magic = LOV_MAGIC; - a_striping.lmm_stripe_size = STRIPE_SIZE; - a_striping.lmm_stripe_pattern = 0; -- -- /* Write file for OST1 only */ -- /* Start at OST 0, and use only 1 OST */ - a_striping.lum_stripe_offset = 0; - a_striping.lum_stripe_count = 1; - a_striping.lmm_stripe_offset = 0; - a_striping.lmm_stripe_count = 1; -- -- result = write_file("/mnt/lustre/ost1", &a_striping, bufsize, -- wbuf, rbuf); -- -- if (result < 0) -- goto out; -- -- /* Write file for OST2 only */ -- /* Start at OST 1, and use only 1 OST */ - a_striping.lum_stripe_offset = 1; - a_striping.lum_stripe_count = 1; - a_striping.lmm_stripe_offset = 1; - a_striping.lmm_stripe_count = 1; -- -- result = write_file("/mnt/lustre/ost2", &a_striping, bufsize, -- wbuf, rbuf); -- -- if (result < 0) -- goto out; -- -- /* Write file across both OST1 and OST2 */ -- /* Start at OST 0, and use only 2 OSTs */ - a_striping.lum_stripe_offset = 0; - a_striping.lum_stripe_count = 2; - a_striping.lmm_stripe_offset = 0; - a_striping.lmm_stripe_count = 2; -- -- result = write_file("/mnt/lustre/ost1and2", &a_striping, bufsize, -- wbuf, rbuf); -- -- if (result < 0) -- goto out; -- --out: -- free(rbuf); -- free(wbuf); -- return result; --} -- -- - int write_file(char *name, struct lov_user_md *striping, int bufsize, -int write_file(char *name, struct lov_mds_md *striping, int bufsize, -- char *wbuf, char *rbuf) --{ -- int fd, result; -- -- printf("opening %s\n", name); -- fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); -- if (fd < 0) { -- fprintf(stderr, "\nUnable to open '%s': %s\n", -- name, strerror(errno)); -- return -errno; -- } -- -- printf("setting stripe data on %s\n", name); -- result = ioctl(fd, LL_IOC_LOV_SETSTRIPE, striping); -- if (result < 0) { -- fprintf(stderr, "\nError on ioctl for '%s' (%d): %s\n", -- name, fd, strerror(errno)); -- close(fd); -- return -errno; -- } -- -- /* Write bogus data */ -- printf("writing data to %s\n", name); -- result = write(fd, wbuf, bufsize); -- if (result < 0) { -- fprintf(stderr, "\nerror: writing data to '%s' (%d): %s\n", -- name, fd, strerror(errno)); -- close(fd); -- return -errno; -- } -- -- if (result != bufsize) { -- fprintf(stderr, "\nerror: short write to '%s' (%d): %d != %d\n", -- name, fd, result, bufsize); -- close(fd); -- return -1; -- } -- -- /* Seek to beginning again */ -- printf("seeking in %s\n", name); -- result = lseek(fd, 0, SEEK_SET); -- if (result < 0) { -- fprintf(stderr, "\nerror: seeking to beginning '%s' (%d): %s\n", -- name, fd, strerror(errno)); -- close(fd); -- return -errno; -- } -- -- /* Read bogus data back */ -- printf("reading data from %s\n", name); -- result = read(fd, rbuf, bufsize); -- if (result < 0) { -- fprintf(stderr, "\nerror: reading data from '%s' (%d): %s\n", -- name, fd, strerror(errno)); -- close(fd); -- return -errno; -- } -- -- if (result != bufsize) { -- fprintf(stderr,"\nerror: short read from '%s' (%d): %d != %d\n", -- name, fd, result, bufsize); -- close(fd); -- return -1; -- } -- -- if (memcmp(wbuf, rbuf, bufsize)) { -- fprintf(stderr, "\nerror: comparing data in '%s' (%d): %s\n", -- name, fd, strerror(errno)); -- close(fd); -- return -1; -- } -- -- close(fd); -- -- return 0; --} diff --cc lustre/tests/lustre.cfg index cc97b1b,cc97b1b..0000000 deleted file mode 100644,100644 --- a/lustre/tests/lustre.cfg +++ /dev/null @@@ -1,49 -1,49 +1,0 @@@ --#!/bin/sh -- --### REMOVE THE FOLLOWING LINES IN ORDER TO TEST LUSTRE WITH THIS CONFIG ### --echo "lustre: edit /etc/lustre/lustre.cfg to enable, exiting" 1>&2 --exit 1 -- --# Common configuration options --# Config file for setting up a local OST and MDS server --NETWORK=tcp --LOCALHOST=`hostname` --SERVER=$LOCALHOST --OSTNODE=$LOCALHOST --CLIENTS=* --PORT=988 -- --# Set up the lock manager (required) --SETUP_LDLM=y -- --#case `echo $LOCALHOST | sed "s/\.[^|]*//"` in --case $LOCALHOST in --$SERVER) -- # Config for setting up a metadata server -- MDSFS=extN -- MDSDEV=/tmp/mds -- MDSSIZE=50000 -- SETUP_MDS=y -- ;; --esac -- --case $LOCALHOST in --$OSTNODE) -- # Config for setting up an object storage target with obdfilter -- OSTDEV=/tmp/ost -- OSTSIZE=200000 -- OSTFS=extN -- OSTTYPE=obdfilter -- SETUP_OST=y -- ;; --esac -- --case $LOCALHOST in --$CLIENTS) -- # Config for setting up a client filesystem mount -- SETUP_MDC=y -- SETUP_OSC=y -- OSCMT=/mnt/lustre -- SETUP_MOUNT=y -- ;; --esac diff --cc lustre/tests/mcr-individual-ost-nogw-config.sh index fa47e49,0aae281..0000000 deleted file mode 100755,100755 --- a/lustre/tests/mcr-individual-ost-nogw-config.sh +++ /dev/null @@@ -1,47 -1,46 +1,0 @@@ --#!/bin/bash -- --config=${1:-echo-no-gw.xml} -- --LMC="save_cmd" --LMC_REAL="../../lustre/utils/lmc -m $config" -- --# TCP/IP servers --SERVER_START=0 --SERVER_CNT=62 -- - PORT=988 --TCPBUF=1048576 -- --h2ip () { -- echo "${1}" --} --BATCH=/tmp/lmc-batch.$$ --save_cmd() { -- echo "$@" >> $BATCH --} -- --[ -f $config ] && rm $config -- --# Client node - ${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT || exit 1 -${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp || exit 1 -- --# this is crude, but effective --let server_per_gw=($SERVER_CNT / $GW_CNT ) --let tot_server=$server_per_gw*$GW_CNT -- --let server=$SERVER_START --while (( $server < $SERVER_CNT + SERVER_START )); --do -- echo "server: $server" - ba=ba$server - OST=ba$server -- # server node - ${LMC} --node $ba --tcpbuf $TCPBUF --net $ba tcp $PORT || exit 1 - ${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp || exit 1 -- # the device on the server - ${LMC} --node $ba --obdtype=obdecho --ost || exit 3 - ${LMC} --node $OST --obdtype=obdecho --ost || exit 3 -- # osc on client - ${LMC} --node client --osc OSC_$ba - ${LMC} --node client --osc OSC_$OST -- let server=$server+1 --done -- --$LMC_REAL --batch $BATCH --rm -f $BATCH diff --cc lustre/tests/mcr-mds-failover-config.sh index ca539be,8a42c3d..0000000 deleted file mode 100755,100755 --- a/lustre/tests/mcr-mds-failover-config.sh +++ /dev/null @@@ -1,49 -1,48 +1,0 @@@ --#!/bin/sh -- --LMC=/usr/local/cfs/lustre/utils/lmc --# LMC="echo lmc" --CONFIG=mcr-mds-failover.xml --LUSTRE_QUERY=/usr/local/cfs/lustre-failover/lustre-query --GW_NODE=mcr21 --CLIENT_ELAN=`hostname | sed s/[^0-9]*//;` --OST_BA=ba50 --OST_UUID=10400010-5dec-11c2-0b5f-00301700041a --MDS_DEVICE=/dev/sda3 --MDS_SIZE=500000 --TCPBUF=1048576 - TCPPORT=988 -- --MDSNODES=`$LUSTRE_QUERY -h emcri -s id=mds -f` --ACTIVEMDS=`$LUSTRE_QUERY -h emcri -s id=mds -a` -- --echo "MDS nodes: $MDSNODES, active: $ACTIVEMDS" -- --h2elan () { -- echo $1 | sed 's/[^0-9]*//g' --} -- --h2ip () { -- echo "${1}" --} -- -- --# create client node --$LMC -o $CONFIG --node client --net '*' elan --$LMC -m $CONFIG --router --node mcr21 --tcpbuf $TCPBUF --net `h2ip $GW_NODE` tcp --$LMC -m $CONFIG --router --node mcr21 --net `h2elan $GW_NODE` elan --$LMC -m $CONFIG --node $GW_NODE --route elan `h2elan $GW_NODE` $CLIENT_ELAN -- --# create MDS node entries --for mds in $MDSNODES; do -- elanaddr=`$LUSTRE_QUERY -h emcri -s id=$mds -e` -- $LMC -m $CONFIG --node $mds --net $elanaddr elan -- $LMC -m $CONFIG --node $mds --mds mds_$mds $MDS_DEVICE $MDS_SIZE --done -- --# create OST node entry - $LMC -m $CONFIG --node $OST_BA --tcpbuf $TCPBUF --net $OST_BA tcp $TCPPORT -$LMC -m $CONFIG --node $OST_BA --tcpbuf $TCPBUF --net $OST_BA tcp --$LMC -m $CONFIG --node $OST_BA --obduuid $OST_UUID --ost bluearc --$LMC -m $CONFIG --node $GW_NODE --route tcp `h2ip $GW_NODE` $OST_BA -- --# mount --$LMC -m $CONFIG --node client --mtpt /mnt/lustre mds_$ACTIVEMDS OSC_$OST_BA diff --cc lustre/tests/mcr-routed-config.sh index f6405d7,f66335e..0000000 deleted file mode 100755,100755 --- a/lustre/tests/mcr-routed-config.sh +++ /dev/null @@@ -1,90 -1,93 +1,0 @@@ --#!/bin/bash -- - config=${1:-mcr2.xml} -BASE=`hostname | sed "s/[i0-9]*$//"` -[ $BASE = "mcr" ] && OSTBASE=${OSTBASE:-ba} || OSTBASE=${OSTBASE:-ba-ost-} - -config=${1:-$BASE.xml} - -BATCH=/tmp/lmc-batch.$$ -save_cmd() { - echo "$@" >> $BATCH -} -- --LMC="save_cmd" --LMC_REAL="../../lustre/utils/lmc -m $config" -- --# TCP/IP servers - SERVER_START=1 - SERVER_CNT=62 - GW_START=1 - GW_CNT=31 - MDS=mcr23 - UUIDLIST=${UUIDLIST:-/home/bluearc/UUID.0920} -SERVER_START=0 -SERVER_CNT=64 -GW_START=0 -GW_CNT=32 -MDS=${BASE}23 -UUIDLIST=${UUIDLIST:-/usr/local/admin/ba-ost/UUID.txt} -- - # THis is needed for to create route for elan network - CLIENT_LO=mcr40 - CLIENT_HI=mcr96 -echo "MDS: $MDS" -- - PORT=988 -# This is needed for to create route for elan network -CLIENT_LO=36 -CLIENT_HI=155 - --TCPBUF=1048576 -- - --h2elan () { -- echo $1 | sed 's/[^0-9]*//g' --} -- --h2ip () { -- echo "${1}" - } - # map gwNN to mcrNN - # assumes /etc/hosts looks like this: - # 192.168.40.11 emcr10 mcr10-eth0 emcr-r2-s1 gw10 - gw2mcr() { - awk '$5 = /'$1'$/ {print substr($2,2)}' /etc/hosts --} - BATCH=/tmp/lmc-batch.$$ - save_cmd() { - echo "$@" >> $BATCH - -# map gateway NN to host NN (assumes mcr[22-25] are not gateways) -gw2node() { - [ $1 -gt 21 ] && echo $(($1 + 4)) || echo $1 --} -- --[ -f $config ] && rm $config -- --${LMC} --node $MDS --net `h2elan $MDS` elan || exit 1 --${LMC} --node $MDS --mds mds1 /tmp/mds1 100000 || exit 1 - ${LMC} --lov lov1 mds1 65536 0 0 -${LMC} --lov lov1 mds1 65536 1 0 -- --# Client node - #${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp $PORT || exit 1 -#${LMC} --node client --tcpbuf $TCPBUF --net '*' tcp || exit 1 --${LMC} --node client --net '*' elan || exit 1 --${LMC} --node client --mtpt /mnt/lustre mds1 lov1 -- --# this is crude, but effective --let server_per_gw=($SERVER_CNT / $GW_CNT ) --let tot_server=$server_per_gw*$GW_CNT - echo "Allocating $server_per_gw per gateway." - echo "For a total of $tot_server Blue Arcs" -echo "Allocating $server_per_gw OSTs per gateway." -echo "For a total of $tot_server Blue Arc OSTs" -- --let gw=$GW_START --let server=$SERVER_START --while (( $gw < $GW_CNT + GW_START )); --do - echo "gw$gw" - gwnode=`gw2mcr gw$gw` - ${LMC} --router --node $gwnode --tcpbuf $TCPBUF --net `h2ip $gwnode` tcp $PORT || exit 1 - gwnode=$BASE`gw2node $gw` - echo "Router: $gwnode" - ${LMC} --router --node $gwnode --tcpbuf $TCPBUF --net `h2ip $gwnode` tcp || exit 1 -- ${LMC} --node $gwnode --net `h2elan $gwnode` elan|| exit 1 -- ${LMC} --node $gwnode --route elan `h2elan $gwnode` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 -- -- let i=0 -- while (( $i < $server_per_gw )); -- do - echo "server: $server" - ba=ba$server - OST=${OSTBASE}$server - echo "server: $OST" -- OBD_UUID=`awk "/$OST / { print \\$3 }" $UUIDLIST` -- [ "$OBD_UUID" ] && OBD_UUID="--obduuid=$OBD_UUID" || echo "$OST: no UUID" -- # server node - ${LMC} --node $ba --tcpbuf $TCPBUF --net $ba tcp $PORT || exit 1 - ${LMC} --node $OST --tcpbuf $TCPBUF --net $OST tcp || exit 1 -- # the device on the server - ${LMC} --lov lov1 --node $ba $OBD_UUID --ost bluearc || exit 3 - ${LMC} --lov lov1 --node $OST $OBD_UUID --ost bluearc || exit 3 -- # route to server - ${LMC} --node $gwnode --route tcp `h2ip $gwnode` $ba || exit 2 - ${LMC} --node $gwnode --route tcp `h2ip $gwnode` $OST || exit 2 -- let server=$server+1 -- let i=$i+1 -- done -- -- let gw=$gw+1 --done -- --$LMC_REAL --batch $BATCH --rm -f $BATCH diff --cc lustre/tests/mcr.sh index 7bfc35a,c7f7919..0000000 deleted file mode 100755,100755 --- a/lustre/tests/mcr.sh +++ /dev/null @@@ -1,46 -1,45 +1,0 @@@ --#!/bin/bash -- --config=${1:-mcr.xml} -- --LMC="../utils/lmc -m $config" -- --# TCP/IP servers --SERVERS="ba-ost-1 ba-ost-2" --ROUTER=dev5 -- --# Elan clients --CLIENT_LO=dev2 --CLIENT_HI=dev25 -- - PORT=988 --TCPBUF=1048576 -- -- --h2elan () { -- echo $1 | sed 's/[^0-9]*//g' --} -- --h2ip () { -- echo "${1}" --} -- --[ -f $config ] && rm $config -- --# Client node --${LMC} --node client --net '*' elan || exit 1 --# Router node - ${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp $PORT || exit 1 -${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp || exit 1 --${LMC} --node $ROUTER --net `h2elan $ROUTER` elan|| exit 1 --${LMC} --node $ROUTER --route elan `h2elan $ROUTER` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 -- --for s in $SERVERS -- do -- # server node - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp $PORT || exit 1 - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp || exit 1 -- # route to server -- ${LMC} --node $ROUTER --route tcp `h2ip $ROUTER` $s || exit 2 -- # the device on the server -- ${LMC} --node $s --obdtype=obdecho --ost || exit 3 -- # attach to the device on the client (this would normally be a moun) -- ${LMC} --node client --osc OSC_$s || exit 4 --done diff --cc lustre/tests/mcreate.c index bc18aa7,9d48b11..0000000 deleted file mode 100644,100644 --- a/lustre/tests/mcreate.c +++ /dev/null @@@ -1,23 -1,23 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --int main(int argc, char ** argv) --{ -- int rc; -- - if (argc < 2) { - if (argc < 2) { -- printf("Usage %s filename\n", argv[0]); -- return 1; -- } -- - rc = mknod(argv[1], S_IFREG| 0444, 0); - if (rc) { - rc = mknod(argv[1], S_IFREG | 0644, 0); - if (rc) { -- printf("mknod(%s) error: %s\n", argv[1], strerror(errno)); -- } -- return rc; - } -} diff --cc lustre/tests/mcrlov.sh index 93f1247,35ba323..0000000 deleted file mode 100755,100755 --- a/lustre/tests/mcrlov.sh +++ /dev/null @@@ -1,52 -1,51 +1,0 @@@ --#!/bin/bash -- --config=${1:-mcrlov.xml} -- --LMC="../utils/lmc -m $config" -- --# TCP/IP servers --SERVERS="ba-ost-1 ba-ost-2" --ROUTER=dev5 --MDS=dev7 --TMP=${TMP:-/tmp} -- --# Elan clients --CLIENT_LO=dev2 --CLIENT_HI=dev25 -- - PORT=988 --TCPBUF=1048576 -- -- --h2elan () { -- echo $1 | sed 's/[^0-9]*//g' --} -- --h2ip () { -- echo "${1}" --} -- --[ -f $config ] && rm $config -- --# Client node --${LMC} --node client --net '*' elan || exit 1 --# Router node - ${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp $PORT || exit 1 -${LMC} --router --node $ROUTER --tcpbuf $TCPBUF --net `h2ip $ROUTER` tcp || exit 1 --${LMC} --node $ROUTER --net `h2elan $ROUTER` elan|| exit 1 --${LMC} --node $ROUTER --route elan `h2elan $ROUTER` `h2elan $CLIENT_LO` `h2elan $CLIENT_HI` || exit 2 -- --${LMC} --node $MDS --net `h2elan $MDS` elan || exit 1 --${LMC} --node $MDS --mds mds1 $TMP/mds1 100000 || exit 1 --${LMC} --lov lov1 mds1 65536 0 0 -- --${LMC} --node client --mtpt /mnt/lustre mds1 lov1 -- --for s in $SERVERS -- do -- # server node - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp $PORT || exit 1 - ${LMC} --node $s --tcpbuf $TCPBUF --net $s tcp || exit 1 -- # route to server -- ${LMC} --node $ROUTER --route tcp `h2ip $ROUTER` $s || exit 2 -- # the device on the server -- ${LMC} --format --lov lov1 --node $s --ost bluearc || exit 3 --done diff --cc lustre/tests/mdcreq.sh index bd54c96,bd54c96..0000000 deleted file mode 100644,100644 --- a/lustre/tests/mdcreq.sh +++ /dev/null @@@ -1,37 -1,37 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`" --. $SRCDIR/common.sh -- --NETWORK=tcp --LOCALHOST=localhost --SERVER=localhost --PORT=988 --TMP=${TMP:-/tmp} -- --setup_portals --setup_lustre -- --MDSFS=ext2 --new_fs ${MDSFS} $TMP/mds 1000 --MDS=$LOOPDEV -- --echo 0xffffffff > /proc/sys/portals/debug -- --$OBDCTL < --#include --#include --#include --#include --#include --#include -- --int main(int argc, char ** argv) --{ -- int rc; -- -- if (argc < 2) { -- printf("Usage %s filename\n", argv[0]); -- return 1; -- } -- -- rc = unlink(argv[1]); -- if (rc) { -- printf("unlink(%s) error: %s\n", argv[1], strerror(errno)); -- } -- return rc; --} diff --cc lustre/tests/net-client.cfg index 7cd4a8d,7cd4a8d..0000000 deleted file mode 100644,100644 --- a/lustre/tests/net-client.cfg +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh --# Config file for setting up a remote server with a real OST --NETWORK=tcp --LOCALHOST=dev5 --SERVER=dev4 --PORT=988 diff --cc lustre/tests/net-local.cfg index 2ce3abe,2ce3abe..0000000 deleted file mode 100644,100644 --- a/lustre/tests/net-local.cfg +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh --# Config file for running tests on a single host over loopback TCP --NETWORK=tcp --LOCALHOST=localhost --SERVER=localhost --PORT=988 diff --cc lustre/tests/net-server.cfg index 8386525,8386525..0000000 deleted file mode 100644,100644 --- a/lustre/tests/net-server.cfg +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh --# Config file for setting up a remote server with a real OST --NETWORK=tcp --LOCALHOST=dev4 --SERVER=dev4 --PORT=988 diff --cc lustre/tests/obddisk.cfg index 22e6ef2,22e6ef2..0000000 deleted file mode 100644,100644 --- a/lustre/tests/obddisk.cfg +++ /dev/null @@@ -1,6 -1,6 +1,0 @@@ --#!/bin/sh --# Config file for setting up an object storage target with obdfilter --OSTDEV=/dev/hda7 --OSTFS=ext2 --OSTTYPE=obdfilter --SETUP_OST=y diff --cc lustre/tests/obdecho.cfg index 2c2b40f,2c2b40f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/obdecho.cfg +++ /dev/null @@@ -1,4 -1,4 +1,0 @@@ --#!/bin/sh --# Config file for setting up a test (echo) OST --OSTTYPE=obdecho --SETUP_OST=y diff --cc lustre/tests/obdfilter.cfg index e9021c2,e9021c2..0000000 deleted file mode 100644,100644 --- a/lustre/tests/obdfilter.cfg +++ /dev/null @@@ -1,7 -1,7 +1,0 @@@ --#!/bin/sh --# Config file for setting up an object storage target with obdfilter --OSTDEV=/tmp/ost --OSTSIZE=10000 --OSTFS=extN --OSTTYPE=obdfilter --SETUP_OST=y diff --cc lustre/tests/openclose.c index cc4b06d,cc4b06d..0000000 deleted file mode 100644,100644 --- a/lustre/tests/openclose.c +++ /dev/null @@@ -1,143 -1,143 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#ifndef O_DIRECT --# define O_DIRECT 040000 /* direct disk access hint */ --#endif -- --int main(int argc, char *argv[]) --{ -- char filename[1024]; -- unsigned long count, i; -- int thread = 0; -- int threads = 0; -- int rc = 0; -- int fd, ioctl_flags = 0; -- -- if (argc < 3 || argc > 4) { -- fprintf(stderr, "usage: %s [threads]\n", -- argv[0]); -- exit(1); -- } -- -- count = strtoul(argv[2], NULL, 0); -- if (argc == 4) -- threads = strtoul(argv[3], NULL, 0); -- -- for (i = 1; i <= threads; i++) { -- rc = fork(); -- if (rc < 0) { -- fprintf(stderr, "error: %s: #%ld - %s\n", argv[0], i, -- strerror(rc = errno)); -- break; -- } else if (rc == 0) { -- thread = i; -- argv[2] = "--device"; -- break; -- } else -- printf("%s: thread #%ld (PID %d) started\n", -- argv[0], i, rc); -- rc = 0; -- } -- -- if (threads && thread == 0) { /* parent process */ -- int live_threads = threads; -- -- while (live_threads > 0) { -- int status; -- pid_t ret; -- -- ret = waitpid(0, &status, 0); -- if (ret == 0) { -- continue; -- } -- -- if (ret < 0) { -- fprintf(stderr, "error: %s: wait - %s\n", -- argv[0], strerror(errno)); -- if (!rc) -- rc = errno; -- } else { -- /* -- * This is a hack. We _should_ be able to use -- * WIFEXITED(status) to see if there was an -- * error, but it appears to be broken and it -- * always returns 1 (OK). See wait(2). -- */ -- int err = WEXITSTATUS(status); -- if (err || WIFSIGNALED(status)) -- fprintf(stderr, -- "%s: PID %d had rc=%d\n", -- argv[0], ret, err); -- if (!rc) -- rc = err; -- -- live_threads--; -- } -- } -- } else { -- if (threads) -- sprintf(filename, "%s-%d", argv[1], thread); -- else -- strcpy(filename, argv[1]); -- -- fd = open(filename, O_RDWR|O_CREAT, 0644); -- if (fd < 0) { -- fprintf(stderr, "open(%s, O_CREAT): %s\n", filename, -- strerror(errno)); -- exit(errno); -- } -- if (close(fd) < 0) { -- fprintf(stderr, "close(): %s\n", strerror(errno)); -- rc = errno; -- goto unlink; -- } -- -- for (i = 0; i < count; i++) { -- fd = open(filename, O_RDWR|O_LARGEFILE|O_DIRECT); -- if (fd < 0) { -- fprintf(stderr, "open(%s, O_RDWR): %s\n", -- filename, strerror(errno)); -- rc = errno; -- break; -- } -- if (ioctl(fd, LL_IOC_SETFLAGS, &ioctl_flags) < 0) { -- fprintf(stderr, "ioctl(): %s\n", -- strerror(errno)); -- rc = errno; -- break; -- } -- if (close(fd) < 0) { -- fprintf(stderr, "close(): %s\n", -- strerror(errno)); -- rc = errno; -- break; -- } -- } -- unlink: -- if (unlink(filename) < 0) { -- fprintf(stderr, "unlink(%s): %s\n", filename, -- strerror(errno)); -- rc = errno; -- } -- if (threads) -- printf("Thread %d done: rc = %d\n", thread, rc); -- else -- printf("Done: rc = %d\n", rc); -- } -- return rc; --} diff --cc lustre/tests/openme.c index 9a1f3f3,9a1f3f3..0000000 deleted file mode 100644,100644 --- a/lustre/tests/openme.c +++ /dev/null @@@ -1,23 -1,23 +1,0 @@@ --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- int fd; -- -- if (argc != 2) { -- printf("Usage openme \n"); -- exit(1); -- } -- -- fd = open(argv[1], O_RDONLY | O_CREAT, 0600); -- if (fd == -1) { -- printf("Error opening %s\n", argv[1]); -- exit(1); -- } -- -- sleep(10000000); -- return 0; --} diff --cc lustre/tests/openunlink.c index 3d5904d,3d5904d..0000000 deleted file mode 100644,100644 --- a/lustre/tests/openunlink.c +++ /dev/null @@@ -1,132 -1,132 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --#define T1 "write before unlink\n" --#define T2 "write after unlink\n" --char buf[128]; -- --int main(int argc, char **argv) --{ -- int fd, rc; -- -- if (argc != 2) { -- fprintf(stderr, "usage: %s filename\n", argv[0]); -- exit(1); -- } else { -- fprintf(stderr, "congratulations - program starting\n"); -- } -- -- fprintf(stderr, "opening\n"); -- fd = open(argv[1], O_RDWR | O_TRUNC | O_CREAT, 0644); -- if (fd == -1) { -- fprintf(stderr, "open (normal) %s\n", strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "writing\n"); -- rc = write(fd, T1, strlen(T1) + 1); -- if (rc != strlen(T1) + 1) { -- fprintf(stderr, "write (normal) %s\n", strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "closing\n"); -- rc = close(fd); -- if (rc) { -- fprintf(stderr, "close (normal) %s\n", strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "opening again\n"); -- fd = open(argv[1], O_RDWR); -- if (fd == -1) { -- fprintf(stderr, "open (unlink) %s\n", strerror(errno)); -- exit(1); -- } -- --#if 0 -- fprintf(stderr, "unlinking\n"); -- rc = unlink(argv[1]); -- if (rc) { -- fprintf(stderr, "unlink %s\n", strerror(errno)); -- exit(1); -- } --#else -- printf("unlink %s and press enter\n", argv[1]); -- getc(stdin); --#endif -- -- fprintf(stderr, "reading\n"); -- rc = read(fd, buf, strlen(T1) + 1); -- if (rc != strlen(T1) + 1) { -- fprintf(stderr, "read (unlink) %s rc %d\n", -- strerror(errno), rc); -- exit(1); -- } -- -- fprintf(stderr, "comparing data\n"); -- if (memcmp(buf, T1, strlen(T1) + 1) ) { -- fprintf(stderr, "FAILURE: read wrong data after unlink\n"); -- exit(1); -- } -- -- fprintf(stderr, "truncating\n"); -- rc = ftruncate(fd, 0); -- if (rc ) { -- fprintf(stderr, "truncate (unlink) %s\n", strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "seeking\n"); -- rc = lseek(fd, 0, SEEK_SET); -- if (rc) { -- fprintf(stderr, "seek (after unlink trunc) %s\n", -- strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "writing again\n"); -- rc = write(fd, T2, strlen(T2) + 1); -- if (rc != strlen(T2) + 1) { -- fprintf(stderr, "write (after unlink trunc) %s (rc %d)\n", -- strerror(errno), rc); -- exit(1); -- } -- -- fprintf(stderr, "seeking\n"); -- rc = lseek(fd, 0, SEEK_SET); -- if (rc) { -- fprintf(stderr, "seek (before unlink read) %s\n", -- strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "reading again\n"); -- rc = read(fd, buf, strlen(T2) + 1); -- if (rc != strlen(T2) + 1) { -- fprintf(stderr, "read (after unlink rewrite) %s\n", -- strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "comparing data again\n"); -- if (memcmp(buf, T2, strlen(T2) + 1)) { -- fprintf(stderr, "FAILURE: read wrong data after rewrite\n"); -- exit(1); -- } -- -- fprintf(stderr, "closing again\n"); -- rc = close(fd); -- if (rc) { -- fprintf(stderr, "close (unlink) %s\n", strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "SUCCESS - goto beer\n"); -- return 0; --} diff --cc lustre/tests/ostreq.sh index 2d600ca,2d600ca..0000000 deleted file mode 100644,100644 --- a/lustre/tests/ostreq.sh +++ /dev/null @@@ -1,37 -1,37 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- --SERVER=localhost --PORT=988 --TMP=${TMP:-/tmp} -- --$ACCEPTOR $PORT -- --$PTLCTL < /proc/sys/portals/debug - if [ ! -e client.txt ]; then - if [ -e /usr/lib/dbench/client.txt ]; then - cp /usr/lib/dbench/client.txt /mnt/lustre/client.txt - elif [ -e /usr/lib/dbench/client_plain.txt ]; then - cp /usr/lib/dbench/client_plain.txt /mnt/lustre/client.txt - fi - fi -#[ -e /proc/sys/portals/debug ] && echo 0 > /proc/sys/portals/debug -TGT=/mnt/lustre/client.txt -SRC=/usr/lib/dbench/client.txt -[ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT -SRC=/usr/lib/dbench/client_plain.txt -[ ! -e $TGT -a -e $SRC ] && echo "copying $SRC to $TGT" && cp $SRC $TGT --cd /mnt/lustre --dbench -c client.txt $@ diff --cc lustre/tests/runfailure-client-mds-recover.sh index 8ea79df,8ea79df..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runfailure-client-mds-recover.sh +++ /dev/null @@@ -1,103 -1,103 +1,0 @@@ --#!/bin/sh --SRCDIR=. -- --. common.sh -- --reconnect () { -- --$OBDCTL < /proc/sys/lustre/fail_loc --touch /mnt/lustre/foo & --ps axww | grep touch --echo "MDS dropped create request -- sleep 4 secs - watch for timeout" --sleep 7 --# reconnect --sleep 1 --echo "did things recover? check for file foo." --ls -l /mnt/lustre --echo "Test 1 done" -- -- --echo --echo "Test 2 test delay queue:" `date` "creating /mnt/lustre/foo" --echo --rm -rf /mnt/lustre/* --mkdir /mnt/lustre/a --echo 0x80000107 > /proc/sys/lustre/fail_loc --touch /mnt/lustre/foo & --ps axww | grep touch --echo "MDS dropped create request -- sleep 4 secs - watch for timeout" --sleep 4 --touch /mnt/lustre/a/f & --#reconnect --sleep 5 --echo "did things recover? check for file foo and a/f" --ls -l /mnt/lustre --ls -l /mnt/lustre/a --echo "Test 2 done" -- --echo --echo "Test 3 dropped reply:" `date` "creating /mnt/lustre/foo2" --echo --rm -rf /mnt/lustre/* --echo 0x80000119 > /proc/sys/lustre/fail_loc --touch /mnt/lustre/foo2 & --ps axww | grep touch --echo "MDS dropped create request -- sleep 4 secs - watch for timeout" --sleep 4 --# reconnect --echo failure cleared --sleep 4 --echo "did things recover? check for file foo2" --ls -l /mnt/lustre --echo "Test 3 done" -- -- --echo --echo "Test 4: Multiple failures" --echo --echo 0x0000107 > /proc/sys/lustre/fail_loc --touch /mnt/lustre/bar & --ps axww | grep touch --echo "touch program will have repeated failures sleeping 10" --sleep 10 --echo 0 > /proc/sys/lustre/fail_loc --# reconnect --sleep 6 --echo "failure cleared" --echo "did things recover? Check for file bar" --ls -l /mnt/lustre/bar -- --echo "Test 4 done" -- -- --echo --echo "Test 5: Continue writing during recovery:" `date` "creating and writing/mnt/lustre/foo" --echo --rm -rf /mnt/lustre/* --./openme /mnt/lustre/foo3 & --./writeme /mnt/lustre/iogoeson & --sleep 1 --ls -l /mnt/lustre --echo 0x80000107 > /proc/sys/lustre/fail_loc --mknod /mnt/lustre/dev c 10 240 & --echo "MDS dropped create request -- sleep 4 secs - watch for timeout" --sleep 6 --# reconnect --sleep 1 --echo "did things recover? check for file foo, bar, check log for reopen." --ls -l /mnt/lustre --echo "Test 5 done" diff --cc lustre/tests/runfailure-mds index f2942c3,f2942c3..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runfailure-mds +++ /dev/null @@@ -1,63 -1,63 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`" --. $SRCDIR/common.sh -- --. $SRCDIR/llmount.sh -- --MNT="setup_mount" -- --test_fail() { -- echo $1 > /proc/sys/lustre/fail_loc -- shift -- echo "Running '$*'" -- $* -- -- echo "Cleaning up and restarting MDS" -- umount /mnt/lustre || fail "unable to unmount" -- $OBDCTL <<- EOF -- name2dev MDSDEV -- cleanup -- detach -- quit -- EOF -- -- echo 0 > /proc/sys/lustre/fail_loc -- -- $OBDCTL <<- EOF -- newdev -- attach mds MDSDEV -- setup ${MDS} ${MDSFS} -- quit -- EOF -- $MNT --} -- --#set -vx -- --touch /mnt/lustre/foo --chmod a+x /mnt/lustre/foo --sync -- --# OBD_FAIL_MDS_REINT_SETATTR_WRITE - MDS will discard data from setattr --test_fail 0x10a chmod 000 /mnt/lustre/foo --ls -l /mnt/lustre/foo --[ ! -x /mnt/lustre/foo ] && fail "/mnt/lustre/foo is not executable!" -- --# OBD_FAIL_MDS_REINT_CREATE_WRITE - MDS will not create the file --test_fail 0x10c touch /mnt/lustre/bar --ls /mnt/lustre/bar --[ $? -eq 0 ] && fail "/mnt/lustre/bar was created!" -- --# OBD_FAIL_MDS_REINT_UNLINK_WRITE - MDS will discard data from unlink --test_fail 0x10e rm /mnt/lustre/foo --ls /mnt/lustre/foo --[ $? -eq 1 ] && fail "/mnt/lustre/foo has been removed!" -- --# OBD_FAIL_MDS_REINT_RENAME_WRITE - MDS will discard data from rename --test_fail 0x112 mv /mnt/lustre/foo /mnt/lustre/bar --ls /mnt/lustre/foo /mnt/lustre/bar --[ ! -f /mnt/lustre/foo -o -f /mnt/lustre/bar ] && \ -- fail "/mnt/lustre/foo has been renamed to bar!" -- --echo "Done." diff --cc lustre/tests/runfailure-net index ce5634b,ce5634b..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runfailure-net +++ /dev/null @@@ -1,66 -1,66 +1,0 @@@ --#!/bin/sh -- --fail() { -- echo "ERROR: $1" 1>&2 -- [ $2 ] && RC=$2 || RC=1 -- exit $RC --} -- --test_fail() { -- oldtimeout=`cat /proc/sys/lustre/timeout` -- echo $TIMEOUT > /proc/sys/lustre/timeout -- echo $1 > /proc/sys/lustre/fail_loc -- shift -- $* & -- sleep $TIMEOUT -- sleep 2 # fudge -- kill -9 $! -- -- echo $oldtimeout > /proc/sys/lustre/timeout -- echo 0 > /proc/sys/lustre/fail_loc -- umount -f /mnt/lustre || fail "cannot unmount /mnt/lustre" -- mount -t lustre_lite -o "osc=$OSC,mdc=$MDC" none /mnt/lustre || \ -- fail "cannot remount $OSC/$MDC on /mnt/lustre" --} -- --set -vx -- --LCTL=../utils/lctl --OSC=OSC_localhost_UUID --MDC=MDC_client1_UUID --TIMEOUT=5 # complete in finite time -- --[ "`mount | grep /mnt/lustre`" ] || echo | sh llmount.sh || exit -1 -- --# GETATTR_NET - ls will hang on the getattr --# test_fail 0x102 ls -l /mnt/lustre -- --# READPAGE_NET - ls will hang reading in new pages (lost+found is not in cache) --test_fail 0x104 ls /mnt/lustre -- --sleep 1 -- --# REINT_NET - touch will hang on setattr --test_fail 0x107 touch /mnt/lustre -- --# REINT_NET - touch will hang on create --test_fail 0x107 touch /mnt/lustre/tt -- --# REINT_NET - mv will hang on rename --touch /mnt/lustre/foo --test_fail 0x107 mv /mnt/lustre/foo /mnt/lustre/bar -- --# REINT_NET - rm will hang on unlink --touch /mnt/lustre/salmon --test_fail 0x107 rm /mnt/lustre/salmon -- --# OPEN_NET - touch will hang on open --touch /mnt/lustre/foo --test_fail 0x113 cat /mnt/lustre/foo -- --# CLOSE_NET - ls will hang on close --test_fail 0x115 ./testreq --close junk_file_handle -- --echo 0 > /proc/sys/lustre/fail_loc -- --echo "Done." diff --cc lustre/tests/runfailure-ost index 0c68d5a,0c68d5a..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runfailure-ost +++ /dev/null @@@ -1,51 -1,51 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`" --. $SRCDIR/common.sh -- --setup_opts "$@" -- --set -vx -- --test_fail() { -- echo $1 > /proc/sys/lustre/fail_loc -- shift -- echo "Running '$*'" -- $* & -- sleep 1 -- kill -9 $! -- -- echo 0 > /proc/sys/lustre/fail_loc -- umount /mnt/lustre || fail "cannot unmount /mnt/lustre" -- setup_mount || fail "cannot remount /mnt/lustre" --} -- --[ "`mount | grep /mnt/lustre`" ] || . llsetup.sh "$@" || exit -1 -- --# OBD_FAIL_OST_OPEN_NET: OST will discard open request packet --touch /mnt/lustre/foo --test_fail 0x208 cat /mnt/lustre/foo -- --# OBD_FAIL_OST_CLOSE_NET: OST will discard close request packet --test_fail 0x209 cat /mnt/lustre/foo -- --# OBD_FAIL_OST_CREATE_NET: OST will discard create request packet --test_fail 0x204 touch /mnt/lustre/bar -- --# OBD_FAIL_OST_DESTROY_NET: OST will discard destroy request packet --test_fail 0x205 rm /mnt/lustre/foo -- --# OBD_FAIL_OST_BRW_NET: OST will discard read request packet --echo foo >> /mnt/lustre/foo --test_fail 0x20a cat /mnt/lustre/foo -- --# OBD_FAIL_OST_BRW_NET: OST will discard write request packet --test_fail 0x20a "echo bar >> /mnt/lustre/foo" -- --# OBD_FAIL_OST_PUNCH_NET: OST will discard truncate request packet --test_fail 0x208 "echo bar > /mnt/lustre/foo" -- --# OBD_FAIL_OST_STATFS_NET: OST will discard statfs request packet --test_fail 0x208 df /mnt/lustre -- --echo "Done." diff --cc lustre/tests/runregression-brw.sh index a066c11,702bd1f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/runregression-brw.sh +++ /dev/null @@@ -1,113 -1,112 +1,0 @@@ --#!/bin/sh --export PATH=/sbin:/usr/sbin:$PATH -- --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- - COUNT=${COUNT:-10000000} -COUNT=${COUNT:-1000000} --COUNT_10=`expr $COUNT / 10` --COUNT_100=`expr $COUNT / 100` -- --ENDRUN=endrun-`hostname` -- - OSCNAME="`$OBDCTL device_list 2> /dev/null | awk '/ osc | lov / { print $4 }' | tail -1`" -ECHONAME="`$OBDCTL device_list 2> /dev/null | awk '/ echo_client / { print $4 }' | tail -1`" -- - if [ -z "$OSCNAME" ]; then - echo "$0: needs an OSC set up first" 1>&2 -if [ -z "$ECHONAME" ]; then - echo "$0: needs an ECHO_CLIENT set up first" 1>&2 -- exit 1 --fi -- --cleanup () { - $OBDCTL --device \$$OSCNAME destroy $OID - $OBDCTL --device \$$ECHONAME destroy $OID --} -- --runthreads() { -- THR=$1 -- DO=$2 -- CNT=$3 -- V=$4 -- PGS=$5 -- -- case $DO in -- test_getattr) -- RW= -- ;; -- test_brw_write) -- DO=test_brw -- RW=w -- ;; - -- test_brw_read) -- DO=test_brw -- RW=r -- ;; -- esac -- - $OBDCTL --threads $THR v \$$OSCNAME $DO $CNT $RW $V $PGS $OID || exit 1 - $OBDCTL --threads $THR v \$$ECHONAME $DO $CNT $RW $V $PGS $OID || exit 1 -- -- if [ -e $ENDRUN ]; then -- rm $ENDRUN -- echo "exiting because $ENDRUN file was found" -- cleanup -- fi --} -- - [ -z "$OID" ] && OID=`$OBDCTL --device \\$$OSCNAME create 1 | awk '/is object id/ { print $6 }'` -[ -z "$OID" ] && OID=`$OBDCTL --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` --[ -z "$OID" ] && echo "error creating object" 1>&2 && exit 1 -- --# TODO: obdctl needs to check on the progress of each forked thread --# (IPC SHM, sockets?) to see if it hangs. --while date; do -- PG=1 -- PGVW=16 -- PGVR=16 -- -- # We use '--threads 1 X' instead of '--device X' so that -- # obdctl can monitor the forked thread for progress (TODO). -- debug_server_off -- debug_client_off -- runthreads 1 test_brw_write 1000 -30 $PG -- runthreads 1 test_brw_read 1000 -30 $PG -- -- [ "$PGVW" ] && runthreads 1 test_brw_write 100 -30 $PGVW -- [ "$PGVW" ] && runthreads 1 test_brw_read 1600 -30 $PG -- [ "$PGVR" ] && runthreads 1 test_brw_read 100 -30 $PGVR -- -- runthreads 1 test_brw_write $COUNT -30 $PG -- runthreads 1 test_brw_read $COUNT -30 $PG -- -- [ "$PGVW" ] && runthreads 1 test_brw_write $COUNT_10 -30 $PGVW -- [ "$PGVR" ] && runthreads 1 test_brw_read $COUNT_10 -30 $PGVR -- -- runthreads 2 test_brw_write $COUNT -30 $PG -- runthreads 2 test_brw_read $COUNT -30 $PG -- -- [ "$PGVW" ] && runthreads 2 test_brw_write $COUNT_10 -30 $PGVW -- [ "$PGVR" ] && runthreads 2 test_brw_read $COUNT_10 -30 $PGVR -- -- runthreads 10 test_brw_write $COUNT_10 -30 $PG -- runthreads 10 test_brw_read $COUNT_10 -30 $PG -- -- [ "$PGVW" ] && runthreads 10 test_brw_write $COUNT_100 -60 $PGVW -- [ "$PGVR" ] && runthreads 10 test_brw_read $COUNT_100 -60 $PGVR -- -- runthreads 32 test_brw_write $COUNT_10 -30 $PG -- runthreads 32 test_brw_read $COUNT_10 -30 $PG -- -- [ "$PGVW" ] && runthreads 32 test_brw_write $COUNT_100 -60 $PGVW -- [ "$PGVR" ] && runthreads 32 test_brw_read $COUNT_100 -60 $PGVR -- -- runthreads 64 test_brw_write $COUNT_10 -30 $PG -- runthreads 64 test_brw_read $COUNT_10 -30 $PG -- -- [ "$PGVW" ] && runthreads 64 test_brw_write $COUNT_100 -60 $PGVW -- [ "$PGVR" ] && runthreads 64 test_brw_read $COUNT_100 -60 $PGVR -- -- runthreads 100 test_brw_write $COUNT_100 -60 $PG -- runthreads 100 test_brw_read $COUNT_100 -60 $PG -- -- [ "$PGVW" ] && runthreads 100 test_brw_write $COUNT_100 -60 $PGVW -- [ "$PGVR" ] && runthreads 100 test_brw_read $COUNT_100 -60 $PGVR --done -- --cleanup diff --cc lustre/tests/runregression-mds.sh index ecfe0d9,ecfe0d9..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runregression-mds.sh +++ /dev/null @@@ -1,67 -1,67 +1,0 @@@ --#!/bin/sh -- --SRCDIR="`dirname $0`" -- --ENDRUN=endrun-`hostname` -- --fail() { -- echo "ERROR: $1" 1>&2 -- [ $2 ] && RC=$2 || RC=1 -- exit $RC --} -- --export PATH=/sbin:/usr/sbin:$SRCDIR:$PATH -- --cleanup() { -- trap 0 -- $LCONF --cleanup $OPTS --} -- --[ "$COUNT" ] || COUNT=1000 -- --[ "$LCONF" ] || LCONF=$SRCDIR/../utils/lconf -- --[ -z "$*" ] && fail "usage: $0 [--reformat] .xml" 1 -- --OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" --if [ -z "$OSCMT" ]; then -- $LCONF $@ || exit 1 -- trap cleanup 0 -- OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" -- [ -z "$OSCMT" ] && fail "no lustre filesystem mounted" 1 --fi -- --V="-10" --while [ "$1" ]; do -- case $1 in -- -v|--verbose) V="1";; -- --reformat) : ;; -- *) OPTS="$OPTS $1" ;; -- esac -- shift --done -- --OSCTMP=`echo $OSCMT | tr "/" "."` --USED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` --USED=`expr $USED + 16` # Some space for the status file -- --THREADS=1 --while [ $THREADS -lt 196 ]; do -- echo "starting $THREADS threads at `date`" -- [ $V -gt 0 ] || echo 0 > /proc/sys/portals/debug -- $SRCDIR/createdestroy /mnt/lustre/file-$$ $COUNT $V $THREADS -- $SRCDIR/openclose /mnt/lustre/file-$$ $COUNT $THREADS -- THREADS=`expr $THREADS + 5` -- $LCONF --cleanup $OPTS || fail 10 -- $LCONF $OPTS || fail 11 --done -- --rm -f $ENDRUN -- --NOWUSED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` --if [ $NOWUSED -gt $USED ]; then -- echo "Space not all freed: now ${NOWUSED}kB, was ${USED}kB." 1>&2 -- echo "This is normal on BA OSTs, because of subdirectories." 1>&2 --fi -- --cleanup diff --cc lustre/tests/runregression-net.sh index 54e645f,288f847..0000000 deleted file mode 100644,100644 --- a/lustre/tests/runregression-net.sh +++ /dev/null @@@ -1,105 -1,100 +1,0 @@@ --#!/bin/sh --export PATH=/sbin:/usr/sbin:$PATH -- --SRCDIR="`dirname $0`/" --. $SRCDIR/common.sh -- - COUNT=${COUNT:-10000000} -COUNT=${COUNT:-1000000} --COUNT_10=`expr $COUNT / 10` --COUNT_100=`expr $COUNT / 100` --COUNT_1000=`expr $COUNT / 1000` -- --ENDRUN=endrun-`hostname` -- - OSCNAME="`$OBDCTL device_list 2> /dev/null | awk '/ osc | lov / { print $4 }' | tail -1`" -ECHONAME="`$OBDCTL device_list 2> /dev/null | awk '/ echo_client / { print $4 }' | tail -1`" -- - if [ -z "$OSCNAME" ]; then - echo "$0: needs an OSC set up first" 1>&2 -if [ -z "$ECHONAME" ]; then - echo "$0: needs an ECHO_CLIENT set up first" 1>&2 -- exit 1 --fi -- --runthreads() { -- THR=$1 -- DO=$2 -- CNT=$3 -- V=$4 -- PGS=$5 -- -- case $DO in -- test_getattr) -- RW= -- ;; - -- test_brw_write) -- DO=test_brw -- RW=w -- ;; -- -- test_brw_read) -- DO=test_brw -- RW=r -- ;; -- esac -- - $OBDCTL --threads $THR v \$$OSCNAME $DO $CNT $RW $V $PGS $OID || exit 1 - $OBDCTL --threads $THR v \$$ECHONAME $DO $CNT $RW $V $PGS $OID || exit 1 -- -- if [ -e endrun ]; then -- rm endrun -- echo "exiting because endrun file was found" -- exit 0 -- fi --} -- - [ -z "$OID" ] && OID=`$OBDCTL --device \\$$OSCNAME create 1 | awk '/is object id/ { print $6 }'` -[ -z "$OID" ] && OID=`$OBDCTL --device \\$$ECHONAME create 1 | awk '/is object id/ { print $6 }'` --[ -z "$OID" ] && echo "error creating object" 1>&2 && exit 1 -- --# TODO: obdctl needs to check on the progress of each forked thread --# (IPC SHM, sockets?) to see if it hangs. --for CMD in test_getattr test_brw_write test_brw_read; do -- case $CMD in -- test_getattr) -- PG= -- PGV= -- ;; -- test_brw_write) -- PG=1 -- PGV=16 -- ;; - -- test_brw_read) -- PG=1 - case $OSTNODE in - ba*) PGV= ;; # disabled until the BA OST code is updated - *) PGV=16 ;; - esac - PGV=16 -- ;; -- esac -- -- # We use '--threads 1 X' instead of '--device X' so that -- # obdctl can monitor the forked thread for progress (TODO). -- runthreads 1 $CMD 1 1 $PG -- runthreads 1 $CMD 100 1 $PG -- -- debug_server_off -- debug_client_off -- runthreads 1 $CMD $COUNT_100 -10 $PG -- [ "$PGV" ] && runthreads 1 $CMD $COUNT_1000 -10 $PGV -- -- runthreads 1 $CMD $COUNT -30 $PG -- [ "$PGV" ] && runthreads 1 $CMD $COUNT_10 -30 $PGV - - runthreads 1 $CMD 100 -10 $PG -- -- runthreads 2 $CMD $COUNT_100 -30 $PG -- [ "$PGV" ] && runthreads 2 $CMD $COUNT_1000 -30 $PGV -- -- runthreads 2 $CMD $COUNT -30 $PG -- [ "$PGV" ] && runthreads 2 $CMD $COUNT_10 -30 $PGV -- -- runthreads 10 $CMD $COUNT_10 -30 $PG -- [ "$PGV" ] && runthreads 10 $CMD $COUNT_100 -30 $PGV -- -- runthreads 100 $CMD $COUNT_100 -30 $PG -- [ "$PGV" ] && runthreads 100 $CMD $COUNT_1000 -30 $PGV --done -- - $OBDCTL --device \$$OSCNAME destroy $OID -$OBDCTL --device \$$ECHONAME destroy $OID diff --cc lustre/tests/runslabinfo index 48d6602,48d6602..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runslabinfo +++ /dev/null @@@ -1,5 -1,5 +1,0 @@@ --#!/bin/sh --while sleep 1 ; do -- egrep "ll_|ldlm|filp|dentry|inode|portals|size-[0-9]* " /proc/slabinfo -- echo '-----------------------' --done diff --cc lustre/tests/runtests index 28288aa,e068a01..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runtests +++ /dev/null @@@ -1,124 -1,115 +1,0 @@@ --#!/bin/sh --# --# Script which does some basic tests to ensure we haven't regressed. --# Probably a good idea to run this before doing any checkins. --# In the future this can become more fancy, but it's OK for now. -- --SRCDIR="`dirname $0`" --fail() { -- echo "ERROR: $1" 1>&2 -- [ $2 ] && RC=$2 || RC=1 -- exit $RC --} -- --export PATH=/sbin:/usr/sbin:$SRCDIR:$PATH - - cleanup() { - $LCONF --cleanup --dump /tmp/debug $OPTS - trap 0 - } -- --ERROR= --SRC=/etc --[ "$COUNT" ] || COUNT=1000 -- --[ "$LCONF" ] || LCONF=$SRCDIR/../utils/lconf -- --[ "$MCREATE" ] || MCREATE=$SRCDIR/../tests/mcreate - - OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" - if [ -z "$OSCMT" ]; then - [ -z "$*" ] && fail "usage: $0 [--reformat] .xml" 1 - $LCONF $@ || exit 1 - trap cleanup 0 - OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" - [ -z "$OSCMT" ] && fail "no lustre filesystem mounted" 1 - fi -- --while [ "$1" ]; do -- case $1 in - -v|--verbose) V=-v;; - --reformat) : ;; - *) OPTS="$OPTS $1" ;; - *.xml) export NAME=`echo $1 | sed "s/.xml//"` ;; -- esac -- shift --done - -OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" -if [ -z "$OSCMT" ]; then - sh llmount.sh - OSCMT="`mount | awk '/ lustre_lite / { print $3 }' | tail -1`" - [ -z "$OSCMT" ] && fail "no lustre filesystem mounted" 1 - I_MOUNTED="yes" -fi -- --OSCTMP=`echo $OSCMT | tr "/" "."` --USED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` --USED=`expr $USED + 16` # Some space for the status file -- --# let's start slowly here... --echo "touching $OSCMT" --touch $OSCMT || fail "can't touch $OSCMT" 2 --HOSTS=$OSCMT/hosts.$$ -- --# this will cause the following cp to trigger bug #620096 - #echo "create an empty file $HOSTS" - #$MCREATE $HOSTS -echo "create an empty file $HOSTS" -$MCREATE $HOSTS -- --echo "copying /etc/hosts to $HOSTS" --cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS" 3 --echo "comparing /etc/hosts and $HOSTS" --diff -u /etc/hosts $HOSTS || fail "$HOSTS different" 4 --echo "renaming $HOSTS to $HOSTS.ren" --mv $HOSTS $HOSTS.ren || fail "can't rename $HOSTS to $HOSTS.ren" 5 --echo "copying /etc/hosts to $HOSTS again" --cp /etc/hosts $HOSTS || fail "can't cp /etc/hosts to $HOSTS again" 6 --echo "truncating $HOSTS" --> $HOSTS || fail "can't truncate $HOSTS" 8 --echo "removing $HOSTS" --rm $HOSTS || fail "can't remove $HOSTS" 9 -- --DST=$OSCMT/runtest.$$ --# let's start slowly here... --echo "creating $DST" --mkdir $DST || fail "can't mkdir $DST" 10 -- - # ok, that hopefully worked, so let's do a little more - FILES=`find $SRC -type f | grep -v mtab | head -$COUNT` -# ok, that hopefully worked, so let's do a little more, with files that -# haven't changed in the last day (hopefully they don't change during test) -FILES=`find $SRC -type f -mtime +1 -ctime +1 | head -$COUNT` --echo "copying files from $SRC to $DST$SRC" --tar cf - $FILES | tar xvf - -C $DST || fail "copying $SRC" 11 -- --echo "comparing newly copied files" --for f in $FILES; do -- [ $V ] && echo "verifying $DST/$f" -- diff -q $f $DST/$f || ERROR=11 --done -- --[ "$ERROR" ] && fail "old and new files are different" $ERROR - - cleanup || exit 19 - sync -- - $LCONF $OPTS || exit 20 -sh llmountcleanup.sh || exit 19 -sh llrmount.sh || exit 20 -- --echo "comparing previously copied files" --for f in $FILES; do -- [ $V ] && echo "verifying $DST/$f" -- diff -q $f $DST/$f || ERROR=22 --done -- --[ "$ERROR" ] && fail "old and new files are different on second diff" $ERROR -- - cleanup || exit 29 - sync - $LCONF $OPTS || exit 30 -sh llmountcleanup.sh || exit 19 -sh llrmount.sh || exit 20 -- --echo "renaming $HOSTS.ren to $HOSTS" --mv $HOSTS.ren $HOSTS || fail "can't rename $HOSTS.ren to $HOSTS" 32 --echo "truncating $HOSTS" --> $HOSTS || fail "can't truncate $HOSTS" 34 --echo "removing $HOSTS" --rm $HOSTS || fail "can't remove $HOSTS again" 36 --echo "removing $DST" --rm -r $V $DST || fail "can't remove $DST" 37 -- --NOWUSED=`df | awk "/$OSCTMP/ { print \\$3 }" | tail -1` --if [ $NOWUSED -gt $USED ]; then -- echo "Space not all freed: now ${NOWUSED}kB, was ${USED}kB." 1>&2 -- echo "This is normal on BA OSTs, because of subdirectories." 1>&2 --fi -- - cleanup $OPTS || exit 29 - sync -if [ "$I_MOUNTED" = "yes" ]; then - sh llmountcleanup.sh || exit 29 -fi diff --cc lustre/tests/runvmstat index 6bff5ce,6bff5ce..0000000 deleted file mode 100755,100755 --- a/lustre/tests/runvmstat +++ /dev/null @@@ -1,2 -1,2 +1,0 @@@ --#!/bin/sh --vmstat 1 | while read LINE ; do echo "`date +%H:%M:%S`: $LINE" ; done diff --cc lustre/tests/sanity.sh index fabbedf,da72bda..0000000 deleted file mode 100644,100644 --- a/lustre/tests/sanity.sh +++ /dev/null @@@ -1,192 -1,218 +1,0 @@@ --#!/bin/bash - - #CLEAN=umount /mnt/lustre - #START=../utils/lconf --minlevel 70 local.xml - CLEAN="sh llmountcleanup.sh" - START="sh llmount.sh" - -- -export NAME=$NAME -clean() { - echo -n "cleanup..." - sh llmountcleanup.sh > /dev/null -} -CLEAN=clean -start() { - echo -n "mounting..." - sh llrmount.sh > /dev/null - echo -n "mounted" -} -START=start -- - echo '==== touch /mnt/lustre/f ; rm /mnt/lustre/* ==== test 19' -echo '== touch .../f ; rm .../f ======================== test 0' --touch /mnt/lustre/f - rm /mnt/lustre/* -rm /mnt/lustre/f --$CLEAN - dmesg | grep -i destruct --$START - -- - echo '=============================== test 1' -echo '== mkdir .../d1; mkdir .../d1/d2 ================= test 1' --mkdir /mnt/lustre/d1 --mkdir /mnt/lustre/d1/d2 --$CLEAN - dmesg | grep -i destruct --$START -- -echo '== rmdir .../d1/d2; rmdir .../d1 ================= test 1b' -rmdir /mnt/lustre/d1/d2 -rmdir /mnt/lustre/d1 -$CLEAN -$START -- - echo '=============================== test 2' -echo '== mkdir .../d2; touch .../d2/f ================== test 2' --mkdir /mnt/lustre/d2 --touch /mnt/lustre/d2/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 3 -echo '== rm -r .../d2; touch .../d2/f ================== test 2b' -rm -r /mnt/lustre/d2 -$CLEAN -$START - -echo '== mkdir .../d3 ================================== test 3' --mkdir /mnt/lustre/d3 --$CLEAN --$START -echo '== touch .../d3/f ================================ test 3b' --touch /mnt/lustre/d3/f --$CLEAN - dmesg | grep -i destruct -$START -echo '== rm -r .../d3 ================================== test 3c' -rm -r /mnt/lustre/d3 -$CLEAN --$START -- - echo '===============================' test 4 -echo '== mkdir .../d4 ================================== test 4' --mkdir /mnt/lustre/d4 --$CLEAN --$START -echo '== mkdir .../d4/d2 =============================== test 4b' --mkdir /mnt/lustre/d4/d2 --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 5 -echo '== mkdir .../d5; mkdir .../d5/d2; chmod .../d5/d2 = test 5' --mkdir /mnt/lustre/d5 --mkdir /mnt/lustre/d5/d2 --chmod 0666 /mnt/lustre/d5/d2 --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 6 -echo '== touch .../f6; chmod .../f6 ==================== test 6' --touch /mnt/lustre/f6 --chmod 0666 /mnt/lustre/f6 --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 7 -echo '== mkdir .../d7; mcreate .../d7/f; chmod .../d7/f = test 7' --mkdir /mnt/lustre/d7 --./mcreate /mnt/lustre/d7/f --chmod 0666 /mnt/lustre/d7/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 8 -echo '== mkdir .../d8; touch .../d8/f; chmod .../d8/f == test 8' --mkdir /mnt/lustre/d8 --touch /mnt/lustre/d8/f --chmod 0666 /mnt/lustre/d8/f --$CLEAN - dmesg | grep -i destruct --$START -- -- - echo '=============9=================' test 9 -echo '== mkdir .../d9; mkdir .../d9/d2; mkdir .../d9/d2/d3 == test 9' --mkdir /mnt/lustre/d9 --mkdir /mnt/lustre/d9/d2 --mkdir /mnt/lustre/d9/d2/d3 --$CLEAN - dmesg | grep -i destruct --$START -- -- - echo '===============================' test 10 -echo '== mkdir .../d10; mkdir .../d10/d2; touch .../d10/d2/f = test 10' --mkdir /mnt/lustre/d10 --mkdir /mnt/lustre/d10/d2 --touch /mnt/lustre/d10/d2/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 11 -echo '=================================================== test 11' --mkdir /mnt/lustre/d11 --mkdir /mnt/lustre/d11/d2 --chmod 0666 /mnt/lustre/d11/d2 --chmod 0555 /mnt/lustre/d11/d2 --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 12 -echo '=================================================== test 12' --mkdir /mnt/lustre/d12 --touch /mnt/lustre/d12/f --chmod 0666 /mnt/lustre/d12/f --chmod 0555 /mnt/lustre/d12/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 13 -echo '=================================================== test 13' --mkdir /mnt/lustre/d13 --cp /etc/passwd /mnt/lustre/d13/f --> /mnt/lustre/d13/f --$CLEAN - dmesg | grep -i destruct --$START -- -- - echo '===============================' test 14 -echo '=================================================== test 14' --mkdir /mnt/lustre/d14 --touch /mnt/lustre/d14/f --rm /mnt/lustre/d14/f --$CLEAN - dmesg | grep -i destruct --$START -- -- - echo '===============================' test 15 -echo '=================================================== test 15' --mkdir /mnt/lustre/d15 --touch /mnt/lustre/d15/f --mv /mnt/lustre/d15/f /mnt/lustre/d15/f2 --$CLEAN - dmesg | grep -i destruct --$START -- - echo '===============================' test 16 -echo '=================================================== test 16' --mkdir /mnt/lustre/d16 --touch /mnt/lustre/d16/f --rm -rf /mnt/lustre/d16/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '====== symlinks: create, remove symlinks (dangling and real) =====' test 17 -echo '== symlinks: create, remove (dangling and real) === test 17' --mkdir /mnt/lustre/d17 --touch /mnt/lustre/d17/f --ln -s /mnt/lustre/d17/f /mnt/lustre/d17/l-exist --ln -s no-such-file /mnt/lustre/d17/l-dangle --ls -l /mnt/lustre/d17 --rm -f /mnt/lustre/l-dangle --rm -f /mnt/lustre/l-exist --$CLEAN - dmesg | grep -i destruct --$START -- - echo '==== touch /mnt/lustre/f ; ls /mnt/lustre ==== test 18' -echo '== touch /mnt/lustre/f ; ls /mnt/lustre ========== test 18' --touch /mnt/lustre/f --ls /mnt/lustre --$CLEAN - dmesg | grep -i destruct --$START -- - echo '==== touch /mnt/lustre/f ; ls -l /mnt/lustre ==== test 19' -echo '== touch /mnt/lustre/f ; ls -l /mnt/lustre ======= test 19' --touch /mnt/lustre/f --ls -l /mnt/lustre -rm /mnt/lustre/f --$CLEAN - dmesg | grep -i destruct --$START -- - echo '==== touch /mnt/lustre/f ; ls -l /mnt/lustre ==== test 19' -echo '== touch /mnt/lustre/f ; ls -l /mnt/lustre ======= test 20' --touch /mnt/lustre/f --rm /mnt/lustre/f --echo "1 done" --touch /mnt/lustre/f --rm /mnt/lustre/f --echo "2 done" --touch /mnt/lustre/f --rm /mnt/lustre/f --echo "3 done" --$CLEAN - dmesg | grep -i destruct -$START - -echo '== write to dangling link ======================= test 21' -mkdir /mnt/lustre/d21 -ln -s dangle /mnt/lustre/d21/link -echo foo >> /mnt/lustre/d21/link -cat /mnt/lustre/d21/dangle -$CLEAN -$START - -# echo '== unpack tar archive as nonroot user =========== test 22' -echo '== please fix test 22' -# mkdir /mnt/lustre/d22 -# chown 4711 /mnt/lustre/d22 -# (./setuid 4711 ; tar cf - /etc/hosts /etc/sysconfig/network | tar xfC - /mnt/lustre/d22 ; ./setuid 0) -# ls -lR /mnt/lustre/d22/etc -# $CLEAN -# $START - -echo '== O_CREAT|O_EXCL in subdir ===================== test 23' -mkdir /mnt/lustre/d23 -./toexcl /mnt/lustre/d23/f23 -./toexcl /mnt/lustre/d23/f23 -$CLEAN --$START -- -echo '======================= finished =======================' --exit diff --cc lustre/tests/snaprun.sh index ea77cfb,ea77cfb..0000000 deleted file mode 100755,100755 --- a/lustre/tests/snaprun.sh +++ /dev/null @@@ -1,36 -1,36 +1,0 @@@ --#!/bin/sh --# Utility script to test several features of a snapshot filesystem --# Assumes that snapshot has already been configured --# --# Copyright (C) 2001 Cluster File Systems, Inc. --# --# This code is issued under the GNU General Public License. --# See the file COPYING in this distribution -- --OBDDIR="`dirname $0`/.." --. $OBDDIR/demos/config.sh -- --qrun ls $MNTOBD --qrun chown bin.bin $MNTOBD --qrun ls -ld $MNTOBD --qrun ls -ld $MNTSNAP --qrun cp /etc/hosts $MNTOBD --qrun ls $MNTOBD --qrun ls $MNTSNAP -- --# More complicated because we can't pass ">>" as an argument easily --echo -n "Run 'echo today >> $MNTOBD/hello' [Y/n]" ; read JUNK --case $JUNK in -- n*|N*) echo "not run" ;; -- *) plog log "echo today >> $MNTOBD/hello" -- echo "today" >> $MNTOBD/hello ;; --esac -- --qrun cat $MNTOBD/hello --qrun cat $MNTSNAP/hello --qrun cat $MNTOBD/link --qrun cat $MNTSNAP/link --qrun rm $MNTOBD/goodbye --qrun ls $MNTOBD --qrun ls $MNTSNAP --qrun cat $MNTSNAP/goodbye diff --cc lustre/tests/stat.c index b719900,b719900..0000000 deleted file mode 100644,100644 --- a/lustre/tests/stat.c +++ /dev/null @@@ -1,24 -1,24 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --int main(int argc, char ** argv) --{ -- int rc; -- struct stat buf; -- -- if (argc < 2) { -- printf("Usage %s filename\n", argv[0]); -- return 1; -- } -- -- rc = stat(argv[1], &buf); -- if (rc) { -- printf("stat(%s) error: %s\n", argv[1], strerror(errno)); -- } -- return rc; --} diff --cc lustre/tests/tbox.sh index 337e1b8,337e1b8..0000000 deleted file mode 100644,100644 --- a/lustre/tests/tbox.sh +++ /dev/null @@@ -1,116 -1,116 +1,0 @@@ --# tbox.sh - Shell functions to manage tinderbox build reporting --# Copyright (C) 2002 Cluster File Systems, Inc. --# Gord Eagle , 2002-08-22 -- --HOSTNAME=`hostname` --PROGNAME=`echo "$0" | sed -e 's%^.*/%%'` --MAILPROG="${MAILPROG-mail}" -- --TBOX_PHASE=build # or test --TBOX_STARTTIME=`date +%s` --TBOX_LOG="${TBOX_LOG-/tmp/tbox.$$.$TBOX_STARTTIME.log}" --TBOX_BUILDMAIL=tinderbox_builds@lustre.org --TBOX_BUILDNAME="${TBOX_BUILDNAME-$PROGNAME-$HOSTNAME}" -- --# Send a status message to the list. --tbox_status() { -- [ -n "$TBOX_BUILDNAME" -a -n "$TBOX_BUILDMAIL" ] || return 0 -- [ "$#" -ge 4 ] || return 1 -- if [ "$#" -gt 4 ]; then -- log="$5" -- echo >> $log -- else -- log= -- fi -- -- TREE="$1" -- SUBJECT="$2" -- STATUS="$3" -- TIMENOW="$4" -- -- echo "sending tinderbox mail to $TBOX_BUILDMAIL: $TREE $SUBJECT $STATUS" -- -- TMPFILE="/tmp/tinderbox.boilerplate.$$.$TIMENOW" -- -- cat > $TMPFILE <<-EOF -- tinderbox: tree: $TREE -- tinderbox: starttime: $TBOX_STARTTIME -- tinderbox: timenow: $TIMENOW -- tinderbox: builddate: $TBOX_STARTTIME -- tinderbox: status: $STATUS -- tinderbox: buildname: $TBOX_BUILDNAME -- tinderbox: errorparser: unix -- tinderbox: END -- --EOF -- -- cat $TMPFILE $log | $MAILPROG -s "build $SUBJECT ($TBOX_BUILDNAME)" $TBOX_BUILDMAIL -- rm -f $TMPFILE --} -- --# Send out the failure or success message based on exit status. --tbox_exit() { -- TREE="$1" -- TAILPID="$2" -- CODE=${3-$?} -- if [ $CODE -eq 0 ]; then -- SUBJECT=successful -- STATUS=success -- else -- SUBJECT=failed -- STATUS="${TBOX_PHASE}_failed" -- fi -- -- # Send off the status message. -- trap 0 -- tbox_status "$TREE" "$SUBJECT" "$STATUS" -- rm -f $TBOX_LOG -- -- # Wait for tail to display all output, then finish it. -- sleep 1 -- kill $TAILPID -- exit $CODE --} -- --# Run a subprogram, but stop it from sending its own tinderbox --# messages. --tbox_absorb_log() { -- # This probably doesn't do what you think it does... it only prepends -- # TBOX_LOG= to our arguments. -- set TBOX_LOG= "$@" -- -- # Now evaluate the command. -- eval "$@" --} -- --# Start the log for a given tree. --tbox_start_log() { -- TREE="$1" -- -- # Send status messages to stdout, stderr. -- exec 6>&1 7>&2 -- -- [ -n "$TBOX_LOG" ] || return 0 -- -- # Initialize the output log file. -- : > $TBOX_LOG -- -- # Send all our output to the log. -- exec >>$TBOX_LOG 2>&1 -- -- # Monitor it on the old stdout. -- tail -f $TBOX_LOG 1>&6 & -- -- # Allow tail to print our last output before exiting. -- trap "tbox_exit \"$TREE\" $! 1" 1 2 10 15 -- trap "tbox_exit \"$TREE\" $!" 0 --} -- -- --# Begin writing to the log and send out the initial status. --# tbox_start TREE --tbox_start() { -- TREE="$1" -- tbox_start_log "$TREE" -- tbox_status "$TREE" starting building "$TBOX_STARTTIME" --} diff --cc lustre/tests/tchmod.c index 9fcb1ac,9fcb1ac..0000000 deleted file mode 100644,100644 --- a/lustre/tests/tchmod.c +++ /dev/null @@@ -1,17 -1,17 +1,0 @@@ --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- mode_t mode; -- -- if (argc != 3) { -- printf("usage: %s mode name\n", argv[0]); -- return 1; -- } -- -- mode = strtoul(argv[1], NULL, 8); -- return chmod(argv[2], mode); --} diff --cc lustre/tests/test.c index d4c6bf7,d4c6bf7..0000000 deleted file mode 100755,100755 --- a/lustre/tests/test.c +++ /dev/null @@@ -1,101 -1,101 +1,0 @@@ --/* -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define LOOP_DEVICE "/dev/loop0" --#define OBD_DEVICE "/dev/obd" -- --int main (int argc, char * argv[]) --{ -- int fd, rc, err = -1; -- struct stat stat_buf; -- struct statfs stfs; -- -- -- if (argc < 2) { -- printf("syntax: %s command [argument]\n", argv[0]); -- printf("Where command is one of \"setup\", \"create\", \"destroy\", or \"sync\".\n"); -- exit(1); -- } -- if (stat(LOOP_DEVICE, &stat_buf)) { -- printf("Couldn't stat(" LOOP_DEVICE ").\n"); -- exit(1); -- } -- printf("Device: %u\n", (unsigned int) stat_buf.st_rdev); -- -- fd = open (OBD_DEVICE, O_RDONLY); -- if (fd == -1) { -- printf("Couldn't open " OBD_DEVICE ".\n"); -- exit(1); -- } -- -- if (!strcmp(argv[1], "setup")) { -- rc = ioctl(fd, OBD_IOC_SETUP, &stat_buf.st_rdev); -- fprintf(stderr, "rc = %d, errno = %d\n", rc, errno); -- } else if (!strcmp(argv[1], "create")) { -- int iter, i; -- -- if (argc < 3) { -- printf("create requires a nonzero argument.\n"); -- exit(1); -- } -- -- iter = atoi(argv[2]); -- if (iter < 1) { -- printf("create requires a nonzero argument.\n"); -- exit(1); -- } -- printf("creating %d objects...\n", iter); -- -- for (i = 0; i < iter; i++) { -- if ((rc = ioctl(fd, OBD_IOC_CREATE, &err))) { -- fprintf(stderr, "Error; aborting.\n"); -- break; -- } -- if ((rc = ioctl(fd, OBD_IOC_DESTROY, &err))) { -- fprintf(stderr, "Error; aborting.\n"); -- break; -- } -- } -- fprintf(stderr, "rc = %d, errno = %d, err = %d\n", -- rc, errno, err); -- } else if (!strcmp(argv[1], "sync")) { -- rc = ioctl(fd, OBD_IOC_SYNC, &err); -- fprintf(stderr, "rc = %d, errno = %d, err = %d\n", -- rc, errno, err); -- } else if (!strcmp(argv[1], "destroy")) { -- int ino; -- -- if (argc < 3) { -- printf("destroy requires a nonzero inode number.\n"); -- exit(1); -- } -- -- ino = atoi(argv[2]); -- if (ino < 1) { -- printf("destroy requires a nonzero inode number.\n"); -- exit(1); -- } -- -- rc = ioctl(fd, OBD_IOC_DESTROY, &ino); -- fprintf(stderr, "rc = %d, errno = %d\n", rc, errno); -- } else { -- printf("Invalid command, run with no arguments for help.\n"); -- } -- close(fd); -- -- return 0; --} diff --cc lustre/tests/test2.c index fbbe6bb,fbbe6bb..0000000 deleted file mode 100755,100755 --- a/lustre/tests/test2.c +++ /dev/null @@@ -1,60 -1,60 +1,0 @@@ --/* -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This code is issued under the GNU General Public License. -- * See the file COPYING in this distribution -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --/* Beware when setting FSROOT that I've not made any attempts to avoid buffer -- * overruns below--this is a test program, it's a static buffer. */ --#define FSROOT "/mnt" --#define OBD_ITERATIONS 10000 -- --int main (int argc, char * argv[]) --{ -- int fd, rc, err = -1; -- struct stat stat_buf; -- -- if (argc < 2) { -- printf("syntax: %s command\n", argv[0]); -- printf("Where command is one of \"setup\" or \"create\".\n"); -- exit(1); -- } -- -- if (!strcmp(argv[1], "setup")) { -- printf("This is silly.\n"); -- } else if (!strcmp(argv[1], "create")) { -- int i, iter; -- -- if (argc < 3) { -- printf("create requires a nonzero argument.\n"); -- exit(1); -- } -- -- iter = atoi(argv[2]); -- -- if (iter < 1) { -- printf("create requires a nonzero argument.\n"); -- exit(1); -- } -- printf("creating %d files...\n", iter); -- -- for (i = 0; i < iter; i++) { -- fd = creat(FSROOT "/foo123", S_IRWXU); -- close(fd); -- unlink(FSROOT "/foo123"); -- } -- } else { -- printf("Invalid command, run with no arguments for help.\n"); -- } -- -- return 0; --} diff --cc lustre/tests/test_brw.c index 196f32c,196f32c..0000000 deleted file mode 100644,100644 --- a/lustre/tests/test_brw.c +++ /dev/null @@@ -1,209 -1,209 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --// not correctly in the headers yet!! --//#define O_DIRECT 0 --#ifndef O_DIRECT --#define O_DIRECT 040000 /* direct disk access hint */ --#endif -- --#define BLOCKSIZE 4096 --#define CERROR(fmt, arg...) fprintf(stderr, fmt, ## arg) --#ifndef __u64 --#define __u64 long long --#define HTON__u64(v) (v) --#endif -- --#ifndef LPU64 --#define LPU64 "%Lu" --#define LPX64 "%#Lx" --#endif -- --#define READ 1 --#define WRITE 2 -- --#define LPDS sizeof(__u64) --int page_debug_setup(void *addr, int len, __u64 off, __u64 id) --{ -- off = HTON__u64(off); -- id = HTON__u64(id); -- memcpy(addr, (char *)&off, LPDS); -- memcpy(addr + LPDS, (char *)&id, LPDS); -- -- addr += len - LPDS - LPDS; -- memcpy(addr, (char *)&off, LPDS); -- memcpy(addr + LPDS, (char *)&id, LPDS); -- -- return 0; --} -- --int page_debug_check(char *who, void *addr, int size, __u64 off, __u64 id) --{ -- __u64 ne_off; -- int err = 0; -- -- ne_off = HTON__u64(off); -- id = HTON__u64(id); -- if (memcmp(addr, (char *)&ne_off, LPDS)) { -- CERROR("%s: for offset "LPU64" off: "LPX64" != "LPX64"\n", -- who, off, *(__u64 *)addr, ne_off); -- err = -EINVAL; -- } -- if (memcmp(addr + LPDS, (char *)&id, LPDS)) { -- CERROR("%s: for offset "LPU64" id: "LPX64" != "LPX64"\n", -- who, off, *(__u64 *)(addr + LPDS), id); -- err = -EINVAL; -- } -- -- addr += size - LPDS - LPDS; -- if (memcmp(addr, (char *)&ne_off, LPDS)) { -- CERROR("%s: for offset "LPU64" end off: "LPX64" != "LPX64"\n", -- who, off, *(__u64 *)addr, ne_off); -- err = -EINVAL; -- } -- if (memcmp(addr + LPDS, (char *)&id, LPDS)) { -- CERROR("%s: for offset "LPU64" end id: "LPX64" != "LPX64"\n", -- who, off, *(__u64 *)(addr + LPDS), id); -- err = -EINVAL; -- } -- -- return err; --} --#undef LPDS -- --void usage(char *prog) --{ -- fprintf(stderr, -- "usage: %s file count [[d]{r|w|rw} [pages_per_vec [objid]]]\n", -- prog); -- exit(1); --} -- --int main(int argc, char **argv) --{ -- int fd; -- char *buf; -- long long count, last, offset; -- long pg_vec, len; -- long long objid = 3; -- int flags = 0; -- int cmd = 0; -- char *end; -- int rc; -- -- if (argc < 3 || argc > 6) -- usage(argv[0]); -- -- count = strtoull(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, "%s: invalid count '%s'\n", argv[0], argv[2]); -- usage(argv[0]); -- } -- if (argc >= 4) { -- if (strchr(argv[3], 'r')) { -- cmd = READ; -- flags = O_RDONLY; -- } -- if (strchr(argv[3], 'w')) { -- cmd |= WRITE; -- flags = O_RDWR | O_CREAT; -- } -- if (strchr(argv[3], 'd')) { -- flags |= O_DIRECT; -- } -- if (!cmd) -- usage(argv[0]); -- } else { -- cmd = READ | WRITE; -- flags = O_RDWR | O_CREAT | O_DIRECT; -- } -- -- if (argc >= 5) { -- pg_vec = strtoul(argv[4], &end, 0); -- if (*end) { -- fprintf(stderr, "%s: invalid pages_per_vec '%s'\n", -- argv[0], argv[4]); -- usage(argv[0]); -- } -- } -- len = pg_vec * BLOCKSIZE; -- last = (long long)count * len; -- -- if (argc >= 6) { -- objid = strtoull(argv[5], &end, 0); -- if (*end) { -- fprintf(stderr, "%s: invalid objid '%s'\n", -- argv[0], argv[5]); -- usage(argv[0]); -- } -- } -- -- printf("%s: %s on %s(objid "LPX64") for "LPU64"x%ld pages \n", -- argv[0], flags & O_DIRECT ? "directio" : "i/o", -- argv[1], objid, count, pg_vec); -- -- buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0); -- if (!buf) { -- fprintf(stderr, "%s: no buffer memory %s\n", -- argv[0], strerror(errno)); -- return 2; -- } -- -- fd = open(argv[1], flags | O_LARGEFILE); -- if (fd == -1) { -- fprintf(stderr, "%s: cannot open %s: %s\n", argv[0], -- argv[1], strerror(errno)); -- return 3; -- } -- -- for (offset = 0; offset < last && cmd & WRITE; offset += len) { -- int i; -- -- for (i = 0; i < len; i += BLOCKSIZE) -- page_debug_setup(buf + i, BLOCKSIZE, offset + i, objid); -- -- rc = write(fd, buf, len); -- -- for (i = 0; i < len; i += BLOCKSIZE) { -- if (page_debug_check("write", buf + i, BLOCKSIZE, -- offset + i, objid)) -- return 10; -- } -- -- if (rc != len) { -- fprintf(stderr, "%s: write error: %s, rc %d\n", -- argv[0], strerror(errno), rc); -- return 4; -- } -- } -- -- if (lseek(fd, 0, SEEK_SET) != 0) { -- fprintf(stderr, "%s: cannot seek %s\n", -- argv[0], strerror(errno)); -- return 5; -- } -- -- for (offset = 0; offset < last && cmd && READ; offset += len) { -- int i; -- -- rc = read(fd, buf, len); -- if (rc != len) { -- fprintf(stderr, "%s: read error: %s, rc %d\n", -- argv[0], strerror(errno), rc); -- return 6; -- } -- -- for (i = 0; i < len; i += BLOCKSIZE) { -- if (page_debug_check("read", buf + i, BLOCKSIZE, -- offset + i, objid)) -- return 11; -- } -- } -- -- return 0; --} diff --cc lustre/tests/testreq.c index bfcbb5e,a0ce1de..0000000 deleted file mode 100644,100644 --- a/lustre/tests/testreq.c +++ /dev/null @@@ -1,137 -1,140 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#define _GNU_SOURCE --#include --#undef _GNU_SOURCE -- --#include -- --static void usage(char *argv0, int status) --{ -- printf( --"Usage: %s [OPTION...]\n\ --\n\ ----getattr \n\ ----setattr \n\ ----readpage \n\ ----open \n\ ----close \n\ ----create \n", argv0); -- -- exit(status); --} -- --int main(int argc, char **argv) --{ - int fd, rc, c, cmd = 0; - int fd = 0; - int rc = 0; - int c = 0; - long cmd = 0; -- unsigned long arg; -- char *short_opts = "h", *name = argv[0]; -- static struct option long_opts[] = { --#define OPT_GETATTR -2 -- {"getattr", no_argument, NULL, OPT_GETATTR}, --#define OPT_READPAGE -3 -- {"readpage", no_argument, NULL, OPT_READPAGE}, --#define OPT_SETATTR -4 -- {"setattr", no_argument, NULL, OPT_SETATTR}, --#define OPT_CREATE -5 -- {"create", no_argument, NULL, OPT_CREATE}, --#define OPT_OPEN -6 -- {"open", no_argument, NULL, OPT_OPEN}, --#define OPT_CLOSE -7 -- {"close", required_argument, NULL, OPT_CLOSE}, --#define OPT_HELP 'h' -- {"help", no_argument, NULL, OPT_HELP}, -- {0} -- }; -- -- do { -- c = getopt_long(argc, argv, short_opts, long_opts, NULL); -- -- switch (c) { -- case OPT_HELP: -- usage(argv[0], 0); -- break; -- case OPT_GETATTR: -- cmd = IOC_REQUEST_GETATTR; -- name = "getattr"; -- arg = 2; -- break; -- case OPT_SETATTR: -- cmd = IOC_REQUEST_SETATTR; -- name = "setattr"; -- arg = 2; -- break; -- case OPT_READPAGE: -- cmd = IOC_REQUEST_READPAGE; -- name = "readpage"; -- arg = 2; -- break; -- case OPT_CREATE: -- cmd = IOC_REQUEST_CREATE; -- name ="create"; -- arg = 2; -- break; -- case OPT_OPEN: -- cmd = IOC_REQUEST_OPEN; -- name = "open"; -- arg = 2; -- break; -- case OPT_CLOSE: -- cmd = IOC_REQUEST_CLOSE; -- name = "close"; -- arg = strtoul(optarg, NULL, 0); -- break; -- case '?': -- usage(argv[0], 1); -- } -- } while (c != -1); -- -- if (cmd == 0) -- usage(argv[0], 1); -- -- fd = open("/dev/request", O_RDONLY); -- if (fd == -1) { -- fprintf(stderr, "error opening /dev/request: %s\n", -- strerror(errno)); -- exit(1); -- } -- -- fprintf(stderr, "Executing %s test (arg=%lu)...\n", name, arg); -- if (cmd == IOC_REQUEST_OPEN) { -- rc = ioctl(fd, cmd, &arg); -- printf("%lu\n", arg); -- } else -- rc = ioctl(fd, cmd, arg); -- fprintf(stderr, "result code: %d\n", rc); -- -- return 0; --} diff --cc lustre/tests/toexcl.c index da13217,da13217..0000000 deleted file mode 100644,100644 --- a/lustre/tests/toexcl.c +++ /dev/null @@@ -1,24 -1,24 +1,0 @@@ --#include --#include --#include --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- int rc; -- -- if (argc != 2) { -- printf("usage: %s name\n", argv[0]); -- return 1; -- } -- -- rc = open(argv[1], O_CREAT|O_EXCL, 0644); -- if (rc == -1) -- printf("open failed: %s\n", strerror(errno)); -- else -- printf("open success.\n"); -- return 0; --} diff --cc lustre/tests/trivial.sh index abfecf0,abfecf0..0000000 deleted file mode 100755,100755 --- a/lustre/tests/trivial.sh +++ /dev/null @@@ -1,11 -1,11 +1,0 @@@ --#!/bin/sh --# Simple test of mount and unmount --sh llsetup.sh obdecho.cfg net-local.cfg client-echo.cfg || exit 1 --# FIXME: Scan logs for any unusual things (unbalanced allocations, errors) --sh llcleanup.sh obdecho.cfg net-local.cfg client-echo.cfg --OBD_LEAK=`dmesg | awk '/obd memory leaked/ { print $7 }'` --[ "$OBD_LEAK" != "0" ] && echo "OBD memory leak: $OBD_LEAK bytes" && ERR=1 --NAL_LEAK=`dmesg | awk '/NAL unloaded/ { print $7 }' --[ "$NAL_LEAK" != "0)" ] && echo "Portals memory leak: $NAL_LEAK" && ERR=1 --/sbin/lsmod | grep -q portals && "Portals module still loaded" && ERR=1 --exit $ERR diff --cc lustre/tests/truncate.c index c49fb15,c49fb15..0000000 deleted file mode 100644,100644 --- a/lustre/tests/truncate.c +++ /dev/null @@@ -1,24 -1,24 +1,0 @@@ --#include --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- unsigned long long off; -- int err; -- -- if (argc != 3) { -- printf("usage %s file bytes\n", argv[0]); -- return 1; -- } -- -- off = strtoull(argv[2], NULL, 0); -- err = truncate64(argv[1], off); -- if ( err ) -- printf("Error truncating %s to %Ld: %s\n", argv[1], off, -- strerror(errno)); -- -- return err; --} diff --cc lustre/tests/uml.sh index 7d8da8f,7d8da8f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/uml.sh +++ /dev/null @@@ -1,63 -1,63 +1,0 @@@ --#!/bin/bash -- --config=${1-uml.xml} --LMC=${LMC-../utils/lmc} --TMP=${TMP:-/tmp} -- --MDSDEV=$TMP/mds1 --MDSSIZE=50000 -- --OSTDEV1=$TMP/ost1 --OSTDEV2=$TMP/ost2 --OSTSIZE=100000 -- --# NOTE - You can't have different MDS/OST nodes and also have clients on the --# MDS/OST nodes without using --endlevel and --startlevel during lconf. --# You can put both MDS/OST on one node and client can be there too. --# CLIENTS is a space-separated list of client nodes. --# --# The rule is that both the MDS and the OST must be set up before any --# of the clients can be started, so plan accordingly. -- --# Three separate systems --MDSNODE=uml1 --OSTNODE=uml2 --CLIENTS="uml3" -- --# Single system with additional clients --#MDSNODE=uml1 --#OSTNODE=uml1 --#CLIENTS="$MDSNODE client" -- --# Two systems with client on MDS, and additional clients (set up OST first) --#MDSNODE=uml1 --#OSTNODE=uml2 --#CLIENTS="$MDSNODE client" -- --# Two systems with client on OST, and additional clients (set up MDS first) --#MDSNODE=uml1 --#OSTNODE=uml2 --#CLIENTS="$OSTNODE client" -- --rm -f $config -- --# create nodes --for NODE in $MDSNODE $OSTNODE $CLIENTS; do -- eval [ \$$NODE ] && continue -- ${LMC} -m $config --node $NODE --net $NODE tcp || exit 1 -- eval "$NODE=done" --done -- --# configure mds server --${LMC} -m $config --format --node $MDSNODE --mds mds1 $MDSDEV $MDSSIZE ||exit 10 -- --# configure ost --${LMC} -m $config --lov lov1 mds1 65536 0 0 || exit 20 --${LMC} -m $config --node $OSTNODE --lov lov1 --ost $OSTDEV1 $OSTSIZE || exit 21 --${LMC} -m $config --node $OSTNODE --lov lov1 --ost $OSTDEV2 $OSTSIZE || exit 22 -- --# create client config(s) --for NODE in $CLIENTS; do -- ${LMC} -m $config --node $NODE --mtpt /mnt/lustre mds1 lov1 || exit 30 --done -- diff --cc lustre/tests/writeme.c index ab8692f,ab8692f..0000000 deleted file mode 100644,100644 --- a/lustre/tests/writeme.c +++ /dev/null @@@ -1,32 -1,32 +1,0 @@@ --#include --#include --#include --#include --#include -- --int main(int argc, char **argv) --{ -- int fd, rc; -- int i = 0; -- char buf[4096]; -- -- memset(buf, 0, 4096); -- -- if (argc != 2) { -- printf("Usage openme \n"); -- exit(1); -- } -- -- fd = open(argv[1], O_RDWR | O_CREAT, 0600); -- if (fd == -1) { -- printf("Error opening %s\n", argv[1]); -- exit(1); -- } -- -- while (1) { -- sprintf(buf, "write %d\n", i); -- rc = write(fd, buf, sizeof(buf)); -- sleep(1); -- } -- return 0; --} diff --cc lustre/utils/.cvsignore index 1820e08,7695706..0000000 deleted file mode 100644,100644 --- a/lustre/utils/.cvsignore +++ /dev/null @@@ -1,11 -1,13 +1,0 @@@ --.Xrefs --config.log --config.status --configure --Makefile --Makefile.in --.deps --tags --TAGS --obdctl --lctl -lfind -lstripe diff --cc lustre/utils/Makefile.am index dc713f4,6a5483d..0000000 deleted file mode 100644,100644 --- a/lustre/utils/Makefile.am +++ /dev/null @@@ -1,17 -1,18 +1,0 @@@ --# Administration utilities Makefile --DEFS= -- --CFLAGS:=-g -O2 -I$(top_srcdir)/utils -I$(PORTALS)/include -I$(srcdir)/../include -Wall -L$(PORTALSLIB) --KFLAGS:= --CPPFLAGS = $(HAVE_LIBREADLINE) --obdctl_LDADD := $(LIBREADLINE) --lctl_LDADD := $(LIBREADLINE) -lptlctl - sbin_PROGRAMS = lctl lfind obdctl -sbin_PROGRAMS = lctl lfind lstripe obdctl --sbin_SCRIPTS = lconf lmc --obdctl_SOURCES = parser.c obdctl.c obd.c parser.h obdctl.h --lctl_SOURCES = parser.c obd.c lctl.c parser.h --lfind_SOURCES = lfind.c -lstripe_SOURCES = lstripe.c --lfind_CPPFLAGS = -D_XOPEN_SOURCE=500 --EXTRA_DIST = $(sbin_SCRIPTS) -- --include $(top_srcdir)/Rules diff --cc lustre/utils/ha_assist.sh index 0f737f5,0f737f5..0000000 deleted file mode 100755,100755 --- a/lustre/utils/ha_assist.sh +++ /dev/null @@@ -1,5 -1,5 +1,0 @@@ --#!/bin/sh -- --echo primary `date` >> /tmp/halog -- -- diff --cc lustre/utils/ha_assist2.sh index a07d8b5,a07d8b5..0000000 deleted file mode 100755,100755 --- a/lustre/utils/ha_assist2.sh +++ /dev/null @@@ -1,35 -1,35 +1,0 @@@ --#!/bin/bash --set -vx --date --echo "ha assist checking for problems" --sleep 3 --if [ ! -e /tmp/halog ]; then -- echo "no problems, exiting" -- exit --fi -- --echo "removing /tmp/halog" --rm /tmp/halog -- --echo secondary start `date` --echo "- please supply a new mds" -- --# invoke ldap client here -- -- --/usr/src/portals/linux/utils/ptlctl < --# This file is part of Lustre, http://www.lustre.org. --# --# Lustre is free software; you can redistribute it and/or --# modify it under the terms of version 2 of the GNU General Public --# License as published by the Free Software Foundation. --# --# Lustre 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. --# --# You should have received a copy of the GNU General Public License --# along with Lustre; if not, write to the Free Software --# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --# --# lconf - lustre configuration tool --# --# lconf is the main driver script for starting and stopping --# lustre filesystem services. --# --# Based in part on the XML obdctl modifications done by Brian Behlendorf -- --import sys, getopt --import string, os, stat, popen2, socket, time, random --import re, exceptions --import xml.dom.minidom -- --# Global parameters --TCP_ACCEPTOR = '' --MAXTCPBUF = 1048576 --DEFAULT_TCPBUF = 1048576 --# --# Maximum number of devices to search for. --# (the /dev/loop* nodes need to be created beforehand) --MAX_LOOP_DEVICES = 256 -- --first_cleanup_error = 0 --def cleanup_error(rc): -- global first_cleanup_error -- if not first_cleanup_error: -- first_cleanup_error = rc -- -- --def usage(): -- print """usage: lconf config.xml -- --config.xml Lustre configuration in xml format. ----get URL to fetch a config file ----node Load config for ---d | --cleanup Cleans up config. (Shutdown) ---f | --force Forced unmounting and/or obd detach during cleanup ---v | --verbose Print system commands as they are run ---h | --help Print this help ----gdb Prints message after creating gdb module script -- and sleeps for 5 seconds. ---n | --noexec Prints the commands and steps that will be run for a -- config without executing them. This can used to check if a -- config file is doing what it should be doing. (Implies -v) ----nomod Skip load/unload module step. ----nosetup Skip device setup/cleanup step. ----reformat Reformat all devices (without question) ----dump Dump the kernel debug log before portals is unloaded ----minlevel Specify the minimum level of services to configure/cleanup (default 0) ----maxlevel Specify the maximum level of services to configure/cleanup (default 100) -- Levels are aproximatly like: -- 10 - network -- 20 - device, ldlm -- 30 - obd, mdd -- 40 - mds, ost -- 50 - mdc, osc -- 60 - lov, lovconfig - 70 - mountpoint - 70 - mountpoint, echo_client --""" -- TODO = """ ----ldap server LDAP server with lustre config database ----makeldiff Translate xml source to LDIFF --This are perhaps not needed: ----lustre="src dir" Base directory of lustre sources. Used to search -- for modules. ----portals=src Portals source --""" -- sys.exit() -- --# ============================================================ --# Config parameters, encapsulated in a class --class Config: -- def __init__(self): -- # flags -- self._noexec = 0 -- self._verbose = 0 -- self._reformat = 0 -- self._cleanup = 0 -- self._gdb = 0 -- self._nomod = 0 -- self._nosetup = 0 -- self._force = 0 -- # parameters -- self._modules = None -- self._node = None -- self._url = None -- self._gdb_script = '/tmp/ogdb' -- self._debug_path = '/tmp/lustre-log' -- self._dump_file = None -- self._src_dir = None -- self._minlevel = 0 -- self._maxlevel = 100 -- -- def verbose(self, flag = None): -- if flag: self._verbose = flag -- return self._verbose -- -- def noexec(self, flag = None): -- if flag: self._noexec = flag -- return self._noexec -- -- def reformat(self, flag = None): -- if flag: self._reformat = flag -- return self._reformat -- -- def cleanup(self, flag = None): -- if flag: self._cleanup = flag -- return self._cleanup -- -- def gdb(self, flag = None): -- if flag: self._gdb = flag -- return self._gdb -- -- def nomod(self, flag = None): -- if flag: self._nomod = flag -- return self._nomod -- -- def nosetup(self, flag = None): -- if flag: self._nosetup = flag -- return self._nosetup -- -- def force(self, flag = None): -- if flag: self._force = flag -- return self._force -- -- def node(self, val = None): -- if val: self._node = val -- return self._node -- -- def url(self, val = None): -- if val: self._url = val -- return self._url -- -- def gdb_script(self): -- if os.path.isdir('/r'): -- return '/r' + self._gdb_script -- else: -- return self._gdb_script -- -- def debug_path(self): -- if os.path.isdir('/r'): -- return '/r' + self._debug_path -- else: -- return self._debug_path -- -- def src_dir(self, val = None): -- if val: self._src_dir = val -- return self._src_dir -- -- def dump_file(self, val = None): -- if val: self._dump_file = val -- return self._dump_file -- -- def minlevel(self, val = None): -- if val: self._minlevel = int(val) -- return self._minlevel -- -- def maxlevel(self, val = None): -- if val: self._maxlevel = int(val) -- return self._maxlevel -- -- -- --config = Config() -- --# ============================================================ --# debugging and error funcs -- --def fixme(msg = "this feature"): -- raise LconfError, msg + ' not implmemented yet.' -- --def panic(*args): -- msg = string.join(map(str,args)) -- if not config.noexec(): -- raise LconfError(msg) -- else: -- print "! " + msg -- --def log(*args): -- msg = string.join(map(str,args)) -- print msg -- --def logall(msgs): -- for s in msgs: -- print string.strip(s) -- --def debug(*args): -- if config.verbose(): -- msg = string.join(map(str,args)) -- print msg -- --# ============================================================ --# locally defined exceptions --class CommandError (exceptions.Exception): -- def __init__(self, cmd_name, cmd_err, rc=None): -- self.cmd_name = cmd_name -- self.cmd_err = cmd_err -- self.rc = rc -- -- def dump(self): -- import types -- if type(self.cmd_err) == types.StringType: -- if self.rc: -- print "! %s (%d): %s" % (self.cmd_name, self.rc, self.cmd_err) -- else: -- print "! %s: %s" % (self.cmd_name, self.cmd_err) -- elif type(self.cmd_err) == types.ListType: -- if self.rc: -- print "! %s (error %d):" % (self.cmd_name, self.rc) -- else: -- print "! %s:" % (self.cmd_name) -- for s in self.cmd_err: -- print "> %s" %(string.strip(s)) -- else: -- print self.cmd_err -- --class LconfError (exceptions.Exception): -- def __init__(self, args): -- self.args = args -- -- --# ============================================================ --# handle lctl interface --class LCTLInterface: -- """ -- Manage communication with lctl -- """ -- -- def __init__(self, cmd): -- """ -- Initialize close by finding the lctl binary. -- """ -- self.lctl = find_prog(cmd) -- if not self.lctl: -- if config.noexec(): -- debug('! lctl not found') -- self.lctl = 'lctl' -- else: -- raise CommandError('lctl', "unable to find lctl binary.") -- -- def run(self, cmds): -- """ -- run lctl -- the cmds are written to stdin of lctl -- lctl doesn't return errors when run in script mode, so -- stderr is checked -- should modify command line to accept multiple commands, or -- create complex command line options -- """ -- debug("+", self.lctl, cmds) -- if config.noexec(): return (0, []) -- p = popen2.Popen3(self.lctl, 1) -- p.tochild.write(cmds + "\n") -- p.tochild.close() -- out = p.fromchild.readlines() -- err = p.childerr.readlines() -- ret = p.wait() -- if os.WIFEXITED(ret): -- rc = os.WEXITSTATUS(ret) -- else: -- rc = 0 -- if rc or len(err): -- raise CommandError(self.lctl, err, rc) -- return rc, out -- -- def runcmd(self, *args): -- """ -- run lctl using the command line -- """ -- cmd = string.join(map(str,args)) -- debug("+", self.lctl, cmd) -- rc, out = run(self.lctl, cmd) -- if rc: -- raise CommandError(self.lctl, out, rc) -- return rc, out -- -- -- def network(self, net, nid): -- """ initialized network and add "self" """ -- # Idea: "mynid" could be used for all network types to add "self," and then -- # this special case would be gone and the "self" hack would be hidden. -- if net in ('tcp', 'toe'): -- cmds = """ -- network %s -- mynid %s -- add_uuid self %s -- quit""" % (net, nid, nid) -- else: -- cmds = """ -- network %s -- add_uuid self %s -- quit""" % (net, nid) -- -- self.run(cmds) -- -- # create a new connection -- def connect(self, net, nid, port, servuuid, send_mem, recv_mem): -- if net in ('tcp', 'toe'): -- cmds = """ -- network %s -- add_uuid %s %s -- send_mem %d -- recv_mem %d -- connect %s %d -- quit""" % (net, servuuid, nid, send_mem, recv_mem, nid, port, ) -- else: -- cmds = """ -- network %s -- add_uuid %s %s -- connect %s %d -- quit""" % (net, servuuid, nid, nid, port, ) -- -- self.run(cmds) -- -- # add a route to a range -- def add_route(self, net, gw, lo, hi): -- cmds = """ -- network %s -- add_route %s %s %s -- quit """ % (net, gw, lo, hi) -- self.run(cmds) -- -- -- def del_route(self, net, gw, lo, hi): -- cmds = """ -- ignore_errors -- network %s -- del_route %s -- quit """ % (net, lo) -- self.run(cmds) -- -- # add a route to a host -- def add_route_host(self, net, uuid, gw, tgt): -- cmds = """ -- network %s -- add_uuid %s %s -- add_route %s %s -- quit """ % (net, uuid, tgt, gw, tgt) -- self.run(cmds) -- -- # add a route to a range -- def del_route_host(self, net, uuid, gw, tgt): -- cmds = """ -- ignore_errors -- network %s -- del_uuid %s -- del_route %s -- quit """ % (net, uuid, tgt) -- self.run(cmds) -- -- # disconnect one connection -- def disconnect(self, net, nid, port, servuuid): -- cmds = """ -- ignore_errors -- network %s -- disconnect %s -- del_uuid %s -- quit""" % (net, nid, servuuid) -- self.run(cmds) -- -- # disconnect all -- def disconnectAll(self, net): -- cmds = """ -- ignore_errors -- network %s -- del_uuid self -- disconnect -- quit""" % (net) -- self.run(cmds) -- -- # create a new device with lctl -- def newdev(self, attach, setup = ""): -- cmds = """ -- newdev -- attach %s -- setup %s -- quit""" % (attach, setup) -- self.run(cmds) -- -- # cleanup a device -- def cleanup(self, name, uuid): -- cmds = """ -- ignore_errors -- device $%s -- cleanup -- detach %s -- quit""" % (name, ('', 'force')[config.force()]) -- self.run(cmds) -- -- # create an lov -- def lov_setconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist): -- cmds = """ -- device $%s -- probe -- lov_setconfig %s %d %d %d %s %s -- quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist) -- self.run(cmds) -- -- # dump the log file -- def dump(self, dump_file): -- cmds = """ -- debug_kernel %s 1 -- quit""" % (dump_file) -- self.run(cmds) -- -- # get list of devices -- def device_list(self): -- rc, out = self.runcmd('device_list') - return out - - # get lustre version - def lustre_version(self): - rc, out = self.runcmd('version') -- return out -- --# ============================================================ --# Various system-level functions --# (ideally moved to their own module) -- --# Run a command and return the output and status. --# stderr is sent to /dev/null, could use popen3 to --# save it if necessary --def run(*args): -- cmd = string.join(map(str,args)) -- debug ("+", cmd) -- if config.noexec(): return (0, []) -- f = os.popen(cmd + ' 2>&1') -- out = f.readlines() -- ret = f.close() -- if ret: -- ret = ret >> 8 -- else: -- ret = 0 -- return (ret, out) -- --# Run a command in the background. --def run_daemon(*args): -- cmd = string.join(map(str,args)) -- debug ("+", cmd) -- if config.noexec(): return 0 -- f = os.popen(cmd + ' 2>&1') -- ret = f.close() -- if ret: -- ret = ret >> 8 -- else: -- ret = 0 -- return ret -- --# Determine full path to use for an external command --# searches dirname(argv[0]) first, then PATH --def find_prog(cmd): -- syspath = string.split(os.environ['PATH'], ':') -- cmdpath = os.path.dirname(sys.argv[0]) -- syspath.insert(0, cmdpath); -- syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/')) -- for d in syspath: -- prog = os.path.join(d,cmd) -- if os.access(prog, os.X_OK): -- return prog -- return '' -- --# Recursively look for file starting at base dir --def do_find_file(base, mod): -- fullname = os.path.join(base, mod) -- if os.access(fullname, os.R_OK): -- return fullname -- for d in os.listdir(base): -- dir = os.path.join(base,d) -- if os.path.isdir(dir): -- module = do_find_file(dir, mod) -- if module: -- return module -- --def find_module(src_dir, dev_dir, modname): -- mod = '%s.o' % (modname) -- module = src_dir +'/'+ dev_dir +'/'+ mod -- try: -- if os.access(module, os.R_OK): -- return module -- except OSError: -- pass -- return None -- --# is the path a block device? --def is_block(path): -- s = () -- try: -- s = os.stat(path) -- except OSError: -- return 0 -- return stat.S_ISBLK(s[stat.ST_MODE]) -- --# build fs according to type --# fixme: dangerous --def mkfs(fstype, dev): -- if(fstype in ('ext3', 'extN')): -- mkfs = 'mkfs.ext2 -j -b 4096' -- else: -- print 'unsupported fs type: ', fstype -- if not is_block(dev): -- force = '-F' -- else: -- force = '' -- (ret, out) = run (mkfs, force, dev) -- if ret: -- panic("Unable to build fs:", dev) -- # enable hash tree indexing on fsswe -- # FIXME: this check can probably go away on 2.5 -- if fstype == 'extN': -- htree = 'echo "feature FEATURE_C5" | debugfs -w' -- (ret, out) = run (htree, dev) -- if ret: -- panic("Unable to enable htree:", dev) -- --# some systems use /dev/loopN, some /dev/loop/N --def loop_base(): -- import re -- loop = '/dev/loop' -- if not os.access(loop + str(0), os.R_OK): -- loop = loop + '/' -- if not os.access(loop + str(0), os.R_OK): -- panic ("can't access loop devices") -- return loop -- --# find loop device assigned to thefile --def find_loop(file): -- loop = loop_base() -- for n in xrange(0, MAX_LOOP_DEVICES): -- dev = loop + str(n) -- if os.access(dev, os.R_OK): -- (stat, out) = run('losetup', dev) -- if (out and stat == 0): -- m = re.search(r'\((.*)\)', out[0]) -- if m and file == m.group(1): -- return dev -- else: -- break -- return '' -- --# create file if necessary and assign the first free loop device --def init_loop(file, size, fstype): -- dev = find_loop(file) -- if dev: -- print 'WARNING file:', file, 'already mapped to', dev -- return dev -- if config.reformat() or not os.access(file, os.R_OK | os.W_OK): -- run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file)) -- loop = loop_base() -- # find next free loop -- for n in xrange(0, MAX_LOOP_DEVICES): -- dev = loop + str(n) -- if os.access(dev, os.R_OK): -- (stat, out) = run('losetup', dev) -- if (stat): -- run('losetup', dev, file) -- return dev -- else: -- print "out of loop devices" -- return '' -- print "out of loop devices" -- return '' -- --# undo loop assignment --def clean_loop(file): -- dev = find_loop(file) -- if dev: -- ret, out = run('losetup -d', dev) -- if ret: -- log('unable to clean loop device:', dev, 'for file:', file) -- logall(out) -- --# determine if dev is formatted as a filesystem --def need_format(fstype, dev): -- # FIXME don't know how to implement this -- return 0 -- --# initialize a block device if needed --def block_dev(dev, size, fstype, format): -- if config.noexec(): return dev -- if not is_block(dev): -- dev = init_loop(dev, size, fstype) -- if config.reformat() or (need_format(fstype, dev) and format == 'yes'): -- mkfs(fstype, dev) -- --# else: --# panic("device:", dev, --# "not prepared, and autoformat is not set.\n", --# "Rerun with --reformat option to format ALL filesystems") -- -- return dev -- --def if2addr(iface): -- """lookup IP address for an interface""" -- rc, out = run("/sbin/ifconfig", iface) -- if rc or not out: -- return None -- addr = string.split(out[1])[1] -- ip = string.split(addr, ':')[1] -- return ip -- --def get_local_address(net_type, wildcard): -- """Return the local address for the network type.""" -- local = "" -- if net_type in ('tcp', 'toe'): -- if ':' in wildcard: -- iface, star = string.split(wildcard, ':') -- local = if2addr(iface) -- if not local: -- panic ("unable to determine ip for:", wildcard) -- else: -- host = socket.gethostname() -- local = socket.gethostbyname(host) -- elif net_type == 'elan': -- # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position' -- try: -- fp = open('/proc/elan/device0/position', 'r') -- lines = fp.readlines() -- fp.close() -- for l in lines: -- a = string.split(l) -- if a[0] == 'NodeId': -- local = a[1] -- break -- except IOError, e: -- log(e) -- elif net_type == 'gm': -- fixme("automatic local address for GM") -- return local -- -- --def is_prepared(uuid): -- """Return true if a device exists for the uuid""" -- # expect this format: -- # 1 UP ldlm ldlm ldlm_UUID 2 -- try: -- out = lctl.device_list() -- for s in out: -- if uuid == string.split(s)[4]: -- return 1 -- except CommandError, e: -- e.dump() -- return 0 -- -- --# ============================================================ --# Classes to prepare and cleanup the various objects --# --class Module: -- """ Base class for the rest of the modules. The default cleanup method is -- defined here, as well as some utilitiy funcs. -- """ -- def __init__(self, module_name, dom_node): -- self.dom_node = dom_node -- self.module_name = module_name -- self.name = get_attr(dom_node, 'name') -- self.uuid = get_attr(dom_node, 'uuid') -- self.kmodule_list = [] -- self._server = None -- self._connected = 0 -- -- def info(self, *args): -- msg = string.join(map(str,args)) -- print self.module_name + ":", self.name, self.uuid, msg -- -- -- def lookup_server(self, srv_uuid): -- """ Lookup a server's network information """ -- net = get_ost_net(self.dom_node.parentNode, srv_uuid) -- if not net: -- panic ("Unable to find a server for:", srv_uuid) -- self._server = Network(net) -- -- def get_server(self): -- return self._server -- -- def cleanup(self): -- """ default cleanup, used for most modules """ -- self.info() -- srv = self.get_server() -- if srv and local_net(srv): -- try: -- lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) -- except CommandError, e: -- log(self.module_name, "disconnect failed: ", self.name) -- e.dump() -- cleanup_error(e.rc) -- try: -- lctl.cleanup(self.name, self.uuid) -- except CommandError, e: -- log(self.module_name, "cleanup failed: ", self.name) -- e.dump() -- cleanup_error(e.rc) -- -- def add_module(self, dev_dir, modname): -- """Append a module to list of modules to load.""" -- self.kmodule_list.append((dev_dir, modname)) -- -- def mod_loaded(self, modname): -- """Check if a module is already loaded. Look in /proc/modules for it.""" -- fp = open('/proc/modules') -- lines = fp.readlines() -- fp.close() -- # please forgive my tired fingers for this one -- ret = filter(lambda word, mod=modname: word == mod, -- map(lambda line: string.split(line)[0], lines)) -- return ret -- -- def load_module(self): -- """Load all the modules in the list in the order they appear.""" -- for dev_dir, mod in self.kmodule_list: -- # (rc, out) = run ('/sbin/lsmod | grep -s', mod) -- if self.mod_loaded(mod) and not config.noexec(): -- continue -- log ('loading module:', mod) -- if config.src_dir(): -- module = find_module(config.src_dir(),dev_dir, mod) -- if not module: -- panic('module not found:', mod) -- (rc, out) = run('/sbin/insmod', module) -- if rc: -- raise CommandError('insmod', out, rc) -- else: -- (rc, out) = run('/sbin/modprobe', mod) -- if rc: -- raise CommandError('modprobe', out, rc) -- -- def cleanup_module(self): -- """Unload the modules in the list in reverse order.""" -- rev = self.kmodule_list -- rev.reverse() -- for dev_dir, mod in rev: -- if not self.mod_loaded(mod): -- continue -- # debug hack -- if mod == 'portals' and config.dump_file(): -- lctl.dump(config.dump_file()) -- log('unloading module:', mod) -- if config.noexec(): -- continue -- (rc, out) = run('/sbin/rmmod', mod) -- if rc: -- log('! unable to unload module:', mod) -- logall(out) -- -- --class Network(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'NETWORK', dom_node) -- self.net_type = get_attr(dom_node,'type') -- self.nid = get_text(dom_node, 'server', '*') -- self.port = get_text_int(dom_node, 'port', 0) -- self.send_mem = get_text_int(dom_node, 'send_mem', DEFAULT_TCPBUF) -- self.recv_mem = get_text_int(dom_node, 'recv_mem', DEFAULT_TCPBUF) -- if '*' in self.nid: -- self.nid = get_local_address(self.net_type, self.nid) -- if not self.nid: -- panic("unable to set nid for", self.net_type, self.nid) -- debug("nid:", self.nid) -- -- self.add_module('portals/linux/oslib/', 'portals') -- if node_needs_router(): -- self.add_module('portals/linux/router', 'kptlrouter') -- if self.net_type == 'tcp': -- self.add_module('portals/linux/socknal', 'ksocknal') -- if self.net_type == 'toe': -- self.add_module('portals/linux/toenal', 'ktoenal') -- if self.net_type == 'elan': -- self.add_module('portals/linux/rqswnal', 'kqswnal') -- if self.net_type == 'gm': -- self.add_module('portals/linux/gmnal', 'kgmnal') -- self.add_module('lustre/obdclass', 'obdclass') -- self.add_module('lustre/ptlrpc', 'ptlrpc') -- -- def prepare(self): -- self.info(self.net_type, self.nid, self.port) -- if self.net_type in ('tcp', 'toe'): -- nal_id = '' # default is socknal -- if self.net_type == 'toe': -- nal_id = '-N 4' -- ret, out = run(TCP_ACCEPTOR, '-s', self.send_mem, '-r', self.recv_mem, nal_id, self.port) -- if ret: -- raise CommandError(TCP_ACCEPTOR, out, ret) -- ret = self.dom_node.getElementsByTagName('route_tbl') -- for a in ret: -- for r in a.getElementsByTagName('route'): -- net_type = get_attr(r, 'type') -- gw = get_attr(r, 'gw') -- lo = get_attr(r, 'lo') -- hi = get_attr(r,'hi', '') -- lctl.add_route(net_type, gw, lo, hi) -- if net_type in ('tcp', 'toe') and net_type == self.net_type and hi == '': -- srv = nid2server(self.dom_node.parentNode.parentNode, lo) -- if not srv: -- panic("no server for nid", lo) -- else: -- lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) -- -- -- lctl.network(self.net_type, self.nid) -- lctl.newdev(attach = "ptlrpc RPCDEV RPCDEV_UUID") -- -- def cleanup(self): -- self.info(self.net_type, self.nid, self.port) -- ret = self.dom_node.getElementsByTagName('route_tbl') -- for a in ret: -- for r in a.getElementsByTagName('route'): -- lo = get_attr(r, 'lo') -- hi = get_attr(r,'hi', '') -- if self.net_type in ('tcp', 'toe') and hi == '': -- srv = nid2server(self.dom_node.parentNode.parentNode, lo) -- if not srv: -- panic("no server for nid", lo) -- else: -- try: -- lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid) -- except CommandError, e: -- print "disconnect failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- try: -- lctl.del_route(self.net_type, self.nid, lo, hi) -- except CommandError, e: -- print "del_route failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- -- try: -- lctl.cleanup("RPCDEV", "RPCDEV_UUID") -- except CommandError, e: -- print "cleanup failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- try: -- lctl.disconnectAll(self.net_type) -- except CommandError, e: -- print "disconnectAll failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- if self.net_type in ('tcp', 'toe'): -- # yikes, this ugly! need to save pid in /var/something -- run("killall acceptor") -- --class LDLM(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'LDLM', dom_node) -- self.add_module('lustre/ldlm', 'ldlm') -- def prepare(self): -- if is_prepared(self.uuid): -- return -- self.info() -- lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid), -- setup ="") -- --class LOV(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'LOV', dom_node) -- self.mds_uuid = get_first_ref(dom_node, 'mds') -- mds= lookup(dom_node.parentNode, self.mds_uuid) -- self.mds_name = getName(mds) -- devs = dom_node.getElementsByTagName('devices') -- if len(devs) > 0: -- dev_node = devs[0] -- self.stripe_sz = get_attr_int(dev_node, 'stripesize', 65536) -- self.stripe_off = get_attr_int(dev_node, 'stripeoffset', 0) -- self.pattern = get_attr_int(dev_node, 'pattern', 0) -- self.devlist = get_all_refs(dev_node, 'osc') -- self.stripe_cnt = get_attr_int(dev_node, 'stripecount', len(self.devlist)) -- self.add_module('lustre/mdc', 'mdc') -- self.add_module('lustre/lov', 'lov') -- -- def prepare(self): -- if is_prepared(self.uuid): -- return -- for osc_uuid in self.devlist: -- osc = lookup(self.dom_node.parentNode, osc_uuid) -- if osc: -- n = OSC(osc) - n.prepare() - try: - # Ignore connection failures, because the LOV will DTRT with - # an unconnected OSC. - n.prepare(ignore_connect_failure=1) - except CommandError: - print "Error preparing OSC %s (inactive)\n" % osc_uuid -- else: -- panic('osc not found:', osc_uuid) -- mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) -- self.info(self.mds_uuid, self.stripe_cnt, self.stripe_sz, -- self.stripe_off, self.pattern, self.devlist, self.mds_name) -- lctl.newdev(attach="lov %s %s" % (self.name, self.uuid), -- setup ="%s" % (mdc_uuid)) -- -- def cleanup(self): -- if not is_prepared(self.uuid): -- return -- for osc_uuid in self.devlist: -- osc = lookup(self.dom_node.parentNode, osc_uuid) -- if osc: -- n = OSC(osc) -- n.cleanup() -- else: -- panic('osc not found:', osc_uuid) -- Module.cleanup(self) -- cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) -- -- -- def load_module(self): -- for osc_uuid in self.devlist: -- osc = lookup(self.dom_node.parentNode, osc_uuid) -- if osc: -- n = OSC(osc) -- n.load_module() -- break -- else: -- panic('osc not found:', osc_uuid) -- Module.load_module(self) -- -- -- def cleanup_module(self): -- Module.cleanup_module(self) -- for osc_uuid in self.devlist: -- osc = lookup(self.dom_node.parentNode, osc_uuid) -- if osc: -- n = OSC(osc) -- n.cleanup_module() -- break -- else: -- panic('osc not found:', osc_uuid) -- --class LOVConfig(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'LOVConfig', dom_node) -- self.lov_uuid = get_first_ref(dom_node, 'lov') -- l = lookup(dom_node.parentNode, self.lov_uuid) -- self.lov = LOV(l) -- -- def prepare(self): -- lov = self.lov -- self.info(lov.mds_uuid, lov.stripe_cnt, lov.stripe_sz, lov.stripe_off, -- lov.pattern, lov.devlist, lov.mds_name) -- lctl.lov_setconfig(lov.uuid, lov.mds_name, lov.stripe_cnt, -- lov.stripe_sz, lov.stripe_off, lov.pattern, -- string.join(lov.devlist)) -- -- def cleanup(self): -- #nothing to do here -- pass -- -- --class MDS(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'MDS', dom_node) -- self.devname, self.size = get_device(dom_node) -- self.fstype = get_text(dom_node, 'fstype') -- # FIXME: if fstype not set, then determine based on kernel version -- self.format = get_text(dom_node, 'autoformat', "no") -- if self.fstype == 'extN': -- self.add_module('lustre/extN', 'extN') -- self.add_module('lustre/mds', 'mds') -- self.add_module('lustre/mds', 'mds_%s' % (self.fstype)) -- -- def prepare(self): -- if is_prepared(self.uuid): -- return -- self.info(self.devname, self.fstype, self.format) -- blkdev = block_dev(self.devname, self.size, self.fstype, self.format) -- if not is_prepared('MDT_UUID'): -- lctl.newdev(attach="mdt %s %s" % ('MDT', 'MDT_UUID'), -- setup ="") -- lctl.newdev(attach="mds %s %s" % (self.name, self.uuid), -- setup ="%s %s" %(blkdev, self.fstype)) -- def cleanup(self): -- if is_prepared('MDT_UUID'): -- try: -- lctl.cleanup("MDT", "MDT_UUID") -- except CommandError, e: -- print "cleanup failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- if not is_prepared(self.uuid): -- return -- Module.cleanup(self) -- clean_loop(self.devname) -- --# Very unusual case, as there is no MDC element in the XML anymore --# Builds itself from an MDS node --class MDC(Module): -- def __init__(self,dom_node): -- self.mds = MDS(dom_node) -- self.dom_node = dom_node -- self.module_name = 'MDC' -- self.kmodule_list = [] -- self._server = None -- self._connected = 0 -- -- host = socket.gethostname() -- self.name = 'MDC_%s' % (self.mds.name) -- self.uuid = '%s_%05x_%05x' % (self.name, int(random.random() * 1048576), -- int(random.random() * 1048576)) -- -- self.lookup_server(self.mds.uuid) -- self.add_module('lustre/mdc', 'mdc') -- -- def prepare(self): -- if is_prepared(self.uuid): -- return -- self.info(self.mds.uuid) -- srv = self.get_server() -- lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) -- lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid), -- setup ="%s %s" %(self.mds.uuid, srv.uuid)) -- --class OBD(Module): -- def __init__(self, dom_node): -- Module.__init__(self, 'OBD', dom_node) -- self.obdtype = get_attr(dom_node, 'type') -- self.devname, self.size = get_device(dom_node) -- self.fstype = get_text(dom_node, 'fstype') -- # FIXME: if fstype not set, then determine based on kernel version -- self.format = get_text(dom_node, 'autoformat', 'yes') -- if self.fstype == 'extN': -- self.add_module('lustre/extN', 'extN') -- self.add_module('lustre/' + self.obdtype, self.obdtype) -- -- # need to check /proc/mounts and /etc/mtab before -- # formatting anything. -- # FIXME: check if device is already formatted. -- def prepare(self): -- if is_prepared(self.uuid): -- return -- self.info(self.obdtype, self.devname, self.size, self.fstype, self.format) -- if self.obdtype == 'obdecho': -- blkdev = '' -- else: -- blkdev = block_dev(self.devname, self.size, self.fstype, self.format) -- lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid), -- setup ="%s %s" %(blkdev, self.fstype)) -- def cleanup(self): -- if not is_prepared(self.uuid): -- return -- Module.cleanup(self) -- if not self.obdtype == 'obdecho': -- clean_loop(self.devname) -- --class OST(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'OST', dom_node) -- self.obd_uuid = get_first_ref(dom_node, 'obd') -- self.add_module('lustre/ost', 'ost') -- -- def prepare(self): -- if is_prepared(self.uuid): -- return -- self.info(self.obd_uuid) -- lctl.newdev(attach="ost %s %s" % (self.name, self.uuid), -- setup ="%s" % (self.obd_uuid)) -- -- --# virtual interface for OSC and LOV --class VOSC(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'VOSC', dom_node) -- if dom_node.nodeName == 'lov': -- self.osc = LOV(dom_node) -- else: -- self.osc = OSC(dom_node) -- def prepare(self): -- self.osc.prepare() -- def cleanup(self): -- self.osc.cleanup() -- def load_module(self): -- self.osc.load_module() -- def cleanup_module(self): -- self.osc.cleanup_module() -- -- --class OSC(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'OSC', dom_node) -- self.obd_uuid = get_first_ref(dom_node, 'obd') -- self.ost_uuid = get_first_ref(dom_node, 'ost') -- self.lookup_server(self.ost_uuid) -- self.add_module('lustre/osc', 'osc') -- - def prepare(self): - def prepare(self, ignore_connect_failure = 0): -- if is_prepared(self.uuid): -- return -- self.info(self.obd_uuid, self.ost_uuid) -- srv = self.get_server() - if local_net(srv): - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) - else: - r = find_route(srv) - if r: - lctl.add_route_host(r[0], srv.uuid, r[1], r[2]) - try: - if local_net(srv): - lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_mem, srv.recv_mem) -- else: - panic ("no route to", srv.nid) - r = find_route(srv) - if r: - lctl.add_route_host(r[0], srv.uuid, r[1], r[2]) - else: - panic ("no route to", srv.nid) - except CommandError: - if (ignore_connect_failure == 0): - pass -- -- lctl.newdev(attach="osc %s %s" % (self.name, self.uuid), -- setup ="%s %s" %(self.obd_uuid, srv.uuid)) -- -- def cleanup(self): -- if not is_prepared(self.uuid): -- return -- srv = self.get_server() -- if local_net(srv): -- Module.cleanup(self) -- else: -- self.info(self.obd_uuid, self.ost_uuid) -- r = find_route(srv) -- if r: -- try: -- lctl.del_route_host(r[0], srv.uuid, r[1], r[2]) -- except CommandError, e: -- print "del_route failed: ", self.name -- e.dump() -- cleanup_error(e.rc) -- Module.cleanup(self) - - -class ECHO_CLIENT(Module): - def __init__(self,dom_node): - Module.__init__(self, 'ECHO_CLIENT', dom_node) - self.add_module('lustre/obdecho', 'obdecho') - self.lov_uuid = get_first_ref(dom_node, 'osc') - l = lookup(self.dom_node.parentNode, self.lov_uuid) - self.osc = VOSC(l) - - def prepare(self): - if is_prepared(self.uuid): - return - self.osc.prepare() # XXX This is so cheating. -p - self.info(self.lov_uuid) -- - lctl.newdev(attach="echo_client %s %s" % (self.name, self.uuid), - setup = self.lov_uuid) - - def cleanup(self): - if not is_prepared(self.uuid): - return - self.osc.cleanup() - - def load_module(self): - self.osc.load_module() - Module.load_module(self) - def cleanup_module(self): - Module.cleanup_module(self) - self.osc.cleanup_module() - -- --class Mountpoint(Module): -- def __init__(self,dom_node): -- Module.__init__(self, 'MTPT', dom_node) -- self.path = get_text(dom_node, 'path') -- self.mds_uuid = get_first_ref(dom_node, 'mds') -- self.lov_uuid = get_first_ref(dom_node, 'osc') -- self.add_module('lustre/mdc', 'mdc') -- self.add_module('lustre/llite', 'llite') -- l = lookup(self.dom_node.parentNode, self.lov_uuid) -- self.osc = VOSC(l) -- -- def prepare(self): -- self.osc.prepare() -- mdc_uuid = prepare_mdc(self.dom_node.parentNode, self.mds_uuid) -- self.info(self.path, self.mds_uuid, self.lov_uuid) -- cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \ -- (self.lov_uuid, mdc_uuid, self.path) -- run("mkdir", self.path) -- ret, val = run(cmd) -- if ret: -- panic("mount failed:", self.path) -- -- def cleanup(self): -- self.info(self.path, self.mds_uuid,self.lov_uuid) -- if config.force(): -- (rc, out) = run("umount -f", self.path) -- else: -- (rc, out) = run("umount", self.path) -- if rc: -- log("umount failed, cleanup will most likely not work.") -- l = lookup(self.dom_node.parentNode, self.lov_uuid) -- self.osc.cleanup() -- cleanup_mdc(self.dom_node.parentNode, self.mds_uuid) -- -- def load_module(self): -- self.osc.load_module() -- Module.load_module(self) -- def cleanup_module(self): -- Module.cleanup_module(self) -- self.osc.cleanup_module() -- -- --# ============================================================ --# XML processing and query --# TODO: Change query funcs to use XPath, which is muc cleaner -- --def get_device(obd): -- list = obd.getElementsByTagName('device') -- if len(list) > 0: -- dev = list[0] -- dev.normalize(); -- size = get_attr_int(dev, 'size', 0) -- return dev.firstChild.data, size -- return '', 0 -- --# Get the text content from the first matching child --# If there is no content (or it is all whitespace), return --# the default --def get_text(dom_node, tag, default=""): -- list = dom_node.getElementsByTagName(tag) -- if len(list) > 0: -- dom_node = list[0] -- dom_node.normalize() -- if dom_node.firstChild: -- txt = string.strip(dom_node.firstChild.data) -- if txt: -- return txt -- return default -- --def get_text_int(dom_node, tag, default=0): -- list = dom_node.getElementsByTagName(tag) -- n = default -- if len(list) > 0: -- dom_node = list[0] -- dom_node.normalize() -- if dom_node.firstChild: -- txt = string.strip(dom_node.firstChild.data) -- if txt: -- try: -- n = int(txt) -- except ValueError: -- panic("text value is not integer:", txt) -- return n -- --def get_attr(dom_node, attr, default=""): -- v = dom_node.getAttribute(attr) -- if v: -- return v -- return default -- --def get_attr_int(dom_node, attr, default=0): -- n = default -- v = dom_node.getAttribute(attr) -- if v: -- try: -- n = int(v) -- except ValueError: -- panic("attr value is not integer", v) -- return n -- --def get_first_ref(dom_node, tag): -- """ Get the first uuidref of the type TAG. Used one only -- one is expected. Returns the uuid.""" -- uuid = None -- refname = '%s_ref' % tag -- list = dom_node.getElementsByTagName(refname) -- if len(list) > 0: -- uuid = getRef(list[0]) -- return uuid -- --def get_all_refs(dom_node, tag): -- """ Get all the refs of type TAG. Returns list of uuids. """ -- uuids = [] -- refname = '%s_ref' % tag -- list = dom_node.getElementsByTagName(refname) -- if len(list) > 0: -- for i in list: -- uuids.append(getRef(i)) -- return uuids -- --def get_ost_net(dom_node, uuid): -- ost = lookup(dom_node, uuid) -- uuid = get_first_ref(ost, 'network') -- if not uuid: -- return None -- return lookup(dom_node, uuid) -- --def nid2server(dom_node, nid): -- netlist = dom_node.getElementsByTagName('network') -- for net_node in netlist: -- if get_text(net_node, 'server') == nid: -- return Network(net_node) -- return None -- --def lookup(dom_node, uuid): -- for n in dom_node.childNodes: -- if n.nodeType == n.ELEMENT_NODE: -- if getUUID(n) == uuid: -- return n -- else: -- n = lookup(n, uuid) -- if n: return n -- return None -- --# Get name attribute of dom_node --def getName(dom_node): -- return dom_node.getAttribute('name') -- --def getRef(dom_node): -- return dom_node.getAttribute('uuidref') -- --# Get name attribute of dom_node --def getUUID(dom_node): -- return dom_node.getAttribute('uuid') -- --# the tag name is the service type --# fixme: this should do some checks to make sure the dom_node is a service --def getServiceType(dom_node): -- return dom_node.nodeName -- --# --# determine what "level" a particular node is at. --# the order of iniitailization is based on level. --def getServiceLevel(dom_node): -- type = getServiceType(dom_node) -- ret=0; -- if type in ('network',): -- ret = 10 -- elif type in ('device', 'ldlm'): -- ret = 20 -- elif type in ('obd', 'mdd'): -- ret = 30 -- elif type in ('mds','ost'): -- ret = 40 -- elif type in ('mdc','osc'): -- ret = 50 -- elif type in ('lov', 'lovconfig'): -- ret = 60 - elif type in ('mountpoint',): - elif type in ('mountpoint', 'echo_client'): -- ret = 70 -- -- if ret < config.minlevel() or ret > config.maxlevel(): -- ret = 0 -- return ret -- --# --# return list of services in a profile. list is a list of tuples --# [(level, dom_node),] --def getServices(lustreNode, profileNode): -- list = [] -- for n in profileNode.childNodes: -- if n.nodeType == n.ELEMENT_NODE: -- servNode = lookup(lustreNode, getRef(n)) -- if not servNode: -- print n -- panic('service not found: ' + getRef(n)) -- level = getServiceLevel(servNode) -- if level > 0: -- list.append((level, servNode)) -- list.sort() -- return list -- --def getByName(lustreNode, name, tag): -- ndList = lustreNode.getElementsByTagName(tag) -- for nd in ndList: -- if getName(nd) == name: -- return nd -- return None -- -- --############################################################ --# MDC UUID hack - --# FIXME: clean this mess up! --# --saved_mdc = {} --def prepare_mdc(dom_node, mds_uuid): -- global saved_mdc -- mds_node = lookup(dom_node, mds_uuid); -- if not mds_node: -- panic("no mds:", mds_uuid) -- if saved_mdc.has_key(mds_uuid): -- return saved_mdc[mds_uuid] -- mdc = MDC(mds_node) -- mdc.prepare() -- saved_mdc[mds_uuid] = mdc.uuid -- return mdc.uuid -- --def cleanup_mdc(dom_node, mds_uuid): -- global saved_mdc -- mds_node = lookup(dom_node, mds_uuid); -- if not mds_node: -- panic("no mds:", mds_uuid) -- if not saved_mdc.has_key(mds_uuid): -- mdc = MDC(mds_node) -- mdc.cleanup() -- saved_mdc[mds_uuid] = mdc.uuid -- -- --############################################################ --# routing ("rooting") --# --routes = [] --local_node = [] --router_flag = 0 -- --def init_node(dom_node): -- global local_node, router_flag -- netlist = dom_node.getElementsByTagName('network') -- for dom_net in netlist: -- type = get_attr(dom_net, 'type') -- gw = get_text(dom_net, 'server') -- local_node.append((type, gw)) -- --def node_needs_router(): -- return router_flag -- --def get_routes(type, gw, dom_net): -- """ Return the routes as a list of tuples of the form: -- [(type, gw, lo, hi),]""" -- res = [] -- tbl = dom_net.getElementsByTagName('route_tbl') -- for t in tbl: -- routes = t.getElementsByTagName('route') -- for r in routes: -- lo = get_attr(r, 'lo') -- hi = get_attr(r, 'hi', '') -- res.append((type, gw, lo, hi)) -- return res -- -- --def init_route_config(lustre): -- """ Scan the lustre config looking for routers. Build list of -- routes. """ -- global routes, router_flag -- routes = [] -- list = lustre.getElementsByTagName('node') -- for node in list: -- if get_attr(node, 'router'): -- router_flag = 1 -- for (local_type, local_nid) in local_node: -- gw = None -- netlist = node.getElementsByTagName('network') -- for dom_net in netlist: -- if local_type == get_attr(dom_net, 'type'): -- gw = get_text(dom_net, 'server') -- break -- if not gw: -- continue -- for dom_net in netlist: -- if local_type != get_attr(dom_net, 'type'): -- for route in get_routes(local_type, gw, dom_net): -- routes.append(route) -- -- --def local_net(net): -- global local_node -- for iface in local_node: -- if net.net_type == iface[0]: -- return 1 -- return 0 -- --def find_route(net): -- global local_node, routes -- frm_type = local_node[0][0] -- to_type = net.net_type -- to = net.nid -- debug ('looking for route to', to_type,to) -- for r in routes: -- if r[2] == to: -- return r -- return None -- -- -- -- --############################################################ --# lconf level logic --# Start a service. --def startService(dom_node, module_flag): -- type = getServiceType(dom_node) -- debug('Service:', type, getName(dom_node), getUUID(dom_node)) -- # there must be a more dynamic way of doing this... -- n = None -- if type == 'ldlm': -- n = LDLM(dom_node) -- elif type == 'lov': -- n = LOV(dom_node) -- elif type == 'lovconfig': -- n = LOVConfig(dom_node) -- elif type == 'network': -- n = Network(dom_node) -- elif type == 'obd': -- n = OBD(dom_node) -- elif type == 'ost': -- n = OST(dom_node) -- elif type == 'mds': -- n = MDS(dom_node) -- elif type == 'osc': -- n = VOSC(dom_node) -- elif type == 'mdc': -- n = MDC(dom_node) -- elif type == 'mountpoint': -- n = Mountpoint(dom_node) - elif type == 'echo_client': - n = ECHO_CLIENT(dom_node) -- else: -- panic ("unknown service type:", type) -- -- if module_flag: -- if config.nomod(): -- return -- if config.cleanup(): -- n.cleanup_module() -- else: -- n.load_module() -- else: -- if config.nosetup(): -- return -- if config.cleanup(): -- n.cleanup() -- else: -- n.prepare() -- --# --# Prepare the system to run lustre using a particular profile --# in a the configuration. --# * load & the modules --# * setup networking for the current node --# * make sure partitions are in place and prepared --# * initialize devices with lctl --# Levels is important, and needs to be enforced. --def startProfile(lustreNode, profileNode, module_flag): -- if not profileNode: -- panic("profile:", profile, "not found.") -- services = getServices(lustreNode, profileNode) -- if config.cleanup(): -- services.reverse() -- for s in services: -- startService(s[1], module_flag) -- -- --# --# Load profile for --def doHost(lustreNode, hosts): -- global routes -- dom_node = None -- for h in hosts: -- dom_node = getByName(lustreNode, h, 'node') -- if dom_node: -- break -- -- if not dom_node: -- print 'No host entry found.' -- return -- -- if not get_attr(dom_node, 'router'): -- init_node(dom_node) -- init_route_config(lustreNode) -- else: -- global router_flag -- router_flag = 1 -- -- # Two step process: (1) load modules, (2) setup lustre -- # if not cleaning, load modules first. -- module_flag = not config.cleanup() -- reflist = dom_node.getElementsByTagName('profile') -- for profile in reflist: -- startProfile(lustreNode, profile, module_flag) -- -- if not config.cleanup(): -- sys_set_debug_path() -- script = config.gdb_script() -- run(lctl.lctl, ' modules >', script) -- if config.gdb(): -- # dump /tmp/ogdb and sleep/pause here -- log ("The GDB module script is in", script) -- time.sleep(5) -- -- module_flag = not module_flag -- for profile in reflist: -- startProfile(lustreNode, profile, module_flag) -- --############################################################ --# Command line processing --# --def parse_cmdline(argv): -- short_opts = "hdnvf" -- long_opts = ["ldap", "reformat", "lustre=", "verbose", "gdb", -- "portals=", "makeldiff", "cleanup", "noexec", -- "help", "node=", "nomod", "nosetup", -- "dump=", "force", "minlevel=", "maxlevel="] -- opts = [] -- args = [] -- try: -- opts, args = getopt.getopt(argv, short_opts, long_opts) -- except getopt.error: -- print "invalid opt" -- usage() -- -- for o, a in opts: -- if o in ("-h", "--help"): -- usage() -- if o in ("-d","--cleanup"): -- config.cleanup(1) -- if o in ("-v", "--verbose"): -- config.verbose(1) -- if o in ("-n", "--noexec"): -- config.noexec(1) -- config.verbose(1) -- if o == "--portals": -- config.portals = a -- if o == "--lustre": -- config.lustre = a -- if o == "--reformat": -- config.reformat(1) -- if o == "--node": -- config.node(a) -- if o == "--gdb": -- config.gdb(1) -- if o == "--nomod": -- config.nomod(1) -- if o == "--nosetup": -- config.nosetup(1) -- if o == "--dump": -- config.dump_file(a) -- if o in ("-f", "--force"): -- config.force(1) -- if o in ("--minlevel",): -- config.minlevel(a) -- if o in ("--maxlevel",): -- config.maxlevel(a) -- -- return args -- --def fetch(url): -- import urllib -- data = "" -- try: -- s = urllib.urlopen(url) -- data = s.read() -- except: -- usage() -- return data -- --def setupModulePath(cmd): -- base = os.path.dirname(cmd) -- if os.access(base+"/Makefile", os.R_OK): -- config.src_dir(base + "/../../") -- --def sys_set_debug_path(): -- debug("debug path: ", config.debug_path()) -- if config.noexec(): -- return -- try: -- fp = open('/proc/sys/portals/debug_path', 'w') -- fp.write(config.debug_path()) -- fp.close() -- except IOError, e: -- print e -- --#/proc/sys/net/core/rmem_max --#/proc/sys/net/core/wmem_max --def sys_set_netmem_max(path, max): -- debug("setting", path, "to at least", max) -- if config.noexec(): -- return -- fp = open(path) -- str = fp.readline() -- fp.close -- cur = int(str) -- if max > cur: -- fp = open(path, 'w') -- fp.write('%d\n' %(max)) -- fp.close() -- -- --def sys_make_devices(): -- if not os.access('/dev/portals', os.R_OK): -- run('mknod /dev/portals c 10 240') -- if not os.access('/dev/obd', os.R_OK): -- run('mknod /dev/obd c 10 241') -- -- --# Add dir to the global PATH, if not already there. --def add_to_path(new_dir): -- syspath = string.split(os.environ['PATH'], ':') -- if new_dir in syspath: -- return -- os.environ['PATH'] = os.environ['PATH'] + ':' + new_dir -- -- --DEFAULT_PATH = ('/sbin', '/usr/sbin', '/bin', '/usr/bin') --# ensure basic elements are in the system path --def sanitise_path(): -- for dir in DEFAULT_PATH: -- add_to_path(dir) -- --# Initialize or shutdown lustre according to a configuration file --# * prepare the system for lustre --# * configure devices with lctl --# Shutdown does steps in reverse --# --def main(): -- global TCP_ACCEPTOR, lctl, MAXTCPBUF -- host = socket.gethostname() -- -- # the PRNG is normally seeded with time(), which is not so good for starting -- # time-synchronized clusters -- input = open('/dev/urandom', 'r') -- if not input: -- print 'Unable to open /dev/urandom!' -- sys.exit(1) -- seed = input.read(32) -- input.close() -- random.seed(seed) -- -- sanitise_path() -- -- args = parse_cmdline(sys.argv[1:]) -- if len(args) > 0: -- if not os.access(args[0], os.R_OK): -- print 'File not found or readable:', args[0] -- sys.exit(1) -- dom = xml.dom.minidom.parse(args[0]) -- elif config.url(): -- xmldata = fetch(config.url()) -- dom = xml.dom.minidom.parseString(xmldata) -- else: -- usage() -- -- node_list = [] -- if config.node(): -- node_list.append(config.node()) -- else: -- if len(host) > 0: -- node_list.append(host) -- node_list.append('localhost') -- debug("configuring for host: ", node_list) -- -- if len(host) > 0: -- config._debug_path = config._debug_path + '-' + host -- config._gdb_script = config._gdb_script + '-' + host -- -- TCP_ACCEPTOR = find_prog('acceptor') -- if not TCP_ACCEPTOR: -- if config.noexec(): -- TCP_ACCEPTOR = 'acceptor' -- debug('! acceptor not found') -- else: -- panic('acceptor not found') -- -- lctl = LCTLInterface('lctl') -- -- setupModulePath(sys.argv[0]) -- sys_make_devices() -- sys_set_netmem_max('/proc/sys/net/core/rmem_max', MAXTCPBUF) -- sys_set_netmem_max('/proc/sys/net/core/wmem_max', MAXTCPBUF) -- doHost(dom.documentElement, node_list) -- --if __name__ == "__main__": -- try: -- main() -- except LconfError, e: -- print e -- except CommandError, e: -- e.dump() -- sys.exit(e.rc) -- -- if first_cleanup_error: -- sys.exit(first_cleanup_error) -- diff --cc lustre/utils/lctl.c index cd7be22,2e6324c..0000000 deleted file mode 100644,100644 --- a/lustre/utils/lctl.c +++ /dev/null @@@ -1,236 -1,239 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Peter J. Braam -- * Author: Phil Schwan - * Author: Robert Read - * Author: Robert Read -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- -- --#include --#include --#include --#include "obdctl.h" --#include "parser.h" -- --static int jt_quit(int argc, char **argv) { -- Parser_quit(argc, argv); -- return 0; --} -- --static int jt_noop(int argc, char **argv) { -- return 0; --} -- --static int jt_opt_ignore_errors(int argc, char **argv) { -- Parser_ignore_errors(1); -- return 0; --} -- --command_t cmdlist[] = { -- /* Metacommands */ -- {"--device", jt_opt_device, 0, -- "run after connecting to device \n" -- "--device "}, -- {"--threads", jt_opt_threads, 0, -- "run separate instances of on device \n" -- "--threads "}, -- {"--ignore_errors", jt_opt_ignore_errors, 0, -- "ignore errors that occur during script processing\n" -- "--ignore_errors"}, -- {"ignore_errors", jt_opt_ignore_errors, 0, -- "ignore errors that occur during script processing\n" -- "ignore_errors"}, -- -- /* Network configuration commands */ -- {"==== network config ====", jt_noop, 0, "network config"}, -- {"network", jt_ptl_network, 0, "commands that follow apply to net\n" - "usage: network "}, - "usage: network "}, -- {"connect", jt_ptl_connect, 0, "connect to a remote nid\n" -- "usage: connect [[ ] | ]"}, -- {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid\n" -- "usage: disconnect "}, -- {"mynid", jt_ptl_mynid, 0, "inform the socknal of the local nid. " -- "The nid defaults to hostname for tcp networks and is automatically " -- "setup for elan/myrinet networks.\n" -- "usage: mynid [nid]"}, -- {"add_uuid", jt_ptl_add_uuid, 0, "associate a UUID with a nid\n" -- "usage: add_uuid "}, -- {"close_uuid", jt_ptl_close_uuid, 0, "disconnect a UUID\n" -- "usage: close_uuid )"}, -- {"del_uuid", jt_ptl_del_uuid, 0, "delete a UUID association\n" -- "usage: del_uuid "}, -- {"add_route", jt_ptl_add_route, 0, -- "add an entry to the routing table\n" -- "usage: add_route [target]"}, -- {"del_route", jt_ptl_del_route, 0, -- "delete an entry from the routing table\n" -- "usage: del_route "}, -- {"route_list", jt_ptl_print_routes, 0, "print the routing table\n" -- "usage: route_list"}, -- {"recv_mem", jt_ptl_rxmem, 0, "set socket receive buffer size, " -- "if size is omited the current size is reported.\n" -- "usage: recv_mem [size]"}, -- {"send_mem", jt_ptl_txmem, 0, "set socket send buffer size, " -- "if size is omited the current size is reported.\n" -- "usage: send_mem [size]"}, -- {"nagle", jt_ptl_nagle, 0, "enable/disable nagle, omiting the " - "argument will cause the current nagle setting to be reported.\n" - "usage: nagle [on/off]"}, - - "argument will cause the current nagle setting to be reported.\n" - "usage: nagle [on/off]"}, - -- /* Device selection commands */ -- {"=== device selection ===", jt_noop, 0, "device selection"}, -- {"newdev", jt_obd_newdev, 0, "create a new device\n" -- "usage: newdev"}, --#if 0 -- {"uuid2dev", jt_obd_uuid2dev, 0, -- "find device attached with and make it the current device\n" -- "usage: uuid2dev "}, --#endif -- {"name2dev", jt_obd_name2dev, 0, -- "find device attached with and make it the current device\n" -- "usage: name2dev "}, -- {"device", jt_obd_device, 0, "set current device to \n" -- "usage: device "}, -- {"device_list", jt_obd_list, 0, "show all devices\n" -- "usage: device_list"}, - - {"lustre_build_version", jt_get_version, 0, - "print the build version of lustre\n" - "usage: lustre_build_version"}, - -- /* Device configuration commands */ -- {"==== device config =====", jt_noop, 0, "device config"}, -- {"attach", jt_obd_attach, 0, -- "set the type of the current device (with and )\n" -- "usage: attach type [name [uuid]]"}, -- {"setup", jt_obd_setup, 0, -- "type specific device configuration information\n" -- "usage: setup "}, -- {"cleanup", jt_obd_cleanup, 0, "cleanup previously setup device\n" -- "usage: cleanup"}, -- {"detach", jt_obd_detach, 0, -- "remove driver (and name and uuid) from current device\n" -- "usage: detach"}, -- {"lov_setconfig", jt_obd_lov_setconfig, 0, -- "write lov configuration to an mds device\n" -- "usage: lov_setconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"}, -- {"lov_getconfig", jt_obd_lov_getconfig, 0, -- "read lov configuration from an mds device\n" -- "usage: lov_getconfig lov-uuid"}, -- -- /* Device operations */ -- {"=== device operations ==", jt_noop, 0, "device operations"}, -- {"probe", jt_obd_connect, 0, -- "build a connection handle to a device. This command is used to " -- "suspend configuration until lctl has ensured that the mds and osc " -- "services are available. This is to avoid mount failures in a " -- "rebooting cluster.\n" -- "usage: probe [timeout]"}, -- {"close", jt_obd_disconnect, 0, -- "close the connection handle\n" -- "usage: close"}, -- {"getattr", jt_obd_getattr, 0, -- "get attribute for OST object \n" -- "usage: getattr "}, -- {"setattr", jt_obd_setattr, 0, -- "set mode attribute for OST object \n" -- "usage: setattr "}, -- {"create", jt_obd_create, 0, -- "create OST objects (with )\n" -- "usage: create [num [mode [verbose]]]"}, -- {"destroy", jt_obd_destroy, 0, -- "destroy OST object [num [verbose]]\n" -- "usage: destroy objects, starting at objid "}, -- {"test_getattr", jt_obd_test_getattr, 0, -- "do getattrs (on OST object (objid+1 on each thread))\n" -- "usage: test_getattr [verbose [[t]objid]]"}, -- {"test_brw", jt_obd_test_brw, 0, -- "do bulk read/writes ( per I/O, on OST object )\n" -- "usage: test_brw [t] [write [verbose [npages [[t]objid]]]]"}, -- {"test_ldlm", jt_obd_test_ldlm, 0, -- "perform lock manager test\n" -- "usage: test_ldlm"}, -- {"ldlm_regress_start", jt_obd_ldlm_regress_start, 0, -- "start lock manager stress test\n" -- "usage: ldlm_regress_start [numthreads [refheld [numres [numext]]]]"}, -- {"ldlm_regress_stop", jt_obd_ldlm_regress_stop, 0, -- "stop lock manager stress test (no args)\n"}, -- {"dump_ldlm", jt_obd_dump_ldlm, 0, -- "dump all lock manager state (no args)"}, -- {"lov_set_osc_active", jt_obd_lov_set_osc_active, 0, -- "(de)activate an OSC in a LOV\n" -- "usage: lov_set_osc_active <1|0 (active|inactive)>"}, -- {"newconn", jt_obd_newconn, 0, "newconn [newuuid]"}, -- {"failconn", jt_obd_failconn, 0, "failconn "}, -- -- /* Debug commands */ -- {"======== debug =========", jt_noop, 0, "debug"}, -- {"debug_kernel", jt_dbg_debug_kernel, 0, -- "get debug buffer and dump to a file" -- "usage: debug_kernel [file] [raw]"}, -- {"debug_file", jt_dbg_debug_file, 0, -- "read debug buffer from input and dump to output" -- "usage: debug_file [output] [raw]"}, -- {"clear", jt_dbg_clear_debug_buf, 0, "clear kernel debug buffer\n" -- "usage: clear"}, -- {"mark", jt_dbg_mark_debug_buf, 0,"insert marker text in kernel debug buffer\n" -- "usage: mark "}, -- {"filter", jt_dbg_filter, 0, "filter message type\n" -- "usage: filter "}, -- {"show", jt_dbg_show, 0, "show message type\n" -- "usage: show "}, -- {"debug_list", jt_dbg_list, 0, "list subsystem and debug types\n" -- "usage: debug_list "}, -- {"modules", jt_dbg_modules, 0, -- "provide gdb-friendly module information\n" -- "usage: modules "}, -- {"panic", jt_dbg_panic, 0, "force the kernel to panic\n" -- "usage: panic"}, - - -- /* User interface commands */ -- {"======= control ========", jt_noop, 0, "control commands"}, -- {"help", Parser_help, 0, "help"}, -- {"exit", jt_quit, 0, "quit"}, -- {"quit", jt_quit, 0, "quit"}, -- { 0, 0, 0, NULL } --}; -- -- -- - int main(int argc, char **argv) -int main(int argc, char **argv) --{ -- int rc; -- -- setlinebuf(stdout); -- -- ptl_initialize(argc, argv); -- if (obd_initialize(argc, argv) < 0) -- exit(2); -- if (dbg_initialize(argc, argv) < 0) -- exit(3); - - -- if (argc > 1) { -- rc = Parser_execarg(argc - 1, argv + 1, cmdlist); -- } else { -- Parser_init("lctl > ", cmdlist); -- rc = Parser_commands(); -- } -- -- obd_cleanup(argc, argv); -- return rc; --} -- diff --cc lustre/utils/lfind.c index 6628a9c,d0b4c49..0000000 deleted file mode 100644,100644 --- a/lustre/utils/lfind.c +++ /dev/null @@@ -1,318 -1,323 +1,0 @@@ --#define _XOPEN_SOURCE 500 -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#define printk printf --#include --#include -#include -- --#warning Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c --#define MAX_LOV_UUID_COUNT 1000 --#define OBD_NOT_FOUND ((__u32)-1) - #define debugMsg if (debug) printf -- --char * cmd; - int debug; --struct option longOpts[] = { - {"debug", 0, 0, 'd'}, -- {"help", 0, 0, 'h'}, -- {"obd", 1, 0, 'o'}, -- {"query", 0, 0, 'o'}, - {"verbose", 0, 0, 'v'}, -- {0, 0, 0, 0} -- }; --int query; - char * shortOpts = "dho:qv"; -int verbose; -char * shortOpts = "ho:qv"; --char * usageMsg = "[ --obd | --query ] ..."; -- - int max_stripe_count = MAX_LOV_UUID_COUNT; -int max_ost_count = MAX_LOV_UUID_COUNT; --obd_uuid_t * obduuid; --__u32 obdcount; --__u32 obdindex; --char * buf; --int buflen; --struct obd_ioctl_data data; --struct lov_desc desc; --obd_uuid_t * uuids; --int uuidslen; --int cfglen; - struct lov_user_md *lum; - int lumlen; -struct lov_mds_md *lmm; -int lmmlen; -- --void init(); --void usage(FILE *stream); --void errMsg(char *fmt, ...); --void processPath(char *path); --int processFile( -- const char *path, -- const struct stat *sp, -- int flag, -- struct FTW *ftwp -- ); --__u32 getobdindex(const char *path); -- --int --main (int argc, char **argv) { -- int c; -- -- cmd = basename(argv[0]); -- -- while ((c = getopt_long(argc, argv, shortOpts, longOpts, NULL)) != -1) { -- switch (c) { - case 'd': - debug++; - break; -- case 'o': -- if (obduuid) { -- errMsg("obd '%s' already specified: '%s'.", -- obduuid, optarg); -- exit(1); -- } -- -- obduuid = (obd_uuid_t *)optarg; -- break; -- case 'h': -- usage(stdout); -- exit(0); -- case 'q': -- query++; - break; - case 'v': - verbose++; -- break; -- case '?': -- usage(stderr); -- exit(1); -- default: -- errMsg("Internal error. Valid '%s' unrecognized.", -- argv[optind - 1]); -- usage(stderr); -- exit(1); -- } -- } -- -- if (optind >= argc) { -- usage(stderr); -- exit(1); -- } -- -- if (obduuid == NULL) -- query++; -- -- init(); -- -- do { -- processPath(argv[optind]); -- } while (++optind < argc); -- -- exit (0); --} -- --void --init() --{ -- int datalen, desclen; -- -- datalen = size_round(sizeof(data)); -- desclen = size_round(sizeof(desc)); - uuidslen = size_round(max_stripe_count * sizeof(*uuids)); - uuidslen = size_round(max_ost_count * sizeof(*uuids)); -- cfglen = datalen + desclen + uuidslen; - lumlen = sizeof(*lum) + max_stripe_count * sizeof(*lum->lum_luoinfo); - if (cfglen > lumlen) - lmmlen = lov_mds_md_size(max_ost_count); - if (cfglen > lmmlen) -- buflen = cfglen; -- else - buflen = lumlen; - buflen = lmmlen; -- --#warning max ioctl buffer size currently hardcoded to 8192 -- if (buflen > 8192) { -- int nuuids, remaining, nluoinfos; -- -- buflen = 8192; -- nuuids = (buflen - datalen - desclen) / sizeof(*uuids); -- uuidslen = size_round(nuuids * sizeof(*uuids)); -- remaining = nuuids * sizeof(*uuids); -- if (uuidslen > remaining) -- nuuids--; - nluoinfos = (buflen - sizeof(*lum)) / sizeof(*lum->lum_luoinfo); - nluoinfos = (buflen - sizeof(*lmm)) / sizeof(*lmm->lmm_objects); -- if (nuuids > nluoinfos) - max_stripe_count = nluoinfos; - max_ost_count = nluoinfos; -- else - max_stripe_count = nuuids; - max_ost_count = nuuids; -- -- cfglen = datalen + desclen + uuidslen; - lumlen = sizeof(*lum) + max_stripe_count * - sizeof(*lum->lum_luoinfo); - lmmlen = lov_mds_md_size(max_ost_count); -- } -- -- if ((buf = malloc(buflen)) == NULL) { -- errMsg("Unable to allocate %d bytes of memory for ioctl's.", -- buflen); -- exit(1); -- } -- - lum = (struct lov_user_md *)buf; - lmm = (struct lov_mds_md *)buf; -- uuids = (obd_uuid_t *)buf; --} -- --void --usage(FILE *stream) --{ -- fprintf(stream, "usage: %s %s\n", cmd, usageMsg); --} -- --void --errMsg(char *fmt, ...) --{ -- va_list args; -- -- fprintf(stderr, "%s: ", cmd); -- va_start(args, fmt); -- vfprintf(stderr, fmt, args); -- va_end(args); -- fprintf(stderr, "\n"); --} -- --void --processPath(char *path) --{ -- obdindex = OBD_NOT_FOUND; -- nftw((const char *)path, processFile, 128, FTW_PHYS|FTW_MOUNT); --} -- --int - processFile(const char *path, - const struct stat *sp, - int flag, - struct FTW *ftwp - ) { - struct lov_user_oinfo *luoinfo; -processFile(const char *path, const struct stat *sp, int flag, struct FTW *ftwp) -{ -- int fd; -- int count; -- int rc; -- int i; -- -- if (flag != FTW_F) -- return 0; -- -- if ((obdcount == 0) && (getobdindex(path) == OBD_NOT_FOUND)) { -- /* terminate nftw walking this tree */ -- return(1); -- } -- -- if ((fd = open(path, O_RDONLY)) < 0) { -- errMsg("open \"%.20s\" failed.", path); -- perror("open"); -- exit(1); -- } -- -- memset((void *)buf, 0, buflen); - lum->lum_stripe_count = max_stripe_count; - lmm->lmm_magic = LOV_MAGIC; - lmm->lmm_ost_count = max_ost_count; -- - if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lum)) < 0) { - if ((rc = ioctl(fd, LL_IOC_LOV_GETSTRIPE, (void *)lmm)) < 0) { -- errMsg("LL_IOC_LOV_GETSTRIPE ioctl failed."); -- perror("ioctl"); -- exit(1); -- } -- -- close(fd); -- - count = lum->lum_stripe_count; - luoinfo = lum->lum_luoinfo; - if (query || verbose) - printf("\n%s:\n", path); -- - if (query) { - printf("%s\n", path); - for (i = 0; i < count; i++, luoinfo++) { - printf("%4d: obdindex: %-4d objid: %lld\n", - i, luoinfo->luo_idx, luoinfo->luo_id); - } - return(0); - if (verbose) { - printf("lmm_magic: 0x%x\n", lmm->lmm_magic); - printf("lmm_object_id: "LPX64"\n", lmm->lmm_object_id); - printf("lmm_stripe_offset: %d\n", lmm->lmm_stripe_offset); - printf("lmm_stripe_count: %d\n", lmm->lmm_stripe_count); - printf("lmm_ost_count: %d\n", lmm->lmm_ost_count); - printf("lmm_stripe_pattern: %d\n", lmm->lmm_stripe_pattern); -- } -- - debugMsg("LL_IOC_LOV_GETSTRIPE:%s: obdindex: %d count: %d\n", - path, obdindex, count); - count = lmm->lmm_ost_count; -- - for (i = 0; i < count; i++, luoinfo++) { - debugMsg("%-4d: obdidx: %-4d objid: %lld\n", - i, luoinfo->luo_idx, luoinfo->luo_id); - if (luoinfo->luo_idx == obdindex) { - printf("%s\n", path); - return 0; - } - if (query || verbose) { - struct lov_object_id *loi; - __u64 oid; - - loi = lmm->lmm_objects; - - printf("obdidx\tobjid\n"); - - for (i = 0; i < count; i++, loi++) - if ((oid = loi->l_object_id)) - printf("%6d\t%5lld\n", i, (long long)oid); - - if (query) - return(0); -- } - - if (lmm->lmm_objects[obdindex].l_object_id) - printf("%s\n", path); -- -- return(0); --} -- --__u32 --getobdindex(const char *path) --{ -- obd_uuid_t *uuidp; -- int fd; -- int rc; -- int i; -- -- if ((fd = open(path, O_RDONLY)) < 0) { -- errMsg("open \"%.20s\" failed.", path); -- perror("open"); -- exit(1); -- } -- -- data.ioc_inllen1 = sizeof(desc); -- data.ioc_inlbuf1 = (char *)&desc; -- data.ioc_inllen2 = uuidslen; -- data.ioc_inlbuf2 = (char *)uuids; -- data.ioc_inllen3 = 0; -- -- memset(&desc, 0, sizeof(desc)); - desc.ld_tgt_count = max_stripe_count; - desc.ld_tgt_count = max_ost_count; -- -- if (obd_ioctl_pack(&data, &buf, buflen)) { -- errMsg("internal buffering error."); -- exit(1); -- } -- -- rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); -- if (rc) { -- errMsg("OBD_IOC_LOV_GET_CONFIG ioctl failed: %d.", errno); -- perror("ioctl"); -- exit(1); -- } -- -- if (obd_ioctl_unpack(&data, buf, buflen)) { -- errMsg("Invalid reply from ioctl."); -- exit(1); -- } -- -- close(fd); -- -- obdcount = desc.ld_tgt_count; -- -- if (query) { -- printf("OBDS:\n"); -- for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) -- printf("%4d: %s\n", i, (char *)uuidp); -- -- return(0); -- } -- -- for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) { -- rc = strncmp((const char *)obduuid, (const char *)uuidp, -- sizeof(*uuidp)); -- if (rc == 0) { -- obdindex = i; -- break; -- } -- } -- -- if (obdindex == OBD_NOT_FOUND) { -- errMsg("obd UUID '%s' not found.", obduuid); -- return(OBD_NOT_FOUND); -- } -- -- return(0); --} diff --cc lustre/utils/llanalyze index e3e21d6,d2c9273..0000000 deleted file mode 100644,100644 --- a/lustre/utils/llanalyze +++ /dev/null @@@ -1,122 -1,268 +1,0 @@@ --#!/usr/bin/perl -- --use Getopt::Long; -use Term::ANSIColor; - --GetOptions("pid=i" => \$pid, -- "trace!" => \$trace, - "silent!" => \$silent, - "rpctrace!" => \$rpctrace, -- "nodlm!" => \$nodlm, - "noclass!" => \$noclass, -- "nonet!" => \$nonet); -- --print "pid: $pid, nodlm $nodlm nonet $nonet trace $trace\n"; - -- --$subsys->{UNDEFINED} = 0; --$subsys->{MDC} = 1; --$subsys->{MDS} = 2; --$subsys->{OSC} = 3; --$subsys->{OST} = 4; --$subsys->{CLASS} = 5; --$subsys->{OBDFS} = 6; --$subsys->{LLITE} = 7; --$subsys->{RPC} = 8; --$subsys->{EXT2OBD} = 9; --$subsys->{PORTALS} = 10; --$subsys->{SOCKNAL} = 11; --$subsys->{QSWNAL} = 12; --$subsys->{PINGER} = 13; --$subsys->{FILTER} = 14; --$subsys->{TRACE} = 15; # obdtrace, not to be confused with D_TRACE */ --$subsys->{ECHO} = 16; --$subsys->{LDLM} = 17; --$subsys->{LOV} = 18; --$subsys->{GMNAL} = 19; --$subsys->{PTLROUTER} = 20; -- -- --$masks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */ --$masks->{INODE} = 1 << 1; # --$masks->{SUPER} = 1 << 2; # --$masks->{EXT2} = 1 << 3; # /* anything from ext2_debug */ --$masks->{MALLOC} = 1 << 4; # /* print malloc, free information */ --$masks->{CACHE} = 1 << 5; # /* cache-related items */ --$masks->{INFO} = 1 << 6; # /* general information */ --$masks->{IOCTL} = 1 << 7; # /* ioctl related information */ --$masks->{BLOCKS} = 1 << 8; # /* ext2 block allocation */ --$masks->{NET} = 1 << 9; # /* network communications */ --$masks->{WARNING} = 1 << 10; # --$masks->{BUFFS} = 1 << 11; # --$masks->{OTHER} = 1 << 12; # --$masks->{DENTRY} = 1 << 13; # --$masks->{PORTALS} = 1 << 14; # /* ENTRY/EXIT markers */ --$masks->{PAGE} = 1 << 15; # /* bulk page handling */ --$masks->{DLMTRACE} = 1 << 16; # --$masks->{ERROR} = 1 << 17; # /* CERROR} = ...) == CDEBUG} = D_ERROR, ...) */ --$masks->{EMERG} = 1 << 18; # /* CEMERG} = ...) == CDEBUG} = D_EMERG, ...) */ --$masks->{HA} = 1 << 19; # /* recovery and failover */ - - -$masks->{RPCTRACE} = 1 << 19; # /* recovery and failover */ -- --sub extractpid --{ - $_ = shift; - $line = shift; --# print "$_\n"; - /l. [0-9]* (.*)\):/; - return $1; - if ($line =~ m/\(\) ([0-9]*)\+[0-9]*\):/) { - return $1; - } - if ($line =~ m/\(\) ([0-9]*) | [0-9]*\+[0-9]*\):/) { - return $1; - } --} -- --sub entering --{ -- $_ = shift; -- $entering = /Process entered/; --} -- --sub leaving --{ -- $_ = shift; -- $entering = /Process leaving/; --} -- --sub getsubsys --{ -- my ($subsys, $mask) = split ":"; -- return hex($subsys); --} -- --sub getmask --{ -- my ($subsys, $mask) = split ":"; -- return hex($mask); -} - -sub setcolor -{ - my $linemask = shift; - if ($linemask == $masks->{TRACE}) { - print color("yellow on_black"); - } - if ($linemask == $masks->{DLMTRACE}) { - print color("magenta on_black"); - } - if ($linemask == $masks->{DLM}) { - print color("magenta on_black"); - } - if ($linemask == $masks->{DENTRY}) { - print color("red on_black"); - } -} - -sub study_lock -{ - $_ = shift; - my $rc; - - $rc = /completion callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { - $completion_callbacks{$1}->{$2} = $3; -# print color("white"); -# print "---CP CB START: $1 $2 $3\n"; -# print color("reset"); - } - $rc = /callback handler finished.* ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { -# print color("white"); -# print "---CP CB END: $1 $2 $3 deleting $completion_callbacks{$1}->{$2}\n"; -# print color("reset"); - delete $completion_callbacks{$1}->{$2}; - } - - if ($rc) { - $rc = /client blocking AST callback handler START ns: (.*) lock: (.*) lrc: (.*) mode/; - $blocking_callbacks{$1}->{$2} = $3; -# print color("white"); -# print "---BL CB START: $1 $2\n"; -# print color("reset"); - } - $rc = /client blocking callback handler END ns: (.*) lock: (.*) lrc: (.*) mode/; - if ($rc) { -# print color("white"); -# print "---BL CB END: $1 $2 $3 deleting $blocking_callbacks{$1}->{$2}\n"; -# print color("reset"); - delete $blocking_callbacks{$1}->{$2}; - } - - $rc = /ldlm_lock_addref.*ns: (.*) lock: (.*) lrc: (.*) mode/; -# print color("white"); -# print "------>addref ns: $1 lock: $2 lrc: $3\n" if ($rc); -# print color("reset"); - $locks{$1}->{$2} = {$3} if ($rc); - $rc = /ldlm_lock_decref.*ns: (.*) lock: (.*) lrc: (.*) mode/; -# print color("white"); -# print "------>decref ns: $1 lock: $2 lrc: $3\n" if ($rc); -# print color("reset"); - $locks{$1}->{$2} = {$3} if ($rc); -} - -sub hanging_locks -{ - my $found; - my $ns; - - foreach (keys %completion_callbacks) { - $ns = $_; - $found = 0; - foreach (keys %{$completion_callbacks{$ns}}) { - if (!$found) { - print "Unfinished completions in ns $ns: \n"; - $found =1; - } - print " lock: $_ lrc: $completion_callbacks{$ns}->{$_}\n"; - } - } - foreach (keys %blocking_callbacks) { - $ns = $_; - $found = 0; - foreach (keys %{$blocking_callbacks{$ns}}) { - if (!$found) { - print "Unfinished blocking in ns $ns: \n"; - $found =1; - } - printf(" lock: $_ lrc: %s\n", $blocking_callbacks{$ns}->{$_}); - } - } - -} - -sub study_intent -{ - $_ = shift; - my $rc; - - $rc = /D_IT UP dentry (.*) fsdata/; - delete $it{$1} if ($rc); - $rc = /D_IT DOWN dentry (.*) fsdata/; - $it{$1} = "yes" if ($rc); -} - -sub unmatched_intents { - my $found; - foreach (keys %it) { - if (!$found) { - print "Unmatched intents: \n"; - $found =1; - } - print " $_\n"; - } --} -- --while () { -- $linepid = extractpid($_); -- $linemask = getmask($_); -- $linesubsys = getsubsys($_); -- --# printf "---> mask %x subsys %x\n", $linemask, $linesubsys; -- -- if (leaving($_)) { -- chop $prefix->{$linepid}; -- chop $prefix->{$linepid}; - } - - if ($linemask == $masks->{DENTRY}) { - study_intent($_); - } - if ($linemask == $masks->{DLMTRACE}) { - study_lock($_); -- } - -- if ( !$pid || $linepid == $pid) { - next if ($rpctrace && $linemask != $masks->{RPCTRACE}); -- next if ($trace && $linemask != $masks->{TRACE}); - - -- next if ($nodlm && -- ( $linesubsys == $subsys->{LDLM})); - next if ($noclass && - ( $linesubsys == $subsys->{CLASS})); - -- next if ($nonet && -- ( $linesubsys == $subsys->{RPC} || -- $linesubsys == $subsys->{NET} || -- $linesubsys == $subsys->{PORTALS} || -- $linesubsys == $subsys->{SOCKNAL} || -- $linesubsys == $subsys->{QSWNAL} || -- $linesubsys == $subsys->{GMNAL})); -- - # printf "sub/mask: %s - %s\n", getsubsys($_), getmask($_); -- - printf "%s%s", $prefix->{$linepid}, $_; - last if $count++ > 100; -# printf "sub/mask: %s - %s\n", getsubsys($_), getmask($_); - if (!$silent) { - setcolor($linemask); - printf("%s%s", $prefix->{$linepid}, $_); - print color("reset"); - } - # last if $count++ > 100; -- } -- if (entering($_)) { -- $prefix->{$linepid} .= ' '; -- } --} - -- -unmatched_intents(); -hanging_locks(); --# printf "argv %s pid %d\n", $ARGV[0], extractpid($ARGV[0]); diff --cc lustre/utils/lmc index 2477170,3d7c7bf..0000000 deleted file mode 100755,100755 --- a/lustre/utils/lmc +++ /dev/null @@@ -1,817 -1,850 +1,0 @@@ --#!/usr/bin/env python --# Copyright (C) 2002 Cluster File Systems, Inc. --# Author: Robert Read -- --# This file is part of Lustre, http://www.lustre.org. --# --# Lustre is free software; you can redistribute it and/or --# modify it under the terms of version 2 of the GNU General Public --# License as published by the Free Software Foundation. --# --# Lustre 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. --# --# You should have received a copy of the GNU General Public License --# along with Lustre; if not, write to the Free Software --# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --# -- --""" --lmc - lustre configurtion data manager -- -- Basic plan for lmc usage: --# create nodes --./lmc --output config.xml --node server --net server1 tcp --./lmc --merge config.xml --node client --net client1 tcp --./lmc --merge config.xml --node client --route gw lo [hi] --./lmc --merge config.xml --router --node gw1 --net gw1 tcp --./lmc --merge config.xml --node gw1 --net 1 elan -- --./lmc --merge config.xml --route elan 1 1 100 --./lmc --merge config.xml --route tcp gw1 ba1 -- -- -- --# configure server --./lmc --merge config.xml --node server --mds mds1 /tmp/mds1 50000 -- --# create lov --./lmc --merge config.xml --lov lov1 mds1 65536 0 0 --./lmc --merge config.xml --node server --lov lov1 --ost /tmp/ost1 100000 --./lmc --merge config.xml --node server --lov lov1 --ost /tmp/ost2 100000 -- --# create client config --./lmc --merge config.xml --node client --mtpt /mnt/lustre mds1 lov1 -- --""" -- --import sys, os, getopt, string --import xml.dom.minidom --from xml.dom.ext import PrettyPrint -- -- --DEFAULT_PORT = 988 # XXX What is the right default acceptor port to use? -- --def usage(): -- print """usage: lmc [--node --ost | --mtpt | --lov] args --Commands: ----node node_name -- Node_name by itself it will create a new node. If the --router -- option is used when creating a new node, then that node will also -- be configured as a router. When used with other commands it -- specifies the node to modify. -- ----net hostname nettype [port, recv_buf, send_buf] -- Nettype is either tcp, toe, elan, or gm. -- Requires --node -- ----route net gw lo [hi] -- This command is used to create routes. NET is the -- network type this route will be used on. The GW is an address of -- one of the local interfaces. LO and HI represent a range of -- addresses that can be reached through the gateway. If HI is not -- set, then a route to the specific host in LO is created. -- ----mds device [size] -- Create a MDS using the device -- Requires --node -- ----lov lov_name [mds_name stripe_sz sub_stripe_count pattern] -- Creates a logical volume -- When used with other commands, it specifics the lov to modify -- ----ost device [size] -- Creates an OBD/OST/OSC configuration triplet for a new device. -- When used on "host", the device will be initialized and the OST -- will be enabled. On client nodes, the OSC will be avaiable. -- Requires --node -- Optional --obduuid Specifies the UUID used for the obd. -- If --lov lov_name is used, this device is added to lov. -- ----mtpt /mnt/point mds_name lov_name|osc_name -- Creates a client mount point. -- Requires --node -- --Options: ----merge="xml file" Add the new objects to an existing file ----format Format the partitions if unformated -- NB: The autoformat option has been disabled until a safe -- method is implemented to determine if a block device has a -- filesystem. ----reformat Reformat partitions (this should be an lconf arg, -- I think) ----obdtype="obdtype" Specifiy obdtype: valid ones are obdecho and obdfilter. -- This is only useful for the --ost command. -- The device parameters are ignored for the obdecho type. --""" -- sys.exit(1) -- --def error(*args): -- msg = string.join(map(str,args)) -- print "Error: ", msg -- sys.exit(1) -- --def warning(*args): -- msg = string.join(map(str,args)) -- print "Warning: ", msg -- --# --# manage names and uuids --# need to initialize this by walking tree to ensure --# no duplicate names or uuids are created. --# this are just place holders for now. --# consider changing this to be like OBD-dev-host --def new_name(base): -- ctr = 2 -- ret = base -- while names.has_key(ret): -- ret = "%s_%d" % (base, ctr) -- ctr = 1 + ctr -- names[ret] = 1 -- return ret -- --def new_uuid(name): -- return "%s_UUID" % (name) -- --ldlm_name = 'ldlm' --ldlm_uuid = 'ldlm_UUID' --def new_lustre(dom): -- """Create a new empty lustre document""" -- # adding ldlm here is a bit of a hack, but one is enough. -- str = """ -- -- """ % (ldlm_name, ldlm_uuid) -- return dom.parseString(str) -- --names = {} --uuids = {} -- --def init_names(doc): -- """initialize auto-name generation tables""" -- global names, uuids -- # get all elements that contain a name attribute -- for n in doc.childNodes: -- if n.nodeType == n.ELEMENT_NODE: -- if getName(n): -- names[getName(n)] = 1 -- uuids[getUUID(n)] = 1 -- init_names(n) -- --def get_format_flag(options): -- if options.has_key('format'): -- if options['format']: -- return 'yes' -- return 'no' -- --############################################################ --# Build config objects using DOM --# --class GenConfig: -- doc = None -- dom = None -- def __init__(self, doc): -- self.doc = doc -- -- def ref(self, type, uuid): -- """ generate <[type]_ref uuidref="[uuid]"/> """ -- tag = "%s_ref" % (type) -- ref = self.doc.createElement(tag) -- ref.setAttribute("uuidref", uuid) -- return ref -- -- def newService(self, tag, name, uuid): -- """ create a new service elmement, which requires name and uuid attributes """ -- new = self.doc.createElement(tag) -- new.setAttribute("name", name); -- new.setAttribute("uuid", uuid); -- return new -- -- def addText(self, node, str): -- txt = self.doc.createTextNode(str) -- node.appendChild(txt) -- -- def addElement(self, node, tag, str=None): -- """ create a new element and add it as a child to node. If str is passed, -- a text node is created for the new element""" -- new = self.doc.createElement(tag) -- if str: -- self.addText(new, str) -- node.appendChild(new) -- return new -- -- def network(self, name, uuid, hostname, net, port=0, tcpbuf=0): -- """create node""" -- network = self.newService("network", name, uuid) -- network.setAttribute("type", net); -- self.addElement(network, "server", hostname) -- if port: -- self.addElement(network, "port", "%d" %(port)) -- if tcpbuf: -- self.addElement(network, "send_mem", "%d" %(tcpbuf)) -- self.addElement(network, "recv_mem", "%d" %(tcpbuf)) -- -- return network -- -- def route(self, net_type, gw, lo, hi): -- """ create one entry for the route table """ -- ref = self.doc.createElement('route') -- ref.setAttribute("type", net_type) -- ref.setAttribute("gw", gw) -- ref.setAttribute("lo", lo) -- if hi: -- ref.setAttribute("hi", hi) -- return ref -- -- def node(self, name, uuid): -- """ create a host """ -- node = self.newService("node", name, uuid) -- self.addElement(node, 'profile') -- return node -- -- def ldlm(self, name, uuid): -- """ create a ldlm """ -- ldlm = self.newService("ldlm", name, uuid) -- return ldlm -- -- def obd(self, name, uuid, fs, obdtype, devname, format, dev_size=0): -- obd = self.newService("obd", name, uuid) -- obd.setAttribute('type', obdtype) -- if fs: -- self.addElement(obd, "fstype", fs) -- if devname: -- dev = self.addElement(obd, "device", devname) -- if (dev_size): -- dev.setAttribute("size", "%s" % (dev_size)) -- self.addElement(obd, "autoformat", format) -- return obd -- -- def osc(self, name, uuid, obd_uuid, net_uuid): -- osc = self.newService("osc", name, uuid) -- osc.appendChild(self.ref("ost", net_uuid)) -- osc.appendChild(self.ref("obd", obd_uuid)) -- return osc -- -- def ost(self, name, uuid, obd_uuid, net_uuid): -- ost = self.newService("ost", name, uuid) -- ost.appendChild(self.ref("network", net_uuid)) -- ost.appendChild(self.ref("obd", obd_uuid)) -- return ost -- -- def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_count, pattern): -- lov = self.newService("lov", name, uuid) -- lov.appendChild(self.ref("mds", mds_uuid)) -- devs = self.addElement(lov, "devices" ) -- devs.setAttribute("stripesize", stripe_sz) -- devs.setAttribute("stripecount", stripe_count) -- devs.setAttribute("pattern", pattern) -- return lov -- -- def lovconfig(self, name, uuid, lov_uuid): -- lovconfig = self.newService("lovconfig", name, uuid) -- lovconfig.appendChild(self.ref("lov", lov_uuid)) -- return lovconfig -- -- def mds(self, name, uuid, fs, devname, format, net_uuid, node_uuid, -- failover_uuid = "", dev_size=0 ): -- mds = self.newService("mds", name, uuid) -- self.addElement(mds, "fstype", fs) -- dev = self.addElement(mds, "device", devname) -- if dev_size: -- dev.setAttribute("size", "%s" % (dev_size)) -- self.addElement(mds, "autoformat", format) -- mds.appendChild(self.ref("network", net_uuid)) -- mds.appendChild(self.ref("node", node_uuid)) -- if failover_uuid: -- mds.appendChild(self.ref("failover", failover_uuid)) -- return mds -- -- def mountpoint(self, name, uuid, mds_uuid, osc_uuid, path): -- mtpt = self.newService("mountpoint", name, uuid) -- mtpt.appendChild(self.ref("mds", mds_uuid)) -- mtpt.appendChild(self.ref("osc", osc_uuid)) -- self.addElement(mtpt, "path", path) -- return mtpt - - def echo_client(self, name, uuid, osc_uuid): - ec = self.newService("echo_client", name, uuid) - ec.appendChild(self.ref("osc", osc_uuid)) - return ec -- --############################################################ --# Utilities to query a DOM tree --# Using this functions we can treat use config information --# directly as a database. --def getName(n): -- return n.getAttribute('name') -- --def getUUID(node): -- return node.getAttribute('uuid') -- -- --def findByName(lustre, name, tag = ""): -- for n in lustre.childNodes: -- if n.nodeType == n.ELEMENT_NODE: -- if tag and n.nodeName != tag: -- continue -- if getName(n) == name: -- return n -- else: -- n = findByName(n, name) -- if n: return n -- return None -- -- --def lookup(node, uuid): -- for n in node.childNodes: -- if n.nodeType == n.ELEMENT_NODE: -- if getUUID(n) == uuid: -- return n -- else: -- n = lookup(n, uuid) -- if n: return n -- return None -- -- --def mds2node(lustre, mds_name): -- """ Find the node a MDS is configured on """ -- mds = findByName(lustre, mds_name, 'mds') -- ref = mds.getElementsByTagName('node_ref') -- if not ref: -- error("mds2node:", "no node_ref found for", '"'+mds_name+'"') -- node_uuid = ref[0].getAttribute('uuidref') -- node = lookup(lustre, node_uuid) -- if not node: -- error('mds2node:', "no node found for :", '"'+mds_name+'"') -- return node -- -- --def name2uuid(lustre, name, tag="", fatal=1): -- ret = findByName(lustre, name, tag) -- if not ret: -- if fatal: -- error('name2uuid:', '"'+name+'"', tag, 'element not found.') -- else: -- return "" -- return getUUID(ret) -- -- --# XXX: assumes only one network element per node. will fix this --# as soon as support for routers is added --def get_net_uuid(lustre, node_name): -- """ get a network uuid for a node_name """ -- node = findByName(lustre, node_name, "node") -- if not node: -- error ('get_net_uuid:', '"'+node_name+'"', "node element not found.") -- net = node.getElementsByTagName('network') -- if net: -- return getUUID(net[0]) -- return None -- -- --def lov_add_osc(gen, lov, osc_uuid): -- devs = lov.getElementsByTagName('devices') -- if len(devs) == 1: -- devs[0].appendChild(gen.ref("osc", osc_uuid)) -- else: -- error("No devices element found for LOV:", lov) -- -- --def node_add_profile(gen, node, ref, uuid): -- ret = node.getElementsByTagName('profile') -- if not ret: -- error('node has no profile:', node) -- ret[0].appendChild(gen.ref(ref, uuid)) -- --def get_attr(dom_node, attr, default=""): -- v = dom_node.getAttribute(attr) -- if v: -- return v -- return default -- --############################################################ --# Top level commands --# --def do_add_node(gen, lustre, options, node_name): -- uuid = new_uuid(node_name) -- node = gen.node(node_name, uuid) -- node_add_profile(gen, node, 'ldlm', ldlm_uuid) -- if options.has_key('router'): -- node.setAttribute('router', '1') -- lustre.appendChild(node) -- return node -- -- --def add_node(gen, lustre, options, args): -- """ create a node with a network config """ -- if len(args) > 1: -- usage() -- -- node_name = options['node'] -- -- ret = findByName(lustre, node_name, "node") -- if ret: -- print "Node:", node_name, "exists." -- return -- do_add_node(gen, lustre, options, node_name) -- -- --def add_net(gen, lustre, options, args): -- """ create a node with a network config """ -- if len(args) < 2: -- usage() -- -- node_name = options['node'] -- nid = args[0] -- net_type = args[1] -- port = 0 -- tcpbuf = 0 -- -- if net_type in ('tcp', 'toe'): -- if len(args) > 2: -- port = int(args[2]) -- else: -- port = DEFAULT_PORT -- if options.has_key('tcpbuf'): -- tcpbuf = int(options['tcpbuf']) -- elif net_type in ('elan', 'gm'): -- port = 0 -- else: -- print "Unknown net_type: ", net_type -- sys.exit(2) -- -- ret = findByName(lustre, node_name, "node") -- if not ret: -- node = do_add_node(gen, lustre, options, node_name) -- else: -- node = ret -- net_name = new_name('NET_'+ node_name +'_'+ net_type) -- net_uuid = new_uuid(net_name) -- node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port, tcpbuf)) -- node_add_profile(gen, node, "network", net_uuid) -- -- --def add_route(gen, lustre, options, args): -- """ create a node with a network config """ -- if len(args) < 3: -- usage() -- -- node_name = options['node'] -- net_type= args[0] -- gw = args[1] -- lo = args[2] -- hi = '' -- -- if len(args) > 3: -- hi = args[3] -- -- node = findByName(lustre, node_name, "node") -- if not node: -- error (node_name, " not found.") -- -- netlist = node.getElementsByTagName('network') -- net = netlist[0] -- rlist = net.getElementsByTagName('route_tbl') -- if len(rlist) > 0: -- rtbl = rlist[0] -- else: -- rtbl = gen.addElement(net, 'route_tbl') -- rtbl.appendChild(gen.route(net_type, gw, lo, hi)) -- -- --def add_mds(gen, lustre, options, args): -- fstype = 'extN' -- -- if len(args) < 1: -- usage() -- -- if options.has_key('node'): -- node_name = options['node'] -- else: -- error("--mds requires a --node argument") -- -- if options.has_key('fstype'): -- fstype = options['fstype'] -- -- mds_name = new_name(options['mds']) -- if mds_name != options['mds']: -- warning("name:", options['mds'], "already used. using:", mds_name) -- devname = args[0] -- if len(args) > 1: -- size = args[1] -- else: -- size = 0 -- -- mds_uuid = new_uuid(mds_name) -- -- node_uuid = name2uuid(lustre, node_name, 'node') -- -- node = findByName(lustre, node_name, "node") -- node_add_profile(gen, node, "mds", mds_uuid) -- net_uuid = get_net_uuid(lustre, node_name) -- if not net_uuid: -- error("NODE: ", node_name, "not found") - -- -- mds = gen.mds(mds_name, mds_uuid, fstype, devname, get_format_flag(options), -- net_uuid, node_uuid, dev_size=size) -- lustre.appendChild(mds) -- -- --def add_ost(gen, lustre, options, args): -- lovname = '' -- obdtype = 'obdfilter' -- devname = '' -- size = 0 -- fstype = 'extN' -- -- if options.has_key('node'): -- node_name = options['node'] -- else: -- error("--ost requires a --node argument") -- -- if options.has_key('lov'): -- lovname = options['lov'] -- -- if options.has_key('obdtype'): -- obdtype = options['obdtype'] -- if options.has_key('fstype'): -- fstype = options['fstype'] -- if obdtype == 'obdecho': -- fstype = '' -- else: -- if len(args) < 1: -- usage() -- devname = args[0] -- if len(args) > 1: -- size = args[1] -- -- obdname = new_name('OBD_'+ node_name) -- oscname = new_name('OSC_'+ node_name) -- ostname = new_name('OST_'+ node_name) -- if options.has_key('obduuid'): -- obd_uuid = options['obduuid'] -- obd = lookup(lustre, obd_uuid) -- if obd: -- error("Duplicate OBD UUID:", obd_uuid) -- else: -- obd_uuid = new_uuid(obdname) -- ost_uuid = new_uuid(ostname) -- osc_uuid = new_uuid(oscname) -- -- net_uuid = get_net_uuid(lustre, node_name) -- if not net_uuid: -- error("NODE: ", node_name, "not found") -- -- obd = gen.obd(obdname, obd_uuid, fstype, obdtype, devname, get_format_flag(options), size) -- ost = gen.ost(ostname, ost_uuid, obd_uuid, net_uuid) -- osc = gen.osc(oscname, osc_uuid, obd_uuid, ost_uuid) -- -- if lovname: -- lov = findByName(lustre, lovname, "lov") -- if not lov: -- error('add_ost:', '"'+lovname+'"', "lov element not found.") -- lov_add_osc(gen, lov, osc_uuid) -- -- node = findByName(lustre, node_name, "node") -- node_add_profile(gen, node, 'obd', obd_uuid) -- node_add_profile(gen, node, 'ost', ost_uuid) -- -- lustre.appendChild(obd) -- lustre.appendChild(osc) -- lustre.appendChild(ost) -- -- --# this is generally only used by llecho.sh --def add_osc(gen, lustre, options, args): -- """ add the osc to the profile for this node. """ -- if len(args) < 1: -- usage() -- osc_name = args[0] -- if options.has_key('node'): -- node_name = options['node'] -- else: -- error("--osc requires a --node argument") -- osc_uuid = name2uuid(lustre, osc_name) # either 'osc' or 'lov' -- node = findByName(lustre, node_name, "node") -- node_add_profile(gen, node, 'osc', osc_uuid) - - -#ditto -def add_echo_client(gen, lustre, options, args): - """ add an echo client to the profile for this node. """ - if len(args) < 1: - usage() - lov_name = args[0] - if options.has_key('node'): - node_name = options['node'] - else: - error("--echo_client requires a --node argument") - node = findByName(lustre, node_name, "node") - - echoname = new_name('ECHO_'+ node_name) - echo_uuid = new_uuid(echoname) - node_add_profile(gen, node, 'echo_client', echo_uuid) - - lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) - if not lov_uuid: - lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) - - echo = gen.echo_client(echoname, echo_uuid, lov_uuid) - lustre.appendChild(echo) -- -- --def add_lov(gen, lustre, options, args): -- """ create a lov """ -- if len(args) < 4: -- usage() -- -- name = new_name(options['lov']) -- if name != options['lov']: -- warning("name:", options['lov'], "already used. using:", name) -- -- mds_name = args[0] -- stripe_sz = args[1] -- stripe_count = args[2] -- pattern = args[3] -- uuid = new_uuid(name) -- -- ret = findByName(lustre, name, "lov") -- if ret: -- error("LOV: ", name, " already exists.") -- -- mds_uuid = name2uuid(lustre, mds_name, 'mds') -- lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_count, pattern) -- lustre.appendChild(lov) -- -- # add an lovconfig entry to the mds profile -- lovconfig_name = new_name('LVCFG_' + name) -- lovconfig_uuid = new_uuid(lovconfig_name) -- node = mds2node(lustre, mds_name) -- node_add_profile(gen, node, "lovconfig", lovconfig_uuid) -- lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid) -- lustre.appendChild(lovconfig) -- -- -- --def add_mtpt(gen, lustre, options, args): -- """ create mtpt on a node """ -- if len(args) < 3: -- usage() -- -- if options.has_key('node'): -- node_name = options['node'] -- else: -- error("--mtpt requires a --node argument") -- -- path = args[0] -- mds_name = args[1] -- lov_name = args[2] -- -- name = new_name('MNT_'+ node_name) -- -- ret = findByName(lustre, name, "mountpoint") -- if ret: -- error("MOUNTPOINT: ", name, " already exists.") -- -- mds_uuid = name2uuid(lustre, mds_name, tag='mds') -- lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0) -- if not lov_uuid: -- lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1) -- -- uuid = new_uuid(name) -- mtpt = gen.mountpoint(name, uuid, mds_uuid, lov_uuid, path) -- node = findByName(lustre, node_name, "node") -- if not node: -- error('node:', node_name, "not found.") -- node_add_profile(gen, node, "mountpoint", uuid) -- lustre.appendChild(mtpt) -- -- --############################################################ --# Command line processing --# --def parse_cmdline(argv): -- short_opts = "ho:i:m:" - long_opts = ["ost", "osc", "mtpt", "lov=", "node=", "mds=", "net", "tcpbuf=", - long_opts = ["ost", "osc", "mtpt", "lov=", "node=", "mds=", "net", - "echo_client", "tcpbuf=", -- "route", "router", "merge=", "format", "reformat", "output=", -- "obdtype=", "fstype=", "obduuid=", "in=", "help", "batch="] -- opts = [] -- args = [] -- options = {} -- try: -- opts, args = getopt.getopt(argv, short_opts, long_opts) -- except getopt.error: -- print "invalid opt" -- usage() -- -- for o, a in opts: -- # Commands to create new devices -- if o == "--ost": -- options['ost'] = 1 -- if o == "--osc": -- options['osc'] = 1 - if o == "--echo_client": - options['echo_client'] = 1 -- if o == "--mds": -- options['mds'] = a -- if o == "--net": -- options['net'] = 1 -- if o == "--mtpt": -- options['mtpt'] = 1 -- if o == "--node": -- options['node'] = a -- if o == "--route": -- options['route'] = 1 -- if o == "--router": -- options['router'] = 1 -- if o == "--lov": -- options['lov'] = a -- -- # Options for commands -- if o == "--obdtype": -- options['obdtype'] = a -- if o == "--fstype": -- options['fstype'] = a -- if o == "--obduuid": -- options['obduuid'] = a -- if o == "--tcpbuf": -- options['tcpbuf'] = a -- -- # lmc options -- if o in ("-h", "--help"): -- usage() -- if o in ("-o", "--output"): -- options['output'] = a -- if o in ("-m", "--merge"): -- options['merge'] = a -- if o == "--format": -- options['format'] = 1 -- if o == "--reformat": -- options['reformat'] = 1 -- if o == "--batch": -- options['batch'] = a -- if o in ("--in" , "-i"): -- options['in'] = a -- -- return options, args -- -- --# simple class for profiling --import time --class chrono: -- def __init__(self): -- self._start = 0 -- def start(self): -- self._stop = 0 -- self._start = time.time() -- def stop(self, msg=''): -- self._stop = time.time() -- if msg: -- self.display(msg) -- def dur(self): -- return self._stop - self._start -- def display(self, msg): -- d = self.dur() -- str = '%s: %g secs' % (msg, d) -- print str -- --############################################################ --# Main --# --def do_command(gen, lustre, options, args): -- if options.has_key('ost'): -- add_ost(gen, lustre, options, args) -- elif options.has_key('osc'): -- add_osc(gen, lustre, options, args) - elif options.has_key('echo_client'): - add_echo_client(gen, lustre, options, args) -- elif options.has_key('mtpt'): -- add_mtpt(gen, lustre, options, args) -- elif options.has_key('mds'): -- add_mds(gen, lustre, options, args) -- elif options.has_key('net'): -- add_net(gen, lustre, options, args) -- elif options.has_key('lov'): -- add_lov(gen, lustre, options, args) -- elif options.has_key('route'): -- add_route(gen, lustre, options, args) -- elif options.has_key('node'): -- add_node(gen, lustre, options, args) -- else: -- print "Missing command" -- usage() -- --def main(): -- options, args = parse_cmdline(sys.argv[1:]) -- outFile = '-' -- -- if options.has_key('merge'): -- outFile = options['merge'] -- if os.access(outFile, os.R_OK): -- doc = xml.dom.minidom.parse(outFile) -- else: -- doc = new_lustre(xml.dom.minidom) -- elif options.has_key('in'): -- doc = xml.dom.minidom.parse(options['in']) -- else: -- doc = new_lustre(xml.dom.minidom) -- -- if options.has_key('output'): -- outFile = options['output'] -- -- lustre = doc.documentElement -- init_names(lustre) -- if lustre.tagName != "lustre": -- print "Existing config not valid." -- sys.exit(1) -- -- gen = GenConfig(doc) -- -- if options.has_key('batch'): -- fp = open(options['batch']) -- batchCommands = fp.readlines() -- fp.close() -- for cmd in batchCommands: -- options, args = parse_cmdline(string.split(cmd)) -- do_command(gen, lustre, options, args) -- else: -- do_command(gen, lustre, options, args) -- -- if outFile == '-': -- PrettyPrint(doc) -- else: -- PrettyPrint(doc, open(outFile,"w")) -- --if __name__ == "__main__": -- main() -- -- diff --cc lustre/utils/lustre.dtd index 0a36580,2df183a..0000000 deleted file mode 100644,100644 --- a/lustre/utils/lustre.dtd +++ /dev/null @@@ -1,105 -1,110 +1,0 @@@ -- -- -- -- -- -- -- -- - -- -- -- -- -- -- -- -- -- -- -- - echo_client_ref | mds_ref | mdc_ref | lov_ref | - lovconfig_ref| mountpoint_ref)*> -- -- -- -- - - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - - -- -- -- -- -- -- -- -- diff --cc lustre/utils/mds-failover-sample index f6269f4,f6269f4..0000000 deleted file mode 100755,100755 --- a/lustre/utils/mds-failover-sample +++ /dev/null @@@ -1,20 -1,20 +1,0 @@@ --#!/bin/sh -- --MDS=NET_mds_tcp_UUID --MDSHOST=mds -- --/r/src/lustre/utils/lctl < -- * Author: Phil Schwan -- * Author: Andreas Dilger -- * Author: Robert Read -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#define printk printf -- --#include --#include --#include --#include /* for IOC_LOV_SET_OSC_ACTIVE */ -#include /* for struct lov_stripe_md */ -#include -- --#include --#include --#include --#include --#include --#include --#include -- --#include /* needed for PAGE_SIZE - rread */ -- --#define __KERNEL__ --#include --#undef __KERNEL__ -- --#include "obdctl.h" --#include "parser.h" --#include -- --#define SHMEM_STATS 1 --#if SHMEM_STATS --# include --# include -- --# define MAX_SHMEM_COUNT 1024 --static long long *shared_counters; --static long long counter_snapshot[2][MAX_SHMEM_COUNT]; --struct timeval prev_time; --#endif -- --int fd = -1; --uint64_t conn_addr = -1; --uint64_t conn_cookie; --char rawbuf[8192]; --char *buf = rawbuf; --int max = sizeof(rawbuf); -- --static int thread; -static struct lov_stripe_md saved_lsm; -static char lsm_valid = 0; -- --static int getfd(char *func); --static char *cmdname(char *func); -- --#define IOCINIT(data) \ --do { \ -- memset(&data, 0, sizeof(data)); \ -- data.ioc_version = OBD_IOCTL_VERSION; \ -- data.ioc_addr = conn_addr; \ -- data.ioc_cookie = conn_cookie; \ -- data.ioc_len = sizeof(data); \ -- if (fd < 0) { \ -- fprintf(stderr, "No device open, use device\n"); \ -- return 1; \ - } \ -} while (0) - -#define IOC_PACK(func, data) \ -do { \ - if (obd_ioctl_pack(&data, &buf, max)) { \ - fprintf(stderr, "error: %s: invalid ioctl\n", \ - cmdname(func)); \ - return -2; \ - } \ -} while (0) - -#define IOC_UNPACK(func, data) \ -do { \ - if (obd_ioctl_unpack(&data, buf, max)) { \ - fprintf(stderr, "error: %s: invalid reply\n", \ - cmdname(func)); \ - return -2; \ -- } \ --} while (0) -- --char *obdo_print(struct obdo *obd) --{ -- char buf[1024]; -- -- sprintf(buf, "id: "LPX64"\ngrp: "LPX64"\natime: "LPU64"\nmtime: "LPU64 -- "\nctime: "LPU64"\nsize: "LPU64"\nblocks: "LPU64 -- "\nblksize: %u\nmode: %o\nuid: %d\ngid: %d\nflags: %x\n" -- "obdflags: %x\nnlink: %d,\nvalid %x\n", -- obd->o_id, obd->o_gr, obd->o_atime, obd->o_mtime, obd->o_ctime, -- obd->o_size, obd->o_blocks, obd->o_blksize, obd->o_mode, -- obd->o_uid, obd->o_gid, obd->o_flags, obd->o_obdflags, -- obd->o_nlink, obd->o_valid); -- return strdup(buf); --} -- -- --#define BAD_VERBOSE (-999999999) -- --#define N2D_OFF 0x100 /* So we can tell between error codes and devices */ -- --static int do_name2dev(char *func, char *name) --{ -- struct obd_ioctl_data data; -- int rc; -- -- if (getfd(func)) -- return -1; -- -- IOCINIT(data); -- -- data.ioc_inllen1 = strlen(name) + 1; -- data.ioc_inlbuf1 = name; -- - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(func)); - return -2; - } - IOC_PACK(func, data); -- rc = ioctl(fd, OBD_IOC_NAME2DEV, buf); -- if (rc < 0) { -- fprintf(stderr, "error: %s: %s - %s\n", cmdname(func), -- name, strerror(rc = errno)); -- return rc; -- } - - memcpy((char *)(&data), buf, sizeof(data)); - IOC_UNPACK(func, data); -- -- return data.ioc_dev + N2D_OFF; --} -- --/* -- * resolve a device name to a device number. -- * supports a number or name. -- * FIXME: support UUID -- */ --static int parse_devname(char *func, char *name) --{ -- int rc; -- int ret = -1; -- -- if (!name) -- return ret; -- if (name[0] == '$') { -- rc = do_name2dev(func, name + 1); -- if (rc >= N2D_OFF) { -- ret = rc - N2D_OFF; -- printf("%s is device %d\n", name, ret); -- } else { -- fprintf(stderr, "error: %s: %s: %s\n", cmdname(func), -- name, "device not found"); -- } -- } else -- ret = strtoul(name, NULL, 0); -- -- return ret; --} -- --static char *cmdname(char *func) --{ -- static char buf[512]; -- -- if (thread) { -- sprintf(buf, "%s-%d", func, thread); -- return buf; -- } -- -- return func; --} -- --static int getfd(char *func) --{ -- if (fd == -1) -- fd = open("/dev/obd", O_RDWR); -- if (fd == -1) { -- fprintf(stderr, "error: %s: opening /dev/obd: %s\n" -- "hint: lustre kernel modules may not be loaded.\n", -- cmdname(func), strerror(errno)); -- return -1; -- } -- return 0; --} -- --#define difftime(a, b) \ -- ((double)(a)->tv_sec - (b)->tv_sec + \ -- ((double)((a)->tv_usec - (b)->tv_usec) / 1000000)) -- --static int be_verbose(int verbose, struct timeval *next_time, -- __u64 num, __u64 *next_num, int num_total) --{ -- struct timeval now; -- -- if (!verbose) -- return 0; -- -- if (next_time != NULL) -- gettimeofday(&now, NULL); -- -- /* A positive verbosity means to print every X iterations */ -- if (verbose > 0 && -- (next_num == NULL || num >= *next_num || num >= num_total)) { -- *next_num += verbose; -- if (next_time) { -- next_time->tv_sec = now.tv_sec - verbose; -- next_time->tv_usec = now.tv_usec; -- } -- return 1; -- } -- -- /* A negative verbosity means to print at most each X seconds */ -- if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){ -- next_time->tv_sec = now.tv_sec - verbose; -- next_time->tv_usec = now.tv_usec; -- if (next_num) -- *next_num = num; -- return 1; -- } -- -- return 0; --} -- --static int get_verbose(char *func, const char *arg) --{ -- int verbose; -- char *end; -- -- if (!arg || arg[0] == 'v') -- verbose = 1; -- else if (arg[0] == 's' || arg[0] == 'q') -- verbose = 0; -- else { -- verbose = (int)strtoul(arg, &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad verbose option '%s'\n", -- cmdname(func), arg); -- return BAD_VERBOSE; -- } -- } -- -- if (verbose < 0) -- printf("Print status every %d seconds\n", -verbose); -- else if (verbose == 1) -- printf("Print status every operation\n"); -- else if (verbose > 1) -- printf("Print status every %d operations\n", verbose); -- -- return verbose; --} -- --int do_disconnect(char *func, int verbose) --{ -- int rc; -- struct obd_ioctl_data data; -- -- if (conn_addr == -1) -- return 0; -- -- IOCINIT(data); -- -- rc = ioctl(fd, OBD_IOC_DISCONNECT, &data); -- if (rc < 0) { - fprintf(stderr, "error: %s: %x %s\n", cmdname(func), - OBD_IOC_DISCONNECT, strerror(errno)); - fprintf(stderr, "error: %s: OPD_IOC_DISCONNECT %s\n", - cmdname(func),strerror(errno)); -- } else { -- if (verbose) -- printf("%s: disconnected conn "LPX64"\n", cmdname(func), -- conn_addr); -- conn_addr = -1; -- } -- -- return rc; --} -- --#if SHMEM_STATS --static void shmem_setup(void) --{ -- /* Create new segment */ -- int shmid = shmget(IPC_PRIVATE, sizeof(counter_snapshot[0]), 0600); -- -- if (shmid == -1) { -- fprintf(stderr, "Can't create shared memory counters: %s\n", -- strerror(errno)); -- return; -- } -- -- /* Attatch to new segment */ -- shared_counters = (long long *)shmat(shmid, NULL, 0); -- -- if (shared_counters == (long long *)(-1)) { -- fprintf(stderr, "Can't attach shared memory counters: %s\n", -- strerror(errno)); -- shared_counters = NULL; -- return; -- } -- -- /* Mark segment as destroyed, so it will disappear when we exit. -- * Forks will inherit attached segments, so we should be OK. -- */ -- if (shmctl(shmid, IPC_RMID, NULL) == -1) { -- fprintf(stderr, "Can't destroy shared memory counters: %s\n", -- strerror(errno)); -- } --} -- --static inline void shmem_reset(void) --{ -- if (shared_counters == NULL) -- return; -- -- memset(shared_counters, 0, sizeof(counter_snapshot[0])); -- memset(counter_snapshot, 0, sizeof(counter_snapshot)); -- gettimeofday(&prev_time, NULL); --} -- --static inline void shmem_bump(void) --{ -- if (shared_counters == NULL || thread <= 0 || thread > MAX_SHMEM_COUNT) -- return; -- -- shared_counters[thread - 1]++; --} -- --static void shmem_snap(int n) --{ -- struct timeval this_time; -- int non_zero = 0; -- long long total = 0; -- double secs; -- int i; -- -- if (shared_counters == NULL || n > MAX_SHMEM_COUNT) -- return; -- -- memcpy(counter_snapshot[1], counter_snapshot[0], -- n * sizeof(counter_snapshot[0][0])); -- memcpy(counter_snapshot[0], shared_counters, -- n * sizeof(counter_snapshot[0][0])); -- gettimeofday(&this_time, NULL); -- -- for (i = 0; i < n; i++) { -- long long this_count = -- counter_snapshot[0][i] - counter_snapshot[1][i]; -- -- if (this_count != 0) { -- non_zero++; -- total += this_count; -- } -- } -- -- secs = (this_time.tv_sec + this_time.tv_usec / 1000000.0) - -- (prev_time.tv_sec + prev_time.tv_usec / 1000000.0); -- -- printf("%d/%d Total: %f/second\n", non_zero, n, total / secs); -- -- prev_time = this_time; --} -- --#define SHMEM_SETUP() shmem_setup() --#define SHMEM_RESET() shmem_reset() --#define SHMEM_BUMP() shmem_bump() --#define SHMEM_SNAP(n) shmem_snap(n) --#else --#define SHMEM_SETUP() --#define SHMEM_RESET() --#define SHMEM_BUMP() --#define SHMEM_SNAP(n) --#endif -- --extern command_t cmdlist[]; -- --static int do_device(char *func, int dev) --{ -- struct obd_ioctl_data data; -- -- memset(&data, 0, sizeof(data)); -- -- data.ioc_dev = dev; -- -- if (getfd(func)) -- return -1; - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(func)); - return -2; - } -- - IOC_PACK(func, data); -- return ioctl(fd, OBD_IOC_DEVICE, buf); --} -- --int jt_obd_device(int argc, char **argv) --{ -- int rc, dev; -- do_disconnect(argv[0], 1); -- -- if (argc != 2) -- return CMD_HELP; -- -- dev = parse_devname(argv[0], argv[1]); -- if (dev < 0) -- return -1; -- -- rc = do_device(argv[0], dev); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_connect(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- -- do_disconnect(argv[0], 1); -- --#warning TODO: implement timeout per lctl usage for probe -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, OBD_IOC_CONNECT, &data); -- if (rc < 0) - fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]), - OBD_IOC_CONNECT, strerror(rc = errno)); - fprintf(stderr, "error: %s: OBD_IOC_CONNECT %s\n", - cmdname(argv[0]), strerror(rc = errno)); -- else { -- conn_addr = data.ioc_addr; -- conn_cookie = data.ioc_cookie; -- } -- return rc; --} -- --int jt_obd_disconnect(int argc, char **argv) --{ -- if (argc != 1) -- return CMD_HELP; -- -- if (conn_addr == -1) -- return 0; -- -- return do_disconnect(argv[0], 0); --} -- --int jt_opt_device(int argc, char **argv) --{ -- char *arg2[3]; -- int ret; -- int rc; -- -- if (argc < 3) -- return CMD_HELP; -- -- rc = do_device("device", parse_devname(argv[0], argv[1])); -- -- if (!rc) { -- arg2[0] = "connect"; -- arg2[1] = NULL; -- rc = jt_obd_connect(1, arg2); -- } -- -- if (!rc) -- rc = Parser_execarg(argc - 2, argv + 2, cmdlist); -- -- ret = do_disconnect(argv[0], 0); -- if (!rc) -- rc = ret; -- -- return rc; --} -- --int jt_opt_threads(int argc, char **argv) --{ -- __u64 threads, next_thread; -- int verbose; -- int rc = 0; -- char *end; -- int i; -- -- if (argc < 5) -- return CMD_HELP; -- -- threads = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid page count '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- -- verbose = get_verbose(argv[0], argv[2]); -- if (verbose == BAD_VERBOSE) -- return CMD_HELP; -- -- if (verbose != 0) -- printf("%s: starting "LPD64" threads on device %s running %s\n", -- argv[0], threads, argv[3], argv[4]); -- -- SHMEM_RESET(); -- -- for (i = 1, next_thread = verbose; i <= threads; i++) { -- rc = fork(); -- if (rc < 0) { -- fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i, -- strerror(rc = errno)); -- break; -- } else if (rc == 0) { -- thread = i; -- argv[2] = "--device"; -- return jt_opt_device(argc - 2, argv + 2); -- } else if (be_verbose(verbose, NULL, i, &next_thread, threads)) -- printf("%s: thread #%d (PID %d) started\n", -- argv[0], i, rc); -- rc = 0; -- } -- -- if (!thread) { /* parent process */ -- int live_threads = threads; -- -- while (live_threads > 0) { -- int status; -- pid_t ret; -- -- ret = waitpid(0, &status, verbose < 0 ? WNOHANG : 0); -- if (ret == 0) { -- if (verbose >= 0) -- abort(); -- -- sleep(-verbose); -- SHMEM_SNAP(threads); -- continue; -- } -- -- if (ret < 0) { -- fprintf(stderr, "error: %s: wait - %s\n", -- argv[0], strerror(errno)); -- if (!rc) -- rc = errno; -- } else { -- /* -- * This is a hack. We _should_ be able to use -- * WIFEXITED(status) to see if there was an -- * error, but it appears to be broken and it -- * always returns 1 (OK). See wait(2). -- */ -- int err = WEXITSTATUS(status); -- if (err || WIFSIGNALED(status)) -- fprintf(stderr, -- "%s: PID %d had rc=%d\n", -- argv[0], ret, err); -- if (!rc) -- rc = err; -- -- live_threads--; -- } -- } -- } -- -- return rc; --} -- --int jt_obd_detach(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- char force = 'F'; -- int rc; -- -- IOCINIT(data); -- -- if (argc != 1 && argc != 2) -- return CMD_HELP; -- -- if (argc == 2) { -- data.ioc_inllen1 = 1; -- data.ioc_inlbuf1 = &force; - } - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; -- } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, OBD_IOC_DETACH, buf); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_cleanup(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, OBD_IOC_CLEANUP, &data); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_newdev(int argc, char **argv) --{ -- int rc; -- struct obd_ioctl_data data; -- -- if (getfd(argv[0])) -- return -1; -- -- IOCINIT(data); -- -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, OBD_IOC_NEWDEV, &data); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- else { -- printf("Current device set to %d\n", data.ioc_dev); -- } - - return rc; -} - -int jt_get_version(int argc, char **argv) -{ - int rc; - char buf[8192]; - struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; - - if (getfd(argv[0])) - return -1; - - memset(buf, 0, sizeof(buf)); - data->ioc_version = OBD_IOCTL_VERSION; - data->ioc_addr = conn_addr; - data->ioc_cookie = conn_addr; - data->ioc_len = sizeof(buf); - data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); - - if (argc != 1) - return CMD_HELP; -- - rc = ioctl(fd, OBD_GET_VERSION, data); - if (rc < 0) - fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), - strerror(rc = errno)); - else { - printf("Lustre version: %s\n", data->ioc_bulk); - } - - printf("lctl version: %s\n",BUILD_VERSION); -- return rc; --} -- --int jt_obd_list(int argc, char **argv) --{ -- int rc; -- char buf[8192]; -- struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf; -- -- if (getfd(argv[0])) -- return -1; -- -- memset(buf, 0, sizeof(buf)); -- data->ioc_version = OBD_IOCTL_VERSION; -- data->ioc_addr = conn_addr; -- data->ioc_cookie = conn_addr; -- data->ioc_len = sizeof(buf); -- data->ioc_inllen1 = sizeof(buf) - size_round(sizeof(*data)); -- -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, OBD_IOC_LIST, data); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- else { -- printf("%s", data->ioc_bulk); -- } -- -- return rc; --} -- --int jt_obd_attach(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- -- if (argc != 2 && argc != 3 && argc != 4) -- return CMD_HELP; -- -- data.ioc_inllen1 = strlen(argv[1]) + 1; -- data.ioc_inlbuf1 = argv[1]; -- if (argc >= 3) { -- data.ioc_inllen2 = strlen(argv[2]) + 1; -- data.ioc_inlbuf2 = argv[2]; -- } -- -- if (argc == 4) { -- data.ioc_inllen3 = strlen(argv[3]) + 1; -- data.ioc_inlbuf3 = argv[3]; - } - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; -- } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, OBD_IOC_ATTACH, buf); -- if (rc < 0) - fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]), - OBD_IOC_ATTACH, strerror(rc = errno)); - fprintf(stderr, "error: %s: OBD_IOC_ATTACH %s\n", - cmdname(argv[0]), strerror(rc = errno)); -- else if (argc == 3) { -- char name[1024]; -- if (strlen(argv[2]) > 128) { -- printf("Name too long to set environment\n"); -- return -EINVAL; -- } -- snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]); -- rc = setenv(name, argv[1], 1); -- if (rc) { -- printf("error setting env variable %s\n", name); -- } -- } -- -- return rc; --} -- --int jt_obd_name2dev(int argc, char **argv) --{ -- int rc; -- -- if (argc != 2) -- return CMD_HELP; -- -- rc = do_name2dev(argv[0], argv[1]); -- if (rc >= N2D_OFF) { -- int dev = rc - N2D_OFF; -- rc = do_device(argv[0], dev); -- if (rc == 0) -- printf("%d\n", dev); -- } -- return rc; --} -- --int jt_obd_setup(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- -- if (argc > 3) -- return CMD_HELP; -- -- data.ioc_dev = -1; -- if (argc > 1) { -- data.ioc_dev = parse_devname(argv[0], argv[1]); -- if (data.ioc_dev < 0) -- return -1; -- data.ioc_inllen1 = strlen(argv[1]) + 1; -- data.ioc_inlbuf1 = argv[1]; -- } -- if (argc == 3) { -- data.ioc_inllen2 = strlen(argv[2]) + 1; -- data.ioc_inlbuf2 = argv[2]; -- } -- - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; - } - IOC_PACK(argv[0], data); -- rc = ioctl(fd, OBD_IOC_SETUP, buf); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} - -- -/* The ioctl API has been extended to provide the LOV stripe metadata to the - * caller when applicable. This utility, however, only saves the LSM for the - * latest CREATE. */ --int jt_obd_create(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct timeval next_time; -- __u64 count = 1, next_count; - int verbose = 1; - int mode = 0100644; - int rc = 0, i; - int verbose = 1, mode = 0100644, rc = 0, i; -- char *end; -- -- IOCINIT(data); -- if (argc < 2 || argc > 4) -- return CMD_HELP; -- -- count = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid iteration count '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- -- if (argc > 2) { -- mode = strtoul(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid mode '%s'\n", -- cmdname(argv[0]), argv[2]); -- return CMD_HELP; -- } -- if (!(mode & S_IFMT)) -- mode |= S_IFREG; -- } -- -- if (argc > 3) { -- verbose = get_verbose(argv[0], argv[3]); -- if (verbose == BAD_VERBOSE) -- return CMD_HELP; -- } -- -- printf("%s: "LPD64" objects\n", cmdname(argv[0]), count); -- gettimeofday(&next_time, NULL); -- next_time.tv_sec -= verbose; -- -- for (i = 1, next_count = verbose; i <= count; i++) { -- data.ioc_obdo1.o_mode = mode; -- data.ioc_obdo1.o_id = i; -- data.ioc_obdo1.o_uid = 0; -- data.ioc_obdo1.o_gid = 0; -- data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | -- OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;; -- - rc = ioctl(fd, OBD_IOC_CREATE, &data); - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_CREATE, buf); - IOC_UNPACK(argv[0], data); - fprintf(stderr, "lsm->lsm_o_id: "LPX64"\n", - saved_lsm.lsm_object_id); -- SHMEM_BUMP(); -- if (rc < 0) { -- fprintf(stderr, "error: %s: #%d - %s\n", -- cmdname(argv[0]), i, strerror(rc = errno)); -- break; -- } -- if (!(data.ioc_obdo1.o_valid & OBD_MD_FLID)) { -- fprintf(stderr, "error: %s: objid not valid #%d:%08x\n", -- cmdname(argv[0]), i, data.ioc_obdo1.o_valid); -- rc = EINVAL; -- break; -- } - - lsm_valid = 1; -- -- if (be_verbose(verbose, &next_time, i, &next_count, count)) -- printf("%s: #%d is object id "LPX64"\n", -- cmdname(argv[0]), i, data.ioc_obdo1.o_id); -- } -- return rc; --} -- --int jt_obd_setattr(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- char *end; -- int rc; -- -- IOCINIT(data); -- if (argc != 2) -- return CMD_HELP; -- -- data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid objid '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- data.ioc_obdo1.o_mode = S_IFREG | strtoul(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid mode '%s'\n", -- cmdname(argv[0]), argv[2]); -- return CMD_HELP; -- } -- data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; -- - rc = ioctl(fd, OBD_IOC_SETATTR, &data); - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_SETATTR, buf); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_destroy(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct timeval next_time; -- __u64 count = 1, next_count; -- int verbose = 1; -- __u64 id; -- char *end; -- int rc = 0, i; -- -- IOCINIT(data); -- if (argc < 2 || argc > 4) -- return CMD_HELP; -- -- id = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid objid '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- if (argc > 2) { -- count = strtoull(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, -- "error: %s: invalid iteration count '%s'\n", -- cmdname(argv[0]), argv[2]); -- return CMD_HELP; -- } -- } -- -- if (argc > 3) { -- verbose = get_verbose(argv[0], argv[3]); -- if (verbose == BAD_VERBOSE) -- return CMD_HELP; -- } -- -- printf("%s: "LPD64" objects\n", cmdname(argv[0]), count); -- gettimeofday(&next_time, NULL); -- next_time.tv_sec -= verbose; -- -- for (i = 1, next_count = verbose; i <= count; i++, id++) { -- data.ioc_obdo1.o_id = id; -- data.ioc_obdo1.o_mode = S_IFREG | 0644; - data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLMODE; -- - rc = ioctl(fd, OBD_IOC_DESTROY, &data); - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_DESTROY, buf); - IOC_UNPACK(argv[0], data); -- SHMEM_BUMP(); -- if (rc < 0) { -- fprintf(stderr, "error: %s: objid "LPX64": %s\n", -- cmdname(argv[0]), id, strerror(rc = errno)); -- break; -- } - lsm_valid = 0; -- -- if (be_verbose(verbose, &next_time, i, &next_count, count)) - printf("%s: #%d is object id 0x%Lx\n", cmdname(argv[0]), - i, (long long)data.ioc_obdo1.o_id); - printf("%s: #%d is object id "LPX64"\n", - cmdname(argv[0]), i, id); -- } -- -- return rc; --} -- --int jt_obd_getattr(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- char *end; -- int rc; -- -- if (argc != 2) -- return CMD_HELP; -- -- IOCINIT(data); -- data.ioc_obdo1.o_id = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid objid '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- /* to help obd filter */ -- data.ioc_obdo1.o_mode = 0100644; -- data.ioc_obdo1.o_valid = 0xffffffff; -- printf("%s: object id "LPX64"\n", cmdname(argv[0]),data.ioc_obdo1.o_id); -- - rc = ioctl(fd, OBD_IOC_GETATTR, &data); - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } - - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_GETATTR, buf); - IOC_UNPACK(argv[0], data); -- if (rc) { -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- } else { -- printf("%s: object id "LPX64", mode %o\n", cmdname(argv[0]), -- data.ioc_obdo1.o_id, data.ioc_obdo1.o_mode); -- } -- return rc; --} -- --int jt_obd_test_getattr(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct timeval start, next_time; -- __u64 i, count, next_count; -- int verbose = 1; -- obd_id objid = 3; -- char *end; -- int rc = 0; -- -- if (argc < 2 && argc > 4) -- return CMD_HELP; -- -- IOCINIT(data); -- count = strtoull(argv[1], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid iteration count '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- -- if (argc >= 3) { -- verbose = get_verbose(argv[0], argv[2]); -- if (verbose == BAD_VERBOSE) -- return CMD_HELP; -- } -- -- if (argc >= 4) { -- if (argv[3][0] == 't') { -- objid = strtoull(argv[3] + 1, &end, 0); -- if (thread) -- objid += thread - 1; -- } else -- objid = strtoull(argv[3], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: invalid objid '%s'\n", -- cmdname(argv[0]), argv[3]); -- return CMD_HELP; -- } -- } -- -- gettimeofday(&start, NULL); -- next_time.tv_sec = start.tv_sec - verbose; -- next_time.tv_usec = start.tv_usec; -- if (verbose != 0) -- printf("%s: getting "LPD64" attrs (objid "LPX64"): %s", -- cmdname(argv[0]), count, objid, ctime(&start.tv_sec)); -- -- for (i = 1, next_count = verbose; i <= count; i++) { -- data.ioc_obdo1.o_id = objid; -- data.ioc_obdo1.o_mode = S_IFREG; -- data.ioc_obdo1.o_valid = 0xffffffff; -- rc = ioctl(fd, OBD_IOC_GETATTR, &data); -- SHMEM_BUMP(); -- if (rc < 0) { - fprintf(stderr, "error: %s: #"LPD64" - %s\n", - cmdname(argv[0]), i, strerror(rc = errno)); - fprintf(stderr, "error: %s: #"LPD64" - %d:%s\n", - cmdname(argv[0]), i, errno, strerror(rc = errno)); -- break; -- } else { -- if (be_verbose -- (verbose, &next_time, i, &next_count, count)) -- printf("%s: got attr #"LPD64"\n", -- cmdname(argv[0]), i); -- } -- } -- -- if (!rc) { -- struct timeval end; -- double diff; -- -- gettimeofday(&end, NULL); -- -- diff = difftime(&end, &start); -- -- --i; -- if (verbose != 0) -- printf("%s: "LPD64" attrs in %.4gs (%.4g attr/s): %s", -- cmdname(argv[0]), i, diff, (double)i / diff, -- ctime(&end.tv_sec)); -- } -- return rc; --} -- --int jt_obd_test_brw(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct timeval start, next_time; -- int pages = 1; -- __u64 count, next_count; -- __u64 objid = 3; -- int verbose = 1, write = 0, rw; -- char *end; -- int thr_offset = 0; -- int i; -- int len; -- int rc = 0; -- -- if (argc < 2 || argc > 6) { -- fprintf(stderr, "error: %s: bad number of arguments: %d\n", -- cmdname(argv[0]), argc); -- return CMD_HELP; -- } -- -- /* make each thread write to a different offset */ -- if (argv[1][0] == 't') { -- count = strtoull(argv[1] + 1, &end, 0); -- if (thread) -- thr_offset = thread - 1; -- } else -- count = strtoull(argv[1], &end, 0); -- -- if (*end) { -- fprintf(stderr, "error: %s: bad iteration count '%s'\n", -- cmdname(argv[0]), argv[1]); -- return CMD_HELP; -- } -- -- if (argc >= 3) { -- if (argv[2][0] == 'w' || argv[2][0] == '1') -- write = 1; -- else if (argv[2][0] == 'r' || argv[2][0] == '0') -- write = 0; -- } -- -- if (argc >= 4) { -- verbose = get_verbose(argv[0], argv[3]); -- if (verbose == BAD_VERBOSE) -- return CMD_HELP; -- } -- -- if (argc >= 5) { -- pages = strtoul(argv[4], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad page count '%s'\n", -- cmdname(argv[0]), argv[4]); -- return CMD_HELP; -- } -- } -- if (argc >= 6) { -- if (argv[5][0] == 't') { -- objid = strtoull(argv[5] + 1, &end, 0); -- if (thread) -- objid += thread - 1; -- } else -- objid = strtoull(argv[5], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad objid '%s'\n", -- cmdname(argv[0]), argv[5]); -- return CMD_HELP; -- } -- } -- -- len = pages * PAGE_SIZE; -- -- IOCINIT(data); -- data.ioc_obdo1.o_id = objid; -- data.ioc_obdo1.o_mode = S_IFREG; -- data.ioc_obdo1.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE; -- data.ioc_count = len; -- data.ioc_offset = thr_offset * len * count; - - if (lsm_valid == 1) { - data.ioc_inllen1 = sizeof(saved_lsm); - data.ioc_inlbuf1 = (char *)&saved_lsm; - } -- -- gettimeofday(&start, NULL); -- next_time.tv_sec = start.tv_sec - verbose; -- next_time.tv_usec = start.tv_usec; -- -- if (verbose != 0) -- printf("%s: %s "LPU64"x%d pages (obj "LPX64", off "LPU64"): %s", -- cmdname(argv[0]), write ? "writing" : "reading", count, -- pages, objid, data.ioc_offset, ctime(&start.tv_sec)); -- - rc = ioctl(fd, OBD_IOC_OPEN, &data); - IOC_PACK(argv[0], data); - rc = ioctl(fd, OBD_IOC_OPEN, buf); - IOC_UNPACK(argv[0], data); -- if (rc) { -- fprintf(stderr, "error: brw_open: %s\n", strerror(rc = errno)); -- return rc; -- } -- -- rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ; -- for (i = 1, next_count = verbose; i <= count; i++) { - rc = ioctl(fd, rw, &data); - rc = ioctl(fd, rw, buf); -- SHMEM_BUMP(); -- if (rc) { -- fprintf(stderr, "error: %s: #%d - %s on %s\n", -- cmdname(argv[0]), i, strerror(rc = errno), -- write ? "write" : "read"); -- break; -- } else if (be_verbose(verbose, &next_time,i, &next_count,count)) -- printf("%s: %s number %dx%d\n", cmdname(argv[0]), -- write ? "write" : "read", i, pages); -- -- data.ioc_offset += len; -- } -- -- if (!rc) { -- struct timeval end; -- double diff; -- -- gettimeofday(&end, NULL); -- -- diff = difftime(&end, &start); -- -- --i; -- if (verbose != 0) -- printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s", -- cmdname(argv[0]), write ? "wrote" : "read", -- i, pages, diff, (double)i * pages / diff, -- ctime(&end.tv_sec)); -- } - rw = ioctl(fd, OBD_IOC_CLOSE, &data); - rw = ioctl(fd, OBD_IOC_CLOSE, buf); -- if (rw) { -- fprintf(stderr, "error: brw_close: %s\n", strerror(rw = errno)); -- if (!rc) -- rc = rw; -- } -- -- return rc; --} -- --int jt_obd_lov_setconfig(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct lov_desc desc; -- obd_uuid_t *uuidarray, *ptr; -- int rc, i; -- char *end; -- -- IOCINIT(data); -- -- if (argc <= 6) -- return CMD_HELP; -- -- if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { -- fprintf(stderr, - "error: %s: LOV uuid '%s' longer than %d characters\n", - "error: %s: LOV uuid '%s' longer than %zd characters\n", -- cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); -- return -EINVAL; -- } -- -- memset(&desc, 0, sizeof(desc)); -- strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); -- desc.ld_tgt_count = argc - 6; -- desc.ld_default_stripe_count = strtoul(argv[2], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad default stripe count '%s'\n", -- cmdname(argv[0]), argv[2]); -- return CMD_HELP; -- } -- if (desc.ld_default_stripe_count > desc.ld_tgt_count) { -- fprintf(stderr, -- "error: %s: default stripe count %u > OST count %u\n", -- cmdname(argv[0]), desc.ld_default_stripe_count, -- desc.ld_tgt_count); -- return -EINVAL; -- } -- -- desc.ld_default_stripe_size = strtoull(argv[3], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad default stripe size '%s'\n", -- cmdname(argv[0]), argv[3]); -- return CMD_HELP; -- } -- if (desc.ld_default_stripe_size < 4096) { -- fprintf(stderr, -- "error: %s: default stripe size "LPU64" too small\n", -- cmdname(argv[0]), desc.ld_default_stripe_size); -- return -EINVAL; -- } else if ((long)desc.ld_default_stripe_size < -- desc.ld_default_stripe_size) { -- fprintf(stderr, -- "error: %s: default stripe size "LPU64" too large\n", -- cmdname(argv[0]), desc.ld_default_stripe_size); -- return -EINVAL; -- } -- desc.ld_default_stripe_offset = strtoull(argv[4], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad default stripe offset '%s'\n", -- cmdname(argv[0]), argv[4]); -- return CMD_HELP; -- } -- desc.ld_pattern = strtoul(argv[5], &end, 0); -- if (*end) { -- fprintf(stderr, "error: %s: bad stripe pattern '%s'\n", -- cmdname(argv[0]), argv[5]); -- return CMD_HELP; -- } -- -- /* NOTE: it is possible to overwrite the default striping parameters, -- * but EXTREME care must be taken when saving the OST UUID list. -- * It must be EXACTLY the same, or have only additions at the -- * end of the list, or only overwrite individual OST entries -- * that are restored from backups of the previous OST. -- */ -- uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); -- if (!uuidarray) { -- fprintf(stderr, "error: %s: no memory for %d UUIDs\n", -- cmdname(argv[0]), desc.ld_tgt_count); -- rc = -ENOMEM; -- goto out; -- } -- for (i = 6, ptr = uuidarray; i < argc; i++, ptr++) { -- if (strlen(argv[i]) >= sizeof(*ptr)) { -- fprintf(stderr, "error: %s: arg %d (%s) too long\n", -- cmdname(argv[0]), i, argv[i]); -- rc = -EINVAL; -- goto out; -- } -- strcpy((char *)ptr, argv[i]); -- } -- -- data.ioc_inllen1 = sizeof(desc); -- data.ioc_inlbuf1 = (char *)&desc; -- data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); -- data.ioc_inlbuf2 = (char *)uuidarray; -- -- if (obd_ioctl_pack(&data, &buf, max)) { -- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); -- rc = -EINVAL; -- goto out; -- } - -- rc = ioctl(fd, OBD_IOC_LOV_SET_CONFIG, buf); -- if (rc) -- fprintf(stderr, "error: %s: ioctl error: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); --out: -- free(uuidarray); -- return rc; --} -- --#define DEF_UUID_ARRAY_LEN (8192 / 40) -- --int jt_obd_lov_getconfig(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- struct lov_desc desc; -- obd_uuid_t *uuidarray; -- int rc; -- -- IOCINIT(data); -- -- if (argc != 2) -- return CMD_HELP; -- -- if (strlen(argv[1]) > sizeof(desc.ld_uuid) - 1) { -- fprintf(stderr, - "error: %s: LOV uuid '%s' longer than %d characters\n", - "error: %s: LOV uuid '%s' longer than %zd characters\n", -- cmdname(argv[0]), argv[1], sizeof(desc.ld_uuid) - 1); -- return -EINVAL; -- } -- -- memset(&desc, 0, sizeof(desc)); -- strncpy(desc.ld_uuid, argv[1], sizeof(desc.ld_uuid) - 1); -- desc.ld_tgt_count = DEF_UUID_ARRAY_LEN; --repeat: -- uuidarray = calloc(desc.ld_tgt_count, sizeof(*uuidarray)); -- if (!uuidarray) { -- fprintf(stderr, "error: %s: no memory for %d uuid's\n", -- cmdname(argv[0]), desc.ld_tgt_count); -- return -ENOMEM; -- } -- -- data.ioc_inllen1 = sizeof(desc); -- data.ioc_inlbuf1 = (char *)&desc; -- data.ioc_inllen2 = desc.ld_tgt_count * sizeof(*uuidarray); -- data.ioc_inlbuf2 = (char *)uuidarray; -- -- if (obd_ioctl_pack(&data, &buf, max)) { -- fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); -- rc = -EINVAL; -- goto out; -- } - -- rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); -- if (rc == -ENOSPC) { -- free(uuidarray); -- goto repeat; -- } else if (rc) { -- fprintf(stderr, "error: %s: ioctl error: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- } else { -- obd_uuid_t *ptr; -- int i; -- -- if (obd_ioctl_unpack(&data, buf, max)) { -- fprintf(stderr, "error: %s: invalid reply\n", -- cmdname(argv[0])); -- rc = -EINVAL; -- goto out; -- } -- printf("default_stripe_count: %u\n", -- desc.ld_default_stripe_count); -- printf("default_stripe_size: "LPU64"\n", -- desc.ld_default_stripe_size); -- printf("default_stripe_offset: "LPU64"\n", -- desc.ld_default_stripe_offset); -- printf("default_stripe_pattern: %u\n", desc.ld_pattern); -- printf("obd_count: %u\n", desc.ld_tgt_count); -- for (i = 0, ptr = uuidarray; i < desc.ld_tgt_count; i++, ptr++) -- printf("%u: %s\n", i, (char *)ptr); -- } --out: -- free(uuidarray); -- return rc; --} -- --int jt_obd_test_ldlm(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, IOC_LDLM_TEST, &data); -- if (rc) -- fprintf(stderr, "error: %s: test failed: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- return rc; --} -- --int jt_obd_dump_ldlm(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, IOC_LDLM_DUMP, &data); -- if (rc) -- fprintf(stderr, "error: %s failed: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- return rc; --} -- --int jt_obd_ldlm_regress_start(int argc, char **argv) --{ -- int rc; -- struct obd_ioctl_data data; -- char argstring[200]; -- int i, count = sizeof(argstring) - 1; -- -- IOCINIT(data); -- if (argc > 5) -- return CMD_HELP; -- -- argstring[0] = '\0'; -- for (i = 1; i < argc; i++) { -- strncat(argstring, " ", count); -- count--; -- strncat(argstring, argv[i], count); -- count -= strlen(argv[i]); -- } -- -- if (strlen(argstring)) { -- data.ioc_inlbuf1 = argstring; -- data.ioc_inllen1 = strlen(argstring) + 1; - } - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; -- } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, IOC_LDLM_REGRESS_START, buf); - -- if (rc) -- fprintf(stderr, "error: %s: test failed: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_ldlm_regress_stop(int argc, char **argv) --{ -- int rc; -- struct obd_ioctl_data data; -- IOCINIT(data); -- -- if (argc != 1) -- return CMD_HELP; -- -- rc = ioctl(fd, IOC_LDLM_REGRESS_STOP, &data); -- -- if (rc) -- fprintf(stderr, "error: %s: test failed: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- return rc; --} -- --int jt_obd_lov_set_osc_active(int argc, char **argv) --{ -- struct obd_ioctl_data data; -- int rc; -- -- IOCINIT(data); -- if (argc != 3) -- return CMD_HELP; -- -- data.ioc_inlbuf1 = argv[1]; -- data.ioc_inllen1 = strlen(argv[1]) + 1; -- -- /* reuse offset for 'active' */ -- data.ioc_offset = atoi(argv[2]); - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; - } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, IOC_LOV_SET_OSC_ACTIVE, buf); - -- if (rc) -- fprintf(stderr, "error: %s: failed: %s\n", -- cmdname(argv[0]), strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_newconn(int argc, char **argv) --{ -- int rc; -- struct obd_ioctl_data data; -- -- IOCINIT(data); -- if (argc < 2 || argc > 3) -- return CMD_HELP; -- -- data.ioc_inllen1 = strlen(argv[1]) + 1; -- data.ioc_inlbuf1 = argv[1]; -- -- if (argc == 3) { -- data.ioc_inllen2 = strlen(argv[2]) + 1; -- data.ioc_inlbuf2 = argv[2]; - } - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; -- } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, OBD_IOC_RECOVD_NEWCONN, buf); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --int jt_obd_failconn(int argc, char **argv) --{ -- int rc; -- struct obd_ioctl_data data; -- -- IOCINIT(data); -- if (argc < 2) -- return CMD_HELP; -- -- data.ioc_inllen1 = strlen(argv[1]) + 1; -- data.ioc_inlbuf1 = argv[1]; - - if (obd_ioctl_pack(&data, &buf, max)) { - fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0])); - return -2; - } -- - IOC_PACK(argv[0], data); -- rc = ioctl(fd, OBD_IOC_RECOVD_FAILCONN, buf); -- if (rc < 0) -- fprintf(stderr, "error: %s: %s\n", cmdname(argv[0]), -- strerror(rc = errno)); -- -- return rc; --} -- --static void signal_server(int sig) --{ -- if (sig == SIGINT) { -- do_disconnect("sigint", 1); -- exit(1); -- } else -- fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig); --} -- --int obd_initialize(int argc, char **argv) --{ -- SHMEM_SETUP(); -- return 0; --} -- -- --void obd_cleanup(int argc, char **argv) --{ -- struct sigaction sigact; -- -- sigact.sa_handler = signal_server; -- sigfillset(&sigact.sa_mask); -- sigact.sa_flags = SA_RESTART; -- sigaction(SIGINT, &sigact, NULL); -- -- do_disconnect(argv[0], 1); --} diff --cc lustre/utils/obdctl.c index 4e934f9,860b908..0000000 deleted file mode 100644,100644 --- a/lustre/utils/obdctl.c +++ /dev/null @@@ -1,103 -1,103 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * Author: Peter J. Braam -- * Author: Phil Schwan -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ -- -- --#include --#include -- --#include "obdctl.h" --#include "parser.h" -- --/* the functions that were in here are now in obd.c */ -- --static int jt_quit(int argc, char **argv) --{ -- int rc = 0; -- Parser_quit(argc, argv); -- -- return rc; --} -- --command_t cmdlist[] = { -- /* Metacommands */ -- {"--device", jt_opt_device, 0, "--device "}, -- {"--threads", jt_opt_threads, 0, -- "--threads "}, -- -- /* Device configuration commands */ -- {"lov_setconfig", jt_obd_lov_setconfig, 0, "configure lov data on MDS " -- "[usage: lovconfig lov-uuid stripecount, stripesize, pattern, UUID1, [UUID2, ...]"}, -- {"list", jt_obd_list, 0, "list the devices (no args)"}, -- {"newdev", jt_obd_newdev, 0, "set device to a new unused obd (no args)"}, -- {"device", jt_obd_device, 0, "set current device (args device_no name)"}, -- {"name2dev", jt_obd_name2dev, 0, -- "set device by name [usage: name2dev devname]"}, -- {"attach", jt_obd_attach, 0, "name the type of device (args: type data"}, -- {"setup", jt_obd_setup, 0, "setup device (args: [data]"}, -- {"detach", jt_obd_detach, 0, "detach the current device (arg: )"}, -- {"cleanup", jt_obd_cleanup, 0, "cleanup the current device (arg: )"}, -- -- /* Session commands */ -- {"connect", jt_obd_connect, 0, "connect - get a connection to device"}, -- {"disconnect", jt_obd_disconnect, 0, -- "disconnect - break connection to device"}, -- -- /* Session operations */ - {"create", jt_obd_create, 0, "create [count [mode [verbose]]]"}, - {"create", jt_obd_create, 0, "create [mode [verbose]]"}, -- {"destroy", jt_obd_destroy, 0, "destroy [count [verbose]]"}, -- {"getattr", jt_obd_getattr, 0, "getattr "}, -- {"setattr", jt_obd_setattr, 0, "setattr "}, -- {"newconn", jt_obd_newconn, 0, "newconn [newuuid]"}, -- {"test_getattr", jt_obd_test_getattr, 0, "test_getattr [verbose [[t]objid]]"}, -- {"test_brw", jt_obd_test_brw, 0, "test_brw [t] [write [verbose [pages [[t]objid]]]]"}, -- {"test_ldlm", jt_obd_test_ldlm, 0, "test lock manager (no args)"}, -- {"dump_ldlm", jt_obd_dump_ldlm, 0, "dump all lock manager state (no args)"}, -- -- /* User interface commands */ -- {"help", Parser_help, 0, "help"}, -- {"exit", jt_quit, 0, "quit"}, -- {"quit", jt_quit, 0, "quit"}, -- {0, 0, 0, NULL} --}; -- -- --int main(int argc, char **argv) --{ -- int rc; -- -- setlinebuf(stdout); -- -- if (obd_initialize(argc, argv) < 0) -- exit(1); -- -- if (argc > 1) { -- rc = Parser_execarg(argc - 1, argv + 1, cmdlist); -- } else { -- Parser_init("obdctl > ", cmdlist); -- rc = Parser_commands(); -- } -- -- obd_cleanup(argc, argv); -- return rc; --} diff --cc lustre/utils/obdctl.h index 98aaffa,01ece92..0000000 deleted file mode 100644,100644 --- a/lustre/utils/obdctl.h +++ /dev/null @@@ -1,62 -1,63 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2002 Cluster File Systems, Inc. -- * -- * Author: Peter J. Braam -- * Author: Phil Schwan -- * Author: Robert Read -- * -- * This file is part of Lustre, http://www.lustre.org. -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#ifndef _OBDCTL_H_ --#define _OBDCTL_H_ -- --int do_disconnect(char *func, int verbose); --int obd_initialize(int argc, char **argv); --void obd_cleanup(int argc, char **argv); -- --int jt_opt_device(int argc, char **argv); --int jt_opt_threads(int argc, char **argv); -- --int jt_obd_device(int argc, char **argv); --int jt_obd_connect(int argc, char **argv); --int jt_obd_disconnect(int argc, char **argv); --int jt_obd_detach(int argc, char **argv); --int jt_obd_cleanup(int argc, char **argv); --int jt_obd_newdev(int argc, char **argv); --int jt_obd_list(int argc, char **argv); --int jt_obd_attach(int argc, char **argv); --int jt_obd_name2dev(int argc, char **argv); --int jt_obd_setup(int argc, char **argv); --int jt_obd_create(int argc, char **argv); --int jt_obd_setattr(int argc, char **argv); --int jt_obd_destroy(int argc, char **argv); --int jt_obd_getattr(int argc, char **argv); --int jt_obd_test_getattr(int argc, char **argv); --int jt_obd_test_brw(int argc, char **argv); --int jt_obd_lov_setconfig(int argc, char **argv); --int jt_obd_lov_getconfig(int argc, char **argv); --int jt_obd_test_ldlm(int argc, char **argv); --int jt_obd_ldlm_regress_start(int argc, char **argv); --int jt_obd_ldlm_regress_stop(int argc, char **argv); --int jt_obd_dump_ldlm(int argc, char **argv); --int jt_obd_lov_set_osc_active(int argc, char **argv); --int jt_obd_newconn(int argc, char **argv); --int jt_obd_failconn(int argc, char **argv); -int jt_get_version(int argc, char **argv); -- --#endif diff --cc lustre/utils/parser.c index ee77e28,0e5a9f0..0000000 deleted file mode 100644,100644 --- a/lustre/utils/parser.c +++ /dev/null @@@ -1,722 -1,722 +1,0 @@@ --/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -- * vim:expandtab:shiftwidth=8:tabstop=8: -- * -- * Copyright (C) 2001 Cluster File Systems, Inc. -- * -- * This file is part of Lustre, http://www.sf.net/projects/lustre/ -- * -- * Lustre is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * Lustre 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with Lustre; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- */ --#include --#include --#include --#include --#include --#include --#include --#include -- --#ifdef HAVE_LIBREADLINE --#define READLINE_LIBRARY --#include -- --//extern char **completion_matches __P((char *, rl_compentry_func_t *)); --extern void using_history(void); --extern void stifle_history(int); --extern void add_history(char *); --#endif -- --#include "parser.h" -- --static command_t * top_level; /* Top level of commands, initialized by -- * InitParser */ --static char * parser_prompt = NULL;/* Parser prompt, set by InitParser */ --static int done; /* Set to 1 if user types exit or quit */ --static int ignore_errors; /* Normally, the parser will quit when -- an error occurs in non-interacive -- mode. Setting this to non-zero will -- force it to keep buggering on. */ -- -- --/* static functions */ --static char *skipwhitespace(char *s); --static char *skiptowhitespace(char *s); --static command_t *find_cmd(char *name, command_t cmds[], char **next); --static int process(char *s, char **next, command_t *lookup, command_t **result, -- char **prev); --static void print_commands(char *str, command_t *table); -- --static char * skipwhitespace(char * s) --{ -- char * t; -- int len; -- -- len = (int)strlen(s); -- for (t = s; t <= s + len && isspace(*t); t++); -- return(t); --} -- -- --static char * skiptowhitespace(char * s) --{ -- char * t; -- -- for (t = s; *t && !isspace(*t); t++); -- return(t); --} -- --static int line2args(char *line, char **argv, int maxargs) --{ -- char *arg; -- int i = 0; -- -- arg = strtok(line, " \t"); -- if ( arg ) { -- argv[i] = arg; -- i++; -- } else -- return 0; -- -- while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) { -- argv[i] = arg; -- i++; -- } -- return i; --} -- --/* find a command -- return it if unique otherwise print alternatives */ --static command_t *Parser_findargcmd(char *name, command_t cmds[]) --{ -- command_t *cmd; -- -- for (cmd = cmds; cmd->pc_name; cmd++) { -- if (strcmp(name, cmd->pc_name) == 0) -- return cmd; -- } -- return NULL; --} -- --void Parser_ignore_errors(int ignore) --{ -- ignore_errors = ignore; --} -- --int Parser_execarg(int argc, char **argv, command_t cmds[]) --{ -- command_t *cmd; -- -- cmd = Parser_findargcmd(argv[0], cmds); -- if ( cmd ) { -- return (cmd->pc_func)(argc, argv); -- } else { -- printf("Try interactive use without arguments or use one of:\n"); -- for (cmd = cmds; cmd->pc_name; cmd++) - printf("\"%s\" ", cmd->pc_name); - printf("\nas argument.\n"); - printf("\"%s\"\n", cmd->pc_name); - printf("as argument.\n"); -- } -- return -1; --} -- --/* returns the command_t * (NULL if not found) corresponding to a -- _partial_ match with the first token in name. It sets *next to -- point to the following token. Does not modify *name. */ --static command_t * find_cmd(char * name, command_t cmds[], char ** next) --{ -- int i, len; -- -- if (!cmds || !name ) -- return NULL; -- -- /* This sets name to point to the first non-white space character, -- and next to the first whitespace after name, len to the length: do -- this with strtok*/ -- name = skipwhitespace(name); -- *next = skiptowhitespace(name); -- len = *next - name; -- if (len == 0) -- return NULL; -- -- for (i = 0; cmds[i].pc_name; i++) { -- if (strncasecmp(name, cmds[i].pc_name, len) == 0) { -- *next = skipwhitespace(*next); -- return(&cmds[i]); -- } -- } -- return NULL; --} -- --/* Recursively process a command line string s and find the command -- corresponding to it. This can be ambiguous, full, incomplete, -- non-existent. */ --static int process(char *s, char ** next, command_t *lookup, -- command_t **result, char **prev) --{ -- *result = find_cmd(s, lookup, next); -- *prev = s; -- -- /* non existent */ -- if ( ! *result ) -- return CMD_NONE; -- -- /* found entry: is it ambigous, i.e. not exact command name and -- more than one command in the list matches. Note that find_cmd -- points to the first ambiguous entry */ -- if ( strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name)) && -- find_cmd(s, (*result) + 1, next)) -- return CMD_AMBIG; -- -- /* found a unique command: component or full? */ -- if ( (*result)->pc_func ) { -- return CMD_COMPLETE; -- } else { -- if ( *next == '\0' ) { -- return CMD_INCOMPLETE; -- } else { -- return process(*next, next, (*result)->pc_sub_cmd, result, prev); -- } -- } --} -- --#ifdef HAVE_LIBREADLINE --static command_t * match_tbl; /* Command completion against this table */ --static char * command_generator(const char * text, int state) --{ -- static int index, -- len; -- char *name; -- -- /* Do we have a match table? */ -- if (!match_tbl) -- return NULL; -- -- /* If this is the first time called on this word, state is 0 */ -- if (!state) { -- index = 0; -- len = (int)strlen(text); -- } -- -- /* Return next name in the command list that paritally matches test */ -- while ( (name = (match_tbl + index)->pc_name) ) { -- index++; -- -- if (strncasecmp(name, text, len) == 0) { -- return(strdup(name)); -- } -- } -- -- /* No more matches */ -- return NULL; --} -- --/* probably called by readline */ --static char **command_completion(char * text, int start, int end) --{ -- command_t * table; -- char * pos; -- -- match_tbl = top_level; -- for (table = find_cmd(rl_line_buffer, match_tbl, &pos); -- table; -- table = find_cmd(pos, match_tbl, &pos)) { -- -- if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd; -- } -- -- return(completion_matches(text, command_generator)); --} --#endif -- --/* take a string and execute the function or print help */ --int execute_line(char * line) --{ -- command_t *cmd, *ambig; -- char *prev; -- char *next, *tmp; -- char *argv[MAXARGS]; -- int i; -- int rc = 0; -- -- switch( process(line, &next, top_level, &cmd, &prev) ) { -- case CMD_AMBIG: -- fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); -- while( (ambig = find_cmd(prev, cmd, &tmp)) ) { -- fprintf(stderr, "%s ", ambig->pc_name); -- cmd = ambig + 1; -- } -- fprintf(stderr, "\n"); -- break; -- case CMD_NONE: -- fprintf(stderr, "No such command, type help\n"); -- break; -- case CMD_INCOMPLETE: -- fprintf(stderr, -- "'%s' incomplete command. Use '%s x' where x is one of:\n", -- line, line); -- fprintf(stderr, "\t"); -- for (i = 0; cmd->pc_sub_cmd[i].pc_name; i++) { -- fprintf(stderr, "%s ", cmd->pc_sub_cmd[i].pc_name); -- } -- fprintf(stderr, "\n"); -- break; -- case CMD_COMPLETE: -- i = line2args(line, argv, MAXARGS); -- rc = (cmd->pc_func)(i, argv); -- -- if (rc == CMD_HELP) -- fprintf(stderr, "%s\n", cmd->pc_help); -- -- break; -- } -- -- return rc; --} -- --int --noop_fn () --{ -- return (0); --} -- --/* just in case you're ever in an airplane and discover you -- forgot to install readline-dev. :) */ --int init_input() --{ -- int interactive = isatty (fileno (stdin)); -- --#ifdef HAVE_LIBREADLINE -- using_history(); -- stifle_history(HISTORY); -- -- if (!interactive) -- { -- rl_prep_term_function = (rl_vintfunc_t *)noop_fn; -- rl_deprep_term_function = (rl_voidfunc_t *)noop_fn; -- } -- -- rl_attempted_completion_function = (CPPFunction *)command_completion; -- rl_completion_entry_function = (void *)command_generator; --#endif -- return interactive; --} -- --#ifndef HAVE_LIBREADLINE --#define add_history(s) --char * readline(char * prompt) --{ -- char line[2048]; -- int n = 0; -- if (prompt) -- printf ("%s", prompt); -- if (fgets(line, sizeof(line), stdin) == NULL) -- return (NULL); -- n = strlen(line); -- if (n && line[n-1] == '\n') -- line[n-1] = '\0'; -- return strdup(line); --} --#endif -- --/* this is the command execution machine */ --int Parser_commands(void) --{ -- char *line, *s; -- int rc = 0, save_error = 0; -- int interactive; -- -- interactive = init_input(); -- -- while(!done) { -- line = readline(interactive ? parser_prompt : NULL); -- -- if (!line) break; -- -- s = skipwhitespace(line); -- -- if (*s) { -- add_history(s); -- rc = execute_line(s); -- } -- /* stop on error if not-interactive */ -- if (rc != 0 && !interactive) { -- if (save_error == 0) -- save_error = rc; -- if (!ignore_errors) -- done = 1; -- } -- -- free(line); -- } -- if (save_error) -- rc = save_error; -- return rc; --} -- -- --/* sets the parser prompt */ --void Parser_init(char * prompt, command_t * cmds) --{ -- done = 0; -- top_level = cmds; -- if (parser_prompt) free(parser_prompt); -- parser_prompt = strdup(prompt); --} -- --/* frees the parser prompt */ --void Parser_exit(int argc, char *argv[]) --{ -- done = 1; -- free(parser_prompt); -- parser_prompt = NULL; --} -- --/* convert a string to an integer */ --int Parser_int(char *s, int *val) --{ -- int ret; -- -- if (*s != '0') -- ret = sscanf(s, "%d", val); -- else if (*(s+1) != 'x') -- ret = sscanf(s, "%o", val); -- else { -- s++; -- ret = sscanf(++s, "%x", val); -- } -- -- return(ret); --} -- -- --void Parser_qhelp(int argc, char *argv[]) { -- -- printf("Available commands are:\n"); -- -- print_commands(NULL, top_level); -- printf("For more help type: help command-name\n"); --} -- --int Parser_help(int argc, char **argv) --{ -- char line[1024]; -- char *next, *prev, *tmp; -- command_t *result, *ambig; -- int i; -- -- if ( argc == 1 ) { -- Parser_qhelp(argc, argv); -- return 0; -- } -- -- line[0]='\0'; -- for ( i = 1 ; i < argc ; i++ ) { -- strcat(line, argv[i]); -- } -- -- switch ( process(line, &next, top_level, &result, &prev) ) { -- case CMD_COMPLETE: -- fprintf(stderr, "%s: %s\n",line, result->pc_help); -- break; -- case CMD_NONE: -- fprintf(stderr, "%s: Unknown command.\n", line); -- break; -- case CMD_INCOMPLETE: -- fprintf(stderr, -- "'%s' incomplete command. Use '%s x' where x is one of:\n", -- line, line); -- fprintf(stderr, "\t"); -- for (i = 0; result->pc_sub_cmd[i].pc_name; i++) { -- fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name); -- } -- fprintf(stderr, "\n"); -- break; -- case CMD_AMBIG: -- fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); -- while( (ambig = find_cmd(prev, result, &tmp)) ) { -- fprintf(stderr, "%s ", ambig->pc_name); -- result = ambig + 1; -- } -- fprintf(stderr, "\n"); -- break; -- } -- return 0; --} -- -- --void Parser_printhelp(char *cmd) --{ -- char *argv[] = { "help", cmd }; -- Parser_help(2, argv); --} -- -- --/************************************************************************* -- * COMMANDS * -- *************************************************************************/ -- -- --static void print_commands(char * str, command_t * table) { -- command_t * cmds; -- char buf[80]; -- -- for (cmds = table; cmds->pc_name; cmds++) { -- if (cmds->pc_func) { -- if (str) printf("\t%s %s\n", str, cmds->pc_name); -- else printf("\t%s\n", cmds->pc_name); -- } -- if (cmds->pc_sub_cmd) { -- if (str) { -- sprintf(buf, "%s %s", str, cmds->pc_name); -- print_commands(buf, cmds->pc_sub_cmd); -- } else { -- print_commands(cmds->pc_name, cmds->pc_sub_cmd); -- } -- } -- } --} -- --char *Parser_getstr(const char *prompt, const char *deft, char *res, -- size_t len) --{ -- char *line = NULL; -- int size = strlen(prompt) + strlen(deft) + 8; -- char *theprompt; -- theprompt = malloc(size); -- assert(theprompt); -- -- sprintf(theprompt, "%s [%s]: ", prompt, deft); -- -- line = readline(theprompt); -- free(theprompt); -- -- if ( line == NULL || *line == '\0' ) { -- strncpy(res, deft, len); -- } else { -- strncpy(res, line, len); -- } -- -- if ( line ) { -- free(line); -- return res; -- } else { -- return NULL; -- } --} -- --/* get integer from prompt, loop forever to get it */ --int Parser_getint(const char *prompt, long min, long max, long deft, int base) --{ -- int rc; -- long result; -- char *line; -- int size = strlen(prompt) + 40; -- char *theprompt = malloc(size); -- assert(theprompt); -- sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft); -- -- fflush(stdout); -- -- do { -- line = NULL; -- line = readline(theprompt); -- if ( !line ) { -- fprintf(stdout, "Please enter an integer.\n"); -- fflush(stdout); -- continue; -- } -- if ( *line == '\0' ) { -- free(line); -- result = deft; -- break; -- } -- rc = Parser_arg2int(line, &result, base); -- free(line); -- if ( rc != 0 ) { -- fprintf(stdout, "Invalid string.\n"); -- fflush(stdout); -- } else if ( result > max || result < min ) { -- fprintf(stdout, "Error: response must lie between %ld and %ld.\n", -- min, max); -- fflush(stdout); -- } else { -- break; -- } -- } while ( 1 ) ; -- -- if (theprompt) -- free(theprompt); -- return result; -- --} -- --/* get boolean (starting with YyNn; loop forever */ --int Parser_getbool(const char *prompt, int deft) --{ -- int result = 0; -- char *line; -- int size = strlen(prompt) + 8; -- char *theprompt = malloc(size); -- assert(theprompt); -- -- fflush(stdout); -- -- if ( deft != 0 && deft != 1 ) { -- fprintf(stderr, "Error: Parser_getbool given bad default (%d).\n", -- deft); -- assert ( 0 ); -- } -- sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y"); -- -- do { -- line = NULL; -- line = readline(theprompt); -- if ( line == NULL ) { -- result = deft; -- break; -- } -- if ( *line == '\0' ) { -- result = deft; -- break; -- } -- if ( *line == 'y' || *line == 'Y' ) { -- result = 1; -- break; -- } -- if ( *line == 'n' || *line == 'N' ) { -- result = 0; -- break; -- } -- if ( line ) -- free(line); -- fprintf(stdout, "Invalid string. Must start with yY or nN\n"); -- fflush(stdout); -- } while ( 1 ); -- -- if ( line ) -- free(line); -- if ( theprompt ) -- free(theprompt); -- return result; --} -- --/* parse int out of a string or prompt for it */ --long Parser_intarg(const char *inp, const char *prompt, int deft, -- int min, int max, int base) --{ -- long result; -- int rc; -- -- rc = Parser_arg2int(inp, &result, base); -- -- if ( rc == 0 ) { -- return result; -- } else { -- return Parser_getint(prompt, deft, min, max, base); -- } --} -- --/* parse int out of a string or prompt for it */ --char *Parser_strarg(char *inp, const char *prompt, const char *deft, -- char *answer, int len) --{ -- if ( inp == NULL || *inp == '\0' ) { -- return Parser_getstr(prompt, deft, answer, len); -- } else -- return inp; --} -- --/* change a string into a number: return 0 on success. No invalid characters -- allowed. The processing of base and validity follows strtol(3)*/ --int Parser_arg2int(const char *inp, long *result, int base) --{ -- char *endptr; -- -- if ( (base !=0) && (base < 2 || base > 36) ) -- return 1; -- -- *result = strtol(inp, &endptr, base); -- -- if ( *inp != '\0' && *endptr == '\0' ) -- return 0; -- else -- return 1; --} -- --/* Convert human readable size string to and int; "1k" -> 1000 */ --int Parser_size (int *sizep, char *str) { -- int size; -- char mod[32]; -- -- switch (sscanf (str, "%d%1[gGmMkK]", &size, mod)) { -- default: -- return (-1); -- -- case 1: -- *sizep = size; -- return (0); -- -- case 2: -- switch (*mod) { -- case 'g': -- case 'G': -- *sizep = size << 30; -- return (0); -- -- case 'm': -- case 'M': -- *sizep = size << 20; -- return (0); -- -- case 'k': -- case 'K': -- *sizep = size << 10; -- return (0); -- -- default: -- *sizep = size; -- return (0); -- } -- } --} -- --/* Convert a string boolean to an int; "enable" -> 1 */ --int Parser_bool (int *b, char *str) { -- if (!strcasecmp (str, "no") || -- !strcasecmp (str, "n") || -- !strcasecmp (str, "off") || -- !strcasecmp (str, "disable")) -- { -- *b = 0; -- return (0); -- } -- -- if (!strcasecmp (str, "yes") || -- !strcasecmp (str, "y") || -- !strcasecmp (str, "on") || -- !strcasecmp (str, "enable")) -- { -- *b = 1; -- return (0); -- } -- -- return (-1); --} -- --int Parser_quit(int argc, char **argv) --{ -- argc = argc; -- argv = argv; -- done = 1; -- return 0; --} diff --cc lustre/utils/parser.h index 5aece60,5aece60..0000000 deleted file mode 100644,100644 --- a/lustre/utils/parser.h +++ /dev/null @@@ -1,74 -1,74 +1,0 @@@ --#ifndef _PARSER_H_ --#define _PARSER_H_ -- --#define HISTORY 100 /* Don't let history grow unbounded */ --#define MAXARGS 100 -- --#define CMD_COMPLETE 0 --#define CMD_INCOMPLETE 1 --#define CMD_NONE 2 --#define CMD_AMBIG 3 --#define CMD_HELP 4 -- --typedef struct parser_cmd { -- char *pc_name; -- int (* pc_func)(int, char **); -- struct parser_cmd * pc_sub_cmd; -- char *pc_help; --} command_t; -- --typedef struct argcmd { -- char *ac_name; -- int (*ac_func)(int, char **); -- char *ac_help; --} argcmd_t; -- --typedef struct network { -- char *type; -- char *server; -- int port; --} network_t; -- --int Parser_quit(int argc, char **argv); --void Parser_init(char *, command_t *); /* Set prompt and load command list */ --int Parser_commands(void); /* Start the command parser */ --void Parser_qhelp(int, char **); /* Quick help routine */ --int Parser_help(int, char **); /* Detailed help routine */ --void Parser_ignore_errors(int ignore); /* Set the ignore errors flag */ --void Parser_printhelp(char *); /* Detailed help routine */ --void Parser_exit(int, char **); /* Shuts down command parser */ --int Parser_execarg(int argc, char **argv, command_t cmds[]); --int execute_line(char * line); -- --/* Converts a string to an integer */ --int Parser_int(char *, int *); -- --/* Prompts for a string, with default values and a maximum length */ --char *Parser_getstr(const char *prompt, const char *deft, char *res, -- size_t len); -- --/* Prompts for an integer, with minimum, maximum and default values and base */ --int Parser_getint(const char *prompt, long min, long max, long deft, -- int base); -- --/* Prompts for a yes/no, with default */ --int Parser_getbool(const char *prompt, int deft); -- --/* Extracts an integer from a string, or prompts if it cannot get one */ --long Parser_intarg(const char *inp, const char *prompt, int deft, -- int min, int max, int base); -- --/* Extracts a word from the input, or propmts if it cannot get one */ --char *Parser_strarg(char *inp, const char *prompt, const char *deft, -- char *answer, int len); -- --/* Extracts an integer from a string with a base */ --int Parser_arg2int(const char *inp, long *result, int base); -- --/* Convert human readable size string to and int; "1k" -> 1000 */ --int Parser_size(int *sizep, char *str); -- --/* Convert a string boolean to an int; "enable" -> 1 */ --int Parser_bool(int *b, char *str); -- --#endif