diff --git a/.gitmodules b/.gitmodules
index 630c2424..dfd4259b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "redpill-lkm"]
path = redpill-lkm
url = git@github.com:fbelavenuto/redpill-lkm.git
+[submodule "addons"]
+ path = addons
+ url = git@github.com:fbelavenuto/arpl-addons.git
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..f288702d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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)
+
+ 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 3 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, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/addons b/addons
new file mode 160000
index 00000000..a82e40e2
--- /dev/null
+++ b/addons
@@ -0,0 +1 @@
+Subproject commit a82e40e27cc829d30a3f6ce216444da1d7e0d030
diff --git a/addons/9p/install.sh b/addons/9p/install.sh
deleted file mode 100644
index a8d42d95..00000000
--- a/addons/9p/install.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ "${1}" = "rd" ]; then
- echo "Installing module for Plan 9 Resource Sharing Support (9P2000)"
- ${INSMOD} "/modules/9pnet.ko"
- ${INSMOD} "/modules/9pnet_virtio.ko"
- ${INSMOD} "/modules/9p.ko" ${PARAMS}
-fi
diff --git a/addons/9p/manifest.yml b/addons/9p/manifest.yml
deleted file mode 100644
index cd4c5807..00000000
--- a/addons/9p/manifest.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-version: 1
-name: 9p
-description: "Driver for Plan 9 Resource Sharing Support (9P2000)"
-available-for:
- bromolow-3.10.108:
- install-script: &script "install.sh"
- modules: true
- apollolake-4.4.180:
- install-script: *script
- modules: true
- broadwell-4.4.180:
- install-script: *script
- modules: true
- broadwellnk-4.4.180:
- install-script: *script
- modules: true
- denverton-4.4.180:
- install-script: *script
- modules: true
- geminilake-4.4.180:
- install-script: *script
- modules: true
- v1000-4.4.180:
- install-script: *script
- modules: true
- purley-4.4.180:
- install-script: *script
- modules: true
diff --git a/addons/9p/src/3.10.108/Makefile b/addons/9p/src/3.10.108/Makefile
deleted file mode 100644
index 0d269d65..00000000
--- a/addons/9p/src/3.10.108/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-obj-m := 9p.o
-
-9p-objs := \
- vfs_super.o \
- vfs_inode.o \
- vfs_inode_dotl.o \
- vfs_addr.o \
- vfs_file.o \
- vfs_dir.o \
- vfs_dentry.o \
- v9fs.o \
- fid.o \
- xattr.o \
- xattr_user.o
-
-9p-y += cache.o
-9p-n += acl.o
-
-obj-m := 9pnet.o
-obj-m += 9pnet_virtio.o
-obj-n += 9pnet_rdma.o
-
-9pnet-objs := \
- mod.o \
- client.o \
- error.o \
- util.o \
- protocol.o \
- trans_fd.o \
- trans_common.o \
-
-9pnet_virtio-objs := \
- trans_virtio.o
-
-9pnet_rdma-objs := \
- trans_rdma.o
diff --git a/addons/9p/src/3.10.108/acl.c b/addons/9p/src/3.10.108/acl.c
deleted file mode 100644
index 9686c1f1..00000000
--- a/addons/9p/src/3.10.108/acl.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "xattr.h"
-#include "acl.h"
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "fid.h"
-
-static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
-{
- ssize_t size;
- void *value = NULL;
- struct posix_acl *acl = NULL;
-
- size = v9fs_fid_xattr_get(fid, name, NULL, 0);
- if (size > 0) {
- value = kzalloc(size, GFP_NOFS);
- if (!value)
- return ERR_PTR(-ENOMEM);
- size = v9fs_fid_xattr_get(fid, name, value, size);
- if (size > 0) {
- acl = posix_acl_from_xattr(&init_user_ns, value, size);
- if (IS_ERR(acl))
- goto err_out;
- }
- } else if (size == -ENODATA || size == 0 ||
- size == -ENOSYS || size == -EOPNOTSUPP) {
- acl = NULL;
- } else
- acl = ERR_PTR(-EIO);
-
-err_out:
- kfree(value);
- return acl;
-}
-
-int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
-{
- int retval = 0;
- struct posix_acl *pacl, *dacl;
- struct v9fs_session_info *v9ses;
-
- v9ses = v9fs_inode2v9ses(inode);
- if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
- ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
- set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL);
- set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
- return 0;
- }
- /* get the default/access acl values and cache them */
- dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT);
- pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS);
-
- if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
- set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
- set_cached_acl(inode, ACL_TYPE_ACCESS, pacl);
- } else
- retval = -EIO;
-
- if (!IS_ERR(dacl))
- posix_acl_release(dacl);
-
- if (!IS_ERR(pacl))
- posix_acl_release(pacl);
-
- return retval;
-}
-
-static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
-{
- struct posix_acl *acl;
- /*
- * 9p Always cache the acl value when
- * instantiating the inode (v9fs_inode_from_fid)
- */
- acl = get_cached_acl(inode, type);
- BUG_ON(acl == ACL_NOT_CACHED);
- return acl;
-}
-
-struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type)
-{
- struct v9fs_session_info *v9ses;
-
- v9ses = v9fs_inode2v9ses(inode);
- if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
- ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
- /*
- * On access = client and acl = on mode get the acl
- * values from the server
- */
- return NULL;
- }
- return v9fs_get_cached_acl(inode, type);
-
-}
-
-static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
-{
- int retval;
- char *name;
- size_t size;
- void *buffer;
- if (!acl)
- return 0;
-
- /* Set a setxattr request to server */
- size = posix_acl_xattr_size(acl->a_count);
- buffer = kmalloc(size, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
- retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
- if (retval < 0)
- goto err_free_out;
- switch (type) {
- case ACL_TYPE_ACCESS:
- name = POSIX_ACL_XATTR_ACCESS;
- break;
- case ACL_TYPE_DEFAULT:
- name = POSIX_ACL_XATTR_DEFAULT;
- break;
- default:
- BUG();
- }
- retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
-err_free_out:
- kfree(buffer);
- return retval;
-}
-
-int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
-{
- int retval = 0;
- struct posix_acl *acl;
-
- if (S_ISLNK(inode->i_mode))
- return -EOPNOTSUPP;
- acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
- if (acl) {
- retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
- if (retval)
- return retval;
- set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
- retval = v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
- posix_acl_release(acl);
- }
- return retval;
-}
-
-int v9fs_set_create_acl(struct inode *inode, struct p9_fid *fid,
- struct posix_acl *dacl, struct posix_acl *acl)
-{
- set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
- set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
- v9fs_set_acl(fid, ACL_TYPE_DEFAULT, dacl);
- v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
- return 0;
-}
-
-void v9fs_put_acl(struct posix_acl *dacl,
- struct posix_acl *acl)
-{
- posix_acl_release(dacl);
- posix_acl_release(acl);
-}
-
-int v9fs_acl_mode(struct inode *dir, umode_t *modep,
- struct posix_acl **dpacl, struct posix_acl **pacl)
-{
- int retval = 0;
- umode_t mode = *modep;
- struct posix_acl *acl = NULL;
-
- if (!S_ISLNK(mode)) {
- acl = v9fs_get_cached_acl(dir, ACL_TYPE_DEFAULT);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- if (!acl)
- mode &= ~current_umask();
- }
- if (acl) {
- if (S_ISDIR(mode))
- *dpacl = posix_acl_dup(acl);
- retval = posix_acl_create(&acl, GFP_NOFS, &mode);
- if (retval < 0)
- return retval;
- if (retval > 0)
- *pacl = acl;
- else
- posix_acl_release(acl);
- }
- *modep = mode;
- return 0;
-}
-
-static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
- void *buffer, size_t size, int type)
-{
- char *full_name;
-
- switch (type) {
- case ACL_TYPE_ACCESS:
- full_name = POSIX_ACL_XATTR_ACCESS;
- break;
- case ACL_TYPE_DEFAULT:
- full_name = POSIX_ACL_XATTR_DEFAULT;
- break;
- default:
- BUG();
- }
- return v9fs_xattr_get(dentry, full_name, buffer, size);
-}
-
-static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
- void *buffer, size_t size, int type)
-{
- struct v9fs_session_info *v9ses;
- struct posix_acl *acl;
- int error;
-
- if (strcmp(name, "") != 0)
- return -EINVAL;
-
- v9ses = v9fs_dentry2v9ses(dentry);
- /*
- * We allow set/get/list of acl when access=client is not specified
- */
- if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
- return v9fs_remote_get_acl(dentry, name, buffer, size, type);
-
- acl = v9fs_get_cached_acl(dentry->d_inode, type);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- if (acl == NULL)
- return -ENODATA;
- error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
- posix_acl_release(acl);
-
- return error;
-}
-
-static int v9fs_remote_set_acl(struct dentry *dentry, const char *name,
- const void *value, size_t size,
- int flags, int type)
-{
- char *full_name;
-
- switch (type) {
- case ACL_TYPE_ACCESS:
- full_name = POSIX_ACL_XATTR_ACCESS;
- break;
- case ACL_TYPE_DEFAULT:
- full_name = POSIX_ACL_XATTR_DEFAULT;
- break;
- default:
- BUG();
- }
- return v9fs_xattr_set(dentry, full_name, value, size, flags);
-}
-
-
-static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
- const void *value, size_t size,
- int flags, int type)
-{
- int retval;
- struct posix_acl *acl;
- struct v9fs_session_info *v9ses;
- struct inode *inode = dentry->d_inode;
-
- if (strcmp(name, "") != 0)
- return -EINVAL;
-
- v9ses = v9fs_dentry2v9ses(dentry);
- /*
- * set the attribute on the remote. Without even looking at the
- * xattr value. We leave it to the server to validate
- */
- if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
- return v9fs_remote_set_acl(dentry, name,
- value, size, flags, type);
-
- if (S_ISLNK(inode->i_mode))
- return -EOPNOTSUPP;
- if (!inode_owner_or_capable(inode))
- return -EPERM;
- if (value) {
- /* update the cached acl value */
- acl = posix_acl_from_xattr(&init_user_ns, value, size);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- else if (acl) {
- retval = posix_acl_valid(acl);
- if (retval)
- goto err_out;
- }
- } else
- acl = NULL;
-
- switch (type) {
- case ACL_TYPE_ACCESS:
- name = POSIX_ACL_XATTR_ACCESS;
- if (acl) {
- struct iattr iattr;
-
- retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
- if (retval)
- goto err_out;
- if (!acl) {
- /*
- * ACL can be represented
- * by the mode bits. So don't
- * update ACL.
- */
- value = NULL;
- size = 0;
- }
- iattr.ia_valid = ATTR_MODE;
- /* FIXME should we update ctime ?
- * What is the following setxattr update the
- * mode ?
- */
- v9fs_vfs_setattr_dotl(dentry, &iattr);
- }
- break;
- case ACL_TYPE_DEFAULT:
- name = POSIX_ACL_XATTR_DEFAULT;
- if (!S_ISDIR(inode->i_mode)) {
- retval = acl ? -EINVAL : 0;
- goto err_out;
- }
- break;
- default:
- BUG();
- }
- retval = v9fs_xattr_set(dentry, name, value, size, flags);
- if (!retval)
- set_cached_acl(inode, type, acl);
-err_out:
- posix_acl_release(acl);
- return retval;
-}
-
-const struct xattr_handler v9fs_xattr_acl_access_handler = {
- .prefix = POSIX_ACL_XATTR_ACCESS,
- .flags = ACL_TYPE_ACCESS,
- .get = v9fs_xattr_get_acl,
- .set = v9fs_xattr_set_acl,
-};
-
-const struct xattr_handler v9fs_xattr_acl_default_handler = {
- .prefix = POSIX_ACL_XATTR_DEFAULT,
- .flags = ACL_TYPE_DEFAULT,
- .get = v9fs_xattr_get_acl,
- .set = v9fs_xattr_set_acl,
-};
diff --git a/addons/9p/src/3.10.108/acl.h b/addons/9p/src/3.10.108/acl.h
deleted file mode 100644
index e4f7e882..00000000
--- a/addons/9p/src/3.10.108/acl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-#ifndef FS_9P_ACL_H
-#define FS_9P_ACL_H
-
-#ifdef CONFIG_9P_FS_POSIX_ACL
-extern int v9fs_get_acl(struct inode *, struct p9_fid *);
-extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
-extern int v9fs_acl_chmod(struct inode *, struct p9_fid *);
-extern int v9fs_set_create_acl(struct inode *, struct p9_fid *,
- struct posix_acl *, struct posix_acl *);
-extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
- struct posix_acl **dpacl, struct posix_acl **pacl);
-extern void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
-#else
-#define v9fs_iop_get_acl NULL
-static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
-{
- return 0;
-}
-static inline int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
-{
- return 0;
-}
-static inline int v9fs_set_create_acl(struct inode *inode,
- struct p9_fid *fid,
- struct posix_acl *dacl,
- struct posix_acl *acl)
-{
- return 0;
-}
-static inline void v9fs_put_acl(struct posix_acl *dacl,
- struct posix_acl *acl)
-{
-}
-static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep,
- struct posix_acl **dpacl,
- struct posix_acl **pacl)
-{
- return 0;
-}
-
-#endif
-#endif /* FS_9P_XATTR_H */
diff --git a/addons/9p/src/3.10.108/cache.c b/addons/9p/src/3.10.108/cache.c
deleted file mode 100644
index a9ea73d6..00000000
--- a/addons/9p/src/3.10.108/cache.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * V9FS cache definitions.
- *
- * Copyright (C) 2009 by Abhishek Kulkarni
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "v9fs.h"
-#include "cache.h"
-
-#define CACHETAG_LEN 11
-
-struct fscache_netfs v9fs_cache_netfs = {
- .name = "9p",
- .version = 0,
-};
-
-/**
- * v9fs_random_cachetag - Generate a random tag to be associated
- * with a new cache session.
- *
- * The value of jiffies is used for a fairly randomly cache tag.
- */
-
-static
-int v9fs_random_cachetag(struct v9fs_session_info *v9ses)
-{
- v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL);
- if (!v9ses->cachetag)
- return -ENOMEM;
-
- return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies);
-}
-
-static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data,
- void *buffer, uint16_t bufmax)
-{
- struct v9fs_session_info *v9ses;
- uint16_t klen = 0;
-
- v9ses = (struct v9fs_session_info *)cookie_netfs_data;
- p9_debug(P9_DEBUG_FSC, "session %p buf %p size %u\n",
- v9ses, buffer, bufmax);
-
- if (v9ses->cachetag)
- klen = strlen(v9ses->cachetag);
-
- if (klen > bufmax)
- return 0;
-
- memcpy(buffer, v9ses->cachetag, klen);
- p9_debug(P9_DEBUG_FSC, "cache session tag %s\n", v9ses->cachetag);
- return klen;
-}
-
-const struct fscache_cookie_def v9fs_cache_session_index_def = {
- .name = "9P.session",
- .type = FSCACHE_COOKIE_TYPE_INDEX,
- .get_key = v9fs_cache_session_get_key,
-};
-
-void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
-{
- /* If no cache session tag was specified, we generate a random one. */
- if (!v9ses->cachetag)
- v9fs_random_cachetag(v9ses);
-
- v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
- &v9fs_cache_session_index_def,
- v9ses);
- p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
- v9ses, v9ses->fscache);
-}
-
-void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
-{
- p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n",
- v9ses, v9ses->fscache);
- fscache_relinquish_cookie(v9ses->fscache, 0);
- v9ses->fscache = NULL;
-}
-
-
-static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
- void *buffer, uint16_t bufmax)
-{
- const struct v9fs_inode *v9inode = cookie_netfs_data;
- memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
- p9_debug(P9_DEBUG_FSC, "inode %p get key %llu\n",
- &v9inode->vfs_inode, v9inode->qid.path);
- return sizeof(v9inode->qid.path);
-}
-
-static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
- uint64_t *size)
-{
- const struct v9fs_inode *v9inode = cookie_netfs_data;
- *size = i_size_read(&v9inode->vfs_inode);
-
- p9_debug(P9_DEBUG_FSC, "inode %p get attr %llu\n",
- &v9inode->vfs_inode, *size);
-}
-
-static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
- void *buffer, uint16_t buflen)
-{
- const struct v9fs_inode *v9inode = cookie_netfs_data;
- memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
- p9_debug(P9_DEBUG_FSC, "inode %p get aux %u\n",
- &v9inode->vfs_inode, v9inode->qid.version);
- return sizeof(v9inode->qid.version);
-}
-
-static enum
-fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
- const void *buffer,
- uint16_t buflen)
-{
- const struct v9fs_inode *v9inode = cookie_netfs_data;
-
- if (buflen != sizeof(v9inode->qid.version))
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- if (memcmp(buffer, &v9inode->qid.version,
- sizeof(v9inode->qid.version)))
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- return FSCACHE_CHECKAUX_OKAY;
-}
-
-static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
-{
- struct v9fs_inode *v9inode = cookie_netfs_data;
- struct pagevec pvec;
- pgoff_t first;
- int loop, nr_pages;
-
- pagevec_init(&pvec, 0);
- first = 0;
-
- for (;;) {
- nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping,
- first,
- PAGEVEC_SIZE - pagevec_count(&pvec));
- if (!nr_pages)
- break;
-
- for (loop = 0; loop < nr_pages; loop++)
- ClearPageFsCache(pvec.pages[loop]);
-
- first = pvec.pages[nr_pages - 1]->index + 1;
-
- pvec.nr = nr_pages;
- pagevec_release(&pvec);
- cond_resched();
- }
-}
-
-const struct fscache_cookie_def v9fs_cache_inode_index_def = {
- .name = "9p.inode",
- .type = FSCACHE_COOKIE_TYPE_DATAFILE,
- .get_key = v9fs_cache_inode_get_key,
- .get_attr = v9fs_cache_inode_get_attr,
- .get_aux = v9fs_cache_inode_get_aux,
- .check_aux = v9fs_cache_inode_check_aux,
- .now_uncached = v9fs_cache_inode_now_uncached,
-};
-
-void v9fs_cache_inode_get_cookie(struct inode *inode)
-{
- struct v9fs_inode *v9inode;
- struct v9fs_session_info *v9ses;
-
- if (!S_ISREG(inode->i_mode))
- return;
-
- v9inode = V9FS_I(inode);
- if (v9inode->fscache)
- return;
-
- v9ses = v9fs_inode2v9ses(inode);
- v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
- &v9fs_cache_inode_index_def,
- v9inode);
-
- p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
- inode, v9inode->fscache);
-}
-
-void v9fs_cache_inode_put_cookie(struct inode *inode)
-{
- struct v9fs_inode *v9inode = V9FS_I(inode);
-
- if (!v9inode->fscache)
- return;
- p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n",
- inode, v9inode->fscache);
-
- fscache_relinquish_cookie(v9inode->fscache, 0);
- v9inode->fscache = NULL;
-}
-
-void v9fs_cache_inode_flush_cookie(struct inode *inode)
-{
- struct v9fs_inode *v9inode = V9FS_I(inode);
-
- if (!v9inode->fscache)
- return;
- p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n",
- inode, v9inode->fscache);
-
- fscache_relinquish_cookie(v9inode->fscache, 1);
- v9inode->fscache = NULL;
-}
-
-void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
-{
- struct v9fs_inode *v9inode = V9FS_I(inode);
- struct p9_fid *fid;
-
- if (!v9inode->fscache)
- return;
-
- spin_lock(&v9inode->fscache_lock);
- fid = filp->private_data;
- if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
- v9fs_cache_inode_flush_cookie(inode);
- else
- v9fs_cache_inode_get_cookie(inode);
-
- spin_unlock(&v9inode->fscache_lock);
-}
-
-void v9fs_cache_inode_reset_cookie(struct inode *inode)
-{
- struct v9fs_inode *v9inode = V9FS_I(inode);
- struct v9fs_session_info *v9ses;
- struct fscache_cookie *old;
-
- if (!v9inode->fscache)
- return;
-
- old = v9inode->fscache;
-
- spin_lock(&v9inode->fscache_lock);
- fscache_relinquish_cookie(v9inode->fscache, 1);
-
- v9ses = v9fs_inode2v9ses(inode);
- v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
- &v9fs_cache_inode_index_def,
- v9inode);
- p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
- inode, old, v9inode->fscache);
-
- spin_unlock(&v9inode->fscache_lock);
-}
-
-int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
-{
- struct inode *inode = page->mapping->host;
- struct v9fs_inode *v9inode = V9FS_I(inode);
-
- BUG_ON(!v9inode->fscache);
-
- return fscache_maybe_release_page(v9inode->fscache, page, gfp);
-}
-
-void __v9fs_fscache_invalidate_page(struct page *page)
-{
- struct inode *inode = page->mapping->host;
- struct v9fs_inode *v9inode = V9FS_I(inode);
-
- BUG_ON(!v9inode->fscache);
-
- if (PageFsCache(page)) {
- fscache_wait_on_page_write(v9inode->fscache, page);
- BUG_ON(!PageLocked(page));
- fscache_uncache_page(v9inode->fscache, page);
- }
-}
-
-static void v9fs_vfs_readpage_complete(struct page *page, void *data,
- int error)
-{
- if (!error)
- SetPageUptodate(page);
-
- unlock_page(page);
-}
-
-/**
- * __v9fs_readpage_from_fscache - read a page from cache
- *
- * Returns 0 if the pages are in cache and a BIO is submitted,
- * 1 if the pages are not in cache and -error otherwise.
- */
-
-int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
-{
- int ret;
- const struct v9fs_inode *v9inode = V9FS_I(inode);
-
- p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
- if (!v9inode->fscache)
- return -ENOBUFS;
-
- ret = fscache_read_or_alloc_page(v9inode->fscache,
- page,
- v9fs_vfs_readpage_complete,
- NULL,
- GFP_KERNEL);
- switch (ret) {
- case -ENOBUFS:
- case -ENODATA:
- p9_debug(P9_DEBUG_FSC, "page/inode not in cache %d\n", ret);
- return 1;
- case 0:
- p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
- return ret;
- default:
- p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
- return ret;
- }
-}
-
-/**
- * __v9fs_readpages_from_fscache - read multiple pages from cache
- *
- * Returns 0 if the pages are in cache and a BIO is submitted,
- * 1 if the pages are not in cache and -error otherwise.
- */
-
-int __v9fs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- int ret;
- const struct v9fs_inode *v9inode = V9FS_I(inode);
-
- p9_debug(P9_DEBUG_FSC, "inode %p pages %u\n", inode, *nr_pages);
- if (!v9inode->fscache)
- return -ENOBUFS;
-
- ret = fscache_read_or_alloc_pages(v9inode->fscache,
- mapping, pages, nr_pages,
- v9fs_vfs_readpage_complete,
- NULL,
- mapping_gfp_mask(mapping));
- switch (ret) {
- case -ENOBUFS:
- case -ENODATA:
- p9_debug(P9_DEBUG_FSC, "pages/inodes not in cache %d\n", ret);
- return 1;
- case 0:
- BUG_ON(!list_empty(pages));
- BUG_ON(*nr_pages != 0);
- p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
- return ret;
- default:
- p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
- return ret;
- }
-}
-
-/**
- * __v9fs_readpage_to_fscache - write a page to the cache
- *
- */
-
-void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
-{
- int ret;
- const struct v9fs_inode *v9inode = V9FS_I(inode);
-
- p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
- ret = fscache_write_page(v9inode->fscache, page, GFP_KERNEL);
- p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
- if (ret != 0)
- v9fs_uncache_page(inode, page);
-}
-
-/*
- * wait for a page to complete writing to the cache
- */
-void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
-{
- const struct v9fs_inode *v9inode = V9FS_I(inode);
- p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
- if (PageFsCache(page))
- fscache_wait_on_page_write(v9inode->fscache, page);
-}
diff --git a/addons/9p/src/3.10.108/cache.h b/addons/9p/src/3.10.108/cache.h
deleted file mode 100644
index 40cc54ce..00000000
--- a/addons/9p/src/3.10.108/cache.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * V9FS cache definitions.
- *
- * Copyright (C) 2009 by Abhishek Kulkarni
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#ifndef _9P_CACHE_H
-#ifdef CONFIG_9P_FSCACHE
-#include
-#include
-
-extern struct fscache_netfs v9fs_cache_netfs;
-extern const struct fscache_cookie_def v9fs_cache_session_index_def;
-extern const struct fscache_cookie_def v9fs_cache_inode_index_def;
-
-extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses);
-extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses);
-
-extern void v9fs_cache_inode_get_cookie(struct inode *inode);
-extern void v9fs_cache_inode_put_cookie(struct inode *inode);
-extern void v9fs_cache_inode_flush_cookie(struct inode *inode);
-extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp);
-extern void v9fs_cache_inode_reset_cookie(struct inode *inode);
-
-extern int __v9fs_cache_register(void);
-extern void __v9fs_cache_unregister(void);
-
-extern int __v9fs_fscache_release_page(struct page *page, gfp_t gfp);
-extern void __v9fs_fscache_invalidate_page(struct page *page);
-extern int __v9fs_readpage_from_fscache(struct inode *inode,
- struct page *page);
-extern int __v9fs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages);
-extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page);
-extern void __v9fs_fscache_wait_on_page_write(struct inode *inode,
- struct page *page);
-
-static inline int v9fs_fscache_release_page(struct page *page,
- gfp_t gfp)
-{
- return __v9fs_fscache_release_page(page, gfp);
-}
-
-static inline void v9fs_fscache_invalidate_page(struct page *page)
-{
- __v9fs_fscache_invalidate_page(page);
-}
-
-static inline int v9fs_readpage_from_fscache(struct inode *inode,
- struct page *page)
-{
- return __v9fs_readpage_from_fscache(inode, page);
-}
-
-static inline int v9fs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- return __v9fs_readpages_from_fscache(inode, mapping, pages,
- nr_pages);
-}
-
-static inline void v9fs_readpage_to_fscache(struct inode *inode,
- struct page *page)
-{
- if (PageFsCache(page))
- __v9fs_readpage_to_fscache(inode, page);
-}
-
-static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
-{
- struct v9fs_inode *v9inode = V9FS_I(inode);
- fscache_uncache_page(v9inode->fscache, page);
- BUG_ON(PageFsCache(page));
-}
-
-static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
- struct page *page)
-{
- return __v9fs_fscache_wait_on_page_write(inode, page);
-}
-
-#else /* CONFIG_9P_FSCACHE */
-
-static inline int v9fs_fscache_release_page(struct page *page,
- gfp_t gfp) {
- return 1;
-}
-
-static inline void v9fs_fscache_invalidate_page(struct page *page) {}
-
-static inline int v9fs_readpage_from_fscache(struct inode *inode,
- struct page *page)
-{
- return -ENOBUFS;
-}
-
-static inline int v9fs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- return -ENOBUFS;
-}
-
-static inline void v9fs_readpage_to_fscache(struct inode *inode,
- struct page *page)
-{}
-
-static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
-{}
-
-static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
- struct page *page)
-{
- return;
-}
-
-#endif /* CONFIG_9P_FSCACHE */
-#endif /* _9P_CACHE_H */
diff --git a/addons/9p/src/3.10.108/client.c b/addons/9p/src/3.10.108/client.c
deleted file mode 100644
index e191aab9..00000000
--- a/addons/9p/src/3.10.108/client.c
+++ /dev/null
@@ -1,2256 +0,0 @@
-/*
- * net/9p/clnt.c
- *
- * 9P Client
- *
- * Copyright (C) 2008 by Eric Van Hensbergen
- * Copyright (C) 2007 by Latchesar Ionkov
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "protocol.h"
-
-#define CREATE_TRACE_POINTS
-#include
-
-/*
- * Client Option Parsing (code inspired by NFS code)
- * - a little lazy - parse all client options
- */
-
-enum {
- Opt_msize,
- Opt_trans,
- Opt_legacy,
- Opt_version,
- Opt_err,
-};
-
-static const match_table_t tokens = {
- {Opt_msize, "msize=%u"},
- {Opt_legacy, "noextend"},
- {Opt_trans, "trans=%s"},
- {Opt_version, "version=%s"},
- {Opt_err, NULL},
-};
-
-inline int p9_is_proto_dotl(struct p9_client *clnt)
-{
- return clnt->proto_version == p9_proto_2000L;
-}
-EXPORT_SYMBOL(p9_is_proto_dotl);
-
-inline int p9_is_proto_dotu(struct p9_client *clnt)
-{
- return clnt->proto_version == p9_proto_2000u;
-}
-EXPORT_SYMBOL(p9_is_proto_dotu);
-
-/*
- * Some error codes are taken directly from the server replies,
- * make sure they are valid.
- */
-static int safe_errno(int err)
-{
- if ((err > 0) || (err < -MAX_ERRNO)) {
- p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
- return -EPROTO;
- }
- return err;
-}
-
-
-/* Interpret mount option for protocol version */
-static int get_protocol_version(char *s)
-{
- int version = -EINVAL;
-
- if (!strcmp(s, "9p2000")) {
- version = p9_proto_legacy;
- p9_debug(P9_DEBUG_9P, "Protocol version: Legacy\n");
- } else if (!strcmp(s, "9p2000.u")) {
- version = p9_proto_2000u;
- p9_debug(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
- } else if (!strcmp(s, "9p2000.L")) {
- version = p9_proto_2000L;
- p9_debug(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
- } else
- pr_info("Unknown protocol version %s\n", s);
-
- return version;
-}
-
-/**
- * parse_options - parse mount options into client structure
- * @opts: options string passed from mount
- * @clnt: existing v9fs client information
- *
- * Return 0 upon success, -ERRNO upon failure
- */
-
-static int parse_opts(char *opts, struct p9_client *clnt)
-{
- char *options, *tmp_options;
- char *p;
- substring_t args[MAX_OPT_ARGS];
- int option;
- char *s;
- int ret = 0;
-
- clnt->proto_version = p9_proto_2000u;
- clnt->msize = 8192;
-
- if (!opts)
- return 0;
-
- tmp_options = kstrdup(opts, GFP_KERNEL);
- if (!tmp_options) {
- p9_debug(P9_DEBUG_ERROR,
- "failed to allocate copy of option string\n");
- return -ENOMEM;
- }
- options = tmp_options;
-
- while ((p = strsep(&options, ",")) != NULL) {
- int token, r;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
- switch (token) {
- case Opt_msize:
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
- }
- clnt->msize = option;
- break;
- case Opt_trans:
- s = match_strdup(&args[0]);
- if (!s) {
- ret = -ENOMEM;
- p9_debug(P9_DEBUG_ERROR,
- "problem allocating copy of trans arg\n");
- goto free_and_return;
- }
- clnt->trans_mod = v9fs_get_trans_by_name(s);
- if (clnt->trans_mod == NULL) {
- pr_info("Could not find request transport: %s\n",
- s);
- ret = -EINVAL;
- kfree(s);
- goto free_and_return;
- }
- kfree(s);
- break;
- case Opt_legacy:
- clnt->proto_version = p9_proto_legacy;
- break;
- case Opt_version:
- s = match_strdup(&args[0]);
- if (!s) {
- ret = -ENOMEM;
- p9_debug(P9_DEBUG_ERROR,
- "problem allocating copy of version arg\n");
- goto free_and_return;
- }
- ret = get_protocol_version(s);
- if (ret == -EINVAL) {
- kfree(s);
- goto free_and_return;
- }
- kfree(s);
- clnt->proto_version = ret;
- break;
- default:
- continue;
- }
- }
-
-free_and_return:
- kfree(tmp_options);
- return ret;
-}
-
-/**
- * p9_tag_alloc - lookup/allocate a request by tag
- * @c: client session to lookup tag within
- * @tag: numeric id for transaction
- *
- * this is a simple array lookup, but will grow the
- * request_slots as necessary to accommodate transaction
- * ids which did not previously have a slot.
- *
- * this code relies on the client spinlock to manage locks, its
- * possible we should switch to something else, but I'd rather
- * stick with something low-overhead for the common case.
- *
- */
-
-static struct p9_req_t *
-p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
-{
- unsigned long flags;
- int row, col;
- struct p9_req_t *req;
- int alloc_msize = min(c->msize, max_size);
-
- /* This looks up the original request by tag so we know which
- * buffer to read the data into */
- tag++;
-
- if (tag >= c->max_tag) {
- spin_lock_irqsave(&c->lock, flags);
- /* check again since original check was outside of lock */
- while (tag >= c->max_tag) {
- row = (tag / P9_ROW_MAXTAG);
- c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
- sizeof(struct p9_req_t), GFP_ATOMIC);
-
- if (!c->reqs[row]) {
- pr_err("Couldn't grow tag array\n");
- spin_unlock_irqrestore(&c->lock, flags);
- return ERR_PTR(-ENOMEM);
- }
- for (col = 0; col < P9_ROW_MAXTAG; col++) {
- c->reqs[row][col].status = REQ_STATUS_IDLE;
- c->reqs[row][col].tc = NULL;
- }
- c->max_tag += P9_ROW_MAXTAG;
- }
- spin_unlock_irqrestore(&c->lock, flags);
- }
- row = tag / P9_ROW_MAXTAG;
- col = tag % P9_ROW_MAXTAG;
-
- req = &c->reqs[row][col];
- if (!req->tc) {
- req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS);
- if (!req->wq) {
- pr_err("Couldn't grow tag array\n");
- return ERR_PTR(-ENOMEM);
- }
- init_waitqueue_head(req->wq);
- req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
- GFP_NOFS);
- req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
- GFP_NOFS);
- if ((!req->tc) || (!req->rc)) {
- pr_err("Couldn't grow tag array\n");
- kfree(req->tc);
- kfree(req->rc);
- kfree(req->wq);
- req->tc = req->rc = NULL;
- req->wq = NULL;
- return ERR_PTR(-ENOMEM);
- }
- req->tc->capacity = alloc_msize;
- req->rc->capacity = alloc_msize;
- req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
- req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
- }
-
- p9pdu_reset(req->tc);
- p9pdu_reset(req->rc);
-
- req->tc->tag = tag-1;
- req->status = REQ_STATUS_ALLOC;
-
- return &c->reqs[row][col];
-}
-
-/**
- * p9_tag_lookup - lookup a request by tag
- * @c: client session to lookup tag within
- * @tag: numeric id for transaction
- *
- */
-
-struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
-{
- int row, col;
-
- /* This looks up the original request by tag so we know which
- * buffer to read the data into */
- tag++;
-
- if(tag >= c->max_tag)
- return NULL;
-
- row = tag / P9_ROW_MAXTAG;
- col = tag % P9_ROW_MAXTAG;
-
- return &c->reqs[row][col];
-}
-EXPORT_SYMBOL(p9_tag_lookup);
-
-/**
- * p9_tag_init - setup tags structure and contents
- * @c: v9fs client struct
- *
- * This initializes the tags structure for each client instance.
- *
- */
-
-static int p9_tag_init(struct p9_client *c)
-{
- int err = 0;
-
- c->tagpool = p9_idpool_create();
- if (IS_ERR(c->tagpool)) {
- err = PTR_ERR(c->tagpool);
- goto error;
- }
- err = p9_idpool_get(c->tagpool); /* reserve tag 0 */
- if (err < 0) {
- p9_idpool_destroy(c->tagpool);
- goto error;
- }
- c->max_tag = 0;
-error:
- return err;
-}
-
-/**
- * p9_tag_cleanup - cleans up tags structure and reclaims resources
- * @c: v9fs client struct
- *
- * This frees resources associated with the tags structure
- *
- */
-static void p9_tag_cleanup(struct p9_client *c)
-{
- int row, col;
-
- /* check to insure all requests are idle */
- for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
- for (col = 0; col < P9_ROW_MAXTAG; col++) {
- if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
- p9_debug(P9_DEBUG_MUX,
- "Attempting to cleanup non-free tag %d,%d\n",
- row, col);
- /* TODO: delay execution of cleanup */
- return;
- }
- }
- }
-
- if (c->tagpool) {
- p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
- p9_idpool_destroy(c->tagpool);
- }
-
- /* free requests associated with tags */
- for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
- for (col = 0; col < P9_ROW_MAXTAG; col++) {
- kfree(c->reqs[row][col].wq);
- kfree(c->reqs[row][col].tc);
- kfree(c->reqs[row][col].rc);
- }
- kfree(c->reqs[row]);
- }
- c->max_tag = 0;
-}
-
-/**
- * p9_free_req - free a request and clean-up as necessary
- * c: client state
- * r: request to release
- *
- */
-
-static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
-{
- int tag = r->tc->tag;
- p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
-
- r->status = REQ_STATUS_IDLE;
- if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
- p9_idpool_put(tag, c->tagpool);
-}
-
-/**
- * p9_client_cb - call back from transport to client
- * c: client state
- * req: request received
- *
- */
-void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
-{
- p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
- wake_up(req->wq);
- p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
-}
-EXPORT_SYMBOL(p9_client_cb);
-
-/**
- * p9_parse_header - parse header arguments out of a packet
- * @pdu: packet to parse
- * @size: size of packet
- * @type: type of request
- * @tag: tag of packet
- * @rewind: set if we need to rewind offset afterwards
- */
-
-int
-p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
- int rewind)
-{
- int8_t r_type;
- int16_t r_tag;
- int32_t r_size;
- int offset = pdu->offset;
- int err;
-
- pdu->offset = 0;
- if (pdu->size == 0)
- pdu->size = 7;
-
- err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
- if (err)
- goto rewind_and_exit;
-
- pdu->size = r_size;
- pdu->id = r_type;
- pdu->tag = r_tag;
-
- p9_debug(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n",
- pdu->size, pdu->id, pdu->tag);
-
- if (type)
- *type = r_type;
- if (tag)
- *tag = r_tag;
- if (size)
- *size = r_size;
-
-
-rewind_and_exit:
- if (rewind)
- pdu->offset = offset;
- return err;
-}
-EXPORT_SYMBOL(p9_parse_header);
-
-/**
- * p9_check_errors - check 9p packet for error return and process it
- * @c: current client instance
- * @req: request to parse and check for error conditions
- *
- * returns error code if one is discovered, otherwise returns 0
- *
- * this will have to be more complicated if we have multiple
- * error packet types
- */
-
-static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
-{
- int8_t type;
- int err;
- int ecode;
-
- err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
- /*
- * dump the response from server
- * This should be after check errors which poplulate pdu_fcall.
- */
- trace_9p_protocol_dump(c, req->rc);
- if (err) {
- p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
- return err;
- }
- if (type != P9_RERROR && type != P9_RLERROR)
- return 0;
-
- if (!p9_is_proto_dotl(c)) {
- char *ename;
- err = p9pdu_readf(req->rc, c->proto_version, "s?d",
- &ename, &ecode);
- if (err)
- goto out_err;
-
- if (p9_is_proto_dotu(c))
- err = -ecode;
-
- if (!err || !IS_ERR_VALUE(err)) {
- err = p9_errstr2errno(ename, strlen(ename));
-
- p9_debug(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
- -ecode, ename);
- }
- kfree(ename);
- } else {
- err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
- err = -ecode;
-
- p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
- }
-
- return err;
-
-out_err:
- p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
-
- return err;
-}
-
-/**
- * p9_check_zc_errors - check 9p packet for error return and process it
- * @c: current client instance
- * @req: request to parse and check for error conditions
- * @in_hdrlen: Size of response protocol buffer.
- *
- * returns error code if one is discovered, otherwise returns 0
- *
- * this will have to be more complicated if we have multiple
- * error packet types
- */
-
-static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
- char *uidata, int in_hdrlen, int kern_buf)
-{
- int err;
- int ecode;
- int8_t type;
- char *ename = NULL;
-
- err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
- /*
- * dump the response from server
- * This should be after parse_header which poplulate pdu_fcall.
- */
- trace_9p_protocol_dump(c, req->rc);
- if (err) {
- p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
- return err;
- }
-
- if (type != P9_RERROR && type != P9_RLERROR)
- return 0;
-
- if (!p9_is_proto_dotl(c)) {
- /* Error is reported in string format */
- int len;
- /* 7 = header size for RERROR; */
- int inline_len = in_hdrlen - 7;
-
- len = req->rc->size - req->rc->offset;
- if (len > (P9_ZC_HDR_SZ - 7)) {
- err = -EFAULT;
- goto out_err;
- }
-
- ename = &req->rc->sdata[req->rc->offset];
- if (len > inline_len) {
- /* We have error in external buffer */
- if (kern_buf) {
- memcpy(ename + inline_len, uidata,
- len - inline_len);
- } else {
- err = copy_from_user(ename + inline_len,
- uidata, len - inline_len);
- if (err) {
- err = -EFAULT;
- goto out_err;
- }
- }
- }
- ename = NULL;
- err = p9pdu_readf(req->rc, c->proto_version, "s?d",
- &ename, &ecode);
- if (err)
- goto out_err;
-
- if (p9_is_proto_dotu(c))
- err = -ecode;
-
- if (!err || !IS_ERR_VALUE(err)) {
- err = p9_errstr2errno(ename, strlen(ename));
-
- p9_debug(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
- -ecode, ename);
- }
- kfree(ename);
- } else {
- err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
- err = -ecode;
-
- p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
- }
- return err;
-
-out_err:
- p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
- return err;
-}
-
-static struct p9_req_t *
-p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
-
-/**
- * p9_client_flush - flush (cancel) a request
- * @c: client state
- * @oldreq: request to cancel
- *
- * This sents a flush for a particular request and links
- * the flush request to the original request. The current
- * code only supports a single flush request although the protocol
- * allows for multiple flush requests to be sent for a single request.
- *
- */
-
-static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
-{
- struct p9_req_t *req;
- int16_t oldtag;
- int err;
-
- err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
- if (err)
- return err;
-
- p9_debug(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
-
- req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
- if (IS_ERR(req))
- return PTR_ERR(req);
-
-
- /* if we haven't received a response for oldreq,
- remove it from the list. */
- spin_lock(&c->lock);
- if (oldreq->status == REQ_STATUS_FLSH)
- list_del(&oldreq->req_list);
- spin_unlock(&c->lock);
-
- p9_free_req(c, req);
- return 0;
-}
-
-static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
- int8_t type, int req_size,
- const char *fmt, va_list ap)
-{
- int tag, err;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type);
-
- /* we allow for any status other than disconnected */
- if (c->status == Disconnected)
- return ERR_PTR(-EIO);
-
- /* if status is begin_disconnected we allow only clunk request */
- if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
- return ERR_PTR(-EIO);
-
- tag = P9_NOTAG;
- if (type != P9_TVERSION) {
- tag = p9_idpool_get(c->tagpool);
- if (tag < 0)
- return ERR_PTR(-ENOMEM);
- }
-
- req = p9_tag_alloc(c, tag, req_size);
- if (IS_ERR(req))
- return req;
-
- /* marshall the data */
- p9pdu_prepare(req->tc, tag, type);
- err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
- if (err)
- goto reterr;
- p9pdu_finalize(c, req->tc);
- trace_9p_client_req(c, type, tag);
- return req;
-reterr:
- p9_free_req(c, req);
- return ERR_PTR(err);
-}
-
-/**
- * p9_client_rpc - issue a request and wait for a response
- * @c: client session
- * @type: type of request
- * @fmt: protocol format string (see protocol.c)
- *
- * Returns request structure (which client must free using p9_free_req)
- */
-
-static struct p9_req_t *
-p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
-{
- va_list ap;
- int sigpending, err;
- unsigned long flags;
- struct p9_req_t *req;
-
- va_start(ap, fmt);
- req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
- va_end(ap);
- if (IS_ERR(req))
- return req;
-
- if (signal_pending(current)) {
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
- } else
- sigpending = 0;
-
- err = c->trans_mod->request(c, req);
- if (err < 0) {
- if (err != -ERESTARTSYS && err != -EFAULT)
- c->status = Disconnected;
- goto reterr;
- }
-again:
- /* Wait for the response */
- err = wait_event_interruptible(*req->wq,
- req->status >= REQ_STATUS_RCVD);
-
- if ((err == -ERESTARTSYS) && (c->status == Connected)
- && (type == P9_TFLUSH)) {
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
- goto again;
- }
-
- if (req->status == REQ_STATUS_ERROR) {
- p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
- err = req->t_err;
- }
- if ((err == -ERESTARTSYS) && (c->status == Connected)) {
- p9_debug(P9_DEBUG_MUX, "flushing\n");
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
-
- if (c->trans_mod->cancel(c, req))
- p9_client_flush(c, req);
-
- /* if we received the response anyway, don't signal error */
- if (req->status == REQ_STATUS_RCVD)
- err = 0;
- }
- if (sigpending) {
- spin_lock_irqsave(¤t->sighand->siglock, flags);
- recalc_sigpending();
- spin_unlock_irqrestore(¤t->sighand->siglock, flags);
- }
- if (err < 0)
- goto reterr;
-
- err = p9_check_errors(c, req);
- trace_9p_client_res(c, type, req->rc->tag, err);
- if (!err)
- return req;
-reterr:
- p9_free_req(c, req);
- return ERR_PTR(safe_errno(err));
-}
-
-/**
- * p9_client_zc_rpc - issue a request and wait for a response
- * @c: client session
- * @type: type of request
- * @uidata: user bffer that should be ued for zero copy read
- * @uodata: user buffer that shoud be user for zero copy write
- * @inlen: read buffer size
- * @olen: write buffer size
- * @hdrlen: reader header size, This is the size of response protocol data
- * @fmt: protocol format string (see protocol.c)
- *
- * Returns request structure (which client must free using p9_free_req)
- */
-static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
- char *uidata, char *uodata,
- int inlen, int olen, int in_hdrlen,
- int kern_buf, const char *fmt, ...)
-{
- va_list ap;
- int sigpending, err;
- unsigned long flags;
- struct p9_req_t *req;
-
- va_start(ap, fmt);
- /*
- * We allocate a inline protocol data of only 4k bytes.
- * The actual content is passed in zero-copy fashion.
- */
- req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
- va_end(ap);
- if (IS_ERR(req))
- return req;
-
- if (signal_pending(current)) {
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
- } else
- sigpending = 0;
-
- /* If we are called with KERNEL_DS force kern_buf */
- if (segment_eq(get_fs(), KERNEL_DS))
- kern_buf = 1;
-
- err = c->trans_mod->zc_request(c, req, uidata, uodata,
- inlen, olen, in_hdrlen, kern_buf);
- if (err < 0) {
- if (err == -EIO)
- c->status = Disconnected;
- if (err != -ERESTARTSYS)
- goto reterr;
- }
- if (req->status == REQ_STATUS_ERROR) {
- p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
- err = req->t_err;
- }
- if ((err == -ERESTARTSYS) && (c->status == Connected)) {
- p9_debug(P9_DEBUG_MUX, "flushing\n");
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
-
- if (c->trans_mod->cancel(c, req))
- p9_client_flush(c, req);
-
- /* if we received the response anyway, don't signal error */
- if (req->status == REQ_STATUS_RCVD)
- err = 0;
- }
- if (sigpending) {
- spin_lock_irqsave(¤t->sighand->siglock, flags);
- recalc_sigpending();
- spin_unlock_irqrestore(¤t->sighand->siglock, flags);
- }
- if (err < 0)
- goto reterr;
-
- err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
- trace_9p_client_res(c, type, req->rc->tag, err);
- if (!err)
- return req;
-reterr:
- p9_free_req(c, req);
- return ERR_PTR(safe_errno(err));
-}
-
-static struct p9_fid *p9_fid_create(struct p9_client *clnt)
-{
- int ret;
- struct p9_fid *fid;
- unsigned long flags;
-
- p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
- fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
- if (!fid)
- return ERR_PTR(-ENOMEM);
-
- ret = p9_idpool_get(clnt->fidpool);
- if (ret < 0) {
- ret = -ENOSPC;
- goto error;
- }
- fid->fid = ret;
-
- memset(&fid->qid, 0, sizeof(struct p9_qid));
- fid->mode = -1;
- fid->uid = current_fsuid();
- fid->clnt = clnt;
- fid->rdir = NULL;
- spin_lock_irqsave(&clnt->lock, flags);
- list_add(&fid->flist, &clnt->fidlist);
- spin_unlock_irqrestore(&clnt->lock, flags);
-
- return fid;
-
-error:
- kfree(fid);
- return ERR_PTR(ret);
-}
-
-static void p9_fid_destroy(struct p9_fid *fid)
-{
- struct p9_client *clnt;
- unsigned long flags;
-
- p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
- clnt = fid->clnt;
- p9_idpool_put(fid->fid, clnt->fidpool);
- spin_lock_irqsave(&clnt->lock, flags);
- list_del(&fid->flist);
- spin_unlock_irqrestore(&clnt->lock, flags);
- kfree(fid->rdir);
- kfree(fid);
-}
-
-static int p9_client_version(struct p9_client *c)
-{
- int err = 0;
- struct p9_req_t *req;
- char *version;
- int msize;
-
- p9_debug(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
- c->msize, c->proto_version);
-
- switch (c->proto_version) {
- case p9_proto_2000L:
- req = p9_client_rpc(c, P9_TVERSION, "ds",
- c->msize, "9P2000.L");
- break;
- case p9_proto_2000u:
- req = p9_client_rpc(c, P9_TVERSION, "ds",
- c->msize, "9P2000.u");
- break;
- case p9_proto_legacy:
- req = p9_client_rpc(c, P9_TVERSION, "ds",
- c->msize, "9P2000");
- break;
- default:
- return -EINVAL;
- break;
- }
-
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
- if (err) {
- p9_debug(P9_DEBUG_9P, "version error %d\n", err);
- trace_9p_protocol_dump(c, req->rc);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
- if (!strncmp(version, "9P2000.L", 8))
- c->proto_version = p9_proto_2000L;
- else if (!strncmp(version, "9P2000.u", 8))
- c->proto_version = p9_proto_2000u;
- else if (!strncmp(version, "9P2000", 6))
- c->proto_version = p9_proto_legacy;
- else {
- err = -EREMOTEIO;
- goto error;
- }
-
- if (msize < c->msize)
- c->msize = msize;
-
-error:
- kfree(version);
- p9_free_req(c, req);
-
- return err;
-}
-
-struct p9_client *p9_client_create(const char *dev_name, char *options)
-{
- int err;
- struct p9_client *clnt;
-
- err = 0;
- clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
- if (!clnt)
- return ERR_PTR(-ENOMEM);
-
- clnt->trans_mod = NULL;
- clnt->trans = NULL;
- spin_lock_init(&clnt->lock);
- INIT_LIST_HEAD(&clnt->fidlist);
-
- err = p9_tag_init(clnt);
- if (err < 0)
- goto free_client;
-
- err = parse_opts(options, clnt);
- if (err < 0)
- goto destroy_tagpool;
-
- if (!clnt->trans_mod)
- clnt->trans_mod = v9fs_get_default_trans();
-
- if (clnt->trans_mod == NULL) {
- err = -EPROTONOSUPPORT;
- p9_debug(P9_DEBUG_ERROR,
- "No transport defined or default transport\n");
- goto destroy_tagpool;
- }
-
- clnt->fidpool = p9_idpool_create();
- if (IS_ERR(clnt->fidpool)) {
- err = PTR_ERR(clnt->fidpool);
- goto put_trans;
- }
-
- p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
- clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
-
- err = clnt->trans_mod->create(clnt, dev_name, options);
- if (err)
- goto destroy_fidpool;
-
- if (clnt->msize > clnt->trans_mod->maxsize)
- clnt->msize = clnt->trans_mod->maxsize;
-
- err = p9_client_version(clnt);
- if (err)
- goto close_trans;
-
- return clnt;
-
-close_trans:
- clnt->trans_mod->close(clnt);
-destroy_fidpool:
- p9_idpool_destroy(clnt->fidpool);
-put_trans:
- v9fs_put_trans(clnt->trans_mod);
-destroy_tagpool:
- p9_idpool_destroy(clnt->tagpool);
-free_client:
- kfree(clnt);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_create);
-
-void p9_client_destroy(struct p9_client *clnt)
-{
- struct p9_fid *fid, *fidptr;
-
- p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);
-
- if (clnt->trans_mod)
- clnt->trans_mod->close(clnt);
-
- v9fs_put_trans(clnt->trans_mod);
-
- list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
- pr_info("Found fid %d not clunked\n", fid->fid);
- p9_fid_destroy(fid);
- }
-
- if (clnt->fidpool)
- p9_idpool_destroy(clnt->fidpool);
-
- p9_tag_cleanup(clnt);
-
- kfree(clnt);
-}
-EXPORT_SYMBOL(p9_client_destroy);
-
-void p9_client_disconnect(struct p9_client *clnt)
-{
- p9_debug(P9_DEBUG_9P, "clnt %p\n", clnt);
- clnt->status = Disconnected;
-}
-EXPORT_SYMBOL(p9_client_disconnect);
-
-void p9_client_begin_disconnect(struct p9_client *clnt)
-{
- p9_debug(P9_DEBUG_9P, "clnt %p\n", clnt);
- clnt->status = BeginDisconnect;
-}
-EXPORT_SYMBOL(p9_client_begin_disconnect);
-
-struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
- char *uname, kuid_t n_uname, char *aname)
-{
- int err = 0;
- struct p9_req_t *req;
- struct p9_fid *fid;
- struct p9_qid qid;
-
-
- p9_debug(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
- afid ? afid->fid : -1, uname, aname);
- fid = p9_fid_create(clnt);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- fid = NULL;
- goto error;
- }
-
- req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
- afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
- qid.type, (unsigned long long)qid.path, qid.version);
-
- memmove(&fid->qid, &qid, sizeof(struct p9_qid));
-
- p9_free_req(clnt, req);
- return fid;
-
-error:
- if (fid)
- p9_fid_destroy(fid);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_attach);
-
-struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
- char **wnames, int clone)
-{
- int err;
- struct p9_client *clnt;
- struct p9_fid *fid;
- struct p9_qid *wqids;
- struct p9_req_t *req;
- uint16_t nwqids, count;
-
- err = 0;
- wqids = NULL;
- clnt = oldfid->clnt;
- if (clone) {
- fid = p9_fid_create(clnt);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- fid = NULL;
- goto error;
- }
-
- fid->uid = oldfid->uid;
- } else
- fid = oldfid;
-
-
- p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
- oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
-
- req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
- nwname, wnames);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto clunk_fid;
- }
- p9_free_req(clnt, req);
-
- p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
-
- if (nwqids != nwname) {
- err = -ENOENT;
- goto clunk_fid;
- }
-
- for (count = 0; count < nwqids; count++)
- p9_debug(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n",
- count, wqids[count].type,
- (unsigned long long)wqids[count].path,
- wqids[count].version);
-
- if (nwname)
- memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
- else
- fid->qid = oldfid->qid;
-
- kfree(wqids);
- return fid;
-
-clunk_fid:
- kfree(wqids);
- p9_client_clunk(fid);
- fid = NULL;
-
-error:
- if (fid && (fid != oldfid))
- p9_fid_destroy(fid);
-
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_walk);
-
-int p9_client_open(struct p9_fid *fid, int mode)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
- struct p9_qid qid;
- int iounit;
-
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> %s fid %d mode %d\n",
- p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
- err = 0;
-
- if (fid->mode != -1)
- return -EINVAL;
-
- if (p9_is_proto_dotl(clnt))
- req = p9_client_rpc(clnt, P9_TLOPEN, "dd", fid->fid, mode);
- else
- req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n",
- p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type,
- (unsigned long long)qid.path, qid.version, iounit);
-
- fid->mode = mode;
- fid->iounit = iounit;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_open);
-
-int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
- kgid_t gid, struct p9_qid *qid)
-{
- int err = 0;
- struct p9_client *clnt;
- struct p9_req_t *req;
- int iounit;
-
- p9_debug(P9_DEBUG_9P,
- ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
- ofid->fid, name, flags, mode,
- from_kgid(&init_user_ns, gid));
- clnt = ofid->clnt;
-
- if (ofid->mode != -1)
- return -EINVAL;
-
- req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags,
- mode, gid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n",
- qid->type,
- (unsigned long long)qid->path,
- qid->version, iounit);
-
- ofid->mode = mode;
- ofid->iounit = iounit;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_create_dotl);
-
-int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
- char *extension)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
- struct p9_qid qid;
- int iounit;
-
- p9_debug(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
- fid->fid, name, perm, mode);
- err = 0;
- clnt = fid->clnt;
-
- if (fid->mode != -1)
- return -EINVAL;
-
- req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
- mode, extension);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
- qid.type,
- (unsigned long long)qid.path,
- qid.version, iounit);
-
- fid->mode = mode;
- fid->iounit = iounit;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_fcreate);
-
-int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, kgid_t gid,
- struct p9_qid *qid)
-{
- int err = 0;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s symtgt %s\n",
- dfid->fid, name, symtgt);
- clnt = dfid->clnt;
-
- req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt,
- gid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n",
- qid->type, (unsigned long long)qid->path, qid->version);
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_symlink);
-
-int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname)
-{
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n",
- dfid->fid, oldfid->fid, newname);
- clnt = dfid->clnt;
- req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid,
- newname);
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
- p9_free_req(clnt, req);
- return 0;
-}
-EXPORT_SYMBOL(p9_client_link);
-
-int p9_client_fsync(struct p9_fid *fid, int datasync)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
- fid->fid, datasync);
- err = 0;
- clnt = fid->clnt;
-
- req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
-
- p9_free_req(clnt, req);
-
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_fsync);
-
-int p9_client_clunk(struct p9_fid *fid)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
- int retries = 0;
-
- if (!fid) {
- pr_warn("%s (%d): Trying to clunk with NULL fid\n",
- __func__, task_pid_nr(current));
- dump_stack();
- return 0;
- }
-
-again:
- p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
- retries);
- err = 0;
- clnt = fid->clnt;
-
- req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
-
- p9_free_req(clnt, req);
-error:
- /*
- * Fid is not valid even after a failed clunk
- * If interrupted, retry once then give up and
- * leak fid until umount.
- */
- if (err == -ERESTARTSYS) {
- if (retries++ == 0)
- goto again;
- } else
- p9_fid_destroy(fid);
- return err;
-}
-EXPORT_SYMBOL(p9_client_clunk);
-
-int p9_client_remove(struct p9_fid *fid)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
- err = 0;
- clnt = fid->clnt;
-
- req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
-
- p9_free_req(clnt, req);
-error:
- if (err == -ERESTARTSYS)
- p9_client_clunk(fid);
- else
- p9_fid_destroy(fid);
- return err;
-}
-EXPORT_SYMBOL(p9_client_remove);
-
-int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
-{
- int err = 0;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- p9_debug(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
- dfid->fid, name, flags);
-
- clnt = dfid->clnt;
- req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
-
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_unlinkat);
-
-int
-p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
- u32 count)
-{
- char *dataptr;
- int kernel_buf = 0;
- struct p9_req_t *req;
- struct p9_client *clnt;
- int err, rsize, non_zc = 0;
-
-
- p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
- fid->fid, (unsigned long long) offset, count);
- err = 0;
- clnt = fid->clnt;
-
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
- rsize = clnt->msize - P9_IOHDRSZ;
-
- if (count < rsize)
- rsize = count;
-
- /* Don't bother zerocopy for small IO (< 1024) */
- if (clnt->trans_mod->zc_request && rsize > 1024) {
- char *indata;
- if (data) {
- kernel_buf = 1;
- indata = data;
- } else
- indata = (__force char *)udata;
- /*
- * response header len is 11
- * PDU Header(7) + IO Size (4)
- */
- req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
- 11, kernel_buf, "dqd", fid->fid,
- offset, rsize);
- } else {
- non_zc = 1;
- req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
- rsize);
- }
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
-
- if (non_zc) {
- if (data) {
- memmove(data, dataptr, count);
- } else {
- err = copy_to_user(udata, dataptr, count);
- if (err) {
- err = -EFAULT;
- goto free_and_error;
- }
- }
- }
- p9_free_req(clnt, req);
- return count;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_read);
-
-int
-p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
- u64 offset, u32 count)
-{
- int err, rsize;
- int kernel_buf = 0;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
- fid->fid, (unsigned long long) offset, count);
- err = 0;
- clnt = fid->clnt;
-
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
- rsize = clnt->msize - P9_IOHDRSZ;
-
- if (count < rsize)
- rsize = count;
-
- /* Don't bother zerocopy for small IO (< 1024) */
- if (clnt->trans_mod->zc_request && rsize > 1024) {
- char *odata;
- if (data) {
- kernel_buf = 1;
- odata = data;
- } else
- odata = (char *)udata;
- req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
- P9_ZC_HDR_SZ, kernel_buf, "dqd",
- fid->fid, offset, rsize);
- } else {
- if (data)
- req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
- offset, rsize, data);
- else
- req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
- offset, rsize, udata);
- }
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
-
- p9_free_req(clnt, req);
- return count;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_write);
-
-struct p9_wstat *p9_client_stat(struct p9_fid *fid)
-{
- int err;
- struct p9_client *clnt;
- struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
- struct p9_req_t *req;
- u16 ignored;
-
- p9_debug(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
-
- if (!ret)
- return ERR_PTR(-ENOMEM);
-
- err = 0;
- clnt = fid->clnt;
-
- req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P,
- "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
- "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
- "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
- "<<< uid=%d gid=%d n_muid=%d\n",
- ret->size, ret->type, ret->dev, ret->qid.type,
- (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
- ret->atime, ret->mtime, (unsigned long long)ret->length,
- ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
- from_kuid(&init_user_ns, ret->n_uid),
- from_kgid(&init_user_ns, ret->n_gid),
- from_kuid(&init_user_ns, ret->n_muid));
-
- p9_free_req(clnt, req);
- return ret;
-
-error:
- kfree(ret);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_stat);
-
-struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
- u64 request_mask)
-{
- int err;
- struct p9_client *clnt;
- struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
- GFP_KERNEL);
- struct p9_req_t *req;
-
- p9_debug(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n",
- fid->fid, request_mask);
-
- if (!ret)
- return ERR_PTR(-ENOMEM);
-
- err = 0;
- clnt = fid->clnt;
-
- req = p9_client_rpc(clnt, P9_TGETATTR, "dq", fid->fid, request_mask);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P,
- "<<< RGETATTR st_result_mask=%lld\n"
- "<<< qid=%x.%llx.%x\n"
- "<<< st_mode=%8.8x st_nlink=%llu\n"
- "<<< st_uid=%d st_gid=%d\n"
- "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
- "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
- "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
- "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
- "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
- "<<< st_gen=%lld st_data_version=%lld",
- ret->st_result_mask, ret->qid.type, ret->qid.path,
- ret->qid.version, ret->st_mode, ret->st_nlink,
- from_kuid(&init_user_ns, ret->st_uid),
- from_kgid(&init_user_ns, ret->st_gid),
- ret->st_rdev, ret->st_size, ret->st_blksize,
- ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
- ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
- ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
- ret->st_gen, ret->st_data_version);
-
- p9_free_req(clnt, req);
- return ret;
-
-error:
- kfree(ret);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_getattr_dotl);
-
-static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
-{
- int ret;
-
- /* NOTE: size shouldn't include its own length */
- /* size[2] type[2] dev[4] qid[13] */
- /* mode[4] atime[4] mtime[4] length[8]*/
- /* name[s] uid[s] gid[s] muid[s] */
- ret = 2+4+13+4+4+4+8+2+2+2+2;
-
- if (wst->name)
- ret += strlen(wst->name);
- if (wst->uid)
- ret += strlen(wst->uid);
- if (wst->gid)
- ret += strlen(wst->gid);
- if (wst->muid)
- ret += strlen(wst->muid);
-
- if ((proto_version == p9_proto_2000u) ||
- (proto_version == p9_proto_2000L)) {
- ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
- if (wst->extension)
- ret += strlen(wst->extension);
- }
-
- return ret;
-}
-
-int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- err = 0;
- clnt = fid->clnt;
- wst->size = p9_client_statsize(wst, clnt->proto_version);
- p9_debug(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
- p9_debug(P9_DEBUG_9P,
- " sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
- " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
- " name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
- " uid=%d gid=%d n_muid=%d\n",
- wst->size, wst->type, wst->dev, wst->qid.type,
- (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
- wst->atime, wst->mtime, (unsigned long long)wst->length,
- wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
- from_kuid(&init_user_ns, wst->n_uid),
- from_kgid(&init_user_ns, wst->n_gid),
- from_kuid(&init_user_ns, wst->n_muid));
-
- req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
-
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_wstat);
-
-int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
- p9_debug(P9_DEBUG_9P,
- " valid=%x mode=%x uid=%d gid=%d size=%lld\n"
- " atime_sec=%lld atime_nsec=%lld\n"
- " mtime_sec=%lld mtime_nsec=%lld\n",
- p9attr->valid, p9attr->mode,
- from_kuid(&init_user_ns, p9attr->uid),
- from_kgid(&init_user_ns, p9attr->gid),
- p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
- p9attr->mtime_sec, p9attr->mtime_nsec);
-
- req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
-
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_setattr);
-
-int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- err = 0;
- clnt = fid->clnt;
-
- p9_debug(P9_DEBUG_9P, ">>> TSTATFS fid %d\n", fid->fid);
-
- req = p9_client_rpc(clnt, P9_TSTATFS, "d", fid->fid);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
- &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
- &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
- "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
- "fsid %llu namelen %ld\n",
- fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
- sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree,
- sb->fsid, (long int)sb->namelen);
-
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_statfs);
-
-int p9_client_rename(struct p9_fid *fid,
- struct p9_fid *newdirfid, const char *name)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- err = 0;
- clnt = fid->clnt;
-
- p9_debug(P9_DEBUG_9P, ">>> TRENAME fid %d newdirfid %d name %s\n",
- fid->fid, newdirfid->fid, name);
-
- req = p9_client_rpc(clnt, P9_TRENAME, "dds", fid->fid,
- newdirfid->fid, name);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
-
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_rename);
-
-int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
- struct p9_fid *newdirfid, const char *new_name)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- err = 0;
- clnt = olddirfid->clnt;
-
- p9_debug(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
- " newdirfid %d new name %s\n", olddirfid->fid, old_name,
- newdirfid->fid, new_name);
-
- req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
- old_name, newdirfid->fid, new_name);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
- newdirfid->fid, new_name);
-
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_renameat);
-
-/*
- * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
- */
-struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
- const char *attr_name, u64 *attr_size)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
- struct p9_fid *attr_fid;
-
- err = 0;
- clnt = file_fid->clnt;
- attr_fid = p9_fid_create(clnt);
- if (IS_ERR(attr_fid)) {
- err = PTR_ERR(attr_fid);
- attr_fid = NULL;
- goto error;
- }
- p9_debug(P9_DEBUG_9P,
- ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
- file_fid->fid, attr_fid->fid, attr_name);
-
- req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
- file_fid->fid, attr_fid->fid, attr_name);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
- err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- p9_free_req(clnt, req);
- goto clunk_fid;
- }
- p9_free_req(clnt, req);
- p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
- attr_fid->fid, *attr_size);
- return attr_fid;
-clunk_fid:
- p9_client_clunk(attr_fid);
- attr_fid = NULL;
-error:
- if (attr_fid && (attr_fid != file_fid))
- p9_fid_destroy(attr_fid);
-
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
-
-int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
- u64 attr_size, int flags)
-{
- int err;
- struct p9_req_t *req;
- struct p9_client *clnt;
-
- p9_debug(P9_DEBUG_9P,
- ">>> TXATTRCREATE fid %d name %s size %lld flag %d\n",
- fid->fid, name, (long long)attr_size, flags);
- err = 0;
- clnt = fid->clnt;
- req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd",
- fid->fid, name, attr_size, flags);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
-
-int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
-{
- int err, rsize, non_zc = 0;
- struct p9_client *clnt;
- struct p9_req_t *req;
- char *dataptr;
-
- p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
- fid->fid, (unsigned long long) offset, count);
-
- err = 0;
- clnt = fid->clnt;
-
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
- rsize = clnt->msize - P9_READDIRHDRSZ;
-
- if (count < rsize)
- rsize = count;
-
- /* Don't bother zerocopy for small IO (< 1024) */
- if (clnt->trans_mod->zc_request && rsize > 1024) {
- /*
- * response header len is 11
- * PDU Header(7) + IO Size (4)
- */
- req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
- 11, 1, "dqd", fid->fid, offset, rsize);
- } else {
- non_zc = 1;
- req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
- offset, rsize);
- }
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- goto error;
- }
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto free_and_error;
- }
- if (rsize < count) {
- pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
- count = rsize;
- }
-
- p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
-
- if (non_zc)
- memmove(data, dataptr, count);
-
- p9_free_req(clnt, req);
- return count;
-
-free_and_error:
- p9_free_req(clnt, req);
-error:
- return err;
-}
-EXPORT_SYMBOL(p9_client_readdir);
-
-int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
- dev_t rdev, kgid_t gid, struct p9_qid *qid)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
- "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
- req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode,
- MAJOR(rdev), MINOR(rdev), gid);
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
- (unsigned long long)qid->path, qid->version);
-
-error:
- p9_free_req(clnt, req);
- return err;
-
-}
-EXPORT_SYMBOL(p9_client_mknod_dotl);
-
-int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
- kgid_t gid, struct p9_qid *qid)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
- fid->fid, name, mode, from_kgid(&init_user_ns, gid));
- req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode,
- gid);
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
- (unsigned long long)qid->path, qid->version);
-
-error:
- p9_free_req(clnt, req);
- return err;
-
-}
-EXPORT_SYMBOL(p9_client_mkdir_dotl);
-
-int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
- "start %lld length %lld proc_id %d client_id %s\n",
- fid->fid, flock->type, flock->flags, flock->start,
- flock->length, flock->proc_id, flock->client_id);
-
- req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
- flock->flags, flock->start, flock->length,
- flock->proc_id, flock->client_id);
-
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
-error:
- p9_free_req(clnt, req);
- return err;
-
-}
-EXPORT_SYMBOL(p9_client_lock_dotl);
-
-int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
- "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
- glock->start, glock->length, glock->proc_id, glock->client_id);
-
- req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid, glock->type,
- glock->start, glock->length, glock->proc_id, glock->client_id);
-
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
- &glock->start, &glock->length, &glock->proc_id,
- &glock->client_id);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
- "proc_id %d client_id %s\n", glock->type, glock->start,
- glock->length, glock->proc_id, glock->client_id);
-error:
- p9_free_req(clnt, req);
- return err;
-}
-EXPORT_SYMBOL(p9_client_getlock_dotl);
-
-int p9_client_readlink(struct p9_fid *fid, char **target)
-{
- int err;
- struct p9_client *clnt;
- struct p9_req_t *req;
-
- err = 0;
- clnt = fid->clnt;
- p9_debug(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
-
- req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
- if (IS_ERR(req))
- return PTR_ERR(req);
-
- err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
- if (err) {
- trace_9p_protocol_dump(clnt, req->rc);
- goto error;
- }
- p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
-error:
- p9_free_req(clnt, req);
- return err;
-}
-EXPORT_SYMBOL(p9_client_readlink);
diff --git a/addons/9p/src/3.10.108/error.c b/addons/9p/src/3.10.108/error.c
deleted file mode 100644
index 126fd0dc..00000000
--- a/addons/9p/src/3.10.108/error.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * linux/fs/9p/error.c
- *
- * Error string handling
- *
- * Plan 9 uses error strings, Unix uses error numbers. These functions
- * try to help manage that and provide for dynamically adding error
- * mappings.
- *
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-
-/**
- * struct errormap - map string errors from Plan 9 to Linux numeric ids
- * @name: string sent over 9P
- * @val: numeric id most closely representing @name
- * @namelen: length of string
- * @list: hash-table list for string lookup
- */
-struct errormap {
- char *name;
- int val;
-
- int namelen;
- struct hlist_node list;
-};
-
-#define ERRHASHSZ 32
-static struct hlist_head hash_errmap[ERRHASHSZ];
-
-/* FixMe - reduce to a reasonable size */
-static struct errormap errmap[] = {
- {"Operation not permitted", EPERM},
- {"wstat prohibited", EPERM},
- {"No such file or directory", ENOENT},
- {"directory entry not found", ENOENT},
- {"file not found", ENOENT},
- {"Interrupted system call", EINTR},
- {"Input/output error", EIO},
- {"No such device or address", ENXIO},
- {"Argument list too long", E2BIG},
- {"Bad file descriptor", EBADF},
- {"Resource temporarily unavailable", EAGAIN},
- {"Cannot allocate memory", ENOMEM},
- {"Permission denied", EACCES},
- {"Bad address", EFAULT},
- {"Block device required", ENOTBLK},
- {"Device or resource busy", EBUSY},
- {"File exists", EEXIST},
- {"Invalid cross-device link", EXDEV},
- {"No such device", ENODEV},
- {"Not a directory", ENOTDIR},
- {"Is a directory", EISDIR},
- {"Invalid argument", EINVAL},
- {"Too many open files in system", ENFILE},
- {"Too many open files", EMFILE},
- {"Text file busy", ETXTBSY},
- {"File too large", EFBIG},
- {"No space left on device", ENOSPC},
- {"Illegal seek", ESPIPE},
- {"Read-only file system", EROFS},
- {"Too many links", EMLINK},
- {"Broken pipe", EPIPE},
- {"Numerical argument out of domain", EDOM},
- {"Numerical result out of range", ERANGE},
- {"Resource deadlock avoided", EDEADLK},
- {"File name too long", ENAMETOOLONG},
- {"No locks available", ENOLCK},
- {"Function not implemented", ENOSYS},
- {"Directory not empty", ENOTEMPTY},
- {"Too many levels of symbolic links", ELOOP},
- {"No message of desired type", ENOMSG},
- {"Identifier removed", EIDRM},
- {"No data available", ENODATA},
- {"Machine is not on the network", ENONET},
- {"Package not installed", ENOPKG},
- {"Object is remote", EREMOTE},
- {"Link has been severed", ENOLINK},
- {"Communication error on send", ECOMM},
- {"Protocol error", EPROTO},
- {"Bad message", EBADMSG},
- {"File descriptor in bad state", EBADFD},
- {"Streams pipe error", ESTRPIPE},
- {"Too many users", EUSERS},
- {"Socket operation on non-socket", ENOTSOCK},
- {"Message too long", EMSGSIZE},
- {"Protocol not available", ENOPROTOOPT},
- {"Protocol not supported", EPROTONOSUPPORT},
- {"Socket type not supported", ESOCKTNOSUPPORT},
- {"Operation not supported", EOPNOTSUPP},
- {"Protocol family not supported", EPFNOSUPPORT},
- {"Network is down", ENETDOWN},
- {"Network is unreachable", ENETUNREACH},
- {"Network dropped connection on reset", ENETRESET},
- {"Software caused connection abort", ECONNABORTED},
- {"Connection reset by peer", ECONNRESET},
- {"No buffer space available", ENOBUFS},
- {"Transport endpoint is already connected", EISCONN},
- {"Transport endpoint is not connected", ENOTCONN},
- {"Cannot send after transport endpoint shutdown", ESHUTDOWN},
- {"Connection timed out", ETIMEDOUT},
- {"Connection refused", ECONNREFUSED},
- {"Host is down", EHOSTDOWN},
- {"No route to host", EHOSTUNREACH},
- {"Operation already in progress", EALREADY},
- {"Operation now in progress", EINPROGRESS},
- {"Is a named type file", EISNAM},
- {"Remote I/O error", EREMOTEIO},
- {"Disk quota exceeded", EDQUOT},
-/* errors from fossil, vacfs, and u9fs */
- {"fid unknown or out of range", EBADF},
- {"permission denied", EACCES},
- {"file does not exist", ENOENT},
- {"authentication failed", ECONNREFUSED},
- {"bad offset in directory read", ESPIPE},
- {"bad use of fid", EBADF},
- {"wstat can't convert between files and directories", EPERM},
- {"directory is not empty", ENOTEMPTY},
- {"file exists", EEXIST},
- {"file already exists", EEXIST},
- {"file or directory already exists", EEXIST},
- {"fid already in use", EBADF},
- {"file in use", ETXTBSY},
- {"i/o error", EIO},
- {"file already open for I/O", ETXTBSY},
- {"illegal mode", EINVAL},
- {"illegal name", ENAMETOOLONG},
- {"not a directory", ENOTDIR},
- {"not a member of proposed group", EPERM},
- {"not owner", EACCES},
- {"only owner can change group in wstat", EACCES},
- {"read only file system", EROFS},
- {"no access to special file", EPERM},
- {"i/o count too large", EIO},
- {"unknown group", EINVAL},
- {"unknown user", EINVAL},
- {"bogus wstat buffer", EPROTO},
- {"exclusive use file already open", EAGAIN},
- {"corrupted directory entry", EIO},
- {"corrupted file entry", EIO},
- {"corrupted block label", EIO},
- {"corrupted meta data", EIO},
- {"illegal offset", EINVAL},
- {"illegal path element", ENOENT},
- {"root of file system is corrupted", EIO},
- {"corrupted super block", EIO},
- {"protocol botch", EPROTO},
- {"file system is full", ENOSPC},
- {"file is in use", EAGAIN},
- {"directory entry is not allocated", ENOENT},
- {"file is read only", EROFS},
- {"file has been removed", EIDRM},
- {"only support truncation to zero length", EPERM},
- {"cannot remove root", EPERM},
- {"file too big", EFBIG},
- {"venti i/o error", EIO},
- /* these are not errors */
- {"u9fs rhostsauth: no authentication required", 0},
- {"u9fs authnone: no authentication required", 0},
- {NULL, -1}
-};
-
-/**
- * p9_error_init - preload mappings into hash list
- *
- */
-
-int p9_error_init(void)
-{
- struct errormap *c;
- int bucket;
-
- /* initialize hash table */
- for (bucket = 0; bucket < ERRHASHSZ; bucket++)
- INIT_HLIST_HEAD(&hash_errmap[bucket]);
-
- /* load initial error map into hash table */
- for (c = errmap; c->name != NULL; c++) {
- c->namelen = strlen(c->name);
- bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
- INIT_HLIST_NODE(&c->list);
- hlist_add_head(&c->list, &hash_errmap[bucket]);
- }
-
- return 1;
-}
-EXPORT_SYMBOL(p9_error_init);
-
-/**
- * errstr2errno - convert error string to error number
- * @errstr: error string
- * @len: length of error string
- *
- */
-
-int p9_errstr2errno(char *errstr, int len)
-{
- int errno;
- struct errormap *c;
- int bucket;
-
- errno = 0;
- c = NULL;
- bucket = jhash(errstr, len, 0) % ERRHASHSZ;
- hlist_for_each_entry(c, &hash_errmap[bucket], list) {
- if (c->namelen == len && !memcmp(c->name, errstr, len)) {
- errno = c->val;
- break;
- }
- }
-
- if (errno == 0) {
- /* TODO: if error isn't found, add it dynamically */
- errstr[len] = 0;
- pr_err("%s: server reported unknown error %s\n",
- __func__, errstr);
- errno = ESERVERFAULT;
- }
-
- return -errno;
-}
-EXPORT_SYMBOL(p9_errstr2errno);
diff --git a/addons/9p/src/3.10.108/fid.c b/addons/9p/src/3.10.108/fid.c
deleted file mode 100644
index d51ec9fa..00000000
--- a/addons/9p/src/3.10.108/fid.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * V9FS FID Management
- *
- * Copyright (C) 2007 by Latchesar Ionkov
- * Copyright (C) 2005, 2006 by Eric Van Hensbergen
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "fid.h"
-
-/**
- * v9fs_fid_add - add a fid to a dentry
- * @dentry: dentry that the fid is being added to
- * @fid: fid to add
- *
- */
-
-static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
-{
- hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
-}
-
-void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
-{
- spin_lock(&dentry->d_lock);
- __add_fid(dentry, fid);
- spin_unlock(&dentry->d_lock);
-}
-
-/**
- * v9fs_fid_find - retrieve a fid that belongs to the specified uid
- * @dentry: dentry to look for fid in
- * @uid: return fid that belongs to the specified user
- * @any: if non-zero, return any fid associated with the dentry
- *
- */
-
-static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
-{
- struct p9_fid *fid, *ret;
-
- p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
- dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
- any);
- ret = NULL;
- /* we'll recheck under lock if there's anything to look in */
- if (dentry->d_fsdata) {
- struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
- spin_lock(&dentry->d_lock);
- hlist_for_each_entry(fid, h, dlist) {
- if (any || uid_eq(fid->uid, uid)) {
- ret = fid;
- break;
- }
- }
- spin_unlock(&dentry->d_lock);
- }
-
- return ret;
-}
-
-/*
- * We need to hold v9ses->rename_sem as long as we hold references
- * to returned path array. Array element contain pointers to
- * dentry names.
- */
-static int build_path_from_dentry(struct v9fs_session_info *v9ses,
- struct dentry *dentry, char ***names)
-{
- int n = 0, i;
- char **wnames;
- struct dentry *ds;
-
- for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent)
- n++;
-
- wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL);
- if (!wnames)
- goto err_out;
-
- for (ds = dentry, i = (n-1); i >= 0; i--, ds = ds->d_parent)
- wnames[i] = (char *)ds->d_name.name;
-
- *names = wnames;
- return n;
-err_out:
- return -ENOMEM;
-}
-
-static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
- kuid_t uid, int any)
-{
- struct dentry *ds;
- char **wnames, *uname;
- int i, n, l, clone, access;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid, *old_fid = NULL;
-
- v9ses = v9fs_dentry2v9ses(dentry);
- access = v9ses->flags & V9FS_ACCESS_MASK;
- fid = v9fs_fid_find(dentry, uid, any);
- if (fid)
- return fid;
- /*
- * we don't have a matching fid. To do a TWALK we need
- * parent fid. We need to prevent rename when we want to
- * look at the parent.
- */
- down_read(&v9ses->rename_sem);
- ds = dentry->d_parent;
- fid = v9fs_fid_find(ds, uid, any);
- if (fid) {
- /* Found the parent fid do a lookup with that */
- fid = p9_client_walk(fid, 1, (char **)&dentry->d_name.name, 1);
- goto fid_out;
- }
- up_read(&v9ses->rename_sem);
-
- /* start from the root and try to do a lookup */
- fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
- if (!fid) {
- /* the user is not attached to the fs yet */
- if (access == V9FS_ACCESS_SINGLE)
- return ERR_PTR(-EPERM);
-
- if (v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses))
- uname = NULL;
- else
- uname = v9ses->uname;
-
- fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
- v9ses->aname);
- if (IS_ERR(fid))
- return fid;
-
- v9fs_fid_add(dentry->d_sb->s_root, fid);
- }
- /* If we are root ourself just return that */
- if (dentry->d_sb->s_root == dentry)
- return fid;
- /*
- * Do a multipath walk with attached root.
- * When walking parent we need to make sure we
- * don't have a parallel rename happening
- */
- down_read(&v9ses->rename_sem);
- n = build_path_from_dentry(v9ses, dentry, &wnames);
- if (n < 0) {
- fid = ERR_PTR(n);
- goto err_out;
- }
- clone = 1;
- i = 0;
- while (i < n) {
- l = min(n - i, P9_MAXWELEM);
- /*
- * We need to hold rename lock when doing a multipath
- * walk to ensure none of the patch component change
- */
- fid = p9_client_walk(fid, l, &wnames[i], clone);
- if (IS_ERR(fid)) {
- if (old_fid) {
- /*
- * If we fail, clunk fid which are mapping
- * to path component and not the last component
- * of the path.
- */
- p9_client_clunk(old_fid);
- }
- kfree(wnames);
- goto err_out;
- }
- old_fid = fid;
- i += l;
- clone = 0;
- }
- kfree(wnames);
-fid_out:
- if (!IS_ERR(fid)) {
- spin_lock(&dentry->d_lock);
- if (d_unhashed(dentry)) {
- spin_unlock(&dentry->d_lock);
- p9_client_clunk(fid);
- fid = ERR_PTR(-ENOENT);
- } else {
- __add_fid(dentry, fid);
- spin_unlock(&dentry->d_lock);
- }
- }
-err_out:
- up_read(&v9ses->rename_sem);
- return fid;
-}
-
-/**
- * v9fs_fid_lookup - lookup for a fid, try to walk if not found
- * @dentry: dentry to look for fid in
- *
- * Look for a fid in the specified dentry for the current user.
- * If no fid is found, try to create one walking from a fid from the parent
- * dentry (if it has one), or the root dentry. If the user haven't accessed
- * the fs yet, attach now and walk from the root.
- */
-
-struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
-{
- kuid_t uid;
- int any, access;
- struct v9fs_session_info *v9ses;
-
- v9ses = v9fs_dentry2v9ses(dentry);
- access = v9ses->flags & V9FS_ACCESS_MASK;
- switch (access) {
- case V9FS_ACCESS_SINGLE:
- case V9FS_ACCESS_USER:
- case V9FS_ACCESS_CLIENT:
- uid = current_fsuid();
- any = 0;
- break;
-
- case V9FS_ACCESS_ANY:
- uid = v9ses->uid;
- any = 1;
- break;
-
- default:
- uid = INVALID_UID;
- any = 0;
- break;
- }
- return v9fs_fid_lookup_with_uid(dentry, uid, any);
-}
-
-struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
-{
- struct p9_fid *fid, *ret;
-
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return fid;
-
- ret = p9_client_walk(fid, 0, NULL, 1);
- return ret;
-}
-
-static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
-{
- struct p9_fid *fid, *ret;
-
- fid = v9fs_fid_lookup_with_uid(dentry, uid, 0);
- if (IS_ERR(fid))
- return fid;
-
- ret = p9_client_walk(fid, 0, NULL, 1);
- return ret;
-}
-
-struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
-{
- int err;
- struct p9_fid *fid;
-
- fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
- if (IS_ERR(fid))
- goto error_out;
- /*
- * writeback fid will only be used to write back the
- * dirty pages. We always request for the open fid in read-write
- * mode so that a partial page write which result in page
- * read can work.
- */
- err = p9_client_open(fid, O_RDWR);
- if (err < 0) {
- p9_client_clunk(fid);
- fid = ERR_PTR(err);
- goto error_out;
- }
-error_out:
- return fid;
-}
diff --git a/addons/9p/src/3.10.108/fid.h b/addons/9p/src/3.10.108/fid.h
deleted file mode 100644
index 2b6787fc..00000000
--- a/addons/9p/src/3.10.108/fid.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * V9FS FID Management
- *
- * Copyright (C) 2005 by Eric Van Hensbergen
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-#ifndef FS_9P_FID_H
-#define FS_9P_FID_H
-#include
-
-struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
-struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
-void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
-struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
-#endif
diff --git a/addons/9p/src/3.10.108/mod.c b/addons/9p/src/3.10.108/mod.c
deleted file mode 100644
index 6ab36aea..00000000
--- a/addons/9p/src/3.10.108/mod.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * net/9p/9p.c
- *
- * 9P entry point
- *
- * Copyright (C) 2007 by Latchesar Ionkov
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef CONFIG_NET_9P_DEBUG
-unsigned int p9_debug_level = 0; /* feature-rific global debug level */
-EXPORT_SYMBOL(p9_debug_level);
-module_param_named(debug, p9_debug_level, uint, 0);
-MODULE_PARM_DESC(debug, "9P debugging level");
-
-void _p9_debug(enum p9_debug_flags level, const char *func,
- const char *fmt, ...)
-{
- struct va_format vaf;
- va_list args;
-
- if ((p9_debug_level & level) != level)
- return;
-
- va_start(args, fmt);
-
- vaf.fmt = fmt;
- vaf.va = &args;
-
- if (level == P9_DEBUG_9P)
- pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
- else
- pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
-
- va_end(args);
-}
-EXPORT_SYMBOL(_p9_debug);
-#endif
-
-/*
- * Dynamic Transport Registration Routines
- *
- */
-
-static DEFINE_SPINLOCK(v9fs_trans_lock);
-static LIST_HEAD(v9fs_trans_list);
-
-/**
- * v9fs_register_trans - register a new transport with 9p
- * @m: structure describing the transport module and entry points
- *
- */
-void v9fs_register_trans(struct p9_trans_module *m)
-{
- spin_lock(&v9fs_trans_lock);
- list_add_tail(&m->list, &v9fs_trans_list);
- spin_unlock(&v9fs_trans_lock);
-}
-EXPORT_SYMBOL(v9fs_register_trans);
-
-/**
- * v9fs_unregister_trans - unregister a 9p transport
- * @m: the transport to remove
- *
- */
-void v9fs_unregister_trans(struct p9_trans_module *m)
-{
- spin_lock(&v9fs_trans_lock);
- list_del_init(&m->list);
- spin_unlock(&v9fs_trans_lock);
-}
-EXPORT_SYMBOL(v9fs_unregister_trans);
-
-/**
- * v9fs_get_trans_by_name - get transport with the matching name
- * @name: string identifying transport
- *
- */
-struct p9_trans_module *v9fs_get_trans_by_name(char *s)
-{
- struct p9_trans_module *t, *found = NULL;
-
- spin_lock(&v9fs_trans_lock);
-
- list_for_each_entry(t, &v9fs_trans_list, list)
- if (strcmp(t->name, s) == 0 &&
- try_module_get(t->owner)) {
- found = t;
- break;
- }
-
- spin_unlock(&v9fs_trans_lock);
- return found;
-}
-EXPORT_SYMBOL(v9fs_get_trans_by_name);
-
-/**
- * v9fs_get_default_trans - get the default transport
- *
- */
-
-struct p9_trans_module *v9fs_get_default_trans(void)
-{
- struct p9_trans_module *t, *found = NULL;
-
- spin_lock(&v9fs_trans_lock);
-
- list_for_each_entry(t, &v9fs_trans_list, list)
- if (t->def && try_module_get(t->owner)) {
- found = t;
- break;
- }
-
- if (!found)
- list_for_each_entry(t, &v9fs_trans_list, list)
- if (try_module_get(t->owner)) {
- found = t;
- break;
- }
-
- spin_unlock(&v9fs_trans_lock);
- return found;
-}
-EXPORT_SYMBOL(v9fs_get_default_trans);
-
-/**
- * v9fs_put_trans - put trans
- * @m: transport to put
- *
- */
-void v9fs_put_trans(struct p9_trans_module *m)
-{
- if (m)
- module_put(m->owner);
-}
-
-/**
- * init_p9 - Initialize module
- *
- */
-static int __init init_p9(void)
-{
- int ret = 0;
-
- p9_error_init();
- pr_info("Installing 9P2000 support\n");
- p9_trans_fd_init();
-
- return ret;
-}
-
-/**
- * exit_p9 - shutdown module
- *
- */
-
-static void __exit exit_p9(void)
-{
- pr_info("Unloading 9P2000 support\n");
-
- p9_trans_fd_exit();
-}
-
-module_init(init_p9)
-module_exit(exit_p9)
-
-MODULE_AUTHOR("Latchesar Ionkov ");
-MODULE_AUTHOR("Eric Van Hensbergen ");
-MODULE_AUTHOR("Ron Minnich ");
-MODULE_LICENSE("GPL");
diff --git a/addons/9p/src/3.10.108/protocol.c b/addons/9p/src/3.10.108/protocol.c
deleted file mode 100644
index ab9127ec..00000000
--- a/addons/9p/src/3.10.108/protocol.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * net/9p/protocol.c
- *
- * 9P Protocol Support Code
- *
- * Copyright (C) 2008 by Eric Van Hensbergen
- *
- * Base on code from Anthony Liguori
- * Copyright (C) 2008 by IBM, Corp.
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "protocol.h"
-
-#include
-
-static int
-p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
-
-void p9stat_free(struct p9_wstat *stbuf)
-{
- kfree(stbuf->name);
- kfree(stbuf->uid);
- kfree(stbuf->gid);
- kfree(stbuf->muid);
- kfree(stbuf->extension);
-}
-EXPORT_SYMBOL(p9stat_free);
-
-size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
-{
- size_t len = min(pdu->size - pdu->offset, size);
- memcpy(data, &pdu->sdata[pdu->offset], len);
- pdu->offset += len;
- return size - len;
-}
-
-static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
-{
- size_t len = min(pdu->capacity - pdu->size, size);
- memcpy(&pdu->sdata[pdu->size], data, len);
- pdu->size += len;
- return size - len;
-}
-
-static size_t
-pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
-{
- size_t len = min(pdu->capacity - pdu->size, size);
- if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
- len = 0;
-
- pdu->size += len;
- return size - len;
-}
-
-/*
- b - int8_t
- w - int16_t
- d - int32_t
- q - int64_t
- s - string
- u - numeric uid
- g - numeric gid
- S - stat
- Q - qid
- D - data blob (int32_t size followed by void *, results are not freed)
- T - array of strings (int16_t count, followed by strings)
- R - array of qids (int16_t count, followed by qids)
- A - stat for 9p2000.L (p9_stat_dotl)
- ? - if optional = 1, continue parsing
-*/
-
-static int
-p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
- va_list ap)
-{
- const char *ptr;
- int errcode = 0;
-
- for (ptr = fmt; *ptr; ptr++) {
- switch (*ptr) {
- case 'b':{
- int8_t *val = va_arg(ap, int8_t *);
- if (pdu_read(pdu, val, sizeof(*val))) {
- errcode = -EFAULT;
- break;
- }
- }
- break;
- case 'w':{
- int16_t *val = va_arg(ap, int16_t *);
- __le16 le_val;
- if (pdu_read(pdu, &le_val, sizeof(le_val))) {
- errcode = -EFAULT;
- break;
- }
- *val = le16_to_cpu(le_val);
- }
- break;
- case 'd':{
- int32_t *val = va_arg(ap, int32_t *);
- __le32 le_val;
- if (pdu_read(pdu, &le_val, sizeof(le_val))) {
- errcode = -EFAULT;
- break;
- }
- *val = le32_to_cpu(le_val);
- }
- break;
- case 'q':{
- int64_t *val = va_arg(ap, int64_t *);
- __le64 le_val;
- if (pdu_read(pdu, &le_val, sizeof(le_val))) {
- errcode = -EFAULT;
- break;
- }
- *val = le64_to_cpu(le_val);
- }
- break;
- case 's':{
- char **sptr = va_arg(ap, char **);
- uint16_t len;
-
- errcode = p9pdu_readf(pdu, proto_version,
- "w", &len);
- if (errcode)
- break;
-
- *sptr = kmalloc(len + 1, GFP_NOFS);
- if (*sptr == NULL) {
- errcode = -EFAULT;
- break;
- }
- if (pdu_read(pdu, *sptr, len)) {
- errcode = -EFAULT;
- kfree(*sptr);
- *sptr = NULL;
- } else
- (*sptr)[len] = 0;
- }
- break;
- case 'u': {
- kuid_t *uid = va_arg(ap, kuid_t *);
- __le32 le_val;
- if (pdu_read(pdu, &le_val, sizeof(le_val))) {
- errcode = -EFAULT;
- break;
- }
- *uid = make_kuid(&init_user_ns,
- le32_to_cpu(le_val));
- } break;
- case 'g': {
- kgid_t *gid = va_arg(ap, kgid_t *);
- __le32 le_val;
- if (pdu_read(pdu, &le_val, sizeof(le_val))) {
- errcode = -EFAULT;
- break;
- }
- *gid = make_kgid(&init_user_ns,
- le32_to_cpu(le_val));
- } break;
- case 'Q':{
- struct p9_qid *qid =
- va_arg(ap, struct p9_qid *);
-
- errcode = p9pdu_readf(pdu, proto_version, "bdq",
- &qid->type, &qid->version,
- &qid->path);
- }
- break;
- case 'S':{
- struct p9_wstat *stbuf =
- va_arg(ap, struct p9_wstat *);
-
- memset(stbuf, 0, sizeof(struct p9_wstat));
- stbuf->n_uid = stbuf->n_muid = INVALID_UID;
- stbuf->n_gid = INVALID_GID;
-
- errcode =
- p9pdu_readf(pdu, proto_version,
- "wwdQdddqssss?sugu",
- &stbuf->size, &stbuf->type,
- &stbuf->dev, &stbuf->qid,
- &stbuf->mode, &stbuf->atime,
- &stbuf->mtime, &stbuf->length,
- &stbuf->name, &stbuf->uid,
- &stbuf->gid, &stbuf->muid,
- &stbuf->extension,
- &stbuf->n_uid, &stbuf->n_gid,
- &stbuf->n_muid);
- if (errcode)
- p9stat_free(stbuf);
- }
- break;
- case 'D':{
- uint32_t *count = va_arg(ap, uint32_t *);
- void **data = va_arg(ap, void **);
-
- errcode =
- p9pdu_readf(pdu, proto_version, "d", count);
- if (!errcode) {
- *count =
- min_t(uint32_t, *count,
- pdu->size - pdu->offset);
- *data = &pdu->sdata[pdu->offset];
- }
- }
- break;
- case 'T':{
- uint16_t *nwname = va_arg(ap, uint16_t *);
- char ***wnames = va_arg(ap, char ***);
-
- errcode = p9pdu_readf(pdu, proto_version,
- "w", nwname);
- if (!errcode) {
- *wnames =
- kmalloc(sizeof(char *) * *nwname,
- GFP_NOFS);
- if (!*wnames)
- errcode = -ENOMEM;
- }
-
- if (!errcode) {
- int i;
-
- for (i = 0; i < *nwname; i++) {
- errcode =
- p9pdu_readf(pdu,
- proto_version,
- "s",
- &(*wnames)[i]);
- if (errcode)
- break;
- }
- }
-
- if (errcode) {
- if (*wnames) {
- int i;
-
- for (i = 0; i < *nwname; i++)
- kfree((*wnames)[i]);
- }
- kfree(*wnames);
- *wnames = NULL;
- }
- }
- break;
- case 'R':{
- int16_t *nwqid = va_arg(ap, int16_t *);
- struct p9_qid **wqids =
- va_arg(ap, struct p9_qid **);
-
- *wqids = NULL;
-
- errcode =
- p9pdu_readf(pdu, proto_version, "w", nwqid);
- if (!errcode) {
- *wqids =
- kmalloc(*nwqid *
- sizeof(struct p9_qid),
- GFP_NOFS);
- if (*wqids == NULL)
- errcode = -ENOMEM;
- }
-
- if (!errcode) {
- int i;
-
- for (i = 0; i < *nwqid; i++) {
- errcode =
- p9pdu_readf(pdu,
- proto_version,
- "Q",
- &(*wqids)[i]);
- if (errcode)
- break;
- }
- }
-
- if (errcode) {
- kfree(*wqids);
- *wqids = NULL;
- }
- }
- break;
- case 'A': {
- struct p9_stat_dotl *stbuf =
- va_arg(ap, struct p9_stat_dotl *);
-
- memset(stbuf, 0, sizeof(struct p9_stat_dotl));
- errcode =
- p9pdu_readf(pdu, proto_version,
- "qQdugqqqqqqqqqqqqqqq",
- &stbuf->st_result_mask,
- &stbuf->qid,
- &stbuf->st_mode,
- &stbuf->st_uid, &stbuf->st_gid,
- &stbuf->st_nlink,
- &stbuf->st_rdev, &stbuf->st_size,
- &stbuf->st_blksize, &stbuf->st_blocks,
- &stbuf->st_atime_sec,
- &stbuf->st_atime_nsec,
- &stbuf->st_mtime_sec,
- &stbuf->st_mtime_nsec,
- &stbuf->st_ctime_sec,
- &stbuf->st_ctime_nsec,
- &stbuf->st_btime_sec,
- &stbuf->st_btime_nsec,
- &stbuf->st_gen,
- &stbuf->st_data_version);
- }
- break;
- case '?':
- if ((proto_version != p9_proto_2000u) &&
- (proto_version != p9_proto_2000L))
- return 0;
- break;
- default:
- BUG();
- break;
- }
-
- if (errcode)
- break;
- }
-
- return errcode;
-}
-
-int
-p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
- va_list ap)
-{
- const char *ptr;
- int errcode = 0;
-
- for (ptr = fmt; *ptr; ptr++) {
- switch (*ptr) {
- case 'b':{
- int8_t val = va_arg(ap, int);
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- }
- break;
- case 'w':{
- __le16 val = cpu_to_le16(va_arg(ap, int));
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- }
- break;
- case 'd':{
- __le32 val = cpu_to_le32(va_arg(ap, int32_t));
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- }
- break;
- case 'q':{
- __le64 val = cpu_to_le64(va_arg(ap, int64_t));
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- }
- break;
- case 's':{
- const char *sptr = va_arg(ap, const char *);
- uint16_t len = 0;
- if (sptr)
- len = min_t(size_t, strlen(sptr),
- USHRT_MAX);
-
- errcode = p9pdu_writef(pdu, proto_version,
- "w", len);
- if (!errcode && pdu_write(pdu, sptr, len))
- errcode = -EFAULT;
- }
- break;
- case 'u': {
- kuid_t uid = va_arg(ap, kuid_t);
- __le32 val = cpu_to_le32(
- from_kuid(&init_user_ns, uid));
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- } break;
- case 'g': {
- kgid_t gid = va_arg(ap, kgid_t);
- __le32 val = cpu_to_le32(
- from_kgid(&init_user_ns, gid));
- if (pdu_write(pdu, &val, sizeof(val)))
- errcode = -EFAULT;
- } break;
- case 'Q':{
- const struct p9_qid *qid =
- va_arg(ap, const struct p9_qid *);
- errcode =
- p9pdu_writef(pdu, proto_version, "bdq",
- qid->type, qid->version,
- qid->path);
- } break;
- case 'S':{
- const struct p9_wstat *stbuf =
- va_arg(ap, const struct p9_wstat *);
- errcode =
- p9pdu_writef(pdu, proto_version,
- "wwdQdddqssss?sugu",
- stbuf->size, stbuf->type,
- stbuf->dev, &stbuf->qid,
- stbuf->mode, stbuf->atime,
- stbuf->mtime, stbuf->length,
- stbuf->name, stbuf->uid,
- stbuf->gid, stbuf->muid,
- stbuf->extension, stbuf->n_uid,
- stbuf->n_gid, stbuf->n_muid);
- } break;
- case 'D':{
- uint32_t count = va_arg(ap, uint32_t);
- const void *data = va_arg(ap, const void *);
-
- errcode = p9pdu_writef(pdu, proto_version, "d",
- count);
- if (!errcode && pdu_write(pdu, data, count))
- errcode = -EFAULT;
- }
- break;
- case 'U':{
- int32_t count = va_arg(ap, int32_t);
- const char __user *udata =
- va_arg(ap, const void __user *);
- errcode = p9pdu_writef(pdu, proto_version, "d",
- count);
- if (!errcode && pdu_write_u(pdu, udata, count))
- errcode = -EFAULT;
- }
- break;
- case 'T':{
- uint16_t nwname = va_arg(ap, int);
- const char **wnames = va_arg(ap, const char **);
-
- errcode = p9pdu_writef(pdu, proto_version, "w",
- nwname);
- if (!errcode) {
- int i;
-
- for (i = 0; i < nwname; i++) {
- errcode =
- p9pdu_writef(pdu,
- proto_version,
- "s",
- wnames[i]);
- if (errcode)
- break;
- }
- }
- }
- break;
- case 'R':{
- int16_t nwqid = va_arg(ap, int);
- struct p9_qid *wqids =
- va_arg(ap, struct p9_qid *);
-
- errcode = p9pdu_writef(pdu, proto_version, "w",
- nwqid);
- if (!errcode) {
- int i;
-
- for (i = 0; i < nwqid; i++) {
- errcode =
- p9pdu_writef(pdu,
- proto_version,
- "Q",
- &wqids[i]);
- if (errcode)
- break;
- }
- }
- }
- break;
- case 'I':{
- struct p9_iattr_dotl *p9attr = va_arg(ap,
- struct p9_iattr_dotl *);
-
- errcode = p9pdu_writef(pdu, proto_version,
- "ddugqqqqq",
- p9attr->valid,
- p9attr->mode,
- p9attr->uid,
- p9attr->gid,
- p9attr->size,
- p9attr->atime_sec,
- p9attr->atime_nsec,
- p9attr->mtime_sec,
- p9attr->mtime_nsec);
- }
- break;
- case '?':
- if ((proto_version != p9_proto_2000u) &&
- (proto_version != p9_proto_2000L))
- return 0;
- break;
- default:
- BUG();
- break;
- }
-
- if (errcode)
- break;
- }
-
- return errcode;
-}
-
-int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-static int
-p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
-{
- struct p9_fcall fake_pdu;
- int ret;
-
- fake_pdu.size = len;
- fake_pdu.capacity = len;
- fake_pdu.sdata = buf;
- fake_pdu.offset = 0;
-
- ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
- if (ret) {
- p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
- trace_9p_protocol_dump(clnt, &fake_pdu);
- }
-
- return ret;
-}
-EXPORT_SYMBOL(p9stat_read);
-
-int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
-{
- pdu->id = type;
- return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
-}
-
-int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
-{
- int size = pdu->size;
- int err;
-
- pdu->size = 0;
- err = p9pdu_writef(pdu, 0, "d", size);
- pdu->size = size;
-
- trace_9p_protocol_dump(clnt, pdu);
- p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
- pdu->size, pdu->id, pdu->tag);
-
- return err;
-}
-
-void p9pdu_reset(struct p9_fcall *pdu)
-{
- pdu->offset = 0;
- pdu->size = 0;
-}
-
-int p9dirent_read(struct p9_client *clnt, char *buf, int len,
- struct p9_dirent *dirent)
-{
- struct p9_fcall fake_pdu;
- int ret;
- char *nameptr;
-
- fake_pdu.size = len;
- fake_pdu.capacity = len;
- fake_pdu.sdata = buf;
- fake_pdu.offset = 0;
-
- ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
- &dirent->d_off, &dirent->d_type, &nameptr);
- if (ret) {
- p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
- trace_9p_protocol_dump(clnt, &fake_pdu);
- goto out;
- }
-
- strcpy(dirent->d_name, nameptr);
- kfree(nameptr);
-
-out:
- return fake_pdu.offset;
-}
-EXPORT_SYMBOL(p9dirent_read);
diff --git a/addons/9p/src/3.10.108/protocol.h b/addons/9p/src/3.10.108/protocol.h
deleted file mode 100644
index 2cc525fa..00000000
--- a/addons/9p/src/3.10.108/protocol.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * net/9p/protocol.h
- *
- * 9P Protocol Support Code
- *
- * Copyright (C) 2008 by Eric Van Hensbergen
- *
- * Base on code from Anthony Liguori
- * Copyright (C) 2008 by IBM, Corp.
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
- va_list ap);
-int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
-int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
-int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu);
-void p9pdu_reset(struct p9_fcall *pdu);
-size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size);
diff --git a/addons/9p/src/3.10.108/trans_common.c b/addons/9p/src/3.10.108/trans_common.c
deleted file mode 100644
index 2ee38791..00000000
--- a/addons/9p/src/3.10.108/trans_common.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Venkateswararao Jujjuri
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "trans_common.h"
-
-/**
- * p9_release_req_pages - Release pages after the transaction.
- */
-void p9_release_pages(struct page **pages, int nr_pages)
-{
- int i;
-
- for (i = 0; i < nr_pages; i++)
- if (pages[i])
- put_page(pages[i]);
-}
-EXPORT_SYMBOL(p9_release_pages);
-
-/**
- * p9_nr_pages - Return number of pages needed to accommodate the payload.
- */
-int p9_nr_pages(char *data, int len)
-{
- unsigned long start_page, end_page;
- start_page = (unsigned long)data >> PAGE_SHIFT;
- end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
- return end_page - start_page;
-}
-EXPORT_SYMBOL(p9_nr_pages);
-
-/**
- * payload_gup - Translates user buffer into kernel pages and
- * pins them either for read/write through get_user_pages_fast().
- * @req: Request to be sent to server.
- * @pdata_off: data offset into the first page after translation (gup).
- * @pdata_len: Total length of the IO. gup may not return requested # of pages.
- * @nr_pages: number of pages to accommodate the payload
- * @rw: Indicates if the pages are for read or write.
- */
-
-int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
-{
- int nr_mapped_pages;
-
- nr_mapped_pages = get_user_pages_fast((unsigned long)data,
- *nr_pages, write, pages);
- if (nr_mapped_pages <= 0)
- return nr_mapped_pages;
-
- *nr_pages = nr_mapped_pages;
- return 0;
-}
-EXPORT_SYMBOL(p9_payload_gup);
diff --git a/addons/9p/src/3.10.108/trans_common.h b/addons/9p/src/3.10.108/trans_common.h
deleted file mode 100644
index 173bb550..00000000
--- a/addons/9p/src/3.10.108/trans_common.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Venkateswararao Jujjuri
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-void p9_release_pages(struct page **, int);
-int p9_payload_gup(char *, int *, struct page **, int);
-int p9_nr_pages(char *, int);
diff --git a/addons/9p/src/3.10.108/trans_fd.c b/addons/9p/src/3.10.108/trans_fd.c
deleted file mode 100644
index 02efb25c..00000000
--- a/addons/9p/src/3.10.108/trans_fd.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * linux/fs/9p/trans_fd.c
- *
- * Fd transport layer. Includes deprecated socket layer.
- *
- * Copyright (C) 2006 by Russ Cox
- * Copyright (C) 2004-2005 by Latchesar Ionkov
- * Copyright (C) 2004-2008 by Eric Van Hensbergen
- * Copyright (C) 1997-2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include /* killme */
-
-#define P9_PORT 564
-#define MAX_SOCK_BUF (64*1024)
-#define MAXPOLLWADDR 2
-
-/**
- * struct p9_fd_opts - per-transport options
- * @rfd: file descriptor for reading (trans=fd)
- * @wfd: file descriptor for writing (trans=fd)
- * @port: port to connect to (trans=tcp)
- *
- */
-
-struct p9_fd_opts {
- int rfd;
- int wfd;
- u16 port;
-};
-
-/**
- * struct p9_trans_fd - transport state
- * @rd: reference to file to read from
- * @wr: reference of file to write to
- * @conn: connection state reference
- *
- */
-
-struct p9_trans_fd {
- struct file *rd;
- struct file *wr;
- struct p9_conn *conn;
-};
-
-/*
- * Option Parsing (code inspired by NFS code)
- * - a little lazy - parse all fd-transport options
- */
-
-enum {
- /* Options that take integer arguments */
- Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
-};
-
-static const match_table_t tokens = {
- {Opt_port, "port=%u"},
- {Opt_rfdno, "rfdno=%u"},
- {Opt_wfdno, "wfdno=%u"},
- {Opt_err, NULL},
-};
-
-enum {
- Rworksched = 1, /* read work scheduled or running */
- Rpending = 2, /* can read */
- Wworksched = 4, /* write work scheduled or running */
- Wpending = 8, /* can write */
-};
-
-struct p9_poll_wait {
- struct p9_conn *conn;
- wait_queue_t wait;
- wait_queue_head_t *wait_addr;
-};
-
-/**
- * struct p9_conn - fd mux connection state information
- * @mux_list: list link for mux to manage multiple connections (?)
- * @client: reference to client instance for this connection
- * @err: error state
- * @req_list: accounting for requests which have been sent
- * @unsent_req_list: accounting for requests that haven't been sent
- * @req: current request being processed (if any)
- * @tmp_buf: temporary buffer to read in header
- * @rsize: amount to read for current frame
- * @rpos: read position in current frame
- * @rbuf: current read buffer
- * @wpos: write position for current frame
- * @wsize: amount of data to write for current frame
- * @wbuf: current write buffer
- * @poll_pending_link: pending links to be polled per conn
- * @poll_wait: array of wait_q's for various worker threads
- * @pt: poll state
- * @rq: current read work
- * @wq: current write work
- * @wsched: ????
- *
- */
-
-struct p9_conn {
- struct list_head mux_list;
- struct p9_client *client;
- int err;
- struct list_head req_list;
- struct list_head unsent_req_list;
- struct p9_req_t *req;
- char tmp_buf[7];
- int rsize;
- int rpos;
- char *rbuf;
- int wpos;
- int wsize;
- char *wbuf;
- struct list_head poll_pending_link;
- struct p9_poll_wait poll_wait[MAXPOLLWADDR];
- poll_table pt;
- struct work_struct rq;
- struct work_struct wq;
- unsigned long wsched;
-};
-
-static void p9_poll_workfn(struct work_struct *work);
-
-static DEFINE_SPINLOCK(p9_poll_lock);
-static LIST_HEAD(p9_poll_pending_list);
-static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
-
-static void p9_mux_poll_stop(struct p9_conn *m)
-{
- unsigned long flags;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
- struct p9_poll_wait *pwait = &m->poll_wait[i];
-
- if (pwait->wait_addr) {
- remove_wait_queue(pwait->wait_addr, &pwait->wait);
- pwait->wait_addr = NULL;
- }
- }
-
- spin_lock_irqsave(&p9_poll_lock, flags);
- list_del_init(&m->poll_pending_link);
- spin_unlock_irqrestore(&p9_poll_lock, flags);
-}
-
-/**
- * p9_conn_cancel - cancel all pending requests with error
- * @m: mux data
- * @err: error code
- *
- */
-
-static void p9_conn_cancel(struct p9_conn *m, int err)
-{
- struct p9_req_t *req, *rtmp;
- unsigned long flags;
- LIST_HEAD(cancel_list);
-
- p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
-
- spin_lock_irqsave(&m->client->lock, flags);
-
- if (m->err) {
- spin_unlock_irqrestore(&m->client->lock, flags);
- return;
- }
-
- m->err = err;
-
- list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
- req->status = REQ_STATUS_ERROR;
- if (!req->t_err)
- req->t_err = err;
- list_move(&req->req_list, &cancel_list);
- }
- list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
- req->status = REQ_STATUS_ERROR;
- if (!req->t_err)
- req->t_err = err;
- list_move(&req->req_list, &cancel_list);
- }
- spin_unlock_irqrestore(&m->client->lock, flags);
-
- list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
- p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
- list_del(&req->req_list);
- p9_client_cb(m->client, req);
- }
-}
-
-static int
-p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
-{
- int ret, n;
- struct p9_trans_fd *ts = NULL;
-
- if (client && client->status == Connected)
- ts = client->trans;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!ts->rd->f_op || !ts->rd->f_op->poll)
- return -EIO;
-
- if (!ts->wr->f_op || !ts->wr->f_op->poll)
- return -EIO;
-
- ret = ts->rd->f_op->poll(ts->rd, pt);
- if (ret < 0)
- return ret;
-
- if (ts->rd != ts->wr) {
- n = ts->wr->f_op->poll(ts->wr, pt);
- if (n < 0)
- return n;
- ret = (ret & ~POLLOUT) | (n & ~POLLIN);
- }
-
- return ret;
-}
-
-/**
- * p9_fd_read- read from a fd
- * @client: client instance
- * @v: buffer to receive data into
- * @len: size of receive buffer
- *
- */
-
-static int p9_fd_read(struct p9_client *client, void *v, int len)
-{
- int ret;
- struct p9_trans_fd *ts = NULL;
-
- if (client && client->status != Disconnected)
- ts = client->trans;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!(ts->rd->f_flags & O_NONBLOCK))
- p9_debug(P9_DEBUG_ERROR, "blocking read ...\n");
-
- ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
- if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- client->status = Disconnected;
- return ret;
-}
-
-/**
- * p9_read_work - called when there is some data to be read from a transport
- * @work: container of work to be done
- *
- */
-
-static void p9_read_work(struct work_struct *work)
-{
- int n, err;
- struct p9_conn *m;
-
- m = container_of(work, struct p9_conn, rq);
-
- if (m->err < 0)
- return;
-
- p9_debug(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos);
-
- if (!m->rbuf) {
- m->rbuf = m->tmp_buf;
- m->rpos = 0;
- m->rsize = 7; /* start by reading header */
- }
-
- clear_bit(Rpending, &m->wsched);
- p9_debug(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n",
- m, m->rpos, m->rsize, m->rsize-m->rpos);
- err = p9_fd_read(m->client, m->rbuf + m->rpos,
- m->rsize - m->rpos);
- p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
- if (err == -EAGAIN) {
- goto end_clear;
- }
-
- if (err <= 0)
- goto error;
-
- m->rpos += err;
-
- if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
- u16 tag;
- p9_debug(P9_DEBUG_TRANS, "got new header\n");
-
- n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
- if (n >= m->client->msize) {
- p9_debug(P9_DEBUG_ERROR,
- "requested packet size too big: %d\n", n);
- err = -EIO;
- goto error;
- }
-
- tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
- p9_debug(P9_DEBUG_TRANS,
- "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
-
- m->req = p9_tag_lookup(m->client, tag);
- if (!m->req || (m->req->status != REQ_STATUS_SENT &&
- m->req->status != REQ_STATUS_FLSH)) {
- p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
- tag);
- err = -EIO;
- goto error;
- }
-
- if (m->req->rc == NULL) {
- m->req->rc = kmalloc(sizeof(struct p9_fcall) +
- m->client->msize, GFP_NOFS);
- if (!m->req->rc) {
- m->req = NULL;
- err = -ENOMEM;
- goto error;
- }
- }
- m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
- memcpy(m->rbuf, m->tmp_buf, m->rsize);
- m->rsize = n;
- }
-
- /* not an else because some packets (like clunk) have no payload */
- if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
- p9_debug(P9_DEBUG_TRANS, "got new packet\n");
- spin_lock(&m->client->lock);
- if (m->req->status != REQ_STATUS_ERROR)
- m->req->status = REQ_STATUS_RCVD;
- list_del(&m->req->req_list);
- spin_unlock(&m->client->lock);
- p9_client_cb(m->client, m->req);
- m->rbuf = NULL;
- m->rpos = 0;
- m->rsize = 0;
- m->req = NULL;
- }
-
-end_clear:
- clear_bit(Rworksched, &m->wsched);
-
- if (!list_empty(&m->req_list)) {
- if (test_and_clear_bit(Rpending, &m->wsched))
- n = POLLIN;
- else
- n = p9_fd_poll(m->client, NULL);
-
- if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
- p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
- schedule_work(&m->rq);
- }
- }
-
- return;
-error:
- p9_conn_cancel(m, err);
- clear_bit(Rworksched, &m->wsched);
-}
-
-/**
- * p9_fd_write - write to a socket
- * @client: client instance
- * @v: buffer to send data from
- * @len: size of send buffer
- *
- */
-
-static int p9_fd_write(struct p9_client *client, void *v, int len)
-{
- int ret;
- mm_segment_t oldfs;
- struct p9_trans_fd *ts = NULL;
-
- if (client && client->status != Disconnected)
- ts = client->trans;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!(ts->wr->f_flags & O_NONBLOCK))
- p9_debug(P9_DEBUG_ERROR, "blocking write ...\n");
-
- oldfs = get_fs();
- set_fs(get_ds());
- /* The cast to a user pointer is valid due to the set_fs() */
- ret = vfs_write(ts->wr, (__force void __user *)v, len, &ts->wr->f_pos);
- set_fs(oldfs);
-
- if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- client->status = Disconnected;
- return ret;
-}
-
-/**
- * p9_write_work - called when a transport can send some data
- * @work: container for work to be done
- *
- */
-
-static void p9_write_work(struct work_struct *work)
-{
- int n, err;
- struct p9_conn *m;
- struct p9_req_t *req;
-
- m = container_of(work, struct p9_conn, wq);
-
- if (m->err < 0) {
- clear_bit(Wworksched, &m->wsched);
- return;
- }
-
- if (!m->wsize) {
- spin_lock(&m->client->lock);
- if (list_empty(&m->unsent_req_list)) {
- clear_bit(Wworksched, &m->wsched);
- spin_unlock(&m->client->lock);
- return;
- }
-
- req = list_entry(m->unsent_req_list.next, struct p9_req_t,
- req_list);
- req->status = REQ_STATUS_SENT;
- p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
- list_move_tail(&req->req_list, &m->req_list);
-
- m->wbuf = req->tc->sdata;
- m->wsize = req->tc->size;
- m->wpos = 0;
- spin_unlock(&m->client->lock);
- }
-
- p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
- m, m->wpos, m->wsize);
- clear_bit(Wpending, &m->wsched);
- err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
- p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
- if (err == -EAGAIN)
- goto end_clear;
-
-
- if (err < 0)
- goto error;
- else if (err == 0) {
- err = -EREMOTEIO;
- goto error;
- }
-
- m->wpos += err;
- if (m->wpos == m->wsize)
- m->wpos = m->wsize = 0;
-
-end_clear:
- clear_bit(Wworksched, &m->wsched);
-
- if (m->wsize || !list_empty(&m->unsent_req_list)) {
- if (test_and_clear_bit(Wpending, &m->wsched))
- n = POLLOUT;
- else
- n = p9_fd_poll(m->client, NULL);
-
- if ((n & POLLOUT) &&
- !test_and_set_bit(Wworksched, &m->wsched)) {
- p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
- schedule_work(&m->wq);
- }
- }
-
- return;
-
-error:
- p9_conn_cancel(m, err);
- clear_bit(Wworksched, &m->wsched);
-}
-
-static int p9_pollwake(wait_queue_t *wait, unsigned int mode, int sync, void *key)
-{
- struct p9_poll_wait *pwait =
- container_of(wait, struct p9_poll_wait, wait);
- struct p9_conn *m = pwait->conn;
- unsigned long flags;
-
- spin_lock_irqsave(&p9_poll_lock, flags);
- if (list_empty(&m->poll_pending_link))
- list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
- spin_unlock_irqrestore(&p9_poll_lock, flags);
-
- schedule_work(&p9_poll_work);
- return 1;
-}
-
-/**
- * p9_pollwait - add poll task to the wait queue
- * @filp: file pointer being polled
- * @wait_address: wait_q to block on
- * @p: poll state
- *
- * called by files poll operation to add v9fs-poll task to files wait queue
- */
-
-static void
-p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
-{
- struct p9_conn *m = container_of(p, struct p9_conn, pt);
- struct p9_poll_wait *pwait = NULL;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
- if (m->poll_wait[i].wait_addr == NULL) {
- pwait = &m->poll_wait[i];
- break;
- }
- }
-
- if (!pwait) {
- p9_debug(P9_DEBUG_ERROR, "not enough wait_address slots\n");
- return;
- }
-
- pwait->conn = m;
- pwait->wait_addr = wait_address;
- init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
- add_wait_queue(wait_address, &pwait->wait);
-}
-
-/**
- * p9_conn_create - allocate and initialize the per-session mux data
- * @client: client instance
- *
- * Note: Creates the polling task if this is the first session.
- */
-
-static struct p9_conn *p9_conn_create(struct p9_client *client)
-{
- int n;
- struct p9_conn *m;
-
- p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize);
- m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
- if (!m)
- return ERR_PTR(-ENOMEM);
-
- INIT_LIST_HEAD(&m->mux_list);
- m->client = client;
-
- INIT_LIST_HEAD(&m->req_list);
- INIT_LIST_HEAD(&m->unsent_req_list);
- INIT_WORK(&m->rq, p9_read_work);
- INIT_WORK(&m->wq, p9_write_work);
- INIT_LIST_HEAD(&m->poll_pending_link);
- init_poll_funcptr(&m->pt, p9_pollwait);
-
- n = p9_fd_poll(client, &m->pt);
- if (n & POLLIN) {
- p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
- set_bit(Rpending, &m->wsched);
- }
-
- if (n & POLLOUT) {
- p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
- set_bit(Wpending, &m->wsched);
- }
-
- return m;
-}
-
-/**
- * p9_poll_mux - polls a mux and schedules read or write works if necessary
- * @m: connection to poll
- *
- */
-
-static void p9_poll_mux(struct p9_conn *m)
-{
- int n;
-
- if (m->err < 0)
- return;
-
- n = p9_fd_poll(m->client, NULL);
- if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
- p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
- if (n >= 0)
- n = -ECONNRESET;
- p9_conn_cancel(m, n);
- }
-
- if (n & POLLIN) {
- set_bit(Rpending, &m->wsched);
- p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
- if (!test_and_set_bit(Rworksched, &m->wsched)) {
- p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
- schedule_work(&m->rq);
- }
- }
-
- if (n & POLLOUT) {
- set_bit(Wpending, &m->wsched);
- p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
- if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
- !test_and_set_bit(Wworksched, &m->wsched)) {
- p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
- schedule_work(&m->wq);
- }
- }
-}
-
-/**
- * p9_fd_request - send 9P request
- * The function can sleep until the request is scheduled for sending.
- * The function can be interrupted. Return from the function is not
- * a guarantee that the request is sent successfully.
- *
- * @client: client instance
- * @req: request to be sent
- *
- */
-
-static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
-{
- int n;
- struct p9_trans_fd *ts = client->trans;
- struct p9_conn *m = ts->conn;
-
- p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
- m, current, req->tc, req->tc->id);
- if (m->err < 0)
- return m->err;
-
- spin_lock(&client->lock);
- req->status = REQ_STATUS_UNSENT;
- list_add_tail(&req->req_list, &m->unsent_req_list);
- spin_unlock(&client->lock);
-
- if (test_and_clear_bit(Wpending, &m->wsched))
- n = POLLOUT;
- else
- n = p9_fd_poll(m->client, NULL);
-
- if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
- schedule_work(&m->wq);
-
- return 0;
-}
-
-static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
-{
- int ret = 1;
-
- p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
-
- spin_lock(&client->lock);
-
- if (req->status == REQ_STATUS_UNSENT) {
- list_del(&req->req_list);
- req->status = REQ_STATUS_FLSHD;
- ret = 0;
- } else if (req->status == REQ_STATUS_SENT)
- req->status = REQ_STATUS_FLSH;
-
- spin_unlock(&client->lock);
-
- return ret;
-}
-
-/**
- * parse_opts - parse mount options into p9_fd_opts structure
- * @params: options string passed from mount
- * @opts: fd transport-specific structure to parse options into
- *
- * Returns 0 upon success, -ERRNO upon failure
- */
-
-static int parse_opts(char *params, struct p9_fd_opts *opts)
-{
- char *p;
- substring_t args[MAX_OPT_ARGS];
- int option;
- char *options, *tmp_options;
-
- opts->port = P9_PORT;
- opts->rfd = ~0;
- opts->wfd = ~0;
-
- if (!params)
- return 0;
-
- tmp_options = kstrdup(params, GFP_KERNEL);
- if (!tmp_options) {
- p9_debug(P9_DEBUG_ERROR,
- "failed to allocate copy of option string\n");
- return -ENOMEM;
- }
- options = tmp_options;
-
- while ((p = strsep(&options, ",")) != NULL) {
- int token;
- int r;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
- if (token != Opt_err) {
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- continue;
- }
- }
- switch (token) {
- case Opt_port:
- opts->port = option;
- break;
- case Opt_rfdno:
- opts->rfd = option;
- break;
- case Opt_wfdno:
- opts->wfd = option;
- break;
- default:
- continue;
- }
- }
-
- kfree(tmp_options);
- return 0;
-}
-
-static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
-{
- struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
- GFP_KERNEL);
- if (!ts)
- return -ENOMEM;
-
- ts->rd = fget(rfd);
- ts->wr = fget(wfd);
- if (!ts->rd || !ts->wr) {
- if (ts->rd)
- fput(ts->rd);
- if (ts->wr)
- fput(ts->wr);
- kfree(ts);
- return -EIO;
- }
-
- client->trans = ts;
- client->status = Connected;
-
- return 0;
-}
-
-static int p9_socket_open(struct p9_client *client, struct socket *csocket)
-{
- struct p9_trans_fd *p;
- struct file *file;
- int ret;
-
- p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- csocket->sk->sk_allocation = GFP_NOIO;
- file = sock_alloc_file(csocket, 0, NULL);
- if (IS_ERR(file)) {
- pr_err("%s (%d): failed to map fd\n",
- __func__, task_pid_nr(current));
- sock_release(csocket);
- kfree(p);
- return PTR_ERR(file);
- }
-
- get_file(file);
- p->wr = p->rd = file;
- client->trans = p;
- client->status = Connected;
-
- p->rd->f_flags |= O_NONBLOCK;
-
- p->conn = p9_conn_create(client);
- if (IS_ERR(p->conn)) {
- ret = PTR_ERR(p->conn);
- p->conn = NULL;
- kfree(p);
- sockfd_put(csocket);
- sockfd_put(csocket);
- return ret;
- }
- return 0;
-}
-
-/**
- * p9_mux_destroy - cancels all pending requests and frees mux resources
- * @m: mux to destroy
- *
- */
-
-static void p9_conn_destroy(struct p9_conn *m)
-{
- p9_debug(P9_DEBUG_TRANS, "mux %p prev %p next %p\n",
- m, m->mux_list.prev, m->mux_list.next);
-
- p9_mux_poll_stop(m);
- cancel_work_sync(&m->rq);
- cancel_work_sync(&m->wq);
-
- p9_conn_cancel(m, -ECONNRESET);
-
- m->client = NULL;
- kfree(m);
-}
-
-/**
- * p9_fd_close - shutdown file descriptor transport
- * @client: client instance
- *
- */
-
-static void p9_fd_close(struct p9_client *client)
-{
- struct p9_trans_fd *ts;
-
- if (!client)
- return;
-
- ts = client->trans;
- if (!ts)
- return;
-
- client->status = Disconnected;
-
- p9_conn_destroy(ts->conn);
-
- if (ts->rd)
- fput(ts->rd);
- if (ts->wr)
- fput(ts->wr);
-
- kfree(ts);
-}
-
-/*
- * stolen from NFS - maybe should be made a generic function?
- */
-static inline int valid_ipaddr4(const char *buf)
-{
- int rc, count, in[4];
-
- rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
- if (rc != 4)
- return -EINVAL;
- for (count = 0; count < 4; count++) {
- if (in[count] > 255)
- return -EINVAL;
- }
- return 0;
-}
-
-static int
-p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
-{
- int err;
- struct socket *csocket;
- struct sockaddr_in sin_server;
- struct p9_fd_opts opts;
-
- err = parse_opts(args, &opts);
- if (err < 0)
- return err;
-
- if (valid_ipaddr4(addr) < 0)
- return -EINVAL;
-
- csocket = NULL;
-
- sin_server.sin_family = AF_INET;
- sin_server.sin_addr.s_addr = in_aton(addr);
- sin_server.sin_port = htons(opts.port);
- err = __sock_create(read_pnet(¤t->nsproxy->net_ns), PF_INET,
- SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
- if (err) {
- pr_err("%s (%d): problem creating socket\n",
- __func__, task_pid_nr(current));
- return err;
- }
-
- err = csocket->ops->connect(csocket,
- (struct sockaddr *)&sin_server,
- sizeof(struct sockaddr_in), 0);
- if (err < 0) {
- pr_err("%s (%d): problem connecting socket to %s\n",
- __func__, task_pid_nr(current), addr);
- sock_release(csocket);
- return err;
- }
-
- return p9_socket_open(client, csocket);
-}
-
-static int
-p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
-{
- int err;
- struct socket *csocket;
- struct sockaddr_un sun_server;
-
- csocket = NULL;
-
- if (strlen(addr) >= UNIX_PATH_MAX) {
- pr_err("%s (%d): address too long: %s\n",
- __func__, task_pid_nr(current), addr);
- return -ENAMETOOLONG;
- }
-
- sun_server.sun_family = PF_UNIX;
- strcpy(sun_server.sun_path, addr);
- err = __sock_create(read_pnet(¤t->nsproxy->net_ns), PF_UNIX,
- SOCK_STREAM, 0, &csocket, 1);
- if (err < 0) {
- pr_err("%s (%d): problem creating socket\n",
- __func__, task_pid_nr(current));
-
- return err;
- }
- err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
- sizeof(struct sockaddr_un) - 1, 0);
- if (err < 0) {
- pr_err("%s (%d): problem connecting socket: %s: %d\n",
- __func__, task_pid_nr(current), addr, err);
- sock_release(csocket);
- return err;
- }
-
- return p9_socket_open(client, csocket);
-}
-
-static int
-p9_fd_create(struct p9_client *client, const char *addr, char *args)
-{
- int err;
- struct p9_fd_opts opts;
- struct p9_trans_fd *p;
-
- parse_opts(args, &opts);
-
- if (opts.rfd == ~0 || opts.wfd == ~0) {
- pr_err("Insufficient options for proto=fd\n");
- return -ENOPROTOOPT;
- }
-
- err = p9_fd_open(client, opts.rfd, opts.wfd);
- if (err < 0)
- return err;
-
- p = (struct p9_trans_fd *) client->trans;
- p->conn = p9_conn_create(client);
- if (IS_ERR(p->conn)) {
- err = PTR_ERR(p->conn);
- p->conn = NULL;
- fput(p->rd);
- fput(p->wr);
- return err;
- }
-
- return 0;
-}
-
-static struct p9_trans_module p9_tcp_trans = {
- .name = "tcp",
- .maxsize = MAX_SOCK_BUF,
- .def = 1,
- .create = p9_fd_create_tcp,
- .close = p9_fd_close,
- .request = p9_fd_request,
- .cancel = p9_fd_cancel,
- .owner = THIS_MODULE,
-};
-
-static struct p9_trans_module p9_unix_trans = {
- .name = "unix",
- .maxsize = MAX_SOCK_BUF,
- .def = 0,
- .create = p9_fd_create_unix,
- .close = p9_fd_close,
- .request = p9_fd_request,
- .cancel = p9_fd_cancel,
- .owner = THIS_MODULE,
-};
-
-static struct p9_trans_module p9_fd_trans = {
- .name = "fd",
- .maxsize = MAX_SOCK_BUF,
- .def = 0,
- .create = p9_fd_create,
- .close = p9_fd_close,
- .request = p9_fd_request,
- .cancel = p9_fd_cancel,
- .owner = THIS_MODULE,
-};
-
-/**
- * p9_poll_proc - poll worker thread
- * @a: thread state and arguments
- *
- * polls all v9fs transports for new events and queues the appropriate
- * work to the work queue
- *
- */
-
-static void p9_poll_workfn(struct work_struct *work)
-{
- unsigned long flags;
-
- p9_debug(P9_DEBUG_TRANS, "start %p\n", current);
-
- spin_lock_irqsave(&p9_poll_lock, flags);
- while (!list_empty(&p9_poll_pending_list)) {
- struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
- struct p9_conn,
- poll_pending_link);
- list_del_init(&conn->poll_pending_link);
- spin_unlock_irqrestore(&p9_poll_lock, flags);
-
- p9_poll_mux(conn);
-
- spin_lock_irqsave(&p9_poll_lock, flags);
- }
- spin_unlock_irqrestore(&p9_poll_lock, flags);
-
- p9_debug(P9_DEBUG_TRANS, "finish\n");
-}
-
-int p9_trans_fd_init(void)
-{
- v9fs_register_trans(&p9_tcp_trans);
- v9fs_register_trans(&p9_unix_trans);
- v9fs_register_trans(&p9_fd_trans);
-
- return 0;
-}
-
-void p9_trans_fd_exit(void)
-{
- flush_work(&p9_poll_work);
- v9fs_unregister_trans(&p9_tcp_trans);
- v9fs_unregister_trans(&p9_unix_trans);
- v9fs_unregister_trans(&p9_fd_trans);
-}
diff --git a/addons/9p/src/3.10.108/trans_rdma.c b/addons/9p/src/3.10.108/trans_rdma.c
deleted file mode 100644
index 2c69ddd6..00000000
--- a/addons/9p/src/3.10.108/trans_rdma.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * linux/fs/9p/trans_rdma.c
- *
- * RDMA transport layer based on the trans_fd.c implementation.
- *
- * Copyright (C) 2008 by Tom Tucker
- * Copyright (C) 2006 by Russ Cox
- * Copyright (C) 2004-2005 by Latchesar Ionkov
- * Copyright (C) 2004-2008 by Eric Van Hensbergen
- * Copyright (C) 1997-2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define P9_PORT 5640
-#define P9_RDMA_SQ_DEPTH 32
-#define P9_RDMA_RQ_DEPTH 32
-#define P9_RDMA_SEND_SGE 4
-#define P9_RDMA_RECV_SGE 4
-#define P9_RDMA_IRD 0
-#define P9_RDMA_ORD 0
-#define P9_RDMA_TIMEOUT 30000 /* 30 seconds */
-#define P9_RDMA_MAXSIZE (4*4096) /* Min SGE is 4, so we can
- * safely advertise a maxsize
- * of 64k */
-
-/**
- * struct p9_trans_rdma - RDMA transport instance
- *
- * @state: tracks the transport state machine for connection setup and tear down
- * @cm_id: The RDMA CM ID
- * @pd: Protection Domain pointer
- * @qp: Queue Pair pointer
- * @cq: Completion Queue pointer
- * @dm_mr: DMA Memory Region pointer
- * @lkey: The local access only memory region key
- * @timeout: Number of uSecs to wait for connection management events
- * @sq_depth: The depth of the Send Queue
- * @sq_sem: Semaphore for the SQ
- * @rq_depth: The depth of the Receive Queue.
- * @rq_count: Count of requests in the Receive Queue.
- * @addr: The remote peer's address
- * @req_lock: Protects the active request list
- * @cm_done: Completion event for connection management tracking
- */
-struct p9_trans_rdma {
- enum {
- P9_RDMA_INIT,
- P9_RDMA_ADDR_RESOLVED,
- P9_RDMA_ROUTE_RESOLVED,
- P9_RDMA_CONNECTED,
- P9_RDMA_FLUSHING,
- P9_RDMA_CLOSING,
- P9_RDMA_CLOSED,
- } state;
- struct rdma_cm_id *cm_id;
- struct ib_pd *pd;
- struct ib_qp *qp;
- struct ib_cq *cq;
- struct ib_mr *dma_mr;
- u32 lkey;
- long timeout;
- int sq_depth;
- struct semaphore sq_sem;
- int rq_depth;
- atomic_t rq_count;
- struct sockaddr_in addr;
- spinlock_t req_lock;
-
- struct completion cm_done;
-};
-
-/**
- * p9_rdma_context - Keeps track of in-process WR
- *
- * @wc_op: The original WR op for when the CQE completes in error.
- * @busa: Bus address to unmap when the WR completes
- * @req: Keeps track of requests (send)
- * @rc: Keepts track of replies (receive)
- */
-struct p9_rdma_req;
-struct p9_rdma_context {
- enum ib_wc_opcode wc_op;
- dma_addr_t busa;
- union {
- struct p9_req_t *req;
- struct p9_fcall *rc;
- };
-};
-
-/**
- * p9_rdma_opts - Collection of mount options
- * @port: port of connection
- * @sq_depth: The requested depth of the SQ. This really doesn't need
- * to be any deeper than the number of threads used in the client
- * @rq_depth: The depth of the RQ. Should be greater than or equal to SQ depth
- * @timeout: Time to wait in msecs for CM events
- */
-struct p9_rdma_opts {
- short port;
- int sq_depth;
- int rq_depth;
- long timeout;
-};
-
-/*
- * Option Parsing (code inspired by NFS code)
- */
-enum {
- /* Options that take integer arguments */
- Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, Opt_err,
-};
-
-static match_table_t tokens = {
- {Opt_port, "port=%u"},
- {Opt_sq_depth, "sq=%u"},
- {Opt_rq_depth, "rq=%u"},
- {Opt_timeout, "timeout=%u"},
- {Opt_err, NULL},
-};
-
-/**
- * parse_opts - parse mount options into rdma options structure
- * @params: options string passed from mount
- * @opts: rdma transport-specific structure to parse options into
- *
- * Returns 0 upon success, -ERRNO upon failure
- */
-static int parse_opts(char *params, struct p9_rdma_opts *opts)
-{
- char *p;
- substring_t args[MAX_OPT_ARGS];
- int option;
- char *options, *tmp_options;
-
- opts->port = P9_PORT;
- opts->sq_depth = P9_RDMA_SQ_DEPTH;
- opts->rq_depth = P9_RDMA_RQ_DEPTH;
- opts->timeout = P9_RDMA_TIMEOUT;
-
- if (!params)
- return 0;
-
- tmp_options = kstrdup(params, GFP_KERNEL);
- if (!tmp_options) {
- p9_debug(P9_DEBUG_ERROR,
- "failed to allocate copy of option string\n");
- return -ENOMEM;
- }
- options = tmp_options;
-
- while ((p = strsep(&options, ",")) != NULL) {
- int token;
- int r;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- continue;
- }
- switch (token) {
- case Opt_port:
- opts->port = option;
- break;
- case Opt_sq_depth:
- opts->sq_depth = option;
- break;
- case Opt_rq_depth:
- opts->rq_depth = option;
- break;
- case Opt_timeout:
- opts->timeout = option;
- break;
- default:
- continue;
- }
- }
- /* RQ must be at least as large as the SQ */
- opts->rq_depth = max(opts->rq_depth, opts->sq_depth);
- kfree(tmp_options);
- return 0;
-}
-
-static int
-p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
-{
- struct p9_client *c = id->context;
- struct p9_trans_rdma *rdma = c->trans;
- switch (event->event) {
- case RDMA_CM_EVENT_ADDR_RESOLVED:
- BUG_ON(rdma->state != P9_RDMA_INIT);
- rdma->state = P9_RDMA_ADDR_RESOLVED;
- break;
-
- case RDMA_CM_EVENT_ROUTE_RESOLVED:
- BUG_ON(rdma->state != P9_RDMA_ADDR_RESOLVED);
- rdma->state = P9_RDMA_ROUTE_RESOLVED;
- break;
-
- case RDMA_CM_EVENT_ESTABLISHED:
- BUG_ON(rdma->state != P9_RDMA_ROUTE_RESOLVED);
- rdma->state = P9_RDMA_CONNECTED;
- break;
-
- case RDMA_CM_EVENT_DISCONNECTED:
- if (rdma)
- rdma->state = P9_RDMA_CLOSED;
- if (c)
- c->status = Disconnected;
- break;
-
- case RDMA_CM_EVENT_TIMEWAIT_EXIT:
- break;
-
- case RDMA_CM_EVENT_ADDR_CHANGE:
- case RDMA_CM_EVENT_ROUTE_ERROR:
- case RDMA_CM_EVENT_DEVICE_REMOVAL:
- case RDMA_CM_EVENT_MULTICAST_JOIN:
- case RDMA_CM_EVENT_MULTICAST_ERROR:
- case RDMA_CM_EVENT_REJECTED:
- case RDMA_CM_EVENT_CONNECT_REQUEST:
- case RDMA_CM_EVENT_CONNECT_RESPONSE:
- case RDMA_CM_EVENT_CONNECT_ERROR:
- case RDMA_CM_EVENT_ADDR_ERROR:
- case RDMA_CM_EVENT_UNREACHABLE:
- c->status = Disconnected;
- rdma_disconnect(rdma->cm_id);
- break;
- default:
- BUG();
- }
- complete(&rdma->cm_done);
- return 0;
-}
-
-static void
-handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma,
- struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
-{
- struct p9_req_t *req;
- int err = 0;
- int16_t tag;
-
- req = NULL;
- ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
- DMA_FROM_DEVICE);
-
- if (status != IB_WC_SUCCESS)
- goto err_out;
-
- err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
- if (err)
- goto err_out;
-
- req = p9_tag_lookup(client, tag);
- if (!req)
- goto err_out;
-
- req->rc = c->rc;
- req->status = REQ_STATUS_RCVD;
- p9_client_cb(client, req);
-
- return;
-
- err_out:
- p9_debug(P9_DEBUG_ERROR, "req %p err %d status %d\n", req, err, status);
- rdma->state = P9_RDMA_FLUSHING;
- client->status = Disconnected;
-}
-
-static void
-handle_send(struct p9_client *client, struct p9_trans_rdma *rdma,
- struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
-{
- ib_dma_unmap_single(rdma->cm_id->device,
- c->busa, c->req->tc->size,
- DMA_TO_DEVICE);
-}
-
-static void qp_event_handler(struct ib_event *event, void *context)
-{
- p9_debug(P9_DEBUG_ERROR, "QP event %d context %p\n",
- event->event, context);
-}
-
-static void cq_comp_handler(struct ib_cq *cq, void *cq_context)
-{
- struct p9_client *client = cq_context;
- struct p9_trans_rdma *rdma = client->trans;
- int ret;
- struct ib_wc wc;
-
- ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
- while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
- struct p9_rdma_context *c = (void *) (unsigned long) wc.wr_id;
-
- switch (c->wc_op) {
- case IB_WC_RECV:
- atomic_dec(&rdma->rq_count);
- handle_recv(client, rdma, c, wc.status, wc.byte_len);
- break;
-
- case IB_WC_SEND:
- handle_send(client, rdma, c, wc.status, wc.byte_len);
- up(&rdma->sq_sem);
- break;
-
- default:
- pr_err("unexpected completion type, c->wc_op=%d, wc.opcode=%d, status=%d\n",
- c->wc_op, wc.opcode, wc.status);
- break;
- }
- kfree(c);
- }
-}
-
-static void cq_event_handler(struct ib_event *e, void *v)
-{
- p9_debug(P9_DEBUG_ERROR, "CQ event %d context %p\n", e->event, v);
-}
-
-static void rdma_destroy_trans(struct p9_trans_rdma *rdma)
-{
- if (!rdma)
- return;
-
- if (rdma->dma_mr && !IS_ERR(rdma->dma_mr))
- ib_dereg_mr(rdma->dma_mr);
-
- if (rdma->qp && !IS_ERR(rdma->qp))
- ib_destroy_qp(rdma->qp);
-
- if (rdma->pd && !IS_ERR(rdma->pd))
- ib_dealloc_pd(rdma->pd);
-
- if (rdma->cq && !IS_ERR(rdma->cq))
- ib_destroy_cq(rdma->cq);
-
- if (rdma->cm_id && !IS_ERR(rdma->cm_id))
- rdma_destroy_id(rdma->cm_id);
-
- kfree(rdma);
-}
-
-static int
-post_recv(struct p9_client *client, struct p9_rdma_context *c)
-{
- struct p9_trans_rdma *rdma = client->trans;
- struct ib_recv_wr wr, *bad_wr;
- struct ib_sge sge;
-
- c->busa = ib_dma_map_single(rdma->cm_id->device,
- c->rc->sdata, client->msize,
- DMA_FROM_DEVICE);
- if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
- goto error;
-
- sge.addr = c->busa;
- sge.length = client->msize;
- sge.lkey = rdma->lkey;
-
- wr.next = NULL;
- c->wc_op = IB_WC_RECV;
- wr.wr_id = (unsigned long) c;
- wr.sg_list = &sge;
- wr.num_sge = 1;
- return ib_post_recv(rdma->qp, &wr, &bad_wr);
-
- error:
- p9_debug(P9_DEBUG_ERROR, "EIO\n");
- return -EIO;
-}
-
-static int rdma_request(struct p9_client *client, struct p9_req_t *req)
-{
- struct p9_trans_rdma *rdma = client->trans;
- struct ib_send_wr wr, *bad_wr;
- struct ib_sge sge;
- int err = 0;
- unsigned long flags;
- struct p9_rdma_context *c = NULL;
- struct p9_rdma_context *rpl_context = NULL;
-
- /* Allocate an fcall for the reply */
- rpl_context = kmalloc(sizeof *rpl_context, GFP_NOFS);
- if (!rpl_context) {
- err = -ENOMEM;
- goto err_close;
- }
-
- /*
- * If the request has a buffer, steal it, otherwise
- * allocate a new one. Typically, requests should already
- * have receive buffers allocated and just swap them around
- */
- if (!req->rc) {
- req->rc = kmalloc(sizeof(struct p9_fcall)+client->msize,
- GFP_NOFS);
- if (req->rc) {
- req->rc->sdata = (char *) req->rc +
- sizeof(struct p9_fcall);
- req->rc->capacity = client->msize;
- }
- }
- rpl_context->rc = req->rc;
- if (!rpl_context->rc) {
- err = -ENOMEM;
- goto err_free2;
- }
-
- /*
- * Post a receive buffer for this request. We need to ensure
- * there is a reply buffer available for every outstanding
- * request. A flushed request can result in no reply for an
- * outstanding request, so we must keep a count to avoid
- * overflowing the RQ.
- */
- if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
- err = post_recv(client, rpl_context);
- if (err)
- goto err_free1;
- } else
- atomic_dec(&rdma->rq_count);
-
- /* remove posted receive buffer from request structure */
- req->rc = NULL;
-
- /* Post the request */
- c = kmalloc(sizeof *c, GFP_NOFS);
- if (!c) {
- err = -ENOMEM;
- goto err_free1;
- }
- c->req = req;
-
- c->busa = ib_dma_map_single(rdma->cm_id->device,
- c->req->tc->sdata, c->req->tc->size,
- DMA_TO_DEVICE);
- if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
- goto error;
-
- sge.addr = c->busa;
- sge.length = c->req->tc->size;
- sge.lkey = rdma->lkey;
-
- wr.next = NULL;
- c->wc_op = IB_WC_SEND;
- wr.wr_id = (unsigned long) c;
- wr.opcode = IB_WR_SEND;
- wr.send_flags = IB_SEND_SIGNALED;
- wr.sg_list = &sge;
- wr.num_sge = 1;
-
- if (down_interruptible(&rdma->sq_sem))
- goto error;
-
- return ib_post_send(rdma->qp, &wr, &bad_wr);
-
- error:
- kfree(c);
- kfree(rpl_context->rc);
- kfree(rpl_context);
- p9_debug(P9_DEBUG_ERROR, "EIO\n");
- return -EIO;
- err_free1:
- kfree(rpl_context->rc);
- err_free2:
- kfree(rpl_context);
- err_close:
- spin_lock_irqsave(&rdma->req_lock, flags);
- if (rdma->state < P9_RDMA_CLOSING) {
- rdma->state = P9_RDMA_CLOSING;
- spin_unlock_irqrestore(&rdma->req_lock, flags);
- rdma_disconnect(rdma->cm_id);
- } else
- spin_unlock_irqrestore(&rdma->req_lock, flags);
- return err;
-}
-
-static void rdma_close(struct p9_client *client)
-{
- struct p9_trans_rdma *rdma;
-
- if (!client)
- return;
-
- rdma = client->trans;
- if (!rdma)
- return;
-
- client->status = Disconnected;
- rdma_disconnect(rdma->cm_id);
- rdma_destroy_trans(rdma);
-}
-
-/**
- * alloc_rdma - Allocate and initialize the rdma transport structure
- * @opts: Mount options structure
- */
-static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
-{
- struct p9_trans_rdma *rdma;
-
- rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL);
- if (!rdma)
- return NULL;
-
- rdma->sq_depth = opts->sq_depth;
- rdma->rq_depth = opts->rq_depth;
- rdma->timeout = opts->timeout;
- spin_lock_init(&rdma->req_lock);
- init_completion(&rdma->cm_done);
- sema_init(&rdma->sq_sem, rdma->sq_depth);
- atomic_set(&rdma->rq_count, 0);
-
- return rdma;
-}
-
-/* its not clear to me we can do anything after send has been posted */
-static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
-{
- return 1;
-}
-
-/**
- * trans_create_rdma - Transport method for creating atransport instance
- * @client: client instance
- * @addr: IP address string
- * @args: Mount options string
- */
-static int
-rdma_create_trans(struct p9_client *client, const char *addr, char *args)
-{
- int err;
- struct p9_rdma_opts opts;
- struct p9_trans_rdma *rdma;
- struct rdma_conn_param conn_param;
- struct ib_qp_init_attr qp_attr;
- struct ib_device_attr devattr;
-
- /* Parse the transport specific mount options */
- err = parse_opts(args, &opts);
- if (err < 0)
- return err;
-
- /* Create and initialize the RDMA transport structure */
- rdma = alloc_rdma(&opts);
- if (!rdma)
- return -ENOMEM;
-
- /* Create the RDMA CM ID */
- rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP,
- IB_QPT_RC);
- if (IS_ERR(rdma->cm_id))
- goto error;
-
- /* Associate the client with the transport */
- client->trans = rdma;
-
- /* Resolve the server's address */
- rdma->addr.sin_family = AF_INET;
- rdma->addr.sin_addr.s_addr = in_aton(addr);
- rdma->addr.sin_port = htons(opts.port);
- err = rdma_resolve_addr(rdma->cm_id, NULL,
- (struct sockaddr *)&rdma->addr,
- rdma->timeout);
- if (err)
- goto error;
- err = wait_for_completion_interruptible(&rdma->cm_done);
- if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED))
- goto error;
-
- /* Resolve the route to the server */
- err = rdma_resolve_route(rdma->cm_id, rdma->timeout);
- if (err)
- goto error;
- err = wait_for_completion_interruptible(&rdma->cm_done);
- if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED))
- goto error;
-
- /* Query the device attributes */
- err = ib_query_device(rdma->cm_id->device, &devattr);
- if (err)
- goto error;
-
- /* Create the Completion Queue */
- rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler,
- cq_event_handler, client,
- opts.sq_depth + opts.rq_depth + 1, 0);
- if (IS_ERR(rdma->cq))
- goto error;
- ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
-
- /* Create the Protection Domain */
- rdma->pd = ib_alloc_pd(rdma->cm_id->device);
- if (IS_ERR(rdma->pd))
- goto error;
-
- /* Cache the DMA lkey in the transport */
- rdma->dma_mr = NULL;
- if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
- rdma->lkey = rdma->cm_id->device->local_dma_lkey;
- else {
- rdma->dma_mr = ib_get_dma_mr(rdma->pd, IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(rdma->dma_mr))
- goto error;
- rdma->lkey = rdma->dma_mr->lkey;
- }
-
- /* Create the Queue Pair */
- memset(&qp_attr, 0, sizeof qp_attr);
- qp_attr.event_handler = qp_event_handler;
- qp_attr.qp_context = client;
- qp_attr.cap.max_send_wr = opts.sq_depth;
- qp_attr.cap.max_recv_wr = opts.rq_depth;
- qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE;
- qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE;
- qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
- qp_attr.qp_type = IB_QPT_RC;
- qp_attr.send_cq = rdma->cq;
- qp_attr.recv_cq = rdma->cq;
- err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr);
- if (err)
- goto error;
- rdma->qp = rdma->cm_id->qp;
-
- /* Request a connection */
- memset(&conn_param, 0, sizeof(conn_param));
- conn_param.private_data = NULL;
- conn_param.private_data_len = 0;
- conn_param.responder_resources = P9_RDMA_IRD;
- conn_param.initiator_depth = P9_RDMA_ORD;
- err = rdma_connect(rdma->cm_id, &conn_param);
- if (err)
- goto error;
- err = wait_for_completion_interruptible(&rdma->cm_done);
- if (err || (rdma->state != P9_RDMA_CONNECTED))
- goto error;
-
- client->status = Connected;
-
- return 0;
-
-error:
- rdma_destroy_trans(rdma);
- return -ENOTCONN;
-}
-
-static struct p9_trans_module p9_rdma_trans = {
- .name = "rdma",
- .maxsize = P9_RDMA_MAXSIZE,
- .def = 0,
- .owner = THIS_MODULE,
- .create = rdma_create_trans,
- .close = rdma_close,
- .request = rdma_request,
- .cancel = rdma_cancel,
-};
-
-/**
- * p9_trans_rdma_init - Register the 9P RDMA transport driver
- */
-static int __init p9_trans_rdma_init(void)
-{
- v9fs_register_trans(&p9_rdma_trans);
- return 0;
-}
-
-static void __exit p9_trans_rdma_exit(void)
-{
- v9fs_unregister_trans(&p9_rdma_trans);
-}
-
-module_init(p9_trans_rdma_init);
-module_exit(p9_trans_rdma_exit);
-
-MODULE_AUTHOR("Tom Tucker ");
-MODULE_DESCRIPTION("RDMA Transport for 9P");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/addons/9p/src/3.10.108/trans_virtio.c b/addons/9p/src/3.10.108/trans_virtio.c
deleted file mode 100644
index c76a4388..00000000
--- a/addons/9p/src/3.10.108/trans_virtio.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * The Virtio 9p transport driver
- *
- * This is a block based transport driver based on the lguest block driver
- * code.
- *
- * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
- *
- * Based on virtio console driver
- * Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "trans_common.h"
-
-#define VIRTQUEUE_NUM 128
-
-/* a single mutex to manage channel initialization and attachment */
-static DEFINE_MUTEX(virtio_9p_lock);
-static DECLARE_WAIT_QUEUE_HEAD(vp_wq);
-static atomic_t vp_pinned = ATOMIC_INIT(0);
-
-/**
- * struct virtio_chan - per-instance transport information
- * @initialized: whether the channel is initialized
- * @inuse: whether the channel is in use
- * @lock: protects multiple elements within this structure
- * @client: client instance
- * @vdev: virtio dev associated with this channel
- * @vq: virtio queue associated with this channel
- * @sg: scatter gather list which is used to pack a request (protected?)
- *
- * We keep all per-channel information in a structure.
- * This structure is allocated within the devices dev->mem space.
- * A pointer to the structure will get put in the transport private.
- *
- */
-
-struct virtio_chan {
- bool inuse;
-
- spinlock_t lock;
-
- struct p9_client *client;
- struct virtio_device *vdev;
- struct virtqueue *vq;
- int ring_bufs_avail;
- wait_queue_head_t *vc_wq;
- /* This is global limit. Since we don't have a global structure,
- * will be placing it in each channel.
- */
- unsigned long p9_max_pages;
- /* Scatterlist: can be too big for stack. */
- struct scatterlist sg[VIRTQUEUE_NUM];
-
- int tag_len;
- /*
- * tag name to identify a mount Non-null terminated
- */
- char *tag;
-
- struct list_head chan_list;
-};
-
-static struct list_head virtio_chan_list;
-
-/* How many bytes left in this page. */
-static unsigned int rest_of_page(void *data)
-{
- return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
-}
-
-/**
- * p9_virtio_close - reclaim resources of a channel
- * @client: client instance
- *
- * This reclaims a channel by freeing its resources and
- * reseting its inuse flag.
- *
- */
-
-static void p9_virtio_close(struct p9_client *client)
-{
- struct virtio_chan *chan = client->trans;
-
- mutex_lock(&virtio_9p_lock);
- if (chan)
- chan->inuse = false;
- mutex_unlock(&virtio_9p_lock);
-}
-
-/**
- * req_done - callback which signals activity from the server
- * @vq: virtio queue activity was received on
- *
- * This notifies us that the server has triggered some activity
- * on the virtio channel - most likely a response to request we
- * sent. Figure out which requests now have responses and wake up
- * those threads.
- *
- * Bugs: could do with some additional sanity checking, but appears to work.
- *
- */
-
-static void req_done(struct virtqueue *vq)
-{
- struct virtio_chan *chan = vq->vdev->priv;
- struct p9_fcall *rc;
- unsigned int len;
- struct p9_req_t *req;
- unsigned long flags;
-
- p9_debug(P9_DEBUG_TRANS, ": request done\n");
-
- while (1) {
- spin_lock_irqsave(&chan->lock, flags);
- rc = virtqueue_get_buf(chan->vq, &len);
- if (rc == NULL) {
- spin_unlock_irqrestore(&chan->lock, flags);
- break;
- }
- chan->ring_bufs_avail = 1;
- spin_unlock_irqrestore(&chan->lock, flags);
- /* Wakeup if anyone waiting for VirtIO ring space. */
- wake_up(chan->vc_wq);
- p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc);
- p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
- req = p9_tag_lookup(chan->client, rc->tag);
- req->status = REQ_STATUS_RCVD;
- p9_client_cb(chan->client, req);
- }
-}
-
-/**
- * pack_sg_list - pack a scatter gather list from a linear buffer
- * @sg: scatter/gather list to pack into
- * @start: which segment of the sg_list to start at
- * @limit: maximum segment to pack data to
- * @data: data to pack into scatter/gather list
- * @count: amount of data to pack into the scatter/gather list
- *
- * sg_lists have multiple segments of various sizes. This will pack
- * arbitrary data into an existing scatter gather list, segmenting the
- * data as necessary within constraints.
- *
- */
-
-static int pack_sg_list(struct scatterlist *sg, int start,
- int limit, char *data, int count)
-{
- int s;
- int index = start;
-
- while (count) {
- s = rest_of_page(data);
- if (s > count)
- s = count;
- BUG_ON(index > limit);
- /* Make sure we don't terminate early. */
- sg_unmark_end(&sg[index]);
- sg_set_buf(&sg[index++], data, s);
- count -= s;
- data += s;
- }
- if (index-start)
- sg_mark_end(&sg[index - 1]);
- return index-start;
-}
-
-/* We don't currently allow canceling of virtio requests */
-static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
-{
- return 1;
-}
-
-/**
- * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
- * this takes a list of pages.
- * @sg: scatter/gather list to pack into
- * @start: which segment of the sg_list to start at
- * @pdata: a list of pages to add into sg.
- * @nr_pages: number of pages to pack into the scatter/gather list
- * @data: data to pack into scatter/gather list
- * @count: amount of data to pack into the scatter/gather list
- */
-static int
-pack_sg_list_p(struct scatterlist *sg, int start, int limit,
- struct page **pdata, int nr_pages, char *data, int count)
-{
- int i = 0, s;
- int data_off;
- int index = start;
-
- BUG_ON(nr_pages > (limit - start));
- /*
- * if the first page doesn't start at
- * page boundary find the offset
- */
- data_off = offset_in_page(data);
- while (nr_pages) {
- s = rest_of_page(data);
- if (s > count)
- s = count;
- /* Make sure we don't terminate early. */
- sg_unmark_end(&sg[index]);
- sg_set_page(&sg[index++], pdata[i++], s, data_off);
- data_off = 0;
- data += s;
- count -= s;
- nr_pages--;
- }
-
- if (index-start)
- sg_mark_end(&sg[index - 1]);
- return index - start;
-}
-
-/**
- * p9_virtio_request - issue a request
- * @client: client instance issuing the request
- * @req: request to be issued
- *
- */
-
-static int
-p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
-{
- int err;
- int in, out, out_sgs, in_sgs;
- unsigned long flags;
- struct virtio_chan *chan = client->trans;
- struct scatterlist *sgs[2];
-
- p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
-
- req->status = REQ_STATUS_SENT;
-req_retry:
- spin_lock_irqsave(&chan->lock, flags);
-
- out_sgs = in_sgs = 0;
- /* Handle out VirtIO ring buffers */
- out = pack_sg_list(chan->sg, 0,
- VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
- if (out)
- sgs[out_sgs++] = chan->sg;
-
- in = pack_sg_list(chan->sg, out,
- VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
- if (in)
- sgs[out_sgs + in_sgs++] = chan->sg + out;
-
- err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
- GFP_ATOMIC);
- if (err < 0) {
- if (err == -ENOSPC) {
- chan->ring_bufs_avail = 0;
- spin_unlock_irqrestore(&chan->lock, flags);
- err = wait_event_interruptible(*chan->vc_wq,
- chan->ring_bufs_avail);
- if (err == -ERESTARTSYS)
- return err;
-
- p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
- goto req_retry;
- } else {
- spin_unlock_irqrestore(&chan->lock, flags);
- p9_debug(P9_DEBUG_TRANS,
- "virtio rpc add_sgs returned failure\n");
- return -EIO;
- }
- }
- virtqueue_kick(chan->vq);
- spin_unlock_irqrestore(&chan->lock, flags);
-
- p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
- return 0;
-}
-
-static int p9_get_mapped_pages(struct virtio_chan *chan,
- struct page **pages, char *data,
- int nr_pages, int write, int kern_buf)
-{
- int err;
- if (!kern_buf) {
- /*
- * We allow only p9_max_pages pinned. We wait for the
- * Other zc request to finish here
- */
- if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
- err = wait_event_interruptible(vp_wq,
- (atomic_read(&vp_pinned) < chan->p9_max_pages));
- if (err == -ERESTARTSYS)
- return err;
- }
- err = p9_payload_gup(data, &nr_pages, pages, write);
- if (err < 0)
- return err;
- atomic_add(nr_pages, &vp_pinned);
- } else {
- /* kernel buffer, no need to pin pages */
- int s, index = 0;
- int count = nr_pages;
- while (nr_pages) {
- s = rest_of_page(data);
- if (is_vmalloc_addr(data))
- pages[index++] = vmalloc_to_page(data);
- else
- pages[index++] = kmap_to_page(data);
- data += s;
- nr_pages--;
- }
- nr_pages = count;
- }
- return nr_pages;
-}
-
-/**
- * p9_virtio_zc_request - issue a zero copy request
- * @client: client instance issuing the request
- * @req: request to be issued
- * @uidata: user bffer that should be ued for zero copy read
- * @uodata: user buffer that shoud be user for zero copy write
- * @inlen: read buffer size
- * @olen: write buffer size
- * @hdrlen: reader header size, This is the size of response protocol data
- *
- */
-static int
-p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
- char *uidata, char *uodata, int inlen,
- int outlen, int in_hdr_len, int kern_buf)
-{
- int in, out, err, out_sgs, in_sgs;
- unsigned long flags;
- int in_nr_pages = 0, out_nr_pages = 0;
- struct page **in_pages = NULL, **out_pages = NULL;
- struct virtio_chan *chan = client->trans;
- struct scatterlist *sgs[4];
-
- p9_debug(P9_DEBUG_TRANS, "virtio request\n");
-
- if (uodata) {
- out_nr_pages = p9_nr_pages(uodata, outlen);
- out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
- GFP_NOFS);
- if (!out_pages) {
- err = -ENOMEM;
- goto err_out;
- }
- out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata,
- out_nr_pages, 0, kern_buf);
- if (out_nr_pages < 0) {
- err = out_nr_pages;
- kfree(out_pages);
- out_pages = NULL;
- goto err_out;
- }
- }
- if (uidata) {
- in_nr_pages = p9_nr_pages(uidata, inlen);
- in_pages = kmalloc(sizeof(struct page *) * in_nr_pages,
- GFP_NOFS);
- if (!in_pages) {
- err = -ENOMEM;
- goto err_out;
- }
- in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata,
- in_nr_pages, 1, kern_buf);
- if (in_nr_pages < 0) {
- err = in_nr_pages;
- kfree(in_pages);
- in_pages = NULL;
- goto err_out;
- }
- }
- req->status = REQ_STATUS_SENT;
-req_retry_pinned:
- spin_lock_irqsave(&chan->lock, flags);
-
- out_sgs = in_sgs = 0;
-
- /* out data */
- out = pack_sg_list(chan->sg, 0,
- VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
-
- if (out)
- sgs[out_sgs++] = chan->sg;
-
- if (out_pages) {
- sgs[out_sgs++] = chan->sg + out;
- out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
- out_pages, out_nr_pages, uodata, outlen);
- }
-
- /*
- * Take care of in data
- * For example TREAD have 11.
- * 11 is the read/write header = PDU Header(7) + IO Size (4).
- * Arrange in such a way that server places header in the
- * alloced memory and payload onto the user buffer.
- */
- in = pack_sg_list(chan->sg, out,
- VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
- if (in)
- sgs[out_sgs + in_sgs++] = chan->sg + out;
-
- if (in_pages) {
- sgs[out_sgs + in_sgs++] = chan->sg + out + in;
- in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
- in_pages, in_nr_pages, uidata, inlen);
- }
-
- BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
- err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
- GFP_ATOMIC);
- if (err < 0) {
- if (err == -ENOSPC) {
- chan->ring_bufs_avail = 0;
- spin_unlock_irqrestore(&chan->lock, flags);
- err = wait_event_interruptible(*chan->vc_wq,
- chan->ring_bufs_avail);
- if (err == -ERESTARTSYS)
- goto err_out;
-
- p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
- goto req_retry_pinned;
- } else {
- spin_unlock_irqrestore(&chan->lock, flags);
- p9_debug(P9_DEBUG_TRANS,
- "virtio rpc add_sgs returned failure\n");
- err = -EIO;
- goto err_out;
- }
- }
- virtqueue_kick(chan->vq);
- spin_unlock_irqrestore(&chan->lock, flags);
- p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
- err = wait_event_interruptible(*req->wq,
- req->status >= REQ_STATUS_RCVD);
- /*
- * Non kernel buffers are pinned, unpin them
- */
-err_out:
- if (!kern_buf) {
- if (in_pages) {
- p9_release_pages(in_pages, in_nr_pages);
- atomic_sub(in_nr_pages, &vp_pinned);
- }
- if (out_pages) {
- p9_release_pages(out_pages, out_nr_pages);
- atomic_sub(out_nr_pages, &vp_pinned);
- }
- /* wakeup anybody waiting for slots to pin pages */
- wake_up(&vp_wq);
- }
- kfree(in_pages);
- kfree(out_pages);
- return err;
-}
-
-static ssize_t p9_mount_tag_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct virtio_chan *chan;
- struct virtio_device *vdev;
-
- vdev = dev_to_virtio(dev);
- chan = vdev->priv;
-
- return snprintf(buf, chan->tag_len + 1, "%s", chan->tag);
-}
-
-static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
-
-/**
- * p9_virtio_probe - probe for existence of 9P virtio channels
- * @vdev: virtio device to probe
- *
- * This probes for existing virtio channels.
- *
- */
-
-static int p9_virtio_probe(struct virtio_device *vdev)
-{
- __u16 tag_len;
- char *tag;
- int err;
- struct virtio_chan *chan;
-
- chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
- if (!chan) {
- pr_err("Failed to allocate virtio 9P channel\n");
- err = -ENOMEM;
- goto fail;
- }
-
- chan->vdev = vdev;
-
- /* We expect one virtqueue, for requests. */
- chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
- if (IS_ERR(chan->vq)) {
- err = PTR_ERR(chan->vq);
- goto out_free_vq;
- }
- chan->vq->vdev->priv = chan;
- spin_lock_init(&chan->lock);
-
- sg_init_table(chan->sg, VIRTQUEUE_NUM);
-
- chan->inuse = false;
- if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
- vdev->config->get(vdev,
- offsetof(struct virtio_9p_config, tag_len),
- &tag_len, sizeof(tag_len));
- } else {
- err = -EINVAL;
- goto out_free_vq;
- }
- tag = kmalloc(tag_len, GFP_KERNEL);
- if (!tag) {
- err = -ENOMEM;
- goto out_free_vq;
- }
- vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
- tag, tag_len);
- chan->tag = tag;
- chan->tag_len = tag_len;
- err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
- if (err) {
- goto out_free_tag;
- }
- chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
- if (!chan->vc_wq) {
- err = -ENOMEM;
- goto out_free_tag;
- }
- init_waitqueue_head(chan->vc_wq);
- chan->ring_bufs_avail = 1;
- /* Ceiling limit to avoid denial of service attacks */
- chan->p9_max_pages = nr_free_buffer_pages()/4;
-
- mutex_lock(&virtio_9p_lock);
- list_add_tail(&chan->chan_list, &virtio_chan_list);
- mutex_unlock(&virtio_9p_lock);
-
- /* Let udev rules use the new mount_tag attribute. */
- kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
-
- return 0;
-
-out_free_tag:
- kfree(tag);
-out_free_vq:
- vdev->config->del_vqs(vdev);
- kfree(chan);
-fail:
- return err;
-}
-
-
-/**
- * p9_virtio_create - allocate a new virtio channel
- * @client: client instance invoking this transport
- * @devname: string identifying the channel to connect to (unused)
- * @args: args passed from sys_mount() for per-transport options (unused)
- *
- * This sets up a transport channel for 9p communication. Right now
- * we only match the first available channel, but eventually we couldlook up
- * alternate channels by matching devname versus a virtio_config entry.
- * We use a simple reference count mechanism to ensure that only a single
- * mount has a channel open at a time.
- *
- */
-
-static int
-p9_virtio_create(struct p9_client *client, const char *devname, char *args)
-{
- struct virtio_chan *chan;
- int ret = -ENOENT;
- int found = 0;
-
- mutex_lock(&virtio_9p_lock);
- list_for_each_entry(chan, &virtio_chan_list, chan_list) {
- if (!strncmp(devname, chan->tag, chan->tag_len) &&
- strlen(devname) == chan->tag_len) {
- if (!chan->inuse) {
- chan->inuse = true;
- found = 1;
- break;
- }
- ret = -EBUSY;
- }
- }
- mutex_unlock(&virtio_9p_lock);
-
- if (!found) {
- pr_err("no channels available\n");
- return ret;
- }
-
- client->trans = (void *)chan;
- client->status = Connected;
- chan->client = client;
-
- return 0;
-}
-
-/**
- * p9_virtio_remove - clean up resources associated with a virtio device
- * @vdev: virtio device to remove
- *
- */
-
-static void p9_virtio_remove(struct virtio_device *vdev)
-{
- struct virtio_chan *chan = vdev->priv;
-
- if (chan->inuse)
- p9_virtio_close(chan->client);
- vdev->config->del_vqs(vdev);
-
- mutex_lock(&virtio_9p_lock);
- list_del(&chan->chan_list);
- mutex_unlock(&virtio_9p_lock);
- sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
- kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
- kfree(chan->tag);
- kfree(chan->vc_wq);
- kfree(chan);
-
-}
-
-static struct virtio_device_id id_table[] = {
- { VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
- { 0 },
-};
-
-static unsigned int features[] = {
- VIRTIO_9P_MOUNT_TAG,
-};
-
-/* The standard "struct lguest_driver": */
-static struct virtio_driver p9_virtio_drv = {
- .feature_table = features,
- .feature_table_size = ARRAY_SIZE(features),
- .driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
- .id_table = id_table,
- .probe = p9_virtio_probe,
- .remove = p9_virtio_remove,
-};
-
-static struct p9_trans_module p9_virtio_trans = {
- .name = "virtio",
- .create = p9_virtio_create,
- .close = p9_virtio_close,
- .request = p9_virtio_request,
- .zc_request = p9_virtio_zc_request,
- .cancel = p9_virtio_cancel,
- /*
- * We leave one entry for input and one entry for response
- * headers. We also skip one more entry to accomodate, address
- * that are not at page boundary, that can result in an extra
- * page in zero copy.
- */
- .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
- .def = 0,
- .owner = THIS_MODULE,
-};
-
-/* The standard init function */
-static int __init p9_virtio_init(void)
-{
- INIT_LIST_HEAD(&virtio_chan_list);
-
- v9fs_register_trans(&p9_virtio_trans);
- return register_virtio_driver(&p9_virtio_drv);
-}
-
-static void __exit p9_virtio_cleanup(void)
-{
- unregister_virtio_driver(&p9_virtio_drv);
- v9fs_unregister_trans(&p9_virtio_trans);
-}
-
-module_init(p9_virtio_init);
-module_exit(p9_virtio_cleanup);
-
-MODULE_DEVICE_TABLE(virtio, id_table);
-MODULE_AUTHOR("Eric Van Hensbergen ");
-MODULE_DESCRIPTION("Virtio 9p Transport");
-MODULE_LICENSE("GPL");
diff --git a/addons/9p/src/3.10.108/util.c b/addons/9p/src/3.10.108/util.c
deleted file mode 100644
index 59f278e6..00000000
--- a/addons/9p/src/3.10.108/util.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * net/9p/util.c
- *
- * This file contains some helper functions
- *
- * Copyright (C) 2007 by Latchesar Ionkov
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/**
- * struct p9_idpool - per-connection accounting for tag idpool
- * @lock: protects the pool
- * @pool: idr to allocate tag id from
- *
- */
-
-struct p9_idpool {
- spinlock_t lock;
- struct idr pool;
-};
-
-/**
- * p9_idpool_create - create a new per-connection id pool
- *
- */
-
-struct p9_idpool *p9_idpool_create(void)
-{
- struct p9_idpool *p;
-
- p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
- if (!p)
- return ERR_PTR(-ENOMEM);
-
- spin_lock_init(&p->lock);
- idr_init(&p->pool);
-
- return p;
-}
-EXPORT_SYMBOL(p9_idpool_create);
-
-/**
- * p9_idpool_destroy - create a new per-connection id pool
- * @p: idpool to destroy
- */
-
-void p9_idpool_destroy(struct p9_idpool *p)
-{
- idr_destroy(&p->pool);
- kfree(p);
-}
-EXPORT_SYMBOL(p9_idpool_destroy);
-
-/**
- * p9_idpool_get - allocate numeric id from pool
- * @p: pool to allocate from
- *
- * Bugs: This seems to be an awful generic function, should it be in idr.c with
- * the lock included in struct idr?
- */
-
-int p9_idpool_get(struct p9_idpool *p)
-{
- int i;
- unsigned long flags;
-
- idr_preload(GFP_NOFS);
- spin_lock_irqsave(&p->lock, flags);
-
- /* no need to store exactly p, we just need something non-null */
- i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
-
- spin_unlock_irqrestore(&p->lock, flags);
- idr_preload_end();
- if (i < 0)
- return -1;
-
- p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
- return i;
-}
-EXPORT_SYMBOL(p9_idpool_get);
-
-/**
- * p9_idpool_put - release numeric id from pool
- * @id: numeric id which is being released
- * @p: pool to release id into
- *
- * Bugs: This seems to be an awful generic function, should it be in idr.c with
- * the lock included in struct idr?
- */
-
-void p9_idpool_put(int id, struct p9_idpool *p)
-{
- unsigned long flags;
-
- p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
-
- spin_lock_irqsave(&p->lock, flags);
- idr_remove(&p->pool, id);
- spin_unlock_irqrestore(&p->lock, flags);
-}
-EXPORT_SYMBOL(p9_idpool_put);
-
-/**
- * p9_idpool_check - check if the specified id is available
- * @id: id to check
- * @p: pool to check
- */
-
-int p9_idpool_check(int id, struct p9_idpool *p)
-{
- return idr_find(&p->pool, id) != NULL;
-}
-EXPORT_SYMBOL(p9_idpool_check);
-
diff --git a/addons/9p/src/3.10.108/v9fs.c b/addons/9p/src/3.10.108/v9fs.c
deleted file mode 100644
index 58e6cbce..00000000
--- a/addons/9p/src/3.10.108/v9fs.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * linux/fs/9p/v9fs.c
- *
- * This file contains functions assisting in mapping VFS to 9P2000
- *
- * Copyright (C) 2004-2008 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "cache.h"
-
-static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
-static LIST_HEAD(v9fs_sessionlist);
-struct kmem_cache *v9fs_inode_cache;
-
-/*
- * Option Parsing (code inspired by NFS code)
- * NOTE: each transport will parse its own options
- */
-
-enum {
- /* Options that take integer arguments */
- Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid,
- /* String options */
- Opt_uname, Opt_remotename, Opt_trans, Opt_cache, Opt_cachetag,
- /* Options that take no arguments */
- Opt_nodevmap,
- /* Cache options */
- Opt_cache_loose, Opt_fscache,
- /* Access options */
- Opt_access, Opt_posixacl,
- /* Error token */
- Opt_err
-};
-
-static const match_table_t tokens = {
- {Opt_debug, "debug=%x"},
- {Opt_dfltuid, "dfltuid=%u"},
- {Opt_dfltgid, "dfltgid=%u"},
- {Opt_afid, "afid=%u"},
- {Opt_uname, "uname=%s"},
- {Opt_remotename, "aname=%s"},
- {Opt_nodevmap, "nodevmap"},
- {Opt_cache, "cache=%s"},
- {Opt_cache_loose, "loose"},
- {Opt_fscache, "fscache"},
- {Opt_cachetag, "cachetag=%s"},
- {Opt_access, "access=%s"},
- {Opt_posixacl, "posixacl"},
- {Opt_err, NULL}
-};
-
-/* Interpret mount options for cache mode */
-static int get_cache_mode(char *s)
-{
- int version = -EINVAL;
-
- if (!strcmp(s, "loose")) {
- version = CACHE_LOOSE;
- p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
- } else if (!strcmp(s, "fscache")) {
- version = CACHE_FSCACHE;
- p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
- } else if (!strcmp(s, "none")) {
- version = CACHE_NONE;
- p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
- } else
- pr_info("Unknown Cache mode %s\n", s);
- return version;
-}
-
-/**
- * v9fs_parse_options - parse mount options into session structure
- * @v9ses: existing v9fs session information
- *
- * Return 0 upon success, -ERRNO upon failure.
- */
-
-static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
-{
- char *options, *tmp_options;
- substring_t args[MAX_OPT_ARGS];
- char *p;
- int option = 0;
- char *s, *e;
- int ret = 0;
-
- /* setup defaults */
- v9ses->afid = ~0;
- v9ses->debug = 0;
- v9ses->cache = CACHE_NONE;
-#ifdef CONFIG_9P_FSCACHE
- v9ses->cachetag = NULL;
-#endif
-
- if (!opts)
- return 0;
-
- tmp_options = kstrdup(opts, GFP_KERNEL);
- if (!tmp_options) {
- ret = -ENOMEM;
- goto fail_option_alloc;
- }
- options = tmp_options;
-
- while ((p = strsep(&options, ",")) != NULL) {
- int token, r;
- if (!*p)
- continue;
- token = match_token(p, tokens, args);
- switch (token) {
- case Opt_debug:
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
- }
- v9ses->debug = option;
-#ifdef CONFIG_NET_9P_DEBUG
- p9_debug_level = option;
-#endif
- break;
-
- case Opt_dfltuid:
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
- }
- v9ses->dfltuid = make_kuid(current_user_ns(), option);
- if (!uid_valid(v9ses->dfltuid)) {
- p9_debug(P9_DEBUG_ERROR,
- "uid field, but not a uid?\n");
- ret = -EINVAL;
- continue;
- }
- break;
- case Opt_dfltgid:
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
- }
- v9ses->dfltgid = make_kgid(current_user_ns(), option);
- if (!gid_valid(v9ses->dfltgid)) {
- p9_debug(P9_DEBUG_ERROR,
- "gid field, but not a gid?\n");
- ret = -EINVAL;
- continue;
- }
- break;
- case Opt_afid:
- r = match_int(&args[0], &option);
- if (r < 0) {
- p9_debug(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
- }
- v9ses->afid = option;
- break;
- case Opt_uname:
- kfree(v9ses->uname);
- v9ses->uname = match_strdup(&args[0]);
- if (!v9ses->uname) {
- ret = -ENOMEM;
- goto free_and_return;
- }
- break;
- case Opt_remotename:
- kfree(v9ses->aname);
- v9ses->aname = match_strdup(&args[0]);
- if (!v9ses->aname) {
- ret = -ENOMEM;
- goto free_and_return;
- }
- break;
- case Opt_nodevmap:
- v9ses->nodev = 1;
- break;
- case Opt_cache_loose:
- v9ses->cache = CACHE_LOOSE;
- break;
- case Opt_fscache:
- v9ses->cache = CACHE_FSCACHE;
- break;
- case Opt_cachetag:
-#ifdef CONFIG_9P_FSCACHE
- v9ses->cachetag = match_strdup(&args[0]);
-#endif
- break;
- case Opt_cache:
- s = match_strdup(&args[0]);
- if (!s) {
- ret = -ENOMEM;
- p9_debug(P9_DEBUG_ERROR,
- "problem allocating copy of cache arg\n");
- goto free_and_return;
- }
- ret = get_cache_mode(s);
- if (ret == -EINVAL) {
- kfree(s);
- goto free_and_return;
- }
-
- v9ses->cache = ret;
- kfree(s);
- break;
-
- case Opt_access:
- s = match_strdup(&args[0]);
- if (!s) {
- ret = -ENOMEM;
- p9_debug(P9_DEBUG_ERROR,
- "problem allocating copy of access arg\n");
- goto free_and_return;
- }
-
- v9ses->flags &= ~V9FS_ACCESS_MASK;
- if (strcmp(s, "user") == 0)
- v9ses->flags |= V9FS_ACCESS_USER;
- else if (strcmp(s, "any") == 0)
- v9ses->flags |= V9FS_ACCESS_ANY;
- else if (strcmp(s, "client") == 0) {
- v9ses->flags |= V9FS_ACCESS_CLIENT;
- } else {
- uid_t uid;
- v9ses->flags |= V9FS_ACCESS_SINGLE;
- uid = simple_strtoul(s, &e, 10);
- if (*e != '\0') {
- ret = -EINVAL;
- pr_info("Unknown access argument %s\n",
- s);
- kfree(s);
- goto free_and_return;
- }
- v9ses->uid = make_kuid(current_user_ns(), uid);
- if (!uid_valid(v9ses->uid)) {
- ret = -EINVAL;
- pr_info("Uknown uid %s\n", s);
- kfree(s);
- goto free_and_return;
- }
- }
-
- kfree(s);
- break;
-
- case Opt_posixacl:
-#ifdef CONFIG_9P_FS_POSIX_ACL
- v9ses->flags |= V9FS_POSIX_ACL;
-#else
- p9_debug(P9_DEBUG_ERROR,
- "Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");
-#endif
- break;
-
- default:
- continue;
- }
- }
-
-free_and_return:
- kfree(tmp_options);
-fail_option_alloc:
- return ret;
-}
-
-/**
- * v9fs_session_init - initialize session
- * @v9ses: session information structure
- * @dev_name: device being mounted
- * @data: options
- *
- */
-
-struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
- const char *dev_name, char *data)
-{
- int retval = -EINVAL;
- struct p9_fid *fid;
- int rc;
-
- v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
- if (!v9ses->uname)
- return ERR_PTR(-ENOMEM);
-
- v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
- if (!v9ses->aname) {
- kfree(v9ses->uname);
- return ERR_PTR(-ENOMEM);
- }
- init_rwsem(&v9ses->rename_sem);
-
- rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
- if (rc) {
- kfree(v9ses->aname);
- kfree(v9ses->uname);
- return ERR_PTR(rc);
- }
-
- spin_lock(&v9fs_sessionlist_lock);
- list_add(&v9ses->slist, &v9fs_sessionlist);
- spin_unlock(&v9fs_sessionlist_lock);
-
- v9ses->uid = INVALID_UID;
- v9ses->dfltuid = V9FS_DEFUID;
- v9ses->dfltgid = V9FS_DEFGID;
-
- v9ses->clnt = p9_client_create(dev_name, data);
- if (IS_ERR(v9ses->clnt)) {
- retval = PTR_ERR(v9ses->clnt);
- v9ses->clnt = NULL;
- p9_debug(P9_DEBUG_ERROR, "problem initializing 9p client\n");
- goto error;
- }
-
- v9ses->flags = V9FS_ACCESS_USER;
-
- if (p9_is_proto_dotl(v9ses->clnt)) {
- v9ses->flags = V9FS_ACCESS_CLIENT;
- v9ses->flags |= V9FS_PROTO_2000L;
- } else if (p9_is_proto_dotu(v9ses->clnt)) {
- v9ses->flags |= V9FS_PROTO_2000U;
- }
-
- rc = v9fs_parse_options(v9ses, data);
- if (rc < 0) {
- retval = rc;
- goto error;
- }
-
- v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
-
- if (!v9fs_proto_dotl(v9ses) &&
- ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
- /*
- * We support ACCESS_CLIENT only for dotl.
- * Fall back to ACCESS_USER
- */
- v9ses->flags &= ~V9FS_ACCESS_MASK;
- v9ses->flags |= V9FS_ACCESS_USER;
- }
- /*FIXME !! */
- /* for legacy mode, fall back to V9FS_ACCESS_ANY */
- if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
- ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
-
- v9ses->flags &= ~V9FS_ACCESS_MASK;
- v9ses->flags |= V9FS_ACCESS_ANY;
- v9ses->uid = INVALID_UID;
- }
- if (!v9fs_proto_dotl(v9ses) ||
- !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
- /*
- * We support ACL checks on clinet only if the protocol is
- * 9P2000.L and access is V9FS_ACCESS_CLIENT.
- */
- v9ses->flags &= ~V9FS_ACL_MASK;
- }
-
- fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
- v9ses->aname);
- if (IS_ERR(fid)) {
- retval = PTR_ERR(fid);
- fid = NULL;
- p9_debug(P9_DEBUG_ERROR, "cannot attach\n");
- goto error;
- }
-
- if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
- fid->uid = v9ses->uid;
- else
- fid->uid = INVALID_UID;
-
-#ifdef CONFIG_9P_FSCACHE
- /* register the session for caching */
- v9fs_cache_session_get_cookie(v9ses);
-#endif
-
- return fid;
-
-error:
- bdi_destroy(&v9ses->bdi);
- return ERR_PTR(retval);
-}
-
-/**
- * v9fs_session_close - shutdown a session
- * @v9ses: session information structure
- *
- */
-
-void v9fs_session_close(struct v9fs_session_info *v9ses)
-{
- if (v9ses->clnt) {
- p9_client_destroy(v9ses->clnt);
- v9ses->clnt = NULL;
- }
-
-#ifdef CONFIG_9P_FSCACHE
- if (v9ses->fscache) {
- v9fs_cache_session_put_cookie(v9ses);
- kfree(v9ses->cachetag);
- }
-#endif
- kfree(v9ses->uname);
- kfree(v9ses->aname);
-
- bdi_destroy(&v9ses->bdi);
-
- spin_lock(&v9fs_sessionlist_lock);
- list_del(&v9ses->slist);
- spin_unlock(&v9fs_sessionlist_lock);
-}
-
-/**
- * v9fs_session_cancel - terminate a session
- * @v9ses: session to terminate
- *
- * mark transport as disconnected and cancel all pending requests.
- */
-
-void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
- p9_debug(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
- p9_client_disconnect(v9ses->clnt);
-}
-
-/**
- * v9fs_session_begin_cancel - Begin terminate of a session
- * @v9ses: session to terminate
- *
- * After this call we don't allow any request other than clunk.
- */
-
-void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
-{
- p9_debug(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
- p9_client_begin_disconnect(v9ses->clnt);
-}
-
-extern int v9fs_error_init(void);
-
-static struct kobject *v9fs_kobj;
-
-#ifdef CONFIG_9P_FSCACHE
-/**
- * caches_show - list caches associated with a session
- *
- * Returns the size of buffer written.
- */
-
-static ssize_t caches_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
-{
- ssize_t n = 0, count = 0, limit = PAGE_SIZE;
- struct v9fs_session_info *v9ses;
-
- spin_lock(&v9fs_sessionlist_lock);
- list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
- if (v9ses->cachetag) {
- n = snprintf(buf, limit, "%s\n", v9ses->cachetag);
- if (n < 0) {
- count = n;
- break;
- }
-
- count += n;
- limit -= n;
- }
- }
-
- spin_unlock(&v9fs_sessionlist_lock);
- return count;
-}
-
-static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches);
-#endif /* CONFIG_9P_FSCACHE */
-
-static struct attribute *v9fs_attrs[] = {
-#ifdef CONFIG_9P_FSCACHE
- &v9fs_attr_cache.attr,
-#endif
- NULL,
-};
-
-static struct attribute_group v9fs_attr_group = {
- .attrs = v9fs_attrs,
-};
-
-/**
- * v9fs_sysfs_init - Initialize the v9fs sysfs interface
- *
- */
-
-static int v9fs_sysfs_init(void)
-{
- v9fs_kobj = kobject_create_and_add("9p", fs_kobj);
- if (!v9fs_kobj)
- return -ENOMEM;
-
- if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) {
- kobject_put(v9fs_kobj);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/**
- * v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface
- *
- */
-
-static void v9fs_sysfs_cleanup(void)
-{
- sysfs_remove_group(v9fs_kobj, &v9fs_attr_group);
- kobject_put(v9fs_kobj);
-}
-
-static void v9fs_inode_init_once(void *foo)
-{
- struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
-#ifdef CONFIG_9P_FSCACHE
- v9inode->fscache = NULL;
-#endif
- memset(&v9inode->qid, 0, sizeof(v9inode->qid));
- inode_init_once(&v9inode->vfs_inode);
-}
-
-/**
- * v9fs_init_inode_cache - initialize a cache for 9P
- * Returns 0 on success.
- */
-static int v9fs_init_inode_cache(void)
-{
- v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
- sizeof(struct v9fs_inode),
- 0, (SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD),
- v9fs_inode_init_once);
- if (!v9fs_inode_cache)
- return -ENOMEM;
-
- return 0;
-}
-
-/**
- * v9fs_destroy_inode_cache - destroy the cache of 9P inode
- *
- */
-static void v9fs_destroy_inode_cache(void)
-{
- /*
- * Make sure all delayed rcu free inodes are flushed before we
- * destroy cache.
- */
- rcu_barrier();
- kmem_cache_destroy(v9fs_inode_cache);
-}
-
-static int v9fs_cache_register(void)
-{
- int ret;
- ret = v9fs_init_inode_cache();
- if (ret < 0)
- return ret;
-#ifdef CONFIG_9P_FSCACHE
- return fscache_register_netfs(&v9fs_cache_netfs);
-#else
- return ret;
-#endif
-}
-
-static void v9fs_cache_unregister(void)
-{
- v9fs_destroy_inode_cache();
-#ifdef CONFIG_9P_FSCACHE
- fscache_unregister_netfs(&v9fs_cache_netfs);
-#endif
-}
-
-/**
- * init_v9fs - Initialize module
- *
- */
-
-static int __init init_v9fs(void)
-{
- int err;
- pr_info("Installing v9fs 9p2000 file system support\n");
- /* TODO: Setup list of registered trasnport modules */
-
- err = v9fs_cache_register();
- if (err < 0) {
- pr_err("Failed to register v9fs for caching\n");
- return err;
- }
-
- err = v9fs_sysfs_init();
- if (err < 0) {
- pr_err("Failed to register with sysfs\n");
- goto out_cache;
- }
- err = register_filesystem(&v9fs_fs_type);
- if (err < 0) {
- pr_err("Failed to register filesystem\n");
- goto out_sysfs_cleanup;
- }
-
- return 0;
-
-out_sysfs_cleanup:
- v9fs_sysfs_cleanup();
-
-out_cache:
- v9fs_cache_unregister();
-
- return err;
-}
-
-/**
- * exit_v9fs - shutdown module
- *
- */
-
-static void __exit exit_v9fs(void)
-{
- v9fs_sysfs_cleanup();
- v9fs_cache_unregister();
- unregister_filesystem(&v9fs_fs_type);
-}
-
-module_init(init_v9fs)
-module_exit(exit_v9fs)
-
-MODULE_AUTHOR("Latchesar Ionkov ");
-MODULE_AUTHOR("Eric Van Hensbergen ");
-MODULE_AUTHOR("Ron Minnich ");
-MODULE_LICENSE("GPL");
diff --git a/addons/9p/src/3.10.108/v9fs.h b/addons/9p/src/3.10.108/v9fs.h
deleted file mode 100644
index a8e127c8..00000000
--- a/addons/9p/src/3.10.108/v9fs.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * V9FS definitions.
- *
- * Copyright (C) 2004-2008 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-#ifndef FS_9P_V9FS_H
-#define FS_9P_V9FS_H
-
-#include
-
-/**
- * enum p9_session_flags - option flags for each 9P session
- * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
- * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
- * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
- * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
- * @V9FS_ACCESS_CLIENT: Just like user, but access check is performed on client.
- * @V9FS_ACCESS_ANY: use a single attach for all users
- * @V9FS_ACCESS_MASK: bit mask of different ACCESS options
- * @V9FS_POSIX_ACL: POSIX ACLs are enforced
- *
- * Session flags reflect options selected by users at mount time
- */
-#define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \
- V9FS_ACCESS_USER | \
- V9FS_ACCESS_CLIENT)
-#define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
-#define V9FS_ACL_MASK V9FS_POSIX_ACL
-
-enum p9_session_flags {
- V9FS_PROTO_2000U = 0x01,
- V9FS_PROTO_2000L = 0x02,
- V9FS_ACCESS_SINGLE = 0x04,
- V9FS_ACCESS_USER = 0x08,
- V9FS_ACCESS_CLIENT = 0x10,
- V9FS_POSIX_ACL = 0x20
-};
-
-/* possible values of ->cache */
-/**
- * enum p9_cache_modes - user specified cache preferences
- * @CACHE_NONE: do not cache data, dentries, or directory contents (default)
- * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
- *
- * eventually support loose, tight, time, session, default always none
- */
-
-enum p9_cache_modes {
- CACHE_NONE,
- CACHE_LOOSE,
- CACHE_FSCACHE,
-};
-
-/**
- * struct v9fs_session_info - per-instance session information
- * @flags: session options of type &p9_session_flags
- * @nodev: set to 1 to disable device mapping
- * @debug: debug level
- * @afid: authentication handle
- * @cache: cache mode of type &p9_cache_modes
- * @cachetag: the tag of the cache associated with this session
- * @fscache: session cookie associated with FS-Cache
- * @options: copy of options string given by user
- * @uname: string user name to mount hierarchy as
- * @aname: mount specifier for remote hierarchy
- * @maxdata: maximum data to be sent/recvd per protocol message
- * @dfltuid: default numeric userid to mount hierarchy as
- * @dfltgid: default numeric groupid to mount hierarchy as
- * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
- * @clnt: reference to 9P network client instantiated for this session
- * @slist: reference to list of registered 9p sessions
- *
- * This structure holds state for each session instance established during
- * a sys_mount() .
- *
- * Bugs: there seems to be a lot of state which could be condensed and/or
- * removed.
- */
-
-struct v9fs_session_info {
- /* options */
- unsigned char flags;
- unsigned char nodev;
- unsigned short debug;
- unsigned int afid;
- unsigned int cache;
-#ifdef CONFIG_9P_FSCACHE
- char *cachetag;
- struct fscache_cookie *fscache;
-#endif
-
- char *uname; /* user name to mount as */
- char *aname; /* name of remote hierarchy being mounted */
- unsigned int maxdata; /* max data for client interface */
- kuid_t dfltuid; /* default uid/muid for legacy support */
- kgid_t dfltgid; /* default gid for legacy support */
- kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
- struct p9_client *clnt; /* 9p client */
- struct list_head slist; /* list of sessions registered with v9fs */
- struct backing_dev_info bdi;
- struct rw_semaphore rename_sem;
-};
-
-/* cache_validity flags */
-#define V9FS_INO_INVALID_ATTR 0x01
-
-struct v9fs_inode {
-#ifdef CONFIG_9P_FSCACHE
- spinlock_t fscache_lock;
- struct fscache_cookie *fscache;
-#endif
- struct p9_qid qid;
- unsigned int cache_validity;
- struct p9_fid *writeback_fid;
- struct mutex v_mutex;
- struct inode vfs_inode;
-};
-
-static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
-{
- return container_of(inode, struct v9fs_inode, vfs_inode);
-}
-
-struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
- char *);
-extern void v9fs_session_close(struct v9fs_session_info *v9ses);
-extern void v9fs_session_cancel(struct v9fs_session_info *v9ses);
-extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
-extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
- unsigned int flags);
-extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
-extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
-extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry);
-extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
- void *p);
-extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
- struct p9_fid *fid,
- struct super_block *sb, int new);
-extern const struct inode_operations v9fs_dir_inode_operations_dotl;
-extern const struct inode_operations v9fs_file_inode_operations_dotl;
-extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
-extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
- struct p9_fid *fid,
- struct super_block *sb, int new);
-
-/* other default globals */
-#define V9FS_PORT 564
-#define V9FS_DEFUSER "nobody"
-#define V9FS_DEFANAME ""
-#define V9FS_DEFUID KUIDT_INIT(-2)
-#define V9FS_DEFGID KGIDT_INIT(-2)
-
-static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
-{
- return (inode->i_sb->s_fs_info);
-}
-
-static inline struct v9fs_session_info *v9fs_dentry2v9ses(struct dentry *dentry)
-{
- return dentry->d_sb->s_fs_info;
-}
-
-static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
-{
- return v9ses->flags & V9FS_PROTO_2000U;
-}
-
-static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
-{
- return v9ses->flags & V9FS_PROTO_2000L;
-}
-
-/**
- * v9fs_get_inode_from_fid - Helper routine to populate an inode by
- * issuing a attribute request
- * @v9ses: session information
- * @fid: fid to issue attribute request for
- * @sb: superblock on which to create inode
- *
- */
-static inline struct inode *
-v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
- struct super_block *sb)
-{
- if (v9fs_proto_dotl(v9ses))
- return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
- else
- return v9fs_inode_from_fid(v9ses, fid, sb, 0);
-}
-
-/**
- * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
- * issuing a attribute request
- * @v9ses: session information
- * @fid: fid to issue attribute request for
- * @sb: superblock on which to create inode
- *
- */
-static inline struct inode *
-v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
- struct super_block *sb)
-{
- if (v9fs_proto_dotl(v9ses))
- return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
- else
- return v9fs_inode_from_fid(v9ses, fid, sb, 1);
-}
-
-#endif
diff --git a/addons/9p/src/3.10.108/v9fs_vfs.h b/addons/9p/src/3.10.108/v9fs_vfs.h
deleted file mode 100644
index dc95a252..00000000
--- a/addons/9p/src/3.10.108/v9fs_vfs.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * V9FS VFS extensions.
- *
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-#ifndef FS_9P_V9FS_VFS_H
-#define FS_9P_V9FS_VFS_H
-
-/* plan9 semantics are that created files are implicitly opened.
- * But linux semantics are that you call create, then open.
- * the plan9 approach is superior as it provides an atomic
- * open.
- * we track the create fid here. When the file is opened, if fidopen is
- * non-zero, we use the fid and can skip some steps.
- * there may be a better way to do this, but I don't know it.
- * one BAD way is to clunk the fid on create, then open it again:
- * you lose the atomicity of file open
- */
-
-/* special case:
- * unlink calls remove, which is an implicit clunk. So we have to track
- * that kind of thing so that we don't try to clunk a dead fid.
- */
-#define P9_LOCK_TIMEOUT (30*HZ)
-
-extern struct file_system_type v9fs_fs_type;
-extern const struct address_space_operations v9fs_addr_operations;
-extern const struct file_operations v9fs_file_operations;
-extern const struct file_operations v9fs_file_operations_dotl;
-extern const struct file_operations v9fs_dir_operations;
-extern const struct file_operations v9fs_dir_operations_dotl;
-extern const struct dentry_operations v9fs_dentry_operations;
-extern const struct dentry_operations v9fs_cached_dentry_operations;
-extern const struct file_operations v9fs_cached_file_operations;
-extern const struct file_operations v9fs_cached_file_operations_dotl;
-extern struct kmem_cache *v9fs_inode_cache;
-
-struct inode *v9fs_alloc_inode(struct super_block *sb);
-void v9fs_destroy_inode(struct inode *inode);
-struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t);
-int v9fs_init_inode(struct v9fs_session_info *v9ses,
- struct inode *inode, umode_t mode, dev_t);
-void v9fs_evict_inode(struct inode *inode);
-ino_t v9fs_qid2ino(struct p9_qid *qid);
-void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
-void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *);
-int v9fs_dir_release(struct inode *inode, struct file *filp);
-int v9fs_file_open(struct inode *inode, struct file *file);
-void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
-int v9fs_uflags2omode(int uflags, int extended);
-
-ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
-ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
-void v9fs_blank_wstat(struct p9_wstat *wstat);
-int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
-int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
- int datasync);
-ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *,
- const char __user *, size_t, loff_t *, int);
-int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
-int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
-static inline void v9fs_invalidate_inode_attr(struct inode *inode)
-{
- struct v9fs_inode *v9inode;
- v9inode = V9FS_I(inode);
- v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
- return;
-}
-
-int v9fs_open_to_dotl_flags(int flags);
-#endif
diff --git a/addons/9p/src/3.10.108/vfs_addr.c b/addons/9p/src/3.10.108/vfs_addr.c
deleted file mode 100644
index 055562c5..00000000
--- a/addons/9p/src/3.10.108/vfs_addr.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * linux/fs/9p/vfs_addr.c
- *
- * This file contians vfs address (mmap) ops for 9P2000.
- *
- * Copyright (C) 2005 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "cache.h"
-#include "fid.h"
-
-/**
- * v9fs_fid_readpage - read an entire page in from 9P
- *
- * @fid: fid being read
- * @page: structure to page
- *
- */
-static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
-{
- int retval;
- loff_t offset;
- char *buffer;
- struct inode *inode;
-
- inode = page->mapping->host;
- p9_debug(P9_DEBUG_VFS, "\n");
-
- BUG_ON(!PageLocked(page));
-
- retval = v9fs_readpage_from_fscache(inode, page);
- if (retval == 0)
- return retval;
-
- buffer = kmap(page);
- offset = page_offset(page);
-
- retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset);
- if (retval < 0) {
- v9fs_uncache_page(inode, page);
- goto done;
- }
-
- memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
- flush_dcache_page(page);
- SetPageUptodate(page);
-
- v9fs_readpage_to_fscache(inode, page);
- retval = 0;
-
-done:
- kunmap(page);
- unlock_page(page);
- return retval;
-}
-
-/**
- * v9fs_vfs_readpage - read an entire page in from 9P
- *
- * @filp: file being read
- * @page: structure to page
- *
- */
-
-static int v9fs_vfs_readpage(struct file *filp, struct page *page)
-{
- return v9fs_fid_readpage(filp->private_data, page);
-}
-
-/**
- * v9fs_vfs_readpages - read a set of pages from 9P
- *
- * @filp: file being read
- * @mapping: the address space
- * @pages: list of pages to read
- * @nr_pages: count of pages to read
- *
- */
-
-static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
- struct list_head *pages, unsigned nr_pages)
-{
- int ret = 0;
- struct inode *inode;
-
- inode = mapping->host;
- p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
-
- ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
- if (ret == 0)
- return ret;
-
- ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
- p9_debug(P9_DEBUG_VFS, " = %d\n", ret);
- return ret;
-}
-
-/**
- * v9fs_release_page - release the private state associated with a page
- *
- * Returns 1 if the page can be released, false otherwise.
- */
-
-static int v9fs_release_page(struct page *page, gfp_t gfp)
-{
- if (PagePrivate(page))
- return 0;
- return v9fs_fscache_release_page(page, gfp);
-}
-
-/**
- * v9fs_invalidate_page - Invalidate a page completely or partially
- *
- * @page: structure to page
- * @offset: offset in the page
- */
-
-static void v9fs_invalidate_page(struct page *page, unsigned long offset)
-{
- /*
- * If called with zero offset, we should release
- * the private state assocated with the page
- */
- if (offset == 0)
- v9fs_fscache_invalidate_page(page);
-}
-
-static int v9fs_vfs_writepage_locked(struct page *page)
-{
- char *buffer;
- int retval, len;
- loff_t offset, size;
- mm_segment_t old_fs;
- struct v9fs_inode *v9inode;
- struct inode *inode = page->mapping->host;
-
- v9inode = V9FS_I(inode);
- size = i_size_read(inode);
- if (page->index == size >> PAGE_CACHE_SHIFT)
- len = size & ~PAGE_CACHE_MASK;
- else
- len = PAGE_CACHE_SIZE;
-
- set_page_writeback(page);
-
- buffer = kmap(page);
- offset = page_offset(page);
-
- old_fs = get_fs();
- set_fs(get_ds());
- /* We should have writeback_fid always set */
- BUG_ON(!v9inode->writeback_fid);
-
- retval = v9fs_file_write_internal(inode,
- v9inode->writeback_fid,
- (__force const char __user *)buffer,
- len, &offset, 0);
- if (retval > 0)
- retval = 0;
-
- set_fs(old_fs);
- kunmap(page);
- end_page_writeback(page);
- return retval;
-}
-
-static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
-{
- int retval;
-
- retval = v9fs_vfs_writepage_locked(page);
- if (retval < 0) {
- if (retval == -EAGAIN) {
- redirty_page_for_writepage(wbc, page);
- retval = 0;
- } else {
- SetPageError(page);
- mapping_set_error(page->mapping, retval);
- }
- } else
- retval = 0;
-
- unlock_page(page);
- return retval;
-}
-
-/**
- * v9fs_launder_page - Writeback a dirty page
- * Returns 0 on success.
- */
-
-static int v9fs_launder_page(struct page *page)
-{
- int retval;
- struct inode *inode = page->mapping->host;
-
- v9fs_fscache_wait_on_page_write(inode, page);
- if (clear_page_dirty_for_io(page)) {
- retval = v9fs_vfs_writepage_locked(page);
- if (retval)
- return retval;
- }
- return 0;
-}
-
-/**
- * v9fs_direct_IO - 9P address space operation for direct I/O
- * @rw: direction (read or write)
- * @iocb: target I/O control block
- * @iov: array of vectors that define I/O buffer
- * @pos: offset in file to begin the operation
- * @nr_segs: size of iovec array
- *
- * The presence of v9fs_direct_IO() in the address space ops vector
- * allowes open() O_DIRECT flags which would have failed otherwise.
- *
- * In the non-cached mode, we shunt off direct read and write requests before
- * the VFS gets them, so this method should never be called.
- *
- * Direct IO is not 'yet' supported in the cached mode. Hence when
- * this routine is called through generic_file_aio_read(), the read/write fails
- * with an error.
- *
- */
-static ssize_t
-v9fs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
- loff_t pos, unsigned long nr_segs)
-{
- /*
- * FIXME
- * Now that we do caching with cache mode enabled, We need
- * to support direct IO
- */
- p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%s) off/no(%lld/%lu) EINVAL\n",
- iocb->ki_filp->f_path.dentry->d_name.name,
- (long long)pos, nr_segs);
-
- return -EINVAL;
-}
-
-static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
- int retval = 0;
- struct page *page;
- struct v9fs_inode *v9inode;
- pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- struct inode *inode = mapping->host;
-
- v9inode = V9FS_I(inode);
-start:
- page = grab_cache_page_write_begin(mapping, index, flags);
- if (!page) {
- retval = -ENOMEM;
- goto out;
- }
- BUG_ON(!v9inode->writeback_fid);
- if (PageUptodate(page))
- goto out;
-
- if (len == PAGE_CACHE_SIZE)
- goto out;
-
- retval = v9fs_fid_readpage(v9inode->writeback_fid, page);
- page_cache_release(page);
- if (!retval)
- goto start;
-out:
- *pagep = page;
- return retval;
-}
-
-static int v9fs_write_end(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
-{
- loff_t last_pos = pos + copied;
- struct inode *inode = page->mapping->host;
-
- if (unlikely(copied < len)) {
- /*
- * zero out the rest of the area
- */
- unsigned from = pos & (PAGE_CACHE_SIZE - 1);
-
- zero_user(page, from + copied, len - copied);
- flush_dcache_page(page);
- }
-
- if (!PageUptodate(page))
- SetPageUptodate(page);
- /*
- * No need to use i_size_read() here, the i_size
- * cannot change under us because we hold the i_mutex.
- */
- if (last_pos > inode->i_size) {
- inode_add_bytes(inode, last_pos - inode->i_size);
- i_size_write(inode, last_pos);
- }
- set_page_dirty(page);
- unlock_page(page);
- page_cache_release(page);
-
- return copied;
-}
-
-
-const struct address_space_operations v9fs_addr_operations = {
- .readpage = v9fs_vfs_readpage,
- .readpages = v9fs_vfs_readpages,
- .set_page_dirty = __set_page_dirty_nobuffers,
- .writepage = v9fs_vfs_writepage,
- .write_begin = v9fs_write_begin,
- .write_end = v9fs_write_end,
- .releasepage = v9fs_release_page,
- .invalidatepage = v9fs_invalidate_page,
- .launder_page = v9fs_launder_page,
- .direct_IO = v9fs_direct_IO,
-};
diff --git a/addons/9p/src/3.10.108/vfs_dentry.c b/addons/9p/src/3.10.108/vfs_dentry.c
deleted file mode 100644
index f039b104..00000000
--- a/addons/9p/src/3.10.108/vfs_dentry.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * linux/fs/9p/vfs_dentry.c
- *
- * This file contians vfs dentry ops for the 9P2000 protocol.
- *
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "fid.h"
-
-/**
- * v9fs_dentry_delete - called when dentry refcount equals 0
- * @dentry: dentry in question
- *
- * By returning 1 here we should remove cacheing of unused
- * dentry components.
- *
- */
-
-static int v9fs_dentry_delete(const struct dentry *dentry)
-{
- p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
- dentry->d_name.name, dentry);
-
- return 1;
-}
-
-/**
- * v9fs_cached_dentry_delete - called when dentry refcount equals 0
- * @dentry: dentry in question
- *
- */
-static int v9fs_cached_dentry_delete(const struct dentry *dentry)
-{
- p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
- dentry->d_name.name, dentry);
-
- /* Don't cache negative dentries */
- if (!dentry->d_inode)
- return 1;
- return 0;
-}
-
-/**
- * v9fs_dentry_release - called when dentry is going to be freed
- * @dentry: dentry that is being release
- *
- */
-
-static void v9fs_dentry_release(struct dentry *dentry)
-{
- struct hlist_node *p, *n;
- p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
- dentry->d_name.name, dentry);
- hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
- p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
- dentry->d_fsdata = NULL;
-}
-
-static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
-{
- struct p9_fid *fid;
- struct inode *inode;
- struct v9fs_inode *v9inode;
-
- if (flags & LOOKUP_RCU)
- return -ECHILD;
-
- inode = dentry->d_inode;
- if (!inode)
- goto out_valid;
-
- v9inode = V9FS_I(inode);
- if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
- int retval;
- struct v9fs_session_info *v9ses;
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- v9ses = v9fs_inode2v9ses(inode);
- if (v9fs_proto_dotl(v9ses))
- retval = v9fs_refresh_inode_dotl(fid, inode);
- else
- retval = v9fs_refresh_inode(fid, inode);
- if (retval == -ENOENT)
- return 0;
- if (retval < 0)
- return retval;
- }
-out_valid:
- return 1;
-}
-
-const struct dentry_operations v9fs_cached_dentry_operations = {
- .d_revalidate = v9fs_lookup_revalidate,
- .d_weak_revalidate = v9fs_lookup_revalidate,
- .d_delete = v9fs_cached_dentry_delete,
- .d_release = v9fs_dentry_release,
-};
-
-const struct dentry_operations v9fs_dentry_operations = {
- .d_delete = v9fs_dentry_delete,
- .d_release = v9fs_dentry_release,
-};
diff --git a/addons/9p/src/3.10.108/vfs_dir.c b/addons/9p/src/3.10.108/vfs_dir.c
deleted file mode 100644
index be1e34ad..00000000
--- a/addons/9p/src/3.10.108/vfs_dir.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * linux/fs/9p/vfs_dir.c
- *
- * This file contains vfs directory ops for the 9P2000 protocol.
- *
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "v9fs.h"
-#include "v9fs_vfs.h"
-#include "fid.h"
-
-/**
- * struct p9_rdir - readdir accounting
- * @mutex: mutex protecting readdir
- * @head: start offset of current dirread buffer
- * @tail: end offset of current dirread buffer
- * @buf: dirread buffer
- *
- * private structure for keeping track of readdir
- * allocated on demand
- */
-
-struct p9_rdir {
- int head;
- int tail;
- uint8_t buf[];
-};
-
-/**
- * dt_type - return file type
- * @mistat: mistat structure
- *
- */
-
-static inline int dt_type(struct p9_wstat *mistat)
-{
- unsigned long perm = mistat->mode;
- int rettype = DT_REG;
-
- if (perm & P9_DMDIR)
- rettype = DT_DIR;
- if (perm & P9_DMSYMLINK)
- rettype = DT_LNK;
-
- return rettype;
-}
-
-static void p9stat_init(struct p9_wstat *stbuf)
-{
- stbuf->name = NULL;
- stbuf->uid = NULL;
- stbuf->gid = NULL;
- stbuf->muid = NULL;
- stbuf->extension = NULL;
-}
-
-/**
- * v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
- * @filp: opened file structure
- * @buflen: Length in bytes of buffer to allocate
- *
- */
-
-static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
-{
- struct p9_fid *fid = filp->private_data;
- if (!fid->rdir)
- fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
- return fid->rdir;
-}
-
-/**
- * v9fs_dir_readdir - read a directory
- * @filp: opened file structure
- * @dirent: directory structure ???
- * @filldir: function to populate directory structure ???
- *
- */
-
-static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
-{
- int over;
- struct p9_wstat st;
- int err = 0;
- struct p9_fid *fid;
- int buflen;
- int reclen = 0;
- struct p9_rdir *rdir;
-
- p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
- fid = filp->private_data;
-
- buflen = fid->clnt->msize - P9_IOHDRSZ;
-
- rdir = v9fs_alloc_rdir_buf(filp, buflen);
- if (!rdir)
- return -ENOMEM;
-
- while (1) {
- if (rdir->tail == rdir->head) {
- err = v9fs_file_readn(filp, rdir->buf, NULL,
- buflen, filp->f_pos);
- if (err <= 0)
- return err;
-
- rdir->head = 0;
- rdir->tail = err;
- }
- while (rdir->head < rdir->tail) {
- p9stat_init(&st);
- err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
- rdir->tail - rdir->head, &st);
- if (err) {
- p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
- p9stat_free(&st);
- return -EIO;
- }
- reclen = st.size+2;
-
- over = filldir(dirent, st.name, strlen(st.name),
- filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
-
- p9stat_free(&st);
-
- if (over)
- return 0;
-
- rdir->head += reclen;
- filp->f_pos += reclen;
- }
- }
-}
-
-/**
- * v9fs_dir_readdir_dotl - read a directory
- * @filp: opened file structure
- * @dirent: buffer to fill dirent structures
- * @filldir: function to populate dirent structures
- *
- */
-static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
- filldir_t filldir)
-{
- int over;
- int err = 0;
- struct p9_fid *fid;
- int buflen;
- struct p9_rdir *rdir;
- struct p9_dirent curdirent;
- u64 oldoffset = 0;
-
- p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
- fid = filp->private_data;
-
- buflen = fid->clnt->msize - P9_READDIRHDRSZ;
-
- rdir = v9fs_alloc_rdir_buf(filp, buflen);
- if (!rdir)
- return -ENOMEM;
-
- while (1) {
- if (rdir->tail == rdir->head) {
- err = p9_client_readdir(fid, rdir->buf, buflen,
- filp->f_pos);
- if (err <= 0)
- return err;
-
- rdir->head = 0;
- rdir->tail = err;
- }
-
- while (rdir->head < rdir->tail) {
-
- err = p9dirent_read(fid->clnt, rdir->buf + rdir->head,
- rdir->tail - rdir->head,
- &curdirent);
- if (err < 0) {
- p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
- return -EIO;
- }
-
- /* d_off in dirent structure tracks the offset into
- * the next dirent in the dir. However, filldir()
- * expects offset into the current dirent. Hence
- * while calling filldir send the offset from the
- * previous dirent structure.
- */
- over = filldir(dirent, curdirent.d_name,
- strlen(curdirent.d_name),
- oldoffset, v9fs_qid2ino(&curdirent.qid),
- curdirent.d_type);
- oldoffset = curdirent.d_off;
-
- if (over)
- return 0;
-
- filp->f_pos = curdirent.d_off;
- rdir->head += err;
- }
- }
-}
-
-
-/**
- * v9fs_dir_release - close a directory
- * @inode: inode of the directory
- * @filp: file pointer to a directory
- *
- */
-
-int v9fs_dir_release(struct inode *inode, struct file *filp)
-{
- struct p9_fid *fid;
-
- fid = filp->private_data;
- p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
- inode, filp, fid ? fid->fid : -1);
- if (fid)
- p9_client_clunk(fid);
- return 0;
-}
-
-const struct file_operations v9fs_dir_operations = {
- .read = generic_read_dir,
- .llseek = generic_file_llseek,
- .readdir = v9fs_dir_readdir,
- .open = v9fs_file_open,
- .release = v9fs_dir_release,
-};
-
-const struct file_operations v9fs_dir_operations_dotl = {
- .read = generic_read_dir,
- .llseek = generic_file_llseek,
- .readdir = v9fs_dir_readdir_dotl,
- .open = v9fs_file_open,
- .release = v9fs_dir_release,
- .fsync = v9fs_file_fsync_dotl,
-};
diff --git a/addons/9p/src/3.10.108/vfs_file.c b/addons/9p/src/3.10.108/vfs_file.c
deleted file mode 100644
index d384a8b7..00000000
--- a/addons/9p/src/3.10.108/vfs_file.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * linux/fs/9p/vfs_file.c
- *
- * This file contians vfs file ops for 9P2000.
- *
- * Copyright (C) 2004 by Eric Van Hensbergen
- * Copyright (C) 2002 by Ron Minnich
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include