aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/CodingStyle20
-rw-r--r--Documentation/DocBook/kernel-api.tmpl4
-rw-r--r--Documentation/DocBook/uio-howto.tmpl611
-rw-r--r--Documentation/HOWTO3
-rw-r--r--Documentation/driver-model/devres.txt2
-rw-r--r--Documentation/feature-removal-schedule.txt14
-rw-r--r--Documentation/ja_JP/HOWTO650
-rw-r--r--Documentation/ja_JP/stable_api_nonsense.txt263
-rw-r--r--Documentation/powerpc/booting-without-of.txt6
-rw-r--r--Documentation/zh_CN/HOWTO536
-rw-r--r--Documentation/zh_CN/stable_api_nonsense.txt157
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts4
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c9
-rw-r--r--drivers/Kconfig1
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/base/core.c168
-rw-r--r--drivers/base/power/Makefile2
-rw-r--r--drivers/base/power/power.h5
-rw-r--r--drivers/base/power/runtime.c85
-rw-r--r--drivers/base/power/sysfs.c66
-rw-r--r--drivers/firewire/fw-ohci.c3
-rw-r--r--drivers/firewire/fw-sbp2.c16
-rw-r--r--drivers/firewire/fw-transaction.c9
-rw-r--r--drivers/firewire/fw-transaction.h4
-rw-r--r--drivers/infiniband/core/cm.c2
-rw-r--r--drivers/infiniband/core/cma.c2
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h54
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes_pSeries.h156
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c28
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c56
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h7
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c50
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c1087
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.h21
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qes.h22
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c39
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c15
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h31
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c10
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c8
-rw-r--r--drivers/infiniband/hw/ehca/hcp_phyp.c2
-rw-r--r--drivers/infiniband/hw/ehca/hipz_fns_core.h4
-rw-r--r--drivers/infiniband/hw/ehca/hipz_hw.h24
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c2
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.h4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_eeprom.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c26
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h4
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c115
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c221
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c28
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h15
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h5
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c4
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c47
-rw-r--r--drivers/net/Kconfig44
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/arm/ether3.c2
-rw-r--r--drivers/net/bfin_mac.c1009
-rw-r--r--drivers/net/bfin_mac.h132
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c37
-rw-r--r--drivers/net/gianfar.c12
-rw-r--r--drivers/net/mlx4/catas.c106
-rw-r--r--drivers/net/mlx4/eq.c56
-rw-r--r--drivers/net/mlx4/intf.c2
-rw-r--r--drivers/net/mlx4/main.c26
-rw-r--r--drivers/net/mlx4/mlx4.h13
-rw-r--r--drivers/net/ni5010.c6
-rw-r--r--drivers/net/ns83820.c2
-rw-r--r--drivers/net/phy/vitesse.c46
-rw-r--r--drivers/net/saa9730.c9
-rw-r--r--drivers/net/tc35815.c2
-rw-r--r--drivers/net/wireless/ipw2100.c6
-rw-r--r--drivers/net/wireless/ipw2200.c18
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/pcmcia/ds.c40
-rw-r--r--drivers/uio/Kconfig29
-rw-r--r--drivers/uio/Makefile2
-rw-r--r--drivers/uio/uio.c701
-rw-r--r--drivers/uio/uio_cif.c156
-rw-r--r--drivers/usb/core/driver.c7
-rw-r--r--fs/cifs/CHANGES13
-rw-r--r--fs/cifs/README38
-rw-r--r--fs/cifs/TODO12
-rw-r--r--fs/cifs/asn1.c57
-rw-r--r--fs/cifs/cifs_debug.c103
-rw-r--r--fs/cifs/cifs_fs_sb.h2
-rw-r--r--fs/cifs/cifs_unicode.c2
-rw-r--r--fs/cifs/cifs_unicode.h39
-rw-r--r--fs/cifs/cifs_uniupr.h8
-rw-r--r--fs/cifs/cifsencrypt.c262
-rw-r--r--fs/cifs/cifsfs.c199
-rw-r--r--fs/cifs/cifsfs.h23
-rw-r--r--fs/cifs/cifsglob.h78
-rw-r--r--fs/cifs/cifspdu.h297
-rw-r--r--fs/cifs/cifsproto.h123
-rw-r--r--fs/cifs/cifssmb.c1621
-rw-r--r--fs/cifs/connect.c1262
-rw-r--r--fs/cifs/dir.c22
-rw-r--r--fs/cifs/export.c49
-rw-r--r--fs/cifs/fcntl.c2
-rw-r--r--fs/cifs/file.c287
-rw-r--r--fs/cifs/inode.c320
-rw-r--r--fs/cifs/ioctl.c4
-rw-r--r--fs/cifs/link.c116
-rw-r--r--fs/cifs/md4.c10
-rw-r--r--fs/cifs/md5.c8
-rw-r--r--fs/cifs/misc.c239
-rw-r--r--fs/cifs/netmisc.c171
-rw-r--r--fs/cifs/nterr.c8
-rw-r--r--fs/cifs/nterr.h8
-rw-r--r--fs/cifs/ntlmssp.h22
-rw-r--r--fs/cifs/readdir.c375
-rw-r--r--fs/cifs/sess.c249
-rw-r--r--fs/cifs/smbdes.c30
-rw-r--r--fs/cifs/smbencrypt.c52
-rw-r--r--fs/cifs/smberr.h8
-rw-r--r--fs/cifs/transport.c248
-rw-r--r--fs/cifs/xattr.c229
-rw-r--r--fs/debugfs/inode.c5
-rw-r--r--fs/gfs2/ops_file.c24
-rw-r--r--fs/locks.c112
-rw-r--r--fs/nfs/file.c16
-rw-r--r--fs/nfsd/nfs4state.c10
-rw-r--r--fs/sysfs/dir.c25
-rw-r--r--fs/sysfs/file.c9
-rw-r--r--fs/sysfs/inode.c2
-rw-r--r--fs/sysfs/mount.c10
-rw-r--r--fs/sysfs/symlink.c12
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--include/linux/device.h10
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/fsl_devices.h1
-rw-r--r--include/linux/kobject.h25
-rw-r--r--include/linux/pm.h11
-rw-r--r--include/linux/uio_driver.h91
-rw-r--r--kernel/power/Kconfig12
-rw-r--r--lib/kobject_uevent.c30
-rw-r--r--net/ieee80211/ieee80211_wx.c7
151 files changed, 9378 insertions, 4882 deletions
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index a667eb1fc26e..7f1730f1a1ae 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -633,12 +633,27 @@ covers RTL which is used frequently with assembly language in the kernel.
633 633
634Kernel developers like to be seen as literate. Do mind the spelling 634Kernel developers like to be seen as literate. Do mind the spelling
635of kernel messages to make a good impression. Do not use crippled 635of kernel messages to make a good impression. Do not use crippled
636words like "dont" and use "do not" or "don't" instead. 636words like "dont"; use "do not" or "don't" instead. Make the messages
637concise, clear, and unambiguous.
637 638
638Kernel messages do not have to be terminated with a period. 639Kernel messages do not have to be terminated with a period.
639 640
640Printing numbers in parentheses (%d) adds no value and should be avoided. 641Printing numbers in parentheses (%d) adds no value and should be avoided.
641 642
643There are a number of driver model diagnostic macros in <linux/device.h>
644which you should use to make sure messages are matched to the right device
645and driver, and are tagged with the right level: dev_err(), dev_warn(),
646dev_info(), and so forth. For messages that aren't associated with a
647particular device, <linux/kernel.h> defines pr_debug() and pr_info().
648
649Coming up with good debugging messages can be quite a challenge; and once
650you have them, they can be a huge help for remote troubleshooting. Such
651messages should be compiled out when the DEBUG symbol is not defined (that
652is, by default they are not included). When you use dev_dbg() or pr_debug(),
653that's automatic. Many subsystems have Kconfig options to turn on -DDEBUG.
654A related convention uses VERBOSE_DEBUG to add dev_vdbg() messages to the
655ones already enabled by DEBUG.
656
642 657
643 Chapter 14: Allocating memory 658 Chapter 14: Allocating memory
644 659
@@ -790,4 +805,5 @@ Kernel CodingStyle, by greg@kroah.com at OLS 2002:
790http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ 805http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
791 806
792-- 807--
793Last updated on 2006-December-06. 808Last updated on 2007-July-13.
809
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index fd2ef4d29b6d..a0af560ed740 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -408,6 +408,10 @@ X!Edrivers/pnp/system.c
408!Edrivers/pnp/manager.c 408!Edrivers/pnp/manager.c
409!Edrivers/pnp/support.c 409!Edrivers/pnp/support.c
410 </sect1> 410 </sect1>
411 <sect1><title>Userspace IO devices</title>
412!Edrivers/uio/uio.c
413!Iinclude/linux/uio_driver.h
414 </sect1>
411 </chapter> 415 </chapter>
412 416
413 <chapter id="blkdev"> 417 <chapter id="blkdev">
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
new file mode 100644
index 000000000000..e3bb29a8d8dd
--- /dev/null
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -0,0 +1,611 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
3"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
4
5<book id="index">
6<bookinfo>
7<title>The Userspace I/O HOWTO</title>
8
9<author>
10 <firstname>Hans-Jürgen</firstname>
11 <surname>Koch</surname>
12 <authorblurb><para>Linux developer, Linutronix</para></authorblurb>
13 <affiliation>
14 <orgname>
15 <ulink url="http://www.linutronix.de">Linutronix</ulink>
16 </orgname>
17
18 <address>
19 <email>hjk@linutronix.de</email>
20 </address>
21 </affiliation>
22</author>
23
24<pubdate>2006-12-11</pubdate>
25
26<abstract>
27 <para>This HOWTO describes concept and usage of Linux kernel's
28 Userspace I/O system.</para>
29</abstract>
30
31<revhistory>
32 <revision>
33 <revnumber>0.3</revnumber>
34 <date>2007-04-29</date>
35 <authorinitials>hjk</authorinitials>
36 <revremark>Added section about userspace drivers.</revremark>
37 </revision>
38 <revision>
39 <revnumber>0.2</revnumber>
40 <date>2007-02-13</date>
41 <authorinitials>hjk</authorinitials>
42 <revremark>Update after multiple mappings were added.</revremark>
43 </revision>
44 <revision>
45 <revnumber>0.1</revnumber>
46 <date>2006-12-11</date>
47 <authorinitials>hjk</authorinitials>
48 <revremark>First draft.</revremark>
49 </revision>
50</revhistory>
51</bookinfo>
52
53<chapter id="aboutthisdoc">
54<?dbhtml filename="about.html"?>
55<title>About this document</title>
56
57<sect1 id="copyright">
58<?dbhtml filename="copyright.html"?>
59<title>Copyright and License</title>
60<para>
61 Copyright (c) 2006 by Hans-Jürgen Koch.</para>
62<para>
63This documentation is Free Software licensed under the terms of the
64GPL version 2.
65</para>
66</sect1>
67
68<sect1 id="translations">
69<?dbhtml filename="translations.html"?>
70<title>Translations</title>
71
72<para>If you know of any translations for this document, or you are
73interested in translating it, please email me
74<email>hjk@linutronix.de</email>.
75</para>
76</sect1>
77
78<sect1 id="preface">
79<title>Preface</title>
80 <para>
81 For many types of devices, creating a Linux kernel driver is
82 overkill. All that is really needed is some way to handle an
83 interrupt and provide access to the memory space of the
84 device. The logic of controlling the device does not
85 necessarily have to be within the kernel, as the device does
86 not need to take advantage of any of other resources that the
87 kernel provides. One such common class of devices that are
88 like this are for industrial I/O cards.
89 </para>
90 <para>
91 To address this situation, the userspace I/O system (UIO) was
92 designed. For typical industrial I/O cards, only a very small
93 kernel module is needed. The main part of the driver will run in
94 user space. This simplifies development and reduces the risk of
95 serious bugs within a kernel module.
96 </para>
97</sect1>
98
99<sect1 id="thanks">
100<title>Acknowledgments</title>
101 <para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
102 Linutronix, who have not only written most of the UIO code, but also
103 helped greatly writing this HOWTO by giving me all kinds of background
104 information.</para>
105</sect1>
106
107<sect1 id="feedback">
108<title>Feedback</title>
109 <para>Find something wrong with this document? (Or perhaps something
110 right?) I would love to hear from you. Please email me at
111 <email>hjk@linutronix.de</email>.</para>
112</sect1>
113</chapter>
114
115<chapter id="about">
116<?dbhtml filename="about.html"?>
117<title>About UIO</title>
118
119<para>If you use UIO for your card's driver, here's what you get:</para>
120
121<itemizedlist>
122<listitem>
123 <para>only one small kernel module to write and maintain.</para>
124</listitem>
125<listitem>
126 <para>develop the main part of your driver in user space,
127 with all the tools and libraries you're used to.</para>
128</listitem>
129<listitem>
130 <para>bugs in your driver won't crash the kernel.</para>
131</listitem>
132<listitem>
133 <para>updates of your driver can take place without recompiling
134 the kernel.</para>
135</listitem>
136<listitem>
137 <para>if you need to keep some parts of your driver closed source,
138 you can do so without violating the GPL license on the kernel.</para>
139</listitem>
140</itemizedlist>
141
142<sect1 id="how_uio_works">
143<title>How UIO works</title>
144 <para>
145 Each UIO device is accessed through a device file and several
146 sysfs attribute files. The device file will be called
147 <filename>/dev/uio0</filename> for the first device, and
148 <filename>/dev/uio1</filename>, <filename>/dev/uio2</filename>
149 and so on for subsequent devices.
150 </para>
151
152 <para><filename>/dev/uioX</filename> is used to access the
153 address space of the card. Just use
154 <function>mmap()</function> to access registers or RAM
155 locations of your card.
156 </para>
157
158 <para>
159 Interrupts are handled by reading from
160 <filename>/dev/uioX</filename>. A blocking
161 <function>read()</function> from
162 <filename>/dev/uioX</filename> will return as soon as an
163 interrupt occurs. You can also use
164 <function>select()</function> on
165 <filename>/dev/uioX</filename> to wait for an interrupt. The
166 integer value read from <filename>/dev/uioX</filename>
167 represents the total interrupt count. You can use this number
168 to figure out if you missed some interrupts.
169 </para>
170
171 <para>
172 To handle interrupts properly, your custom kernel module can
173 provide its own interrupt handler. It will automatically be
174 called by the built-in handler.
175 </para>
176
177 <para>
178 For cards that don't generate interrupts but need to be
179 polled, there is the possibility to set up a timer that
180 triggers the interrupt handler at configurable time intervals.
181 See <filename>drivers/uio/uio_dummy.c</filename> for an
182 example of this technique.
183 </para>
184
185 <para>
186 Each driver provides attributes that are used to read or write
187 variables. These attributes are accessible through sysfs
188 files. A custom kernel driver module can add its own
189 attributes to the device owned by the uio driver, but not added
190 to the UIO device itself at this time. This might change in the
191 future if it would be found to be useful.
192 </para>
193
194 <para>
195 The following standard attributes are provided by the UIO
196 framework:
197 </para>
198<itemizedlist>
199<listitem>
200 <para>
201 <filename>name</filename>: The name of your device. It is
202 recommended to use the name of your kernel module for this.
203 </para>
204</listitem>
205<listitem>
206 <para>
207 <filename>version</filename>: A version string defined by your
208 driver. This allows the user space part of your driver to deal
209 with different versions of the kernel module.
210 </para>
211</listitem>
212<listitem>
213 <para>
214 <filename>event</filename>: The total number of interrupts
215 handled by the driver since the last time the device node was
216 read.
217 </para>
218</listitem>
219</itemizedlist>
220<para>
221 These attributes appear under the
222 <filename>/sys/class/uio/uioX</filename> directory. Please
223 note that this directory might be a symlink, and not a real
224 directory. Any userspace code that accesses it must be able
225 to handle this.
226</para>
227<para>
228 Each UIO device can make one or more memory regions available for
229 memory mapping. This is necessary because some industrial I/O cards
230 require access to more than one PCI memory region in a driver.
231</para>
232<para>
233 Each mapping has its own directory in sysfs, the first mapping
234 appears as <filename>/sys/class/uio/uioX/maps/map0/</filename>.
235 Subsequent mappings create directories <filename>map1/</filename>,
236 <filename>map2/</filename>, and so on. These directories will only
237 appear if the size of the mapping is not 0.
238</para>
239<para>
240 Each <filename>mapX/</filename> directory contains two read-only files
241 that show start address and size of the memory:
242</para>
243<itemizedlist>
244<listitem>
245 <para>
246 <filename>addr</filename>: The address of memory that can be mapped.
247 </para>
248</listitem>
249<listitem>
250 <para>
251 <filename>size</filename>: The size, in bytes, of the memory
252 pointed to by addr.
253 </para>
254</listitem>
255</itemizedlist>
256
257<para>
258 From userspace, the different mappings are distinguished by adjusting
259 the <varname>offset</varname> parameter of the
260 <function>mmap()</function> call. To map the memory of mapping N, you
261 have to use N times the page size as your offset:
262</para>
263<programlisting format="linespecific">
264offset = N * getpagesize();
265</programlisting>
266
267</sect1>
268</chapter>
269
270<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
271<?dbhtml filename="using-uio_dummy.html"?>
272<title>Using uio_dummy</title>
273 <para>
274 Well, there is no real use for uio_dummy. Its only purpose is
275 to test most parts of the UIO system (everything except
276 hardware interrupts), and to serve as an example for the
277 kernel module that you will have to write yourself.
278 </para>
279
280<sect1 id="what_uio_dummy_does">
281<title>What uio_dummy does</title>
282 <para>
283 The kernel module <filename>uio_dummy.ko</filename> creates a
284 device that uses a timer to generate periodic interrupts. The
285 interrupt handler does nothing but increment a counter. The
286 driver adds two custom attributes, <varname>count</varname>
287 and <varname>freq</varname>, that appear under
288 <filename>/sys/devices/platform/uio_dummy/</filename>.
289 </para>
290
291 <para>
292 The attribute <varname>count</varname> can be read and
293 written. The associated file
294 <filename>/sys/devices/platform/uio_dummy/count</filename>
295 appears as a normal text file and contains the total number of
296 timer interrupts. If you look at it (e.g. using
297 <function>cat</function>), you'll notice it is slowly counting
298 up.
299 </para>
300
301 <para>
302 The attribute <varname>freq</varname> can be read and written.
303 The content of
304 <filename>/sys/devices/platform/uio_dummy/freq</filename>
305 represents the number of system timer ticks between two timer
306 interrupts. The default value of <varname>freq</varname> is
307 the value of the kernel variable <varname>HZ</varname>, which
308 gives you an interval of one second. Lower values will
309 increase the frequency. Try the following:
310 </para>
311<programlisting format="linespecific">
312cd /sys/devices/platform/uio_dummy/
313echo 100 > freq
314</programlisting>
315 <para>
316 Use <function>cat count</function> to see how the interrupt
317 frequency changes.
318 </para>
319</sect1>
320</chapter>
321
322<chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
323<?dbhtml filename="custom_kernel_module.html"?>
324<title>Writing your own kernel module</title>
325 <para>
326 Please have a look at <filename>uio_dummy.c</filename> as an
327 example. The following paragraphs explain the different
328 sections of this file.
329 </para>
330
331<sect1 id="uio_info">
332<title>struct uio_info</title>
333 <para>
334 This structure tells the framework the details of your driver,
335 Some of the members are required, others are optional.
336 </para>
337
338<itemizedlist>
339<listitem><para>
340<varname>char *name</varname>: Required. The name of your driver as
341it will appear in sysfs. I recommend using the name of your module for this.
342</para></listitem>
343
344<listitem><para>
345<varname>char *version</varname>: Required. This string appears in
346<filename>/sys/class/uio/uioX/version</filename>.
347</para></listitem>
348
349<listitem><para>
350<varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
351have memory that can be mapped with <function>mmap()</function>. For each
352mapping you need to fill one of the <varname>uio_mem</varname> structures.
353See the description below for details.
354</para></listitem>
355
356<listitem><para>
357<varname>long irq</varname>: Required. If your hardware generates an
358interrupt, it's your modules task to determine the irq number during
359initialization. If you don't have a hardware generated interrupt but
360want to trigger the interrupt handler in some other way, set
361<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
362uio_dummy module does this as it triggers the event mechanism in a timer
363routine. If you had no interrupt at all, you could set
364<varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
365rarely makes sense.
366</para></listitem>
367
368<listitem><para>
369<varname>unsigned long irq_flags</varname>: Required if you've set
370<varname>irq</varname> to a hardware interrupt number. The flags given
371here will be used in the call to <function>request_irq()</function>.
372</para></listitem>
373
374<listitem><para>
375<varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
376*vma)</varname>: Optional. If you need a special
377<function>mmap()</function> function, you can set it here. If this
378pointer is not NULL, your <function>mmap()</function> will be called
379instead of the built-in one.
380</para></listitem>
381
382<listitem><para>
383<varname>int (*open)(struct uio_info *info, struct inode *inode)
384</varname>: Optional. You might want to have your own
385<function>open()</function>, e.g. to enable interrupts only when your
386device is actually used.
387</para></listitem>
388
389<listitem><para>
390<varname>int (*release)(struct uio_info *info, struct inode *inode)
391</varname>: Optional. If you define your own
392<function>open()</function>, you will probably also want a custom
393<function>release()</function> function.
394</para></listitem>
395</itemizedlist>
396
397<para>
398Usually, your device will have one or more memory regions that can be mapped
399to user space. For each region, you have to set up a
400<varname>struct uio_mem</varname> in the <varname>mem[]</varname> array.
401Here's a description of the fields of <varname>struct uio_mem</varname>:
402</para>
403
404<itemizedlist>
405<listitem><para>
406<varname>int memtype</varname>: Required if the mapping is used. Set this to
407<varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
408card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
409memory (e.g. allocated with <function>kmalloc()</function>). There's also
410<varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
411</para></listitem>
412
413<listitem><para>
414<varname>unsigned long addr</varname>: Required if the mapping is used.
415Fill in the address of your memory block. This address is the one that
416appears in sysfs.
417</para></listitem>
418
419<listitem><para>
420<varname>unsigned long size</varname>: Fill in the size of the
421memory block that <varname>addr</varname> points to. If <varname>size</varname>
422is zero, the mapping is considered unused. Note that you
423<emphasis>must</emphasis> initialize <varname>size</varname> with zero for
424all unused mappings.
425</para></listitem>
426
427<listitem><para>
428<varname>void *internal_addr</varname>: If you have to access this memory
429region from within your kernel module, you will want to map it internally by
430using something like <function>ioremap()</function>. Addresses
431returned by this function cannot be mapped to user space, so you must not
432store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
433instead to remember such an address.
434</para></listitem>
435</itemizedlist>
436
437<para>
438Please do not touch the <varname>kobj</varname> element of
439<varname>struct uio_mem</varname>! It is used by the UIO framework
440to set up sysfs files for this mapping. Simply leave it alone.
441</para>
442</sect1>
443
444<sect1 id="adding_irq_handler">
445<title>Adding an interrupt handler</title>
446 <para>
447 What you need to do in your interrupt handler depends on your
448 hardware and on how you want to handle it. You should try to
449 keep the amount of code in your kernel interrupt handler low.
450 If your hardware requires no action that you
451 <emphasis>have</emphasis> to perform after each interrupt,
452 then your handler can be empty.</para> <para>If, on the other
453 hand, your hardware <emphasis>needs</emphasis> some action to
454 be performed after each interrupt, then you
455 <emphasis>must</emphasis> do it in your kernel module. Note
456 that you cannot rely on the userspace part of your driver. Your
457 userspace program can terminate at any time, possibly leaving
458 your hardware in a state where proper interrupt handling is
459 still required.
460 </para>
461
462 <para>
463 There might also be applications where you want to read data
464 from your hardware at each interrupt and buffer it in a piece
465 of kernel memory you've allocated for that purpose. With this
466 technique you could avoid loss of data if your userspace
467 program misses an interrupt.
468 </para>
469
470 <para>
471 A note on shared interrupts: Your driver should support
472 interrupt sharing whenever this is possible. It is possible if
473 and only if your driver can detect whether your hardware has
474 triggered the interrupt or not. This is usually done by looking
475 at an interrupt status register. If your driver sees that the
476 IRQ bit is actually set, it will perform its actions, and the
477 handler returns IRQ_HANDLED. If the driver detects that it was
478 not your hardware that caused the interrupt, it will do nothing
479 and return IRQ_NONE, allowing the kernel to call the next
480 possible interrupt handler.
481 </para>
482
483 <para>
484 If you decide not to support shared interrupts, your card
485 won't work in computers with no free interrupts. As this
486 frequently happens on the PC platform, you can save yourself a
487 lot of trouble by supporting interrupt sharing.
488 </para>
489</sect1>
490
491</chapter>
492
493<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
494<?dbhtml filename="userspace_driver.html"?>
495<title>Writing a driver in userspace</title>
496 <para>
497 Once you have a working kernel module for your hardware, you can
498 write the userspace part of your driver. You don't need any special
499 libraries, your driver can be written in any reasonable language,
500 you can use floating point numbers and so on. In short, you can
501 use all the tools and libraries you'd normally use for writing a
502 userspace application.
503 </para>
504
505<sect1 id="getting_uio_information">
506<title>Getting information about your UIO device</title>
507 <para>
508 Information about all UIO devices is available in sysfs. The
509 first thing you should do in your driver is check
510 <varname>name</varname> and <varname>version</varname> to
511 make sure your talking to the right device and that its kernel
512 driver has the version you expect.
513 </para>
514 <para>
515 You should also make sure that the memory mapping you need
516 exists and has the size you expect.
517 </para>
518 <para>
519 There is a tool called <varname>lsuio</varname> that lists
520 UIO devices and their attributes. It is available here:
521 </para>
522 <para>
523 <ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
524 http://www.osadl.org/projects/downloads/UIO/user/</ulink>
525 </para>
526 <para>
527 With <varname>lsuio</varname> you can quickly check if your
528 kernel module is loaded and which attributes it exports.
529 Have a look at the manpage for details.
530 </para>
531 <para>
532 The source code of <varname>lsuio</varname> can serve as an
533 example for getting information about an UIO device.
534 The file <filename>uio_helper.c</filename> contains a lot of
535 functions you could use in your userspace driver code.
536 </para>
537</sect1>
538
539<sect1 id="mmap_device_memory">
540<title>mmap() device memory</title>
541 <para>
542 After you made sure you've got the right device with the
543 memory mappings you need, all you have to do is to call
544 <function>mmap()</function> to map the device's memory
545 to userspace.
546 </para>
547 <para>
548 The parameter <varname>offset</varname> of the
549 <function>mmap()</function> call has a special meaning
550 for UIO devices: It is used to select which mapping of
551 your device you want to map. To map the memory of
552 mapping N, you have to use N times the page size as
553 your offset:
554 </para>
555<programlisting format="linespecific">
556 offset = N * getpagesize();
557</programlisting>
558 <para>
559 N starts from zero, so if you've got only one memory
560 range to map, set <varname>offset = 0</varname>.
561 A drawback of this technique is that memory is always
562 mapped beginning with its start address.
563 </para>
564</sect1>
565
566<sect1 id="wait_for_interrupts">
567<title>Waiting for interrupts</title>
568 <para>
569 After you successfully mapped your devices memory, you
570 can access it like an ordinary array. Usually, you will
571 perform some initialization. After that, your hardware
572 starts working and will generate an interrupt as soon
573 as it's finished, has some data available, or needs your
574 attention because an error occured.
575 </para>
576 <para>
577 <filename>/dev/uioX</filename> is a read-only file. A
578 <function>read()</function> will always block until an
579 interrupt occurs. There is only one legal value for the
580 <varname>count</varname> parameter of
581 <function>read()</function>, and that is the size of a
582 signed 32 bit integer (4). Any other value for
583 <varname>count</varname> causes <function>read()</function>
584 to fail. The signed 32 bit integer read is the interrupt
585 count of your device. If the value is one more than the value
586 you read the last time, everything is OK. If the difference
587 is greater than one, you missed interrupts.
588 </para>
589 <para>
590 You can also use <function>select()</function> on
591 <filename>/dev/uioX</filename>.
592 </para>
593</sect1>
594
595</chapter>
596
597<appendix id="app1">
598<title>Further information</title>
599<itemizedlist>
600 <listitem><para>
601 <ulink url="http://www.osadl.org">
602 OSADL homepage.</ulink>
603 </para></listitem>
604 <listitem><para>
605 <ulink url="http://www.linutronix.de">
606 Linutronix homepage.</ulink>
607 </para></listitem>
608</itemizedlist>
609</appendix>
610
611</book>
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 98e2701c746f..f8cc3f8ed152 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -249,6 +249,9 @@ process is as follows:
249 release a new -rc kernel every week. 249 release a new -rc kernel every week.
250 - Process continues until the kernel is considered "ready", the 250 - Process continues until the kernel is considered "ready", the
251 process should last around 6 weeks. 251 process should last around 6 weeks.
252 - A list of known regressions present in each -rc release is
253 tracked at the following URI:
254 http://kernelnewbies.org/known_regressions
252 255
253It is worth mentioning what Andrew Morton wrote on the linux-kernel 256It is worth mentioning what Andrew Morton wrote on the linux-kernel
254mailing list about kernel releases: 257mailing list about kernel releases:
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 6c8d8f27db34..8569072fa387 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -207,7 +207,7 @@ responsibility. This is usually non-issue because bus ops and
207resource allocations already do the job. 207resource allocations already do the job.
208 208
209For an example of single-instance devres type, read pcim_iomap_table() 209For an example of single-instance devres type, read pcim_iomap_table()
210in lib/iomap.c. 210in lib/devres.c.
211 211
212All devres interface functions can be called without context if the 212All devres interface functions can be called without context if the
213right gfp mask is given. 213right gfp mask is given.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index d05e6243b4df..66c8b4b165c1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -26,9 +26,7 @@ Who: Hans Verkuil <hverkuil@xs4all.nl> and
26 26
27--------------------------- 27---------------------------
28 28
29What: /sys/devices/.../power/state 29What: dev->power.power_state
30 dev->power.power_state
31 dpm_runtime_{suspend,resume)()
32When: July 2007 30When: July 2007
33Why: Broken design for runtime control over driver power states, confusing 31Why: Broken design for runtime control over driver power states, confusing
34 driver-internal runtime power management with: mechanisms to support 32 driver-internal runtime power management with: mechanisms to support
@@ -310,3 +308,13 @@ Why: The arch/powerpc tree is the merged architecture for ppc32 and ppc64
310Who: linuxppc-dev@ozlabs.org 308Who: linuxppc-dev@ozlabs.org
311 309
312--------------------------- 310---------------------------
311
312What: mthca driver's MSI support
313When: January 2008
314Files: drivers/infiniband/hw/mthca/*.[ch]
315Why: All mthca hardware also supports MSI-X, which provides
316 strictly more functionality than MSI. So there is no point in
317 having both MSI-X and MSI support in the driver.
318Who: Roland Dreier <rolandd@cisco.com>
319
320---------------------------
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO
new file mode 100644
index 000000000000..b2446a090870
--- /dev/null
+++ b/Documentation/ja_JP/HOWTO
@@ -0,0 +1,650 @@
1NOTE:
2This is Japanese translated version of "Documentation/HOWTO".
3This one is maintained by Tsugikazu Shibata <tshibata@ab.jp.nec.com>
4and JF Project team <www.linux.or.jp/JF>.
5If you find difference with original file or problem in translation,
6please contact maintainer of this file or JF project.
7
8Please also note that purpose of this file is easier to read for non
9English natives and not to be intended to fork. So, if you have any
10comments or updates of this file, please try to update Original(English)
11file at first.
12
13Last Updated: 2007/06/04
14==================================
15これは、
16linux-2.6.21/Documentation/HOWTO
17の和訳です。
18
19翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
20翻訳日: 2007/06/04
21翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
22校正者: 松倉さん <nbh--mats at nifty dot com>
23 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
24 武井伸光さん、<takei at webmasters dot gr dot jp>
25 かねこさん (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp>
26 野口さん (Kenji Noguchi) <tokyo246 at gmail dot com>
27 河内さん (Takayoshi Kochi) <t-kochi at bq dot jp dot nec dot com>
28 岩本さん (iwamoto) <iwamoto.kn at ncos dot nec dot co dot jp>
29==================================
30
31Linux カーネル開発のやり方
32-------------------------------
33
34これは上のトピック( Linux カーネル開発のやり方)の重要な事柄を網羅した
35ドキュメントです。ここには Linux カーネル開発者になるための方法と
36Linux カーネル開発コミュニティと共に活動するやり方を学ぶ方法が含まれて
37います。カーネルプログラミングに関する技術的な項目に関することは何も含
38めないようにしていますが、カーネル開発者となるための正しい方向に向かう
39手助けになります。
40
41もし、このドキュメントのどこかが古くなっていた場合には、このドキュメン
42トの最後にリストしたメンテナーにパッチを送ってください。
43
44はじめに
45---------
46
47あなたは Linux カーネルの開発者になる方法を学びたいのでしょうか? そ
48れともあなたは上司から「このデバイスの Linux ドライバを書くように」と
49言われているのでしょうか? 
50この文書の目的は、あなたが踏むべき手順と、コミュニティと一緒にうまく働
51くヒントを書き下すことで、あなたが知るべき全てのことを教えることです。
52また、このコミュニティがなぜ今うまくまわっているのかという理由の一部も
53説明しようと試みています。
54
55カーネルは 少量のアーキテクチャ依存部分がアセンブリ言語で書かれている
56以外は大部分は C 言語で書かれています。C言語をよく理解していることはカー
57ネル開発者には必要です。アーキテクチャ向けの低レベル部分の開発をするの
58でなければ、(どんなアーキテクチャでも)アセンブリ(訳注: 言語)は必要あり
59ません。以下の本は、C 言語の十分な知識や何年もの経験に取って代わるもの
60ではありませんが、少なくともリファレンスとしてはいい本です。
61 - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
62 -『プログラミング言語C第2版』(B.W. カーニハン/D.M. リッチー著 石田晴久訳) [共立出版]
63 - "Practical C Programming" by Steve Oualline [O'Reilly]
64 - 『C実践プログラミング第3版』(Steve Oualline著 望月康司監訳 谷口功訳) [オライリージャパン]
65 - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
66 - 『新・詳説 C 言語 H&S リファレンス』
67 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク]
68
69カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル
70は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って
71います。カーネルは標準 C ライブラリとは関係がないといった、C 言語フリー
72スタンディング環境です。そのため、C の標準で使えないものもあります。任
73意の long long の除算や浮動小数点は使えません。
74ときどき、カーネルがツールチェインや C 言語拡張に置いている前提がどう
75なっているのかわかりにくいことがあり、また、残念なことに決定的なリファ
76レンスは存在しません。情報を得るには、gcc の info ページ( info gcc )を
77みてください。
78
79あなたは既存の開発コミュニティと一緒に作業する方法を学ぼうとしているこ
80とに留意してください。そのコミュニティは、コーディング、スタイル、
81開発手順について高度な標準を持つ、多様な人の集まりです。
82地理的に分散した大規模なチームに対してもっともうまくいくとわかったこと
83をベースにしながら、これらの標準は長い時間をかけて築かれてきました。
84これらはきちんと文書化されていますから、事前にこれらの標準についてでき
85るだけたくさん学んでください。また皆があなたやあなたの会社のやり方に合わ
86せてくれると思わないでください。
87
88法的問題
89------------
90
91Linux カーネルのソースコードは GPL ライセンスの下でリリースされていま
92す。ライセンスの詳細については、ソースツリーのメインディレクトリに存在
93する、COPYING のファイルをみてください。もしライセンスについてさらに質
94問があれば、Linux Kernel メーリングリストに質問するのではなく、どうぞ
95法律家に相談してください。メーリングリストの人達は法律家ではなく、法的
96問題については彼らの声明はあてにするべきではありません。
97
98GPL に関する共通の質問や回答については、以下を参照してください。
99 http://www.gnu.org/licenses/gpl-faq.html
100
101ドキュメント
102------------
103
104Linux カーネルソースツリーは幅広い範囲のドキュメントを含んでおり、それ
105らはカーネルコミュニティと会話する方法を学ぶのに非常に貴重なものです。
106新しい機能がカーネルに追加される場合、その機能の使い方について説明した
107新しいドキュメントファイルも追加することを勧めます。
108カーネルの変更が、カーネルがユーザ空間に公開しているインターフェイスの
109変更を引き起こす場合、その変更を説明するマニュアルページのパッチや情報
110をマニュアルページのメンテナ mtk-manpages@gmx.net に送ることを勧めます。
111
112以下はカーネルソースツリーに含まれている読んでおくべきファイルの一覧で
113す-
114
115 README
116 このファイルは Linuxカーネルの簡単な背景とカーネルを設定(訳注
117 configure )し、生成(訳注 build )するために必要なことは何かが書かれ
118 ています。カーネルに関して初めての人はここからスタートするとよいで
119 しょう。
120
121 Documentation/Changes
122 このファイルはカーネルをうまく生成(訳注 build )し、走らせるのに最
123 小限のレベルで必要な数々のソフトウェアパッケージの一覧を示してい
124 ます。
125
126 Documentation/CodingStyle
127 これは Linux カーネルのコーディングスタイルと背景にある理由を記述
128 しています。全ての新しいコードはこのドキュメントにあるガイドライン
129 に従っていることを期待されています。大部分のメンテナーはこれらのルー
130 ルに従っているものだけを受け付け、多くの人は正しいスタイルのコード
131 だけをレビューします。
132
133 Documentation/SubmittingPatches
134 Documentation/SubmittingDrivers
135 これらのファイルには、どうやってうまくパッチを作って投稿するかに
136 ついて非常に詳しく書かれており、以下を含みます(これだけに限らない
137 けれども)
138 - Email に含むこと
139 - Email の形式
140 - だれに送るか
141 これらのルールに従えばうまくいくことを保証することではありません
142 が (すべてのパッチは内容とスタイルについて精査を受けるので)、
143 ルールに従わなければ間違いなくうまくいかないでしょう。
144 この他にパッチを作る方法についてのよくできた記述は-
145
146 "The Perfect Patch"
147 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
148 "Linux kernel patch submission format"
149 http://linux.yyz.us/patch-format.html
150
151 Documentation/stable_api_nonsense.txt
152 このファイルはカーネルの中に不変のAPIを持たないことにした意識的な
153 決断の背景にある理由について書かれています。以下のようなことを含
154 んでいます-
155 - サブシステムとの間に層を作ること(コンパチビリティのため?)
156 - オペレーティングシステム間のドライバの移植性
157 - カーネルソースツリーの素早い変更を遅らせる(もしくは素早い変更
158 を妨げる)
159 このドキュメントは Linux 開発の思想を理解するのに非常に重要です。
160 そして、他のOSでの開発者が Linux に移る時にとても重要です。
161
162 Documentation/SecurityBugs
163 もし Linux カーネルでセキュリティ問題を発見したように思ったら、こ
164 のドキュメントのステップに従ってカーネル開発者に連絡し、問題解決を
165 支援してください。
166
167 Documentation/ManagementStyle
168 このドキュメントは Linux カーネルのメンテナー達がどう行動するか、
169 彼らの手法の背景にある共有されている精神について記述しています。こ
170 れはカーネル開発の初心者なら(もしくは、単に興味があるだけの人でも)
171 重要です。なぜならこのドキュメントは、カーネルメンテナー達の独特な
172 行動についての多くの誤解や混乱を解消するからです。
173
174 Documentation/stable_kernel_rules.txt
175 このファイルはどのように stable カーネルのリリースが行われるかのルー
176 ルが記述されています。そしてこれらのリリースの中のどこかで変更を取
177 り入れてもらいたい場合に何をすればいいかが示されています。
178
179 Documentation/kernel-docs.txt
180  カーネル開発に付随する外部ドキュメントのリストです。もしあなたが
181 探しているものがカーネル内のドキュメントでみつからなかった場合、
182 このリストをあたってみてください。
183
184 Documentation/applying-patches.txt
185 パッチとはなにか、パッチをどうやって様々なカーネルの開発ブランチに
186 適用するのかについて正確に記述した良い入門書です。
187
188カーネルはソースコードから自動的に生成可能な多数のドキュメントを自分自
189身でもっています。これにはカーネル内 API のすべての記述や、どう正しく
190ロックをかけるかの規則が含まれます。このドキュメントは
191Documentation/DocBook/ ディレクトリに作られ、以下のように
192 make pdfdocs
193 make psdocs
194 make htmldocs
195 make mandocs
196コマンドを実行するとメインカーネルのソースディレクトリから
197それぞれ、PDF, Postscript, HTML, man page の形式で生成されます。
198
199カーネル開発者になるには
200---------------------------
201
202もしあなたが、Linux カーネル開発について何も知らないならば、
203KernelNewbies プロジェクトを見るべきです
204 http://kernelnewbies.org
205
206このサイトには役に立つメーリングリストがあり、基本的なカーネル開発に関
207するほとんどどんな種類の質問もできます (既に回答されているようなことを
208聞く前にまずはアーカイブを調べてください)。
209またここには、リアルタイムで質問を聞くことができる IRC チャネルや、Linux
210カーネルの開発に関して学ぶのに便利なたくさんの役に立つドキュメントがあ
211ります。
212
213web サイトには、コードの構成、サブシステム、現在存在するプロジェクト(ツ
214リーにあるもの無いものの両方)の基本的な管理情報があります。
215ここには、また、カーネルのコンパイルのやり方やパッチの当て方などの間接
216的な基本情報も記述されています。
217
218あなたがどこからスタートしてよいかわからないが、Linux カーネル開発コミュ
219ニティに参加して何かすることをさがしている場合には、Linux kernel
220Janitor's プロジェクトにいけばよいでしょう -
221 http://janitor.kernelnewbies.org/
222ここはそのようなスタートをするのにうってつけの場所です。ここには、
223Linux カーネルソースツリーの中に含まれる、きれいにし、修正しなければな
224らない、単純な問題のリストが記述されています。このプロジェクトに関わる
225開発者と一緒に作業することで、あなたのパッチを Linuxカーネルツリーに入
226れるための基礎を学ぶことができ、そしてもしあなたがまだアイディアを持っ
227ていない場合には、次にやる仕事の方向性が見えてくるかもしれません。
228
229もしあなたが、すでにひとまとまりコードを書いていて、カーネルツリーに入
230れたいと思っていたり、それに関する適切な支援を求めたい場合、カーネル
231メンターズプロジェクトはそのような皆さんを助けるためにできました。
232ここにはメーリングリストがあり、以下から参照できます
233 http://selenic.com/mailman/listinfo/kernel-mentors
234
235実際に Linux カーネルのコードについて修正を加える前に、どうやってその
236コードが動作するのかを理解することが必要です。そのためには、特別なツー
237ルの助けを借りてでも、それを直接よく読むことが最良の方法です(ほとんど
238のトリッキーな部分は十分にコメントしてありますから)。そういうツールで
239特におすすめなのは、Linux クロスリファレンスプロジェクトです。これは、
240自己参照方式で、索引がついた web 形式で、ソースコードを参照することが
241できます。この最新の素晴しいカーネルコードのリポジトリは以下で見つかり
242ます-
243 http://sosdg.org/~coywolf/lxr/
244
245開発プロセス
246-----------------------
247
248Linux カーネルの開発プロセスは現在幾つかの異なるメインカーネル「ブラン
249チ」と多数のサブシステム毎のカーネルブランチから構成されます。
250これらのブランチとは-
251 - メインの 2.6.x カーネルツリー
252 - 2.6.x.y -stable カーネルツリー
253 - 2.6.x -git カーネルパッチ
254 - 2.6.x -mm カーネルパッチ
255 - サブシステム毎のカーネルツリーとパッチ
256
2572.6.x カーネルツリー
258-----------------
259
2602.6.x カーネルは Linus Torvalds によってメンテナンスされ、kernel.org
261の pub/linux/kernel/v2.6/ ディレクトリに存在します。この開発プロセスは
262以下のとおり-
263
264 - 新しいカーネルがリリースされた直後に、2週間の特別期間が設けられ、
265 この期間中に、メンテナー達は Linus に大きな差分を送ることができま
266 す。このような差分は通常 -mm カーネルに数週間含まれてきたパッチで
267 す。 大きな変更は git(カーネルのソース管理ツール、詳細は
268 http://git.or.cz/ 参照) を使って送るのが好ましいやり方ですが、パッ
269 チファイルの形式のまま送るのでも十分です。
270
271 - 2週間後、-rc1 カーネルがリリースされ、この後にはカーネル全体の安定
272 性に影響をあたえるような新機能は含まない類のパッチしか取り込むこと
273 はできません。新しいドライバ(もしくはファイルシステム)のパッチは
274 -rc1 の後で受け付けられることもあることを覚えておいてください。な
275 ぜなら、変更が独立していて、追加されたコードの外の領域に影響を与え
276 ない限り、退行のリスクは無いからです。-rc1 がリリースされた後、
277 Linus へパッチを送付するのに git を使うこともできますが、パッチは
278 レビューのために、パブリックなメーリングリストへも同時に送る必要が
279 あります。
280
281 - 新しい -rc は Linus が、最新の git ツリーがテスト目的であれば十分
282 に安定した状態にあると判断したときにリリースされます。目標は毎週新
283 しい -rc カーネルをリリースすることです。
284
285 - このプロセスはカーネルが 「準備ができた」と考えられるまで継続しま
286 す。このプロセスはだいたい 6週間継続します。
287
288Andrew Morton が Linux-kernel メーリングリストにカーネルリリースについ
289て書いたことをここで言っておくことは価値があります-
290 「カーネルがいつリリースされるかは誰も知りません。なぜなら、これは現
291 実に認識されたバグの状況によりリリースされるのであり、前もって決めら
292 れた計画によってリリースされるものではないからです。」
293
2942.6.x.y -stable カーネルツリー
295---------------------------
296
297バージョンに4つ目の数字がついたカーネルは -stable カーネルです。これに
298は、2.6.x カーネルで見つかったセキュリティ問題や重大な後戻りに対する比
299較的小さい重要な修正が含まれます。
300
301これは、開発/実験的バージョンのテストに協力することに興味が無く、
302最新の安定したカーネルを使いたいユーザに推奨するブランチです。
303
304もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x
305が最新の安定版カーネルです。
306
3072.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、だ
308いたい隔週でリリースされています。
309
310カーネルツリーに入っている、Documentation/stable_kernel_rules.txt ファ
311イルにはどのような種類の変更が -stable ツリーに受け入れ可能か、またリ
312リースプロセスがどう動くかが記述されています。
313
3142.6.x -git パッチ
315------------------
316
317git リポジトリで管理されているLinus のカーネルツリーの毎日のスナップ
318ショットがあります。(だから -git という名前がついています)。これらのパッ
319チはおおむね毎日リリースされており、Linus のツリーの現状を表します。こ
320れは -rc カーネルと比べて、パッチが大丈夫かどうかも確認しないで自動的
321に生成されるので、より実験的です。
322
3232.6.x -mm カーネルパッチ
324------------------------
325
326Andrew Morton によってリリースされる実験的なカーネルパッチ群です。
327Andrew は個別のサブシステムカーネルツリーとパッチを全て集めてきて
328linux-kernel メーリングリストで収集された多数のパッチと同時に一つにま
329とめます。
330このツリーは新機能とパッチが検証される場となります。ある期間の間パッチ
331が -mm に入って価値を証明されたら、Andrew やサブシステムメンテナが、メ
332インラインへ入れるように Linus にプッシュします。
333
334メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ
335チが -mm ツリーでテストされることが強く推奨されます。
336
337これらのカーネルは安定して動作すべきシステムとして使うのには適切ではあ
338りませんし、カーネルブランチの中でももっとも動作にリスクが高いものです。
339
340もしあなたが、カーネル開発プロセスの支援をしたいと思っているのであれば、
341どうぞこれらのカーネルリリースをテストに使ってみて、そしてもし問題があ
342れば、またもし全てが正しく動作したとしても、linux-kernel メーリングリ
343ストにフィードバックを提供してください。
344
345すべての他の実験的パッチに加えて、これらのカーネルは通常リリース時点で
346メインラインの -git カーネルに含まれる全ての変更も含んでいます。
347
348-mm カーネルは決まったスケジュールではリリースされません、しかし通常幾
349つかの -mm カーネル (1 から 3 が普通)が各-rc カーネルの間にリリースさ
350れます。
351
352サブシステム毎のカーネルツリーとパッチ
353-------------------------------------------
354
355カーネルの様々な領域で何が起きているかを見られるようにするため、多くの
356カーネルサブシステム開発者は彼らの開発ツリーを公開しています。これらの
357ツリーは説明したように -mm カーネルリリースに入れ込まれます。
358
359以下はさまざまなカーネルツリーの中のいくつかのリスト-
360
361 git ツリー-
362 - Kbuild の開発ツリー、Sam Ravnborg <sam@ravnborg.org>
363 kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
364
365 - ACPI の開発ツリー、 Len Brown <len.brown@intel.com>
366 kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
367
368 - Block の開発ツリー、Jens Axboe <axboe@suse.de>
369 kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
370
371 - DRM の開発ツリー、Dave Airlie <airlied@linux.ie>
372 kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
373
374 - ia64 の開発ツリー、Tony Luck <tony.luck@intel.com>
375 kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
376
377 - ieee1394 の開発ツリー、Jody McIntyre <scjody@modernduck.com>
378 kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
379
380 - infiniband, Roland Dreier <rolandd@cisco.com>
381 kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
382
383 - libata, Jeff Garzik <jgarzik@pobox.com>
384 kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
385
386 - ネットワークドライバ, Jeff Garzik <jgarzik@pobox.com>
387 kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
388
389 - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
390 kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
391
392 - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
393 kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
394
395 その他の git カーネルツリーは http://kernel.org/git に一覧表がありま
396 す。
397
398 quilt ツリー-
399 - USB, PCI ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
400 kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
401
402バグレポート
403-------------
404
405bugzilla.kernel.org は Linux カーネル開発者がカーネルのバグを追跡する
406場所です。ユーザは見つけたバグの全てをこのツールで報告すべきです。
407どう kernel bugzilla を使うかの詳細は、以下を参照してください-
408 http://test.kernel.org/bugzilla/faq.html
409
410メインカーネルソースディレクトリにあるファイル REPORTING-BUGS はカーネ
411ルバグらしいものについてどうレポートするかの良いテンプレートであり、問
412題の追跡を助けるためにカーネル開発者にとってどんな情報が必要なのかの詳
413細が書かれています。
414
415メーリングリスト
416-------------
417
418上のいくつかのドキュメントで述べていますが、コアカーネル開発者の大部分
419は Linux kernel メーリングリストに参加しています。このリストの登録/脱
420退の方法については以下を参照してください-
421 http://vger.kernel.org/vger-lists.html#linux-kernel
422
423このメーリングリストのアーカイブは web 上の多数の場所に存在します。こ
424れらのアーカイブを探すにはサーチエンジンを使いましょう。例えば-
425 http://dir.gmane.org/gmane.linux.kernel
426
427リストに投稿する前にすでにその話題がアーカイブに存在するかどうかを検索
428することを是非やってください。多数の事がすでに詳細に渡って議論されて
429おり、アーカイブにのみ記録されています。
430
431大部分のカーネルサブシステムも自分の個別の開発を実施するメーリングリス
432トを持っています。個々のグループがどんなリストを持っているかは、
433MAINTAINERS ファイルにリストがありますので参照してください。
434
435多くのリストは kernel.org でホストされています。これらの情報は以下にあ
436ります-
437 http://vger.kernel.org/vger-lists.html
438
439メーリングリストを使う場合、良い行動習慣に従うようにしましょう。
440少し安っぽいが、以下の URL は上のリスト(や他のリスト)で会話する場合の
441シンプルなガイドラインを示しています-
442 http://www.albion.com/netiquette/
443
444もし複数の人があなたのメールに返事をした場合、CC: で受ける人のリストは
445だいぶ多くなるでしょう。良い理由がない場合、CC: リストから誰かを削除を
446しないように、また、メーリングリストのアドレスだけにリプライすることの
447ないようにしましょう。1つは送信者から、もう1つはリストからのように、メー
448ルを2回受けることになってもそれに慣れ、しゃれたメールヘッダーを追加し
449てこの状態を変えようとしないように。人々はそのようなことは好みません。
450
451今までのメールでのやりとりとその間のあなたの発言はそのまま残し、
452"John Kernlehacker wrote ...:" の行をあなたのリプライの先頭行にして、
453メールの先頭でなく、各引用行の間にあなたの言いたいことを追加するべきで
454す。
455
456もしパッチをメールに付ける場合は、Documentaion/SubmittingPatches に提
457示されているように、それは プレーンな可読テキストにすることを忘れない
458ようにしましょう。カーネル開発者は 添付や圧縮したパッチを扱いたがりま
459せん-
460彼らはあなたのパッチの行毎にコメントを入れたいので、そのためにはそうす
461るしかありません。あなたのメールプログラムが空白やタブを圧縮しないよう
462に確認した方がいいです。最初の良いテストとしては、自分にメールを送って
463みて、そのパッチを自分で当ててみることです。もしそれがうまく行かないな
464ら、あなたのメールプログラムを直してもらうか、正しく動くように変えるべ
465きです。
466
467とりわけ、他の登録者に対する尊敬を表すようにすることを覚えておいてくだ
468さい。
469
470コミュニティと共に働くこと
471--------------------------
472
473カーネルコミュニティのゴールは可能なかぎり最高のカーネルを提供すること
474です。あなたがパッチを受け入れてもらうために投稿した場合、それは、技術
475的メリットだけがレビューされます。その際、あなたは何を予想すべきでしょ
476うか?
477 - 批判
478 - コメント
479 - 変更の要求
480 - パッチの正当性の証明要求
481 - 沈黙
482
483思い出してください、ここはあなたのパッチをカーネルに入れる話です。あ
484なたは、あなたのパッチに対する批判とコメントを受け入れるべきで、それら
485を技術的レベルで評価して、パッチを再作成するか、なぜそれらの変更をすべ
486きでないかを明確で簡潔な理由の説明を提供してください。
487もし、あなたのパッチに何も反応がない場合、たまにはメールの山に埋もれて
488見逃され、あなたの投稿が忘れられてしまうこともあるので、数日待って再度
489投稿してください。
490
491あなたがやるべきでないものは?
492 - 質問なしにあなたのパッチが受け入れられると想像すること
493 - 守りに入ること
494 - コメントを無視すること
495 - 要求された変更を何もしないでパッチを出し直すこと
496
497可能な限り最高の技術的解決を求めているコミュニティでは、パッチがどのく
498らい有益なのかについては常に異なる意見があります。あなたは協調的である
499べきですし、また、あなたのアイディアをカーネルに対してうまく合わせるよ
500うにすることが望まれています。もしくは、最低限あなたのアイディアがそれ
501だけの価値があるとすすんで証明するようにしなければなりません。
502正しい解決に向かって進もうという意志がある限り、間違うことがあっても許
503容されることを忘れないでください。
504
505あなたの最初のパッチに単に 1ダースもの修正を求めるリストの返答になるこ
506とも普通のことです。これはあなたのパッチが受け入れられないということで
507は *ありません*、そしてあなた自身に反対することを意味するのでも *ありま
508せん*。単に自分のパッチに対して指摘された問題を全て修正して再送すれば
509いいのです。
510
511カーネルコミュニティと企業組織のちがい
512-----------------------------------------------------------------
513
514カーネルコミュニティは大部分の伝統的な会社の開発環境とは異ったやり方で
515動いています。以下は問題を避けるためにできるとよいことののリストです-
516
517 あなたの提案する変更について言うときのうまい言い方:
518
519 - "これは複数の問題を解決します"
520 - "これは2000行のコードを削除します"
521 - "以下のパッチは、私が言おうとしていることを説明するものです"
522 - "私はこれを5つの異なるアーキテクチャでテストしたのですが..."
523 - "以下は一連の小さなパッチ群ですが..."
524 - "これは典型的なマシンでの性能を向上させます.."
525
526 やめた方がいい悪い言い方:
527
528 - このやり方で AIX/ptx/Solaris ではできたので、できるはずだ
529 - 私はこれを20年もの間やってきた、だから
530 - これは、私の会社が金儲けをするために必要だ
531 - これは我々のエンタープライズ向け商品ラインのためである
532 - これは 私が自分のアイディアを記述した、1000ページの設計資料である
533 - 私はこれについて、6ケ月作業している。
534 - 以下は ... に関する5000行のパッチです
535 - 私は現在のぐちゃぐちゃを全部書き直した、それが以下です...
536 - 私は〆切がある、そのためこのパッチは今すぐ適用される必要がある
537
538カーネルコミュニティが大部分の伝統的なソフトウェアエンジニアリングの労
539働環境と異なるもう一つの点は、やりとりに顔を合わせないということです。
540email と irc を第一のコミュニケーションの形とする一つの利点は、性別や
541民族の差別がないことです。Linux カーネルの職場環境は女性や少数民族を受
542容します。なぜなら、email アドレスによってのみあなたが認識されるからで
543す。
544国際的な側面からも活動領域を均等にするようにします。なぜならば、あなた
545は人の名前で性別を想像できないからです。ある男性が アンドレアという名
546前で、女性の名前は パット かもしれません (訳注 Andrea は米国では女性、
547それ以外(欧州など)では男性名として使われることが多い。同様に、Pat は
548Patricia (主に女性名)や Patrick (主に男性名)の略称)。
549Linux カーネルの活動をして、意見を表明したことがある大部分の女性は、前
550向きな経験をもっています。
551
552言葉の壁は英語が得意でない一部の人には問題になります。
553メーリングリストの中できちんとアイディアを交換するには、相当うまく英語
554を操れる必要があることもあります。そのため、あなたは自分のメール
555を送る前に英語で意味が通じているかをチェックすることをお薦めします。
556
557変更を分割する
558---------------------
559
560Linux カーネルコミュニティは、一度に大量のコードの塊を喜んで受容するこ
561とはありません。変更は正確に説明される必要があり、議論され、小さい、個
562別の部分に分割する必要があります。これはこれまで多くの会社がやり慣れて
563きたことと全く正反対のことです。あなたのプロポーザルは、開発プロセスのと
564ても早い段階から紹介されるべきです。そうすれば あなたは自分のやってい
565ることにフィードバックを得られます。これは、コミュニティからみれば、あ
566なたが彼らと一緒にやっているように感じられ、単にあなたの提案する機能の
567ゴミ捨て場として使っているのではない、と感じられるでしょう。
568しかし、一度に 50 もの email をメーリングリストに送りつけるようなことは
569やってはいけません、あなたのパッチ群はいつもどんな時でもそれよりは小さ
570くなければなりません。
571
572パッチを分割する理由は以下です-
573
5741) 小さいパッチはあなたのパッチが適用される見込みを大きくします、カー
575 ネルの人達はパッチが正しいかどうかを確認する時間や労力をかけないか
576 らです。5行のパッチはメンテナがたった1秒見るだけで適用できます。し
577 かし、500行のパッチは、正しいことをレビューするのに数時間かかるかも
578 しれません(時間はパッチのサイズなどにより指数関数に比例してかかりま
579 す)
580 小さいパッチは何かあったときにデバッグもとても簡単になります。パッ
581 チを1個1個取り除くのは、とても大きなパッチを当てた後に(かつ、何かお
582 かしくなった後で)解剖するのに比べればとても簡単です。
583
5842) 小さいパッチを送るだけでなく、送るまえに、書き直して、シンプルにす
585 る(もしくは、単に順番を変えるだけでも)ことも、とても重要です。
586
587以下はカーネル開発者の Al Viro のたとえ話しです:
588
589 "生徒の数学の宿題を採点する先生のことを考えてみてください、先
590 生は生徒が解に到達するまでの試行錯誤をみたいとは思わないでしょ
591 う。先生は簡潔な最高の解をみたいのです。良い生徒はこれを知って
592 おり、そして最終解の前の中間作業を提出することは決してないので
593 す"
594 カーネル開発でもこれは同じです。メンテナー達とレビューア達は、
595 問題を解決する解の背後になる思考プロセスをみたいとは思いません。
596 彼らは単純であざやかな解決方法をみたいのです。
597
598あざやかな解を説明するのと、コミュニティと共に仕事をし、未解決の仕事を
599議論することのバランスをキープするのは難しいかもしれません。
600ですから、開発プロセスの早期段階で改善のためのフィードバックをもらうよ
601うにするのもいいですが、変更点を小さい部分に分割して全体ではまだ完成し
602ていない仕事を(部分的に)取り込んでもらえるようにすることもいいことです。
603
604また、でき上がっていないものや、"将来直す" ようなパッチを、本流に含め
605てもらうように送っても、それは受け付けられないことを理解してください。
606
607あなたの変更を正当化する
608-------------------
609
610あなたのパッチを分割するのと同時に、なぜその変更を追加しなければならな
611いかを Linux コミュニティに知らせることはとても重要です。新機能は必要
612性と有用性で正当化されなければなりません。
613
614あなたの変更の説明
615--------------------
616
617あなたのパッチを送付する場合には、メールの中のテキストで何を言うかにつ
618いて、特別に注意を払ってください。この情報はパッチの ChangeLog に使わ
619れ、いつも皆がみられるように保管されます。これは次のような項目を含め、
620パッチを完全に記述するべきです-
621
622 - なぜ変更が必要か
623 - パッチ全体の設計アプローチ
624 - 実装の詳細
625 - テスト結果
626
627これについて全てがどのようにあるべきかについての詳細は、以下のドキュメ
628ントの ChangeLog セクションをみてください-
629 "The Perfect Patch"
630 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
631
632これらのどれもが、時にはとても困難です。これらの慣例を完璧に実施するに
633は数年かかるかもしれません。これは継続的な改善のプロセスであり、そのた
634めには多数の忍耐と決意を必要とするものです。でも、諦めないで、これは可
635能なことです。多数の人がすでにできていますし、彼らも皆最初はあなたと同
636じところからスタートしたのですから。
637
638Paolo Ciarrocchi に感謝、彼は彼の書いた "Development Process"
639(http://linux.tar.bz/articles/2.6-development_process)セクショ
640ンをこのテキストの原型にすることを許可してくれました。
641Rundy Dunlap と Gerrit Huizenga はメーリングリストでやるべきこととやっ
642てはいけないことのリストを提供してくれました。
643以下の人々のレビュー、コメント、貢献に感謝。
644Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers,
645Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, Andi
646Kleen, Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop,
647David A. Wheeler, Junio Hamano, Michael Kerrisk, と Alex Shepard
648彼らの支援なしでは、このドキュメントはできなかったでしょう。
649
650Maintainer: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/Documentation/ja_JP/stable_api_nonsense.txt b/Documentation/ja_JP/stable_api_nonsense.txt
new file mode 100644
index 000000000000..b3f2b27f0881
--- /dev/null
+++ b/Documentation/ja_JP/stable_api_nonsense.txt
@@ -0,0 +1,263 @@
1NOTE:
2This is a Japanese translated version of
3"Documentation/stable_api_nonsense.txt".
4This one is maintained by
5IKEDA, Munehiro <m-ikeda@ds.jp.nec.com>
6and JF Project team <http://www.linux.or.jp/JF/>.
7If you find difference with original file or problem in translation,
8please contact the maintainer of this file or JF project.
9
10Please also note that purpose of this file is easier to read for non
11English natives and not to be intended to fork. So, if you have any
12comments or updates of this file, please try to update
13Original(English) file at first.
14
15==================================
16これは、
17linux-2.6.22-rc4/Documentation/stable_api_nonsense.txt の和訳
18です。
19翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
20翻訳日 : 2007/06/11
21原著作者: Greg Kroah-Hartman < greg at kroah dot com >
22翻訳者 : 池田 宗広 < m-ikeda at ds dot jp dot nec dot com >
23校正者 : Masanori Kobayashi さん < zap03216 at nifty dot ne dot jp >
24 Seiji Kaneko さん < skaneko at a2 dot mbn dot or dot jp >
25==================================
26
27
28
29Linux カーネルのドライバインターフェース
30(あなたの質問すべてに対する回答とその他諸々)
31
32Greg Kroah-Hartman <greg at kroah dot com>
33
34
35この文書は、なぜ Linux ではバイナリカーネルインターフェースが定義
36されていないのか、またはなぜ不変のカーネルインターフェースを持たな
37いのか、ということを説明するために書かれた。ここでの話題は「カーネ
38ル内部の」インターフェースについてであり、ユーザー空間とのインター
39フェースではないことを理解してほしい。カーネルとユーザー空間とのイ
40ンターフェースとはアプリケーションプログラムが使用するものであり、
41つまりシステムコールのインターフェースがこれに当たる。これは今まで
42長きに渡り、かつ今後も「まさしく」不変である。私は確か 0.9 か何か
43より前のカーネルを使ってビルドした古いプログラムを持っているが、そ
44れは最新の 2.6 カーネルでもきちんと動作する。ユーザー空間とのイン
45ターフェースは、ユーザーとアプリケーションプログラマが不変性を信頼
46してよいものの一つである。
47
48
49要旨
50----
51
52あなたは不変のカーネルインターフェースが必要だと考えているかもしれ
53ないが、実際のところはそうではない。あなたは必要としているものが分
54かっていない。あなたが必要としているものは安定して動作するドライバ
55であり、それはドライバがメインのカーネルツリーに含まれる場合のみ得
56ることができる。ドライバがメインのカーネルツリーに含まれていると、
57他にも多くの良いことがある。それは、Linux をより強固で、安定な、成
58熟したオペレーティングシステムにすることができるということだ。これ
59こそ、そもそもあなたが Linux を使う理由のはずだ。
60
61
62はじめに
63--------
64
65カーネル内部のインターフェース変更を心配しなければならないドライバ
66を書きたいなどというのは、変わり者だけだ。この世界のほとんどの人は、
67そのようなドライバがどんなインターフェースを使っているかなど知らな
68いし、そんなドライバのことなど全く気にもかけていない。
69
70
71まず初めに、クローズソースとか、ソースコードの隠蔽とか、バイナリの
72みが配布される使い物にならない代物[訳注(1)]とか、実体はバイナリ
73コードでそれを読み込むためのラッパー部分のみソースコードが公開され
74ているとか、その他用語は何であれ GPL の下にソースコードがリリース
75されていないカーネルドライバに関する法的な問題について、私は「いか
76なる議論も」行うつもりがない。法的な疑問があるのならば、プログラマ
77である私ではなく、弁護士に相談して欲しい。ここでは単に、技術的な問
78題について述べることにする。(法的な問題を軽視しているわけではない。
79それらは実際に存在するし、あなたはそれをいつも気にかけておく必要が
80ある)
81
82訳注(1)
83「使い物にならない代物」の原文は "blob"
84
85
86さてここでは、バイナリカーネルインターフェースについてと、ソースレ
87ベルでのインターフェースの不変性について、という二つの話題を取り上
88げる。この二つは互いに依存する関係にあるが、まずはバイナリインター
89フェースについて議論を行いやっつけてしまおう。
90
91
92バイナリカーネルインターフェース
93--------------------------------
94
95もしソースレベルでのインターフェースが不変ならば、バイナリインター
96フェースも当然のように不変である、というのは正しいだろうか?正しく
97ない。Linux カーネルに関する以下の事実を考えてみてほしい。
98 - あなたが使用するCコンパイラのバージョンによって、カーネル内部
99 の構造体の配置構造は異なったものになる。また、関数は異なった方
100 法でカーネルに含まれることになるかもしれない(例えばインライン
101 関数として扱われたり、扱われなかったりする)。個々の関数がどの
102 ようにコンパイルされるかはそれほど重要ではないが、構造体のパデ
103 ィングが異なるというのは非常に重要である。
104 - あなたがカーネルのビルドオプションをどのように設定するかによっ
105 て、カーネルには広い範囲で異なった事態が起こり得る。
106 - データ構造は異なるデータフィールドを持つかもしれない
107 - いくつかの関数は全く実装されていない状態になり得る
108 (例:SMP向けではないビルドでは、いくつかのロックは中身が
109 カラにコンパイルされる)
110 - カーネル内のメモリは、異なった方法で配置され得る。これはビ
111 ルドオプションに依存している。
112 - Linux は様々な異なるプロセッサアーキテクチャ上で動作する。
113 あるアーキテクチャ用のバイナリドライバを、他のアーキテクチャで
114 正常に動作させる方法はない。
115
116
117ある特定のカーネル設定を使用し、カーネルをビルドしたのと正確に同じ
118Cコンパイラを使用して単にカーネルモジュールをコンパイルするだけで
119も、あなたはこれらいくつもの問題に直面することになる。ある特定の
120Linux ディストリビューションの、ある特定のリリースバージョン用にモ
121ジュールを提供しようと思っただけでも、これらの問題を引き起こすには
122十分である。にも関わらず Linux ディストリビューションの数と、サ
123ポートするディストリビューションのリリース数を掛け算し、それら一つ
124一つについてビルドを行ったとしたら、今度はリリースごとのビルドオプ
125ションの違いという悪夢にすぐさま悩まされることになる。また、ディス
126トリビューションの各リリースバージョンには、異なるハードウェア(プ
127ロセッサタイプや種々のオプション)に対応するため、何種類かのカーネ
128ルが含まれているということも理解して欲しい。従って、ある一つのリ
129リースバージョンだけのためにモジュールを作成する場合でも、あなたは
130何バージョンものモジュールを用意しなければならない。
131
132
133信じて欲しい。このような方法でサポートを続けようとするなら、あなた
134はいずれ正気を失うだろう。遠い昔、私はそれがいかに困難なことか、身
135をもって学んだのだ・・・
136
137
138不変のカーネルソースレベルインターフェース
139------------------------------------------
140
141メインカーネルツリーに含まれていない Linux カーネルドライバを継続
142してサポートしていこうとしている人たちとの議論においては、これは極
143めて「引火性の高い」話題である。[訳注(2)]
144
145訳注(2)
146「引火性の高い」の原文は "volatile"。
147volatile には「揮発性の」「爆発しやすい」という意味の他、「変わり
148やすい」「移り気な」という意味がある。
149「(この話題は)爆発的に激しい論争を巻き起こしかねない」ということ
150を、「(カーネルのソースレベルインターフェースは)移ろい行くもので
151ある」ということを連想させる "volatile" という単語で表現している。
152
153
154Linux カーネルの開発は継続的に速いペースで行われ、決して歩みを緩め
155ることがない。その中でカーネル開発者達は、現状のインターフェースに
156あるバグを見つけ、より良い方法を考え出す。彼らはやがて、現状のイン
157ターフェースがより正しく動作するように修正を行う。その過程で関数の
158名前は変更されるかもしれず、構造体は大きく、または小さくなるかもし
159れず、関数の引数は検討しなおされるかもしれない。そのような場合、引
160き続き全てが正常に動作するよう、カーネル内でこれらのインターフェー
161スを使用している個所も全て同時に修正される。
162
163
164具体的な例として、カーネル内の USB インターフェースを挙げる。USB
165サブシステムはこれまでに少なくとも3回の書き直しが行われ、その結果
166インターフェースが変更された。これらの書き直しはいくつかの異なった
167問題を修正するために行われた。
168 - 同期的データストリームが非同期に変更された。これにより多数のド
169 ライバを単純化でき、全てのドライバのスループットが向上した。今
170 やほとんど全ての USB デバイスは、考えられる最高の速度で動作し
171 ている。
172 - USB ドライバが USB サブシステムのコアから行う、データパケット
173 用のメモリ確保方法が変更された。これに伴い、いくつもの文書化さ
174 れたデッドロック条件を回避するため、全ての USB ドライバはより
175 多くの情報を USB コアに提供しなければならないようになっている。
176
177
178このできごとは、数多く存在するクローズソースのオペレーティングシス
179テムとは全く対照的だ。それらは長期に渡り古い USB インターフェース
180をメンテナンスしなければならない。古いインターフェースが残ることで、
181新たな開発者が偶然古いインターフェースを使い、正しくない方法で開発
182を行ってしまう可能性が生じる。これによりシステムの安定性は危険にさ
183らされることになる。
184
185
186上に挙げたどちらの例においても、開発者達はその変更が重要かつ必要で
187あることに合意し、比較的楽にそれを実行した。もし Linux がソースレ
188ベルでインターフェースの不変性を保証しなければならないとしたら、新
189しいインターフェースを作ると同時に、古い、問題のある方を今後ともメ
190ンテナンスするという余計な仕事を USB の開発者にさせなければならな
191い。Linux の USB 開発者は、自分の時間を使って仕事をしている。よっ
192て、価値のない余計な仕事を報酬もなしに実行しろと言うことはできない。
193
194
195セキュリティ問題も、Linux にとっては非常に重要である。ひとたびセキ
196ュリティに関する問題が発見されれば、それは極めて短期間のうちに修正
197される。セキュリティ問題の発生を防ぐための修正は、カーネルの内部イ
198ンターフェースの変更を何度も引き起こしてきた。その際同時に、変更さ
199れたインターフェースを使用する全てのドライバもまた変更された。これ
200により問題が解消し、将来偶然に問題が再発してしまわないことが保証さ
201れる。もし内部インターフェースの変更が許されないとしたら、このよう
202にセキュリティ問題を修正し、将来再発しないことを保証することなど不
203可能なのだ。
204
205
206カーネルのインターフェースは時が経つにつれクリーンナップを受ける。
207誰も使っていないインターフェースは削除される。これにより、可能な限
208りカーネルが小さく保たれ、現役の全てのインターフェースが可能な限り
209テストされることを保証しているのだ。(使われていないインターフェー
210スの妥当性をテストすることは不可能と言っていいだろう)
211
212
213
214これから何をすべきか
215-----------------------
216
217では、もしメインのカーネルツリーに含まれない Linux カーネルドライ
218バがあったとして、あなたは、つまり開発者は何をするべきだろうか?全
219てのディストリビューションの全てのカーネルバージョン向けにバイナリ
220のドライバを供給することは悪夢であり、カーネルインターフェースの変
221更を追いかけ続けることもまた過酷な仕事だ。
222
223
224答えは簡単。そのドライバをメインのカーネルツリーに入れてしまえばよ
225い。(ここで言及しているのは、GPL に従って公開されるドライバのこと
226だということに注意してほしい。あなたのコードがそれに該当しないなら
227ば、さよなら。幸運を祈ります。ご自分で何とかしてください。Andrew
228と Linus からのコメント<Andrew と Linus のコメントへのリンクをこ
229こに置く>をどうぞ)ドライバがメインツリーに入れば、カーネルのイン
230ターフェースが変更された場合、変更を行った開発者によってドライバも
231修正されることになるだろう。あなたはほとんど労力を払うことなしに、
232常にビルド可能できちんと動作するドライバを手に入れることができる。
233
234
235ドライバをメインのカーネルツリーに入れると、非常に好ましい以下の効
236果がある。
237 - ドライバの品質が向上する一方で、(元の開発者にとっての)メンテ
238 ナンスコストは下がる。
239 - あなたのドライバに他の開発者が機能を追加してくれる。
240 - 誰かがあなたのドライバにあるバグを見つけ、修正してくれる。
241 - 誰かがあなたのドライバにある改善点を見つけてくれる。
242 - 外部インターフェースが変更されドライバの更新が必要になった場合、
243 誰かがあなたの代わりに更新してくれる。
244 - ドライバを入れてくれとディストロに頼まなくても、そのドライバは
245 全ての Linux ディストリビューションに自動的に含まれてリリース
246 される。
247
248
249Linux では、他のどのオペレーティングシステムよりも数多くのデバイス
250が「そのまま」使用できるようになった。また Linux は、どのオペレー
251ティングシステムよりも数多くのプロセッサアーキテクチャ上でそれらの
252デバイスを使用することができるようにもなった。このように、Linux の
253開発モデルは実証されており、今後も間違いなく正しい方向へと進んでい
254くだろう。:)
255
256
257
258------
259
260この文書の初期の草稿に対し、Randy Dunlap, Andrew Morton, David
261Brownell, Hanna Linder, Robert Love, Nishanth Aravamudan から査読
262と助言を頂きました。感謝申し上げます。
263
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 0c2434822094..76733a3962f0 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1250,6 +1250,12 @@ platforms are moved over to use the flattened-device-tree model.
1250 network device. This is used by the bootwrapper to interpret 1250 network device. This is used by the bootwrapper to interpret
1251 MAC addresses passed by the firmware when no information other 1251 MAC addresses passed by the firmware when no information other
1252 than indices is available to associate an address with a device. 1252 than indices is available to associate an address with a device.
1253 - phy-connection-type : a string naming the controller/PHY interface type,
1254 i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
1255 "tbi", or "rtbi". This property is only really needed if the connection
1256 is of type "rgmii-id", as all other connection types are detected by
1257 hardware.
1258
1253 1259
1254 Example: 1260 Example:
1255 1261
diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO
new file mode 100644
index 000000000000..48fc67bfbe3d
--- /dev/null
+++ b/Documentation/zh_CN/HOWTO
@@ -0,0 +1,536 @@
1Chinese translated version of Documentation/HOWTO
2
3If you have any comment or update to the content, please contact the
4original document maintainer directly. However, if you have problem
5communicating in English you can also ask the Chinese maintainer for
6help. Contact the Chinese maintainer, if this translation is outdated
7or there is problem with translation.
8
9Maintainer: Greg Kroah-Hartman <greg@kroah.com>
10Chinese maintainer: Li Yang <leoli@freescale.com>
11---------------------------------------------------------------------
12Documentation/HOWTO 的中文翻译
13
14如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16译存在问题,请联系中文版维护者。
17
18英文版维护者: Greg Kroah-Hartman <greg@kroah.com>
19中文版维护者: 李阳 Li Yang <leoli@freescale.com>
20中文版翻译者: 李阳 Li Yang <leoli@freescale.com>
21中文版校译者: 钟宇 TripleX Chung <xxx.phy@gmail.com>
22 陈琦 Maggie Chen <chenqi@beyondsoft.com>
23 王聪 Wang Cong <xiyou.wangcong@gmail.com>
24
25以下为正文
26---------------------------------------------------------------------
27
28如何参与Linux内核开发
29---------------------
30
31这是一篇将如何参与Linux内核开发的相关问题一网打尽的终极秘笈。它将指导你
32成为一名Linux内核开发者,并且学会如何同Linux内核开发社区合作。它尽可能不
33包括任何关于内核编程的技术细节,但会给你指引一条获得这些知识的正确途径。
34
35如果这篇文章中的任何内容不再适用,请给文末列出的文件维护者发送补丁。
36
37
38入门
39----
40
41你想了解如何成为一名Linux内核开发者?或者老板吩咐你“给这个设备写个Linux
42驱动程序”?这篇文章的目的就是教会你达成这些目标的全部诀窍,它将描述你需
43要经过的流程以及给出如何同内核社区合作的一些提示。它还将试图解释内核社区
44为何这样运作。
45
46Linux内核大部分是由C语言写成的,一些体系结构相关的代码用到了汇编语言。要
47参与内核开发,你必须精通C语言。除非你想为某个架构开发底层代码,否则你并
48不需要了解(任何体系结构的)汇编语言。下面列举的书籍虽然不能替代扎实的C
49语言教育和多年的开发经验,但如果需要的话,做为参考还是不错的:
50 - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
51 《C程序设计语言(第2版·新版)》(徐宝文 李志 译)[机械工业出版社]
52 - "Practical C Programming" by Steve Oualline [O'Reilly]
53 《实用C语言编程(第三版)》(郭大海 译)[中国电力出版社]
54 - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
55 《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社]
56
57Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些
58标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以
59并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许
60使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目
61前还没有明确的参考资料可以解释它们。请查阅gcc信息页(使用“info gcc”命令
62显示)获得一些这方面信息。
63
64请记住你是在学习怎么和已经存在的开发社区打交道。它由一群形形色色的人组成,
65他们对代码、风格和过程有着很高的标准。这些标准是在长期实践中总结出来的,
66适应于地理上分散的大型开发团队。它们已经被很好得整理成档,建议你在开发
67之前尽可能多的学习这些标准,而不要期望别人来适应你或者你公司的行为方式。
68
69
70法律问题
71--------
72
73Linux内核源代码都是在GPL(通用公共许可证)的保护下发布的。要了解这种许可
74的细节请查看源代码主目录下的COPYING文件。如果你对它还有更深入问题请联系
75律师,而不要在Linux内核邮件组上提问。因为邮件组里的人并不是律师,不要期
76望他们的话有法律效力。
77
78对于GPL的常见问题和解答,请访问以下链接:
79 http://www.gnu.org/licenses/gpl-faq.html
80
81
82文档
83----
84
85Linux内核代码中包含有大量的文档。这些文档对于学习如何与内核社区互动有着
86不可估量的价值。当一个新的功能被加入内核,最好把解释如何使用这个功能的文
87档也放进内核。当内核的改动导致面向用户空间的接口发生变化时,最好将相关信
88息或手册页(manpages)的补丁发到mtk-manpages@gmx.net,以向手册页(manpages)
89的维护者解释这些变化。
90
91以下是内核代码中需要阅读的文档:
92 README
93 文件简要介绍了Linux内核的背景,并且描述了如何配置和编译内核。内核的
94 新用户应该从这里开始。
95
96 Documentation/Changes
97 文件给出了用来编译和使用内核所需要的最小软件包列表。
98
99 Documentation/CodingStyle
100 描述Linux内核的代码风格和理由。所有新代码需要遵守这篇文档中定义的规
101 范。大多数维护者只会接收符合规定的补丁,很多人也只会帮忙检查符合风格
102 的代码。
103
104 Documentation/SubmittingPatches
105 Documentation/SubmittingDrivers
106 这两份文档明确描述如何创建和发送补丁,其中包括(但不仅限于):
107 - 邮件内容
108 - 邮件格式
109 - 选择收件人
110 遵守这些规定并不能保证提交成功(因为所有补丁需要通过严格的内容和风格
111 审查),但是忽视他们几乎就意味着失败。
112
113 其他关于如何正确地生成补丁的优秀文档包括:
114 "The Perfect Patch"
115 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
116 "Linux kernel patch submission format"
117 http://linux.yyz.us/patch-format.html
118
119 Documentation/stable_api_nonsense.txt
120 论证内核为什么特意不包括稳定的内核内部API,也就是说不包括像这样的特
121 性:
122 - 子系统中间层(为了兼容性?)
123 - 在不同操作系统间易于移植的驱动程序
124 - 减缓(甚至阻止)内核代码的快速变化
125 这篇文档对于理解Linux的开发哲学至关重要。对于将开发平台从其他操作系
126 统转移到Linux的人来说也很重要。
127
128 Documentation/SecurityBugs
129 如果你认为自己发现了Linux内核的安全性问题,请根据这篇文档中的步骤来
130 提醒其他内核开发者并帮助解决这个问题。
131
132 Documentation/ManagementStyle
133 描述内核维护者的工作方法及其共有特点。这对于刚刚接触内核开发(或者对
134 它感到好奇)的人来说很重要,因为它解释了很多对于内核维护者独特行为的
135 普遍误解与迷惑。
136
137 Documentation/stable_kernel_rules.txt
138 解释了稳定版内核发布的规则,以及如何将改动放入这些版本的步骤。
139
140 Documentation/kernel-docs.txt
141 有助于内核开发的外部文档列表。如果你在内核自带的文档中没有找到你想找
142 的内容,可以查看这些文档。
143
144 Documentation/applying-patches.txt
145 关于补丁是什么以及如何将它打在不同内核开发分支上的好介绍
146
147内核还拥有大量从代码自动生成的文档。它包含内核内部API的全面介绍以及如何
148妥善处理加锁的规则。生成的文档会放在 Documentation/DocBook/目录下。在内
149核源码的主目录中使用以下不同命令将会分别生成PDF、Postscript、HTML和手册
150页等不同格式的文档:
151 make pdfdocs
152 make psdocs
153 make htmldocs
154 make mandocs
155
156
157如何成为内核开发者
158------------------
159如果你对Linux内核开发一无所知,你应该访问“Linux内核新手”计划:
160 http://kernelnewbies.org
161它拥有一个可以问各种最基本的内核开发问题的邮件列表(在提问之前一定要记得
162查找已往的邮件,确认是否有人已经回答过相同的问题)。它还拥有一个可以获得
163实时反馈的IRC聊天频道,以及大量对于学习Linux内核开发相当有帮助的文档。
164
165网站简要介绍了源代码组织结构、子系统划分以及目前正在进行的项目(包括内核
166中的和单独维护的)。它还提供了一些基本的帮助信息,比如如何编译内核和打补
167丁。
168
169如果你想加入内核开发社区并协助完成一些任务,却找不到从哪里开始,可以访问
170“Linux内核房管员”计划:
171 http://janitor.kernelnewbies.org/
172这是极佳的起点。它提供一个相对简单的任务列表,列出内核代码中需要被重新
173整理或者改正的地方。通过和负责这个计划的开发者们一同工作,你会学到将补丁
174集成进内核的基本原理。如果还没有决定下一步要做什么的话,你还可能会得到方
175向性的指点。
176
177如果你已经有一些现成的代码想要放到内核中,但是需要一些帮助来使它们拥有正
178确的格式。请访问“内核导师”计划。这个计划就是用来帮助你完成这个目标的。它
179是一个邮件列表,地址如下:
180 http://selenic.com/mailman/listinfo/kernel-mentors
181
182在真正动手修改内核代码之前,理解要修改的代码如何运作是必需的。要达到这个
183目的,没什么办法比直接读代码更有效了(大多数花招都会有相应的注释),而且
184一些特制的工具还可以提供帮助。例如,“Linux代码交叉引用”项目就是一个值得
185特别推荐的帮助工具,它将源代码显示在有编目和索引的网页上。其中一个更新及
186时的内核源码库,可以通过以下地址访问:
187 http://sosdg.org/~coywolf/lxr/
188
189
190开发流程
191--------
192
193目前Linux内核开发流程包括几个“主内核分支”和很多子系统相关的内核分支。这
194些分支包括:
195 - 2.6.x主内核源码树
196 - 2.6.x.y -stable内核源码树
197 - 2.6.x -git内核补丁集
198 - 2.6.x -mm内核补丁集
199 - 子系统相关的内核源码树和补丁集
200
201
2022.6.x内核主源码树
203-----------------
2042.6.x内核是由Linus Torvalds(Linux的创造者)亲自维护的。你可以在
205kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循以下步
206骤:
207 - 每当一个新版本的内核被发布,为期两周的集成窗口将被打开。在这段时间里
208 维护者可以向Linus提交大段的修改,通常这些修改已经被放到-mm内核中几个
209 星期了。提交大量修改的首选方式是使用git工具(内核的代码版本管理工具
210 ,更多的信息可以在http://git.or.cz/获取),不过使用普通补丁也是可以
211 的。
212 - 两个星期以后-rc1版本内核发布。之后只有不包含可能影响整个内核稳定性的
213 新功能的补丁才可能被接受。请注意一个全新的驱动程序(或者文件系统)有
214 可能在-rc1后被接受是因为这样的修改完全独立,不会影响其他的代码,所以
215 没有造成内核退步的风险。在-rc1以后也可以用git向Linus提交补丁,不过所
216 有的补丁需要同时被发送到相应的公众邮件列表以征询意见。
217 - 当Linus认为当前的git源码树已经达到一个合理健全的状态足以发布供人测试
218 时,一个新的-rc版本就会被发布。计划是每周都发布新的-rc版本。
219 - 这个过程一直持续下去直到内核被认为达到足够稳定的状态,持续时间大概是
220 6个星期。
221
222关于内核发布,值得一提的是Andrew Morton在linux-kernel邮件列表中如是说:
223 “没有人知道新内核何时会被发布,因为发布是根据已知bug的情况来决定
224 的,而不是根据一个事先制定好的时间表。”
225
226
2272.6.x.y -stable(稳定版)内核源码树
228-----------------------------------
229由4个数字组成的内核版本号说明此内核是-stable版本。它们包含基于2.6.x版本
230内核的相对较小且至关重要的修补,这些修补针对安全性问题或者严重的内核退步。
231
232这种版本的内核适用于那些期望获得最新的稳定版内核并且不想参与测试开发版或
233者实验版的用户。
234
235如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
236版内核。
237
2382.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
239布新版本。
240
241内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
242版内核接受的修改类型以及发布的流程。
243
244
2452.6.x -git补丁集
246----------------
247Linus的内核源码树的每日快照,这个源码树是由git工具管理的(由此得名)。这
248些补丁通常每天更新以反映Linus的源码树的最新状态。它们比-rc版本的内核源码
249树更具试验性质,因为这个补丁集是全自动生成的,没有任何人来确认其是否真正
250健全。
251
252
2532.6.x -mm补丁集
254---------------
255这是由Andrew Morton维护的试验性内核补丁集。Andrew将所有子系统的内核源码
256和补丁拼凑到一起,并且加入了大量从linux-kernel邮件列表中采集的补丁。这个
257源码树是新功能和补丁的试炼场。当补丁在-mm补丁集里证明了其价值以后Andrew
258或者相应子系统的维护者会将补丁发给Linus以便集成进主内核源码树。
259
260在将所有新补丁发给Linus以集成到主内核源码树之前,我们非常鼓励先把这些补
261丁放在-mm版内核源码树中进行测试。
262
263这些内核版本不适合在需要稳定运行的系统上运行,因为运行它们比运行任何其他
264内核分支都更具有风险。
265
266如果你想为内核开发进程提供帮助,请尝试并使用这些内核版本,并在
267linux-kernel邮件列表中提供反馈,告诉大家你遇到了问题还是一切正常。
268
269通常-mm版补丁集不光包括这些额外的试验性补丁,还包括发布时-git版主源码树
270中的改动。
271
272-mm版内核没有固定的发布周期,但是通常在每两个-rc版内核发布之间都会有若干
273个-mm版内核发布(一般是1至3个)。
274
275
276子系统相关内核源码树和补丁集
277----------------------------
278相当一部分内核子系统开发者会公开他们自己的开发源码树,以便其他人能了解内
279核的不同领域正在发生的事情。如上所述,这些源码树会被集成到-mm版本内核中。
280
281下面是目前可用的一些内核源码树的列表:
282 通过git管理的源码树:
283 - Kbuild开发源码树, Sam Ravnborg <sam@ravnborg.org>
284 git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
285
286 - ACPI开发源码树, Len Brown <len.brown@intel.com>
287 git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
288
289 - 块设备开发源码树, Jens Axboe <axboe@suse.de>
290 git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
291
292 - DRM开发源码树, Dave Airlie <airlied@linux.ie>
293 git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
294
295 - ia64开发源码树, Tony Luck <tony.luck@intel.com>
296 git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
297
298 - ieee1394开发源码树, Jody McIntyre <scjody@modernduck.com>
299 git.kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
300
301 - infiniband开发源码树, Roland Dreier <rolandd@cisco.com>
302 git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
303
304 - libata开发源码树, Jeff Garzik <jgarzik@pobox.com>
305 git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
306
307 - 网络驱动程序开发源码树, Jeff Garzik <jgarzik@pobox.com>
308 git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
309
310 - pcmcia开发源码树, Dominik Brodowski <linux@dominikbrodowski.net>
311 git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
312
313 - SCSI开发源码树, James Bottomley <James.Bottomley@SteelEye.com>
314 git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
315
316 使用quilt管理的补丁集:
317 - USB, PCI, 驱动程序核心和I2C, Greg Kroah-Hartman <gregkh@suse.de>
318 kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
319 - x86-64, 部分i386, Andi Kleen <ak@suse.de>
320 ftp.firstfloor.org:/pub/ak/x86_64/quilt/
321
322 其他内核源码树可以在http://git.kernel.org的列表中和MAINTAINERS文件里
323 找到。
324
325报告bug
326-------
327
328bugzilla.kernel.org是Linux内核开发者们用来跟踪内核Bug的网站。我们鼓励用
329户在这个工具中报告找到的所有bug。如何使用内核bugzilla的细节请访问:
330 http://test.kernel.org/bugzilla/faq.html
331
332内核源码主目录中的REPORTING-BUGS文件里有一个很好的模板。它指导用户如何报
333告可能的内核bug以及需要提供哪些信息来帮助内核开发者们找到问题的根源。
334
335
336利用bug报告
337-----------
338
339练习内核开发技能的最好办法就是修改其他人报告的bug。你不光可以帮助内核变
340得更加稳定,还可以学会如何解决实际问题从而提高自己的技能,并且让其他开发
341者感受到你的存在。修改bug是赢得其他开发者赞誉的最好办法,因为并不是很多
342人都喜欢浪费时间去修改别人报告的bug。
343
344要尝试修改已知的bug,请访问http://bugzilla.kernel.org网址。如果你想获得
345最新bug的通知,可以订阅bugme-new邮件列表(只有新的bug报告会被寄到这里)
346或者订阅bugme-janitor邮件列表(所有bugzilla的变动都会被寄到这里)。
347
348 http://lists.osdl.org/mailman/listinfo/bugme-new
349 http://lists.osdl.org/mailman/listinfo/bugme-janitors
350
351
352邮件列表
353--------
354
355正如上面的文档所描述,大多数的骨干内核开发者都加入了Linux Kernel邮件列
356表。如何订阅和退订列表的细节可以在这里找到:
357 http://vger.kernel.org/vger-lists.html#linux-kernel
358网上很多地方都有这个邮件列表的存档(archive)。可以使用搜索引擎来找到这些
359存档。比如:
360 http://dir.gmane.org/gmane.linux.kernel
361在发信之前,我们强烈建议你先在存档中搜索你想要讨论的问题。很多已经被详细
362讨论过的问题只在邮件列表的存档中可以找到。
363
364大多数内核子系统也有自己独立的邮件列表来协调各自的开发工作。从
365MAINTAINERS文件中可以找到不同话题对应的邮件列表。
366
367很多邮件列表架设在kernel.org服务器上。这些列表的信息可以在这里找到:
368 http://vger.kernel.org/vger-lists.html
369
370在使用这些邮件列表时,请记住保持良好的行为习惯。下面的链接提供了与这些列
371表(或任何其它邮件列表)交流的一些简单规则,虽然内容有点滥竽充数。
372 http://www.albion.com/netiquette/
373
374当有很多人回复你的邮件时,邮件的抄送列表会变得很长。请不要将任何人从抄送
375列表中删除,除非你有足够的理由这么做。也不要只回复到邮件列表。请习惯于同
376一封邮件接收两次(一封来自发送者一封来自邮件列表),而不要试图通过添加一
377些奇特的邮件头来解决这个问题,人们不会喜欢的。
378
379记住保留你所回复内容的上下文和源头。在你回复邮件的顶部保留“某某某说到……”
380这几行。将你的评论加在被引用的段落之间而不要放在邮件的顶部。
381
382如果你在邮件中附带补丁,请确认它们是可以直接阅读的纯文本(如
383Documentation/SubmittingPatches文档中所述)。内核开发者们不希望遇到附件
384或者被压缩了的补丁。只有这样才能保证他们可以直接评论你的每行代码。请确保
385你使用的邮件发送程序不会修改空格和制表符。一个防范性的测试方法是先将邮件
386发送给自己,然后自己尝试是否可以顺利地打上收到的补丁。如果测试不成功,请
387调整或者更换你的邮件发送程序直到它正确工作为止。
388
389总而言之,请尊重其他的邮件列表订阅者。
390
391
392同内核社区合作
393----------------
394
395内核社区的目标就是提供尽善尽美的内核。所以当你提交补丁期望被接受进内核的
396时候,它的技术价值以及其他方面都将被评审。那么你可能会得到什么呢?
397 - 批评
398 - 评论
399 - 要求修改
400 - 要求证明修改的必要性
401 - 沉默
402
403要记住,这些是把补丁放进内核的正常情况。你必须学会听取对补丁的批评和评论,
404从技术层面评估它们,然后要么重写你的补丁要么简明扼要地论证修改是不必要
405的。如果你发的邮件没有得到任何回应,请过几天后再试一次,因为有时信件会湮
406没在茫茫信海中。
407
408你不应该做的事情:
409 - 期望自己的补丁不受任何质疑就直接被接受
410 - 翻脸
411 - 忽略别人的评论
412 - 没有按照别人的要求做任何修改就重新提交
413
414在一个努力追寻最好技术方案的社区里,对于一个补丁有多少好处总会有不同的见
415解。你必须要抱着合作的态度,愿意改变自己的观点来适应内核的风格。或者至少
416愿意去证明你的想法是有价值的。记住,犯错误是允许的,只要你愿意朝着正确的
417方案去努力。
418
419如果你的第一个补丁换来的是一堆修改建议,这是很正常的。这并不代表你的补丁
420不会被接受,也不意味着有人和你作对。你只需要改正所有提出的问题然后重新发
421送你的补丁。
422
423内核社区和公司文化的差异
424------------------------
425
426内核社区的工作模式同大多数传统公司开发队伍的工作模式并不相同。下面这些例
427子,可以帮助你避免某些可能发生问题:
428 用这些话介绍你的修改提案会有好处:
429 - 它同时解决了多个问题
430 - 它删除了2000行代码
431 - 这是补丁,它已经解释了我想要说明的
432 - 我在5种不同的体系结构上测试过它……
433 - 这是一系列小补丁用来……
434 - 这个修改提高了普通机器的性能……
435
436 应该避免如下的说法:
437 - 我们在AIX/ptx/Solaris就是这么做的,所以这么做肯定是好的……
438 - 我做这行已经20年了,所以……
439 - 为了我们公司赚钱考虑必须这么做
440 - 这是我们的企业产品线所需要的
441 - 这里是描述我观点的1000页设计文档
442 - 这是一个5000行的补丁用来……
443 - 我重写了现在乱七八糟的代码,这就是……
444 - 我被规定了最后期限,所以这个补丁需要立刻被接受
445
446另外一个内核社区与大部分传统公司的软件开发队伍不同的地方是无法面对面地交
447流。使用电子邮件和IRC聊天工具做为主要沟通工具的一个好处是性别和种族歧视
448将会更少。Linux内核的工作环境更能接受妇女和少数族群,因为每个人在别人眼
449里只是一个邮件地址。国际化也帮助了公平的实现,因为你无法通过姓名来判断人
450的性别。男人有可能叫李丽,女人也有可能叫王刚。大多数在Linux内核上工作过
451并表达过看法的女性对在linux上工作的经历都给出了正面的评价。
452
453对于一些不习惯使用英语的人来说,语言可能是一个引起问题的障碍。在邮件列表
454中要正确地表达想法必需良好地掌握语言,所以建议你在发送邮件之前最好检查一
455下英文写得是否正确。
456
457
458拆分修改
459--------
460
461Linux内核社区并不喜欢一下接收大段的代码。修改需要被恰当地介绍、讨论并且
462拆分成独立的小段。这几乎完全和公司中的习惯背道而驰。你的想法应该在开发最
463开始的阶段就让大家知道,这样你就可以及时获得对你正在进行的开发的反馈。这
464样也会让社区觉得你是在和他们协作,而不是仅仅把他们当作倾销新功能的对象。
465无论如何,你不要一次性地向邮件列表发送50封信,你的补丁序列应该永远用不到
466这么多。
467
468将补丁拆开的原因如下:
469
4701) 小的补丁更有可能被接受,因为它们不需要太多的时间和精力去验证其正确性。
471 一个5行的补丁,可能在维护者看了一眼以后就会被接受。而500行的补丁则
472 需要数个小时来审查其正确性(所需时间随补丁大小增加大约呈指数级增长)。
473
474 当出了问题的时候,小的补丁也会让调试变得非常容易。一个一个补丁地回溯
475 将会比仔细剖析一个被打上的大补丁(这个补丁破坏了其他东西)容易得多。
476
4772)不光发送小的补丁很重要,在提交之前重新编排、化简(或者仅仅重新排列)
478 补丁也是很重要的。
479
480这里有内核开发者Al Viro打的一个比方:
481 “想象一个老师正在给学生批改数学作业。老师并不希望看到学生为了得
482 到正确解法所进行的尝试和产生的错误。他希望看到的是最干净最优雅的
483 解答。好学生了解这点,绝不会把最终解决之前的中间方案提交上去。”
484
485 内核开发也是这样。维护者和评审者不希望看到一个人在解决问题时的思
486 考过程。他们只希望看到简单和优雅的解决方案。
487
488直接给出一流的解决方案,和社区一起协作讨论尚未完成的工作,这两者之间似乎
489很难找到一个平衡点。所以最好尽早开始收集有利于你进行改进的反馈;同时也要
490保证修改分成很多小块,这样在整个项目都准备好被包含进内核之前,其中的一部
491分可能会先被接收。
492
493必须了解这样做是不可接受的:试图将未完成的工作提交进内核,然后再找时间修
494复。
495
496
497证明修改的必要性
498----------------
499除了将补丁拆成小块,很重要的一点是让Linux社区了解他们为什么需要这样修改。
500你必须证明新功能是有人需要的并且是有用的。
501
502
503记录修改
504--------
505
506当你发送补丁的时候,需要特别留意邮件正文的内容。因为这里的信息将会做为补
507丁的修改记录(ChangeLog),会被一直保留以备大家查阅。它需要完全地描述补丁,
508包括:
509 - 为什么需要这个修改
510 - 补丁的总体设计
511 - 实现细节
512 - 测试结果
513
514想了解它具体应该看起来像什么,请查阅以下文档中的“ChangeLog”章节:
515 “The Perfect Patch”
516 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
517
518
519这些事情有时候做起来很难。要在任何方面都做到完美可能需要好几年时间。这是
520一个持续提高的过程,它需要大量的耐心和决心。只要不放弃,你一定可以做到。
521很多人已经做到了,而他们都曾经和现在的你站在同样的起点上。
522
523
524---------------
525感谢Paolo Ciarrocchi允许“开发流程”部分基于他所写的文章
526(http://linux.tar.bz/articles/2.6-development_process),感谢Randy
527Dunlap和Gerrit Huizenga完善了应该说和不该说的列表。感谢Pat Mochel, Hanna
528Linder, Randy Dunlap, Kay Sievers, Vojtech Pavlik, Jan Kara, Josh Boyer,
529Kees Cook, Andrew Morton, Andi Kleen, Vadim Lobanov, Jesper Juhl, Adrian
530Bunk, Keri Harris, Frans Pop, David A. Wheeler, Junio Hamano, Michael
531Kerrisk和Alex Shepard的评审、建议和贡献。没有他们的帮助,这篇文档是不可
532能完成的。
533
534
535
536英文版维护者: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/Documentation/zh_CN/stable_api_nonsense.txt b/Documentation/zh_CN/stable_api_nonsense.txt
new file mode 100644
index 000000000000..c26a27d1ee7d
--- /dev/null
+++ b/Documentation/zh_CN/stable_api_nonsense.txt
@@ -0,0 +1,157 @@
1Chinese translated version of Documentation/stable_api_nonsense.txt
2
3If you have any comment or update to the content, please contact the
4original document maintainer directly. However, if you have problem
5communicating in English you can also ask the Chinese maintainer for help.
6Contact the Chinese maintainer, if this translation is outdated or there
7is problem with translation.
8
9Maintainer: Greg Kroah-Hartman <greg@kroah.com>
10Chinese maintainer: TripleX Chung <zhongyu@18mail.cn>
11---------------------------------------------------------------------
12Documentation/stable_api_nonsense.txt 的中文翻译
13
14如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16译存在问题,请联系中文版维护者。
17
18英文版维护者: Greg Kroah-Hartman <greg@kroah.com>
19中文版维护者: 钟宇 TripleX Chung <zhongyu@18mail.cn>
20中文版翻译者: 钟宇 TripleX Chung <zhongyu@18mail.cn>
21中文版校译者: 李阳 Li Yang <leoli@freescale.com>
22以下为正文
23---------------------------------------------------------------------
24
25写作本文档的目的,是为了解释为什么Linux既没有二进制内核接口,也没有稳定
26的内核接口。这里所说的内核接口,是指内核里的接口,而不是内核和用户空间
27的接口。内核到用户空间的接口,是提供给应用程序使用的系统调用,系统调用
28在历史上几乎没有过变化,将来也不会有变化。我有一些老应用程序是在0.9版本
29或者更早版本的内核上编译的,在使用2.6版本内核的Linux发布上依然用得很好
30。用户和应用程序作者可以将这个接口看成是稳定的。
31
32
33执行纲要
34--------
35
36你也许以为自己想要稳定的内核接口,但是你不清楚你要的实际上不是它。你需
37要的其实是稳定的驱动程序,而你只有将驱动程序放到公版内核的源代码树里,
38才有可能达到这个目的。而且这样做还有很多其它好处,正是因为这些好处使得
39Linux能成为强壮,稳定,成熟的操作系统,这也是你最开始选择Linux的原因。
40
41
42入门
43-----
44
45只有那些写驱动程序的“怪人”才会担心内核接口的改变,对广大用户来说,既
46看不到内核接口,也不需要去关心它。
47
48首先,我不打算讨论关于任何非GPL许可的内核驱动的法律问题,这些非GPL许可
49的驱动程序包括不公开源代码,隐藏源代码,二进制或者是用源代码包装,或者
50是其它任何形式的不能以GPL许可公开源代码的驱动程序。如果有法律问题,请咨
51询律师,我只是一个程序员,所以我只打算探讨技术问题(不是小看法律问题,
52法律问题很实际,并且需要一直关注)。
53
54既然只谈技术问题,我们就有了下面两个主题:二进制内核接口和稳定的内核源
55代码接口。这两个问题是互相关联的,让我们先解决掉二进制接口的问题。
56
57
58二进制内核接口
59--------------
60假如我们有一个稳定的内核源代码接口,那么自然而然的,我们就拥有了稳定的
61二进制接口,是这样的吗?错。让我们看看关于Linux内核的几点事实:
62 - 取决于所用的C编译器的版本,不同的内核数据结构里的结构体的对齐方
63式会有差别,代码中不同函数的表现形式也不一样(函数是不是被inline编译取
64决于编译器行为)。不同的函数的表现形式并不重要,但是数据结构内部的对齐
65方式很关键。
66 - 取决于内核的配置选项,不同的选项会让内核的很多东西发生改变:
67 - 同一个结构体可能包含不同的成员变量
68 - 有的函数可能根本不会被实现(比如编译的时候没有选择SMP支持
69,一些锁函数就会被定义成空函数)。
70 - 内核使用的内存会以不同的方式对齐,这取决于不同的内核配置选
71项。
72 - Linux可以在很多的不同体系结构的处理器上运行。在某个体系结构上编
73译好的二进制驱动程序,不可能在另外一个体系结构上正确的运行。
74
75对于一个特定的内核,满足这些条件并不难,使用同一个C编译器和同样的内核配
76置选项来编译驱动程序模块就可以了。这对于给一个特定Linux发布的特定版本提
77供驱动程序,是完全可以满足需求的。但是如果你要给不同发布的不同版本都发
78布一个驱动程序,就需要在每个发布上用不同的内核设置参数都编译一次内核,
79这简直跟噩梦一样。而且还要注意到,每个Linux发布还提供不同的Linux内核,
80这些内核都针对不同的硬件类型进行了优化(有很多种不同的处理器,还有不同
81的内核设置选项)。所以每发布一次驱动程序,都需要提供很多不同版本的内核
82模块。
83
84相信我,如果你真的要采取这种发布方式,一定会慢慢疯掉,我很久以前就有过
85深刻的教训...
86
87
88稳定的内核源代码接口
89--------------------
90
91如果有人不将他的内核驱动程序,放入公版内核的源代码树,而又想让驱动程序
92一直保持在最新的内核中可用,那么这个话题将会变得没完没了。
93 内核开发是持续而且快节奏的,从来都不会慢下来。内核开发人员在当前接口中
94找到bug,或者找到更好的实现方式。一旦发现这些,他们就很快会去修改当前的
95接口。修改接口意味着,函数名可能会改变,结构体可能被扩充或者删减,函数
96的参数也可能发生改变。一旦接口被修改,内核中使用这些接口的地方需要同时
97修正,这样才能保证所有的东西继续工作。
98
99举一个例子,内核的USB驱动程序接口在USB子系统的整个生命周期中,至少经历
100了三次重写。这些重写解决以下问题:
101 - 把数据流从同步模式改成非同步模式,这个改动减少了一些驱动程序的
102复杂度,提高了所有USB驱动程序的吞吐率,这样几乎所有的USB设备都能以最大
103速率工作了。
104 - 修改了USB核心代码中为USB驱动分配数据包内存的方式,所有的驱动都
105需要提供更多的参数给USB核心,以修正了很多已经被记录在案的死锁。
106
107这和一些封闭源代码的操作系统形成鲜明的对比,在那些操作系统上,不得不额
108外的维护旧的USB接口。这导致了一个可能性,新的开发者依然会不小心使用旧的
109接口,以不恰当的方式编写代码,进而影响到操作系统的稳定性。
110 在上面的例子中,所有的开发者都同意这些重要的改动,在这样的情况下修改代
111价很低。如果Linux保持一个稳定的内核源代码接口,那么就得创建一个新的接口
112;旧的,有问题的接口必须一直维护,给Linux USB开发者带来额外的工作。既然
113所有的Linux USB驱动的作者都是利用自己的时间工作,那么要求他们去做毫无意
114义的免费额外工作,是不可能的。
115 安全问题对Linux来说十分重要。一个安全问题被发现,就会在短时间内得到修
116正。在很多情况下,这将导致Linux内核中的一些接口被重写,以从根本上避免安
117全问题。一旦接口被重写,所有使用这些接口的驱动程序,必须同时得到修正,
118以确定安全问题已经得到修复并且不可能在未来还有同样的安全问题。如果内核
119内部接口不允许改变,那么就不可能修复这样的安全问题,也不可能确认这样的
120安全问题以后不会发生。
121开发者一直在清理内核接口。如果一个接口没有人在使用了,它就会被删除。这
122样可以确保内核尽可能的小,而且所有潜在的接口都会得到尽可能完整的测试
123(没有人使用的接口是不可能得到良好的测试的)。
124
125
126要做什么
127-------
128
129如果你写了一个Linux内核驱动,但是它还不在Linux源代码树里,作为一个开发
130者,你应该怎么做?为每个发布的每个版本提供一个二进制驱动,那简直是一个
131噩梦,要跟上永远处于变化之中的内核接口,也是一件辛苦活。
132很简单,让你的驱动进入内核源代码树(要记得我们在谈论的是以GPL许可发行
133的驱动,如果你的代码不符合GPL,那么祝你好运,你只能自己解决这个问题了,
134你这个吸血鬼<把Andrew和Linus对吸血鬼的定义链接到这里>)。当你的代码加入
135公版内核源代码树之后,如果一个内核接口改变,你的驱动会直接被修改接口的
136那个人修改。保证你的驱动永远都可以编译通过,并且一直工作,你几乎不需要
137做什么事情。
138
139把驱动放到内核源代码树里会有很多的好处:
140 - 驱动的质量会提升,而维护成本(对原始作者来说)会下降。
141 - 其他人会给驱动添加新特性。
142 - 其他人会找到驱动中的bug并修复。
143 - 其他人会在驱动中找到性能优化的机会。
144 - 当外部的接口的改变需要修改驱动程序的时候,其他人会修改驱动程序
145
146 - 不需要联系任何发行商,这个驱动会自动的随着所有的Linux发布一起发
147布。
148
149和别的操作系统相比,Linux为更多不同的设备提供现成的驱动,而且能在更多不
150同体系结构的处理器上支持这些设备。这个经过考验的开发模式,必然是错不了
151的 :)
152
153-------------
154感谢 Randy Dunlap, Andrew Morton, David Brownell, Hanna Linder,
155Robert Love, and Nishanth Aravamudan 对于本文档早期版本的评审和建议。
156
157英文版维护者: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index e78f62f13bac..f6b2665ccb2b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -732,6 +732,13 @@ L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
732W: http://blackfin.uclinux.org 732W: http://blackfin.uclinux.org
733S: Supported 733S: Supported
734 734
735BLACKFIN EMAC DRIVER
736P: Bryan Wu
737M: bryan.wu@analog.com
738L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
739W: http://blackfin.uclinux.org
740S: Supported
741
735BLACKFIN RTC DRIVER 742BLACKFIN RTC DRIVER
736P: Mike Frysinger 743P: Mike Frysinger
737M: michael.frysinger@analog.com 744M: michael.frysinger@analog.com
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index db56a02b748f..6a78a2b37c08 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -131,6 +131,7 @@
131 interrupts = <1d 2 1e 2 22 2>; 131 interrupts = <1d 2 1e 2 22 2>;
132 interrupt-parent = <&mpic>; 132 interrupt-parent = <&mpic>;
133 phy-handle = <&phy0>; 133 phy-handle = <&phy0>;
134 phy-connection-type = "rgmii-id";
134 }; 135 };
135 136
136 ethernet@25000 { 137 ethernet@25000 {
@@ -150,6 +151,7 @@
150 interrupts = <23 2 24 2 28 2>; 151 interrupts = <23 2 24 2 28 2>;
151 interrupt-parent = <&mpic>; 152 interrupt-parent = <&mpic>;
152 phy-handle = <&phy1>; 153 phy-handle = <&phy1>;
154 phy-connection-type = "rgmii-id";
153 }; 155 };
154 156
155 ethernet@26000 { 157 ethernet@26000 {
@@ -169,6 +171,7 @@
169 interrupts = <1F 2 20 2 21 2>; 171 interrupts = <1F 2 20 2 21 2>;
170 interrupt-parent = <&mpic>; 172 interrupt-parent = <&mpic>;
171 phy-handle = <&phy2>; 173 phy-handle = <&phy2>;
174 phy-connection-type = "rgmii-id";
172 }; 175 };
173 176
174 ethernet@27000 { 177 ethernet@27000 {
@@ -188,6 +191,7 @@
188 interrupts = <25 2 26 2 27 2>; 191 interrupts = <25 2 26 2 27 2>;
189 interrupt-parent = <&mpic>; 192 interrupt-parent = <&mpic>;
190 phy-handle = <&phy3>; 193 phy-handle = <&phy3>;
194 phy-connection-type = "rgmii-id";
191 }; 195 };
192 serial@4500 { 196 serial@4500 {
193 device_type = "serial"; 197 device_type = "serial";
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index c0ddc80d8160..3289fab01e92 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -197,6 +197,7 @@ static int __init gfar_of_init(void)
197 struct gianfar_platform_data gfar_data; 197 struct gianfar_platform_data gfar_data;
198 const unsigned int *id; 198 const unsigned int *id;
199 const char *model; 199 const char *model;
200 const char *ctype;
200 const void *mac_addr; 201 const void *mac_addr;
201 const phandle *ph; 202 const phandle *ph;
202 int n_res = 2; 203 int n_res = 2;
@@ -254,6 +255,14 @@ static int __init gfar_of_init(void)
254 FSL_GIANFAR_DEV_HAS_VLAN | 255 FSL_GIANFAR_DEV_HAS_VLAN |
255 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 256 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
256 257
258 ctype = of_get_property(np, "phy-connection-type", NULL);
259
260 /* We only care about rgmii-id. The rest are autodetected */
261 if (ctype && !strcmp(ctype, "rgmii-id"))
262 gfar_data.interface = PHY_INTERFACE_MODE_RGMII_ID;
263 else
264 gfar_data.interface = PHY_INTERFACE_MODE_MII;
265
257 ph = of_get_property(np, "phy-handle", NULL); 266 ph = of_get_property(np, "phy-handle", NULL);
258 phy = of_find_node_by_phandle(*ph); 267 phy = of_find_node_by_phandle(*ph);
259 268
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7916f4b86d23..ae01d86070bb 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,4 +84,5 @@ source "drivers/auxdisplay/Kconfig"
84 84
85source "drivers/kvm/Kconfig" 85source "drivers/kvm/Kconfig"
86 86
87source "drivers/uio/Kconfig"
87endmenu 88endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 6d9d7fab77f5..c34c8efff609 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ATA) += ata/
40obj-$(CONFIG_FUSION) += message/ 40obj-$(CONFIG_FUSION) += message/
41obj-$(CONFIG_FIREWIRE) += firewire/ 41obj-$(CONFIG_FIREWIRE) += firewire/
42obj-$(CONFIG_IEEE1394) += ieee1394/ 42obj-$(CONFIG_IEEE1394) += ieee1394/
43obj-$(CONFIG_UIO) += uio/
43obj-y += cdrom/ 44obj-y += cdrom/
44obj-y += auxdisplay/ 45obj-y += auxdisplay/
45obj-$(CONFIG_MTD) += mtd/ 46obj-$(CONFIG_MTD) += mtd/
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0455aa78fa13..3599ab2506d2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -24,6 +24,8 @@
24#include "base.h" 24#include "base.h"
25#include "power/power.h" 25#include "power/power.h"
26 26
27extern const char *kobject_actions[];
28
27int (*platform_notify)(struct device * dev) = NULL; 29int (*platform_notify)(struct device * dev) = NULL;
28int (*platform_notify_remove)(struct device * dev) = NULL; 30int (*platform_notify_remove)(struct device * dev) = NULL;
29 31
@@ -303,10 +305,25 @@ out:
303static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, 305static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
304 const char *buf, size_t count) 306 const char *buf, size_t count)
305{ 307{
306 if (memcmp(buf, "add", 3) != 0) 308 size_t len = count;
307 dev_err(dev, "uevent: unsupported action-string; this will " 309 enum kobject_action action;
308 "be ignored in a future kernel version"); 310
311 if (len && buf[len-1] == '\n')
312 len--;
313
314 for (action = 0; action < KOBJ_MAX; action++) {
315 if (strncmp(kobject_actions[action], buf, len) != 0)
316 continue;
317 if (kobject_actions[action][len] != '\0')
318 continue;
319 kobject_uevent(&dev->kobj, action);
320 goto out;
321 }
322
323 dev_err(dev, "uevent: unsupported action-string; this will "
324 "be ignored in a future kernel version\n");
309 kobject_uevent(&dev->kobj, KOBJ_ADD); 325 kobject_uevent(&dev->kobj, KOBJ_ADD);
326out:
310 return count; 327 return count;
311} 328}
312 329
@@ -643,6 +660,82 @@ static int setup_parent(struct device *dev, struct device *parent)
643 return 0; 660 return 0;
644} 661}
645 662
663static int device_add_class_symlinks(struct device *dev)
664{
665 int error;
666
667 if (!dev->class)
668 return 0;
669 error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
670 "subsystem");
671 if (error)
672 goto out;
673 /*
674 * If this is not a "fake" compatible device, then create the
675 * symlink from the class to the device.
676 */
677 if (dev->kobj.parent != &dev->class->subsys.kobj) {
678 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
679 dev->bus_id);
680 if (error)
681 goto out_subsys;
682 }
683 /* only bus-device parents get a "device"-link */
684 if (dev->parent && dev->parent->bus) {
685 error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
686 "device");
687 if (error)
688 goto out_busid;
689#ifdef CONFIG_SYSFS_DEPRECATED
690 {
691 char * class_name = make_class_name(dev->class->name,
692 &dev->kobj);
693 if (class_name)
694 error = sysfs_create_link(&dev->parent->kobj,
695 &dev->kobj, class_name);
696 kfree(class_name);
697 if (error)
698 goto out_device;
699 }
700#endif
701 }
702 return 0;
703
704#ifdef CONFIG_SYSFS_DEPRECATED
705out_device:
706 if (dev->parent)
707 sysfs_remove_link(&dev->kobj, "device");
708#endif
709out_busid:
710 if (dev->kobj.parent != &dev->class->subsys.kobj)
711 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
712out_subsys:
713 sysfs_remove_link(&dev->kobj, "subsystem");
714out:
715 return error;
716}
717
718static void device_remove_class_symlinks(struct device *dev)
719{
720 if (!dev->class)
721 return;
722 if (dev->parent) {
723#ifdef CONFIG_SYSFS_DEPRECATED
724 char *class_name;
725
726 class_name = make_class_name(dev->class->name, &dev->kobj);
727 if (class_name) {
728 sysfs_remove_link(&dev->parent->kobj, class_name);
729 kfree(class_name);
730 }
731#endif
732 sysfs_remove_link(&dev->kobj, "device");
733 }
734 if (dev->kobj.parent != &dev->class->subsys.kobj)
735 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
736 sysfs_remove_link(&dev->kobj, "subsystem");
737}
738
646/** 739/**
647 * device_add - add device to device hierarchy. 740 * device_add - add device to device hierarchy.
648 * @dev: device. 741 * @dev: device.
@@ -657,7 +750,6 @@ static int setup_parent(struct device *dev, struct device *parent)
657int device_add(struct device *dev) 750int device_add(struct device *dev)
658{ 751{
659 struct device *parent = NULL; 752 struct device *parent = NULL;
660 char *class_name = NULL;
661 struct class_interface *class_intf; 753 struct class_interface *class_intf;
662 int error = -EINVAL; 754 int error = -EINVAL;
663 755
@@ -697,27 +789,9 @@ int device_add(struct device *dev)
697 goto ueventattrError; 789 goto ueventattrError;
698 } 790 }
699 791
700 if (dev->class) { 792 error = device_add_class_symlinks(dev);
701 sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, 793 if (error)
702 "subsystem"); 794 goto SymlinkError;
703 /* If this is not a "fake" compatible device, then create the
704 * symlink from the class to the device. */
705 if (dev->kobj.parent != &dev->class->subsys.kobj)
706 sysfs_create_link(&dev->class->subsys.kobj,
707 &dev->kobj, dev->bus_id);
708 if (parent) {
709 sysfs_create_link(&dev->kobj, &dev->parent->kobj,
710 "device");
711#ifdef CONFIG_SYSFS_DEPRECATED
712 class_name = make_class_name(dev->class->name,
713 &dev->kobj);
714 if (class_name)
715 sysfs_create_link(&dev->parent->kobj,
716 &dev->kobj, class_name);
717#endif
718 }
719 }
720
721 error = device_add_attrs(dev); 795 error = device_add_attrs(dev);
722 if (error) 796 if (error)
723 goto AttrsError; 797 goto AttrsError;
@@ -744,7 +818,6 @@ int device_add(struct device *dev)
744 up(&dev->class->sem); 818 up(&dev->class->sem);
745 } 819 }
746 Done: 820 Done:
747 kfree(class_name);
748 put_device(dev); 821 put_device(dev);
749 return error; 822 return error;
750 BusError: 823 BusError:
@@ -755,6 +828,8 @@ int device_add(struct device *dev)
755 BUS_NOTIFY_DEL_DEVICE, dev); 828 BUS_NOTIFY_DEL_DEVICE, dev);
756 device_remove_attrs(dev); 829 device_remove_attrs(dev);
757 AttrsError: 830 AttrsError:
831 device_remove_class_symlinks(dev);
832 SymlinkError:
758 if (MAJOR(dev->devt)) 833 if (MAJOR(dev->devt))
759 device_remove_file(dev, &devt_attr); 834 device_remove_file(dev, &devt_attr);
760 835
@@ -1139,7 +1214,7 @@ int device_rename(struct device *dev, char *new_name)
1139{ 1214{
1140 char *old_class_name = NULL; 1215 char *old_class_name = NULL;
1141 char *new_class_name = NULL; 1216 char *new_class_name = NULL;
1142 char *old_symlink_name = NULL; 1217 char *old_device_name = NULL;
1143 int error; 1218 int error;
1144 1219
1145 dev = get_device(dev); 1220 dev = get_device(dev);
@@ -1153,42 +1228,49 @@ int device_rename(struct device *dev, char *new_name)
1153 old_class_name = make_class_name(dev->class->name, &dev->kobj); 1228 old_class_name = make_class_name(dev->class->name, &dev->kobj);
1154#endif 1229#endif
1155 1230
1156 if (dev->class) { 1231 old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
1157 old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); 1232 if (!old_device_name) {
1158 if (!old_symlink_name) { 1233 error = -ENOMEM;
1159 error = -ENOMEM; 1234 goto out;
1160 goto out_free_old_class;
1161 }
1162 strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
1163 } 1235 }
1164 1236 strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
1165 strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); 1237 strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
1166 1238
1167 error = kobject_rename(&dev->kobj, new_name); 1239 error = kobject_rename(&dev->kobj, new_name);
1240 if (error) {
1241 strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
1242 goto out;
1243 }
1168 1244
1169#ifdef CONFIG_SYSFS_DEPRECATED 1245#ifdef CONFIG_SYSFS_DEPRECATED
1170 if (old_class_name) { 1246 if (old_class_name) {
1171 new_class_name = make_class_name(dev->class->name, &dev->kobj); 1247 new_class_name = make_class_name(dev->class->name, &dev->kobj);
1172 if (new_class_name) { 1248 if (new_class_name) {
1173 sysfs_create_link(&dev->parent->kobj, &dev->kobj, 1249 error = sysfs_create_link(&dev->parent->kobj,
1174 new_class_name); 1250 &dev->kobj, new_class_name);
1251 if (error)
1252 goto out;
1175 sysfs_remove_link(&dev->parent->kobj, old_class_name); 1253 sysfs_remove_link(&dev->parent->kobj, old_class_name);
1176 } 1254 }
1177 } 1255 }
1178#endif 1256#endif
1179 1257
1180 if (dev->class) { 1258 if (dev->class) {
1181 sysfs_remove_link(&dev->class->subsys.kobj, 1259 sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
1182 old_symlink_name); 1260 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
1183 sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, 1261 dev->bus_id);
1184 dev->bus_id); 1262 if (error) {
1263 /* Uh... how to unravel this if restoring can fail? */
1264 dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
1265 __FUNCTION__, error);
1266 }
1185 } 1267 }
1268out:
1186 put_device(dev); 1269 put_device(dev);
1187 1270
1188 kfree(new_class_name); 1271 kfree(new_class_name);
1189 kfree(old_symlink_name);
1190 out_free_old_class:
1191 kfree(old_class_name); 1272 kfree(old_class_name);
1273 kfree(old_device_name);
1192 1274
1193 return error; 1275 return error;
1194} 1276}
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 91f230939c1e..fff178007208 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,5 @@
1obj-y := shutdown.o 1obj-y := shutdown.o
2obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o 2obj-$(CONFIG_PM) += main.o suspend.o resume.o sysfs.o
3obj-$(CONFIG_PM_TRACE) += trace.o 3obj-$(CONFIG_PM_TRACE) += trace.o
4 4
5ifeq ($(CONFIG_DEBUG_DRIVER),y) 5ifeq ($(CONFIG_DEBUG_DRIVER),y)
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 2760f25b3ac5..591a0dd5deee 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -62,11 +62,6 @@ extern int resume_device(struct device *);
62 */ 62 */
63extern int suspend_device(struct device *, pm_message_t); 63extern int suspend_device(struct device *, pm_message_t);
64 64
65
66/*
67 * runtime.c
68 */
69
70#else /* CONFIG_PM */ 65#else /* CONFIG_PM */
71 66
72 67
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
deleted file mode 100644
index df6174d85866..000000000000
--- a/drivers/base/power/runtime.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * drivers/base/power/runtime.c - Handling dynamic device power management.
3 *
4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Lab
6 *
7 */
8
9#include <linux/device.h>
10#include "power.h"
11
12
13static void runtime_resume(struct device * dev)
14{
15 dev_dbg(dev, "resuming\n");
16 if (!dev->power.power_state.event)
17 return;
18 if (!resume_device(dev))
19 dev->power.power_state = PMSG_ON;
20}
21
22
23/**
24 * dpm_runtime_resume - Power one device back on.
25 * @dev: Device.
26 *
27 * Bring one device back to the on state by first powering it
28 * on, then restoring state. We only operate on devices that aren't
29 * already on.
30 * FIXME: We need to handle devices that are in an unknown state.
31 */
32
33void dpm_runtime_resume(struct device * dev)
34{
35 mutex_lock(&dpm_mtx);
36 runtime_resume(dev);
37 mutex_unlock(&dpm_mtx);
38}
39EXPORT_SYMBOL(dpm_runtime_resume);
40
41
42/**
43 * dpm_runtime_suspend - Put one device in low-power state.
44 * @dev: Device.
45 * @state: State to enter.
46 */
47
48int dpm_runtime_suspend(struct device * dev, pm_message_t state)
49{
50 int error = 0;
51
52 mutex_lock(&dpm_mtx);
53 if (dev->power.power_state.event == state.event)
54 goto Done;
55
56 if (dev->power.power_state.event)
57 runtime_resume(dev);
58
59 if (!(error = suspend_device(dev, state)))
60 dev->power.power_state = state;
61 Done:
62 mutex_unlock(&dpm_mtx);
63 return error;
64}
65EXPORT_SYMBOL(dpm_runtime_suspend);
66
67
68#if 0
69/**
70 * dpm_set_power_state - Update power_state field.
71 * @dev: Device.
72 * @state: Power state device is in.
73 *
74 * This is an update mechanism for drivers to notify the core
75 * what power state a device is in. Device probing code may not
76 * always be able to tell, but we need accurate information to
77 * work reliably.
78 */
79void dpm_set_power_state(struct device * dev, pm_message_t state)
80{
81 mutex_lock(&dpm_mtx);
82 dev->power.power_state = state;
83 mutex_unlock(&dpm_mtx);
84}
85#endif /* 0 */
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 2d47517dbe32..f2ed179cd695 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -7,69 +7,6 @@
7#include "power.h" 7#include "power.h"
8 8
9 9
10#ifdef CONFIG_PM_SYSFS_DEPRECATED
11
12/**
13 * state - Control current power state of device
14 *
15 * show() returns the current power state of the device. '0' indicates
16 * the device is on. Other values (2) indicate the device is in some low
17 * power state.
18 *
19 * store() sets the current power state, which is an integer valued
20 * 0, 2, or 3. Devices with bus.suspend_late(), or bus.resume_early()
21 * methods fail this operation; those methods couldn't be called.
22 * Otherwise,
23 *
24 * - If the recorded dev->power.power_state.event matches the
25 * target value, nothing is done.
26 * - If the recorded event code is nonzero, the device is reactivated
27 * by calling bus.resume() and/or class.resume().
28 * - If the target value is nonzero, the device is suspended by
29 * calling class.suspend() and/or bus.suspend() with event code
30 * PM_EVENT_SUSPEND.
31 *
32 * This mechanism is DEPRECATED and should only be used for testing.
33 */
34
35static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
36{
37 if (dev->power.power_state.event)
38 return sprintf(buf, "2\n");
39 else
40 return sprintf(buf, "0\n");
41}
42
43static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
44{
45 pm_message_t state;
46 int error = -EINVAL;
47
48 /* disallow incomplete suspend sequences */
49 if (dev->bus && (dev->bus->suspend_late || dev->bus->resume_early))
50 return error;
51
52 state.event = PM_EVENT_SUSPEND;
53 /* Older apps expected to write "3" here - confused with PCI D3 */
54 if ((n == 1) && !strcmp(buf, "3"))
55 error = dpm_runtime_suspend(dev, state);
56
57 if ((n == 1) && !strcmp(buf, "2"))
58 error = dpm_runtime_suspend(dev, state);
59
60 if ((n == 1) && !strcmp(buf, "0")) {
61 dpm_runtime_resume(dev);
62 error = 0;
63 }
64
65 return error ? error : n;
66}
67
68static DEVICE_ATTR(state, 0644, state_show, state_store);
69
70
71#endif /* CONFIG_PM_SYSFS_DEPRECATED */
72
73/* 10/*
74 * wakeup - Report/change current wakeup option for device 11 * wakeup - Report/change current wakeup option for device
75 * 12 *
@@ -143,9 +80,6 @@ static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
143 80
144 81
145static struct attribute * power_attrs[] = { 82static struct attribute * power_attrs[] = {
146#ifdef CONFIG_PM_SYSFS_DEPRECATED
147 &dev_attr_state.attr,
148#endif
149 &dev_attr_wakeup.attr, 83 &dev_attr_wakeup.attr,
150 NULL, 84 NULL,
151}; 85};
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 41476abc0693..db703758db98 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -224,6 +224,7 @@ ohci_update_phy_reg(struct fw_card *card, int addr,
224 u32 val, old; 224 u32 val, old;
225 225
226 reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); 226 reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr));
227 flush_writes(ohci);
227 msleep(2); 228 msleep(2);
228 val = reg_read(ohci, OHCI1394_PhyControl); 229 val = reg_read(ohci, OHCI1394_PhyControl);
229 if ((val & OHCI1394_PhyControl_ReadDone) == 0) { 230 if ((val & OHCI1394_PhyControl_ReadDone) == 0) {
@@ -586,7 +587,7 @@ static void context_stop(struct context *ctx)
586 break; 587 break;
587 588
588 fw_notify("context_stop: still active (0x%08x)\n", reg); 589 fw_notify("context_stop: still active (0x%08x)\n", reg);
589 msleep(1); 590 mdelay(1);
590 } 591 }
591} 592}
592 593
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 7c53be0387fb..fc984474162c 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -840,7 +840,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
840 container_of(base_orb, struct sbp2_command_orb, base); 840 container_of(base_orb, struct sbp2_command_orb, base);
841 struct fw_unit *unit = orb->unit; 841 struct fw_unit *unit = orb->unit;
842 struct fw_device *device = fw_device(unit->device.parent); 842 struct fw_device *device = fw_device(unit->device.parent);
843 struct scatterlist *sg;
844 int result; 843 int result;
845 844
846 if (status != NULL) { 845 if (status != NULL) {
@@ -876,11 +875,10 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
876 dma_unmap_single(device->card->device, orb->base.request_bus, 875 dma_unmap_single(device->card->device, orb->base.request_bus,
877 sizeof(orb->request), DMA_TO_DEVICE); 876 sizeof(orb->request), DMA_TO_DEVICE);
878 877
879 if (orb->cmd->use_sg > 0) { 878 if (scsi_sg_count(orb->cmd) > 0)
880 sg = (struct scatterlist *)orb->cmd->request_buffer; 879 dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
881 dma_unmap_sg(device->card->device, sg, orb->cmd->use_sg, 880 scsi_sg_count(orb->cmd),
882 orb->cmd->sc_data_direction); 881 orb->cmd->sc_data_direction);
883 }
884 882
885 if (orb->page_table_bus != 0) 883 if (orb->page_table_bus != 0)
886 dma_unmap_single(device->card->device, orb->page_table_bus, 884 dma_unmap_single(device->card->device, orb->page_table_bus,
@@ -901,8 +899,8 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
901 int sg_len, l, i, j, count; 899 int sg_len, l, i, j, count;
902 dma_addr_t sg_addr; 900 dma_addr_t sg_addr;
903 901
904 sg = (struct scatterlist *)orb->cmd->request_buffer; 902 sg = scsi_sglist(orb->cmd);
905 count = dma_map_sg(device->card->device, sg, orb->cmd->use_sg, 903 count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
906 orb->cmd->sc_data_direction); 904 orb->cmd->sc_data_direction);
907 if (count == 0) 905 if (count == 0)
908 goto fail; 906 goto fail;
@@ -971,7 +969,7 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
971 return 0; 969 return 0;
972 970
973 fail_page_table: 971 fail_page_table:
974 dma_unmap_sg(device->card->device, sg, orb->cmd->use_sg, 972 dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
975 orb->cmd->sc_data_direction); 973 orb->cmd->sc_data_direction);
976 fail: 974 fail:
977 return -ENOMEM; 975 return -ENOMEM;
@@ -1031,7 +1029,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1031 orb->request.misc |= 1029 orb->request.misc |=
1032 COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); 1030 COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
1033 1031
1034 if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) 1032 if (scsi_sg_count(cmd) && sbp2_command_orb_map_scatterlist(orb) < 0)
1035 goto fail_mapping; 1033 goto fail_mapping;
1036 1034
1037 fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); 1035 fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 80d0121463d0..3ce8e2fbe15f 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -605,8 +605,10 @@ fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
605 * check is sufficient to ensure we don't send response to 605 * check is sufficient to ensure we don't send response to
606 * broadcast packets or posted writes. 606 * broadcast packets or posted writes.
607 */ 607 */
608 if (request->ack != ACK_PENDING) 608 if (request->ack != ACK_PENDING) {
609 kfree(request);
609 return; 610 return;
611 }
610 612
611 if (rcode == RCODE_COMPLETE) 613 if (rcode == RCODE_COMPLETE)
612 fw_fill_response(&request->response, request->request_header, 614 fw_fill_response(&request->response, request->request_header,
@@ -628,11 +630,6 @@ fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
628 unsigned long flags; 630 unsigned long flags;
629 int tcode, destination, source; 631 int tcode, destination, source;
630 632
631 if (p->payload_length > 2048) {
632 /* FIXME: send error response. */
633 return;
634 }
635
636 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) 633 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
637 return; 634 return;
638 635
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 5abed193f4a6..5ceaccd10564 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -123,6 +123,10 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
123 size_t length, 123 size_t length,
124 void *callback_data); 124 void *callback_data);
125 125
126/*
127 * Important note: The callback must guarantee that either fw_send_response()
128 * or kfree() is called on the @request.
129 */
126typedef void (*fw_address_callback_t)(struct fw_card *card, 130typedef void (*fw_address_callback_t)(struct fw_card *card,
127 struct fw_request *request, 131 struct fw_request *request,
128 int tcode, int destination, int source, 132 int tcode, int destination, int source,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 9820c67ba47d..4df269f5d9ac 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3374,7 +3374,7 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
3374} 3374}
3375EXPORT_SYMBOL(ib_cm_init_qp_attr); 3375EXPORT_SYMBOL(ib_cm_init_qp_attr);
3376 3376
3377void cm_get_ack_delay(struct cm_device *cm_dev) 3377static void cm_get_ack_delay(struct cm_device *cm_dev)
3378{ 3378{
3379 struct ib_device_attr attr; 3379 struct ib_device_attr attr;
3380 3380
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 23af7a032a03..9ffb9987450a 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -573,7 +573,7 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
573 break; 573 break;
574 case RDMA_TRANSPORT_IWARP: 574 case RDMA_TRANSPORT_IWARP:
575 if (!id_priv->cm_id.iw) { 575 if (!id_priv->cm_id.iw) {
576 qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE; 576 qp_attr->qp_access_flags = 0;
577 *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS; 577 *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS;
578 } else 578 } else
579 ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr, 579 ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 3b41dc0c39dd..5dc68cd5621b 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1914,6 +1914,7 @@ int iwch_create_listen(struct iw_cm_id *cm_id, int backlog)
1914fail3: 1914fail3:
1915 cxgb3_free_stid(ep->com.tdev, ep->stid); 1915 cxgb3_free_stid(ep->com.tdev, ep->stid);
1916fail2: 1916fail2:
1917 cm_id->rem_ref(cm_id);
1917 put_ep(&ep->com); 1918 put_ep(&ep->com);
1918fail1: 1919fail1:
1919out: 1920out:
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 3cd6bf3402d1..e53a97af1260 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -79,7 +79,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
79 av->av.ipd = (ah_mult > 0) ? 79 av->av.ipd = (ah_mult > 0) ?
80 ((ehca_mult - 1) / ah_mult) : 0; 80 ((ehca_mult - 1) / ah_mult) : 0;
81 } else 81 } else
82 av->av.ipd = ehca_static_rate; 82 av->av.ipd = ehca_static_rate;
83 83
84 av->av.lnh = ah_attr->ah_flags; 84 av->av.lnh = ah_attr->ah_flags;
85 av->av.grh.word_0 = EHCA_BMASK_SET(GRH_IPVERSION_MASK, 6); 85 av->av.grh.word_0 = EHCA_BMASK_SET(GRH_IPVERSION_MASK, 6);
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index daf823ea1ace..043e4fb23fb0 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -204,11 +204,11 @@ struct ehca_mr {
204 spinlock_t mrlock; 204 spinlock_t mrlock;
205 205
206 enum ehca_mr_flag flags; 206 enum ehca_mr_flag flags;
207 u32 num_pages; /* number of MR pages */ 207 u32 num_kpages; /* number of kernel pages */
208 u32 num_4k; /* number of 4k "page" portions to form MR */ 208 u32 num_hwpages; /* number of hw pages to form MR */
209 int acl; /* ACL (stored here for usage in reregister) */ 209 int acl; /* ACL (stored here for usage in reregister) */
210 u64 *start; /* virtual start address (stored here for */ 210 u64 *start; /* virtual start address (stored here for */
211 /* usage in reregister) */ 211 /* usage in reregister) */
212 u64 size; /* size (stored here for usage in reregister) */ 212 u64 size; /* size (stored here for usage in reregister) */
213 u32 fmr_page_size; /* page size for FMR */ 213 u32 fmr_page_size; /* page size for FMR */
214 u32 fmr_max_pages; /* max pages for FMR */ 214 u32 fmr_max_pages; /* max pages for FMR */
@@ -217,9 +217,6 @@ struct ehca_mr {
217 /* fw specific data */ 217 /* fw specific data */
218 struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */ 218 struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */
219 struct h_galpas galpas; 219 struct h_galpas galpas;
220 /* data for userspace bridge */
221 u32 nr_of_pages;
222 void *pagearray;
223}; 220};
224 221
225struct ehca_mw { 222struct ehca_mw {
@@ -241,26 +238,29 @@ enum ehca_mr_pgi_type {
241 238
242struct ehca_mr_pginfo { 239struct ehca_mr_pginfo {
243 enum ehca_mr_pgi_type type; 240 enum ehca_mr_pgi_type type;
244 u64 num_pages; 241 u64 num_kpages;
245 u64 page_cnt; 242 u64 kpage_cnt;
246 u64 num_4k; /* number of 4k "page" portions */ 243 u64 num_hwpages; /* number of hw pages */
247 u64 page_4k_cnt; /* counter for 4k "page" portions */ 244 u64 hwpage_cnt; /* counter for hw pages */
248 u64 next_4k; /* next 4k "page" portion in buffer/chunk/listelem */ 245 u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
249 246
250 /* type EHCA_MR_PGI_PHYS section */ 247 union {
251 int num_phys_buf; 248 struct { /* type EHCA_MR_PGI_PHYS section */
252 struct ib_phys_buf *phys_buf_array; 249 int num_phys_buf;
253 u64 next_buf; 250 struct ib_phys_buf *phys_buf_array;
254 251 u64 next_buf;
255 /* type EHCA_MR_PGI_USER section */ 252 } phy;
256 struct ib_umem *region; 253 struct { /* type EHCA_MR_PGI_USER section */
257 struct ib_umem_chunk *next_chunk; 254 struct ib_umem *region;
258 u64 next_nmap; 255 struct ib_umem_chunk *next_chunk;
259 256 u64 next_nmap;
260 /* type EHCA_MR_PGI_FMR section */ 257 } usr;
261 u64 *page_list; 258 struct { /* type EHCA_MR_PGI_FMR section */
262 u64 next_listelem; 259 u64 fmr_pgsize;
263 /* next_4k also used within EHCA_MR_PGI_FMR */ 260 u64 *page_list;
261 u64 next_listelem;
262 } fmr;
263 } u;
264}; 264};
265 265
266/* output parameters for MR/FMR hipz calls */ 266/* output parameters for MR/FMR hipz calls */
@@ -391,6 +391,6 @@ struct ehca_alloc_qp_parms {
391 391
392int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp); 392int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
393int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num); 393int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num);
394struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int qp_num); 394struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
395 395
396#endif 396#endif
diff --git a/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
index fb3df5c271e7..1798e6466bd0 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes_pSeries.h
@@ -154,83 +154,83 @@ struct hcp_modify_qp_control_block {
154 u32 reserved_70_127[58]; /* 70 */ 154 u32 reserved_70_127[58]; /* 70 */
155}; 155};
156 156
157#define MQPCB_MASK_QKEY EHCA_BMASK_IBM(0,0) 157#define MQPCB_MASK_QKEY EHCA_BMASK_IBM( 0, 0)
158#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM(2,2) 158#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM( 2, 2)
159#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM(3,3) 159#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM( 3, 3)
160#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM(4,4) 160#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM( 4, 4)
161#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24,31) 161#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24, 31)
162#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM(5,5) 162#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM( 5, 5)
163#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM(6,6) 163#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM( 6, 6)
164#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24,31) 164#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24, 31)
165#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM(7,7) 165#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM( 7, 7)
166#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM(8,8) 166#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM( 8, 8)
167#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM(9,9) 167#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM( 9, 9)
168#define MQPCB_QP_STATE EHCA_BMASK_IBM(24,31) 168#define MQPCB_QP_STATE EHCA_BMASK_IBM(24, 31)
169#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11,11) 169#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11, 11)
170#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12,12) 170#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12, 12)
171#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13,13) 171#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13, 13)
172#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14,14) 172#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14, 14)
173#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15,15) 173#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15, 15)
174#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16,16) 174#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16, 16)
175#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17,17) 175#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17, 17)
176#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18,18) 176#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18, 18)
177#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19,19) 177#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19, 19)
178#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20,20) 178#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20, 20)
179#define MQPCB_PATH_MTU EHCA_BMASK_IBM(24,31) 179#define MQPCB_PATH_MTU EHCA_BMASK_IBM(24, 31)
180#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21,21) 180#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21, 21)
181#define MQPCB_MAX_STATIC_RATE EHCA_BMASK_IBM(24,31) 181#define MQPCB_MAX_STATIC_RATE EHCA_BMASK_IBM(24, 31)
182#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22,22) 182#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22, 22)
183#define MQPCB_DLID EHCA_BMASK_IBM(16,31) 183#define MQPCB_DLID EHCA_BMASK_IBM(16, 31)
184#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23,23) 184#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23, 23)
185#define MQPCB_RNR_RETRY_COUNT EHCA_BMASK_IBM(29,31) 185#define MQPCB_RNR_RETRY_COUNT EHCA_BMASK_IBM(29, 31)
186#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24,24) 186#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24, 24)
187#define MQPCB_SOURCE_PATH_BITS EHCA_BMASK_IBM(25,31) 187#define MQPCB_SOURCE_PATH_BITS EHCA_BMASK_IBM(25, 31)
188#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25,25) 188#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25, 25)
189#define MQPCB_TRAFFIC_CLASS EHCA_BMASK_IBM(24,31) 189#define MQPCB_TRAFFIC_CLASS EHCA_BMASK_IBM(24, 31)
190#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26,26) 190#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26, 26)
191#define MQPCB_HOP_LIMIT EHCA_BMASK_IBM(24,31) 191#define MQPCB_HOP_LIMIT EHCA_BMASK_IBM(24, 31)
192#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27,27) 192#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27, 27)
193#define MQPCB_SOURCE_GID_IDX EHCA_BMASK_IBM(24,31) 193#define MQPCB_SOURCE_GID_IDX EHCA_BMASK_IBM(24, 31)
194#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28,28) 194#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28, 28)
195#define MQPCB_FLOW_LABEL EHCA_BMASK_IBM(12,31) 195#define MQPCB_FLOW_LABEL EHCA_BMASK_IBM(12, 31)
196#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30,30) 196#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30, 30)
197#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31,31) 197#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31, 31)
198#define MQPCB_SERVICE_LEVEL_AL EHCA_BMASK_IBM(28,31) 198#define MQPCB_SERVICE_LEVEL_AL EHCA_BMASK_IBM(28, 31)
199#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32,32) 199#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32, 32)
200#define MQPCB_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(31,31) 200#define MQPCB_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(31, 31)
201#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33,33) 201#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33, 33)
202#define MQPCB_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31) 202#define MQPCB_RETRY_COUNT_AL EHCA_BMASK_IBM(29, 31)
203#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34,34) 203#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34, 34)
204#define MQPCB_TIMEOUT_AL EHCA_BMASK_IBM(27,31) 204#define MQPCB_TIMEOUT_AL EHCA_BMASK_IBM(27, 31)
205#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35,35) 205#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35, 35)
206#define MQPCB_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(24,31) 206#define MQPCB_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(24, 31)
207#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36,36) 207#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36, 36)
208#define MQPCB_DLID_AL EHCA_BMASK_IBM(16,31) 208#define MQPCB_DLID_AL EHCA_BMASK_IBM(16, 31)
209#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37,37) 209#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37, 37)
210#define MQPCB_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(29,31) 210#define MQPCB_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(29, 31)
211#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38,38) 211#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38, 38)
212#define MQPCB_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(25,31) 212#define MQPCB_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(25, 31)
213#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39,39) 213#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39, 39)
214#define MQPCB_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(24,31) 214#define MQPCB_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(24, 31)
215#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40,40) 215#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40, 40)
216#define MQPCB_HOP_LIMIT_AL EHCA_BMASK_IBM(24,31) 216#define MQPCB_HOP_LIMIT_AL EHCA_BMASK_IBM(24, 31)
217#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41,41) 217#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41, 41)
218#define MQPCB_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(24,31) 218#define MQPCB_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(24, 31)
219#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42,42) 219#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42, 42)
220#define MQPCB_FLOW_LABEL_AL EHCA_BMASK_IBM(12,31) 220#define MQPCB_FLOW_LABEL_AL EHCA_BMASK_IBM(12, 31)
221#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44,44) 221#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44, 44)
222#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45,45) 222#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45, 45)
223#define MQPCB_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(16,31) 223#define MQPCB_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
224#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46,46) 224#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46, 46)
225#define MQPCB_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(16,31) 225#define MQPCB_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
226#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47,47) 226#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47, 47)
227#define MQPCB_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(31,31) 227#define MQPCB_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(31, 31)
228#define MQPCB_QP_NUMBER EHCA_BMASK_IBM(8,31) 228#define MQPCB_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
229#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48,48) 229#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48, 48)
230#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31,31) 230#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31, 31)
231#define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49,49) 231#define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49, 49)
232#define MQPCB_CURR_SRQ_LIMIT EHCA_BMASK_IBM(16,31) 232#define MQPCB_CURR_SRQ_LIMIT EHCA_BMASK_IBM(16, 31)
233#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50,50) 233#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50, 50)
234#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51,51) 234#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51, 51)
235 235
236#endif /* __EHCA_CLASSES_PSERIES_H__ */ 236#endif /* __EHCA_CLASSES_PSERIES_H__ */
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 01d4a148bd71..9e87883b561a 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -97,7 +97,7 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
97 return ret; 97 return ret;
98} 98}
99 99
100struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num) 100struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
101{ 101{
102 struct ehca_qp *ret = NULL; 102 struct ehca_qp *ret = NULL;
103 unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1); 103 unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 4961eb88827c..4825975f88cf 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -96,7 +96,8 @@ int ehca_create_eq(struct ehca_shca *shca,
96 for (i = 0; i < nr_pages; i++) { 96 for (i = 0; i < nr_pages; i++) {
97 u64 rpage; 97 u64 rpage;
98 98
99 if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) { 99 vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
100 if (!vpage) {
100 ret = H_RESOURCE; 101 ret = H_RESOURCE;
101 goto create_eq_exit2; 102 goto create_eq_exit2;
102 } 103 }
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index bbd3c6a5822f..fc19ef9fd963 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -127,6 +127,7 @@ int ehca_query_port(struct ib_device *ibdev,
127 u8 port, struct ib_port_attr *props) 127 u8 port, struct ib_port_attr *props)
128{ 128{
129 int ret = 0; 129 int ret = 0;
130 u64 h_ret;
130 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, 131 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
131 ib_device); 132 ib_device);
132 struct hipz_query_port *rblock; 133 struct hipz_query_port *rblock;
@@ -137,7 +138,8 @@ int ehca_query_port(struct ib_device *ibdev,
137 return -ENOMEM; 138 return -ENOMEM;
138 } 139 }
139 140
140 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { 141 h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
142 if (h_ret != H_SUCCESS) {
141 ehca_err(&shca->ib_device, "Can't query port properties"); 143 ehca_err(&shca->ib_device, "Can't query port properties");
142 ret = -EINVAL; 144 ret = -EINVAL;
143 goto query_port1; 145 goto query_port1;
@@ -197,6 +199,7 @@ int ehca_query_sma_attr(struct ehca_shca *shca,
197 u8 port, struct ehca_sma_attr *attr) 199 u8 port, struct ehca_sma_attr *attr)
198{ 200{
199 int ret = 0; 201 int ret = 0;
202 u64 h_ret;
200 struct hipz_query_port *rblock; 203 struct hipz_query_port *rblock;
201 204
202 rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC); 205 rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC);
@@ -205,7 +208,8 @@ int ehca_query_sma_attr(struct ehca_shca *shca,
205 return -ENOMEM; 208 return -ENOMEM;
206 } 209 }
207 210
208 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { 211 h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
212 if (h_ret != H_SUCCESS) {
209 ehca_err(&shca->ib_device, "Can't query port properties"); 213 ehca_err(&shca->ib_device, "Can't query port properties");
210 ret = -EINVAL; 214 ret = -EINVAL;
211 goto query_sma_attr1; 215 goto query_sma_attr1;
@@ -230,9 +234,11 @@ query_sma_attr1:
230int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) 234int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
231{ 235{
232 int ret = 0; 236 int ret = 0;
233 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); 237 u64 h_ret;
238 struct ehca_shca *shca;
234 struct hipz_query_port *rblock; 239 struct hipz_query_port *rblock;
235 240
241 shca = container_of(ibdev, struct ehca_shca, ib_device);
236 if (index > 16) { 242 if (index > 16) {
237 ehca_err(&shca->ib_device, "Invalid index: %x.", index); 243 ehca_err(&shca->ib_device, "Invalid index: %x.", index);
238 return -EINVAL; 244 return -EINVAL;
@@ -244,7 +250,8 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
244 return -ENOMEM; 250 return -ENOMEM;
245 } 251 }
246 252
247 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { 253 h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
254 if (h_ret != H_SUCCESS) {
248 ehca_err(&shca->ib_device, "Can't query port properties"); 255 ehca_err(&shca->ib_device, "Can't query port properties");
249 ret = -EINVAL; 256 ret = -EINVAL;
250 goto query_pkey1; 257 goto query_pkey1;
@@ -262,6 +269,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
262 int index, union ib_gid *gid) 269 int index, union ib_gid *gid)
263{ 270{
264 int ret = 0; 271 int ret = 0;
272 u64 h_ret;
265 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, 273 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
266 ib_device); 274 ib_device);
267 struct hipz_query_port *rblock; 275 struct hipz_query_port *rblock;
@@ -277,7 +285,8 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port,
277 return -ENOMEM; 285 return -ENOMEM;
278 } 286 }
279 287
280 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { 288 h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
289 if (h_ret != H_SUCCESS) {
281 ehca_err(&shca->ib_device, "Can't query port properties"); 290 ehca_err(&shca->ib_device, "Can't query port properties");
282 ret = -EINVAL; 291 ret = -EINVAL;
283 goto query_gid1; 292 goto query_gid1;
@@ -302,11 +311,12 @@ int ehca_modify_port(struct ib_device *ibdev,
302 struct ib_port_modify *props) 311 struct ib_port_modify *props)
303{ 312{
304 int ret = 0; 313 int ret = 0;
305 struct ehca_shca *shca = container_of(ibdev, struct ehca_shca, ib_device); 314 struct ehca_shca *shca;
306 struct hipz_query_port *rblock; 315 struct hipz_query_port *rblock;
307 u32 cap; 316 u32 cap;
308 u64 hret; 317 u64 hret;
309 318
319 shca = container_of(ibdev, struct ehca_shca, ib_device);
310 if ((props->set_port_cap_mask | props->clr_port_cap_mask) 320 if ((props->set_port_cap_mask | props->clr_port_cap_mask)
311 & ~allowed_port_caps) { 321 & ~allowed_port_caps) {
312 ehca_err(&shca->ib_device, "Non-changeable bits set in masks " 322 ehca_err(&shca->ib_device, "Non-changeable bits set in masks "
@@ -325,7 +335,8 @@ int ehca_modify_port(struct ib_device *ibdev,
325 goto modify_port1; 335 goto modify_port1;
326 } 336 }
327 337
328 if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) { 338 hret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
339 if (hret != H_SUCCESS) {
329 ehca_err(&shca->ib_device, "Can't query port properties"); 340 ehca_err(&shca->ib_device, "Can't query port properties");
330 ret = -EINVAL; 341 ret = -EINVAL;
331 goto modify_port2; 342 goto modify_port2;
@@ -337,7 +348,8 @@ int ehca_modify_port(struct ib_device *ibdev,
337 hret = hipz_h_modify_port(shca->ipz_hca_handle, port, 348 hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
338 cap, props->init_type, port_modify_mask); 349 cap, props->init_type, port_modify_mask);
339 if (hret != H_SUCCESS) { 350 if (hret != H_SUCCESS) {
340 ehca_err(&shca->ib_device, "Modify port failed hret=%lx", hret); 351 ehca_err(&shca->ib_device, "Modify port failed hret=%lx",
352 hret);
341 ret = -EINVAL; 353 ret = -EINVAL;
342 } 354 }
343 355
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 96eba3830754..4fb01fcb63ae 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -49,26 +49,26 @@
49#include "hipz_fns.h" 49#include "hipz_fns.h"
50#include "ipz_pt_fn.h" 50#include "ipz_pt_fn.h"
51 51
52#define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) 52#define EQE_COMPLETION_EVENT EHCA_BMASK_IBM( 1, 1)
53#define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) 53#define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
54#define EQE_EE_IDENTIFIER EHCA_BMASK_IBM(2,7) 54#define EQE_EE_IDENTIFIER EHCA_BMASK_IBM( 2, 7)
55#define EQE_CQ_NUMBER EHCA_BMASK_IBM(8,31) 55#define EQE_CQ_NUMBER EHCA_BMASK_IBM( 8, 31)
56#define EQE_QP_NUMBER EHCA_BMASK_IBM(8,31) 56#define EQE_QP_NUMBER EHCA_BMASK_IBM( 8, 31)
57#define EQE_QP_TOKEN EHCA_BMASK_IBM(32,63) 57#define EQE_QP_TOKEN EHCA_BMASK_IBM(32, 63)
58#define EQE_CQ_TOKEN EHCA_BMASK_IBM(32,63) 58#define EQE_CQ_TOKEN EHCA_BMASK_IBM(32, 63)
59 59
60#define NEQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) 60#define NEQE_COMPLETION_EVENT EHCA_BMASK_IBM( 1, 1)
61#define NEQE_EVENT_CODE EHCA_BMASK_IBM(2,7) 61#define NEQE_EVENT_CODE EHCA_BMASK_IBM( 2, 7)
62#define NEQE_PORT_NUMBER EHCA_BMASK_IBM(8,15) 62#define NEQE_PORT_NUMBER EHCA_BMASK_IBM( 8, 15)
63#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16,16) 63#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16, 16)
64#define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16,16) 64#define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16, 16)
65 65
66#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63) 66#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52, 63)
67#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7) 67#define ERROR_DATA_TYPE EHCA_BMASK_IBM( 0, 7)
68 68
69static void queue_comp_task(struct ehca_cq *__cq); 69static void queue_comp_task(struct ehca_cq *__cq);
70 70
71static struct ehca_comp_pool* pool; 71static struct ehca_comp_pool *pool;
72#ifdef CONFIG_HOTPLUG_CPU 72#ifdef CONFIG_HOTPLUG_CPU
73static struct notifier_block comp_pool_callback_nb; 73static struct notifier_block comp_pool_callback_nb;
74#endif 74#endif
@@ -85,8 +85,8 @@ static inline void comp_event_callback(struct ehca_cq *cq)
85 return; 85 return;
86} 86}
87 87
88static void print_error_data(struct ehca_shca * shca, void* data, 88static void print_error_data(struct ehca_shca *shca, void *data,
89 u64* rblock, int length) 89 u64 *rblock, int length)
90{ 90{
91 u64 type = EHCA_BMASK_GET(ERROR_DATA_TYPE, rblock[2]); 91 u64 type = EHCA_BMASK_GET(ERROR_DATA_TYPE, rblock[2]);
92 u64 resource = rblock[1]; 92 u64 resource = rblock[1];
@@ -94,7 +94,7 @@ static void print_error_data(struct ehca_shca * shca, void* data,
94 switch (type) { 94 switch (type) {
95 case 0x1: /* Queue Pair */ 95 case 0x1: /* Queue Pair */
96 { 96 {
97 struct ehca_qp *qp = (struct ehca_qp*)data; 97 struct ehca_qp *qp = (struct ehca_qp *)data;
98 98
99 /* only print error data if AER is set */ 99 /* only print error data if AER is set */
100 if (rblock[6] == 0) 100 if (rblock[6] == 0)
@@ -107,7 +107,7 @@ static void print_error_data(struct ehca_shca * shca, void* data,
107 } 107 }
108 case 0x4: /* Completion Queue */ 108 case 0x4: /* Completion Queue */
109 { 109 {
110 struct ehca_cq *cq = (struct ehca_cq*)data; 110 struct ehca_cq *cq = (struct ehca_cq *)data;
111 111
112 ehca_err(&shca->ib_device, 112 ehca_err(&shca->ib_device,
113 "CQ 0x%x (resource=%lx) has errors.", 113 "CQ 0x%x (resource=%lx) has errors.",
@@ -572,7 +572,7 @@ void ehca_tasklet_eq(unsigned long data)
572 ehca_process_eq((struct ehca_shca*)data, 1); 572 ehca_process_eq((struct ehca_shca*)data, 1);
573} 573}
574 574
575static inline int find_next_online_cpu(struct ehca_comp_pool* pool) 575static inline int find_next_online_cpu(struct ehca_comp_pool *pool)
576{ 576{
577 int cpu; 577 int cpu;
578 unsigned long flags; 578 unsigned long flags;
@@ -636,7 +636,7 @@ static void queue_comp_task(struct ehca_cq *__cq)
636 __queue_comp_task(__cq, cct); 636 __queue_comp_task(__cq, cct);
637} 637}
638 638
639static void run_comp_task(struct ehca_cpu_comp_task* cct) 639static void run_comp_task(struct ehca_cpu_comp_task *cct)
640{ 640{
641 struct ehca_cq *cq; 641 struct ehca_cq *cq;
642 unsigned long flags; 642 unsigned long flags;
@@ -666,12 +666,12 @@ static void run_comp_task(struct ehca_cpu_comp_task* cct)
666 666
667static int comp_task(void *__cct) 667static int comp_task(void *__cct)
668{ 668{
669 struct ehca_cpu_comp_task* cct = __cct; 669 struct ehca_cpu_comp_task *cct = __cct;
670 int cql_empty; 670 int cql_empty;
671 DECLARE_WAITQUEUE(wait, current); 671 DECLARE_WAITQUEUE(wait, current);
672 672
673 set_current_state(TASK_INTERRUPTIBLE); 673 set_current_state(TASK_INTERRUPTIBLE);
674 while(!kthread_should_stop()) { 674 while (!kthread_should_stop()) {
675 add_wait_queue(&cct->wait_queue, &wait); 675 add_wait_queue(&cct->wait_queue, &wait);
676 676
677 spin_lock_irq(&cct->task_lock); 677 spin_lock_irq(&cct->task_lock);
@@ -745,7 +745,7 @@ static void take_over_work(struct ehca_comp_pool *pool,
745 745
746 list_splice_init(&cct->cq_list, &list); 746 list_splice_init(&cct->cq_list, &list);
747 747
748 while(!list_empty(&list)) { 748 while (!list_empty(&list)) {
749 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); 749 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
750 750
751 list_del(&cq->entry); 751 list_del(&cq->entry);
@@ -768,7 +768,7 @@ static int comp_pool_callback(struct notifier_block *nfb,
768 case CPU_UP_PREPARE: 768 case CPU_UP_PREPARE:
769 case CPU_UP_PREPARE_FROZEN: 769 case CPU_UP_PREPARE_FROZEN:
770 ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); 770 ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu);
771 if(!create_comp_task(pool, cpu)) { 771 if (!create_comp_task(pool, cpu)) {
772 ehca_gen_err("Can't create comp_task for cpu: %x", cpu); 772 ehca_gen_err("Can't create comp_task for cpu: %x", cpu);
773 return NOTIFY_BAD; 773 return NOTIFY_BAD;
774 } 774 }
@@ -838,7 +838,7 @@ int ehca_create_comp_pool(void)
838 838
839#ifdef CONFIG_HOTPLUG_CPU 839#ifdef CONFIG_HOTPLUG_CPU
840 comp_pool_callback_nb.notifier_call = comp_pool_callback; 840 comp_pool_callback_nb.notifier_call = comp_pool_callback;
841 comp_pool_callback_nb.priority =0; 841 comp_pool_callback_nb.priority = 0;
842 register_cpu_notifier(&comp_pool_callback_nb); 842 register_cpu_notifier(&comp_pool_callback_nb);
843#endif 843#endif
844 844
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index 77aeca6a2c2f..dce503bb7d6b 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -81,8 +81,9 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
81 int num_phys_buf, 81 int num_phys_buf,
82 int mr_access_flags, u64 *iova_start); 82 int mr_access_flags, u64 *iova_start);
83 83
84struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt, 84struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
85 int mr_access_flags, struct ib_udata *udata); 85 u64 virt, int mr_access_flags,
86 struct ib_udata *udata);
86 87
87int ehca_rereg_phys_mr(struct ib_mr *mr, 88int ehca_rereg_phys_mr(struct ib_mr *mr,
88 int mr_rereg_mask, 89 int mr_rereg_mask,
@@ -192,7 +193,7 @@ void ehca_poll_eqs(unsigned long data);
192void *ehca_alloc_fw_ctrlblock(gfp_t flags); 193void *ehca_alloc_fw_ctrlblock(gfp_t flags);
193void ehca_free_fw_ctrlblock(void *ptr); 194void ehca_free_fw_ctrlblock(void *ptr);
194#else 195#else
195#define ehca_alloc_fw_ctrlblock(flags) ((void *) get_zeroed_page(flags)) 196#define ehca_alloc_fw_ctrlblock(flags) ((void *)get_zeroed_page(flags))
196#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) 197#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr))
197#endif 198#endif
198 199
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 28ba2dd24216..36377c6db3d4 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -107,7 +107,7 @@ static DEFINE_SPINLOCK(shca_list_lock);
107static struct timer_list poll_eqs_timer; 107static struct timer_list poll_eqs_timer;
108 108
109#ifdef CONFIG_PPC_64K_PAGES 109#ifdef CONFIG_PPC_64K_PAGES
110static struct kmem_cache *ctblk_cache = NULL; 110static struct kmem_cache *ctblk_cache;
111 111
112void *ehca_alloc_fw_ctrlblock(gfp_t flags) 112void *ehca_alloc_fw_ctrlblock(gfp_t flags)
113{ 113{
@@ -200,8 +200,8 @@ static void ehca_destroy_slab_caches(void)
200#endif 200#endif
201} 201}
202 202
203#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) 203#define EHCA_HCAAVER EHCA_BMASK_IBM(32, 39)
204#define EHCA_REVID EHCA_BMASK_IBM(40,63) 204#define EHCA_REVID EHCA_BMASK_IBM(40, 63)
205 205
206static struct cap_descr { 206static struct cap_descr {
207 u64 mask; 207 u64 mask;
@@ -263,22 +263,27 @@ int ehca_sense_attributes(struct ehca_shca *shca)
263 263
264 ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid); 264 ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
265 265
266 if ((hcaaver == 1) && (revid == 0)) 266 if (hcaaver == 1) {
267 shca->hw_level = 0x11; 267 if (revid <= 3)
268 else if ((hcaaver == 1) && (revid == 1)) 268 shca->hw_level = 0x10 | (revid + 1);
269 shca->hw_level = 0x12; 269 else
270 else if ((hcaaver == 1) && (revid == 2)) 270 shca->hw_level = 0x14;
271 shca->hw_level = 0x13; 271 } else if (hcaaver == 2) {
272 else if ((hcaaver == 2) && (revid == 0)) 272 if (revid == 0)
273 shca->hw_level = 0x21; 273 shca->hw_level = 0x21;
274 else if ((hcaaver == 2) && (revid == 0x10)) 274 else if (revid == 0x10)
275 shca->hw_level = 0x22; 275 shca->hw_level = 0x22;
276 else { 276 else if (revid == 0x20 || revid == 0x21)
277 shca->hw_level = 0x23;
278 }
279
280 if (!shca->hw_level) {
277 ehca_gen_warn("unknown hardware version" 281 ehca_gen_warn("unknown hardware version"
278 " - assuming default level"); 282 " - assuming default level");
279 shca->hw_level = 0x22; 283 shca->hw_level = 0x22;
280 } 284 }
281 } 285 } else
286 shca->hw_level = ehca_hw_level;
282 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level); 287 ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
283 288
284 shca->sport[0].rate = IB_RATE_30_GBPS; 289 shca->sport[0].rate = IB_RATE_30_GBPS;
@@ -290,7 +295,7 @@ int ehca_sense_attributes(struct ehca_shca *shca)
290 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) 295 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
291 ehca_gen_dbg(" %s", hca_cap_descr[i].descr); 296 ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
292 297
293 port = (struct hipz_query_port *) rblock; 298 port = (struct hipz_query_port *)rblock;
294 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); 299 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
295 if (h_ret != H_SUCCESS) { 300 if (h_ret != H_SUCCESS) {
296 ehca_gen_err("Cannot query port properties. h_ret=%lx", 301 ehca_gen_err("Cannot query port properties. h_ret=%lx",
@@ -439,7 +444,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
439 return -EPERM; 444 return -EPERM;
440 } 445 }
441 446
442 ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0); 447 ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void *)(-1), 10, 0);
443 if (IS_ERR(ibcq)) { 448 if (IS_ERR(ibcq)) {
444 ehca_err(&shca->ib_device, "Cannot create AQP1 CQ."); 449 ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
445 return PTR_ERR(ibcq); 450 return PTR_ERR(ibcq);
@@ -666,7 +671,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
666 } 671 }
667 672
668 /* create internal protection domain */ 673 /* create internal protection domain */
669 ibpd = ehca_alloc_pd(&shca->ib_device, (void*)(-1), NULL); 674 ibpd = ehca_alloc_pd(&shca->ib_device, (void *)(-1), NULL);
670 if (IS_ERR(ibpd)) { 675 if (IS_ERR(ibpd)) {
671 ehca_err(&shca->ib_device, "Cannot create internal PD."); 676 ehca_err(&shca->ib_device, "Cannot create internal PD.");
672 ret = PTR_ERR(ibpd); 677 ret = PTR_ERR(ibpd);
@@ -863,18 +868,21 @@ int __init ehca_module_init(void)
863 printk(KERN_INFO "eHCA Infiniband Device Driver " 868 printk(KERN_INFO "eHCA Infiniband Device Driver "
864 "(Rel.: SVNEHCA_0023)\n"); 869 "(Rel.: SVNEHCA_0023)\n");
865 870
866 if ((ret = ehca_create_comp_pool())) { 871 ret = ehca_create_comp_pool();
872 if (ret) {
867 ehca_gen_err("Cannot create comp pool."); 873 ehca_gen_err("Cannot create comp pool.");
868 return ret; 874 return ret;
869 } 875 }
870 876
871 if ((ret = ehca_create_slab_caches())) { 877 ret = ehca_create_slab_caches();
878 if (ret) {
872 ehca_gen_err("Cannot create SLAB caches"); 879 ehca_gen_err("Cannot create SLAB caches");
873 ret = -ENOMEM; 880 ret = -ENOMEM;
874 goto module_init1; 881 goto module_init1;
875 } 882 }
876 883
877 if ((ret = ibmebus_register_driver(&ehca_driver))) { 884 ret = ibmebus_register_driver(&ehca_driver);
885 if (ret) {
878 ehca_gen_err("Cannot register eHCA device driver"); 886 ehca_gen_err("Cannot register eHCA device driver");
879 ret = -EINVAL; 887 ret = -EINVAL;
880 goto module_init2; 888 goto module_init2;
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index add79bd44e39..6262c5462d50 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -48,6 +48,11 @@
48#include "hcp_if.h" 48#include "hcp_if.h"
49#include "hipz_hw.h" 49#include "hipz_hw.h"
50 50
51#define NUM_CHUNKS(length, chunk_size) \
52 (((length) + (chunk_size - 1)) / (chunk_size))
53/* max number of rpages (per hcall register_rpages) */
54#define MAX_RPAGES 512
55
51static struct kmem_cache *mr_cache; 56static struct kmem_cache *mr_cache;
52static struct kmem_cache *mw_cache; 57static struct kmem_cache *mw_cache;
53 58
@@ -56,9 +61,9 @@ static struct ehca_mr *ehca_mr_new(void)
56 struct ehca_mr *me; 61 struct ehca_mr *me;
57 62
58 me = kmem_cache_zalloc(mr_cache, GFP_KERNEL); 63 me = kmem_cache_zalloc(mr_cache, GFP_KERNEL);
59 if (me) { 64 if (me)
60 spin_lock_init(&me->mrlock); 65 spin_lock_init(&me->mrlock);
61 } else 66 else
62 ehca_gen_err("alloc failed"); 67 ehca_gen_err("alloc failed");
63 68
64 return me; 69 return me;
@@ -74,9 +79,9 @@ static struct ehca_mw *ehca_mw_new(void)
74 struct ehca_mw *me; 79 struct ehca_mw *me;
75 80
76 me = kmem_cache_zalloc(mw_cache, GFP_KERNEL); 81 me = kmem_cache_zalloc(mw_cache, GFP_KERNEL);
77 if (me) { 82 if (me)
78 spin_lock_init(&me->mwlock); 83 spin_lock_init(&me->mwlock);
79 } else 84 else
80 ehca_gen_err("alloc failed"); 85 ehca_gen_err("alloc failed");
81 86
82 return me; 87 return me;
@@ -106,11 +111,12 @@ struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
106 goto get_dma_mr_exit0; 111 goto get_dma_mr_exit0;
107 } 112 }
108 113
109 ret = ehca_reg_maxmr(shca, e_maxmr, (u64*)KERNELBASE, 114 ret = ehca_reg_maxmr(shca, e_maxmr, (u64 *)KERNELBASE,
110 mr_access_flags, e_pd, 115 mr_access_flags, e_pd,
111 &e_maxmr->ib.ib_mr.lkey, 116 &e_maxmr->ib.ib_mr.lkey,
112 &e_maxmr->ib.ib_mr.rkey); 117 &e_maxmr->ib.ib_mr.rkey);
113 if (ret) { 118 if (ret) {
119 ehca_mr_delete(e_maxmr);
114 ib_mr = ERR_PTR(ret); 120 ib_mr = ERR_PTR(ret);
115 goto get_dma_mr_exit0; 121 goto get_dma_mr_exit0;
116 } 122 }
@@ -144,9 +150,6 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
144 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd); 150 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
145 151
146 u64 size; 152 u64 size;
147 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0};
148 u32 num_pages_mr;
149 u32 num_pages_4k; /* 4k portion "pages" */
150 153
151 if ((num_phys_buf <= 0) || !phys_buf_array) { 154 if ((num_phys_buf <= 0) || !phys_buf_array) {
152 ehca_err(pd->device, "bad input values: num_phys_buf=%x " 155 ehca_err(pd->device, "bad input values: num_phys_buf=%x "
@@ -190,12 +193,6 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
190 goto reg_phys_mr_exit0; 193 goto reg_phys_mr_exit0;
191 } 194 }
192 195
193 /* determine number of MR pages */
194 num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size +
195 PAGE_SIZE - 1) / PAGE_SIZE);
196 num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size +
197 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE);
198
199 /* register MR on HCA */ 196 /* register MR on HCA */
200 if (ehca_mr_is_maxmr(size, iova_start)) { 197 if (ehca_mr_is_maxmr(size, iova_start)) {
201 e_mr->flags |= EHCA_MR_FLAG_MAXMR; 198 e_mr->flags |= EHCA_MR_FLAG_MAXMR;
@@ -207,13 +204,22 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd,
207 goto reg_phys_mr_exit1; 204 goto reg_phys_mr_exit1;
208 } 205 }
209 } else { 206 } else {
210 pginfo.type = EHCA_MR_PGI_PHYS; 207 struct ehca_mr_pginfo pginfo;
211 pginfo.num_pages = num_pages_mr; 208 u32 num_kpages;
212 pginfo.num_4k = num_pages_4k; 209 u32 num_hwpages;
213 pginfo.num_phys_buf = num_phys_buf; 210
214 pginfo.phys_buf_array = phys_buf_array; 211 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size,
215 pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) / 212 PAGE_SIZE);
216 EHCA_PAGESIZE); 213 num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) +
214 size, EHCA_PAGESIZE);
215 memset(&pginfo, 0, sizeof(pginfo));
216 pginfo.type = EHCA_MR_PGI_PHYS;
217 pginfo.num_kpages = num_kpages;
218 pginfo.num_hwpages = num_hwpages;
219 pginfo.u.phy.num_phys_buf = num_phys_buf;
220 pginfo.u.phy.phys_buf_array = phys_buf_array;
221 pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
222 EHCA_PAGESIZE);
217 223
218 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, 224 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
219 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, 225 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -240,18 +246,19 @@ reg_phys_mr_exit0:
240 246
241/*----------------------------------------------------------------------*/ 247/*----------------------------------------------------------------------*/
242 248
243struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt, 249struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
244 int mr_access_flags, struct ib_udata *udata) 250 u64 virt, int mr_access_flags,
251 struct ib_udata *udata)
245{ 252{
246 struct ib_mr *ib_mr; 253 struct ib_mr *ib_mr;
247 struct ehca_mr *e_mr; 254 struct ehca_mr *e_mr;
248 struct ehca_shca *shca = 255 struct ehca_shca *shca =
249 container_of(pd->device, struct ehca_shca, ib_device); 256 container_of(pd->device, struct ehca_shca, ib_device);
250 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd); 257 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
251 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 258 struct ehca_mr_pginfo pginfo;
252 int ret; 259 int ret;
253 u32 num_pages_mr; 260 u32 num_kpages;
254 u32 num_pages_4k; /* 4k portion "pages" */ 261 u32 num_hwpages;
255 262
256 if (!pd) { 263 if (!pd) {
257 ehca_gen_err("bad pd=%p", pd); 264 ehca_gen_err("bad pd=%p", pd);
@@ -289,7 +296,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
289 e_mr->umem = ib_umem_get(pd->uobject->context, start, length, 296 e_mr->umem = ib_umem_get(pd->uobject->context, start, length,
290 mr_access_flags); 297 mr_access_flags);
291 if (IS_ERR(e_mr->umem)) { 298 if (IS_ERR(e_mr->umem)) {
292 ib_mr = (void *) e_mr->umem; 299 ib_mr = (void *)e_mr->umem;
293 goto reg_user_mr_exit1; 300 goto reg_user_mr_exit1;
294 } 301 }
295 302
@@ -301,23 +308,24 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt
301 } 308 }
302 309
303 /* determine number of MR pages */ 310 /* determine number of MR pages */
304 num_pages_mr = (((virt % PAGE_SIZE) + length + PAGE_SIZE - 1) / 311 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
305 PAGE_SIZE); 312 num_hwpages = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length,
306 num_pages_4k = (((virt % EHCA_PAGESIZE) + length + EHCA_PAGESIZE - 1) / 313 EHCA_PAGESIZE);
307 EHCA_PAGESIZE);
308 314
309 /* register MR on HCA */ 315 /* register MR on HCA */
310 pginfo.type = EHCA_MR_PGI_USER; 316 memset(&pginfo, 0, sizeof(pginfo));
311 pginfo.num_pages = num_pages_mr; 317 pginfo.type = EHCA_MR_PGI_USER;
312 pginfo.num_4k = num_pages_4k; 318 pginfo.num_kpages = num_kpages;
313 pginfo.region = e_mr->umem; 319 pginfo.num_hwpages = num_hwpages;
314 pginfo.next_4k = e_mr->umem->offset / EHCA_PAGESIZE; 320 pginfo.u.usr.region = e_mr->umem;
315 pginfo.next_chunk = list_prepare_entry(pginfo.next_chunk, 321 pginfo.next_hwpage = e_mr->umem->offset / EHCA_PAGESIZE;
316 (&e_mr->umem->chunk_list), 322 pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk,
317 list); 323 (&e_mr->umem->chunk_list),
318 324 list);
319 ret = ehca_reg_mr(shca, e_mr, (u64*) virt, length, mr_access_flags, e_pd, 325
320 &pginfo, &e_mr->ib.ib_mr.lkey, &e_mr->ib.ib_mr.rkey); 326 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags,
327 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
328 &e_mr->ib.ib_mr.rkey);
321 if (ret) { 329 if (ret) {
322 ib_mr = ERR_PTR(ret); 330 ib_mr = ERR_PTR(ret);
323 goto reg_user_mr_exit2; 331 goto reg_user_mr_exit2;
@@ -360,9 +368,9 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
360 struct ehca_pd *new_pd; 368 struct ehca_pd *new_pd;
361 u32 tmp_lkey, tmp_rkey; 369 u32 tmp_lkey, tmp_rkey;
362 unsigned long sl_flags; 370 unsigned long sl_flags;
363 u32 num_pages_mr = 0; 371 u32 num_kpages = 0;
364 u32 num_pages_4k = 0; /* 4k portion "pages" */ 372 u32 num_hwpages = 0;
365 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 373 struct ehca_mr_pginfo pginfo;
366 u32 cur_pid = current->tgid; 374 u32 cur_pid = current->tgid;
367 375
368 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && 376 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
@@ -414,7 +422,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
414 goto rereg_phys_mr_exit0; 422 goto rereg_phys_mr_exit0;
415 } 423 }
416 if (!phys_buf_array || num_phys_buf <= 0) { 424 if (!phys_buf_array || num_phys_buf <= 0) {
417 ehca_err(mr->device, "bad input values: mr_rereg_mask=%x" 425 ehca_err(mr->device, "bad input values mr_rereg_mask=%x"
418 " phys_buf_array=%p num_phys_buf=%x", 426 " phys_buf_array=%p num_phys_buf=%x",
419 mr_rereg_mask, phys_buf_array, num_phys_buf); 427 mr_rereg_mask, phys_buf_array, num_phys_buf);
420 ret = -EINVAL; 428 ret = -EINVAL;
@@ -438,10 +446,10 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
438 446
439 /* set requested values dependent on rereg request */ 447 /* set requested values dependent on rereg request */
440 spin_lock_irqsave(&e_mr->mrlock, sl_flags); 448 spin_lock_irqsave(&e_mr->mrlock, sl_flags);
441 new_start = e_mr->start; /* new == old address */ 449 new_start = e_mr->start;
442 new_size = e_mr->size; /* new == old length */ 450 new_size = e_mr->size;
443 new_acl = e_mr->acl; /* new == old access control */ 451 new_acl = e_mr->acl;
444 new_pd = container_of(mr->pd,struct ehca_pd,ib_pd); /*new == old PD*/ 452 new_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
445 453
446 if (mr_rereg_mask & IB_MR_REREG_TRANS) { 454 if (mr_rereg_mask & IB_MR_REREG_TRANS) {
447 new_start = iova_start; /* change address */ 455 new_start = iova_start; /* change address */
@@ -458,17 +466,18 @@ int ehca_rereg_phys_mr(struct ib_mr *mr,
458 ret = -EINVAL; 466 ret = -EINVAL;
459 goto rereg_phys_mr_exit1; 467 goto rereg_phys_mr_exit1;
460 } 468 }
461 num_pages_mr = ((((u64)new_start % PAGE_SIZE) + new_size + 469 num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) +
462 PAGE_SIZE - 1) / PAGE_SIZE); 470 new_size, PAGE_SIZE);
463 num_pages_4k = ((((u64)new_start % EHCA_PAGESIZE) + new_size + 471 num_hwpages = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) +
464 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE); 472 new_size, EHCA_PAGESIZE);
465 pginfo.type = EHCA_MR_PGI_PHYS; 473 memset(&pginfo, 0, sizeof(pginfo));
466 pginfo.num_pages = num_pages_mr; 474 pginfo.type = EHCA_MR_PGI_PHYS;
467 pginfo.num_4k = num_pages_4k; 475 pginfo.num_kpages = num_kpages;
468 pginfo.num_phys_buf = num_phys_buf; 476 pginfo.num_hwpages = num_hwpages;
469 pginfo.phys_buf_array = phys_buf_array; 477 pginfo.u.phy.num_phys_buf = num_phys_buf;
470 pginfo.next_4k = (((u64)iova_start & ~PAGE_MASK) / 478 pginfo.u.phy.phys_buf_array = phys_buf_array;
471 EHCA_PAGESIZE); 479 pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) /
480 EHCA_PAGESIZE);
472 } 481 }
473 if (mr_rereg_mask & IB_MR_REREG_ACCESS) 482 if (mr_rereg_mask & IB_MR_REREG_ACCESS)
474 new_acl = mr_access_flags; 483 new_acl = mr_access_flags;
@@ -510,7 +519,7 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
510 struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd); 519 struct ehca_pd *my_pd = container_of(mr->pd, struct ehca_pd, ib_pd);
511 u32 cur_pid = current->tgid; 520 u32 cur_pid = current->tgid;
512 unsigned long sl_flags; 521 unsigned long sl_flags;
513 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 522 struct ehca_mr_hipzout_parms hipzout;
514 523
515 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && 524 if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context &&
516 (my_pd->ownpid != cur_pid)) { 525 (my_pd->ownpid != cur_pid)) {
@@ -536,14 +545,14 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
536 "hca_hndl=%lx mr_hndl=%lx lkey=%x", 545 "hca_hndl=%lx mr_hndl=%lx lkey=%x",
537 h_ret, mr, shca->ipz_hca_handle.handle, 546 h_ret, mr, shca->ipz_hca_handle.handle,
538 e_mr->ipz_mr_handle.handle, mr->lkey); 547 e_mr->ipz_mr_handle.handle, mr->lkey);
539 ret = ehca_mrmw_map_hrc_query_mr(h_ret); 548 ret = ehca2ib_return_code(h_ret);
540 goto query_mr_exit1; 549 goto query_mr_exit1;
541 } 550 }
542 mr_attr->pd = mr->pd; 551 mr_attr->pd = mr->pd;
543 mr_attr->device_virt_addr = hipzout.vaddr; 552 mr_attr->device_virt_addr = hipzout.vaddr;
544 mr_attr->size = hipzout.len; 553 mr_attr->size = hipzout.len;
545 mr_attr->lkey = hipzout.lkey; 554 mr_attr->lkey = hipzout.lkey;
546 mr_attr->rkey = hipzout.rkey; 555 mr_attr->rkey = hipzout.rkey;
547 ehca_mrmw_reverse_map_acl(&hipzout.acl, &mr_attr->mr_access_flags); 556 ehca_mrmw_reverse_map_acl(&hipzout.acl, &mr_attr->mr_access_flags);
548 557
549query_mr_exit1: 558query_mr_exit1:
@@ -596,7 +605,7 @@ int ehca_dereg_mr(struct ib_mr *mr)
596 "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x", 605 "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x",
597 h_ret, shca, e_mr, shca->ipz_hca_handle.handle, 606 h_ret, shca, e_mr, shca->ipz_hca_handle.handle,
598 e_mr->ipz_mr_handle.handle, mr->lkey); 607 e_mr->ipz_mr_handle.handle, mr->lkey);
599 ret = ehca_mrmw_map_hrc_free_mr(h_ret); 608 ret = ehca2ib_return_code(h_ret);
600 goto dereg_mr_exit0; 609 goto dereg_mr_exit0;
601 } 610 }
602 611
@@ -622,7 +631,7 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
622 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd); 631 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
623 struct ehca_shca *shca = 632 struct ehca_shca *shca =
624 container_of(pd->device, struct ehca_shca, ib_device); 633 container_of(pd->device, struct ehca_shca, ib_device);
625 struct ehca_mw_hipzout_parms hipzout = {{0},0}; 634 struct ehca_mw_hipzout_parms hipzout;
626 635
627 e_mw = ehca_mw_new(); 636 e_mw = ehca_mw_new();
628 if (!e_mw) { 637 if (!e_mw) {
@@ -636,7 +645,7 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd)
636 ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lx " 645 ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lx "
637 "shca=%p hca_hndl=%lx mw=%p", 646 "shca=%p hca_hndl=%lx mw=%p",
638 h_ret, shca, shca->ipz_hca_handle.handle, e_mw); 647 h_ret, shca, shca->ipz_hca_handle.handle, e_mw);
639 ib_mw = ERR_PTR(ehca_mrmw_map_hrc_alloc(h_ret)); 648 ib_mw = ERR_PTR(ehca2ib_return_code(h_ret));
640 goto alloc_mw_exit1; 649 goto alloc_mw_exit1;
641 } 650 }
642 /* successful MW allocation */ 651 /* successful MW allocation */
@@ -679,7 +688,7 @@ int ehca_dealloc_mw(struct ib_mw *mw)
679 "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx", 688 "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx",
680 h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle, 689 h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle,
681 e_mw->ipz_mw_handle.handle); 690 e_mw->ipz_mw_handle.handle);
682 return ehca_mrmw_map_hrc_free_mw(h_ret); 691 return ehca2ib_return_code(h_ret);
683 } 692 }
684 /* successful deallocation */ 693 /* successful deallocation */
685 ehca_mw_delete(e_mw); 694 ehca_mw_delete(e_mw);
@@ -699,7 +708,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
699 struct ehca_mr *e_fmr; 708 struct ehca_mr *e_fmr;
700 int ret; 709 int ret;
701 u32 tmp_lkey, tmp_rkey; 710 u32 tmp_lkey, tmp_rkey;
702 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 711 struct ehca_mr_pginfo pginfo;
703 712
704 /* check other parameters */ 713 /* check other parameters */
705 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) && 714 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) &&
@@ -745,6 +754,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
745 e_fmr->flags |= EHCA_MR_FLAG_FMR; 754 e_fmr->flags |= EHCA_MR_FLAG_FMR;
746 755
747 /* register MR on HCA */ 756 /* register MR on HCA */
757 memset(&pginfo, 0, sizeof(pginfo));
748 ret = ehca_reg_mr(shca, e_fmr, NULL, 758 ret = ehca_reg_mr(shca, e_fmr, NULL,
749 fmr_attr->max_pages * (1 << fmr_attr->page_shift), 759 fmr_attr->max_pages * (1 << fmr_attr->page_shift),
750 mr_access_flags, e_pd, &pginfo, 760 mr_access_flags, e_pd, &pginfo,
@@ -783,7 +793,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
783 container_of(fmr->device, struct ehca_shca, ib_device); 793 container_of(fmr->device, struct ehca_shca, ib_device);
784 struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr); 794 struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr);
785 struct ehca_pd *e_pd = container_of(fmr->pd, struct ehca_pd, ib_pd); 795 struct ehca_pd *e_pd = container_of(fmr->pd, struct ehca_pd, ib_pd);
786 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 796 struct ehca_mr_pginfo pginfo;
787 u32 tmp_lkey, tmp_rkey; 797 u32 tmp_lkey, tmp_rkey;
788 798
789 if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) { 799 if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {
@@ -809,14 +819,16 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
809 fmr, e_fmr->fmr_map_cnt, e_fmr->fmr_max_maps); 819 fmr, e_fmr->fmr_map_cnt, e_fmr->fmr_max_maps);
810 } 820 }
811 821
812 pginfo.type = EHCA_MR_PGI_FMR; 822 memset(&pginfo, 0, sizeof(pginfo));
813 pginfo.num_pages = list_len; 823 pginfo.type = EHCA_MR_PGI_FMR;
814 pginfo.num_4k = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE); 824 pginfo.num_kpages = list_len;
815 pginfo.page_list = page_list; 825 pginfo.num_hwpages = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE);
816 pginfo.next_4k = ((iova & (e_fmr->fmr_page_size-1)) / 826 pginfo.u.fmr.page_list = page_list;
817 EHCA_PAGESIZE); 827 pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) /
828 EHCA_PAGESIZE);
829 pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size;
818 830
819 ret = ehca_rereg_mr(shca, e_fmr, (u64*)iova, 831 ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova,
820 list_len * e_fmr->fmr_page_size, 832 list_len * e_fmr->fmr_page_size,
821 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, &tmp_rkey); 833 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, &tmp_rkey);
822 if (ret) 834 if (ret)
@@ -831,8 +843,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr,
831map_phys_fmr_exit0: 843map_phys_fmr_exit0:
832 if (ret) 844 if (ret)
833 ehca_err(fmr->device, "ret=%x fmr=%p page_list=%p list_len=%x " 845 ehca_err(fmr->device, "ret=%x fmr=%p page_list=%p list_len=%x "
834 "iova=%lx", 846 "iova=%lx", ret, fmr, page_list, list_len, iova);
835 ret, fmr, page_list, list_len, iova);
836 return ret; 847 return ret;
837} /* end ehca_map_phys_fmr() */ 848} /* end ehca_map_phys_fmr() */
838 849
@@ -922,7 +933,7 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr)
922 "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x", 933 "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x",
923 h_ret, e_fmr, shca->ipz_hca_handle.handle, 934 h_ret, e_fmr, shca->ipz_hca_handle.handle,
924 e_fmr->ipz_mr_handle.handle, fmr->lkey); 935 e_fmr->ipz_mr_handle.handle, fmr->lkey);
925 ret = ehca_mrmw_map_hrc_free_mr(h_ret); 936 ret = ehca2ib_return_code(h_ret);
926 goto free_fmr_exit0; 937 goto free_fmr_exit0;
927 } 938 }
928 /* successful deregistration */ 939 /* successful deregistration */
@@ -950,12 +961,12 @@ int ehca_reg_mr(struct ehca_shca *shca,
950 int ret; 961 int ret;
951 u64 h_ret; 962 u64 h_ret;
952 u32 hipz_acl; 963 u32 hipz_acl;
953 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 964 struct ehca_mr_hipzout_parms hipzout;
954 965
955 ehca_mrmw_map_acl(acl, &hipz_acl); 966 ehca_mrmw_map_acl(acl, &hipz_acl);
956 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 967 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
957 if (ehca_use_hp_mr == 1) 968 if (ehca_use_hp_mr == 1)
958 hipz_acl |= 0x00000001; 969 hipz_acl |= 0x00000001;
959 970
960 h_ret = hipz_h_alloc_resource_mr(shca->ipz_hca_handle, e_mr, 971 h_ret = hipz_h_alloc_resource_mr(shca->ipz_hca_handle, e_mr,
961 (u64)iova_start, size, hipz_acl, 972 (u64)iova_start, size, hipz_acl,
@@ -963,7 +974,7 @@ int ehca_reg_mr(struct ehca_shca *shca,
963 if (h_ret != H_SUCCESS) { 974 if (h_ret != H_SUCCESS) {
964 ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lx " 975 ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lx "
965 "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle); 976 "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle);
966 ret = ehca_mrmw_map_hrc_alloc(h_ret); 977 ret = ehca2ib_return_code(h_ret);
967 goto ehca_reg_mr_exit0; 978 goto ehca_reg_mr_exit0;
968 } 979 }
969 980
@@ -974,11 +985,11 @@ int ehca_reg_mr(struct ehca_shca *shca,
974 goto ehca_reg_mr_exit1; 985 goto ehca_reg_mr_exit1;
975 986
976 /* successful registration */ 987 /* successful registration */
977 e_mr->num_pages = pginfo->num_pages; 988 e_mr->num_kpages = pginfo->num_kpages;
978 e_mr->num_4k = pginfo->num_4k; 989 e_mr->num_hwpages = pginfo->num_hwpages;
979 e_mr->start = iova_start; 990 e_mr->start = iova_start;
980 e_mr->size = size; 991 e_mr->size = size;
981 e_mr->acl = acl; 992 e_mr->acl = acl;
982 *lkey = hipzout.lkey; 993 *lkey = hipzout.lkey;
983 *rkey = hipzout.rkey; 994 *rkey = hipzout.rkey;
984 return 0; 995 return 0;
@@ -988,10 +999,10 @@ ehca_reg_mr_exit1:
988 if (h_ret != H_SUCCESS) { 999 if (h_ret != H_SUCCESS) {
989 ehca_err(&shca->ib_device, "h_ret=%lx shca=%p e_mr=%p " 1000 ehca_err(&shca->ib_device, "h_ret=%lx shca=%p e_mr=%p "
990 "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x " 1001 "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x "
991 "pginfo=%p num_pages=%lx num_4k=%lx ret=%x", 1002 "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%x",
992 h_ret, shca, e_mr, iova_start, size, acl, e_pd, 1003 h_ret, shca, e_mr, iova_start, size, acl, e_pd,
993 hipzout.lkey, pginfo, pginfo->num_pages, 1004 hipzout.lkey, pginfo, pginfo->num_kpages,
994 pginfo->num_4k, ret); 1005 pginfo->num_hwpages, ret);
995 ehca_err(&shca->ib_device, "internal error in ehca_reg_mr, " 1006 ehca_err(&shca->ib_device, "internal error in ehca_reg_mr, "
996 "not recoverable"); 1007 "not recoverable");
997 } 1008 }
@@ -999,9 +1010,9 @@ ehca_reg_mr_exit0:
999 if (ret) 1010 if (ret)
1000 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p " 1011 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
1001 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " 1012 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
1002 "num_pages=%lx num_4k=%lx", 1013 "num_kpages=%lx num_hwpages=%lx",
1003 ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo, 1014 ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo,
1004 pginfo->num_pages, pginfo->num_4k); 1015 pginfo->num_kpages, pginfo->num_hwpages);
1005 return ret; 1016 return ret;
1006} /* end ehca_reg_mr() */ 1017} /* end ehca_reg_mr() */
1007 1018
@@ -1026,24 +1037,24 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
1026 } 1037 }
1027 1038
1028 /* max 512 pages per shot */ 1039 /* max 512 pages per shot */
1029 for (i = 0; i < ((pginfo->num_4k + 512 - 1) / 512); i++) { 1040 for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) {
1030 1041
1031 if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) { 1042 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
1032 rnum = pginfo->num_4k % 512; /* last shot */ 1043 rnum = pginfo->num_hwpages % MAX_RPAGES; /* last shot */
1033 if (rnum == 0) 1044 if (rnum == 0)
1034 rnum = 512; /* last shot is full */ 1045 rnum = MAX_RPAGES; /* last shot is full */
1035 } else 1046 } else
1036 rnum = 512; 1047 rnum = MAX_RPAGES;
1037 1048
1038 if (rnum > 1) { 1049 ret = ehca_set_pagebuf(pginfo, rnum, kpage);
1039 ret = ehca_set_pagebuf(e_mr, pginfo, rnum, kpage); 1050 if (ret) {
1040 if (ret) { 1051 ehca_err(&shca->ib_device, "ehca_set_pagebuf "
1041 ehca_err(&shca->ib_device, "ehca_set_pagebuf "
1042 "bad rc, ret=%x rnum=%x kpage=%p", 1052 "bad rc, ret=%x rnum=%x kpage=%p",
1043 ret, rnum, kpage); 1053 ret, rnum, kpage);
1044 ret = -EFAULT; 1054 goto ehca_reg_mr_rpages_exit1;
1045 goto ehca_reg_mr_rpages_exit1; 1055 }
1046 } 1056
1057 if (rnum > 1) {
1047 rpage = virt_to_abs(kpage); 1058 rpage = virt_to_abs(kpage);
1048 if (!rpage) { 1059 if (!rpage) {
1049 ehca_err(&shca->ib_device, "kpage=%p i=%x", 1060 ehca_err(&shca->ib_device, "kpage=%p i=%x",
@@ -1051,21 +1062,14 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
1051 ret = -EFAULT; 1062 ret = -EFAULT;
1052 goto ehca_reg_mr_rpages_exit1; 1063 goto ehca_reg_mr_rpages_exit1;
1053 } 1064 }
1054 } else { /* rnum==1 */ 1065 } else
1055 ret = ehca_set_pagebuf_1(e_mr, pginfo, &rpage); 1066 rpage = *kpage;
1056 if (ret) {
1057 ehca_err(&shca->ib_device, "ehca_set_pagebuf_1 "
1058 "bad rc, ret=%x i=%x", ret, i);
1059 ret = -EFAULT;
1060 goto ehca_reg_mr_rpages_exit1;
1061 }
1062 }
1063 1067
1064 h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr, 1068 h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr,
1065 0, /* pagesize 4k */ 1069 0, /* pagesize 4k */
1066 0, rpage, rnum); 1070 0, rpage, rnum);
1067 1071
1068 if (i == ((pginfo->num_4k + 512 - 1) / 512) - 1) { 1072 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {
1069 /* 1073 /*
1070 * check for 'registration complete'==H_SUCCESS 1074 * check for 'registration complete'==H_SUCCESS
1071 * and for 'page registered'==H_PAGE_REGISTERED 1075 * and for 'page registered'==H_PAGE_REGISTERED
@@ -1078,7 +1082,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
1078 shca->ipz_hca_handle.handle, 1082 shca->ipz_hca_handle.handle,
1079 e_mr->ipz_mr_handle.handle, 1083 e_mr->ipz_mr_handle.handle,
1080 e_mr->ib.ib_mr.lkey); 1084 e_mr->ib.ib_mr.lkey);
1081 ret = ehca_mrmw_map_hrc_rrpg_last(h_ret); 1085 ret = ehca2ib_return_code(h_ret);
1082 break; 1086 break;
1083 } else 1087 } else
1084 ret = 0; 1088 ret = 0;
@@ -1089,7 +1093,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
1089 e_mr->ib.ib_mr.lkey, 1093 e_mr->ib.ib_mr.lkey,
1090 shca->ipz_hca_handle.handle, 1094 shca->ipz_hca_handle.handle,
1091 e_mr->ipz_mr_handle.handle); 1095 e_mr->ipz_mr_handle.handle);
1092 ret = ehca_mrmw_map_hrc_rrpg_notlast(h_ret); 1096 ret = ehca2ib_return_code(h_ret);
1093 break; 1097 break;
1094 } else 1098 } else
1095 ret = 0; 1099 ret = 0;
@@ -1101,8 +1105,8 @@ ehca_reg_mr_rpages_exit1:
1101ehca_reg_mr_rpages_exit0: 1105ehca_reg_mr_rpages_exit0:
1102 if (ret) 1106 if (ret)
1103 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " 1107 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p "
1104 "num_pages=%lx num_4k=%lx", ret, shca, e_mr, pginfo, 1108 "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr,
1105 pginfo->num_pages, pginfo->num_4k); 1109 pginfo, pginfo->num_kpages, pginfo->num_hwpages);
1106 return ret; 1110 return ret;
1107} /* end ehca_reg_mr_rpages() */ 1111} /* end ehca_reg_mr_rpages() */
1108 1112
@@ -1124,7 +1128,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
1124 u64 *kpage; 1128 u64 *kpage;
1125 u64 rpage; 1129 u64 rpage;
1126 struct ehca_mr_pginfo pginfo_save; 1130 struct ehca_mr_pginfo pginfo_save;
1127 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 1131 struct ehca_mr_hipzout_parms hipzout;
1128 1132
1129 ehca_mrmw_map_acl(acl, &hipz_acl); 1133 ehca_mrmw_map_acl(acl, &hipz_acl);
1130 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1134 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1137,12 +1141,12 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
1137 } 1141 }
1138 1142
1139 pginfo_save = *pginfo; 1143 pginfo_save = *pginfo;
1140 ret = ehca_set_pagebuf(e_mr, pginfo, pginfo->num_4k, kpage); 1144 ret = ehca_set_pagebuf(pginfo, pginfo->num_hwpages, kpage);
1141 if (ret) { 1145 if (ret) {
1142 ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p " 1146 ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "
1143 "pginfo=%p type=%x num_pages=%lx num_4k=%lx kpage=%p", 1147 "pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx "
1144 e_mr, pginfo, pginfo->type, pginfo->num_pages, 1148 "kpage=%p", e_mr, pginfo, pginfo->type,
1145 pginfo->num_4k,kpage); 1149 pginfo->num_kpages, pginfo->num_hwpages, kpage);
1146 goto ehca_rereg_mr_rereg1_exit1; 1150 goto ehca_rereg_mr_rereg1_exit1;
1147 } 1151 }
1148 rpage = virt_to_abs(kpage); 1152 rpage = virt_to_abs(kpage);
@@ -1164,7 +1168,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
1164 "(Rereg1), h_ret=%lx e_mr=%p", h_ret, e_mr); 1168 "(Rereg1), h_ret=%lx e_mr=%p", h_ret, e_mr);
1165 *pginfo = pginfo_save; 1169 *pginfo = pginfo_save;
1166 ret = -EAGAIN; 1170 ret = -EAGAIN;
1167 } else if ((u64*)hipzout.vaddr != iova_start) { 1171 } else if ((u64 *)hipzout.vaddr != iova_start) {
1168 ehca_err(&shca->ib_device, "PHYP changed iova_start in " 1172 ehca_err(&shca->ib_device, "PHYP changed iova_start in "
1169 "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p " 1173 "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p "
1170 "mr_handle=%lx lkey=%x lkey_out=%x", iova_start, 1174 "mr_handle=%lx lkey=%x lkey_out=%x", iova_start,
@@ -1176,11 +1180,11 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
1176 * successful reregistration 1180 * successful reregistration
1177 * note: start and start_out are identical for eServer HCAs 1181 * note: start and start_out are identical for eServer HCAs
1178 */ 1182 */
1179 e_mr->num_pages = pginfo->num_pages; 1183 e_mr->num_kpages = pginfo->num_kpages;
1180 e_mr->num_4k = pginfo->num_4k; 1184 e_mr->num_hwpages = pginfo->num_hwpages;
1181 e_mr->start = iova_start; 1185 e_mr->start = iova_start;
1182 e_mr->size = size; 1186 e_mr->size = size;
1183 e_mr->acl = acl; 1187 e_mr->acl = acl;
1184 *lkey = hipzout.lkey; 1188 *lkey = hipzout.lkey;
1185 *rkey = hipzout.rkey; 1189 *rkey = hipzout.rkey;
1186 } 1190 }
@@ -1190,9 +1194,9 @@ ehca_rereg_mr_rereg1_exit1:
1190ehca_rereg_mr_rereg1_exit0: 1194ehca_rereg_mr_rereg1_exit0:
1191 if ( ret && (ret != -EAGAIN) ) 1195 if ( ret && (ret != -EAGAIN) )
1192 ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " 1196 ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
1193 "pginfo=%p num_pages=%lx num_4k=%lx", 1197 "pginfo=%p num_kpages=%lx num_hwpages=%lx",
1194 ret, *lkey, *rkey, pginfo, pginfo->num_pages, 1198 ret, *lkey, *rkey, pginfo, pginfo->num_kpages,
1195 pginfo->num_4k); 1199 pginfo->num_hwpages);
1196 return ret; 1200 return ret;
1197} /* end ehca_rereg_mr_rereg1() */ 1201} /* end ehca_rereg_mr_rereg1() */
1198 1202
@@ -1214,10 +1218,12 @@ int ehca_rereg_mr(struct ehca_shca *shca,
1214 int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */ 1218 int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */
1215 1219
1216 /* first determine reregistration hCall(s) */ 1220 /* first determine reregistration hCall(s) */
1217 if ((pginfo->num_4k > 512) || (e_mr->num_4k > 512) || 1221 if ((pginfo->num_hwpages > MAX_RPAGES) ||
1218 (pginfo->num_4k > e_mr->num_4k)) { 1222 (e_mr->num_hwpages > MAX_RPAGES) ||
1219 ehca_dbg(&shca->ib_device, "Rereg3 case, pginfo->num_4k=%lx " 1223 (pginfo->num_hwpages > e_mr->num_hwpages)) {
1220 "e_mr->num_4k=%x", pginfo->num_4k, e_mr->num_4k); 1224 ehca_dbg(&shca->ib_device, "Rereg3 case, "
1225 "pginfo->num_hwpages=%lx e_mr->num_hwpages=%x",
1226 pginfo->num_hwpages, e_mr->num_hwpages);
1221 rereg_1_hcall = 0; 1227 rereg_1_hcall = 0;
1222 rereg_3_hcall = 1; 1228 rereg_3_hcall = 1;
1223 } 1229 }
@@ -1253,7 +1259,7 @@ int ehca_rereg_mr(struct ehca_shca *shca,
1253 h_ret, e_mr, shca->ipz_hca_handle.handle, 1259 h_ret, e_mr, shca->ipz_hca_handle.handle,
1254 e_mr->ipz_mr_handle.handle, 1260 e_mr->ipz_mr_handle.handle,
1255 e_mr->ib.ib_mr.lkey); 1261 e_mr->ib.ib_mr.lkey);
1256 ret = ehca_mrmw_map_hrc_free_mr(h_ret); 1262 ret = ehca2ib_return_code(h_ret);
1257 goto ehca_rereg_mr_exit0; 1263 goto ehca_rereg_mr_exit0;
1258 } 1264 }
1259 /* clean ehca_mr_t, without changing struct ib_mr and lock */ 1265 /* clean ehca_mr_t, without changing struct ib_mr and lock */
@@ -1281,9 +1287,9 @@ ehca_rereg_mr_exit0:
1281 if (ret) 1287 if (ret)
1282 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p " 1288 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p "
1283 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " 1289 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "
1284 "num_pages=%lx lkey=%x rkey=%x rereg_1_hcall=%x " 1290 "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x "
1285 "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size, 1291 "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size,
1286 acl, e_pd, pginfo, pginfo->num_pages, *lkey, *rkey, 1292 acl, e_pd, pginfo, pginfo->num_kpages, *lkey, *rkey,
1287 rereg_1_hcall, rereg_3_hcall); 1293 rereg_1_hcall, rereg_3_hcall);
1288 return ret; 1294 return ret;
1289} /* end ehca_rereg_mr() */ 1295} /* end ehca_rereg_mr() */
@@ -1295,97 +1301,86 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca,
1295{ 1301{
1296 int ret = 0; 1302 int ret = 0;
1297 u64 h_ret; 1303 u64 h_ret;
1298 int rereg_1_hcall = 1; /* 1: use hipz_mr_reregister directly */
1299 int rereg_3_hcall = 0; /* 1: use 3 hipz calls for unmapping */
1300 struct ehca_pd *e_pd = 1304 struct ehca_pd *e_pd =
1301 container_of(e_fmr->ib.ib_fmr.pd, struct ehca_pd, ib_pd); 1305 container_of(e_fmr->ib.ib_fmr.pd, struct ehca_pd, ib_pd);
1302 struct ehca_mr save_fmr; 1306 struct ehca_mr save_fmr;
1303 u32 tmp_lkey, tmp_rkey; 1307 u32 tmp_lkey, tmp_rkey;
1304 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 1308 struct ehca_mr_pginfo pginfo;
1305 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 1309 struct ehca_mr_hipzout_parms hipzout;
1310 struct ehca_mr save_mr;
1306 1311
1307 /* first check if reregistration hCall can be used for unmap */ 1312 if (e_fmr->fmr_max_pages <= MAX_RPAGES) {
1308 if (e_fmr->fmr_max_pages > 512) {
1309 rereg_1_hcall = 0;
1310 rereg_3_hcall = 1;
1311 }
1312
1313 if (rereg_1_hcall) {
1314 /* 1313 /*
1315 * note: after using rereg hcall with len=0, 1314 * note: after using rereg hcall with len=0,
1316 * rereg hcall must be used again for registering pages 1315 * rereg hcall must be used again for registering pages
1317 */ 1316 */
1318 h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_fmr, 0, 1317 h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_fmr, 0,
1319 0, 0, e_pd->fw_pd, 0, &hipzout); 1318 0, 0, e_pd->fw_pd, 0, &hipzout);
1320 if (h_ret != H_SUCCESS) { 1319 if (h_ret == H_SUCCESS) {
1321 /*
1322 * should not happen, because length checked above,
1323 * FMRs are not shared and no MW bound to FMRs
1324 */
1325 ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
1326 "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx "
1327 "mr_hndl=%lx lkey=%x lkey_out=%x",
1328 h_ret, e_fmr, shca->ipz_hca_handle.handle,
1329 e_fmr->ipz_mr_handle.handle,
1330 e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
1331 rereg_3_hcall = 1;
1332 } else {
1333 /* successful reregistration */ 1320 /* successful reregistration */
1334 e_fmr->start = NULL; 1321 e_fmr->start = NULL;
1335 e_fmr->size = 0; 1322 e_fmr->size = 0;
1336 tmp_lkey = hipzout.lkey; 1323 tmp_lkey = hipzout.lkey;
1337 tmp_rkey = hipzout.rkey; 1324 tmp_rkey = hipzout.rkey;
1325 return 0;
1338 } 1326 }
1327 /*
1328 * should not happen, because length checked above,
1329 * FMRs are not shared and no MW bound to FMRs
1330 */
1331 ehca_err(&shca->ib_device, "hipz_reregister_pmr failed "
1332 "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx "
1333 "mr_hndl=%lx lkey=%x lkey_out=%x",
1334 h_ret, e_fmr, shca->ipz_hca_handle.handle,
1335 e_fmr->ipz_mr_handle.handle,
1336 e_fmr->ib.ib_fmr.lkey, hipzout.lkey);
1337 /* try free and rereg */
1339 } 1338 }
1340 1339
1341 if (rereg_3_hcall) { 1340 /* first free old FMR */
1342 struct ehca_mr save_mr; 1341 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);
1343 1342 if (h_ret != H_SUCCESS) {
1344 /* first free old FMR */ 1343 ehca_err(&shca->ib_device, "hipz_free_mr failed, "
1345 h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); 1344 "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx "
1346 if (h_ret != H_SUCCESS) { 1345 "lkey=%x",
1347 ehca_err(&shca->ib_device, "hipz_free_mr failed, " 1346 h_ret, e_fmr, shca->ipz_hca_handle.handle,
1348 "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx " 1347 e_fmr->ipz_mr_handle.handle,
1349 "lkey=%x", 1348 e_fmr->ib.ib_fmr.lkey);
1350 h_ret, e_fmr, shca->ipz_hca_handle.handle, 1349 ret = ehca2ib_return_code(h_ret);
1351 e_fmr->ipz_mr_handle.handle, 1350 goto ehca_unmap_one_fmr_exit0;
1352 e_fmr->ib.ib_fmr.lkey); 1351 }
1353 ret = ehca_mrmw_map_hrc_free_mr(h_ret); 1352 /* clean ehca_mr_t, without changing lock */
1354 goto ehca_unmap_one_fmr_exit0; 1353 save_fmr = *e_fmr;
1355 } 1354 ehca_mr_deletenew(e_fmr);
1356 /* clean ehca_mr_t, without changing lock */ 1355
1357 save_fmr = *e_fmr; 1356 /* set some MR values */
1358 ehca_mr_deletenew(e_fmr); 1357 e_fmr->flags = save_fmr.flags;
1359 1358 e_fmr->fmr_page_size = save_fmr.fmr_page_size;
1360 /* set some MR values */ 1359 e_fmr->fmr_max_pages = save_fmr.fmr_max_pages;
1361 e_fmr->flags = save_fmr.flags; 1360 e_fmr->fmr_max_maps = save_fmr.fmr_max_maps;
1362 e_fmr->fmr_page_size = save_fmr.fmr_page_size; 1361 e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt;
1363 e_fmr->fmr_max_pages = save_fmr.fmr_max_pages; 1362 e_fmr->acl = save_fmr.acl;
1364 e_fmr->fmr_max_maps = save_fmr.fmr_max_maps; 1363
1365 e_fmr->fmr_map_cnt = save_fmr.fmr_map_cnt; 1364 memset(&pginfo, 0, sizeof(pginfo));
1366 e_fmr->acl = save_fmr.acl; 1365 pginfo.type = EHCA_MR_PGI_FMR;
1367 1366 pginfo.num_kpages = 0;
1368 pginfo.type = EHCA_MR_PGI_FMR; 1367 pginfo.num_hwpages = 0;
1369 pginfo.num_pages = 0; 1368 ret = ehca_reg_mr(shca, e_fmr, NULL,
1370 pginfo.num_4k = 0; 1369 (e_fmr->fmr_max_pages * e_fmr->fmr_page_size),
1371 ret = ehca_reg_mr(shca, e_fmr, NULL, 1370 e_fmr->acl, e_pd, &pginfo, &tmp_lkey,
1372 (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), 1371 &tmp_rkey);
1373 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, 1372 if (ret) {
1374 &tmp_rkey); 1373 u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr;
1375 if (ret) { 1374 memcpy(&e_fmr->flags, &(save_mr.flags),
1376 u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; 1375 sizeof(struct ehca_mr) - offset);
1377 memcpy(&e_fmr->flags, &(save_mr.flags), 1376 goto ehca_unmap_one_fmr_exit0;
1378 sizeof(struct ehca_mr) - offset);
1379 goto ehca_unmap_one_fmr_exit0;
1380 }
1381 } 1377 }
1382 1378
1383ehca_unmap_one_fmr_exit0: 1379ehca_unmap_one_fmr_exit0:
1384 if (ret) 1380 if (ret)
1385 ehca_err(&shca->ib_device, "ret=%x tmp_lkey=%x tmp_rkey=%x " 1381 ehca_err(&shca->ib_device, "ret=%x tmp_lkey=%x tmp_rkey=%x "
1386 "fmr_max_pages=%x rereg_1_hcall=%x rereg_3_hcall=%x", 1382 "fmr_max_pages=%x",
1387 ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages, 1383 ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages);
1388 rereg_1_hcall, rereg_3_hcall);
1389 return ret; 1384 return ret;
1390} /* end ehca_unmap_one_fmr() */ 1385} /* end ehca_unmap_one_fmr() */
1391 1386
@@ -1403,7 +1398,7 @@ int ehca_reg_smr(struct ehca_shca *shca,
1403 int ret = 0; 1398 int ret = 0;
1404 u64 h_ret; 1399 u64 h_ret;
1405 u32 hipz_acl; 1400 u32 hipz_acl;
1406 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 1401 struct ehca_mr_hipzout_parms hipzout;
1407 1402
1408 ehca_mrmw_map_acl(acl, &hipz_acl); 1403 ehca_mrmw_map_acl(acl, &hipz_acl);
1409 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1404 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1419,15 +1414,15 @@ int ehca_reg_smr(struct ehca_shca *shca,
1419 shca->ipz_hca_handle.handle, 1414 shca->ipz_hca_handle.handle,
1420 e_origmr->ipz_mr_handle.handle, 1415 e_origmr->ipz_mr_handle.handle,
1421 e_origmr->ib.ib_mr.lkey); 1416 e_origmr->ib.ib_mr.lkey);
1422 ret = ehca_mrmw_map_hrc_reg_smr(h_ret); 1417 ret = ehca2ib_return_code(h_ret);
1423 goto ehca_reg_smr_exit0; 1418 goto ehca_reg_smr_exit0;
1424 } 1419 }
1425 /* successful registration */ 1420 /* successful registration */
1426 e_newmr->num_pages = e_origmr->num_pages; 1421 e_newmr->num_kpages = e_origmr->num_kpages;
1427 e_newmr->num_4k = e_origmr->num_4k; 1422 e_newmr->num_hwpages = e_origmr->num_hwpages;
1428 e_newmr->start = iova_start; 1423 e_newmr->start = iova_start;
1429 e_newmr->size = e_origmr->size; 1424 e_newmr->size = e_origmr->size;
1430 e_newmr->acl = acl; 1425 e_newmr->acl = acl;
1431 e_newmr->ipz_mr_handle = hipzout.handle; 1426 e_newmr->ipz_mr_handle = hipzout.handle;
1432 *lkey = hipzout.lkey; 1427 *lkey = hipzout.lkey;
1433 *rkey = hipzout.rkey; 1428 *rkey = hipzout.rkey;
@@ -1453,10 +1448,10 @@ int ehca_reg_internal_maxmr(
1453 struct ehca_mr *e_mr; 1448 struct ehca_mr *e_mr;
1454 u64 *iova_start; 1449 u64 *iova_start;
1455 u64 size_maxmr; 1450 u64 size_maxmr;
1456 struct ehca_mr_pginfo pginfo={0,0,0,0,0,0,0,NULL,0,NULL,NULL,0,NULL,0}; 1451 struct ehca_mr_pginfo pginfo;
1457 struct ib_phys_buf ib_pbuf; 1452 struct ib_phys_buf ib_pbuf;
1458 u32 num_pages_mr; 1453 u32 num_kpages;
1459 u32 num_pages_4k; /* 4k portion "pages" */ 1454 u32 num_hwpages;
1460 1455
1461 e_mr = ehca_mr_new(); 1456 e_mr = ehca_mr_new();
1462 if (!e_mr) { 1457 if (!e_mr) {
@@ -1468,28 +1463,29 @@ int ehca_reg_internal_maxmr(
1468 1463
1469 /* register internal max-MR on HCA */ 1464 /* register internal max-MR on HCA */
1470 size_maxmr = (u64)high_memory - PAGE_OFFSET; 1465 size_maxmr = (u64)high_memory - PAGE_OFFSET;
1471 iova_start = (u64*)KERNELBASE; 1466 iova_start = (u64 *)KERNELBASE;
1472 ib_pbuf.addr = 0; 1467 ib_pbuf.addr = 0;
1473 ib_pbuf.size = size_maxmr; 1468 ib_pbuf.size = size_maxmr;
1474 num_pages_mr = ((((u64)iova_start % PAGE_SIZE) + size_maxmr + 1469 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr,
1475 PAGE_SIZE - 1) / PAGE_SIZE); 1470 PAGE_SIZE);
1476 num_pages_4k = ((((u64)iova_start % EHCA_PAGESIZE) + size_maxmr + 1471 num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size_maxmr,
1477 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE); 1472 EHCA_PAGESIZE);
1478 1473
1479 pginfo.type = EHCA_MR_PGI_PHYS; 1474 memset(&pginfo, 0, sizeof(pginfo));
1480 pginfo.num_pages = num_pages_mr; 1475 pginfo.type = EHCA_MR_PGI_PHYS;
1481 pginfo.num_4k = num_pages_4k; 1476 pginfo.num_kpages = num_kpages;
1482 pginfo.num_phys_buf = 1; 1477 pginfo.num_hwpages = num_hwpages;
1483 pginfo.phys_buf_array = &ib_pbuf; 1478 pginfo.u.phy.num_phys_buf = 1;
1479 pginfo.u.phy.phys_buf_array = &ib_pbuf;
1484 1480
1485 ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd, 1481 ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd,
1486 &pginfo, &e_mr->ib.ib_mr.lkey, 1482 &pginfo, &e_mr->ib.ib_mr.lkey,
1487 &e_mr->ib.ib_mr.rkey); 1483 &e_mr->ib.ib_mr.rkey);
1488 if (ret) { 1484 if (ret) {
1489 ehca_err(&shca->ib_device, "reg of internal max MR failed, " 1485 ehca_err(&shca->ib_device, "reg of internal max MR failed, "
1490 "e_mr=%p iova_start=%p size_maxmr=%lx num_pages_mr=%x " 1486 "e_mr=%p iova_start=%p size_maxmr=%lx num_kpages=%x "
1491 "num_pages_4k=%x", e_mr, iova_start, size_maxmr, 1487 "num_hwpages=%x", e_mr, iova_start, size_maxmr,
1492 num_pages_mr, num_pages_4k); 1488 num_kpages, num_hwpages);
1493 goto ehca_reg_internal_maxmr_exit1; 1489 goto ehca_reg_internal_maxmr_exit1;
1494 } 1490 }
1495 1491
@@ -1524,7 +1520,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
1524 u64 h_ret; 1520 u64 h_ret;
1525 struct ehca_mr *e_origmr = shca->maxmr; 1521 struct ehca_mr *e_origmr = shca->maxmr;
1526 u32 hipz_acl; 1522 u32 hipz_acl;
1527 struct ehca_mr_hipzout_parms hipzout = {{0},0,0,0,0,0}; 1523 struct ehca_mr_hipzout_parms hipzout;
1528 1524
1529 ehca_mrmw_map_acl(acl, &hipz_acl); 1525 ehca_mrmw_map_acl(acl, &hipz_acl);
1530 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1526 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl);
@@ -1538,14 +1534,14 @@ int ehca_reg_maxmr(struct ehca_shca *shca,
1538 h_ret, e_origmr, shca->ipz_hca_handle.handle, 1534 h_ret, e_origmr, shca->ipz_hca_handle.handle,
1539 e_origmr->ipz_mr_handle.handle, 1535 e_origmr->ipz_mr_handle.handle,
1540 e_origmr->ib.ib_mr.lkey); 1536 e_origmr->ib.ib_mr.lkey);
1541 return ehca_mrmw_map_hrc_reg_smr(h_ret); 1537 return ehca2ib_return_code(h_ret);
1542 } 1538 }
1543 /* successful registration */ 1539 /* successful registration */
1544 e_newmr->num_pages = e_origmr->num_pages; 1540 e_newmr->num_kpages = e_origmr->num_kpages;
1545 e_newmr->num_4k = e_origmr->num_4k; 1541 e_newmr->num_hwpages = e_origmr->num_hwpages;
1546 e_newmr->start = iova_start; 1542 e_newmr->start = iova_start;
1547 e_newmr->size = e_origmr->size; 1543 e_newmr->size = e_origmr->size;
1548 e_newmr->acl = acl; 1544 e_newmr->acl = acl;
1549 e_newmr->ipz_mr_handle = hipzout.handle; 1545 e_newmr->ipz_mr_handle = hipzout.handle;
1550 *lkey = hipzout.lkey; 1546 *lkey = hipzout.lkey;
1551 *rkey = hipzout.rkey; 1547 *rkey = hipzout.rkey;
@@ -1677,299 +1673,187 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
1677 1673
1678/*----------------------------------------------------------------------*/ 1674/*----------------------------------------------------------------------*/
1679 1675
1680/* setup page buffer from page info */ 1676/* PAGE_SIZE >= pginfo->hwpage_size */
1681int ehca_set_pagebuf(struct ehca_mr *e_mr, 1677static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
1682 struct ehca_mr_pginfo *pginfo, 1678 u32 number,
1683 u32 number, 1679 u64 *kpage)
1684 u64 *kpage)
1685{ 1680{
1686 int ret = 0; 1681 int ret = 0;
1687 struct ib_umem_chunk *prev_chunk; 1682 struct ib_umem_chunk *prev_chunk;
1688 struct ib_umem_chunk *chunk; 1683 struct ib_umem_chunk *chunk;
1689 struct ib_phys_buf *pbuf; 1684 u64 pgaddr;
1690 u64 *fmrlist;
1691 u64 num4k, pgaddr, offs4k;
1692 u32 i = 0; 1685 u32 i = 0;
1693 u32 j = 0; 1686 u32 j = 0;
1694 1687
1695 if (pginfo->type == EHCA_MR_PGI_PHYS) { 1688 /* loop over desired chunk entries */
1696 /* loop over desired phys_buf_array entries */ 1689 chunk = pginfo->u.usr.next_chunk;
1697 while (i < number) { 1690 prev_chunk = pginfo->u.usr.next_chunk;
1698 pbuf = pginfo->phys_buf_array + pginfo->next_buf; 1691 list_for_each_entry_continue(
1699 num4k = ((pbuf->addr % EHCA_PAGESIZE) + pbuf->size + 1692 chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
1700 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE; 1693 for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
1701 offs4k = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE; 1694 pgaddr = page_to_pfn(chunk->page_list[i].page)
1702 while (pginfo->next_4k < offs4k + num4k) { 1695 << PAGE_SHIFT ;
1703 /* sanity check */ 1696 *kpage = phys_to_abs(pgaddr +
1704 if ((pginfo->page_cnt >= pginfo->num_pages) || 1697 (pginfo->next_hwpage *
1705 (pginfo->page_4k_cnt >= pginfo->num_4k)) { 1698 EHCA_PAGESIZE));
1706 ehca_gen_err("page_cnt >= num_pages, "
1707 "page_cnt=%lx "
1708 "num_pages=%lx "
1709 "page_4k_cnt=%lx "
1710 "num_4k=%lx i=%x",
1711 pginfo->page_cnt,
1712 pginfo->num_pages,
1713 pginfo->page_4k_cnt,
1714 pginfo->num_4k, i);
1715 ret = -EFAULT;
1716 goto ehca_set_pagebuf_exit0;
1717 }
1718 *kpage = phys_to_abs(
1719 (pbuf->addr & EHCA_PAGEMASK)
1720 + (pginfo->next_4k * EHCA_PAGESIZE));
1721 if ( !(*kpage) && pbuf->addr ) {
1722 ehca_gen_err("pbuf->addr=%lx "
1723 "pbuf->size=%lx "
1724 "next_4k=%lx", pbuf->addr,
1725 pbuf->size,
1726 pginfo->next_4k);
1727 ret = -EFAULT;
1728 goto ehca_set_pagebuf_exit0;
1729 }
1730 (pginfo->page_4k_cnt)++;
1731 (pginfo->next_4k)++;
1732 if (pginfo->next_4k %
1733 (PAGE_SIZE / EHCA_PAGESIZE) == 0)
1734 (pginfo->page_cnt)++;
1735 kpage++;
1736 i++;
1737 if (i >= number) break;
1738 }
1739 if (pginfo->next_4k >= offs4k + num4k) {
1740 (pginfo->next_buf)++;
1741 pginfo->next_4k = 0;
1742 }
1743 }
1744 } else if (pginfo->type == EHCA_MR_PGI_USER) {
1745 /* loop over desired chunk entries */
1746 chunk = pginfo->next_chunk;
1747 prev_chunk = pginfo->next_chunk;
1748 list_for_each_entry_continue(chunk,
1749 (&(pginfo->region->chunk_list)),
1750 list) {
1751 for (i = pginfo->next_nmap; i < chunk->nmap; ) {
1752 pgaddr = ( page_to_pfn(chunk->page_list[i].page)
1753 << PAGE_SHIFT );
1754 *kpage = phys_to_abs(pgaddr +
1755 (pginfo->next_4k *
1756 EHCA_PAGESIZE));
1757 if ( !(*kpage) ) {
1758 ehca_gen_err("pgaddr=%lx "
1759 "chunk->page_list[i]=%lx "
1760 "i=%x next_4k=%lx mr=%p",
1761 pgaddr,
1762 (u64)sg_dma_address(
1763 &chunk->
1764 page_list[i]),
1765 i, pginfo->next_4k, e_mr);
1766 ret = -EFAULT;
1767 goto ehca_set_pagebuf_exit0;
1768 }
1769 (pginfo->page_4k_cnt)++;
1770 (pginfo->next_4k)++;
1771 kpage++;
1772 if (pginfo->next_4k %
1773 (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
1774 (pginfo->page_cnt)++;
1775 (pginfo->next_nmap)++;
1776 pginfo->next_4k = 0;
1777 i++;
1778 }
1779 j++;
1780 if (j >= number) break;
1781 }
1782 if ((pginfo->next_nmap >= chunk->nmap) &&
1783 (j >= number)) {
1784 pginfo->next_nmap = 0;
1785 prev_chunk = chunk;
1786 break;
1787 } else if (pginfo->next_nmap >= chunk->nmap) {
1788 pginfo->next_nmap = 0;
1789 prev_chunk = chunk;
1790 } else if (j >= number)
1791 break;
1792 else
1793 prev_chunk = chunk;
1794 }
1795 pginfo->next_chunk =
1796 list_prepare_entry(prev_chunk,
1797 (&(pginfo->region->chunk_list)),
1798 list);
1799 } else if (pginfo->type == EHCA_MR_PGI_FMR) {
1800 /* loop over desired page_list entries */
1801 fmrlist = pginfo->page_list + pginfo->next_listelem;
1802 for (i = 0; i < number; i++) {
1803 *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
1804 pginfo->next_4k * EHCA_PAGESIZE);
1805 if ( !(*kpage) ) { 1699 if ( !(*kpage) ) {
1806 ehca_gen_err("*fmrlist=%lx fmrlist=%p " 1700 ehca_gen_err("pgaddr=%lx "
1807 "next_listelem=%lx next_4k=%lx", 1701 "chunk->page_list[i]=%lx "
1808 *fmrlist, fmrlist, 1702 "i=%x next_hwpage=%lx",
1809 pginfo->next_listelem, 1703 pgaddr, (u64)sg_dma_address(
1810 pginfo->next_4k); 1704 &chunk->page_list[i]),
1811 ret = -EFAULT; 1705 i, pginfo->next_hwpage);
1812 goto ehca_set_pagebuf_exit0; 1706 return -EFAULT;
1813 } 1707 }
1814 (pginfo->page_4k_cnt)++; 1708 (pginfo->hwpage_cnt)++;
1815 (pginfo->next_4k)++; 1709 (pginfo->next_hwpage)++;
1816 kpage++; 1710 kpage++;
1817 if (pginfo->next_4k % 1711 if (pginfo->next_hwpage %
1818 (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) { 1712 (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
1819 (pginfo->page_cnt)++; 1713 (pginfo->kpage_cnt)++;
1820 (pginfo->next_listelem)++; 1714 (pginfo->u.usr.next_nmap)++;
1821 fmrlist++; 1715 pginfo->next_hwpage = 0;
1822 pginfo->next_4k = 0; 1716 i++;
1823 } 1717 }
1718 j++;
1719 if (j >= number) break;
1824 } 1720 }
1825 } else { 1721 if ((pginfo->u.usr.next_nmap >= chunk->nmap) &&
1826 ehca_gen_err("bad pginfo->type=%x", pginfo->type); 1722 (j >= number)) {
1827 ret = -EFAULT; 1723 pginfo->u.usr.next_nmap = 0;
1828 goto ehca_set_pagebuf_exit0; 1724 prev_chunk = chunk;
1725 break;
1726 } else if (pginfo->u.usr.next_nmap >= chunk->nmap) {
1727 pginfo->u.usr.next_nmap = 0;
1728 prev_chunk = chunk;
1729 } else if (j >= number)
1730 break;
1731 else
1732 prev_chunk = chunk;
1829 } 1733 }
1830 1734 pginfo->u.usr.next_chunk =
1831ehca_set_pagebuf_exit0: 1735 list_prepare_entry(prev_chunk,
1832 if (ret) 1736 (&(pginfo->u.usr.region->chunk_list)),
1833 ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx " 1737 list);
1834 "num_4k=%lx next_buf=%lx next_4k=%lx number=%x "
1835 "kpage=%p page_cnt=%lx page_4k_cnt=%lx i=%x "
1836 "next_listelem=%lx region=%p next_chunk=%p "
1837 "next_nmap=%lx", ret, e_mr, pginfo, pginfo->type,
1838 pginfo->num_pages, pginfo->num_4k,
1839 pginfo->next_buf, pginfo->next_4k, number, kpage,
1840 pginfo->page_cnt, pginfo->page_4k_cnt, i,
1841 pginfo->next_listelem, pginfo->region,
1842 pginfo->next_chunk, pginfo->next_nmap);
1843 return ret; 1738 return ret;
1844} /* end ehca_set_pagebuf() */ 1739}
1845
1846/*----------------------------------------------------------------------*/
1847 1740
1848/* setup 1 page from page info page buffer */ 1741int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
1849int ehca_set_pagebuf_1(struct ehca_mr *e_mr, 1742 u32 number,
1850 struct ehca_mr_pginfo *pginfo, 1743 u64 *kpage)
1851 u64 *rpage)
1852{ 1744{
1853 int ret = 0; 1745 int ret = 0;
1854 struct ib_phys_buf *tmp_pbuf; 1746 struct ib_phys_buf *pbuf;
1855 u64 *fmrlist; 1747 u64 num_hw, offs_hw;
1856 struct ib_umem_chunk *chunk; 1748 u32 i = 0;
1857 struct ib_umem_chunk *prev_chunk; 1749
1858 u64 pgaddr, num4k, offs4k; 1750 /* loop over desired phys_buf_array entries */
1859 1751 while (i < number) {
1860 if (pginfo->type == EHCA_MR_PGI_PHYS) { 1752 pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf;
1861 /* sanity check */ 1753 num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) +
1862 if ((pginfo->page_cnt >= pginfo->num_pages) || 1754 pbuf->size, EHCA_PAGESIZE);
1863 (pginfo->page_4k_cnt >= pginfo->num_4k)) { 1755 offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE;
1864 ehca_gen_err("page_cnt >= num_pages, page_cnt=%lx " 1756 while (pginfo->next_hwpage < offs_hw + num_hw) {
1865 "num_pages=%lx page_4k_cnt=%lx num_4k=%lx", 1757 /* sanity check */
1866 pginfo->page_cnt, pginfo->num_pages, 1758 if ((pginfo->kpage_cnt >= pginfo->num_kpages) ||
1867 pginfo->page_4k_cnt, pginfo->num_4k); 1759 (pginfo->hwpage_cnt >= pginfo->num_hwpages)) {
1868 ret = -EFAULT; 1760 ehca_gen_err("kpage_cnt >= num_kpages, "
1869 goto ehca_set_pagebuf_1_exit0; 1761 "kpage_cnt=%lx num_kpages=%lx "
1870 } 1762 "hwpage_cnt=%lx "
1871 tmp_pbuf = pginfo->phys_buf_array + pginfo->next_buf; 1763 "num_hwpages=%lx i=%x",
1872 num4k = ((tmp_pbuf->addr % EHCA_PAGESIZE) + tmp_pbuf->size + 1764 pginfo->kpage_cnt,
1873 EHCA_PAGESIZE - 1) / EHCA_PAGESIZE; 1765 pginfo->num_kpages,
1874 offs4k = (tmp_pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE; 1766 pginfo->hwpage_cnt,
1875 *rpage = phys_to_abs((tmp_pbuf->addr & EHCA_PAGEMASK) + 1767 pginfo->num_hwpages, i);
1876 (pginfo->next_4k * EHCA_PAGESIZE)); 1768 return -EFAULT;
1877 if ( !(*rpage) && tmp_pbuf->addr ) {
1878 ehca_gen_err("tmp_pbuf->addr=%lx"
1879 " tmp_pbuf->size=%lx next_4k=%lx",
1880 tmp_pbuf->addr, tmp_pbuf->size,
1881 pginfo->next_4k);
1882 ret = -EFAULT;
1883 goto ehca_set_pagebuf_1_exit0;
1884 }
1885 (pginfo->page_4k_cnt)++;
1886 (pginfo->next_4k)++;
1887 if (pginfo->next_4k % (PAGE_SIZE / EHCA_PAGESIZE) == 0)
1888 (pginfo->page_cnt)++;
1889 if (pginfo->next_4k >= offs4k + num4k) {
1890 (pginfo->next_buf)++;
1891 pginfo->next_4k = 0;
1892 }
1893 } else if (pginfo->type == EHCA_MR_PGI_USER) {
1894 chunk = pginfo->next_chunk;
1895 prev_chunk = pginfo->next_chunk;
1896 list_for_each_entry_continue(chunk,
1897 (&(pginfo->region->chunk_list)),
1898 list) {
1899 pgaddr = ( page_to_pfn(chunk->page_list[
1900 pginfo->next_nmap].page)
1901 << PAGE_SHIFT);
1902 *rpage = phys_to_abs(pgaddr +
1903 (pginfo->next_4k * EHCA_PAGESIZE));
1904 if ( !(*rpage) ) {
1905 ehca_gen_err("pgaddr=%lx chunk->page_list[]=%lx"
1906 " next_nmap=%lx next_4k=%lx mr=%p",
1907 pgaddr, (u64)sg_dma_address(
1908 &chunk->page_list[
1909 pginfo->
1910 next_nmap]),
1911 pginfo->next_nmap, pginfo->next_4k,
1912 e_mr);
1913 ret = -EFAULT;
1914 goto ehca_set_pagebuf_1_exit0;
1915 }
1916 (pginfo->page_4k_cnt)++;
1917 (pginfo->next_4k)++;
1918 if (pginfo->next_4k %
1919 (PAGE_SIZE / EHCA_PAGESIZE) == 0) {
1920 (pginfo->page_cnt)++;
1921 (pginfo->next_nmap)++;
1922 pginfo->next_4k = 0;
1923 } 1769 }
1924 if (pginfo->next_nmap >= chunk->nmap) { 1770 *kpage = phys_to_abs(
1925 pginfo->next_nmap = 0; 1771 (pbuf->addr & EHCA_PAGEMASK)
1926 prev_chunk = chunk; 1772 + (pginfo->next_hwpage * EHCA_PAGESIZE));
1773 if ( !(*kpage) && pbuf->addr ) {
1774 ehca_gen_err("pbuf->addr=%lx "
1775 "pbuf->size=%lx "
1776 "next_hwpage=%lx", pbuf->addr,
1777 pbuf->size,
1778 pginfo->next_hwpage);
1779 return -EFAULT;
1927 } 1780 }
1928 break; 1781 (pginfo->hwpage_cnt)++;
1782 (pginfo->next_hwpage)++;
1783 if (pginfo->next_hwpage %
1784 (PAGE_SIZE / EHCA_PAGESIZE) == 0)
1785 (pginfo->kpage_cnt)++;
1786 kpage++;
1787 i++;
1788 if (i >= number) break;
1789 }
1790 if (pginfo->next_hwpage >= offs_hw + num_hw) {
1791 (pginfo->u.phy.next_buf)++;
1792 pginfo->next_hwpage = 0;
1929 } 1793 }
1930 pginfo->next_chunk = 1794 }
1931 list_prepare_entry(prev_chunk, 1795 return ret;
1932 (&(pginfo->region->chunk_list)), 1796}
1933 list); 1797
1934 } else if (pginfo->type == EHCA_MR_PGI_FMR) { 1798int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
1935 fmrlist = pginfo->page_list + pginfo->next_listelem; 1799 u32 number,
1936 *rpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) + 1800 u64 *kpage)
1937 pginfo->next_4k * EHCA_PAGESIZE); 1801{
1938 if ( !(*rpage) ) { 1802 int ret = 0;
1803 u64 *fmrlist;
1804 u32 i;
1805
1806 /* loop over desired page_list entries */
1807 fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
1808 for (i = 0; i < number; i++) {
1809 *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) +
1810 pginfo->next_hwpage * EHCA_PAGESIZE);
1811 if ( !(*kpage) ) {
1939 ehca_gen_err("*fmrlist=%lx fmrlist=%p " 1812 ehca_gen_err("*fmrlist=%lx fmrlist=%p "
1940 "next_listelem=%lx next_4k=%lx", 1813 "next_listelem=%lx next_hwpage=%lx",
1941 *fmrlist, fmrlist, pginfo->next_listelem, 1814 *fmrlist, fmrlist,
1942 pginfo->next_4k); 1815 pginfo->u.fmr.next_listelem,
1943 ret = -EFAULT; 1816 pginfo->next_hwpage);
1944 goto ehca_set_pagebuf_1_exit0; 1817 return -EFAULT;
1945 } 1818 }
1946 (pginfo->page_4k_cnt)++; 1819 (pginfo->hwpage_cnt)++;
1947 (pginfo->next_4k)++; 1820 (pginfo->next_hwpage)++;
1948 if (pginfo->next_4k % 1821 kpage++;
1949 (e_mr->fmr_page_size / EHCA_PAGESIZE) == 0) { 1822 if (pginfo->next_hwpage %
1950 (pginfo->page_cnt)++; 1823 (pginfo->u.fmr.fmr_pgsize / EHCA_PAGESIZE) == 0) {
1951 (pginfo->next_listelem)++; 1824 (pginfo->kpage_cnt)++;
1952 pginfo->next_4k = 0; 1825 (pginfo->u.fmr.next_listelem)++;
1826 fmrlist++;
1827 pginfo->next_hwpage = 0;
1953 } 1828 }
1954 } else { 1829 }
1830 return ret;
1831}
1832
1833/* setup page buffer from page info */
1834int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
1835 u32 number,
1836 u64 *kpage)
1837{
1838 int ret;
1839
1840 switch (pginfo->type) {
1841 case EHCA_MR_PGI_PHYS:
1842 ret = ehca_set_pagebuf_phys(pginfo, number, kpage);
1843 break;
1844 case EHCA_MR_PGI_USER:
1845 ret = ehca_set_pagebuf_user1(pginfo, number, kpage);
1846 break;
1847 case EHCA_MR_PGI_FMR:
1848 ret = ehca_set_pagebuf_fmr(pginfo, number, kpage);
1849 break;
1850 default:
1955 ehca_gen_err("bad pginfo->type=%x", pginfo->type); 1851 ehca_gen_err("bad pginfo->type=%x", pginfo->type);
1956 ret = -EFAULT; 1852 ret = -EFAULT;
1957 goto ehca_set_pagebuf_1_exit0; 1853 break;
1958 } 1854 }
1959
1960ehca_set_pagebuf_1_exit0:
1961 if (ret)
1962 ehca_gen_err("ret=%x e_mr=%p pginfo=%p type=%x num_pages=%lx "
1963 "num_4k=%lx next_buf=%lx next_4k=%lx rpage=%p "
1964 "page_cnt=%lx page_4k_cnt=%lx next_listelem=%lx "
1965 "region=%p next_chunk=%p next_nmap=%lx", ret, e_mr,
1966 pginfo, pginfo->type, pginfo->num_pages,
1967 pginfo->num_4k, pginfo->next_buf, pginfo->next_4k,
1968 rpage, pginfo->page_cnt, pginfo->page_4k_cnt,
1969 pginfo->next_listelem, pginfo->region,
1970 pginfo->next_chunk, pginfo->next_nmap);
1971 return ret; 1855 return ret;
1972} /* end ehca_set_pagebuf_1() */ 1856} /* end ehca_set_pagebuf() */
1973 1857
1974/*----------------------------------------------------------------------*/ 1858/*----------------------------------------------------------------------*/
1975 1859
@@ -1982,7 +1866,7 @@ int ehca_mr_is_maxmr(u64 size,
1982{ 1866{
1983 /* a MR is treated as max-MR only if it fits following: */ 1867 /* a MR is treated as max-MR only if it fits following: */
1984 if ((size == ((u64)high_memory - PAGE_OFFSET)) && 1868 if ((size == ((u64)high_memory - PAGE_OFFSET)) &&
1985 (iova_start == (void*)KERNELBASE)) { 1869 (iova_start == (void *)KERNELBASE)) {
1986 ehca_gen_dbg("this is a max-MR"); 1870 ehca_gen_dbg("this is a max-MR");
1987 return 1; 1871 return 1;
1988 } else 1872 } else
@@ -2042,196 +1926,23 @@ void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
2042/*----------------------------------------------------------------------*/ 1926/*----------------------------------------------------------------------*/
2043 1927
2044/* 1928/*
2045 * map HIPZ rc to IB retcodes for MR/MW allocations
2046 * Used for hipz_mr_reg_alloc and hipz_mw_alloc.
2047 */
2048int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc)
2049{
2050 switch (hipz_rc) {
2051 case H_SUCCESS: /* successful completion */
2052 return 0;
2053 case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
2054 case H_CONSTRAINED: /* resource constraint */
2055 case H_NO_MEM:
2056 return -ENOMEM;
2057 case H_BUSY: /* long busy */
2058 return -EBUSY;
2059 default:
2060 return -EINVAL;
2061 }
2062} /* end ehca_mrmw_map_hrc_alloc() */
2063
2064/*----------------------------------------------------------------------*/
2065
2066/*
2067 * map HIPZ rc to IB retcodes for MR register rpage
2068 * Used for hipz_h_register_rpage_mr at registering last page
2069 */
2070int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc)
2071{
2072 switch (hipz_rc) {
2073 case H_SUCCESS: /* registration complete */
2074 return 0;
2075 case H_PAGE_REGISTERED: /* page registered */
2076 case H_ADAPTER_PARM: /* invalid adapter handle */
2077 case H_RH_PARM: /* invalid resource handle */
2078/* case H_QT_PARM: invalid queue type */
2079 case H_PARAMETER: /*
2080 * invalid logical address,
2081 * or count zero or greater 512
2082 */
2083 case H_TABLE_FULL: /* page table full */
2084 case H_HARDWARE: /* HCA not operational */
2085 return -EINVAL;
2086 case H_BUSY: /* long busy */
2087 return -EBUSY;
2088 default:
2089 return -EINVAL;
2090 }
2091} /* end ehca_mrmw_map_hrc_rrpg_last() */
2092
2093/*----------------------------------------------------------------------*/
2094
2095/*
2096 * map HIPZ rc to IB retcodes for MR register rpage
2097 * Used for hipz_h_register_rpage_mr at registering one page, but not last page
2098 */
2099int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc)
2100{
2101 switch (hipz_rc) {
2102 case H_PAGE_REGISTERED: /* page registered */
2103 return 0;
2104 case H_SUCCESS: /* registration complete */
2105 case H_ADAPTER_PARM: /* invalid adapter handle */
2106 case H_RH_PARM: /* invalid resource handle */
2107/* case H_QT_PARM: invalid queue type */
2108 case H_PARAMETER: /*
2109 * invalid logical address,
2110 * or count zero or greater 512
2111 */
2112 case H_TABLE_FULL: /* page table full */
2113 case H_HARDWARE: /* HCA not operational */
2114 return -EINVAL;
2115 case H_BUSY: /* long busy */
2116 return -EBUSY;
2117 default:
2118 return -EINVAL;
2119 }
2120} /* end ehca_mrmw_map_hrc_rrpg_notlast() */
2121
2122/*----------------------------------------------------------------------*/
2123
2124/* map HIPZ rc to IB retcodes for MR query. Used for hipz_mr_query. */
2125int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc)
2126{
2127 switch (hipz_rc) {
2128 case H_SUCCESS: /* successful completion */
2129 return 0;
2130 case H_ADAPTER_PARM: /* invalid adapter handle */
2131 case H_RH_PARM: /* invalid resource handle */
2132 return -EINVAL;
2133 case H_BUSY: /* long busy */
2134 return -EBUSY;
2135 default:
2136 return -EINVAL;
2137 }
2138} /* end ehca_mrmw_map_hrc_query_mr() */
2139
2140/*----------------------------------------------------------------------*/
2141/*----------------------------------------------------------------------*/
2142
2143/*
2144 * map HIPZ rc to IB retcodes for freeing MR resource
2145 * Used for hipz_h_free_resource_mr
2146 */
2147int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc)
2148{
2149 switch (hipz_rc) {
2150 case H_SUCCESS: /* resource freed */
2151 return 0;
2152 case H_ADAPTER_PARM: /* invalid adapter handle */
2153 case H_RH_PARM: /* invalid resource handle */
2154 case H_R_STATE: /* invalid resource state */
2155 case H_HARDWARE: /* HCA not operational */
2156 return -EINVAL;
2157 case H_RESOURCE: /* Resource in use */
2158 case H_BUSY: /* long busy */
2159 return -EBUSY;
2160 default:
2161 return -EINVAL;
2162 }
2163} /* end ehca_mrmw_map_hrc_free_mr() */
2164
2165/*----------------------------------------------------------------------*/
2166
2167/*
2168 * map HIPZ rc to IB retcodes for freeing MW resource
2169 * Used for hipz_h_free_resource_mw
2170 */
2171int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc)
2172{
2173 switch (hipz_rc) {
2174 case H_SUCCESS: /* resource freed */
2175 return 0;
2176 case H_ADAPTER_PARM: /* invalid adapter handle */
2177 case H_RH_PARM: /* invalid resource handle */
2178 case H_R_STATE: /* invalid resource state */
2179 case H_HARDWARE: /* HCA not operational */
2180 return -EINVAL;
2181 case H_RESOURCE: /* Resource in use */
2182 case H_BUSY: /* long busy */
2183 return -EBUSY;
2184 default:
2185 return -EINVAL;
2186 }
2187} /* end ehca_mrmw_map_hrc_free_mw() */
2188
2189/*----------------------------------------------------------------------*/
2190
2191/*
2192 * map HIPZ rc to IB retcodes for SMR registrations
2193 * Used for hipz_h_register_smr.
2194 */
2195int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc)
2196{
2197 switch (hipz_rc) {
2198 case H_SUCCESS: /* successful completion */
2199 return 0;
2200 case H_ADAPTER_PARM: /* invalid adapter handle */
2201 case H_RH_PARM: /* invalid resource handle */
2202 case H_MEM_PARM: /* invalid MR virtual address */
2203 case H_MEM_ACCESS_PARM: /* invalid access controls */
2204 case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
2205 return -EINVAL;
2206 case H_BUSY: /* long busy */
2207 return -EBUSY;
2208 default:
2209 return -EINVAL;
2210 }
2211} /* end ehca_mrmw_map_hrc_reg_smr() */
2212
2213/*----------------------------------------------------------------------*/
2214
2215/*
2216 * MR destructor and constructor 1929 * MR destructor and constructor
2217 * used in Reregister MR verb, sets all fields in ehca_mr_t to 0, 1930 * used in Reregister MR verb, sets all fields in ehca_mr_t to 0,
2218 * except struct ib_mr and spinlock 1931 * except struct ib_mr and spinlock
2219 */ 1932 */
2220void ehca_mr_deletenew(struct ehca_mr *mr) 1933void ehca_mr_deletenew(struct ehca_mr *mr)
2221{ 1934{
2222 mr->flags = 0; 1935 mr->flags = 0;
2223 mr->num_pages = 0; 1936 mr->num_kpages = 0;
2224 mr->num_4k = 0; 1937 mr->num_hwpages = 0;
2225 mr->acl = 0; 1938 mr->acl = 0;
2226 mr->start = NULL; 1939 mr->start = NULL;
2227 mr->fmr_page_size = 0; 1940 mr->fmr_page_size = 0;
2228 mr->fmr_max_pages = 0; 1941 mr->fmr_max_pages = 0;
2229 mr->fmr_max_maps = 0; 1942 mr->fmr_max_maps = 0;
2230 mr->fmr_map_cnt = 0; 1943 mr->fmr_map_cnt = 0;
2231 memset(&mr->ipz_mr_handle, 0, sizeof(mr->ipz_mr_handle)); 1944 memset(&mr->ipz_mr_handle, 0, sizeof(mr->ipz_mr_handle));
2232 memset(&mr->galpas, 0, sizeof(mr->galpas)); 1945 memset(&mr->galpas, 0, sizeof(mr->galpas));
2233 mr->nr_of_pages = 0;
2234 mr->pagearray = NULL;
2235} /* end ehca_mr_deletenew() */ 1946} /* end ehca_mr_deletenew() */
2236 1947
2237int ehca_init_mrmw_cache(void) 1948int ehca_init_mrmw_cache(void)
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h
index d936e40a5748..24f13fe3708b 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.h
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h
@@ -101,15 +101,10 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
101 u64 *page_list, 101 u64 *page_list,
102 int list_len); 102 int list_len);
103 103
104int ehca_set_pagebuf(struct ehca_mr *e_mr, 104int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
105 struct ehca_mr_pginfo *pginfo,
106 u32 number, 105 u32 number,
107 u64 *kpage); 106 u64 *kpage);
108 107
109int ehca_set_pagebuf_1(struct ehca_mr *e_mr,
110 struct ehca_mr_pginfo *pginfo,
111 u64 *rpage);
112
113int ehca_mr_is_maxmr(u64 size, 108int ehca_mr_is_maxmr(u64 size,
114 u64 *iova_start); 109 u64 *iova_start);
115 110
@@ -121,20 +116,6 @@ void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl);
121void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, 116void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
122 int *ib_acl); 117 int *ib_acl);
123 118
124int ehca_mrmw_map_hrc_alloc(const u64 hipz_rc);
125
126int ehca_mrmw_map_hrc_rrpg_last(const u64 hipz_rc);
127
128int ehca_mrmw_map_hrc_rrpg_notlast(const u64 hipz_rc);
129
130int ehca_mrmw_map_hrc_query_mr(const u64 hipz_rc);
131
132int ehca_mrmw_map_hrc_free_mr(const u64 hipz_rc);
133
134int ehca_mrmw_map_hrc_free_mw(const u64 hipz_rc);
135
136int ehca_mrmw_map_hrc_reg_smr(const u64 hipz_rc);
137
138void ehca_mr_deletenew(struct ehca_mr *mr); 119void ehca_mr_deletenew(struct ehca_mr *mr);
139 120
140#endif /*_EHCA_MRMW_H_*/ 121#endif /*_EHCA_MRMW_H_*/
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h
index 8707d297ce4c..818803057ebf 100644
--- a/drivers/infiniband/hw/ehca/ehca_qes.h
+++ b/drivers/infiniband/hw/ehca/ehca_qes.h
@@ -53,13 +53,13 @@ struct ehca_vsgentry {
53 u32 length; 53 u32 length;
54}; 54};
55 55
56#define GRH_FLAG_MASK EHCA_BMASK_IBM(7,7) 56#define GRH_FLAG_MASK EHCA_BMASK_IBM( 7, 7)
57#define GRH_IPVERSION_MASK EHCA_BMASK_IBM(0,3) 57#define GRH_IPVERSION_MASK EHCA_BMASK_IBM( 0, 3)
58#define GRH_TCLASS_MASK EHCA_BMASK_IBM(4,12) 58#define GRH_TCLASS_MASK EHCA_BMASK_IBM( 4, 12)
59#define GRH_FLOWLABEL_MASK EHCA_BMASK_IBM(13,31) 59#define GRH_FLOWLABEL_MASK EHCA_BMASK_IBM(13, 31)
60#define GRH_PAYLEN_MASK EHCA_BMASK_IBM(32,47) 60#define GRH_PAYLEN_MASK EHCA_BMASK_IBM(32, 47)
61#define GRH_NEXTHEADER_MASK EHCA_BMASK_IBM(48,55) 61#define GRH_NEXTHEADER_MASK EHCA_BMASK_IBM(48, 55)
62#define GRH_HOPLIMIT_MASK EHCA_BMASK_IBM(56,63) 62#define GRH_HOPLIMIT_MASK EHCA_BMASK_IBM(56, 63)
63 63
64/* 64/*
65 * Unreliable Datagram Address Vector Format 65 * Unreliable Datagram Address Vector Format
@@ -206,10 +206,10 @@ struct ehca_wqe {
206 206
207}; 207};
208 208
209#define WC_SEND_RECEIVE EHCA_BMASK_IBM(0,0) 209#define WC_SEND_RECEIVE EHCA_BMASK_IBM(0, 0)
210#define WC_IMM_DATA EHCA_BMASK_IBM(1,1) 210#define WC_IMM_DATA EHCA_BMASK_IBM(1, 1)
211#define WC_GRH_PRESENT EHCA_BMASK_IBM(2,2) 211#define WC_GRH_PRESENT EHCA_BMASK_IBM(2, 2)
212#define WC_SE_BIT EHCA_BMASK_IBM(3,3) 212#define WC_SE_BIT EHCA_BMASK_IBM(3, 3)
213#define WC_STATUS_ERROR_BIT 0x80000000 213#define WC_STATUS_ERROR_BIT 0x80000000
214#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800 214#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800
215#define WC_STATUS_PURGE_BIT 0x10 215#define WC_STATUS_PURGE_BIT 0x10
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 74671250303f..48e9ceacd6fa 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -602,10 +602,10 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
602 /* UD circumvention */ 602 /* UD circumvention */
603 parms.act_nr_send_sges -= 2; 603 parms.act_nr_send_sges -= 2;
604 parms.act_nr_recv_sges -= 2; 604 parms.act_nr_recv_sges -= 2;
605 swqe_size = offsetof(struct ehca_wqe, 605 swqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[
606 u.ud_av.sg_list[parms.act_nr_send_sges]); 606 parms.act_nr_send_sges]);
607 rwqe_size = offsetof(struct ehca_wqe, 607 rwqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[
608 u.ud_av.sg_list[parms.act_nr_recv_sges]); 608 parms.act_nr_recv_sges]);
609 } 609 }
610 610
611 if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) { 611 if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) {
@@ -690,8 +690,8 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd,
690 if (my_qp->send_cq) { 690 if (my_qp->send_cq) {
691 ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp); 691 ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp);
692 if (ret) { 692 if (ret) {
693 ehca_err(pd->device, "Couldn't assign qp to send_cq ret=%x", 693 ehca_err(pd->device,
694 ret); 694 "Couldn't assign qp to send_cq ret=%x", ret);
695 goto create_qp_exit4; 695 goto create_qp_exit4;
696 } 696 }
697 } 697 }
@@ -749,7 +749,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
749 struct ehca_qp *ret; 749 struct ehca_qp *ret;
750 750
751 ret = internal_create_qp(pd, qp_init_attr, NULL, udata, 0); 751 ret = internal_create_qp(pd, qp_init_attr, NULL, udata, 0);
752 return IS_ERR(ret) ? (struct ib_qp *) ret : &ret->ib_qp; 752 return IS_ERR(ret) ? (struct ib_qp *)ret : &ret->ib_qp;
753} 753}
754 754
755int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, 755int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
@@ -780,7 +780,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd,
780 780
781 my_qp = internal_create_qp(pd, &qp_init_attr, srq_init_attr, udata, 1); 781 my_qp = internal_create_qp(pd, &qp_init_attr, srq_init_attr, udata, 1);
782 if (IS_ERR(my_qp)) 782 if (IS_ERR(my_qp))
783 return (struct ib_srq *) my_qp; 783 return (struct ib_srq *)my_qp;
784 784
785 /* copy back return values */ 785 /* copy back return values */
786 srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr; 786 srq_init_attr->attr.max_wr = qp_init_attr.cap.max_recv_wr;
@@ -875,7 +875,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
875 my_qp, qp_num, h_ret); 875 my_qp, qp_num, h_ret);
876 return ehca2ib_return_code(h_ret); 876 return ehca2ib_return_code(h_ret);
877 } 877 }
878 bad_send_wqe_p = (void*)((u64)bad_send_wqe_p & (~(1L<<63))); 878 bad_send_wqe_p = (void *)((u64)bad_send_wqe_p & (~(1L << 63)));
879 ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p", 879 ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p",
880 qp_num, bad_send_wqe_p); 880 qp_num, bad_send_wqe_p);
881 /* convert wqe pointer to vadr */ 881 /* convert wqe pointer to vadr */
@@ -890,7 +890,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
890 } 890 }
891 891
892 /* loop sets wqe's purge bit */ 892 /* loop sets wqe's purge bit */
893 wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs); 893 wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs);
894 *bad_wqe_cnt = 0; 894 *bad_wqe_cnt = 0;
895 while (wqe->optype != 0xff && wqe->wqef != 0xff) { 895 while (wqe->optype != 0xff && wqe->wqef != 0xff) {
896 if (ehca_debug_level) 896 if (ehca_debug_level)
@@ -898,7 +898,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
898 wqe->nr_of_data_seg = 0; /* suppress data access */ 898 wqe->nr_of_data_seg = 0; /* suppress data access */
899 wqe->wqef = WQEF_PURGE; /* WQE to be purged */ 899 wqe->wqef = WQEF_PURGE; /* WQE to be purged */
900 q_ofs = ipz_queue_advance_offset(squeue, q_ofs); 900 q_ofs = ipz_queue_advance_offset(squeue, q_ofs);
901 wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs); 901 wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs);
902 *bad_wqe_cnt = (*bad_wqe_cnt)+1; 902 *bad_wqe_cnt = (*bad_wqe_cnt)+1;
903 } 903 }
904 /* 904 /*
@@ -1003,7 +1003,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1003 goto modify_qp_exit1; 1003 goto modify_qp_exit1;
1004 } 1004 }
1005 1005
1006 ehca_dbg(ibqp->device,"ehca_qp=%p qp_num=%x current qp_state=%x " 1006 ehca_dbg(ibqp->device, "ehca_qp=%p qp_num=%x current qp_state=%x "
1007 "new qp_state=%x attribute_mask=%x", 1007 "new qp_state=%x attribute_mask=%x",
1008 my_qp, ibqp->qp_num, qp_cur_state, attr->qp_state, attr_mask); 1008 my_qp, ibqp->qp_num, qp_cur_state, attr->qp_state, attr_mask);
1009 1009
@@ -1019,7 +1019,8 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1019 goto modify_qp_exit1; 1019 goto modify_qp_exit1;
1020 } 1020 }
1021 1021
1022 if ((mqpcb->qp_state = ib2ehca_qp_state(qp_new_state))) 1022 mqpcb->qp_state = ib2ehca_qp_state(qp_new_state);
1023 if (mqpcb->qp_state)
1023 update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1); 1024 update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
1024 else { 1025 else {
1025 ret = -EINVAL; 1026 ret = -EINVAL;
@@ -1077,7 +1078,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1077 spin_lock_irqsave(&my_qp->spinlock_s, flags); 1078 spin_lock_irqsave(&my_qp->spinlock_s, flags);
1078 squeue_locked = 1; 1079 squeue_locked = 1;
1079 /* mark next free wqe */ 1080 /* mark next free wqe */
1080 wqe = (struct ehca_wqe*) 1081 wqe = (struct ehca_wqe *)
1081 ipz_qeit_get(&my_qp->ipz_squeue); 1082 ipz_qeit_get(&my_qp->ipz_squeue);
1082 wqe->optype = wqe->wqef = 0xff; 1083 wqe->optype = wqe->wqef = 0xff;
1083 ehca_dbg(ibqp->device, "qp_num=%x next_free_wqe=%p", 1084 ehca_dbg(ibqp->device, "qp_num=%x next_free_wqe=%p",
@@ -1312,7 +1313,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1312 if (h_ret != H_SUCCESS) { 1313 if (h_ret != H_SUCCESS) {
1313 ret = ehca2ib_return_code(h_ret); 1314 ret = ehca2ib_return_code(h_ret);
1314 ehca_err(ibqp->device, "hipz_h_modify_qp() failed rc=%lx " 1315 ehca_err(ibqp->device, "hipz_h_modify_qp() failed rc=%lx "
1315 "ehca_qp=%p qp_num=%x",h_ret, my_qp, ibqp->qp_num); 1316 "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num);
1316 goto modify_qp_exit2; 1317 goto modify_qp_exit2;
1317 } 1318 }
1318 1319
@@ -1411,7 +1412,7 @@ int ehca_query_qp(struct ib_qp *qp,
1411 } 1412 }
1412 1413
1413 if (qp_attr_mask & QP_ATTR_QUERY_NOT_SUPPORTED) { 1414 if (qp_attr_mask & QP_ATTR_QUERY_NOT_SUPPORTED) {
1414 ehca_err(qp->device,"Invalid attribute mask " 1415 ehca_err(qp->device, "Invalid attribute mask "
1415 "ehca_qp=%p qp_num=%x qp_attr_mask=%x ", 1416 "ehca_qp=%p qp_num=%x qp_attr_mask=%x ",
1416 my_qp, qp->qp_num, qp_attr_mask); 1417 my_qp, qp->qp_num, qp_attr_mask);
1417 return -EINVAL; 1418 return -EINVAL;
@@ -1419,7 +1420,7 @@ int ehca_query_qp(struct ib_qp *qp,
1419 1420
1420 qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 1421 qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
1421 if (!qpcb) { 1422 if (!qpcb) {
1422 ehca_err(qp->device,"Out of memory for qpcb " 1423 ehca_err(qp->device, "Out of memory for qpcb "
1423 "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); 1424 "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num);
1424 return -ENOMEM; 1425 return -ENOMEM;
1425 } 1426 }
@@ -1431,7 +1432,7 @@ int ehca_query_qp(struct ib_qp *qp,
1431 1432
1432 if (h_ret != H_SUCCESS) { 1433 if (h_ret != H_SUCCESS) {
1433 ret = ehca2ib_return_code(h_ret); 1434 ret = ehca2ib_return_code(h_ret);
1434 ehca_err(qp->device,"hipz_h_query_qp() failed " 1435 ehca_err(qp->device, "hipz_h_query_qp() failed "
1435 "ehca_qp=%p qp_num=%x h_ret=%lx", 1436 "ehca_qp=%p qp_num=%x h_ret=%lx",
1436 my_qp, qp->qp_num, h_ret); 1437 my_qp, qp->qp_num, h_ret);
1437 goto query_qp_exit1; 1438 goto query_qp_exit1;
@@ -1442,7 +1443,7 @@ int ehca_query_qp(struct ib_qp *qp,
1442 1443
1443 if (qp_attr->cur_qp_state == -EINVAL) { 1444 if (qp_attr->cur_qp_state == -EINVAL) {
1444 ret = -EINVAL; 1445 ret = -EINVAL;
1445 ehca_err(qp->device,"Got invalid ehca_qp_state=%x " 1446 ehca_err(qp->device, "Got invalid ehca_qp_state=%x "
1446 "ehca_qp=%p qp_num=%x", 1447 "ehca_qp=%p qp_num=%x",
1447 qpcb->qp_state, my_qp, qp->qp_num); 1448 qpcb->qp_state, my_qp, qp->qp_num);
1448 goto query_qp_exit1; 1449 goto query_qp_exit1;
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 61da65e6e5e0..94eed70fedf5 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -79,7 +79,8 @@ static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue,
79 } 79 }
80 80
81 if (ehca_debug_level) { 81 if (ehca_debug_level) {
82 ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", ipz_rqueue); 82 ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p",
83 ipz_rqueue);
83 ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe"); 84 ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe");
84 } 85 }
85 86
@@ -99,7 +100,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
99 struct ib_mad_hdr *mad_hdr = send_wr->wr.ud.mad_hdr; 100 struct ib_mad_hdr *mad_hdr = send_wr->wr.ud.mad_hdr;
100 struct ib_sge *sge = send_wr->sg_list; 101 struct ib_sge *sge = send_wr->sg_list;
101 ehca_gen_dbg("send_wr#%x wr_id=%lx num_sge=%x " 102 ehca_gen_dbg("send_wr#%x wr_id=%lx num_sge=%x "
102 "send_flags=%x opcode=%x",idx, send_wr->wr_id, 103 "send_flags=%x opcode=%x", idx, send_wr->wr_id,
103 send_wr->num_sge, send_wr->send_flags, 104 send_wr->num_sge, send_wr->send_flags,
104 send_wr->opcode); 105 send_wr->opcode);
105 if (mad_hdr) { 106 if (mad_hdr) {
@@ -116,7 +117,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
116 mad_hdr->attr_mod); 117 mad_hdr->attr_mod);
117 } 118 }
118 for (j = 0; j < send_wr->num_sge; j++) { 119 for (j = 0; j < send_wr->num_sge; j++) {
119 u8 *data = (u8 *) abs_to_virt(sge->addr); 120 u8 *data = (u8 *)abs_to_virt(sge->addr);
120 ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x " 121 ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x "
121 "lkey=%x", 122 "lkey=%x",
122 idx, j, data, sge->length, sge->lkey); 123 idx, j, data, sge->length, sge->lkey);
@@ -534,9 +535,11 @@ poll_cq_one_read_cqe:
534 535
535 cqe_count++; 536 cqe_count++;
536 if (unlikely(cqe->status & WC_STATUS_PURGE_BIT)) { 537 if (unlikely(cqe->status & WC_STATUS_PURGE_BIT)) {
537 struct ehca_qp *qp=ehca_cq_get_qp(my_cq, cqe->local_qp_number); 538 struct ehca_qp *qp;
538 int purgeflag; 539 int purgeflag;
539 unsigned long flags; 540 unsigned long flags;
541
542 qp = ehca_cq_get_qp(my_cq, cqe->local_qp_number);
540 if (!qp) { 543 if (!qp) {
541 ehca_err(cq->device, "cq_num=%x qp_num=%x " 544 ehca_err(cq->device, "cq_num=%x qp_num=%x "
542 "could not find qp -> ignore cqe", 545 "could not find qp -> ignore cqe",
@@ -551,8 +554,8 @@ poll_cq_one_read_cqe:
551 spin_unlock_irqrestore(&qp->spinlock_s, flags); 554 spin_unlock_irqrestore(&qp->spinlock_s, flags);
552 555
553 if (purgeflag) { 556 if (purgeflag) {
554 ehca_dbg(cq->device, "Got CQE with purged bit qp_num=%x " 557 ehca_dbg(cq->device,
555 "src_qp=%x", 558 "Got CQE with purged bit qp_num=%x src_qp=%x",
556 cqe->local_qp_number, cqe->remote_qp_number); 559 cqe->local_qp_number, cqe->remote_qp_number);
557 if (ehca_debug_level) 560 if (ehca_debug_level)
558 ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x", 561 ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x",
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 03b185f873da..678b81391861 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -93,14 +93,14 @@ extern int ehca_debug_level;
93#define ehca_gen_dbg(format, arg...) \ 93#define ehca_gen_dbg(format, arg...) \
94 do { \ 94 do { \
95 if (unlikely(ehca_debug_level)) \ 95 if (unlikely(ehca_debug_level)) \
96 printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n",\ 96 printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n", \
97 get_paca()->paca_index, __FUNCTION__, ## arg); \ 97 get_paca()->paca_index, __FUNCTION__, ## arg); \
98 } while (0) 98 } while (0)
99 99
100#define ehca_gen_warn(format, arg...) \ 100#define ehca_gen_warn(format, arg...) \
101 do { \ 101 do { \
102 if (unlikely(ehca_debug_level)) \ 102 if (unlikely(ehca_debug_level)) \
103 printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n",\ 103 printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n", \
104 get_paca()->paca_index, __FUNCTION__, ## arg); \ 104 get_paca()->paca_index, __FUNCTION__, ## arg); \
105 } while (0) 105 } while (0)
106 106
@@ -114,12 +114,12 @@ extern int ehca_debug_level;
114 * <format string> adr=X ofs=Y <8 bytes hex> <8 bytes hex> 114 * <format string> adr=X ofs=Y <8 bytes hex> <8 bytes hex>
115 */ 115 */
116#define ehca_dmp(adr, len, format, args...) \ 116#define ehca_dmp(adr, len, format, args...) \
117 do { \ 117 do { \
118 unsigned int x; \ 118 unsigned int x; \
119 unsigned int l = (unsigned int)(len); \ 119 unsigned int l = (unsigned int)(len); \
120 unsigned char *deb = (unsigned char*)(adr); \ 120 unsigned char *deb = (unsigned char *)(adr); \
121 for (x = 0; x < l; x += 16) { \ 121 for (x = 0; x < l; x += 16) { \
122 printk("EHCA_DMP:%s " format \ 122 printk(KERN_INFO "EHCA_DMP:%s " format \
123 " adr=%p ofs=%04x %016lx %016lx\n", \ 123 " adr=%p ofs=%04x %016lx %016lx\n", \
124 __FUNCTION__, ##args, deb, x, \ 124 __FUNCTION__, ##args, deb, x, \
125 *((u64 *)&deb[0]), *((u64 *)&deb[8])); \ 125 *((u64 *)&deb[0]), *((u64 *)&deb[8])); \
@@ -128,16 +128,16 @@ extern int ehca_debug_level;
128 } while (0) 128 } while (0)
129 129
130/* define a bitmask, little endian version */ 130/* define a bitmask, little endian version */
131#define EHCA_BMASK(pos,length) (((pos)<<16)+(length)) 131#define EHCA_BMASK(pos, length) (((pos) << 16) + (length))
132 132
133/* define a bitmask, the ibm way... */ 133/* define a bitmask, the ibm way... */
134#define EHCA_BMASK_IBM(from,to) (((63-to)<<16)+((to)-(from)+1)) 134#define EHCA_BMASK_IBM(from, to) (((63 - to) << 16) + ((to) - (from) + 1))
135 135
136/* internal function, don't use */ 136/* internal function, don't use */
137#define EHCA_BMASK_SHIFTPOS(mask) (((mask)>>16)&0xffff) 137#define EHCA_BMASK_SHIFTPOS(mask) (((mask) >> 16) & 0xffff)
138 138
139/* internal function, don't use */ 139/* internal function, don't use */
140#define EHCA_BMASK_MASK(mask) (0xffffffffffffffffULL >> ((64-(mask))&0xffff)) 140#define EHCA_BMASK_MASK(mask) (~0ULL >> ((64 - (mask)) & 0xffff))
141 141
142/** 142/**
143 * EHCA_BMASK_SET - return value shifted and masked by mask 143 * EHCA_BMASK_SET - return value shifted and masked by mask
@@ -145,14 +145,14 @@ extern int ehca_debug_level;
145 * variable&=~EHCA_BMASK_SET(MY_MASK,-1) clears the bits from the mask 145 * variable&=~EHCA_BMASK_SET(MY_MASK,-1) clears the bits from the mask
146 * in variable 146 * in variable
147 */ 147 */
148#define EHCA_BMASK_SET(mask,value) \ 148#define EHCA_BMASK_SET(mask, value) \
149 ((EHCA_BMASK_MASK(mask) & ((u64)(value)))<<EHCA_BMASK_SHIFTPOS(mask)) 149 ((EHCA_BMASK_MASK(mask) & ((u64)(value))) << EHCA_BMASK_SHIFTPOS(mask))
150 150
151/** 151/**
152 * EHCA_BMASK_GET - extract a parameter from value by mask 152 * EHCA_BMASK_GET - extract a parameter from value by mask
153 */ 153 */
154#define EHCA_BMASK_GET(mask,value) \ 154#define EHCA_BMASK_GET(mask, value) \
155 (EHCA_BMASK_MASK(mask)& (((u64)(value))>>EHCA_BMASK_SHIFTPOS(mask))) 155 (EHCA_BMASK_MASK(mask) & (((u64)(value)) >> EHCA_BMASK_SHIFTPOS(mask)))
156 156
157 157
158/* Converts ehca to ib return code */ 158/* Converts ehca to ib return code */
@@ -161,8 +161,11 @@ static inline int ehca2ib_return_code(u64 ehca_rc)
161 switch (ehca_rc) { 161 switch (ehca_rc) {
162 case H_SUCCESS: 162 case H_SUCCESS:
163 return 0; 163 return 0;
164 case H_RESOURCE: /* Resource in use */
164 case H_BUSY: 165 case H_BUSY:
165 return -EBUSY; 166 return -EBUSY;
167 case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */
168 case H_CONSTRAINED: /* resource constraint */
166 case H_NO_MEM: 169 case H_NO_MEM:
167 return -ENOMEM; 170 return -ENOMEM;
168 default: 171 default:
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 3031b3bb56f9..05c415744e3b 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -70,7 +70,7 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context)
70 70
71static void ehca_mm_open(struct vm_area_struct *vma) 71static void ehca_mm_open(struct vm_area_struct *vma)
72{ 72{
73 u32 *count = (u32*)vma->vm_private_data; 73 u32 *count = (u32 *)vma->vm_private_data;
74 if (!count) { 74 if (!count) {
75 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx", 75 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
76 vma->vm_start, vma->vm_end); 76 vma->vm_start, vma->vm_end);
@@ -86,7 +86,7 @@ static void ehca_mm_open(struct vm_area_struct *vma)
86 86
87static void ehca_mm_close(struct vm_area_struct *vma) 87static void ehca_mm_close(struct vm_area_struct *vma)
88{ 88{
89 u32 *count = (u32*)vma->vm_private_data; 89 u32 *count = (u32 *)vma->vm_private_data;
90 if (!count) { 90 if (!count) {
91 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx", 91 ehca_gen_err("Invalid vma struct vm_start=%lx vm_end=%lx",
92 vma->vm_start, vma->vm_end); 92 vma->vm_start, vma->vm_end);
@@ -215,7 +215,8 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
215 case 2: /* qp rqueue_addr */ 215 case 2: /* qp rqueue_addr */
216 ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue", 216 ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue",
217 qp->ib_qp.qp_num); 217 qp->ib_qp.qp_num);
218 ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, &qp->mm_count_rqueue); 218 ret = ehca_mmap_queue(vma, &qp->ipz_rqueue,
219 &qp->mm_count_rqueue);
219 if (unlikely(ret)) { 220 if (unlikely(ret)) {
220 ehca_err(qp->ib_qp.device, 221 ehca_err(qp->ib_qp.device,
221 "ehca_mmap_queue(rq) failed rc=%x qp_num=%x", 222 "ehca_mmap_queue(rq) failed rc=%x qp_num=%x",
@@ -227,7 +228,8 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
227 case 3: /* qp squeue_addr */ 228 case 3: /* qp squeue_addr */
228 ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue", 229 ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue",
229 qp->ib_qp.qp_num); 230 qp->ib_qp.qp_num);
230 ret = ehca_mmap_queue(vma, &qp->ipz_squeue, &qp->mm_count_squeue); 231 ret = ehca_mmap_queue(vma, &qp->ipz_squeue,
232 &qp->mm_count_squeue);
231 if (unlikely(ret)) { 233 if (unlikely(ret)) {
232 ehca_err(qp->ib_qp.device, 234 ehca_err(qp->ib_qp.device,
233 "ehca_mmap_queue(sq) failed rc=%x qp_num=%x", 235 "ehca_mmap_queue(sq) failed rc=%x qp_num=%x",
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 4776a8b0feec..3394e05f4b4f 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -501,8 +501,8 @@ u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
501 return H_PARAMETER; 501 return H_PARAMETER;
502 } 502 }
503 503
504 return hipz_h_register_rpage(adapter_handle,pagesize,queue_type, 504 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
505 qp_handle.handle,logical_address_of_page, 505 qp_handle.handle, logical_address_of_page,
506 count); 506 count);
507} 507}
508 508
@@ -522,9 +522,9 @@ u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
522 qp_handle.handle, /* r6 */ 522 qp_handle.handle, /* r6 */
523 0, 0, 0, 0, 0, 0); 523 0, 0, 0, 0, 0, 0);
524 if (log_addr_next_sq_wqe2processed) 524 if (log_addr_next_sq_wqe2processed)
525 *log_addr_next_sq_wqe2processed = (void*)outs[0]; 525 *log_addr_next_sq_wqe2processed = (void *)outs[0];
526 if (log_addr_next_rq_wqe2processed) 526 if (log_addr_next_rq_wqe2processed)
527 *log_addr_next_rq_wqe2processed = (void*)outs[1]; 527 *log_addr_next_rq_wqe2processed = (void *)outs[1];
528 528
529 return ret; 529 return ret;
530} 530}
diff --git a/drivers/infiniband/hw/ehca/hcp_phyp.c b/drivers/infiniband/hw/ehca/hcp_phyp.c
index 0b1a4772c78a..214821095cb1 100644
--- a/drivers/infiniband/hw/ehca/hcp_phyp.c
+++ b/drivers/infiniband/hw/ehca/hcp_phyp.c
@@ -50,7 +50,7 @@ int hcall_map_page(u64 physaddr, u64 *mapaddr)
50 50
51int hcall_unmap_page(u64 mapaddr) 51int hcall_unmap_page(u64 mapaddr)
52{ 52{
53 iounmap((volatile void __iomem*)mapaddr); 53 iounmap((volatile void __iomem *) mapaddr);
54 return 0; 54 return 0;
55} 55}
56 56
diff --git a/drivers/infiniband/hw/ehca/hipz_fns_core.h b/drivers/infiniband/hw/ehca/hipz_fns_core.h
index 20898a153446..868735fd3187 100644
--- a/drivers/infiniband/hw/ehca/hipz_fns_core.h
+++ b/drivers/infiniband/hw/ehca/hipz_fns_core.h
@@ -53,10 +53,10 @@
53#define hipz_galpa_load_cq(gal, offset) \ 53#define hipz_galpa_load_cq(gal, offset) \
54 hipz_galpa_load(gal, CQTEMM_OFFSET(offset)) 54 hipz_galpa_load(gal, CQTEMM_OFFSET(offset))
55 55
56#define hipz_galpa_store_qp(gal,offset, value) \ 56#define hipz_galpa_store_qp(gal, offset, value) \
57 hipz_galpa_store(gal, QPTEMM_OFFSET(offset), value) 57 hipz_galpa_store(gal, QPTEMM_OFFSET(offset), value)
58#define hipz_galpa_load_qp(gal, offset) \ 58#define hipz_galpa_load_qp(gal, offset) \
59 hipz_galpa_load(gal,QPTEMM_OFFSET(offset)) 59 hipz_galpa_load(gal, QPTEMM_OFFSET(offset))
60 60
61static inline void hipz_update_sqa(struct ehca_qp *qp, u16 nr_wqes) 61static inline void hipz_update_sqa(struct ehca_qp *qp, u16 nr_wqes)
62{ 62{
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h
index dad6dea5636b..d9739e554515 100644
--- a/drivers/infiniband/hw/ehca/hipz_hw.h
+++ b/drivers/infiniband/hw/ehca/hipz_hw.h
@@ -161,11 +161,11 @@ struct hipz_qptemm {
161/* 0x1000 */ 161/* 0x1000 */
162}; 162};
163 163
164#define QPX_SQADDER EHCA_BMASK_IBM(48,63) 164#define QPX_SQADDER EHCA_BMASK_IBM(48, 63)
165#define QPX_RQADDER EHCA_BMASK_IBM(48,63) 165#define QPX_RQADDER EHCA_BMASK_IBM(48, 63)
166#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3,3) 166#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3, 3)
167 167
168#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x) 168#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm, x)
169 169
170/* MRMWPT Entry Memory Map */ 170/* MRMWPT Entry Memory Map */
171struct hipz_mrmwmm { 171struct hipz_mrmwmm {
@@ -187,7 +187,7 @@ struct hipz_mrmwmm {
187 187
188}; 188};
189 189
190#define MRMWMM_OFFSET(x) offsetof(struct hipz_mrmwmm,x) 190#define MRMWMM_OFFSET(x) offsetof(struct hipz_mrmwmm, x)
191 191
192struct hipz_qpedmm { 192struct hipz_qpedmm {
193 /* 0x00 */ 193 /* 0x00 */
@@ -238,7 +238,7 @@ struct hipz_qpedmm {
238 u64 qpedx_rrva3; 238 u64 qpedx_rrva3;
239}; 239};
240 240
241#define QPEDMM_OFFSET(x) offsetof(struct hipz_qpedmm,x) 241#define QPEDMM_OFFSET(x) offsetof(struct hipz_qpedmm, x)
242 242
243/* CQ Table Entry Memory Map */ 243/* CQ Table Entry Memory Map */
244struct hipz_cqtemm { 244struct hipz_cqtemm {
@@ -263,12 +263,12 @@ struct hipz_cqtemm {
263/* 0x1000 */ 263/* 0x1000 */
264}; 264};
265 265
266#define CQX_FEC_CQE_CNT EHCA_BMASK_IBM(32,63) 266#define CQX_FEC_CQE_CNT EHCA_BMASK_IBM(32, 63)
267#define CQX_FECADDER EHCA_BMASK_IBM(32,63) 267#define CQX_FECADDER EHCA_BMASK_IBM(32, 63)
268#define CQX_N0_GENERATE_SOLICITED_COMP_EVENT EHCA_BMASK_IBM(0,0) 268#define CQX_N0_GENERATE_SOLICITED_COMP_EVENT EHCA_BMASK_IBM(0, 0)
269#define CQX_N1_GENERATE_COMP_EVENT EHCA_BMASK_IBM(0,0) 269#define CQX_N1_GENERATE_COMP_EVENT EHCA_BMASK_IBM(0, 0)
270 270
271#define CQTEMM_OFFSET(x) offsetof(struct hipz_cqtemm,x) 271#define CQTEMM_OFFSET(x) offsetof(struct hipz_cqtemm, x)
272 272
273/* EQ Table Entry Memory Map */ 273/* EQ Table Entry Memory Map */
274struct hipz_eqtemm { 274struct hipz_eqtemm {
@@ -293,7 +293,7 @@ struct hipz_eqtemm {
293 293
294}; 294};
295 295
296#define EQTEMM_OFFSET(x) offsetof(struct hipz_eqtemm,x) 296#define EQTEMM_OFFSET(x) offsetof(struct hipz_eqtemm, x)
297 297
298/* access control defines for MR/MW */ 298/* access control defines for MR/MW */
299#define HIPZ_ACCESSCTRL_L_WRITE 0x00800000 299#define HIPZ_ACCESSCTRL_L_WRITE 0x00800000
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index bf7a40088f61..9606f13ed092 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -114,7 +114,7 @@ int ipz_queue_ctor(struct ipz_queue *queue,
114 */ 114 */
115 f = 0; 115 f = 0;
116 while (f < nr_of_pages) { 116 while (f < nr_of_pages) {
117 u8 *kpage = (u8*)get_zeroed_page(GFP_KERNEL); 117 u8 *kpage = (u8 *)get_zeroed_page(GFP_KERNEL);
118 int k; 118 int k;
119 if (!kpage) 119 if (!kpage)
120 goto ipz_queue_ctor_exit0; /*NOMEM*/ 120 goto ipz_queue_ctor_exit0; /*NOMEM*/
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index 007f0882fd40..39a4f64aff41 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -240,7 +240,7 @@ void *ipz_qeit_eq_get_inc(struct ipz_queue *queue);
240static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue) 240static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
241{ 241{
242 void *ret = ipz_qeit_get(queue); 242 void *ret = ipz_qeit_get(queue);
243 u32 qe = *(u8 *) ret; 243 u32 qe = *(u8 *)ret;
244 if ((qe >> 7) != (queue->toggle_state & 1)) 244 if ((qe >> 7) != (queue->toggle_state & 1))
245 return NULL; 245 return NULL;
246 ipz_qeit_eq_get_inc(queue); /* this is a good one */ 246 ipz_qeit_eq_get_inc(queue); /* this is a good one */
@@ -250,7 +250,7 @@ static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
250static inline void *ipz_eqit_eq_peek_valid(struct ipz_queue *queue) 250static inline void *ipz_eqit_eq_peek_valid(struct ipz_queue *queue)
251{ 251{
252 void *ret = ipz_qeit_get(queue); 252 void *ret = ipz_qeit_get(queue);
253 u32 qe = *(u8 *) ret; 253 u32 qe = *(u8 *)ret;
254 if ((qe >> 7) != (queue->toggle_state & 1)) 254 if ((qe >> 7) != (queue->toggle_state & 1))
255 return NULL; 255 return NULL;
256 return ret; 256 return ret;
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 9361f5ab8bd6..09c5fd84b1e3 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -1889,7 +1889,7 @@ void ipath_write_kreg_port(const struct ipath_devdata *dd, ipath_kreg regno,
1889/* Below is "non-zero" to force override, but both actual LEDs are off */ 1889/* Below is "non-zero" to force override, but both actual LEDs are off */
1890#define LED_OVER_BOTH_OFF (8) 1890#define LED_OVER_BOTH_OFF (8)
1891 1891
1892void ipath_run_led_override(unsigned long opaque) 1892static void ipath_run_led_override(unsigned long opaque)
1893{ 1893{
1894 struct ipath_devdata *dd = (struct ipath_devdata *)opaque; 1894 struct ipath_devdata *dd = (struct ipath_devdata *)opaque;
1895 int timeoff; 1895 int timeoff;
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c
index 6b9147964a4f..b4503e9c1e95 100644
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c
@@ -426,8 +426,8 @@ bail:
426 * @buffer: data to write 426 * @buffer: data to write
427 * @len: number of bytes to write 427 * @len: number of bytes to write
428 */ 428 */
429int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offset, 429static int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offset,
430 const void *buffer, int len) 430 const void *buffer, int len)
431{ 431{
432 u8 single_byte; 432 u8 single_byte;
433 int sub_len; 433 int sub_len;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 47aa43428fbf..1fd91c59f246 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -70,7 +70,7 @@ static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum)
70 * If rewrite is true, and bits are set in the sendbufferror registers, 70 * If rewrite is true, and bits are set in the sendbufferror registers,
71 * we'll write to the buffer, for error recovery on parity errors. 71 * we'll write to the buffer, for error recovery on parity errors.
72 */ 72 */
73void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite) 73static void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
74{ 74{
75 u32 piobcnt; 75 u32 piobcnt;
76 unsigned long sbuf[4]; 76 unsigned long sbuf[4];
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 3105005fc9d2..ace63ef78e6f 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -776,7 +776,6 @@ void ipath_get_eeprom_info(struct ipath_devdata *);
776int ipath_update_eeprom_log(struct ipath_devdata *dd); 776int ipath_update_eeprom_log(struct ipath_devdata *dd);
777void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr); 777void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
778u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); 778u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
779void ipath_disarm_senderrbufs(struct ipath_devdata *, int);
780 779
781/* 780/*
782 * Set LED override, only the two LSBs have "public" meaning, but 781 * Set LED override, only the two LSBs have "public" meaning, but
@@ -820,7 +819,6 @@ static inline u64 ipath_mdio_req(int cmd, int dev, int reg, int data)
820#define IPATH_MDIO_CTRL_8355_REG_10 0x1D 819#define IPATH_MDIO_CTRL_8355_REG_10 0x1D
821 820
822int ipath_get_user_pages(unsigned long, size_t, struct page **); 821int ipath_get_user_pages(unsigned long, size_t, struct page **);
823int ipath_get_user_pages_nocopy(unsigned long, struct page **);
824void ipath_release_user_pages(struct page **, size_t); 822void ipath_release_user_pages(struct page **, size_t);
825void ipath_release_user_pages_on_close(struct page **, size_t); 823void ipath_release_user_pages_on_close(struct page **, size_t);
826int ipath_eeprom_read(struct ipath_devdata *, u8, void *, int); 824int ipath_eeprom_read(struct ipath_devdata *, u8, void *, int);
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 85256747d8a1..c69c25239443 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -507,7 +507,7 @@ static int want_buffer(struct ipath_devdata *dd)
507 * 507 *
508 * Called when we run out of PIO buffers. 508 * Called when we run out of PIO buffers.
509 */ 509 */
510void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev) 510static void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
511{ 511{
512 unsigned long flags; 512 unsigned long flags;
513 513
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 27034d38b3dd..0190edc8044e 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -171,32 +171,6 @@ int ipath_get_user_pages(unsigned long start_page, size_t num_pages,
171 return ret; 171 return ret;
172} 172}
173 173
174/**
175 * ipath_get_user_pages_nocopy - lock a single page for I/O and mark shared
176 * @start_page: the page to lock
177 * @p: the output page structure
178 *
179 * This is similar to ipath_get_user_pages, but it's always one page, and we
180 * mark the page as locked for I/O, and shared. This is used for the user
181 * process page that contains the destination address for the rcvhdrq tail
182 * update, so we need to have the vma. If we don't do this, the page can be
183 * taken away from us on fork, even if the child never touches it, and then
184 * the user process never sees the tail register updates.
185 */
186int ipath_get_user_pages_nocopy(unsigned long page, struct page **p)
187{
188 struct vm_area_struct *vma;
189 int ret;
190
191 down_write(&current->mm->mmap_sem);
192
193 ret = __get_user_pages(page, 1, p, &vma);
194
195 up_write(&current->mm->mmap_sem);
196
197 return ret;
198}
199
200void ipath_release_user_pages(struct page **p, size_t num_pages) 174void ipath_release_user_pages(struct page **p, size_t num_pages)
201{ 175{
202 down_write(&current->mm->mmap_sem); 176 down_write(&current->mm->mmap_sem);
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 65f7181e9cf8..16aa61fd8085 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -488,7 +488,7 @@ bail:;
488 * This is called from ipath_do_rcv_timer() at interrupt level to check for 488 * This is called from ipath_do_rcv_timer() at interrupt level to check for
489 * QPs which need retransmits and to collect performance numbers. 489 * QPs which need retransmits and to collect performance numbers.
490 */ 490 */
491void ipath_ib_timer(struct ipath_ibdev *dev) 491static void ipath_ib_timer(struct ipath_ibdev *dev)
492{ 492{
493 struct ipath_qp *resend = NULL; 493 struct ipath_qp *resend = NULL;
494 struct list_head *last; 494 struct list_head *last;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index f3d1f2cee6f8..9bbe81967f14 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -782,8 +782,6 @@ void ipath_update_mmap_info(struct ipath_ibdev *dev,
782 782
783int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); 783int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
784 784
785void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev);
786
787void ipath_insert_rnr_queue(struct ipath_qp *qp); 785void ipath_insert_rnr_queue(struct ipath_qp *qp);
788 786
789int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); 787int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only);
@@ -807,8 +805,6 @@ void ipath_ib_rcv(struct ipath_ibdev *, void *, void *, u32);
807 805
808int ipath_ib_piobufavail(struct ipath_ibdev *); 806int ipath_ib_piobufavail(struct ipath_ibdev *);
809 807
810void ipath_ib_timer(struct ipath_ibdev *);
811
812unsigned ipath_get_npkeys(struct ipath_devdata *); 808unsigned ipath_get_npkeys(struct ipath_devdata *);
813 809
814u32 ipath_get_cr_errpkey(struct ipath_devdata *); 810u32 ipath_get_cr_errpkey(struct ipath_devdata *);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 40042184ad58..b5a24fbef70d 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1183,6 +1183,43 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1183 return cur + nreq >= wq->max_post; 1183 return cur + nreq >= wq->max_post;
1184} 1184}
1185 1185
1186static __always_inline void set_raddr_seg(struct mlx4_wqe_raddr_seg *rseg,
1187 u64 remote_addr, u32 rkey)
1188{
1189 rseg->raddr = cpu_to_be64(remote_addr);
1190 rseg->rkey = cpu_to_be32(rkey);
1191 rseg->reserved = 0;
1192}
1193
1194static void set_atomic_seg(struct mlx4_wqe_atomic_seg *aseg, struct ib_send_wr *wr)
1195{
1196 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
1197 aseg->swap_add = cpu_to_be64(wr->wr.atomic.swap);
1198 aseg->compare = cpu_to_be64(wr->wr.atomic.compare_add);
1199 } else {
1200 aseg->swap_add = cpu_to_be64(wr->wr.atomic.compare_add);
1201 aseg->compare = 0;
1202 }
1203
1204}
1205
1206static void set_datagram_seg(struct mlx4_wqe_datagram_seg *dseg,
1207 struct ib_send_wr *wr)
1208{
1209 memcpy(dseg->av, &to_mah(wr->wr.ud.ah)->av, sizeof (struct mlx4_av));
1210 dseg->dqpn = cpu_to_be32(wr->wr.ud.remote_qpn);
1211 dseg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey);
1212
1213}
1214
1215static void set_data_seg(struct mlx4_wqe_data_seg *dseg,
1216 struct ib_sge *sg)
1217{
1218 dseg->byte_count = cpu_to_be32(sg->length);
1219 dseg->lkey = cpu_to_be32(sg->lkey);
1220 dseg->addr = cpu_to_be64(sg->addr);
1221}
1222
1186int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 1223int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1187 struct ib_send_wr **bad_wr) 1224 struct ib_send_wr **bad_wr)
1188{ 1225{
@@ -1238,26 +1275,13 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1238 switch (wr->opcode) { 1275 switch (wr->opcode) {
1239 case IB_WR_ATOMIC_CMP_AND_SWP: 1276 case IB_WR_ATOMIC_CMP_AND_SWP:
1240 case IB_WR_ATOMIC_FETCH_AND_ADD: 1277 case IB_WR_ATOMIC_FETCH_AND_ADD:
1241 ((struct mlx4_wqe_raddr_seg *) wqe)->raddr = 1278 set_raddr_seg(wqe, wr->wr.atomic.remote_addr,
1242 cpu_to_be64(wr->wr.atomic.remote_addr); 1279 wr->wr.atomic.rkey);
1243 ((struct mlx4_wqe_raddr_seg *) wqe)->rkey =
1244 cpu_to_be32(wr->wr.atomic.rkey);
1245 ((struct mlx4_wqe_raddr_seg *) wqe)->reserved = 0;
1246
1247 wqe += sizeof (struct mlx4_wqe_raddr_seg); 1280 wqe += sizeof (struct mlx4_wqe_raddr_seg);
1248 1281
1249 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) { 1282 set_atomic_seg(wqe, wr);
1250 ((struct mlx4_wqe_atomic_seg *) wqe)->swap_add =
1251 cpu_to_be64(wr->wr.atomic.swap);
1252 ((struct mlx4_wqe_atomic_seg *) wqe)->compare =
1253 cpu_to_be64(wr->wr.atomic.compare_add);
1254 } else {
1255 ((struct mlx4_wqe_atomic_seg *) wqe)->swap_add =
1256 cpu_to_be64(wr->wr.atomic.compare_add);
1257 ((struct mlx4_wqe_atomic_seg *) wqe)->compare = 0;
1258 }
1259
1260 wqe += sizeof (struct mlx4_wqe_atomic_seg); 1283 wqe += sizeof (struct mlx4_wqe_atomic_seg);
1284
1261 size += (sizeof (struct mlx4_wqe_raddr_seg) + 1285 size += (sizeof (struct mlx4_wqe_raddr_seg) +
1262 sizeof (struct mlx4_wqe_atomic_seg)) / 16; 1286 sizeof (struct mlx4_wqe_atomic_seg)) / 16;
1263 1287
@@ -1266,15 +1290,10 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1266 case IB_WR_RDMA_READ: 1290 case IB_WR_RDMA_READ:
1267 case IB_WR_RDMA_WRITE: 1291 case IB_WR_RDMA_WRITE:
1268 case IB_WR_RDMA_WRITE_WITH_IMM: 1292 case IB_WR_RDMA_WRITE_WITH_IMM:
1269 ((struct mlx4_wqe_raddr_seg *) wqe)->raddr = 1293 set_raddr_seg(wqe, wr->wr.rdma.remote_addr,
1270 cpu_to_be64(wr->wr.rdma.remote_addr); 1294 wr->wr.rdma.rkey);
1271 ((struct mlx4_wqe_raddr_seg *) wqe)->rkey =
1272 cpu_to_be32(wr->wr.rdma.rkey);
1273 ((struct mlx4_wqe_raddr_seg *) wqe)->reserved = 0;
1274
1275 wqe += sizeof (struct mlx4_wqe_raddr_seg); 1295 wqe += sizeof (struct mlx4_wqe_raddr_seg);
1276 size += sizeof (struct mlx4_wqe_raddr_seg) / 16; 1296 size += sizeof (struct mlx4_wqe_raddr_seg) / 16;
1277
1278 break; 1297 break;
1279 1298
1280 default: 1299 default:
@@ -1284,13 +1303,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1284 break; 1303 break;
1285 1304
1286 case IB_QPT_UD: 1305 case IB_QPT_UD:
1287 memcpy(((struct mlx4_wqe_datagram_seg *) wqe)->av, 1306 set_datagram_seg(wqe, wr);
1288 &to_mah(wr->wr.ud.ah)->av, sizeof (struct mlx4_av));
1289 ((struct mlx4_wqe_datagram_seg *) wqe)->dqpn =
1290 cpu_to_be32(wr->wr.ud.remote_qpn);
1291 ((struct mlx4_wqe_datagram_seg *) wqe)->qkey =
1292 cpu_to_be32(wr->wr.ud.remote_qkey);
1293
1294 wqe += sizeof (struct mlx4_wqe_datagram_seg); 1307 wqe += sizeof (struct mlx4_wqe_datagram_seg);
1295 size += sizeof (struct mlx4_wqe_datagram_seg) / 16; 1308 size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
1296 break; 1309 break;
@@ -1313,12 +1326,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1313 } 1326 }
1314 1327
1315 for (i = 0; i < wr->num_sge; ++i) { 1328 for (i = 0; i < wr->num_sge; ++i) {
1316 ((struct mlx4_wqe_data_seg *) wqe)->byte_count = 1329 set_data_seg(wqe, wr->sg_list + i);
1317 cpu_to_be32(wr->sg_list[i].length);
1318 ((struct mlx4_wqe_data_seg *) wqe)->lkey =
1319 cpu_to_be32(wr->sg_list[i].lkey);
1320 ((struct mlx4_wqe_data_seg *) wqe)->addr =
1321 cpu_to_be64(wr->sg_list[i].addr);
1322 1330
1323 wqe += sizeof (struct mlx4_wqe_data_seg); 1331 wqe += sizeof (struct mlx4_wqe_data_seg);
1324 size += sizeof (struct mlx4_wqe_data_seg) / 16; 1332 size += sizeof (struct mlx4_wqe_data_seg) / 16;
@@ -1498,7 +1506,7 @@ static int to_ib_qp_access_flags(int mlx4_flags)
1498static void to_ib_ah_attr(struct mlx4_dev *dev, struct ib_ah_attr *ib_ah_attr, 1506static void to_ib_ah_attr(struct mlx4_dev *dev, struct ib_ah_attr *ib_ah_attr,
1499 struct mlx4_qp_path *path) 1507 struct mlx4_qp_path *path)
1500{ 1508{
1501 memset(ib_ah_attr, 0, sizeof *path); 1509 memset(ib_ah_attr, 0, sizeof *ib_ah_attr);
1502 ib_ah_attr->port_num = path->sched_queue & 0x40 ? 2 : 1; 1510 ib_ah_attr->port_num = path->sched_queue & 0x40 ? 2 : 1;
1503 1511
1504 if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->caps.num_ports) 1512 if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->caps.num_ports)
@@ -1515,7 +1523,7 @@ static void to_ib_ah_attr(struct mlx4_dev *dev, struct ib_ah_attr *ib_ah_attr,
1515 ib_ah_attr->grh.traffic_class = 1523 ib_ah_attr->grh.traffic_class =
1516 (be32_to_cpu(path->tclass_flowlabel) >> 20) & 0xff; 1524 (be32_to_cpu(path->tclass_flowlabel) >> 20) & 0xff;
1517 ib_ah_attr->grh.flow_label = 1525 ib_ah_attr->grh.flow_label =
1518 be32_to_cpu(path->tclass_flowlabel) & 0xffffff; 1526 be32_to_cpu(path->tclass_flowlabel) & 0xfffff;
1519 memcpy(ib_ah_attr->grh.dgid.raw, 1527 memcpy(ib_ah_attr->grh.dgid.raw,
1520 path->rgid, sizeof ib_ah_attr->grh.dgid.raw); 1528 path->rgid, sizeof ib_ah_attr->grh.dgid.raw);
1521 } 1529 }
@@ -1560,7 +1568,10 @@ int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
1560 } 1568 }
1561 1569
1562 qp_attr->pkey_index = context.pri_path.pkey_index & 0x7f; 1570 qp_attr->pkey_index = context.pri_path.pkey_index & 0x7f;
1563 qp_attr->port_num = context.pri_path.sched_queue & 0x40 ? 2 : 1; 1571 if (qp_attr->qp_state == IB_QPS_INIT)
1572 qp_attr->port_num = qp->port;
1573 else
1574 qp_attr->port_num = context.pri_path.sched_queue & 0x40 ? 2 : 1;
1564 1575
1565 /* qp_attr->en_sqd_async_notify is only applicable in modify qp */ 1576 /* qp_attr->en_sqd_async_notify is only applicable in modify qp */
1566 qp_attr->sq_draining = mlx4_state == MLX4_QP_STATE_SQ_DRAINING; 1577 qp_attr->sq_draining = mlx4_state == MLX4_QP_STATE_SQ_DRAINING;
@@ -1578,17 +1589,25 @@ int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
1578 1589
1579done: 1590done:
1580 qp_attr->cur_qp_state = qp_attr->qp_state; 1591 qp_attr->cur_qp_state = qp_attr->qp_state;
1592 qp_attr->cap.max_recv_wr = qp->rq.wqe_cnt;
1593 qp_attr->cap.max_recv_sge = qp->rq.max_gs;
1594
1581 if (!ibqp->uobject) { 1595 if (!ibqp->uobject) {
1582 qp_attr->cap.max_send_wr = qp->sq.wqe_cnt; 1596 qp_attr->cap.max_send_wr = qp->sq.wqe_cnt;
1583 qp_attr->cap.max_recv_wr = qp->rq.wqe_cnt; 1597 qp_attr->cap.max_send_sge = qp->sq.max_gs;
1584 qp_attr->cap.max_send_sge = qp->sq.max_gs; 1598 } else {
1585 qp_attr->cap.max_recv_sge = qp->rq.max_gs; 1599 qp_attr->cap.max_send_wr = 0;
1586 qp_attr->cap.max_inline_data = (1 << qp->sq.wqe_shift) - 1600 qp_attr->cap.max_send_sge = 0;
1587 send_wqe_overhead(qp->ibqp.qp_type) -
1588 sizeof (struct mlx4_wqe_inline_seg);
1589 qp_init_attr->cap = qp_attr->cap;
1590 } 1601 }
1591 1602
1603 /*
1604 * We don't support inline sends for kernel QPs (yet), and we
1605 * don't know what userspace's value should be.
1606 */
1607 qp_attr->cap.max_inline_data = 0;
1608
1609 qp_init_attr->cap = qp_attr->cap;
1610
1592 return 0; 1611 return 0;
1593} 1612}
1594 1613
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index aa563e61de65..76fed7545c53 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -67,7 +67,7 @@ MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
67 67
68static int msi = 0; 68static int msi = 0;
69module_param(msi, int, 0444); 69module_param(msi, int, 0444);
70MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero"); 70MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero (deprecated, use MSI-X instead)");
71 71
72#else /* CONFIG_PCI_MSI */ 72#else /* CONFIG_PCI_MSI */
73 73
@@ -1117,9 +1117,21 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1117 1117
1118 if (msi_x && !mthca_enable_msi_x(mdev)) 1118 if (msi_x && !mthca_enable_msi_x(mdev))
1119 mdev->mthca_flags |= MTHCA_FLAG_MSI_X; 1119 mdev->mthca_flags |= MTHCA_FLAG_MSI_X;
1120 if (msi && !(mdev->mthca_flags & MTHCA_FLAG_MSI_X) && 1120 else if (msi) {
1121 !pci_enable_msi(pdev)) 1121 static int warned;
1122 mdev->mthca_flags |= MTHCA_FLAG_MSI; 1122
1123 if (!warned) {
1124 printk(KERN_WARNING PFX "WARNING: MSI support will be "
1125 "removed from the ib_mthca driver in January 2008.\n");
1126 printk(KERN_WARNING " If you are using MSI and cannot "
1127 "switch to MSI-X, please tell "
1128 "<general@lists.openfabrics.org>.\n");
1129 ++warned;
1130 }
1131
1132 if (!pci_enable_msi(pdev))
1133 mdev->mthca_flags |= MTHCA_FLAG_MSI;
1134 }
1123 1135
1124 if (mthca_cmd_init(mdev)) { 1136 if (mthca_cmd_init(mdev)) {
1125 mthca_err(mdev, "Failed to init command interface, aborting.\n"); 1137 mthca_err(mdev, "Failed to init command interface, aborting.\n");
@@ -1135,7 +1147,7 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
1135 goto err_cmd; 1147 goto err_cmd;
1136 1148
1137 if (mdev->fw_ver < mthca_hca_table[hca_type].latest_fw) { 1149 if (mdev->fw_ver < mthca_hca_table[hca_type].latest_fw) {
1138 mthca_warn(mdev, "HCA FW version %d.%d.%3d is old (%d.%d.%3d is current).\n", 1150 mthca_warn(mdev, "HCA FW version %d.%d.%03d is old (%d.%d.%03d is current).\n",
1139 (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff, 1151 (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
1140 (int) (mdev->fw_ver & 0xffff), 1152 (int) (mdev->fw_ver & 0xffff),
1141 (int) (mthca_hca_table[hca_type].latest_fw >> 32), 1153 (int) (mthca_hca_table[hca_type].latest_fw >> 32),
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 11f1d99db40b..df01b2026a64 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1578,6 +1578,45 @@ static inline int mthca_wq_overflow(struct mthca_wq *wq, int nreq,
1578 return cur + nreq >= wq->max; 1578 return cur + nreq >= wq->max;
1579} 1579}
1580 1580
1581static __always_inline void set_raddr_seg(struct mthca_raddr_seg *rseg,
1582 u64 remote_addr, u32 rkey)
1583{
1584 rseg->raddr = cpu_to_be64(remote_addr);
1585 rseg->rkey = cpu_to_be32(rkey);
1586 rseg->reserved = 0;
1587}
1588
1589static __always_inline void set_atomic_seg(struct mthca_atomic_seg *aseg,
1590 struct ib_send_wr *wr)
1591{
1592 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
1593 aseg->swap_add = cpu_to_be64(wr->wr.atomic.swap);
1594 aseg->compare = cpu_to_be64(wr->wr.atomic.compare_add);
1595 } else {
1596 aseg->swap_add = cpu_to_be64(wr->wr.atomic.compare_add);
1597 aseg->compare = 0;
1598 }
1599
1600}
1601
1602static void set_tavor_ud_seg(struct mthca_tavor_ud_seg *useg,
1603 struct ib_send_wr *wr)
1604{
1605 useg->lkey = cpu_to_be32(to_mah(wr->wr.ud.ah)->key);
1606 useg->av_addr = cpu_to_be64(to_mah(wr->wr.ud.ah)->avdma);
1607 useg->dqpn = cpu_to_be32(wr->wr.ud.remote_qpn);
1608 useg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey);
1609
1610}
1611
1612static void set_arbel_ud_seg(struct mthca_arbel_ud_seg *useg,
1613 struct ib_send_wr *wr)
1614{
1615 memcpy(useg->av, to_mah(wr->wr.ud.ah)->av, MTHCA_AV_SIZE);
1616 useg->dqpn = cpu_to_be32(wr->wr.ud.remote_qpn);
1617 useg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey);
1618}
1619
1581int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 1620int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1582 struct ib_send_wr **bad_wr) 1621 struct ib_send_wr **bad_wr)
1583{ 1622{
@@ -1590,8 +1629,15 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1590 int nreq; 1629 int nreq;
1591 int i; 1630 int i;
1592 int size; 1631 int size;
1593 int size0 = 0; 1632 /*
1594 u32 f0 = 0; 1633 * f0 and size0 are only used if nreq != 0, and they will
1634 * always be initialized the first time through the main loop
1635 * before nreq is incremented. So nreq cannot become non-zero
1636 * without initializing f0 and size0, and they are in fact
1637 * never used uninitialized.
1638 */
1639 int uninitialized_var(size0);
1640 u32 uninitialized_var(f0);
1595 int ind; 1641 int ind;
1596 u8 op0 = 0; 1642 u8 op0 = 0;
1597 1643
@@ -1636,25 +1682,11 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1636 switch (wr->opcode) { 1682 switch (wr->opcode) {
1637 case IB_WR_ATOMIC_CMP_AND_SWP: 1683 case IB_WR_ATOMIC_CMP_AND_SWP:
1638 case IB_WR_ATOMIC_FETCH_AND_ADD: 1684 case IB_WR_ATOMIC_FETCH_AND_ADD:
1639 ((struct mthca_raddr_seg *) wqe)->raddr = 1685 set_raddr_seg(wqe, wr->wr.atomic.remote_addr,
1640 cpu_to_be64(wr->wr.atomic.remote_addr); 1686 wr->wr.atomic.rkey);
1641 ((struct mthca_raddr_seg *) wqe)->rkey =
1642 cpu_to_be32(wr->wr.atomic.rkey);
1643 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
1644
1645 wqe += sizeof (struct mthca_raddr_seg); 1687 wqe += sizeof (struct mthca_raddr_seg);
1646 1688
1647 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) { 1689 set_atomic_seg(wqe, wr);
1648 ((struct mthca_atomic_seg *) wqe)->swap_add =
1649 cpu_to_be64(wr->wr.atomic.swap);
1650 ((struct mthca_atomic_seg *) wqe)->compare =
1651 cpu_to_be64(wr->wr.atomic.compare_add);
1652 } else {
1653 ((struct mthca_atomic_seg *) wqe)->swap_add =
1654 cpu_to_be64(wr->wr.atomic.compare_add);
1655 ((struct mthca_atomic_seg *) wqe)->compare = 0;
1656 }
1657
1658 wqe += sizeof (struct mthca_atomic_seg); 1690 wqe += sizeof (struct mthca_atomic_seg);
1659 size += (sizeof (struct mthca_raddr_seg) + 1691 size += (sizeof (struct mthca_raddr_seg) +
1660 sizeof (struct mthca_atomic_seg)) / 16; 1692 sizeof (struct mthca_atomic_seg)) / 16;
@@ -1663,12 +1695,9 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1663 case IB_WR_RDMA_WRITE: 1695 case IB_WR_RDMA_WRITE:
1664 case IB_WR_RDMA_WRITE_WITH_IMM: 1696 case IB_WR_RDMA_WRITE_WITH_IMM:
1665 case IB_WR_RDMA_READ: 1697 case IB_WR_RDMA_READ:
1666 ((struct mthca_raddr_seg *) wqe)->raddr = 1698 set_raddr_seg(wqe, wr->wr.rdma.remote_addr,
1667 cpu_to_be64(wr->wr.rdma.remote_addr); 1699 wr->wr.rdma.rkey);
1668 ((struct mthca_raddr_seg *) wqe)->rkey = 1700 wqe += sizeof (struct mthca_raddr_seg);
1669 cpu_to_be32(wr->wr.rdma.rkey);
1670 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
1671 wqe += sizeof (struct mthca_raddr_seg);
1672 size += sizeof (struct mthca_raddr_seg) / 16; 1701 size += sizeof (struct mthca_raddr_seg) / 16;
1673 break; 1702 break;
1674 1703
@@ -1683,12 +1712,9 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1683 switch (wr->opcode) { 1712 switch (wr->opcode) {
1684 case IB_WR_RDMA_WRITE: 1713 case IB_WR_RDMA_WRITE:
1685 case IB_WR_RDMA_WRITE_WITH_IMM: 1714 case IB_WR_RDMA_WRITE_WITH_IMM:
1686 ((struct mthca_raddr_seg *) wqe)->raddr = 1715 set_raddr_seg(wqe, wr->wr.rdma.remote_addr,
1687 cpu_to_be64(wr->wr.rdma.remote_addr); 1716 wr->wr.rdma.rkey);
1688 ((struct mthca_raddr_seg *) wqe)->rkey = 1717 wqe += sizeof (struct mthca_raddr_seg);
1689 cpu_to_be32(wr->wr.rdma.rkey);
1690 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
1691 wqe += sizeof (struct mthca_raddr_seg);
1692 size += sizeof (struct mthca_raddr_seg) / 16; 1718 size += sizeof (struct mthca_raddr_seg) / 16;
1693 break; 1719 break;
1694 1720
@@ -1700,16 +1726,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1700 break; 1726 break;
1701 1727
1702 case UD: 1728 case UD:
1703 ((struct mthca_tavor_ud_seg *) wqe)->lkey = 1729 set_tavor_ud_seg(wqe, wr);
1704 cpu_to_be32(to_mah(wr->wr.ud.ah)->key); 1730 wqe += sizeof (struct mthca_tavor_ud_seg);
1705 ((struct mthca_tavor_ud_seg *) wqe)->av_addr =
1706 cpu_to_be64(to_mah(wr->wr.ud.ah)->avdma);
1707 ((struct mthca_tavor_ud_seg *) wqe)->dqpn =
1708 cpu_to_be32(wr->wr.ud.remote_qpn);
1709 ((struct mthca_tavor_ud_seg *) wqe)->qkey =
1710 cpu_to_be32(wr->wr.ud.remote_qkey);
1711
1712 wqe += sizeof (struct mthca_tavor_ud_seg);
1713 size += sizeof (struct mthca_tavor_ud_seg) / 16; 1731 size += sizeof (struct mthca_tavor_ud_seg) / 16;
1714 break; 1732 break;
1715 1733
@@ -1734,13 +1752,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1734 } 1752 }
1735 1753
1736 for (i = 0; i < wr->num_sge; ++i) { 1754 for (i = 0; i < wr->num_sge; ++i) {
1737 ((struct mthca_data_seg *) wqe)->byte_count = 1755 mthca_set_data_seg(wqe, wr->sg_list + i);
1738 cpu_to_be32(wr->sg_list[i].length); 1756 wqe += sizeof (struct mthca_data_seg);
1739 ((struct mthca_data_seg *) wqe)->lkey =
1740 cpu_to_be32(wr->sg_list[i].lkey);
1741 ((struct mthca_data_seg *) wqe)->addr =
1742 cpu_to_be64(wr->sg_list[i].addr);
1743 wqe += sizeof (struct mthca_data_seg);
1744 size += sizeof (struct mthca_data_seg) / 16; 1757 size += sizeof (struct mthca_data_seg) / 16;
1745 } 1758 }
1746 1759
@@ -1768,11 +1781,11 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1768 mthca_opcode[wr->opcode]); 1781 mthca_opcode[wr->opcode]);
1769 wmb(); 1782 wmb();
1770 ((struct mthca_next_seg *) prev_wqe)->ee_nds = 1783 ((struct mthca_next_seg *) prev_wqe)->ee_nds =
1771 cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size | 1784 cpu_to_be32((nreq ? 0 : MTHCA_NEXT_DBD) | size |
1772 ((wr->send_flags & IB_SEND_FENCE) ? 1785 ((wr->send_flags & IB_SEND_FENCE) ?
1773 MTHCA_NEXT_FENCE : 0)); 1786 MTHCA_NEXT_FENCE : 0));
1774 1787
1775 if (!size0) { 1788 if (!nreq) {
1776 size0 = size; 1789 size0 = size;
1777 op0 = mthca_opcode[wr->opcode]; 1790 op0 = mthca_opcode[wr->opcode];
1778 f0 = wr->send_flags & IB_SEND_FENCE ? 1791 f0 = wr->send_flags & IB_SEND_FENCE ?
@@ -1822,7 +1835,14 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1822 int nreq; 1835 int nreq;
1823 int i; 1836 int i;
1824 int size; 1837 int size;
1825 int size0 = 0; 1838 /*
1839 * size0 is only used if nreq != 0, and it will always be
1840 * initialized the first time through the main loop before
1841 * nreq is incremented. So nreq cannot become non-zero
1842 * without initializing size0, and it is in fact never used
1843 * uninitialized.
1844 */
1845 int uninitialized_var(size0);
1826 int ind; 1846 int ind;
1827 void *wqe; 1847 void *wqe;
1828 void *prev_wqe; 1848 void *prev_wqe;
@@ -1863,13 +1883,8 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1863 } 1883 }
1864 1884
1865 for (i = 0; i < wr->num_sge; ++i) { 1885 for (i = 0; i < wr->num_sge; ++i) {
1866 ((struct mthca_data_seg *) wqe)->byte_count = 1886 mthca_set_data_seg(wqe, wr->sg_list + i);
1867 cpu_to_be32(wr->sg_list[i].length); 1887 wqe += sizeof (struct mthca_data_seg);
1868 ((struct mthca_data_seg *) wqe)->lkey =
1869 cpu_to_be32(wr->sg_list[i].lkey);
1870 ((struct mthca_data_seg *) wqe)->addr =
1871 cpu_to_be64(wr->sg_list[i].addr);
1872 wqe += sizeof (struct mthca_data_seg);
1873 size += sizeof (struct mthca_data_seg) / 16; 1888 size += sizeof (struct mthca_data_seg) / 16;
1874 } 1889 }
1875 1890
@@ -1881,7 +1896,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1881 ((struct mthca_next_seg *) prev_wqe)->ee_nds = 1896 ((struct mthca_next_seg *) prev_wqe)->ee_nds =
1882 cpu_to_be32(MTHCA_NEXT_DBD | size); 1897 cpu_to_be32(MTHCA_NEXT_DBD | size);
1883 1898
1884 if (!size0) 1899 if (!nreq)
1885 size0 = size; 1900 size0 = size;
1886 1901
1887 ++ind; 1902 ++ind;
@@ -1903,7 +1918,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1903 1918
1904 qp->rq.next_ind = ind; 1919 qp->rq.next_ind = ind;
1905 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; 1920 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
1906 size0 = 0;
1907 } 1921 }
1908 } 1922 }
1909 1923
@@ -1945,8 +1959,15 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1945 int nreq; 1959 int nreq;
1946 int i; 1960 int i;
1947 int size; 1961 int size;
1948 int size0 = 0; 1962 /*
1949 u32 f0 = 0; 1963 * f0 and size0 are only used if nreq != 0, and they will
1964 * always be initialized the first time through the main loop
1965 * before nreq is incremented. So nreq cannot become non-zero
1966 * without initializing f0 and size0, and they are in fact
1967 * never used uninitialized.
1968 */
1969 int uninitialized_var(size0);
1970 u32 uninitialized_var(f0);
1950 int ind; 1971 int ind;
1951 u8 op0 = 0; 1972 u8 op0 = 0;
1952 1973
@@ -1966,7 +1987,6 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1966 doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0); 1987 doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
1967 1988
1968 qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB; 1989 qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB;
1969 size0 = 0;
1970 1990
1971 /* 1991 /*
1972 * Make sure that descriptors are written before 1992 * Make sure that descriptors are written before
@@ -2017,26 +2037,12 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2017 switch (wr->opcode) { 2037 switch (wr->opcode) {
2018 case IB_WR_ATOMIC_CMP_AND_SWP: 2038 case IB_WR_ATOMIC_CMP_AND_SWP:
2019 case IB_WR_ATOMIC_FETCH_AND_ADD: 2039 case IB_WR_ATOMIC_FETCH_AND_ADD:
2020 ((struct mthca_raddr_seg *) wqe)->raddr = 2040 set_raddr_seg(wqe, wr->wr.atomic.remote_addr,
2021 cpu_to_be64(wr->wr.atomic.remote_addr); 2041 wr->wr.atomic.rkey);
2022 ((struct mthca_raddr_seg *) wqe)->rkey =
2023 cpu_to_be32(wr->wr.atomic.rkey);
2024 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
2025
2026 wqe += sizeof (struct mthca_raddr_seg); 2042 wqe += sizeof (struct mthca_raddr_seg);
2027 2043
2028 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) { 2044 set_atomic_seg(wqe, wr);
2029 ((struct mthca_atomic_seg *) wqe)->swap_add = 2045 wqe += sizeof (struct mthca_atomic_seg);
2030 cpu_to_be64(wr->wr.atomic.swap);
2031 ((struct mthca_atomic_seg *) wqe)->compare =
2032 cpu_to_be64(wr->wr.atomic.compare_add);
2033 } else {
2034 ((struct mthca_atomic_seg *) wqe)->swap_add =
2035 cpu_to_be64(wr->wr.atomic.compare_add);
2036 ((struct mthca_atomic_seg *) wqe)->compare = 0;
2037 }
2038
2039 wqe += sizeof (struct mthca_atomic_seg);
2040 size += (sizeof (struct mthca_raddr_seg) + 2046 size += (sizeof (struct mthca_raddr_seg) +
2041 sizeof (struct mthca_atomic_seg)) / 16; 2047 sizeof (struct mthca_atomic_seg)) / 16;
2042 break; 2048 break;
@@ -2044,12 +2050,9 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2044 case IB_WR_RDMA_READ: 2050 case IB_WR_RDMA_READ:
2045 case IB_WR_RDMA_WRITE: 2051 case IB_WR_RDMA_WRITE:
2046 case IB_WR_RDMA_WRITE_WITH_IMM: 2052 case IB_WR_RDMA_WRITE_WITH_IMM:
2047 ((struct mthca_raddr_seg *) wqe)->raddr = 2053 set_raddr_seg(wqe, wr->wr.rdma.remote_addr,
2048 cpu_to_be64(wr->wr.rdma.remote_addr); 2054 wr->wr.rdma.rkey);
2049 ((struct mthca_raddr_seg *) wqe)->rkey = 2055 wqe += sizeof (struct mthca_raddr_seg);
2050 cpu_to_be32(wr->wr.rdma.rkey);
2051 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
2052 wqe += sizeof (struct mthca_raddr_seg);
2053 size += sizeof (struct mthca_raddr_seg) / 16; 2056 size += sizeof (struct mthca_raddr_seg) / 16;
2054 break; 2057 break;
2055 2058
@@ -2064,12 +2067,9 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2064 switch (wr->opcode) { 2067 switch (wr->opcode) {
2065 case IB_WR_RDMA_WRITE: 2068 case IB_WR_RDMA_WRITE:
2066 case IB_WR_RDMA_WRITE_WITH_IMM: 2069 case IB_WR_RDMA_WRITE_WITH_IMM:
2067 ((struct mthca_raddr_seg *) wqe)->raddr = 2070 set_raddr_seg(wqe, wr->wr.rdma.remote_addr,
2068 cpu_to_be64(wr->wr.rdma.remote_addr); 2071 wr->wr.rdma.rkey);
2069 ((struct mthca_raddr_seg *) wqe)->rkey = 2072 wqe += sizeof (struct mthca_raddr_seg);
2070 cpu_to_be32(wr->wr.rdma.rkey);
2071 ((struct mthca_raddr_seg *) wqe)->reserved = 0;
2072 wqe += sizeof (struct mthca_raddr_seg);
2073 size += sizeof (struct mthca_raddr_seg) / 16; 2073 size += sizeof (struct mthca_raddr_seg) / 16;
2074 break; 2074 break;
2075 2075
@@ -2081,14 +2081,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2081 break; 2081 break;
2082 2082
2083 case UD: 2083 case UD:
2084 memcpy(((struct mthca_arbel_ud_seg *) wqe)->av, 2084 set_arbel_ud_seg(wqe, wr);
2085 to_mah(wr->wr.ud.ah)->av, MTHCA_AV_SIZE); 2085 wqe += sizeof (struct mthca_arbel_ud_seg);
2086 ((struct mthca_arbel_ud_seg *) wqe)->dqpn =
2087 cpu_to_be32(wr->wr.ud.remote_qpn);
2088 ((struct mthca_arbel_ud_seg *) wqe)->qkey =
2089 cpu_to_be32(wr->wr.ud.remote_qkey);
2090
2091 wqe += sizeof (struct mthca_arbel_ud_seg);
2092 size += sizeof (struct mthca_arbel_ud_seg) / 16; 2086 size += sizeof (struct mthca_arbel_ud_seg) / 16;
2093 break; 2087 break;
2094 2088
@@ -2113,13 +2107,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2113 } 2107 }
2114 2108
2115 for (i = 0; i < wr->num_sge; ++i) { 2109 for (i = 0; i < wr->num_sge; ++i) {
2116 ((struct mthca_data_seg *) wqe)->byte_count = 2110 mthca_set_data_seg(wqe, wr->sg_list + i);
2117 cpu_to_be32(wr->sg_list[i].length); 2111 wqe += sizeof (struct mthca_data_seg);
2118 ((struct mthca_data_seg *) wqe)->lkey =
2119 cpu_to_be32(wr->sg_list[i].lkey);
2120 ((struct mthca_data_seg *) wqe)->addr =
2121 cpu_to_be64(wr->sg_list[i].addr);
2122 wqe += sizeof (struct mthca_data_seg);
2123 size += sizeof (struct mthca_data_seg) / 16; 2112 size += sizeof (struct mthca_data_seg) / 16;
2124 } 2113 }
2125 2114
@@ -2151,7 +2140,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2151 ((wr->send_flags & IB_SEND_FENCE) ? 2140 ((wr->send_flags & IB_SEND_FENCE) ?
2152 MTHCA_NEXT_FENCE : 0)); 2141 MTHCA_NEXT_FENCE : 0));
2153 2142
2154 if (!size0) { 2143 if (!nreq) {
2155 size0 = size; 2144 size0 = size;
2156 op0 = mthca_opcode[wr->opcode]; 2145 op0 = mthca_opcode[wr->opcode];
2157 f0 = wr->send_flags & IB_SEND_FENCE ? 2146 f0 = wr->send_flags & IB_SEND_FENCE ?
@@ -2241,20 +2230,12 @@ int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
2241 } 2230 }
2242 2231
2243 for (i = 0; i < wr->num_sge; ++i) { 2232 for (i = 0; i < wr->num_sge; ++i) {
2244 ((struct mthca_data_seg *) wqe)->byte_count = 2233 mthca_set_data_seg(wqe, wr->sg_list + i);
2245 cpu_to_be32(wr->sg_list[i].length);
2246 ((struct mthca_data_seg *) wqe)->lkey =
2247 cpu_to_be32(wr->sg_list[i].lkey);
2248 ((struct mthca_data_seg *) wqe)->addr =
2249 cpu_to_be64(wr->sg_list[i].addr);
2250 wqe += sizeof (struct mthca_data_seg); 2234 wqe += sizeof (struct mthca_data_seg);
2251 } 2235 }
2252 2236
2253 if (i < qp->rq.max_gs) { 2237 if (i < qp->rq.max_gs)
2254 ((struct mthca_data_seg *) wqe)->byte_count = 0; 2238 mthca_set_data_seg_inval(wqe);
2255 ((struct mthca_data_seg *) wqe)->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
2256 ((struct mthca_data_seg *) wqe)->addr = 0;
2257 }
2258 2239
2259 qp->wrid[ind] = wr->wr_id; 2240 qp->wrid[ind] = wr->wr_id;
2260 2241
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index b8f05a526673..88d219e730ad 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -543,20 +543,12 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
543 } 543 }
544 544
545 for (i = 0; i < wr->num_sge; ++i) { 545 for (i = 0; i < wr->num_sge; ++i) {
546 ((struct mthca_data_seg *) wqe)->byte_count = 546 mthca_set_data_seg(wqe, wr->sg_list + i);
547 cpu_to_be32(wr->sg_list[i].length);
548 ((struct mthca_data_seg *) wqe)->lkey =
549 cpu_to_be32(wr->sg_list[i].lkey);
550 ((struct mthca_data_seg *) wqe)->addr =
551 cpu_to_be64(wr->sg_list[i].addr);
552 wqe += sizeof (struct mthca_data_seg); 547 wqe += sizeof (struct mthca_data_seg);
553 } 548 }
554 549
555 if (i < srq->max_gs) { 550 if (i < srq->max_gs)
556 ((struct mthca_data_seg *) wqe)->byte_count = 0; 551 mthca_set_data_seg_inval(wqe);
557 ((struct mthca_data_seg *) wqe)->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
558 ((struct mthca_data_seg *) wqe)->addr = 0;
559 }
560 552
561 ((struct mthca_next_seg *) prev_wqe)->nda_op = 553 ((struct mthca_next_seg *) prev_wqe)->nda_op =
562 cpu_to_be32((ind << srq->wqe_shift) | 1); 554 cpu_to_be32((ind << srq->wqe_shift) | 1);
@@ -662,20 +654,12 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
662 } 654 }
663 655
664 for (i = 0; i < wr->num_sge; ++i) { 656 for (i = 0; i < wr->num_sge; ++i) {
665 ((struct mthca_data_seg *) wqe)->byte_count = 657 mthca_set_data_seg(wqe, wr->sg_list + i);
666 cpu_to_be32(wr->sg_list[i].length);
667 ((struct mthca_data_seg *) wqe)->lkey =
668 cpu_to_be32(wr->sg_list[i].lkey);
669 ((struct mthca_data_seg *) wqe)->addr =
670 cpu_to_be64(wr->sg_list[i].addr);
671 wqe += sizeof (struct mthca_data_seg); 658 wqe += sizeof (struct mthca_data_seg);
672 } 659 }
673 660
674 if (i < srq->max_gs) { 661 if (i < srq->max_gs)
675 ((struct mthca_data_seg *) wqe)->byte_count = 0; 662 mthca_set_data_seg_inval(wqe);
676 ((struct mthca_data_seg *) wqe)->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
677 ((struct mthca_data_seg *) wqe)->addr = 0;
678 }
679 663
680 srq->wrid[ind] = wr->wr_id; 664 srq->wrid[ind] = wr->wr_id;
681 srq->first_free = next_ind; 665 srq->first_free = next_ind;
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index e7d2c1e86199..f6a66fe78e48 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -113,4 +113,19 @@ struct mthca_mlx_seg {
113 __be16 vcrc; 113 __be16 vcrc;
114}; 114};
115 115
116static __always_inline void mthca_set_data_seg(struct mthca_data_seg *dseg,
117 struct ib_sge *sg)
118{
119 dseg->byte_count = cpu_to_be32(sg->length);
120 dseg->lkey = cpu_to_be32(sg->lkey);
121 dseg->addr = cpu_to_be64(sg->addr);
122}
123
124static __always_inline void mthca_set_data_seg_inval(struct mthca_data_seg *dseg)
125{
126 dseg->byte_count = 0;
127 dseg->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
128 dseg->addr = 0;
129}
130
116#endif /* MTHCA_WQE_H */ 131#endif /* MTHCA_WQE_H */
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index e2353701e8bb..1ee867b1b341 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -310,8 +310,6 @@ int iser_conn_init(struct iser_conn **ib_conn);
310 310
311void iser_conn_terminate(struct iser_conn *ib_conn); 311void iser_conn_terminate(struct iser_conn *ib_conn);
312 312
313void iser_conn_release(struct iser_conn *ib_conn);
314
315void iser_rcv_completion(struct iser_desc *desc, 313void iser_rcv_completion(struct iser_desc *desc,
316 unsigned long dto_xfer_len); 314 unsigned long dto_xfer_len);
317 315
@@ -329,9 +327,6 @@ void iser_reg_single(struct iser_device *device,
329 struct iser_regd_buf *regd_buf, 327 struct iser_regd_buf *regd_buf,
330 enum dma_data_direction direction); 328 enum dma_data_direction direction);
331 329
332int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
333 enum iser_data_dir cmd_dir);
334
335void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask, 330void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
336 enum iser_data_dir cmd_dir); 331 enum iser_data_dir cmd_dir);
337 332
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index fc9f1fd0ae54..36cdf77ae92a 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -103,8 +103,8 @@ void iser_reg_single(struct iser_device *device,
103/** 103/**
104 * iser_start_rdma_unaligned_sg 104 * iser_start_rdma_unaligned_sg
105 */ 105 */
106int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, 106static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
107 enum iser_data_dir cmd_dir) 107 enum iser_data_dir cmd_dir)
108{ 108{
109 int dma_nents; 109 int dma_nents;
110 struct ib_device *dev; 110 struct ib_device *dev;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 2044de1164ac..d42ec0156eec 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -311,6 +311,29 @@ static int iser_conn_state_comp_exch(struct iser_conn *ib_conn,
311} 311}
312 312
313/** 313/**
314 * Frees all conn objects and deallocs conn descriptor
315 */
316static void iser_conn_release(struct iser_conn *ib_conn)
317{
318 struct iser_device *device = ib_conn->device;
319
320 BUG_ON(ib_conn->state != ISER_CONN_DOWN);
321
322 mutex_lock(&ig.connlist_mutex);
323 list_del(&ib_conn->conn_list);
324 mutex_unlock(&ig.connlist_mutex);
325
326 iser_free_ib_conn_res(ib_conn);
327 ib_conn->device = NULL;
328 /* on EVENT_ADDR_ERROR there's no device yet for this conn */
329 if (device != NULL)
330 iser_device_try_release(device);
331 if (ib_conn->iser_conn)
332 ib_conn->iser_conn->ib_conn = NULL;
333 kfree(ib_conn);
334}
335
336/**
314 * triggers start of the disconnect procedures and wait for them to be done 337 * triggers start of the disconnect procedures and wait for them to be done
315 */ 338 */
316void iser_conn_terminate(struct iser_conn *ib_conn) 339void iser_conn_terminate(struct iser_conn *ib_conn)
@@ -550,30 +573,6 @@ connect_failure:
550} 573}
551 574
552/** 575/**
553 * Frees all conn objects and deallocs conn descriptor
554 */
555void iser_conn_release(struct iser_conn *ib_conn)
556{
557 struct iser_device *device = ib_conn->device;
558
559 BUG_ON(ib_conn->state != ISER_CONN_DOWN);
560
561 mutex_lock(&ig.connlist_mutex);
562 list_del(&ib_conn->conn_list);
563 mutex_unlock(&ig.connlist_mutex);
564
565 iser_free_ib_conn_res(ib_conn);
566 ib_conn->device = NULL;
567 /* on EVENT_ADDR_ERROR there's no device yet for this conn */
568 if (device != NULL)
569 iser_device_try_release(device);
570 if (ib_conn->iser_conn)
571 ib_conn->iser_conn->ib_conn = NULL;
572 kfree(ib_conn);
573}
574
575
576/**
577 * iser_reg_page_vec - Register physical memory 576 * iser_reg_page_vec - Register physical memory
578 * 577 *
579 * returns: 0 on success, errno code on failure 578 * returns: 0 on success, errno code on failure
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5fb659f8b20e..3073f679584b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -838,6 +838,50 @@ config ULTRA32
838 <file:Documentation/networking/net-modules.txt>. The module 838 <file:Documentation/networking/net-modules.txt>. The module
839 will be called smc-ultra32. 839 will be called smc-ultra32.
840 840
841config BFIN_MAC
842 tristate "Blackfin 536/537 on-chip mac support"
843 depends on NET_ETHERNET && (BF537 || BF536) && (!BF537_PORT_H)
844 select CRC32
845 select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
846 help
847 This is the driver for blackfin on-chip mac device. Say Y if you want it
848 compiled into the kernel. This driver is also available as a module
849 ( = code which can be inserted in and removed from the running kernel
850 whenever you want). The module will be called bfin_mac.
851
852config BFIN_MAC_USE_L1
853 bool "Use L1 memory for rx/tx packets"
854 depends on BFIN_MAC && BF537
855 default y
856 help
857 To get maximum network performace, you should use L1 memory as rx/tx buffers.
858 Say N here if you want to reserve L1 memory for other uses.
859
860config BFIN_TX_DESC_NUM
861 int "Number of transmit buffer packets"
862 depends on BFIN_MAC
863 range 6 10 if BFIN_MAC_USE_L1
864 range 10 100
865 default "10"
866 help
867 Set the number of buffer packets used in driver.
868
869config BFIN_RX_DESC_NUM
870 int "Number of receive buffer packets"
871 depends on BFIN_MAC
872 range 20 100 if BFIN_MAC_USE_L1
873 range 20 800
874 default "20"
875 help
876 Set the number of buffer packets used in driver.
877
878config BFIN_MAC_RMII
879 bool "RMII PHY Interface (EXPERIMENTAL)"
880 depends on BFIN_MAC && EXPERIMENTAL
881 default n
882 help
883 Use Reduced PHY MII Interface
884
841config SMC9194 885config SMC9194
842 tristate "SMC 9194 support" 886 tristate "SMC 9194 support"
843 depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) 887 depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0e286ab8855a..aaaa0a04bb46 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -200,6 +200,7 @@ obj-$(CONFIG_S2IO) += s2io.o
200obj-$(CONFIG_MYRI10GE) += myri10ge/ 200obj-$(CONFIG_MYRI10GE) += myri10ge/
201obj-$(CONFIG_SMC91X) += smc91x.o 201obj-$(CONFIG_SMC91X) += smc91x.o
202obj-$(CONFIG_SMC911X) += smc911x.o 202obj-$(CONFIG_SMC911X) += smc911x.o
203obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
203obj-$(CONFIG_DM9000) += dm9000.o 204obj-$(CONFIG_DM9000) += dm9000.o
204obj-$(CONFIG_FEC_8XX) += fec_8xx/ 205obj-$(CONFIG_FEC_8XX) += fec_8xx/
205obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o 206obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index da713500654d..a7cac695a9bd 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -464,7 +464,7 @@ static void ether3_setmulticastlist(struct net_device *dev)
464 if (dev->flags & IFF_PROMISC) { 464 if (dev->flags & IFF_PROMISC) {
465 /* promiscuous mode */ 465 /* promiscuous mode */
466 priv(dev)->regs.config1 |= CFG1_RECVPROMISC; 466 priv(dev)->regs.config1 |= CFG1_RECVPROMISC;
467 } else if (dev->flags & IFF_ALLMULTI) { 467 } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
468 priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI; 468 priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI;
469 } else 469 } else
470 priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD; 470 priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
new file mode 100644
index 000000000000..9a08d656f1ce
--- /dev/null
+++ b/drivers/net/bfin_mac.c
@@ -0,0 +1,1009 @@
1/*
2 * File: drivers/net/bfin_mac.c
3 * Based on:
4 * Maintainer:
5 * Bryan Wu <bryan.wu@analog.com>
6 *
7 * Original author:
8 * Luke Yang <luke.yang@analog.com>
9 *
10 * Created:
11 * Description:
12 *
13 * Modified:
14 * Copyright 2004-2006 Analog Devices Inc.
15 *
16 * Bugs: Enter bugs at http://blackfin.uclinux.org/
17 *
18 * This program is free software ; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation ; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY ; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program ; see the file COPYING.
30 * If not, write to the Free Software Foundation,
31 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/sched.h>
38#include <linux/slab.h>
39#include <linux/delay.h>
40#include <linux/timer.h>
41#include <linux/errno.h>
42#include <linux/irq.h>
43#include <linux/io.h>
44#include <linux/ioport.h>
45#include <linux/crc32.h>
46#include <linux/device.h>
47#include <linux/spinlock.h>
48#include <linux/ethtool.h>
49#include <linux/mii.h>
50
51#include <linux/netdevice.h>
52#include <linux/etherdevice.h>
53#include <linux/skbuff.h>
54
55#include <linux/platform_device.h>
56#include <linux/netdevice.h>
57#include <linux/etherdevice.h>
58#include <linux/skbuff.h>
59
60#include <asm/dma.h>
61#include <linux/dma-mapping.h>
62
63#include <asm/blackfin.h>
64#include <asm/cacheflush.h>
65#include <asm/portmux.h>
66
67#include "bfin_mac.h"
68
69#define DRV_NAME "bfin_mac"
70#define DRV_VERSION "1.1"
71#define DRV_AUTHOR "Bryan Wu, Luke Yang"
72#define DRV_DESC "Blackfin BF53[67] on-chip Ethernet MAC driver"
73
74MODULE_AUTHOR(DRV_AUTHOR);
75MODULE_LICENSE("GPL");
76MODULE_DESCRIPTION(DRV_DESC);
77
78#if defined(CONFIG_BFIN_MAC_USE_L1)
79# define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size)
80# define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr)
81#else
82# define bfin_mac_alloc(dma_handle, size) \
83 dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
84# define bfin_mac_free(dma_handle, ptr) \
85 dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
86#endif
87
88#define PKT_BUF_SZ 1580
89
90#define MAX_TIMEOUT_CNT 500
91
92/* pointers to maintain transmit list */
93static struct net_dma_desc_tx *tx_list_head;
94static struct net_dma_desc_tx *tx_list_tail;
95static struct net_dma_desc_rx *rx_list_head;
96static struct net_dma_desc_rx *rx_list_tail;
97static struct net_dma_desc_rx *current_rx_ptr;
98static struct net_dma_desc_tx *current_tx_ptr;
99static struct net_dma_desc_tx *tx_desc;
100static struct net_dma_desc_rx *rx_desc;
101
102static void desc_list_free(void)
103{
104 struct net_dma_desc_rx *r;
105 struct net_dma_desc_tx *t;
106 int i;
107#if !defined(CONFIG_BFIN_MAC_USE_L1)
108 dma_addr_t dma_handle = 0;
109#endif
110
111 if (tx_desc) {
112 t = tx_list_head;
113 for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
114 if (t) {
115 if (t->skb) {
116 dev_kfree_skb(t->skb);
117 t->skb = NULL;
118 }
119 t = t->next;
120 }
121 }
122 bfin_mac_free(dma_handle, tx_desc);
123 }
124
125 if (rx_desc) {
126 r = rx_list_head;
127 for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
128 if (r) {
129 if (r->skb) {
130 dev_kfree_skb(r->skb);
131 r->skb = NULL;
132 }
133 r = r->next;
134 }
135 }
136 bfin_mac_free(dma_handle, rx_desc);
137 }
138}
139
140static int desc_list_init(void)
141{
142 int i;
143 struct sk_buff *new_skb;
144#if !defined(CONFIG_BFIN_MAC_USE_L1)
145 /*
146 * This dma_handle is useless in Blackfin dma_alloc_coherent().
147 * The real dma handler is the return value of dma_alloc_coherent().
148 */
149 dma_addr_t dma_handle;
150#endif
151
152 tx_desc = bfin_mac_alloc(&dma_handle,
153 sizeof(struct net_dma_desc_tx) *
154 CONFIG_BFIN_TX_DESC_NUM);
155 if (tx_desc == NULL)
156 goto init_error;
157
158 rx_desc = bfin_mac_alloc(&dma_handle,
159 sizeof(struct net_dma_desc_rx) *
160 CONFIG_BFIN_RX_DESC_NUM);
161 if (rx_desc == NULL)
162 goto init_error;
163
164 /* init tx_list */
165 tx_list_head = tx_list_tail = tx_desc;
166
167 for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
168 struct net_dma_desc_tx *t = tx_desc + i;
169 struct dma_descriptor *a = &(t->desc_a);
170 struct dma_descriptor *b = &(t->desc_b);
171
172 /*
173 * disable DMA
174 * read from memory WNR = 0
175 * wordsize is 32 bits
176 * 6 half words is desc size
177 * large desc flow
178 */
179 a->config = WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
180 a->start_addr = (unsigned long)t->packet;
181 a->x_count = 0;
182 a->next_dma_desc = b;
183
184 /*
185 * enabled DMA
186 * write to memory WNR = 1
187 * wordsize is 32 bits
188 * disable interrupt
189 * 6 half words is desc size
190 * large desc flow
191 */
192 b->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
193 b->start_addr = (unsigned long)(&(t->status));
194 b->x_count = 0;
195
196 t->skb = NULL;
197 tx_list_tail->desc_b.next_dma_desc = a;
198 tx_list_tail->next = t;
199 tx_list_tail = t;
200 }
201 tx_list_tail->next = tx_list_head; /* tx_list is a circle */
202 tx_list_tail->desc_b.next_dma_desc = &(tx_list_head->desc_a);
203 current_tx_ptr = tx_list_head;
204
205 /* init rx_list */
206 rx_list_head = rx_list_tail = rx_desc;
207
208 for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
209 struct net_dma_desc_rx *r = rx_desc + i;
210 struct dma_descriptor *a = &(r->desc_a);
211 struct dma_descriptor *b = &(r->desc_b);
212
213 /* allocate a new skb for next time receive */
214 new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
215 if (!new_skb) {
216 printk(KERN_NOTICE DRV_NAME
217 ": init: low on mem - packet dropped\n");
218 goto init_error;
219 }
220 skb_reserve(new_skb, 2);
221 r->skb = new_skb;
222
223 /*
224 * enabled DMA
225 * write to memory WNR = 1
226 * wordsize is 32 bits
227 * disable interrupt
228 * 6 half words is desc size
229 * large desc flow
230 */
231 a->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
232 /* since RXDWA is enabled */
233 a->start_addr = (unsigned long)new_skb->data - 2;
234 a->x_count = 0;
235 a->next_dma_desc = b;
236
237 /*
238 * enabled DMA
239 * write to memory WNR = 1
240 * wordsize is 32 bits
241 * enable interrupt
242 * 6 half words is desc size
243 * large desc flow
244 */
245 b->config = DMAEN | WNR | WDSIZE_32 | DI_EN |
246 NDSIZE_6 | DMAFLOW_LARGE;
247 b->start_addr = (unsigned long)(&(r->status));
248 b->x_count = 0;
249
250 rx_list_tail->desc_b.next_dma_desc = a;
251 rx_list_tail->next = r;
252 rx_list_tail = r;
253 }
254 rx_list_tail->next = rx_list_head; /* rx_list is a circle */
255 rx_list_tail->desc_b.next_dma_desc = &(rx_list_head->desc_a);
256 current_rx_ptr = rx_list_head;
257
258 return 0;
259
260init_error:
261 desc_list_free();
262 printk(KERN_ERR DRV_NAME ": kmalloc failed\n");
263 return -ENOMEM;
264}
265
266
267/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
268
269/* Set FER regs to MUX in Ethernet pins */
270static int setup_pin_mux(int action)
271{
272#if defined(CONFIG_BFIN_MAC_RMII)
273 u16 pin_req[] = P_RMII0;
274#else
275 u16 pin_req[] = P_MII0;
276#endif
277
278 if (action) {
279 if (peripheral_request_list(pin_req, DRV_NAME)) {
280 printk(KERN_ERR DRV_NAME
281 ": Requesting Peripherals failed\n");
282 return -EFAULT;
283 }
284 } else
285 peripheral_free_list(pin_req);
286
287 return 0;
288}
289
290/* Wait until the previous MDC/MDIO transaction has completed */
291static void poll_mdc_done(void)
292{
293 int timeout_cnt = MAX_TIMEOUT_CNT;
294
295 /* poll the STABUSY bit */
296 while ((bfin_read_EMAC_STAADD()) & STABUSY) {
297 mdelay(10);
298 if (timeout_cnt-- < 0) {
299 printk(KERN_ERR DRV_NAME
300 ": wait MDC/MDIO transaction to complete timeout\n");
301 break;
302 }
303 }
304}
305
306/* Read an off-chip register in a PHY through the MDC/MDIO port */
307static u16 read_phy_reg(u16 PHYAddr, u16 RegAddr)
308{
309 poll_mdc_done();
310 /* read mode */
311 bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) |
312 SET_REGAD(RegAddr) |
313 STABUSY);
314 poll_mdc_done();
315
316 return (u16) bfin_read_EMAC_STADAT();
317}
318
319/* Write an off-chip register in a PHY through the MDC/MDIO port */
320static void raw_write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data)
321{
322 bfin_write_EMAC_STADAT(Data);
323
324 /* write mode */
325 bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) |
326 SET_REGAD(RegAddr) |
327 STAOP |
328 STABUSY);
329
330 poll_mdc_done();
331}
332
333static void write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data)
334{
335 poll_mdc_done();
336 raw_write_phy_reg(PHYAddr, RegAddr, Data);
337}
338
339/* set up the phy */
340static void bf537mac_setphy(struct net_device *dev)
341{
342 u16 phydat;
343 struct bf537mac_local *lp = netdev_priv(dev);
344
345 /* Program PHY registers */
346 pr_debug("start setting up phy\n");
347
348 /* issue a reset */
349 raw_write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, 0x8000);
350
351 /* wait half a second */
352 msleep(500);
353
354 phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL);
355
356 /* advertise flow control supported */
357 phydat = read_phy_reg(lp->PhyAddr, PHYREG_ANAR);
358 phydat |= (1 << 10);
359 write_phy_reg(lp->PhyAddr, PHYREG_ANAR, phydat);
360
361 phydat = 0;
362 if (lp->Negotiate)
363 phydat |= 0x1000; /* enable auto negotiation */
364 else {
365 if (lp->FullDuplex)
366 phydat |= (1 << 8); /* full duplex */
367 else
368 phydat &= (~(1 << 8)); /* half duplex */
369
370 if (!lp->Port10)
371 phydat |= (1 << 13); /* 100 Mbps */
372 else
373 phydat &= (~(1 << 13)); /* 10 Mbps */
374 }
375
376 if (lp->Loopback)
377 phydat |= (1 << 14); /* enable TX->RX loopback */
378
379 write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, phydat);
380 msleep(500);
381
382 phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL);
383 /* check for SMSC PHY */
384 if ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID1) == 0x7) &&
385 ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID2) & 0xfff0) == 0xC0A0)) {
386 /*
387 * we have SMSC PHY so reqest interrupt
388 * on link down condition
389 */
390
391 /* enable interrupts */
392 write_phy_reg(lp->PhyAddr, 30, 0x0ff);
393 }
394}
395
396/**************************************************************************/
397void setup_system_regs(struct net_device *dev)
398{
399 int phyaddr;
400 unsigned short sysctl, phydat;
401 u32 opmode;
402 struct bf537mac_local *lp = netdev_priv(dev);
403 int count = 0;
404
405 phyaddr = lp->PhyAddr;
406
407 /* Enable PHY output */
408 if (!(bfin_read_VR_CTL() & PHYCLKOE))
409 bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
410
411 /* MDC = 2.5 MHz */
412 sysctl = SET_MDCDIV(24);
413 /* Odd word alignment for Receive Frame DMA word */
414 /* Configure checksum support and rcve frame word alignment */
415#if defined(BFIN_MAC_CSUM_OFFLOAD)
416 sysctl |= RXDWA | RXCKS;
417#else
418 sysctl |= RXDWA;
419#endif
420 bfin_write_EMAC_SYSCTL(sysctl);
421 /* auto negotiation on */
422 /* full duplex */
423 /* 100 Mbps */
424 phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
425 write_phy_reg(phyaddr, PHYREG_MODECTL, phydat);
426
427 /* test if full duplex supported */
428 do {
429 msleep(100);
430 phydat = read_phy_reg(phyaddr, PHYREG_MODESTAT);
431 if (count > 30) {
432 printk(KERN_NOTICE DRV_NAME ": Link is down\n");
433 printk(KERN_NOTICE DRV_NAME
434 "please check your network connection\n");
435 break;
436 }
437 count++;
438 } while (!(phydat & 0x0004));
439
440 phydat = read_phy_reg(phyaddr, PHYREG_ANLPAR);
441
442 if ((phydat & 0x0100) || (phydat & 0x0040)) {
443 opmode = FDMODE;
444 } else {
445 opmode = 0;
446 printk(KERN_INFO DRV_NAME
447 ": Network is set to half duplex\n");
448 }
449
450#if defined(CONFIG_BFIN_MAC_RMII)
451 opmode |= RMII; /* For Now only 100MBit are supported */
452#endif
453
454 bfin_write_EMAC_OPMODE(opmode);
455
456 bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
457
458 /* Initialize the TX DMA channel registers */
459 bfin_write_DMA2_X_COUNT(0);
460 bfin_write_DMA2_X_MODIFY(4);
461 bfin_write_DMA2_Y_COUNT(0);
462 bfin_write_DMA2_Y_MODIFY(0);
463
464 /* Initialize the RX DMA channel registers */
465 bfin_write_DMA1_X_COUNT(0);
466 bfin_write_DMA1_X_MODIFY(4);
467 bfin_write_DMA1_Y_COUNT(0);
468 bfin_write_DMA1_Y_MODIFY(0);
469}
470
471void setup_mac_addr(u8 * mac_addr)
472{
473 u32 addr_low = le32_to_cpu(*(__le32 *) & mac_addr[0]);
474 u16 addr_hi = le16_to_cpu(*(__le16 *) & mac_addr[4]);
475
476 /* this depends on a little-endian machine */
477 bfin_write_EMAC_ADDRLO(addr_low);
478 bfin_write_EMAC_ADDRHI(addr_hi);
479}
480
481static void adjust_tx_list(void)
482{
483 int timeout_cnt = MAX_TIMEOUT_CNT;
484
485 if (tx_list_head->status.status_word != 0
486 && current_tx_ptr != tx_list_head) {
487 goto adjust_head; /* released something, just return; */
488 }
489
490 /*
491 * if nothing released, check wait condition
492 * current's next can not be the head,
493 * otherwise the dma will not stop as we want
494 */
495 if (current_tx_ptr->next->next == tx_list_head) {
496 while (tx_list_head->status.status_word == 0) {
497 mdelay(10);
498 if (tx_list_head->status.status_word != 0
499 || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
500 goto adjust_head;
501 }
502 if (timeout_cnt-- < 0) {
503 printk(KERN_ERR DRV_NAME
504 ": wait for adjust tx list head timeout\n");
505 break;
506 }
507 }
508 if (tx_list_head->status.status_word != 0) {
509 goto adjust_head;
510 }
511 }
512
513 return;
514
515adjust_head:
516 do {
517 tx_list_head->desc_a.config &= ~DMAEN;
518 tx_list_head->status.status_word = 0;
519 if (tx_list_head->skb) {
520 dev_kfree_skb(tx_list_head->skb);
521 tx_list_head->skb = NULL;
522 } else {
523 printk(KERN_ERR DRV_NAME
524 ": no sk_buff in a transmitted frame!\n");
525 }
526 tx_list_head = tx_list_head->next;
527 } while (tx_list_head->status.status_word != 0
528 && current_tx_ptr != tx_list_head);
529 return;
530
531}
532
533static int bf537mac_hard_start_xmit(struct sk_buff *skb,
534 struct net_device *dev)
535{
536 struct bf537mac_local *lp = netdev_priv(dev);
537 unsigned int data;
538
539 current_tx_ptr->skb = skb;
540
541 /*
542 * Is skb->data always 16-bit aligned?
543 * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)?
544 */
545 if ((((unsigned int)(skb->data)) & 0x02) == 2) {
546 /* move skb->data to current_tx_ptr payload */
547 data = (unsigned int)(skb->data) - 2;
548 *((unsigned short *)data) = (unsigned short)(skb->len);
549 current_tx_ptr->desc_a.start_addr = (unsigned long)data;
550 /* this is important! */
551 blackfin_dcache_flush_range(data, (data + (skb->len)) + 2);
552
553 } else {
554 *((unsigned short *)(current_tx_ptr->packet)) =
555 (unsigned short)(skb->len);
556 memcpy((char *)(current_tx_ptr->packet + 2), skb->data,
557 (skb->len));
558 current_tx_ptr->desc_a.start_addr =
559 (unsigned long)current_tx_ptr->packet;
560 if (current_tx_ptr->status.status_word != 0)
561 current_tx_ptr->status.status_word = 0;
562 blackfin_dcache_flush_range((unsigned int)current_tx_ptr->
563 packet,
564 (unsigned int)(current_tx_ptr->
565 packet + skb->len) +
566 2);
567 }
568
569 /* enable this packet's dma */
570 current_tx_ptr->desc_a.config |= DMAEN;
571
572 /* tx dma is running, just return */
573 if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
574 goto out;
575
576 /* tx dma is not running */
577 bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
578 /* dma enabled, read from memory, size is 6 */
579 bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
580 /* Turn on the EMAC tx */
581 bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
582
583out:
584 adjust_tx_list();
585 current_tx_ptr = current_tx_ptr->next;
586 dev->trans_start = jiffies;
587 lp->stats.tx_packets++;
588 lp->stats.tx_bytes += (skb->len);
589 return 0;
590}
591
592static void bf537mac_rx(struct net_device *dev)
593{
594 struct sk_buff *skb, *new_skb;
595 struct bf537mac_local *lp = netdev_priv(dev);
596 unsigned short len;
597
598 /* allocate a new skb for next time receive */
599 skb = current_rx_ptr->skb;
600 new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
601 if (!new_skb) {
602 printk(KERN_NOTICE DRV_NAME
603 ": rx: low on mem - packet dropped\n");
604 lp->stats.rx_dropped++;
605 goto out;
606 }
607 /* reserve 2 bytes for RXDWA padding */
608 skb_reserve(new_skb, 2);
609 current_rx_ptr->skb = new_skb;
610 current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
611
612 len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
613 skb_put(skb, len);
614 blackfin_dcache_invalidate_range((unsigned long)skb->head,
615 (unsigned long)skb->tail);
616
617 dev->last_rx = jiffies;
618 skb->dev = dev;
619 skb->protocol = eth_type_trans(skb, dev);
620#if defined(BFIN_MAC_CSUM_OFFLOAD)
621 skb->csum = current_rx_ptr->status.ip_payload_csum;
622 skb->ip_summed = CHECKSUM_PARTIAL;
623#endif
624
625 netif_rx(skb);
626 lp->stats.rx_packets++;
627 lp->stats.rx_bytes += len;
628 current_rx_ptr->status.status_word = 0x00000000;
629 current_rx_ptr = current_rx_ptr->next;
630
631out:
632 return;
633}
634
635/* interrupt routine to handle rx and error signal */
636static irqreturn_t bf537mac_interrupt(int irq, void *dev_id)
637{
638 struct net_device *dev = dev_id;
639 int number = 0;
640
641get_one_packet:
642 if (current_rx_ptr->status.status_word == 0) {
643 /* no more new packet received */
644 if (number == 0) {
645 if (current_rx_ptr->next->status.status_word != 0) {
646 current_rx_ptr = current_rx_ptr->next;
647 goto real_rx;
648 }
649 }
650 bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
651 DMA_DONE | DMA_ERR);
652 return IRQ_HANDLED;
653 }
654
655real_rx:
656 bf537mac_rx(dev);
657 number++;
658 goto get_one_packet;
659}
660
661#ifdef CONFIG_NET_POLL_CONTROLLER
662static void bf537mac_poll(struct net_device *dev)
663{
664 disable_irq(IRQ_MAC_RX);
665 bf537mac_interrupt(IRQ_MAC_RX, dev);
666 enable_irq(IRQ_MAC_RX);
667}
668#endif /* CONFIG_NET_POLL_CONTROLLER */
669
670static void bf537mac_reset(void)
671{
672 unsigned int opmode;
673
674 opmode = bfin_read_EMAC_OPMODE();
675 opmode &= (~RE);
676 opmode &= (~TE);
677 /* Turn off the EMAC */
678 bfin_write_EMAC_OPMODE(opmode);
679}
680
681/*
682 * Enable Interrupts, Receive, and Transmit
683 */
684static int bf537mac_enable(struct net_device *dev)
685{
686 u32 opmode;
687
688 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
689
690 /* Set RX DMA */
691 bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
692 bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
693
694 /* Wait MII done */
695 poll_mdc_done();
696
697 /* We enable only RX here */
698 /* ASTP : Enable Automatic Pad Stripping
699 PR : Promiscuous Mode for test
700 PSF : Receive frames with total length less than 64 bytes.
701 FDMODE : Full Duplex Mode
702 LB : Internal Loopback for test
703 RE : Receiver Enable */
704 opmode = bfin_read_EMAC_OPMODE();
705 if (opmode & FDMODE)
706 opmode |= PSF;
707 else
708 opmode |= DRO | DC | PSF;
709 opmode |= RE;
710
711#if defined(CONFIG_BFIN_MAC_RMII)
712 opmode |= RMII; /* For Now only 100MBit are supported */
713#ifdef CONFIG_BF_REV_0_2
714 opmode |= TE;
715#endif
716#endif
717 /* Turn on the EMAC rx */
718 bfin_write_EMAC_OPMODE(opmode);
719
720 return 0;
721}
722
723/* Our watchdog timed out. Called by the networking layer */
724static void bf537mac_timeout(struct net_device *dev)
725{
726 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
727
728 bf537mac_reset();
729
730 /* reset tx queue */
731 tx_list_tail = tx_list_head->next;
732
733 bf537mac_enable(dev);
734
735 /* We can accept TX packets again */
736 dev->trans_start = jiffies;
737 netif_wake_queue(dev);
738}
739
740/*
741 * Get the current statistics.
742 * This may be called with the card open or closed.
743 */
744static struct net_device_stats *bf537mac_query_statistics(struct net_device
745 *dev)
746{
747 struct bf537mac_local *lp = netdev_priv(dev);
748
749 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
750
751 return &lp->stats;
752}
753
754/*
755 * This routine will, depending on the values passed to it,
756 * either make it accept multicast packets, go into
757 * promiscuous mode (for TCPDUMP and cousins) or accept
758 * a select set of multicast packets
759 */
760static void bf537mac_set_multicast_list(struct net_device *dev)
761{
762 u32 sysctl;
763
764 if (dev->flags & IFF_PROMISC) {
765 printk(KERN_INFO "%s: set to promisc mode\n", dev->name);
766 sysctl = bfin_read_EMAC_OPMODE();
767 sysctl |= RAF;
768 bfin_write_EMAC_OPMODE(sysctl);
769 } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
770 /* accept all multicast */
771 sysctl = bfin_read_EMAC_OPMODE();
772 sysctl |= PAM;
773 bfin_write_EMAC_OPMODE(sysctl);
774 } else {
775 /* clear promisc or multicast mode */
776 sysctl = bfin_read_EMAC_OPMODE();
777 sysctl &= ~(RAF | PAM);
778 bfin_write_EMAC_OPMODE(sysctl);
779 }
780}
781
782/*
783 * this puts the device in an inactive state
784 */
785static void bf537mac_shutdown(struct net_device *dev)
786{
787 /* Turn off the EMAC */
788 bfin_write_EMAC_OPMODE(0x00000000);
789 /* Turn off the EMAC RX DMA */
790 bfin_write_DMA1_CONFIG(0x0000);
791 bfin_write_DMA2_CONFIG(0x0000);
792}
793
794/*
795 * Open and Initialize the interface
796 *
797 * Set up everything, reset the card, etc..
798 */
799static int bf537mac_open(struct net_device *dev)
800{
801 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
802
803 /*
804 * Check that the address is valid. If its not, refuse
805 * to bring the device up. The user must specify an
806 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
807 */
808 if (!is_valid_ether_addr(dev->dev_addr)) {
809 printk(KERN_WARNING DRV_NAME ": no valid ethernet hw addr\n");
810 return -EINVAL;
811 }
812
813 /* initial rx and tx list */
814 desc_list_init();
815
816 bf537mac_setphy(dev);
817 setup_system_regs(dev);
818 bf537mac_reset();
819 bf537mac_enable(dev);
820
821 pr_debug("hardware init finished\n");
822 netif_start_queue(dev);
823 netif_carrier_on(dev);
824
825 return 0;
826}
827
828/*
829 *
830 * this makes the board clean up everything that it can
831 * and not talk to the outside world. Caused by
832 * an 'ifconfig ethX down'
833 */
834static int bf537mac_close(struct net_device *dev)
835{
836 pr_debug("%s: %s\n", dev->name, __FUNCTION__);
837
838 netif_stop_queue(dev);
839 netif_carrier_off(dev);
840
841 /* clear everything */
842 bf537mac_shutdown(dev);
843
844 /* free the rx/tx buffers */
845 desc_list_free();
846
847 return 0;
848}
849
850static int __init bf537mac_probe(struct net_device *dev)
851{
852 struct bf537mac_local *lp = netdev_priv(dev);
853 int retval;
854
855 /* Grab the MAC address in the MAC */
856 *(__le32 *) (&(dev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
857 *(__le16 *) (&(dev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI());
858
859 /* probe mac */
860 /*todo: how to proble? which is revision_register */
861 bfin_write_EMAC_ADDRLO(0x12345678);
862 if (bfin_read_EMAC_ADDRLO() != 0x12345678) {
863 pr_debug("can't detect bf537 mac!\n");
864 retval = -ENODEV;
865 goto err_out;
866 }
867
868 /* set the GPIO pins to Ethernet mode */
869 retval = setup_pin_mux(1);
870
871 if (retval)
872 return retval;
873
874 /*Is it valid? (Did bootloader initialize it?) */
875 if (!is_valid_ether_addr(dev->dev_addr)) {
876 /* Grab the MAC from the board somehow - this is done in the
877 arch/blackfin/mach-bf537/boards/eth_mac.c */
878 get_bf537_ether_addr(dev->dev_addr);
879 }
880
881 /* If still not valid, get a random one */
882 if (!is_valid_ether_addr(dev->dev_addr)) {
883 random_ether_addr(dev->dev_addr);
884 }
885
886 setup_mac_addr(dev->dev_addr);
887
888 /* Fill in the fields of the device structure with ethernet values. */
889 ether_setup(dev);
890
891 dev->open = bf537mac_open;
892 dev->stop = bf537mac_close;
893 dev->hard_start_xmit = bf537mac_hard_start_xmit;
894 dev->tx_timeout = bf537mac_timeout;
895 dev->get_stats = bf537mac_query_statistics;
896 dev->set_multicast_list = bf537mac_set_multicast_list;
897#ifdef CONFIG_NET_POLL_CONTROLLER
898 dev->poll_controller = bf537mac_poll;
899#endif
900
901 /* fill in some of the fields */
902 lp->version = 1;
903 lp->PhyAddr = 0x01;
904 lp->CLKIN = 25;
905 lp->FullDuplex = 0;
906 lp->Negotiate = 1;
907 lp->FlowControl = 0;
908 spin_lock_init(&lp->lock);
909
910 /* now, enable interrupts */
911 /* register irq handler */
912 if (request_irq
913 (IRQ_MAC_RX, bf537mac_interrupt, IRQF_DISABLED | IRQF_SHARED,
914 "BFIN537_MAC_RX", dev)) {
915 printk(KERN_WARNING DRV_NAME
916 ": Unable to attach BlackFin MAC RX interrupt\n");
917 return -EBUSY;
918 }
919
920 /* Enable PHY output early */
921 if (!(bfin_read_VR_CTL() & PHYCLKOE))
922 bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
923
924 retval = register_netdev(dev);
925 if (retval == 0) {
926 /* now, print out the card info, in a short format.. */
927 printk(KERN_INFO "%s: Version %s, %s\n",
928 DRV_NAME, DRV_VERSION, DRV_DESC);
929 }
930
931err_out:
932 return retval;
933}
934
935static int bfin_mac_probe(struct platform_device *pdev)
936{
937 struct net_device *ndev;
938
939 ndev = alloc_etherdev(sizeof(struct bf537mac_local));
940 if (!ndev) {
941 printk(KERN_WARNING DRV_NAME ": could not allocate device\n");
942 return -ENOMEM;
943 }
944
945 SET_MODULE_OWNER(ndev);
946 SET_NETDEV_DEV(ndev, &pdev->dev);
947
948 platform_set_drvdata(pdev, ndev);
949
950 if (bf537mac_probe(ndev) != 0) {
951 platform_set_drvdata(pdev, NULL);
952 free_netdev(ndev);
953 printk(KERN_WARNING DRV_NAME ": not found\n");
954 return -ENODEV;
955 }
956
957 return 0;
958}
959
960static int bfin_mac_remove(struct platform_device *pdev)
961{
962 struct net_device *ndev = platform_get_drvdata(pdev);
963
964 platform_set_drvdata(pdev, NULL);
965
966 unregister_netdev(ndev);
967
968 free_irq(IRQ_MAC_RX, ndev);
969
970 free_netdev(ndev);
971
972 setup_pin_mux(0);
973
974 return 0;
975}
976
977static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t state)
978{
979 return 0;
980}
981
982static int bfin_mac_resume(struct platform_device *pdev)
983{
984 return 0;
985}
986
987static struct platform_driver bfin_mac_driver = {
988 .probe = bfin_mac_probe,
989 .remove = bfin_mac_remove,
990 .resume = bfin_mac_resume,
991 .suspend = bfin_mac_suspend,
992 .driver = {
993 .name = DRV_NAME,
994 },
995};
996
997static int __init bfin_mac_init(void)
998{
999 return platform_driver_register(&bfin_mac_driver);
1000}
1001
1002module_init(bfin_mac_init);
1003
1004static void __exit bfin_mac_cleanup(void)
1005{
1006 platform_driver_unregister(&bfin_mac_driver);
1007}
1008
1009module_exit(bfin_mac_cleanup);
diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h
new file mode 100644
index 000000000000..af87189b85fa
--- /dev/null
+++ b/drivers/net/bfin_mac.h
@@ -0,0 +1,132 @@
1/*
2 * File: drivers/net/bfin_mac.c
3 * Based on:
4 * Maintainer:
5 * Bryan Wu <bryan.wu@analog.com>
6 *
7 * Original author:
8 * Luke Yang <luke.yang@analog.com>
9 *
10 * Created:
11 * Description:
12 *
13 * Modified:
14 * Copyright 2004-2006 Analog Devices Inc.
15 *
16 * Bugs: Enter bugs at http://blackfin.uclinux.org/
17 *
18 * This program is free software ; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation ; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY ; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program ; see the file COPYING.
30 * If not, write to the Free Software Foundation,
31 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34/*
35 * PHY REGISTER NAMES
36 */
37#define PHYREG_MODECTL 0x0000
38#define PHYREG_MODESTAT 0x0001
39#define PHYREG_PHYID1 0x0002
40#define PHYREG_PHYID2 0x0003
41#define PHYREG_ANAR 0x0004
42#define PHYREG_ANLPAR 0x0005
43#define PHYREG_ANER 0x0006
44#define PHYREG_NSR 0x0010
45#define PHYREG_LBREMR 0x0011
46#define PHYREG_REC 0x0012
47#define PHYREG_10CFG 0x0013
48#define PHYREG_PHY1_1 0x0014
49#define PHYREG_PHY1_2 0x0015
50#define PHYREG_PHY2 0x0016
51#define PHYREG_TW_1 0x0017
52#define PHYREG_TW_2 0x0018
53#define PHYREG_TEST 0x0019
54
55#define PHY_RESET 0x8000
56#define PHY_ANEG_EN 0x1000
57#define PHY_DUPLEX 0x0100
58#define PHY_SPD_SET 0x2000
59
60#define BFIN_MAC_CSUM_OFFLOAD
61
62struct dma_descriptor {
63 struct dma_descriptor *next_dma_desc;
64 unsigned long start_addr;
65 unsigned short config;
66 unsigned short x_count;
67};
68
69struct status_area_rx {
70#if defined(BFIN_MAC_CSUM_OFFLOAD)
71 unsigned short ip_hdr_csum; /* ip header checksum */
72 /* ip payload(udp or tcp or others) checksum */
73 unsigned short ip_payload_csum;
74#endif
75 unsigned long status_word; /* the frame status word */
76};
77
78struct status_area_tx {
79 unsigned long status_word; /* the frame status word */
80};
81
82/* use two descriptors for a packet */
83struct net_dma_desc_rx {
84 struct net_dma_desc_rx *next;
85 struct sk_buff *skb;
86 struct dma_descriptor desc_a;
87 struct dma_descriptor desc_b;
88 struct status_area_rx status;
89};
90
91/* use two descriptors for a packet */
92struct net_dma_desc_tx {
93 struct net_dma_desc_tx *next;
94 struct sk_buff *skb;
95 struct dma_descriptor desc_a;
96 struct dma_descriptor desc_b;
97 unsigned char packet[1560];
98 struct status_area_tx status;
99};
100
101struct bf537mac_local {
102 /*
103 * these are things that the kernel wants me to keep, so users
104 * can find out semi-useless statistics of how well the card is
105 * performing
106 */
107 struct net_device_stats stats;
108
109 int version;
110
111 int FlowEnabled; /* record if data flow is active */
112 int EtherIntIVG; /* IVG for the ethernet interrupt */
113 int RXIVG; /* IVG for the RX completion */
114 int TXIVG; /* IVG for the TX completion */
115 int PhyAddr; /* PHY address */
116 int OpMode; /* set these bits n the OPMODE regs */
117 int Port10; /* set port speed to 10 Mbit/s */
118 int GenChksums; /* IP checksums to be calculated */
119 int NoRcveLnth; /* dont insert recv length at start of buffer */
120 int StripPads; /* remove trailing pad bytes */
121 int FullDuplex; /* set full duplex mode */
122 int Negotiate; /* enable auto negotiation */
123 int Loopback; /* loopback at the PHY */
124 int Cache; /* Buffers may be cached */
125 int FlowControl; /* flow control active */
126 int CLKIN; /* clock in value in MHZ */
127 unsigned short IntMask; /* interrupt mask */
128 unsigned char Mac[6]; /* MAC address of the board */
129 spinlock_t lock;
130};
131
132extern void get_bf537_ether_addr(char *addr);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 6628fa622e2c..489c8b260dd8 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41#define DRV_NAME "ehea" 41#define DRV_NAME "ehea"
42#define DRV_VERSION "EHEA_0070" 42#define DRV_VERSION "EHEA_0071"
43 43
44/* eHEA capability flags */ 44/* eHEA capability flags */
45#define DLPAR_PORT_ADD_REM 1 45#define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 1d1571cf322e..4c70a9301c1b 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -466,6 +466,8 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
466 cqe->vlan_tag); 466 cqe->vlan_tag);
467 else 467 else
468 netif_receive_skb(skb); 468 netif_receive_skb(skb);
469
470 dev->last_rx = jiffies;
469 } else { 471 } else {
470 pr->p_stats.poll_receive_errors++; 472 pr->p_stats.poll_receive_errors++;
471 port_reset = ehea_treat_poll_error(pr, rq, cqe, 473 port_reset = ehea_treat_poll_error(pr, rq, cqe,
@@ -1433,7 +1435,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
1433 port->logical_port_id, 1435 port->logical_port_id,
1434 reg_type, port->mac_addr, 0, hcallid); 1436 reg_type, port->mac_addr, 0, hcallid);
1435 if (hret != H_SUCCESS) { 1437 if (hret != H_SUCCESS) {
1436 ehea_error("reg_dereg_bcmc failed (tagged)"); 1438 ehea_error("%sregistering bc address failed (tagged)",
1439 hcallid == H_REG_BCMC ? "" : "de");
1437 ret = -EIO; 1440 ret = -EIO;
1438 goto out_herr; 1441 goto out_herr;
1439 } 1442 }
@@ -1444,7 +1447,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
1444 port->logical_port_id, 1447 port->logical_port_id,
1445 reg_type, port->mac_addr, 0, hcallid); 1448 reg_type, port->mac_addr, 0, hcallid);
1446 if (hret != H_SUCCESS) { 1449 if (hret != H_SUCCESS) {
1447 ehea_error("reg_dereg_bcmc failed (vlan)"); 1450 ehea_error("%sregistering bc address failed (vlan)",
1451 hcallid == H_REG_BCMC ? "" : "de");
1448 ret = -EIO; 1452 ret = -EIO;
1449 } 1453 }
1450out_herr: 1454out_herr:
@@ -2170,7 +2174,6 @@ static int ehea_up(struct net_device *dev)
2170{ 2174{
2171 int ret, i; 2175 int ret, i;
2172 struct ehea_port *port = netdev_priv(dev); 2176 struct ehea_port *port = netdev_priv(dev);
2173 u64 mac_addr = 0;
2174 2177
2175 if (port->state == EHEA_PORT_UP) 2178 if (port->state == EHEA_PORT_UP)
2176 return 0; 2179 return 0;
@@ -2189,18 +2192,10 @@ static int ehea_up(struct net_device *dev)
2189 goto out_clean_pr; 2192 goto out_clean_pr;
2190 } 2193 }
2191 2194
2192 ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
2193 if (ret) {
2194 ret = -EIO;
2195 ehea_error("out_clean_pr");
2196 goto out_clean_pr;
2197 }
2198 mac_addr = (*(u64*)dev->dev_addr) >> 16;
2199
2200 ret = ehea_reg_interrupts(dev); 2195 ret = ehea_reg_interrupts(dev);
2201 if (ret) { 2196 if (ret) {
2202 ehea_error("out_dereg_bc"); 2197 ehea_error("reg_interrupts failed. ret:%d", ret);
2203 goto out_dereg_bc; 2198 goto out_clean_pr;
2204 } 2199 }
2205 2200
2206 for(i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { 2201 for(i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
@@ -2226,9 +2221,6 @@ static int ehea_up(struct net_device *dev)
2226out_free_irqs: 2221out_free_irqs:
2227 ehea_free_interrupts(dev); 2222 ehea_free_interrupts(dev);
2228 2223
2229out_dereg_bc:
2230 ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2231
2232out_clean_pr: 2224out_clean_pr:
2233 ehea_clean_all_portres(port); 2225 ehea_clean_all_portres(port);
2234out: 2226out:
@@ -2273,7 +2265,6 @@ static int ehea_down(struct net_device *dev)
2273 &port->port_res[i].d_netdev->state)) 2265 &port->port_res[i].d_netdev->state))
2274 msleep(1); 2266 msleep(1);
2275 2267
2276 ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2277 port->state = EHEA_PORT_DOWN; 2268 port->state = EHEA_PORT_DOWN;
2278 2269
2279 ret = ehea_clean_all_portres(port); 2270 ret = ehea_clean_all_portres(port);
@@ -2655,12 +2646,18 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
2655 2646
2656 INIT_WORK(&port->reset_task, ehea_reset_port); 2647 INIT_WORK(&port->reset_task, ehea_reset_port);
2657 2648
2649 ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
2650 if (ret) {
2651 ret = -EIO;
2652 goto out_unreg_port;
2653 }
2654
2658 ehea_set_ethtool_ops(dev); 2655 ehea_set_ethtool_ops(dev);
2659 2656
2660 ret = register_netdev(dev); 2657 ret = register_netdev(dev);
2661 if (ret) { 2658 if (ret) {
2662 ehea_error("register_netdev failed. ret=%d", ret); 2659 ehea_error("register_netdev failed. ret=%d", ret);
2663 goto out_unreg_port; 2660 goto out_dereg_bc;
2664 } 2661 }
2665 2662
2666 ret = ehea_get_jumboframe_status(port, &jumbo); 2663 ret = ehea_get_jumboframe_status(port, &jumbo);
@@ -2675,6 +2672,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
2675 2672
2676 return port; 2673 return port;
2677 2674
2675out_dereg_bc:
2676 ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2677
2678out_unreg_port: 2678out_unreg_port:
2679 ehea_unregister_port(port); 2679 ehea_unregister_port(port);
2680 2680
@@ -2694,6 +2694,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
2694{ 2694{
2695 unregister_netdev(port->netdev); 2695 unregister_netdev(port->netdev);
2696 ehea_unregister_port(port); 2696 ehea_unregister_port(port);
2697 ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2697 kfree(port->mc_list); 2698 kfree(port->mc_list);
2698 free_netdev(port->netdev); 2699 free_netdev(port->netdev);
2699 port->adapter->active_ports--; 2700 port->adapter->active_ports--;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index d7a1a58de766..f92690555dd9 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -420,8 +420,18 @@ static phy_interface_t gfar_get_interface(struct net_device *dev)
420 if (ecntrl & ECNTRL_REDUCED_MODE) { 420 if (ecntrl & ECNTRL_REDUCED_MODE) {
421 if (ecntrl & ECNTRL_REDUCED_MII_MODE) 421 if (ecntrl & ECNTRL_REDUCED_MII_MODE)
422 return PHY_INTERFACE_MODE_RMII; 422 return PHY_INTERFACE_MODE_RMII;
423 else 423 else {
424 phy_interface_t interface = priv->einfo->interface;
425
426 /*
427 * This isn't autodetected right now, so it must
428 * be set by the device tree or platform code.
429 */
430 if (interface == PHY_INTERFACE_MODE_RGMII_ID)
431 return PHY_INTERFACE_MODE_RGMII_ID;
432
424 return PHY_INTERFACE_MODE_RGMII; 433 return PHY_INTERFACE_MODE_RGMII;
434 }
425 } 435 }
426 436
427 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) 437 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index 1bb088aeaf71..6b32ec94b3a8 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -30,41 +30,133 @@
30 * SOFTWARE. 30 * SOFTWARE.
31 */ 31 */
32 32
33#include <linux/workqueue.h>
34
33#include "mlx4.h" 35#include "mlx4.h"
34 36
35void mlx4_handle_catas_err(struct mlx4_dev *dev) 37enum {
38 MLX4_CATAS_POLL_INTERVAL = 5 * HZ,
39};
40
41static DEFINE_SPINLOCK(catas_lock);
42
43static LIST_HEAD(catas_list);
44static struct workqueue_struct *catas_wq;
45static struct work_struct catas_work;
46
47static int internal_err_reset = 1;
48module_param(internal_err_reset, int, 0644);
49MODULE_PARM_DESC(internal_err_reset,
50 "Reset device on internal errors if non-zero (default 1)");
51
52static void dump_err_buf(struct mlx4_dev *dev)
36{ 53{
37 struct mlx4_priv *priv = mlx4_priv(dev); 54 struct mlx4_priv *priv = mlx4_priv(dev);
38 55
39 int i; 56 int i;
40 57
41 mlx4_err(dev, "Catastrophic error detected:\n"); 58 mlx4_err(dev, "Internal error detected:\n");
42 for (i = 0; i < priv->fw.catas_size; ++i) 59 for (i = 0; i < priv->fw.catas_size; ++i)
43 mlx4_err(dev, " buf[%02x]: %08x\n", 60 mlx4_err(dev, " buf[%02x]: %08x\n",
44 i, swab32(readl(priv->catas_err.map + i))); 61 i, swab32(readl(priv->catas_err.map + i)));
62}
45 63
46 mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0); 64static void poll_catas(unsigned long dev_ptr)
65{
66 struct mlx4_dev *dev = (struct mlx4_dev *) dev_ptr;
67 struct mlx4_priv *priv = mlx4_priv(dev);
68
69 if (readl(priv->catas_err.map)) {
70 dump_err_buf(dev);
71
72 mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0);
73
74 if (internal_err_reset) {
75 spin_lock(&catas_lock);
76 list_add(&priv->catas_err.list, &catas_list);
77 spin_unlock(&catas_lock);
78
79 queue_work(catas_wq, &catas_work);
80 }
81 } else
82 mod_timer(&priv->catas_err.timer,
83 round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL));
47} 84}
48 85
49void mlx4_map_catas_buf(struct mlx4_dev *dev) 86static void catas_reset(struct work_struct *work)
87{
88 struct mlx4_priv *priv, *tmppriv;
89 struct mlx4_dev *dev;
90
91 LIST_HEAD(tlist);
92 int ret;
93
94 spin_lock_irq(&catas_lock);
95 list_splice_init(&catas_list, &tlist);
96 spin_unlock_irq(&catas_lock);
97
98 list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) {
99 ret = mlx4_restart_one(priv->dev.pdev);
100 dev = &priv->dev;
101 if (ret)
102 mlx4_err(dev, "Reset failed (%d)\n", ret);
103 else
104 mlx4_dbg(dev, "Reset succeeded\n");
105 }
106}
107
108void mlx4_start_catas_poll(struct mlx4_dev *dev)
50{ 109{
51 struct mlx4_priv *priv = mlx4_priv(dev); 110 struct mlx4_priv *priv = mlx4_priv(dev);
52 unsigned long addr; 111 unsigned long addr;
53 112
113 INIT_LIST_HEAD(&priv->catas_err.list);
114 init_timer(&priv->catas_err.timer);
115 priv->catas_err.map = NULL;
116
54 addr = pci_resource_start(dev->pdev, priv->fw.catas_bar) + 117 addr = pci_resource_start(dev->pdev, priv->fw.catas_bar) +
55 priv->fw.catas_offset; 118 priv->fw.catas_offset;
56 119
57 priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4); 120 priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4);
58 if (!priv->catas_err.map) 121 if (!priv->catas_err.map) {
59 mlx4_warn(dev, "Failed to map catastrophic error buffer at 0x%lx\n", 122 mlx4_warn(dev, "Failed to map internal error buffer at 0x%lx\n",
60 addr); 123 addr);
124 return;
125 }
61 126
127 priv->catas_err.timer.data = (unsigned long) dev;
128 priv->catas_err.timer.function = poll_catas;
129 priv->catas_err.timer.expires =
130 round_jiffies(jiffies + MLX4_CATAS_POLL_INTERVAL);
131 add_timer(&priv->catas_err.timer);
62} 132}
63 133
64void mlx4_unmap_catas_buf(struct mlx4_dev *dev) 134void mlx4_stop_catas_poll(struct mlx4_dev *dev)
65{ 135{
66 struct mlx4_priv *priv = mlx4_priv(dev); 136 struct mlx4_priv *priv = mlx4_priv(dev);
67 137
138 del_timer_sync(&priv->catas_err.timer);
139
68 if (priv->catas_err.map) 140 if (priv->catas_err.map)
69 iounmap(priv->catas_err.map); 141 iounmap(priv->catas_err.map);
142
143 spin_lock_irq(&catas_lock);
144 list_del(&priv->catas_err.list);
145 spin_unlock_irq(&catas_lock);
146}
147
148int __init mlx4_catas_init(void)
149{
150 INIT_WORK(&catas_work, catas_reset);
151
152 catas_wq = create_singlethread_workqueue("mlx4_err");
153 if (!catas_wq)
154 return -ENOMEM;
155
156 return 0;
157}
158
159void mlx4_catas_cleanup(void)
160{
161 destroy_workqueue(catas_wq);
70} 162}
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 27a82cecd693..2095c843fa15 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -89,14 +89,12 @@ struct mlx4_eq_context {
89 (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED) | \ 89 (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED) | \
90 (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \ 90 (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
91 (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR) | \ 91 (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR) | \
92 (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR) | \
93 (1ull << MLX4_EVENT_TYPE_PORT_CHANGE) | \ 92 (1ull << MLX4_EVENT_TYPE_PORT_CHANGE) | \
94 (1ull << MLX4_EVENT_TYPE_ECC_DETECT) | \ 93 (1ull << MLX4_EVENT_TYPE_ECC_DETECT) | \
95 (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) | \ 94 (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) | \
96 (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE) | \ 95 (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE) | \
97 (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \ 96 (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT) | \
98 (1ull << MLX4_EVENT_TYPE_CMD)) 97 (1ull << MLX4_EVENT_TYPE_CMD))
99#define MLX4_CATAS_EVENT_MASK (1ull << MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR)
100 98
101struct mlx4_eqe { 99struct mlx4_eqe {
102 u8 reserved1; 100 u8 reserved1;
@@ -264,7 +262,7 @@ static irqreturn_t mlx4_interrupt(int irq, void *dev_ptr)
264 262
265 writel(priv->eq_table.clr_mask, priv->eq_table.clr_int); 263 writel(priv->eq_table.clr_mask, priv->eq_table.clr_int);
266 264
267 for (i = 0; i < MLX4_EQ_CATAS; ++i) 265 for (i = 0; i < MLX4_NUM_EQ; ++i)
268 work |= mlx4_eq_int(dev, &priv->eq_table.eq[i]); 266 work |= mlx4_eq_int(dev, &priv->eq_table.eq[i]);
269 267
270 return IRQ_RETVAL(work); 268 return IRQ_RETVAL(work);
@@ -281,14 +279,6 @@ static irqreturn_t mlx4_msi_x_interrupt(int irq, void *eq_ptr)
281 return IRQ_HANDLED; 279 return IRQ_HANDLED;
282} 280}
283 281
284static irqreturn_t mlx4_catas_interrupt(int irq, void *dev_ptr)
285{
286 mlx4_handle_catas_err(dev_ptr);
287
288 /* MSI-X vectors always belong to us */
289 return IRQ_HANDLED;
290}
291
292static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap, 282static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap,
293 int eq_num) 283 int eq_num)
294{ 284{
@@ -490,11 +480,9 @@ static void mlx4_free_irqs(struct mlx4_dev *dev)
490 480
491 if (eq_table->have_irq) 481 if (eq_table->have_irq)
492 free_irq(dev->pdev->irq, dev); 482 free_irq(dev->pdev->irq, dev);
493 for (i = 0; i < MLX4_EQ_CATAS; ++i) 483 for (i = 0; i < MLX4_NUM_EQ; ++i)
494 if (eq_table->eq[i].have_irq) 484 if (eq_table->eq[i].have_irq)
495 free_irq(eq_table->eq[i].irq, eq_table->eq + i); 485 free_irq(eq_table->eq[i].irq, eq_table->eq + i);
496 if (eq_table->eq[MLX4_EQ_CATAS].have_irq)
497 free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev);
498} 486}
499 487
500static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev) 488static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)
@@ -598,32 +586,19 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev)
598 if (dev->flags & MLX4_FLAG_MSI_X) { 586 if (dev->flags & MLX4_FLAG_MSI_X) {
599 static const char *eq_name[] = { 587 static const char *eq_name[] = {
600 [MLX4_EQ_COMP] = DRV_NAME " (comp)", 588 [MLX4_EQ_COMP] = DRV_NAME " (comp)",
601 [MLX4_EQ_ASYNC] = DRV_NAME " (async)", 589 [MLX4_EQ_ASYNC] = DRV_NAME " (async)"
602 [MLX4_EQ_CATAS] = DRV_NAME " (catas)"
603 }; 590 };
604 591
605 err = mlx4_create_eq(dev, 1, MLX4_EQ_CATAS, 592 for (i = 0; i < MLX4_NUM_EQ; ++i) {
606 &priv->eq_table.eq[MLX4_EQ_CATAS]);
607 if (err)
608 goto err_out_async;
609
610 for (i = 0; i < MLX4_EQ_CATAS; ++i) {
611 err = request_irq(priv->eq_table.eq[i].irq, 593 err = request_irq(priv->eq_table.eq[i].irq,
612 mlx4_msi_x_interrupt, 594 mlx4_msi_x_interrupt,
613 0, eq_name[i], priv->eq_table.eq + i); 595 0, eq_name[i], priv->eq_table.eq + i);
614 if (err) 596 if (err)
615 goto err_out_catas; 597 goto err_out_async;
616 598
617 priv->eq_table.eq[i].have_irq = 1; 599 priv->eq_table.eq[i].have_irq = 1;
618 } 600 }
619 601
620 err = request_irq(priv->eq_table.eq[MLX4_EQ_CATAS].irq,
621 mlx4_catas_interrupt, 0,
622 eq_name[MLX4_EQ_CATAS], dev);
623 if (err)
624 goto err_out_catas;
625
626 priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1;
627 } else { 602 } else {
628 err = request_irq(dev->pdev->irq, mlx4_interrupt, 603 err = request_irq(dev->pdev->irq, mlx4_interrupt,
629 IRQF_SHARED, DRV_NAME, dev); 604 IRQF_SHARED, DRV_NAME, dev);
@@ -639,22 +614,11 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev)
639 mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n", 614 mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n",
640 priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err); 615 priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err);
641 616
642 for (i = 0; i < MLX4_EQ_CATAS; ++i) 617 for (i = 0; i < MLX4_NUM_EQ; ++i)
643 eq_set_ci(&priv->eq_table.eq[i], 1); 618 eq_set_ci(&priv->eq_table.eq[i], 1);
644 619
645 if (dev->flags & MLX4_FLAG_MSI_X) {
646 err = mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 0,
647 priv->eq_table.eq[MLX4_EQ_CATAS].eqn);
648 if (err)
649 mlx4_warn(dev, "MAP_EQ for catas EQ %d failed (%d)\n",
650 priv->eq_table.eq[MLX4_EQ_CATAS].eqn, err);
651 }
652
653 return 0; 620 return 0;
654 621
655err_out_catas:
656 mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]);
657
658err_out_async: 622err_out_async:
659 mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]); 623 mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]);
660 624
@@ -675,19 +639,13 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
675 struct mlx4_priv *priv = mlx4_priv(dev); 639 struct mlx4_priv *priv = mlx4_priv(dev);
676 int i; 640 int i;
677 641
678 if (dev->flags & MLX4_FLAG_MSI_X)
679 mlx4_MAP_EQ(dev, MLX4_CATAS_EVENT_MASK, 1,
680 priv->eq_table.eq[MLX4_EQ_CATAS].eqn);
681
682 mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1, 642 mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1,
683 priv->eq_table.eq[MLX4_EQ_ASYNC].eqn); 643 priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);
684 644
685 mlx4_free_irqs(dev); 645 mlx4_free_irqs(dev);
686 646
687 for (i = 0; i < MLX4_EQ_CATAS; ++i) 647 for (i = 0; i < MLX4_NUM_EQ; ++i)
688 mlx4_free_eq(dev, &priv->eq_table.eq[i]); 648 mlx4_free_eq(dev, &priv->eq_table.eq[i]);
689 if (dev->flags & MLX4_FLAG_MSI_X)
690 mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_CATAS]);
691 649
692 mlx4_unmap_clr_int(dev); 650 mlx4_unmap_clr_int(dev);
693 651
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 9ae951bf6aa6..be5d9e90ccf2 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -142,6 +142,7 @@ int mlx4_register_device(struct mlx4_dev *dev)
142 mlx4_add_device(intf, priv); 142 mlx4_add_device(intf, priv);
143 143
144 mutex_unlock(&intf_mutex); 144 mutex_unlock(&intf_mutex);
145 mlx4_start_catas_poll(dev);
145 146
146 return 0; 147 return 0;
147} 148}
@@ -151,6 +152,7 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
151 struct mlx4_priv *priv = mlx4_priv(dev); 152 struct mlx4_priv *priv = mlx4_priv(dev);
152 struct mlx4_interface *intf; 153 struct mlx4_interface *intf;
153 154
155 mlx4_stop_catas_poll(dev);
154 mutex_lock(&intf_mutex); 156 mutex_lock(&intf_mutex);
155 157
156 list_for_each_entry(intf, &intf_list, list) 158 list_for_each_entry(intf, &intf_list, list)
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index a4f2e0475a71..4dc9dc19b716 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -78,7 +78,7 @@ static const char mlx4_version[] __devinitdata =
78static struct mlx4_profile default_profile = { 78static struct mlx4_profile default_profile = {
79 .num_qp = 1 << 16, 79 .num_qp = 1 << 16,
80 .num_srq = 1 << 16, 80 .num_srq = 1 << 16,
81 .rdmarc_per_qp = 4, 81 .rdmarc_per_qp = 1 << 4,
82 .num_cq = 1 << 16, 82 .num_cq = 1 << 16,
83 .num_mcg = 1 << 13, 83 .num_mcg = 1 << 13,
84 .num_mpt = 1 << 17, 84 .num_mpt = 1 << 17,
@@ -583,13 +583,11 @@ static int __devinit mlx4_setup_hca(struct mlx4_dev *dev)
583 goto err_pd_table_free; 583 goto err_pd_table_free;
584 } 584 }
585 585
586 mlx4_map_catas_buf(dev);
587
588 err = mlx4_init_eq_table(dev); 586 err = mlx4_init_eq_table(dev);
589 if (err) { 587 if (err) {
590 mlx4_err(dev, "Failed to initialize " 588 mlx4_err(dev, "Failed to initialize "
591 "event queue table, aborting.\n"); 589 "event queue table, aborting.\n");
592 goto err_catas_buf; 590 goto err_mr_table_free;
593 } 591 }
594 592
595 err = mlx4_cmd_use_events(dev); 593 err = mlx4_cmd_use_events(dev);
@@ -659,8 +657,7 @@ err_cmd_poll:
659err_eq_table_free: 657err_eq_table_free:
660 mlx4_cleanup_eq_table(dev); 658 mlx4_cleanup_eq_table(dev);
661 659
662err_catas_buf: 660err_mr_table_free:
663 mlx4_unmap_catas_buf(dev);
664 mlx4_cleanup_mr_table(dev); 661 mlx4_cleanup_mr_table(dev);
665 662
666err_pd_table_free: 663err_pd_table_free:
@@ -836,9 +833,6 @@ err_cleanup:
836 mlx4_cleanup_cq_table(dev); 833 mlx4_cleanup_cq_table(dev);
837 mlx4_cmd_use_polling(dev); 834 mlx4_cmd_use_polling(dev);
838 mlx4_cleanup_eq_table(dev); 835 mlx4_cleanup_eq_table(dev);
839
840 mlx4_unmap_catas_buf(dev);
841
842 mlx4_cleanup_mr_table(dev); 836 mlx4_cleanup_mr_table(dev);
843 mlx4_cleanup_pd_table(dev); 837 mlx4_cleanup_pd_table(dev);
844 mlx4_cleanup_uar_table(dev); 838 mlx4_cleanup_uar_table(dev);
@@ -885,9 +879,6 @@ static void __devexit mlx4_remove_one(struct pci_dev *pdev)
885 mlx4_cleanup_cq_table(dev); 879 mlx4_cleanup_cq_table(dev);
886 mlx4_cmd_use_polling(dev); 880 mlx4_cmd_use_polling(dev);
887 mlx4_cleanup_eq_table(dev); 881 mlx4_cleanup_eq_table(dev);
888
889 mlx4_unmap_catas_buf(dev);
890
891 mlx4_cleanup_mr_table(dev); 882 mlx4_cleanup_mr_table(dev);
892 mlx4_cleanup_pd_table(dev); 883 mlx4_cleanup_pd_table(dev);
893 884
@@ -908,6 +899,12 @@ static void __devexit mlx4_remove_one(struct pci_dev *pdev)
908 } 899 }
909} 900}
910 901
902int mlx4_restart_one(struct pci_dev *pdev)
903{
904 mlx4_remove_one(pdev);
905 return mlx4_init_one(pdev, NULL);
906}
907
911static struct pci_device_id mlx4_pci_table[] = { 908static struct pci_device_id mlx4_pci_table[] = {
912 { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */ 909 { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */
913 { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */ 910 { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */
@@ -930,6 +927,10 @@ static int __init mlx4_init(void)
930{ 927{
931 int ret; 928 int ret;
932 929
930 ret = mlx4_catas_init();
931 if (ret)
932 return ret;
933
933 ret = pci_register_driver(&mlx4_driver); 934 ret = pci_register_driver(&mlx4_driver);
934 return ret < 0 ? ret : 0; 935 return ret < 0 ? ret : 0;
935} 936}
@@ -937,6 +938,7 @@ static int __init mlx4_init(void)
937static void __exit mlx4_cleanup(void) 938static void __exit mlx4_cleanup(void)
938{ 939{
939 pci_unregister_driver(&mlx4_driver); 940 pci_unregister_driver(&mlx4_driver);
941 mlx4_catas_cleanup();
940} 942}
941 943
942module_init(mlx4_init); 944module_init(mlx4_init);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index d9c91a71fc87..be304a7c2c91 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -39,6 +39,7 @@
39 39
40#include <linux/mutex.h> 40#include <linux/mutex.h>
41#include <linux/radix-tree.h> 41#include <linux/radix-tree.h>
42#include <linux/timer.h>
42 43
43#include <linux/mlx4/device.h> 44#include <linux/mlx4/device.h>
44#include <linux/mlx4/doorbell.h> 45#include <linux/mlx4/doorbell.h>
@@ -67,7 +68,6 @@ enum {
67enum { 68enum {
68 MLX4_EQ_ASYNC, 69 MLX4_EQ_ASYNC,
69 MLX4_EQ_COMP, 70 MLX4_EQ_COMP,
70 MLX4_EQ_CATAS,
71 MLX4_NUM_EQ 71 MLX4_NUM_EQ
72}; 72};
73 73
@@ -248,7 +248,8 @@ struct mlx4_mcg_table {
248 248
249struct mlx4_catas_err { 249struct mlx4_catas_err {
250 u32 __iomem *map; 250 u32 __iomem *map;
251 int size; 251 struct timer_list timer;
252 struct list_head list;
252}; 253};
253 254
254struct mlx4_priv { 255struct mlx4_priv {
@@ -311,9 +312,11 @@ void mlx4_cleanup_qp_table(struct mlx4_dev *dev);
311void mlx4_cleanup_srq_table(struct mlx4_dev *dev); 312void mlx4_cleanup_srq_table(struct mlx4_dev *dev);
312void mlx4_cleanup_mcg_table(struct mlx4_dev *dev); 313void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
313 314
314void mlx4_map_catas_buf(struct mlx4_dev *dev); 315void mlx4_start_catas_poll(struct mlx4_dev *dev);
315void mlx4_unmap_catas_buf(struct mlx4_dev *dev); 316void mlx4_stop_catas_poll(struct mlx4_dev *dev);
316 317int mlx4_catas_init(void);
318void mlx4_catas_cleanup(void);
319int mlx4_restart_one(struct pci_dev *pdev);
317int mlx4_register_device(struct mlx4_dev *dev); 320int mlx4_register_device(struct mlx4_dev *dev);
318void mlx4_unregister_device(struct mlx4_dev *dev); 321void mlx4_unregister_device(struct mlx4_dev *dev);
319void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_event type, 322void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_event type,
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 3d5b4232f65f..22a3b3dc7d89 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -670,14 +670,10 @@ static void ni5010_set_multicast_list(struct net_device *dev)
670 670
671 PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name)); 671 PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
672 672
673 if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI) { 673 if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
674 dev->flags |= IFF_PROMISC; 674 dev->flags |= IFF_PROMISC;
675 outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */ 675 outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
676 PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name)); 676 PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
677 } else if (dev->mc_list) {
678 /* Sorry, multicast not supported */
679 PRINTK((KERN_DEBUG "%s: No multicast, entering broadcast mode\n", dev->name));
680 outb(RMD_BROADCAST, EDLC_RMODE);
681 } else { 677 } else {
682 PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name)); 678 PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name));
683 outb(RMD_BROADCAST, EDLC_RMODE); /* Disable promiscuous mode, use normal mode */ 679 outb(RMD_BROADCAST, EDLC_RMODE); /* Disable promiscuous mode, use normal mode */
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 104aab3c957f..ea80e6cb3dec 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1582,7 +1582,7 @@ static void ns83820_set_multicast(struct net_device *ndev)
1582 else 1582 else
1583 and_mask &= ~(RFCR_AAU | RFCR_AAM); 1583 and_mask &= ~(RFCR_AAU | RFCR_AAM);
1584 1584
1585 if (ndev->flags & IFF_ALLMULTI) 1585 if (ndev->flags & IFF_ALLMULTI || ndev->mc_count)
1586 or_mask |= RFCR_AAM; 1586 or_mask |= RFCR_AAM;
1587 else 1587 else
1588 and_mask &= ~RFCR_AAM; 1588 and_mask &= ~RFCR_AAM;
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 596222b260d6..6a5385647911 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -21,6 +21,10 @@
21/* Vitesse Extended Control Register 1 */ 21/* Vitesse Extended Control Register 1 */
22#define MII_VSC8244_EXT_CON1 0x17 22#define MII_VSC8244_EXT_CON1 0x17
23#define MII_VSC8244_EXTCON1_INIT 0x0000 23#define MII_VSC8244_EXTCON1_INIT 0x0000
24#define MII_VSC8244_EXTCON1_TX_SKEW_MASK 0x0c00
25#define MII_VSC8244_EXTCON1_RX_SKEW_MASK 0x0300
26#define MII_VSC8244_EXTCON1_TX_SKEW 0x0800
27#define MII_VSC8244_EXTCON1_RX_SKEW 0x0200
24 28
25/* Vitesse Interrupt Mask Register */ 29/* Vitesse Interrupt Mask Register */
26#define MII_VSC8244_IMASK 0x19 30#define MII_VSC8244_IMASK 0x19
@@ -39,7 +43,7 @@
39 43
40/* Vitesse Auxiliary Control/Status Register */ 44/* Vitesse Auxiliary Control/Status Register */
41#define MII_VSC8244_AUX_CONSTAT 0x1c 45#define MII_VSC8244_AUX_CONSTAT 0x1c
42#define MII_VSC8244_AUXCONSTAT_INIT 0x0004 46#define MII_VSC8244_AUXCONSTAT_INIT 0x0000
43#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 47#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020
44#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 48#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018
45#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 49#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010
@@ -51,6 +55,7 @@ MODULE_LICENSE("GPL");
51 55
52static int vsc824x_config_init(struct phy_device *phydev) 56static int vsc824x_config_init(struct phy_device *phydev)
53{ 57{
58 int extcon;
54 int err; 59 int err;
55 60
56 err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, 61 err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
@@ -58,14 +63,34 @@ static int vsc824x_config_init(struct phy_device *phydev)
58 if (err < 0) 63 if (err < 0)
59 return err; 64 return err;
60 65
61 err = phy_write(phydev, MII_VSC8244_EXT_CON1, 66 extcon = phy_read(phydev, MII_VSC8244_EXT_CON1);
62 MII_VSC8244_EXTCON1_INIT); 67
68 if (extcon < 0)
69 return err;
70
71 extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK |
72 MII_VSC8244_EXTCON1_RX_SKEW_MASK);
73
74 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
75 extcon |= (MII_VSC8244_EXTCON1_TX_SKEW |
76 MII_VSC8244_EXTCON1_RX_SKEW);
77
78 err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon);
79
63 return err; 80 return err;
64} 81}
65 82
66static int vsc824x_ack_interrupt(struct phy_device *phydev) 83static int vsc824x_ack_interrupt(struct phy_device *phydev)
67{ 84{
68 int err = phy_read(phydev, MII_VSC8244_ISTAT); 85 int err = 0;
86
87 /*
88 * Don't bother to ACK the interrupts if interrupts
89 * are disabled. The 824x cannot clear the interrupts
90 * if they are disabled.
91 */
92 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
93 err = phy_read(phydev, MII_VSC8244_ISTAT);
69 94
70 return (err < 0) ? err : 0; 95 return (err < 0) ? err : 0;
71} 96}
@@ -77,8 +102,19 @@ static int vsc824x_config_intr(struct phy_device *phydev)
77 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 102 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
78 err = phy_write(phydev, MII_VSC8244_IMASK, 103 err = phy_write(phydev, MII_VSC8244_IMASK,
79 MII_VSC8244_IMASK_MASK); 104 MII_VSC8244_IMASK_MASK);
80 else 105 else {
106 /*
107 * The Vitesse PHY cannot clear the interrupt
108 * once it has disabled them, so we clear them first
109 */
110 err = phy_read(phydev, MII_VSC8244_ISTAT);
111
112 if (err)
113 return err;
114
81 err = phy_write(phydev, MII_VSC8244_IMASK, 0); 115 err = phy_write(phydev, MII_VSC8244_IMASK, 0);
116 }
117
82 return err; 118 return err;
83} 119}
84 120
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index 451486b32f23..7dae4d404978 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -940,15 +940,14 @@ static void lan_saa9730_set_multicast(struct net_device *dev)
940 CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC, 940 CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
941 &lp->lan_saa9730_regs->CamCtl); 941 &lp->lan_saa9730_regs->CamCtl);
942 } else { 942 } else {
943 if (dev->flags & IFF_ALLMULTI) { 943 if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
944 /* accept all multicast packets */ 944 /* accept all multicast packets */
945 writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
946 CAM_CONTROL_BROAD_ACC,
947 &lp->lan_saa9730_regs->CamCtl);
948 } else {
949 /* 945 /*
950 * Will handle the multicast stuff later. -carstenl 946 * Will handle the multicast stuff later. -carstenl
951 */ 947 */
948 writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
949 CAM_CONTROL_BROAD_ACC,
950 &lp->lan_saa9730_regs->CamCtl);
952 } 951 }
953 } 952 }
954 953
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 75655add3f34..7f94ca930988 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -626,7 +626,7 @@ static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
626 return -ENODEV; 626 return -ENODEV;
627} 627}
628#else 628#else
629static int __devinit tc35815_read_plat_dev_addr(struct device *dev) 629static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
630{ 630{
631 return -ENODEV; 631 return -ENODEV;
632} 632}
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 072ede71e575..8990585bd228 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -7868,10 +7868,10 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7868 goto done; 7868 goto done;
7869 } 7869 }
7870 7870
7871 if ((mode < 1) || (mode > POWER_MODES)) 7871 if ((mode < 0) || (mode > POWER_MODES))
7872 mode = IPW_POWER_AUTO; 7872 mode = IPW_POWER_AUTO;
7873 7873
7874 if (priv->power_mode != mode) 7874 if (IPW_POWER_LEVEL(priv->power_mode) != mode)
7875 err = ipw2100_set_power_mode(priv, mode); 7875 err = ipw2100_set_power_mode(priv, mode);
7876 done: 7876 done:
7877 mutex_unlock(&priv->action_mutex); 7877 mutex_unlock(&priv->action_mutex);
@@ -7902,7 +7902,7 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
7902 break; 7902 break;
7903 case IPW_POWER_AUTO: 7903 case IPW_POWER_AUTO:
7904 snprintf(extra, MAX_POWER_STRING, 7904 snprintf(extra, MAX_POWER_STRING,
7905 "Power save level: %d (Auto)", 0); 7905 "Power save level: %d (Auto)", level);
7906 break; 7906 break;
7907 default: 7907 default:
7908 timeout = timeout_duration[level - 1] / 1000; 7908 timeout = timeout_duration[level - 1] / 1000;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index aa32a97380ec..61497c467467 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -70,7 +70,7 @@
70#define VQ 70#define VQ
71#endif 71#endif
72 72
73#define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ 73#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ
74#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 74#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
75#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" 75#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
76#define DRV_VERSION IPW2200_VERSION 76#define DRV_VERSION IPW2200_VERSION
@@ -2506,7 +2506,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2506 break; 2506 break;
2507 } 2507 }
2508 2508
2509 param = cpu_to_le32(mode); 2509 param = cpu_to_le32(param);
2510 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), 2510 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
2511 &param); 2511 &param);
2512} 2512}
@@ -9568,6 +9568,7 @@ static int ipw_wx_set_power(struct net_device *dev,
9568 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; 9568 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
9569 else 9569 else
9570 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; 9570 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
9571
9571 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9572 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
9572 if (err) { 9573 if (err) {
9573 IPW_DEBUG_WX("failed setting power mode.\n"); 9574 IPW_DEBUG_WX("failed setting power mode.\n");
@@ -9604,22 +9605,19 @@ static int ipw_wx_set_powermode(struct net_device *dev,
9604 struct ipw_priv *priv = ieee80211_priv(dev); 9605 struct ipw_priv *priv = ieee80211_priv(dev);
9605 int mode = *(int *)extra; 9606 int mode = *(int *)extra;
9606 int err; 9607 int err;
9608
9607 mutex_lock(&priv->mutex); 9609 mutex_lock(&priv->mutex);
9608 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9610 if ((mode < 1) || (mode > IPW_POWER_LIMIT))
9609 mode = IPW_POWER_AC; 9611 mode = IPW_POWER_AC;
9610 priv->power_mode = mode;
9611 } else {
9612 priv->power_mode = IPW_POWER_ENABLED | mode;
9613 }
9614 9612
9615 if (priv->power_mode != mode) { 9613 if (IPW_POWER_LEVEL(priv->power_mode) != mode) {
9616 err = ipw_send_power_mode(priv, mode); 9614 err = ipw_send_power_mode(priv, mode);
9617
9618 if (err) { 9615 if (err) {
9619 IPW_DEBUG_WX("failed setting power mode.\n"); 9616 IPW_DEBUG_WX("failed setting power mode.\n");
9620 mutex_unlock(&priv->mutex); 9617 mutex_unlock(&priv->mutex);
9621 return err; 9618 return err;
9622 } 9619 }
9620 priv->power_mode = IPW_POWER_ENABLED | mode;
9623 } 9621 }
9624 mutex_unlock(&priv->mutex); 9622 mutex_unlock(&priv->mutex);
9625 return 0; 9623 return 0;
@@ -10555,7 +10553,7 @@ static irqreturn_t ipw_isr(int irq, void *data)
10555 spin_lock(&priv->irq_lock); 10553 spin_lock(&priv->irq_lock);
10556 10554
10557 if (!(priv->status & STATUS_INT_ENABLED)) { 10555 if (!(priv->status & STATUS_INT_ENABLED)) {
10558 /* Shared IRQ */ 10556 /* IRQ is disabled */
10559 goto none; 10557 goto none;
10560 } 10558 }
10561 10559
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 28d41a29d7b1..a9c339ef116a 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -72,6 +72,8 @@ static struct usb_device_id usb_ids[] = {
72 { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, 72 { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
73 { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, 73 { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
74 { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, 74 { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
75 { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
76 { USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B },
75 /* "Driverless" devices that need ejecting */ 77 /* "Driverless" devices that need ejecting */
76 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, 78 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
77 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, 79 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 143c6efc478a..a99607142fc8 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1127,6 +1127,34 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
1127 1127
1128#endif 1128#endif
1129 1129
1130/************************ runtime PM support ***************************/
1131
1132static int pcmcia_dev_suspend(struct device *dev, pm_message_t state);
1133static int pcmcia_dev_resume(struct device *dev);
1134
1135static int runtime_suspend(struct device *dev)
1136{
1137 int rc;
1138
1139 down(&dev->sem);
1140 rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND);
1141 up(&dev->sem);
1142 if (!rc)
1143 dev->power.power_state.event = PM_EVENT_SUSPEND;
1144 return rc;
1145}
1146
1147static void runtime_resume(struct device *dev)
1148{
1149 int rc;
1150
1151 down(&dev->sem);
1152 rc = pcmcia_dev_resume(dev);
1153 up(&dev->sem);
1154 if (!rc)
1155 dev->power.power_state.event = PM_EVENT_ON;
1156}
1157
1130/************************ per-device sysfs output ***************************/ 1158/************************ per-device sysfs output ***************************/
1131 1159
1132#define pcmcia_device_attr(field, test, format) \ 1160#define pcmcia_device_attr(field, test, format) \
@@ -1173,9 +1201,9 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute
1173 return -EINVAL; 1201 return -EINVAL;
1174 1202
1175 if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) 1203 if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
1176 ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); 1204 ret = runtime_suspend(dev);
1177 else if (p_dev->suspended && !strncmp(buf, "on", 2)) 1205 else if (p_dev->suspended && !strncmp(buf, "on", 2))
1178 dpm_runtime_resume(dev); 1206 runtime_resume(dev);
1179 1207
1180 return ret ? ret : count; 1208 return ret ? ret : count;
1181} 1209}
@@ -1312,10 +1340,10 @@ static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
1312 struct pcmcia_socket *skt = _data; 1340 struct pcmcia_socket *skt = _data;
1313 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 1341 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1314 1342
1315 if (p_dev->socket != skt) 1343 if (p_dev->socket != skt || p_dev->suspended)
1316 return 0; 1344 return 0;
1317 1345
1318 return dpm_runtime_suspend(dev, PMSG_SUSPEND); 1346 return runtime_suspend(dev);
1319} 1347}
1320 1348
1321static int pcmcia_bus_resume_callback(struct device *dev, void * _data) 1349static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
@@ -1323,10 +1351,10 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
1323 struct pcmcia_socket *skt = _data; 1351 struct pcmcia_socket *skt = _data;
1324 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 1352 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1325 1353
1326 if (p_dev->socket != skt) 1354 if (p_dev->socket != skt || !p_dev->suspended)
1327 return 0; 1355 return 0;
1328 1356
1329 dpm_runtime_resume(dev); 1357 runtime_resume(dev);
1330 1358
1331 return 0; 1359 return 0;
1332} 1360}
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
new file mode 100644
index 000000000000..b778ed71f636
--- /dev/null
+++ b/drivers/uio/Kconfig
@@ -0,0 +1,29 @@
1menu "Userspace I/O"
2 depends on !S390
3
4config UIO
5 tristate "Userspace I/O drivers"
6 default n
7 help
8 Enable this to allow the userspace driver core code to be
9 built. This code allows userspace programs easy access to
10 kernel interrupts and memory locations, allowing some drivers
11 to be written in userspace. Note that a small kernel driver
12 is also required for interrupt handling to work properly.
13
14 If you don't know what to do here, say N.
15
16config UIO_CIF
17 tristate "generic Hilscher CIF Card driver"
18 depends on UIO && PCI
19 default n
20 help
21 Driver for Hilscher CIF DeviceNet and Profibus cards. This
22 driver requires a userspace component that handles all of the
23 heavy lifting and can be found at:
24 http://www.osadl.org/projects/downloads/UIO/user/cif-*
25
26 To compile this driver as a module, choose M here: the module
27 will be called uio_cif.
28
29endmenu
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
new file mode 100644
index 000000000000..7fecfb459da5
--- /dev/null
+++ b/drivers/uio/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_UIO) += uio.o
2obj-$(CONFIG_UIO_CIF) += uio_cif.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
new file mode 100644
index 000000000000..865f32b63b5c
--- /dev/null
+++ b/drivers/uio/uio.c
@@ -0,0 +1,701 @@
1/*
2 * drivers/uio/uio.c
3 *
4 * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
5 * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
6 * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
7 * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
8 *
9 * Userspace IO
10 *
11 * Base Functions
12 *
13 * Licensed under the GPLv2 only.
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/poll.h>
19#include <linux/device.h>
20#include <linux/mm.h>
21#include <linux/idr.h>
22#include <linux/string.h>
23#include <linux/kobject.h>
24#include <linux/uio_driver.h>
25
26#define UIO_MAX_DEVICES 255
27
28struct uio_device {
29 struct module *owner;
30 struct device *dev;
31 int minor;
32 atomic_t event;
33 struct fasync_struct *async_queue;
34 wait_queue_head_t wait;
35 int vma_count;
36 struct uio_info *info;
37 struct kset map_attr_kset;
38};
39
40static int uio_major;
41static DEFINE_IDR(uio_idr);
42static struct file_operations uio_fops;
43
44/* UIO class infrastructure */
45static struct uio_class {
46 struct kref kref;
47 struct class *class;
48} *uio_class;
49
50/*
51 * attributes
52 */
53
54static struct attribute attr_addr = {
55 .name = "addr",
56 .mode = S_IRUGO,
57};
58
59static struct attribute attr_size = {
60 .name = "size",
61 .mode = S_IRUGO,
62};
63
64static struct attribute* map_attrs[] = {
65 &attr_addr, &attr_size, NULL
66};
67
68static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
69 char *buf)
70{
71 struct uio_mem *mem = container_of(kobj, struct uio_mem, kobj);
72
73 if (strncmp(attr->name,"addr",4) == 0)
74 return sprintf(buf, "0x%lx\n", mem->addr);
75
76 if (strncmp(attr->name,"size",4) == 0)
77 return sprintf(buf, "0x%lx\n", mem->size);
78
79 return -ENODEV;
80}
81
82static void map_attr_release(struct kobject *kobj)
83{
84 /* TODO ??? */
85}
86
87static struct sysfs_ops map_attr_ops = {
88 .show = map_attr_show,
89};
90
91static struct kobj_type map_attr_type = {
92 .release = map_attr_release,
93 .sysfs_ops = &map_attr_ops,
94 .default_attrs = map_attrs,
95};
96
97static ssize_t show_name(struct device *dev,
98 struct device_attribute *attr, char *buf)
99{
100 struct uio_device *idev = dev_get_drvdata(dev);
101 if (idev)
102 return sprintf(buf, "%s\n", idev->info->name);
103 else
104 return -ENODEV;
105}
106static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
107
108static ssize_t show_version(struct device *dev,
109 struct device_attribute *attr, char *buf)
110{
111 struct uio_device *idev = dev_get_drvdata(dev);
112 if (idev)
113 return sprintf(buf, "%s\n", idev->info->version);
114 else
115 return -ENODEV;
116}
117static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
118
119static ssize_t show_event(struct device *dev,
120 struct device_attribute *attr, char *buf)
121{
122 struct uio_device *idev = dev_get_drvdata(dev);
123 if (idev)
124 return sprintf(buf, "%u\n",
125 (unsigned int)atomic_read(&idev->event));
126 else
127 return -ENODEV;
128}
129static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
130
131static struct attribute *uio_attrs[] = {
132 &dev_attr_name.attr,
133 &dev_attr_version.attr,
134 &dev_attr_event.attr,
135 NULL,
136};
137
138static struct attribute_group uio_attr_grp = {
139 .attrs = uio_attrs,
140};
141
142/*
143 * device functions
144 */
145static int uio_dev_add_attributes(struct uio_device *idev)
146{
147 int ret;
148 int mi;
149 int map_found = 0;
150 struct uio_mem *mem;
151
152 ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
153 if (ret)
154 goto err_group;
155
156 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
157 mem = &idev->info->mem[mi];
158 if (mem->size == 0)
159 break;
160 if (!map_found) {
161 map_found = 1;
162 kobject_set_name(&idev->map_attr_kset.kobj,"maps");
163 idev->map_attr_kset.ktype = &map_attr_type;
164 idev->map_attr_kset.kobj.parent = &idev->dev->kobj;
165 ret = kset_register(&idev->map_attr_kset);
166 if (ret)
167 goto err_remove_group;
168 }
169 kobject_init(&mem->kobj);
170 kobject_set_name(&mem->kobj,"map%d",mi);
171 mem->kobj.parent = &idev->map_attr_kset.kobj;
172 mem->kobj.kset = &idev->map_attr_kset;
173 ret = kobject_add(&mem->kobj);
174 if (ret)
175 goto err_remove_maps;
176 }
177
178 return 0;
179
180err_remove_maps:
181 for (mi--; mi>=0; mi--) {
182 mem = &idev->info->mem[mi];
183 kobject_unregister(&mem->kobj);
184 }
185 kset_unregister(&idev->map_attr_kset); /* Needed ? */
186err_remove_group:
187 sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
188err_group:
189 dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
190 return ret;
191}
192
193static void uio_dev_del_attributes(struct uio_device *idev)
194{
195 int mi;
196 struct uio_mem *mem;
197 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
198 mem = &idev->info->mem[mi];
199 if (mem->size == 0)
200 break;
201 kobject_unregister(&mem->kobj);
202 }
203 kset_unregister(&idev->map_attr_kset);
204 sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
205}
206
207static int uio_get_minor(struct uio_device *idev)
208{
209 static DEFINE_MUTEX(minor_lock);
210 int retval = -ENOMEM;
211 int id;
212
213 mutex_lock(&minor_lock);
214 if (idr_pre_get(&uio_idr, GFP_KERNEL) == 0)
215 goto exit;
216
217 retval = idr_get_new(&uio_idr, idev, &id);
218 if (retval < 0) {
219 if (retval == -EAGAIN)
220 retval = -ENOMEM;
221 goto exit;
222 }
223 idev->minor = id & MAX_ID_MASK;
224exit:
225 mutex_unlock(&minor_lock);
226 return retval;
227}
228
229static void uio_free_minor(struct uio_device *idev)
230{
231 idr_remove(&uio_idr, idev->minor);
232}
233
234/**
235 * uio_event_notify - trigger an interrupt event
236 * @info: UIO device capabilities
237 */
238void uio_event_notify(struct uio_info *info)
239{
240 struct uio_device *idev = info->uio_dev;
241
242 atomic_inc(&idev->event);
243 wake_up_interruptible(&idev->wait);
244 kill_fasync(&idev->async_queue, SIGIO, POLL_IN);
245}
246EXPORT_SYMBOL_GPL(uio_event_notify);
247
248/**
249 * uio_interrupt - hardware interrupt handler
250 * @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
251 * @dev_id: Pointer to the devices uio_device structure
252 */
253static irqreturn_t uio_interrupt(int irq, void *dev_id)
254{
255 struct uio_device *idev = (struct uio_device *)dev_id;
256 irqreturn_t ret = idev->info->handler(irq, idev->info);
257
258 if (ret == IRQ_HANDLED)
259 uio_event_notify(idev->info);
260
261 return ret;
262}
263
264struct uio_listener {
265 struct uio_device *dev;
266 s32 event_count;
267};
268
269static int uio_open(struct inode *inode, struct file *filep)
270{
271 struct uio_device *idev;
272 struct uio_listener *listener;
273 int ret = 0;
274
275 idev = idr_find(&uio_idr, iminor(inode));
276 if (!idev)
277 return -ENODEV;
278
279 listener = kmalloc(sizeof(*listener), GFP_KERNEL);
280 if (!listener)
281 return -ENOMEM;
282
283 listener->dev = idev;
284 listener->event_count = atomic_read(&idev->event);
285 filep->private_data = listener;
286
287 if (idev->info->open) {
288 if (!try_module_get(idev->owner))
289 return -ENODEV;
290 ret = idev->info->open(idev->info, inode);
291 module_put(idev->owner);
292 }
293
294 if (ret)
295 kfree(listener);
296
297 return ret;
298}
299
300static int uio_fasync(int fd, struct file *filep, int on)
301{
302 struct uio_listener *listener = filep->private_data;
303 struct uio_device *idev = listener->dev;
304
305 return fasync_helper(fd, filep, on, &idev->async_queue);
306}
307
308static int uio_release(struct inode *inode, struct file *filep)
309{
310 int ret = 0;
311 struct uio_listener *listener = filep->private_data;
312 struct uio_device *idev = listener->dev;
313
314 if (idev->info->release) {
315 if (!try_module_get(idev->owner))
316 return -ENODEV;
317 ret = idev->info->release(idev->info, inode);
318 module_put(idev->owner);
319 }
320 if (filep->f_flags & FASYNC)
321 ret = uio_fasync(-1, filep, 0);
322 kfree(listener);
323 return ret;
324}
325
326static unsigned int uio_poll(struct file *filep, poll_table *wait)
327{
328 struct uio_listener *listener = filep->private_data;
329 struct uio_device *idev = listener->dev;
330
331 if (idev->info->irq == UIO_IRQ_NONE)
332 return -EIO;
333
334 poll_wait(filep, &idev->wait, wait);
335 if (listener->event_count != atomic_read(&idev->event))
336 return POLLIN | POLLRDNORM;
337 return 0;
338}
339
340static ssize_t uio_read(struct file *filep, char __user *buf,
341 size_t count, loff_t *ppos)
342{
343 struct uio_listener *listener = filep->private_data;
344 struct uio_device *idev = listener->dev;
345 DECLARE_WAITQUEUE(wait, current);
346 ssize_t retval;
347 s32 event_count;
348
349 if (idev->info->irq == UIO_IRQ_NONE)
350 return -EIO;
351
352 if (count != sizeof(s32))
353 return -EINVAL;
354
355 add_wait_queue(&idev->wait, &wait);
356
357 do {
358 set_current_state(TASK_INTERRUPTIBLE);
359
360 event_count = atomic_read(&idev->event);
361 if (event_count != listener->event_count) {
362 if (copy_to_user(buf, &event_count, count))
363 retval = -EFAULT;
364 else {
365 listener->event_count = event_count;
366 retval = count;
367 }
368 break;
369 }
370
371 if (filep->f_flags & O_NONBLOCK) {
372 retval = -EAGAIN;
373 break;
374 }
375
376 if (signal_pending(current)) {
377 retval = -ERESTARTSYS;
378 break;
379 }
380 schedule();
381 } while (1);
382
383 __set_current_state(TASK_RUNNING);
384 remove_wait_queue(&idev->wait, &wait);
385
386 return retval;
387}
388
389static int uio_find_mem_index(struct vm_area_struct *vma)
390{
391 int mi;
392 struct uio_device *idev = vma->vm_private_data;
393
394 for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
395 if (idev->info->mem[mi].size == 0)
396 return -1;
397 if (vma->vm_pgoff == mi)
398 return mi;
399 }
400 return -1;
401}
402
403static void uio_vma_open(struct vm_area_struct *vma)
404{
405 struct uio_device *idev = vma->vm_private_data;
406 idev->vma_count++;
407}
408
409static void uio_vma_close(struct vm_area_struct *vma)
410{
411 struct uio_device *idev = vma->vm_private_data;
412 idev->vma_count--;
413}
414
415static struct page *uio_vma_nopage(struct vm_area_struct *vma,
416 unsigned long address, int *type)
417{
418 struct uio_device *idev = vma->vm_private_data;
419 struct page* page = NOPAGE_SIGBUS;
420
421 int mi = uio_find_mem_index(vma);
422 if (mi < 0)
423 return page;
424
425 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
426 page = virt_to_page(idev->info->mem[mi].addr);
427 else
428 page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
429 get_page(page);
430 if (type)
431 *type = VM_FAULT_MINOR;
432 return page;
433}
434
435static struct vm_operations_struct uio_vm_ops = {
436 .open = uio_vma_open,
437 .close = uio_vma_close,
438 .nopage = uio_vma_nopage,
439};
440
441static int uio_mmap_physical(struct vm_area_struct *vma)
442{
443 struct uio_device *idev = vma->vm_private_data;
444 int mi = uio_find_mem_index(vma);
445 if (mi < 0)
446 return -EINVAL;
447
448 vma->vm_flags |= VM_IO | VM_RESERVED;
449
450 return remap_pfn_range(vma,
451 vma->vm_start,
452 idev->info->mem[mi].addr >> PAGE_SHIFT,
453 vma->vm_end - vma->vm_start,
454 vma->vm_page_prot);
455}
456
457static int uio_mmap_logical(struct vm_area_struct *vma)
458{
459 vma->vm_flags |= VM_RESERVED;
460 vma->vm_ops = &uio_vm_ops;
461 uio_vma_open(vma);
462 return 0;
463}
464
465static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
466{
467 struct uio_listener *listener = filep->private_data;
468 struct uio_device *idev = listener->dev;
469 int mi;
470 unsigned long requested_pages, actual_pages;
471 int ret = 0;
472
473 if (vma->vm_end < vma->vm_start)
474 return -EINVAL;
475
476 vma->vm_private_data = idev;
477
478 mi = uio_find_mem_index(vma);
479 if (mi < 0)
480 return -EINVAL;
481
482 requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
483 actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
484 if (requested_pages > actual_pages)
485 return -EINVAL;
486
487 if (idev->info->mmap) {
488 if (!try_module_get(idev->owner))
489 return -ENODEV;
490 ret = idev->info->mmap(idev->info, vma);
491 module_put(idev->owner);
492 return ret;
493 }
494
495 switch (idev->info->mem[mi].memtype) {
496 case UIO_MEM_PHYS:
497 return uio_mmap_physical(vma);
498 case UIO_MEM_LOGICAL:
499 case UIO_MEM_VIRTUAL:
500 return uio_mmap_logical(vma);
501 default:
502 return -EINVAL;
503 }
504}
505
506static struct file_operations uio_fops = {
507 .owner = THIS_MODULE,
508 .open = uio_open,
509 .release = uio_release,
510 .read = uio_read,
511 .mmap = uio_mmap,
512 .poll = uio_poll,
513 .fasync = uio_fasync,
514};
515
516static int uio_major_init(void)
517{
518 uio_major = register_chrdev(0, "uio", &uio_fops);
519 if (uio_major < 0)
520 return uio_major;
521 return 0;
522}
523
524static void uio_major_cleanup(void)
525{
526 unregister_chrdev(uio_major, "uio");
527}
528
529static int init_uio_class(void)
530{
531 int ret = 0;
532
533 if (uio_class != NULL) {
534 kref_get(&uio_class->kref);
535 goto exit;
536 }
537
538 /* This is the first time in here, set everything up properly */
539 ret = uio_major_init();
540 if (ret)
541 goto exit;
542
543 uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
544 if (!uio_class) {
545 ret = -ENOMEM;
546 goto err_kzalloc;
547 }
548
549 kref_init(&uio_class->kref);
550 uio_class->class = class_create(THIS_MODULE, "uio");
551 if (IS_ERR(uio_class->class)) {
552 ret = IS_ERR(uio_class->class);
553 printk(KERN_ERR "class_create failed for uio\n");
554 goto err_class_create;
555 }
556 return 0;
557
558err_class_create:
559 kfree(uio_class);
560 uio_class = NULL;
561err_kzalloc:
562 uio_major_cleanup();
563exit:
564 return ret;
565}
566
567static void release_uio_class(struct kref *kref)
568{
569 /* Ok, we cheat as we know we only have one uio_class */
570 class_destroy(uio_class->class);
571 kfree(uio_class);
572 uio_major_cleanup();
573 uio_class = NULL;
574}
575
576static void uio_class_destroy(void)
577{
578 if (uio_class)
579 kref_put(&uio_class->kref, release_uio_class);
580}
581
582/**
583 * uio_register_device - register a new userspace IO device
584 * @owner: module that creates the new device
585 * @parent: parent device
586 * @info: UIO device capabilities
587 *
588 * returns zero on success or a negative error code.
589 */
590int __uio_register_device(struct module *owner,
591 struct device *parent,
592 struct uio_info *info)
593{
594 struct uio_device *idev;
595 int ret = 0;
596
597 if (!parent || !info || !info->name || !info->version)
598 return -EINVAL;
599
600 info->uio_dev = NULL;
601
602 ret = init_uio_class();
603 if (ret)
604 return ret;
605
606 idev = kzalloc(sizeof(*idev), GFP_KERNEL);
607 if (!idev) {
608 ret = -ENOMEM;
609 goto err_kzalloc;
610 }
611
612 idev->owner = owner;
613 idev->info = info;
614 init_waitqueue_head(&idev->wait);
615 atomic_set(&idev->event, 0);
616
617 ret = uio_get_minor(idev);
618 if (ret)
619 goto err_get_minor;
620
621 idev->dev = device_create(uio_class->class, parent,
622 MKDEV(uio_major, idev->minor),
623 "uio%d", idev->minor);
624 if (IS_ERR(idev->dev)) {
625 printk(KERN_ERR "UIO: device register failed\n");
626 ret = PTR_ERR(idev->dev);
627 goto err_device_create;
628 }
629 dev_set_drvdata(idev->dev, idev);
630
631 ret = uio_dev_add_attributes(idev);
632 if (ret)
633 goto err_uio_dev_add_attributes;
634
635 info->uio_dev = idev;
636
637 if (idev->info->irq >= 0) {
638 ret = request_irq(idev->info->irq, uio_interrupt,
639 idev->info->irq_flags, idev->info->name, idev);
640 if (ret)
641 goto err_request_irq;
642 }
643
644 return 0;
645
646err_request_irq:
647 uio_dev_del_attributes(idev);
648err_uio_dev_add_attributes:
649 device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
650err_device_create:
651 uio_free_minor(idev);
652err_get_minor:
653 kfree(idev);
654err_kzalloc:
655 uio_class_destroy();
656 return ret;
657}
658EXPORT_SYMBOL_GPL(__uio_register_device);
659
660/**
661 * uio_unregister_device - unregister a industrial IO device
662 * @info: UIO device capabilities
663 *
664 */
665void uio_unregister_device(struct uio_info *info)
666{
667 struct uio_device *idev;
668
669 if (!info || !info->uio_dev)
670 return;
671
672 idev = info->uio_dev;
673
674 uio_free_minor(idev);
675
676 if (info->irq >= 0)
677 free_irq(info->irq, idev);
678
679 uio_dev_del_attributes(idev);
680
681 dev_set_drvdata(idev->dev, NULL);
682 device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
683 kfree(idev);
684 uio_class_destroy();
685
686 return;
687}
688EXPORT_SYMBOL_GPL(uio_unregister_device);
689
690static int __init uio_init(void)
691{
692 return 0;
693}
694
695static void __exit uio_exit(void)
696{
697}
698
699module_init(uio_init)
700module_exit(uio_exit)
701MODULE_LICENSE("GPL v2");
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
new file mode 100644
index 000000000000..838bae460831
--- /dev/null
+++ b/drivers/uio/uio_cif.c
@@ -0,0 +1,156 @@
1/*
2 * UIO Hilscher CIF card driver
3 *
4 * (C) 2007 Hans J. Koch <hjk@linutronix.de>
5 * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
6 *
7 * Licensed under GPL version 2 only.
8 *
9 */
10
11#include <linux/device.h>
12#include <linux/module.h>
13#include <linux/pci.h>
14#include <linux/uio_driver.h>
15
16#include <asm/io.h>
17
18#ifndef PCI_DEVICE_ID_PLX_9030
19#define PCI_DEVICE_ID_PLX_9030 0x9030
20#endif
21
22#define PLX9030_INTCSR 0x4C
23#define INTSCR_INT1_ENABLE 0x01
24#define INTSCR_INT1_STATUS 0x04
25#define INT1_ENABLED_AND_ACTIVE (INTSCR_INT1_ENABLE | INTSCR_INT1_STATUS)
26
27#define PCI_SUBVENDOR_ID_PEP 0x1518
28#define CIF_SUBDEVICE_PROFIBUS 0x430
29#define CIF_SUBDEVICE_DEVICENET 0x432
30
31
32static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info)
33{
34 void __iomem *plx_intscr = dev_info->mem[0].internal_addr
35 + PLX9030_INTCSR;
36
37 if ((ioread8(plx_intscr) & INT1_ENABLED_AND_ACTIVE)
38 != INT1_ENABLED_AND_ACTIVE)
39 return IRQ_NONE;
40
41 /* Disable interrupt */
42 iowrite8(ioread8(plx_intscr) & ~INTSCR_INT1_ENABLE, plx_intscr);
43 return IRQ_HANDLED;
44}
45
46static int __devinit hilscher_pci_probe(struct pci_dev *dev,
47 const struct pci_device_id *id)
48{
49 struct uio_info *info;
50
51 info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
52 if (!info)
53 return -ENOMEM;
54
55 if (pci_enable_device(dev))
56 goto out_free;
57
58 if (pci_request_regions(dev, "hilscher"))
59 goto out_disable;
60
61 info->mem[0].addr = pci_resource_start(dev, 0);
62 if (!info->mem[0].addr)
63 goto out_release;
64 info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
65 pci_resource_len(dev, 0));
66 if (!info->mem[0].internal_addr)
67 goto out_release;
68
69 info->mem[0].size = pci_resource_len(dev, 0);
70 info->mem[0].memtype = UIO_MEM_PHYS;
71 info->mem[1].addr = pci_resource_start(dev, 2);
72 info->mem[1].size = pci_resource_len(dev, 2);
73 info->mem[1].memtype = UIO_MEM_PHYS;
74 switch (id->subdevice) {
75 case CIF_SUBDEVICE_PROFIBUS:
76 info->name = "CIF_Profibus";
77 break;
78 case CIF_SUBDEVICE_DEVICENET:
79 info->name = "CIF_Devicenet";
80 break;
81 default:
82 info->name = "CIF_???";
83 }
84 info->version = "0.0.1";
85 info->irq = dev->irq;
86 info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
87 info->handler = hilscher_handler;
88
89 if (uio_register_device(&dev->dev, info))
90 goto out_unmap;
91
92 pci_set_drvdata(dev, info);
93
94 return 0;
95out_unmap:
96 iounmap(info->mem[0].internal_addr);
97out_release:
98 pci_release_regions(dev);
99out_disable:
100 pci_disable_device(dev);
101out_free:
102 kfree (info);
103 return -ENODEV;
104}
105
106static void hilscher_pci_remove(struct pci_dev *dev)
107{
108 struct uio_info *info = pci_get_drvdata(dev);
109
110 uio_unregister_device(info);
111 pci_release_regions(dev);
112 pci_disable_device(dev);
113 pci_set_drvdata(dev, NULL);
114 iounmap(info->mem[0].internal_addr);
115
116 kfree (info);
117}
118
119static struct pci_device_id hilscher_pci_ids[] = {
120 {
121 .vendor = PCI_VENDOR_ID_PLX,
122 .device = PCI_DEVICE_ID_PLX_9030,
123 .subvendor = PCI_SUBVENDOR_ID_PEP,
124 .subdevice = CIF_SUBDEVICE_PROFIBUS,
125 },
126 {
127 .vendor = PCI_VENDOR_ID_PLX,
128 .device = PCI_DEVICE_ID_PLX_9030,
129 .subvendor = PCI_SUBVENDOR_ID_PEP,
130 .subdevice = CIF_SUBDEVICE_DEVICENET,
131 },
132 { 0, }
133};
134
135static struct pci_driver hilscher_pci_driver = {
136 .name = "hilscher",
137 .id_table = hilscher_pci_ids,
138 .probe = hilscher_pci_probe,
139 .remove = hilscher_pci_remove,
140};
141
142static int __init hilscher_init_module(void)
143{
144 return pci_register_driver(&hilscher_pci_driver);
145}
146
147static void __exit hilscher_exit_module(void)
148{
149 pci_unregister_driver(&hilscher_pci_driver);
150}
151
152module_init(hilscher_init_module);
153module_exit(hilscher_exit_module);
154
155MODULE_LICENSE("GPL v2");
156MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 73c49362cd47..654857493a82 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -29,13 +29,6 @@
29#include "hcd.h" 29#include "hcd.h"
30#include "usb.h" 30#include "usb.h"
31 31
32#define VERBOSE_DEBUG 0
33
34#if VERBOSE_DEBUG
35#define dev_vdbg dev_dbg
36#else
37#define dev_vdbg(dev, fmt, args...) do { } while (0)
38#endif
39 32
40#ifdef CONFIG_HOTPLUG 33#ifdef CONFIG_HOTPLUG
41 34
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index a9b6bc5157b8..6d84ca2beead 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,10 @@
1Version 1.50
2------------
3Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
4done with "serverino" mount option). Add support for POSIX Unlink
5(helps with certain sharing violation cases when server such as
6Samba supports newer POSIX CIFS Protocol Extensions).
7
1Version 1.49 8Version 1.49
2------------ 9------------
3IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6 10IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
@@ -8,7 +15,11 @@ when Unix Extensions were ignored). This allows users to override the
8default uid and gid for files when they are certain that the uids or 15default uid and gid for files when they are certain that the uids or
9gids on the server do not match those of the client. Make "sec=none" 16gids on the server do not match those of the client. Make "sec=none"
10mount override username (so that null user connection is attempted) 17mount override username (so that null user connection is attempted)
11to match what documentation said. 18to match what documentation said. Support for very large reads, over 127K,
19available to some newer servers (such as Samba 3.0.26 and later but
20note that it also requires setting CIFSMaxBufSize at module install
21time to a larger value which may hurt performance in some cases).
22Make sign option force signing (or fail if server does not support it).
12 23
13Version 1.48 24Version 1.48
14------------ 25------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 4d01697722cc..85f1eb14083e 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -301,10 +301,21 @@ A partial list of the supported mount options follows:
301 during the local client kernel build will be used. 301 during the local client kernel build will be used.
302 If server does not support Unicode, this parameter is 302 If server does not support Unicode, this parameter is
303 unused. 303 unused.
304 rsize default read size (usually 16K) 304 rsize default read size (usually 16K). The client currently
305 wsize default write size (usually 16K, 32K is often better over GigE) 305 can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize
306 maximum wsize currently allowed by CIFS is 57344 (14 4096 byte 306 defaults to 16K and may be changed (from 8K to the maximum
307 pages) 307 kmalloc size allowed by your kernel) at module install time
308 for cifs.ko. Setting CIFSMaxBufSize to a very large value
309 will cause cifs to use more memory and may reduce performance
310 in some cases. To use rsize greater than 127K (the original
311 cifs protocol maximum) also requires that the server support
312 a new Unix Capability flag (for very large read) which some
313 newer servers (e.g. Samba 3.0.26 or later) do. rsize can be
314 set from a minimum of 2048 to a maximum of 130048 (127K or
315 CIFSMaxBufSize, whichever is smaller)
316 wsize default write size (default 57344)
317 maximum wsize currently allowed by CIFS is 57344 (fourteen
318 4096 byte pages)
308 rw mount the network share read-write (note that the 319 rw mount the network share read-write (note that the
309 server may still consider the share read-only) 320 server may still consider the share read-only)
310 ro mount network share read-only 321 ro mount network share read-only
@@ -359,7 +370,7 @@ A partial list of the supported mount options follows:
359 Note that this does not affect the normal ACL check on the 370 Note that this does not affect the normal ACL check on the
360 target machine done by the server software (of the server 371 target machine done by the server software (of the server
361 ACL against the user name provided at mount time). 372 ACL against the user name provided at mount time).
362 serverino Use servers inode numbers instead of generating automatically 373 serverino Use server's inode numbers instead of generating automatically
363 incrementing inode numbers on the client. Although this will 374 incrementing inode numbers on the client. Although this will
364 make it easier to spot hardlinked files (as they will have 375 make it easier to spot hardlinked files (as they will have
365 the same inode numbers) and inode numbers may be persistent, 376 the same inode numbers) and inode numbers may be persistent,
@@ -367,12 +378,11 @@ A partial list of the supported mount options follows:
367 are unique if multiple server side mounts are exported under a 378 are unique if multiple server side mounts are exported under a
368 single share (since inode numbers on the servers might not 379 single share (since inode numbers on the servers might not
369 be unique if multiple filesystems are mounted under the same 380 be unique if multiple filesystems are mounted under the same
370 shared higher level directory). Note that this requires that 381 shared higher level directory). Note that some older
371 the server support the CIFS Unix Extensions as other servers 382 (e.g. pre-Windows 2000) do not support returning UniqueIDs
372 do not return a unique IndexNumber on SMB FindFirst (most 383 or the CIFS Unix Extensions equivalent and for those
373 servers return zero as the IndexNumber). Parameter has no 384 this mount option will have no effect. Exporting cifs mounts
374 effect to Windows servers and others which do not support the 385 under nfsd requires this mount option on the cifs mount.
375 CIFS Unix Extensions.
376 noserverino Client generates inode numbers (rather than using the actual one 386 noserverino Client generates inode numbers (rather than using the actual one
377 from the server) by default. 387 from the server) by default.
378 setuids If the CIFS Unix extensions are negotiated with the server 388 setuids If the CIFS Unix extensions are negotiated with the server
@@ -582,10 +592,10 @@ the start of smb requests and responses can be enabled via:
582 592
583 echo 1 > /proc/fs/cifs/traceSMB 593 echo 1 > /proc/fs/cifs/traceSMB
584 594
585Two other experimental features are under development and to test 595Two other experimental features are under development. To test these
586require enabling CONFIG_CIFS_EXPERIMENTAL 596requires enabling CONFIG_CIFS_EXPERIMENTAL
587 597
588 More efficient write operations 598 ipv6 enablement
589 599
590 DNOTIFY fcntl: needed for support of directory change 600 DNOTIFY fcntl: needed for support of directory change
591 notification and perhaps later for file leases) 601 notification and perhaps later for file leases)
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 78b620e332bd..d7bd51575fd6 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -18,9 +18,9 @@ better)
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Kerberos/SPNEGO session setup support - (started)
20 20
21e) More testing of NTLMv2 authentication (mostly implemented - double check 21e) Cleanup now unneeded SessSetup code in
22that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in 22fs/cifs/connect.c and add back in NTLMSSP code if any servers
23fs/cifs/connect.c) 23need it
24 24
25f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup 25f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup
26used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM 26used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
@@ -106,6 +106,12 @@ but recognizes them
106succeed but still return access denied (appears to be Windows 106succeed but still return access denied (appears to be Windows
107server not cifs client problem) and has not been reproduced recently. 107server not cifs client problem) and has not been reproduced recently.
108NTFS partitions do not have this problem. 108NTFS partitions do not have this problem.
1094) Unix/POSIX capabilities are reset after reconnection, and affect
110a few fields in the tree connection but we do do not know which
111superblocks to apply these changes to. We should probably walk
112the list of superblocks to set these. Also need to check the
113flags on the second mount to the same share, and see if we
114can do the same trick that NFS does to remount duplicate shares.
109 115
110Misc testing to do 116Misc testing to do
111================== 117==================
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 2e75883b7f54..f50a88d58f78 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in 2 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
3 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich 3 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
4 * 4 *
5 * Copyright (c) 2000 RP Internet (www.rpi.net.au). 5 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -80,7 +80,7 @@
80static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; 80static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
81static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; 81static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
82 82
83/* 83/*
84 * ASN.1 context. 84 * ASN.1 context.
85 */ 85 */
86struct asn1_ctx { 86struct asn1_ctx {
@@ -190,7 +190,7 @@ asn1_header_decode(struct asn1_ctx *ctx,
190 unsigned char **eoc, 190 unsigned char **eoc,
191 unsigned int *cls, unsigned int *con, unsigned int *tag) 191 unsigned int *cls, unsigned int *con, unsigned int *tag)
192{ 192{
193 unsigned int def = 0; 193 unsigned int def = 0;
194 unsigned int len = 0; 194 unsigned int len = 0;
195 195
196 if (!asn1_id_decode(ctx, cls, con, tag)) 196 if (!asn1_id_decode(ctx, cls, con, tag))
@@ -331,7 +331,7 @@ static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
331 *integer |= ch; 331 *integer |= ch;
332 } 332 }
333 return 1; 333 return 1;
334} 334}
335 335
336static unsigned char 336static unsigned char
337asn1_octets_decode(struct asn1_ctx *ctx, 337asn1_octets_decode(struct asn1_ctx *ctx,
@@ -376,7 +376,7 @@ asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
376 return 1; 376 return 1;
377} 377}
378 378
379static int 379static int
380asn1_oid_decode(struct asn1_ctx *ctx, 380asn1_oid_decode(struct asn1_ctx *ctx,
381 unsigned char *eoc, unsigned long **oid, unsigned int *len) 381 unsigned char *eoc, unsigned long **oid, unsigned int *len)
382{ 382{
@@ -459,7 +459,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
459 unsigned int cls, con, tag, oidlen, rc; 459 unsigned int cls, con, tag, oidlen, rc;
460 int use_ntlmssp = FALSE; 460 int use_ntlmssp = FALSE;
461 461
462 *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */ 462 *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
463 463
464 /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ 464 /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
465 465
@@ -498,7 +498,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
498 return 0; 498 return 0;
499 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 499 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
500 || (tag != ASN1_EOC)) { 500 || (tag != ASN1_EOC)) {
501 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0", 501 cFYI(1,
502 ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
502 cls, con, tag, end, *end)); 503 cls, con, tag, end, *end));
503 return 0; 504 return 0;
504 } 505 }
@@ -508,7 +509,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
508 return 0; 509 return 0;
509 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 510 } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
510 || (tag != ASN1_SEQ)) { 511 || (tag != ASN1_SEQ)) {
511 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1", 512 cFYI(1,
513 ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
512 cls, con, tag, end, *end)); 514 cls, con, tag, end, *end));
513 return 0; 515 return 0;
514 } 516 }
@@ -540,32 +542,34 @@ decode_negTokenInit(unsigned char *security_blob, int length,
540 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); 542 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
541 if (!rc) { 543 if (!rc) {
542 cFYI(1, 544 cFYI(1,
543 ("Error 1 decoding negTokenInit header exit 2")); 545 ("Error decoding negTokenInit hdr exit2"));
544 return 0; 546 return 0;
545 } 547 }
546 if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { 548 if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
547 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); 549 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
548 if(rc) { 550 if (rc) {
549 cFYI(1, 551 cFYI(1,
550 ("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx", 552 ("OID len = %d oid = 0x%lx 0x%lx "
551 oidlen, *oid, *(oid + 1), *(oid + 2), 553 "0x%lx 0x%lx",
552 *(oid + 3))); 554 oidlen, *oid, *(oid + 1),
553 rc = compare_oid(oid, oidlen, NTLMSSP_OID, 555 *(oid + 2), *(oid + 3)));
554 NTLMSSP_OID_LEN); 556 rc = compare_oid(oid, oidlen,
557 NTLMSSP_OID, NTLMSSP_OID_LEN);
555 kfree(oid); 558 kfree(oid);
556 if (rc) 559 if (rc)
557 use_ntlmssp = TRUE; 560 use_ntlmssp = TRUE;
558 } 561 }
559 } else { 562 } else {
560 cFYI(1,("This should be an oid what is going on? ")); 563 cFYI(1, ("Should be an oid what is going on?"));
561 } 564 }
562 } 565 }
563 566
564 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 567 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
565 cFYI(1, 568 cFYI(1,
566 ("Error decoding last part of negTokenInit exit 3")); 569 ("Error decoding last part negTokenInit exit3"));
567 return 0; 570 return 0;
568 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ 571 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
572 /* tag = 3 indicating mechListMIC */
569 cFYI(1, 573 cFYI(1,
570 ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", 574 ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
571 cls, con, tag, end, *end)); 575 cls, con, tag, end, *end));
@@ -573,7 +577,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
573 } 577 }
574 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 578 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
575 cFYI(1, 579 cFYI(1,
576 ("Error decoding last part of negTokenInit exit 5")); 580 ("Error decoding last part negTokenInit exit5"));
577 return 0; 581 return 0;
578 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 582 } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
579 || (tag != ASN1_SEQ)) { 583 || (tag != ASN1_SEQ)) {
@@ -584,7 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
584 588
585 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 589 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
586 cFYI(1, 590 cFYI(1,
587 ("Error decoding last part of negTokenInit exit 7")); 591 ("Error decoding last part negTokenInit exit 7"));
588 return 0; 592 return 0;
589 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { 593 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
590 cFYI(1, 594 cFYI(1,
@@ -594,20 +598,21 @@ decode_negTokenInit(unsigned char *security_blob, int length,
594 } 598 }
595 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 599 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
596 cFYI(1, 600 cFYI(1,
597 ("Error decoding last part of negTokenInit exit 9")); 601 ("Error decoding last part negTokenInit exit9"));
598 return 0; 602 return 0;
599 } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) 603 } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
600 || (tag != ASN1_GENSTR)) { 604 || (tag != ASN1_GENSTR)) {
601 cFYI(1, 605 cFYI(1,
602 ("Exit 10 cls = %d con = %d tag = %d end = %p (%d)", 606 ("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
603 cls, con, tag, end, *end)); 607 cls, con, tag, end, *end));
604 return 0; 608 return 0;
605 } 609 }
606 cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ 610 cFYI(1, ("Need to call asn1_octets_decode() function for %s",
611 ctx.pointer)); /* is this UTF-8 or ASCII? */
607 } 612 }
608 613
609 /* if (use_kerberos) 614 /* if (use_kerberos)
610 *secType = Kerberos 615 *secType = Kerberos
611 else */ 616 else */
612 if (use_ntlmssp) { 617 if (use_ntlmssp) {
613 *secType = NTLMSSP; 618 *secType = NTLMSSP;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 07838b2ac1ce..1bf8cf522ad6 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -58,7 +58,7 @@ cifs_dump_mem(char *label, void *data, int length)
58} 58}
59 59
60#ifdef CONFIG_CIFS_DEBUG2 60#ifdef CONFIG_CIFS_DEBUG2
61void cifs_dump_detail(struct smb_hdr * smb) 61void cifs_dump_detail(struct smb_hdr *smb)
62{ 62{
63 cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", 63 cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
64 smb->Command, smb->Status.CifsError, 64 smb->Command, smb->Status.CifsError,
@@ -67,10 +67,10 @@ void cifs_dump_detail(struct smb_hdr * smb)
67} 67}
68 68
69 69
70void cifs_dump_mids(struct TCP_Server_Info * server) 70void cifs_dump_mids(struct TCP_Server_Info *server)
71{ 71{
72 struct list_head *tmp; 72 struct list_head *tmp;
73 struct mid_q_entry * mid_entry; 73 struct mid_q_entry *mid_entry;
74 74
75 if (server == NULL) 75 if (server == NULL)
76 return; 76 return;
@@ -114,12 +114,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
114{ 114{
115 struct list_head *tmp; 115 struct list_head *tmp;
116 struct list_head *tmp1; 116 struct list_head *tmp1;
117 struct mid_q_entry * mid_entry; 117 struct mid_q_entry *mid_entry;
118 struct cifsSesInfo *ses; 118 struct cifsSesInfo *ses;
119 struct cifsTconInfo *tcon; 119 struct cifsTconInfo *tcon;
120 int i; 120 int i;
121 int length = 0; 121 int length = 0;
122 char * original_buf = buf; 122 char *original_buf = buf;
123 123
124 *beginBuffer = buf + offset; 124 *beginBuffer = buf + offset;
125 125
@@ -145,7 +145,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
145 (ses->serverNOS == NULL)) { 145 (ses->serverNOS == NULL)) {
146 buf += sprintf(buf, "\nentry for %s not fully " 146 buf += sprintf(buf, "\nentry for %s not fully "
147 "displayed\n\t", ses->serverName); 147 "displayed\n\t", ses->serverName);
148
149 } else { 148 } else {
150 length = 149 length =
151 sprintf(buf, 150 sprintf(buf,
@@ -901,90 +900,14 @@ security_flags_write(struct file *file, const char __user *buffer,
901 } 900 }
902 /* flags look ok - update the global security flags for cifs module */ 901 /* flags look ok - update the global security flags for cifs module */
903 extended_security = flags; 902 extended_security = flags;
903 if (extended_security & CIFSSEC_MUST_SIGN) {
904 /* requiring signing implies signing is allowed */
905 extended_security |= CIFSSEC_MAY_SIGN;
906 cFYI(1, ("packet signing now required"));
907 } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
908 cFYI(1, ("packet signing disabled"));
909 }
910 /* BB should we turn on MAY flags for other MUST options? */
904 return count; 911 return count;
905} 912}
906
907/* static int
908ntlmv2_enabled_read(char *page, char **start, off_t off,
909 int count, int *eof, void *data)
910{
911 int len;
912
913 len = sprintf(page, "%d\n", ntlmv2_support);
914
915 len -= off;
916 *start = page + off;
917
918 if (len > count)
919 len = count;
920 else
921 *eof = 1;
922
923 if (len < 0)
924 len = 0;
925
926 return len;
927}
928static int
929ntlmv2_enabled_write(struct file *file, const char __user *buffer,
930 unsigned long count, void *data)
931{
932 char c;
933 int rc;
934
935 rc = get_user(c, buffer);
936 if (rc)
937 return rc;
938 if (c == '0' || c == 'n' || c == 'N')
939 ntlmv2_support = 0;
940 else if (c == '1' || c == 'y' || c == 'Y')
941 ntlmv2_support = 1;
942 else if (c == '2')
943 ntlmv2_support = 2;
944
945 return count;
946}
947
948static int
949packet_signing_enabled_read(char *page, char **start, off_t off,
950 int count, int *eof, void *data)
951{
952 int len;
953
954 len = sprintf(page, "%d\n", sign_CIFS_PDUs);
955
956 len -= off;
957 *start = page + off;
958
959 if (len > count)
960 len = count;
961 else
962 *eof = 1;
963
964 if (len < 0)
965 len = 0;
966
967 return len;
968}
969static int
970packet_signing_enabled_write(struct file *file, const char __user *buffer,
971 unsigned long count, void *data)
972{
973 char c;
974 int rc;
975
976 rc = get_user(c, buffer);
977 if (rc)
978 return rc;
979 if (c == '0' || c == 'n' || c == 'N')
980 sign_CIFS_PDUs = 0;
981 else if (c == '1' || c == 'y' || c == 'Y')
982 sign_CIFS_PDUs = 1;
983 else if (c == '2')
984 sign_CIFS_PDUs = 2;
985
986 return count;
987} */
988
989
990#endif 913#endif
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 4cc2012e9322..34af556cdd8d 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -43,6 +43,6 @@ struct cifs_sb_info {
43 mode_t mnt_dir_mode; 43 mode_t mnt_dir_mode;
44 int mnt_cifs_flags; 44 int mnt_cifs_flags;
45 int prepathlen; 45 int prepathlen;
46 char * prepath; 46 char *prepath;
47}; 47};
48#endif /* _CIFS_FS_SB_H */ 48#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 701e9a9185f2..b5903b89250d 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -66,7 +66,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
66{ 66{
67 int charlen; 67 int charlen;
68 int i; 68 int i;
69 wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */ 69 wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */
70 70
71 for (i = 0; len && *from; i++, from += charlen, len -= charlen) { 71 for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
72 72
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 39e5b970325f..614c11fcdcb6 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -5,20 +5,20 @@
5 * Convert a unicode character to upper or lower case using 5 * Convert a unicode character to upper or lower case using
6 * compressed tables. 6 * compressed tables.
7 * 7 *
8 * Copyright (c) International Business Machines Corp., 2000,2005555555555555555555555555555555555555555555555555555555 8 * Copyright (c) International Business Machines Corp., 2000,2007
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 * the GNU General Public License for more details. 18 * the GNU General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 * 24 *
@@ -70,7 +70,7 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
70 * Address of the first string 70 * Address of the first string
71 */ 71 */
72static inline wchar_t * 72static inline wchar_t *
73UniStrcat(wchar_t * ucs1, const wchar_t * ucs2) 73UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
74{ 74{
75 wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */ 75 wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */
76 76
@@ -88,7 +88,7 @@ UniStrcat(wchar_t * ucs1, const wchar_t * ucs2)
88 * or NULL if the character is not in the string 88 * or NULL if the character is not in the string
89 */ 89 */
90static inline wchar_t * 90static inline wchar_t *
91UniStrchr(const wchar_t * ucs, wchar_t uc) 91UniStrchr(const wchar_t *ucs, wchar_t uc)
92{ 92{
93 while ((*ucs != uc) && *ucs) 93 while ((*ucs != uc) && *ucs)
94 ucs++; 94 ucs++;
@@ -107,7 +107,7 @@ UniStrchr(const wchar_t * ucs, wchar_t uc)
107 * > 0: First string is greater than second 107 * > 0: First string is greater than second
108 */ 108 */
109static inline int 109static inline int
110UniStrcmp(const wchar_t * ucs1, const wchar_t * ucs2) 110UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
111{ 111{
112 while ((*ucs1 == *ucs2) && *ucs1) { 112 while ((*ucs1 == *ucs2) && *ucs1) {
113 ucs1++; 113 ucs1++;
@@ -120,7 +120,7 @@ UniStrcmp(const wchar_t * ucs1, const wchar_t * ucs2)
120 * UniStrcpy: Copy a string 120 * UniStrcpy: Copy a string
121 */ 121 */
122static inline wchar_t * 122static inline wchar_t *
123UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2) 123UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
124{ 124{
125 wchar_t *anchor = ucs1; /* save the start of result string */ 125 wchar_t *anchor = ucs1; /* save the start of result string */
126 126
@@ -132,7 +132,7 @@ UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2)
132 * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes) 132 * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes)
133 */ 133 */
134static inline size_t 134static inline size_t
135UniStrlen(const wchar_t * ucs1) 135UniStrlen(const wchar_t *ucs1)
136{ 136{
137 int i = 0; 137 int i = 0;
138 138
@@ -142,10 +142,11 @@ UniStrlen(const wchar_t * ucs1)
142} 142}
143 143
144/* 144/*
145 * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a string (length limited) 145 * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a
146 * string (length limited)
146 */ 147 */
147static inline size_t 148static inline size_t
148UniStrnlen(const wchar_t * ucs1, int maxlen) 149UniStrnlen(const wchar_t *ucs1, int maxlen)
149{ 150{
150 int i = 0; 151 int i = 0;
151 152
@@ -161,7 +162,7 @@ UniStrnlen(const wchar_t * ucs1, int maxlen)
161 * UniStrncat: Concatenate length limited string 162 * UniStrncat: Concatenate length limited string
162 */ 163 */
163static inline wchar_t * 164static inline wchar_t *
164UniStrncat(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 165UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
165{ 166{
166 wchar_t *anchor = ucs1; /* save pointer to string 1 */ 167 wchar_t *anchor = ucs1; /* save pointer to string 1 */
167 168
@@ -179,7 +180,7 @@ UniStrncat(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
179 * UniStrncmp: Compare length limited string 180 * UniStrncmp: Compare length limited string
180 */ 181 */
181static inline int 182static inline int
182UniStrncmp(const wchar_t * ucs1, const wchar_t * ucs2, size_t n) 183UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
183{ 184{
184 if (!n) 185 if (!n)
185 return 0; /* Null strings are equal */ 186 return 0; /* Null strings are equal */
@@ -194,7 +195,7 @@ UniStrncmp(const wchar_t * ucs1, const wchar_t * ucs2, size_t n)
194 * UniStrncmp_le: Compare length limited string - native to little-endian 195 * UniStrncmp_le: Compare length limited string - native to little-endian
195 */ 196 */
196static inline int 197static inline int
197UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2, size_t n) 198UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
198{ 199{
199 if (!n) 200 if (!n)
200 return 0; /* Null strings are equal */ 201 return 0; /* Null strings are equal */
@@ -209,7 +210,7 @@ UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2, size_t n)
209 * UniStrncpy: Copy length limited string with pad 210 * UniStrncpy: Copy length limited string with pad
210 */ 211 */
211static inline wchar_t * 212static inline wchar_t *
212UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 213UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
213{ 214{
214 wchar_t *anchor = ucs1; 215 wchar_t *anchor = ucs1;
215 216
@@ -226,7 +227,7 @@ UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
226 * UniStrncpy_le: Copy length limited string with pad to little-endian 227 * UniStrncpy_le: Copy length limited string with pad to little-endian
227 */ 228 */
228static inline wchar_t * 229static inline wchar_t *
229UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2, size_t n) 230UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
230{ 231{
231 wchar_t *anchor = ucs1; 232 wchar_t *anchor = ucs1;
232 233
@@ -247,7 +248,7 @@ UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2, size_t n)
247 * NULL if no matching string is found 248 * NULL if no matching string is found
248 */ 249 */
249static inline wchar_t * 250static inline wchar_t *
250UniStrstr(const wchar_t * ucs1, const wchar_t * ucs2) 251UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
251{ 252{
252 const wchar_t *anchor1 = ucs1; 253 const wchar_t *anchor1 = ucs1;
253 const wchar_t *anchor2 = ucs2; 254 const wchar_t *anchor2 = ucs2;
@@ -297,7 +298,7 @@ UniToupper(register wchar_t uc)
297 * UniStrupr: Upper case a unicode string 298 * UniStrupr: Upper case a unicode string
298 */ 299 */
299static inline wchar_t * 300static inline wchar_t *
300UniStrupr(register wchar_t * upin) 301UniStrupr(register wchar_t *upin)
301{ 302{
302 register wchar_t *up; 303 register wchar_t *up;
303 304
@@ -338,7 +339,7 @@ UniTolower(wchar_t uc)
338 * UniStrlwr: Lower case a unicode string 339 * UniStrlwr: Lower case a unicode string
339 */ 340 */
340static inline wchar_t * 341static inline wchar_t *
341UniStrlwr(register wchar_t * upin) 342UniStrlwr(register wchar_t *upin)
342{ 343{
343 register wchar_t *up; 344 register wchar_t *up;
344 345
diff --git a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h
index da2ad5b451ac..18a9d978e519 100644
--- a/fs/cifs/cifs_uniupr.h
+++ b/fs/cifs/cifs_uniupr.h
@@ -3,16 +3,16 @@
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details. 12 * the GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 17 *
18 * uniupr.h - Unicode compressed case ranges 18 * uniupr.h - Unicode compressed case ranges
@@ -53,7 +53,7 @@ signed char CifsUniUpperTable[512] = {
53 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */ 53 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */
54 -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */ 54 -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */
55 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */ 55 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */
56 -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */ 56 -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */
57 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */ 57 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */
58 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */ 58 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */
59}; 59};
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index fdeda519eace..36272293027d 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -21,7 +21,7 @@
21 21
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include "cifspdu.h" 23#include "cifspdu.h"
24#include "cifsglob.h" 24#include "cifsglob.h"
25#include "cifs_debug.h" 25#include "cifs_debug.h"
26#include "md5.h" 26#include "md5.h"
27#include "cifs_unicode.h" 27#include "cifs_unicode.h"
@@ -29,54 +29,57 @@
29#include <linux/ctype.h> 29#include <linux/ctype.h>
30#include <linux/random.h> 30#include <linux/random.h>
31 31
32/* Calculate and return the CIFS signature based on the mac key and the smb pdu */ 32/* Calculate and return the CIFS signature based on the mac key and SMB PDU */
33/* the 16 byte signature must be allocated by the caller */ 33/* the 16 byte signature must be allocated by the caller */
34/* Note we only use the 1st eight bytes */ 34/* Note we only use the 1st eight bytes */
35/* Note that the smb header signature field on input contains the 35/* Note that the smb header signature field on input contains the
36 sequence number before this function is called */ 36 sequence number before this function is called */
37 37
38extern void mdfour(unsigned char *out, unsigned char *in, int n); 38extern void mdfour(unsigned char *out, unsigned char *in, int n);
39extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 39extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
40extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 40extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
41 unsigned char *p24); 41 unsigned char *p24);
42 42
43static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, 43static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
44 const char * key, char * signature) 44 const struct mac_key *key, char *signature)
45{ 45{
46 struct MD5Context context; 46 struct MD5Context context;
47 47
48 if((cifs_pdu == NULL) || (signature == NULL)) 48 if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
49 return -EINVAL; 49 return -EINVAL;
50 50
51 MD5Init(&context); 51 MD5Init(&context);
52 MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 52 MD5Update(&context, (char *)&key->data, key->len);
53 MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); 53 MD5Update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
54 MD5Final(signature,&context); 54
55 MD5Final(signature, &context);
55 return 0; 56 return 0;
56} 57}
57 58
58int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, 59int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
59 __u32 * pexpected_response_sequence_number) 60 __u32 *pexpected_response_sequence_number)
60{ 61{
61 int rc = 0; 62 int rc = 0;
62 char smb_signature[20]; 63 char smb_signature[20];
63 64
64 if((cifs_pdu == NULL) || (server == NULL)) 65 if ((cifs_pdu == NULL) || (server == NULL))
65 return -EINVAL; 66 return -EINVAL;
66 67
67 if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 68 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
68 return rc; 69 return rc;
69 70
70 spin_lock(&GlobalMid_Lock); 71 spin_lock(&GlobalMid_Lock);
71 cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(server->sequence_number); 72 cifs_pdu->Signature.Sequence.SequenceNumber =
73 cpu_to_le32(server->sequence_number);
72 cifs_pdu->Signature.Sequence.Reserved = 0; 74 cifs_pdu->Signature.Sequence.Reserved = 0;
73 75
74 *pexpected_response_sequence_number = server->sequence_number++; 76 *pexpected_response_sequence_number = server->sequence_number++;
75 server->sequence_number++; 77 server->sequence_number++;
76 spin_unlock(&GlobalMid_Lock); 78 spin_unlock(&GlobalMid_Lock);
77 79
78 rc = cifs_calculate_signature(cifs_pdu, server->mac_signing_key,smb_signature); 80 rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key,
79 if(rc) 81 smb_signature);
82 if (rc)
80 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 83 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
81 else 84 else
82 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 85 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
@@ -84,115 +87,119 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
84 return rc; 87 return rc;
85} 88}
86 89
87static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 90static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
88 const char * key, char * signature) 91 const struct mac_key *key, char *signature)
89{ 92{
90 struct MD5Context context; 93 struct MD5Context context;
91 int i; 94 int i;
92 95
93 if((iov == NULL) || (signature == NULL)) 96 if ((iov == NULL) || (signature == NULL) || (key == NULL))
94 return -EINVAL; 97 return -EINVAL;
95 98
96 MD5Init(&context); 99 MD5Init(&context);
97 MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); 100 MD5Update(&context, (char *)&key->data, key->len);
98 for(i=0;i<n_vec;i++) { 101 for (i = 0; i < n_vec; i++) {
99 if(iov[i].iov_base == NULL) { 102 if (iov[i].iov_base == NULL) {
100 cERROR(1,("null iovec entry")); 103 cERROR(1, ("null iovec entry"));
101 return -EIO; 104 return -EIO;
102 } else if(iov[i].iov_len == 0) 105 } else if (iov[i].iov_len == 0)
103 break; /* bail out if we are sent nothing to sign */ 106 break; /* bail out if we are sent nothing to sign */
104 /* The first entry includes a length field (which does not get 107 /* The first entry includes a length field (which does not get
105 signed that occupies the first 4 bytes before the header */ 108 signed that occupies the first 4 bytes before the header */
106 if(i==0) { 109 if (i == 0) {
107 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */ 110 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
108 break; /* nothing to sign or corrupt header */ 111 break; /* nothing to sign or corrupt header */
109 MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4); 112 MD5Update(&context, iov[0].iov_base+4,
113 iov[0].iov_len-4);
110 } else 114 } else
111 MD5Update(&context,iov[i].iov_base, iov[i].iov_len); 115 MD5Update(&context, iov[i].iov_base, iov[i].iov_len);
112 } 116 }
113 117
114 MD5Final(signature,&context); 118 MD5Final(signature, &context);
115 119
116 return 0; 120 return 0;
117} 121}
118 122
119 123
120int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, 124int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
121 __u32 * pexpected_response_sequence_number) 125 __u32 * pexpected_response_sequence_number)
122{ 126{
123 int rc = 0; 127 int rc = 0;
124 char smb_signature[20]; 128 char smb_signature[20];
125 struct smb_hdr * cifs_pdu = iov[0].iov_base; 129 struct smb_hdr *cifs_pdu = iov[0].iov_base;
126 130
127 if((cifs_pdu == NULL) || (server == NULL)) 131 if ((cifs_pdu == NULL) || (server == NULL))
128 return -EINVAL; 132 return -EINVAL;
129 133
130 if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 134 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
131 return rc; 135 return rc;
132 136
133 spin_lock(&GlobalMid_Lock); 137 spin_lock(&GlobalMid_Lock);
134 cifs_pdu->Signature.Sequence.SequenceNumber = 138 cifs_pdu->Signature.Sequence.SequenceNumber =
135 cpu_to_le32(server->sequence_number); 139 cpu_to_le32(server->sequence_number);
136 cifs_pdu->Signature.Sequence.Reserved = 0; 140 cifs_pdu->Signature.Sequence.Reserved = 0;
137 141
138 *pexpected_response_sequence_number = server->sequence_number++; 142 *pexpected_response_sequence_number = server->sequence_number++;
139 server->sequence_number++; 143 server->sequence_number++;
140 spin_unlock(&GlobalMid_Lock); 144 spin_unlock(&GlobalMid_Lock);
141 145
142 rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key, 146 rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key,
143 smb_signature); 147 smb_signature);
144 if(rc) 148 if (rc)
145 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 149 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
146 else 150 else
147 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 151 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
148
149 return rc;
150 152
153 return rc;
151} 154}
152 155
153int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, 156int cifs_verify_signature(struct smb_hdr *cifs_pdu,
154 __u32 expected_sequence_number) 157 const struct mac_key *mac_key,
158 __u32 expected_sequence_number)
155{ 159{
156 unsigned int rc; 160 unsigned int rc;
157 char server_response_sig[8]; 161 char server_response_sig[8];
158 char what_we_think_sig_should_be[20]; 162 char what_we_think_sig_should_be[20];
159 163
160 if((cifs_pdu == NULL) || (mac_key == NULL)) 164 if ((cifs_pdu == NULL) || (mac_key == NULL))
161 return -EINVAL; 165 return -EINVAL;
162 166
163 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 167 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
164 return 0; 168 return 0;
165 169
166 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { 170 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
167 struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)cifs_pdu; 171 struct smb_com_lock_req *pSMB =
168 if(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) 172 (struct smb_com_lock_req *)cifs_pdu;
173 if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
169 return 0; 174 return 0;
170 } 175 }
171 176
172 /* BB what if signatures are supposed to be on for session but server does not 177 /* BB what if signatures are supposed to be on for session but
173 send one? BB */ 178 server does not send one? BB */
174 179
175 /* Do not need to verify session setups with signature "BSRSPYL " */ 180 /* Do not need to verify session setups with signature "BSRSPYL " */
176 if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0) 181 if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
177 cFYI(1,("dummy signature received for smb command 0x%x",cifs_pdu->Command)); 182 cFYI(1, ("dummy signature received for smb command 0x%x",
183 cifs_pdu->Command));
178 184
179 /* save off the origiginal signature so we can modify the smb and check 185 /* save off the origiginal signature so we can modify the smb and check
180 its signature against what the server sent */ 186 its signature against what the server sent */
181 memcpy(server_response_sig,cifs_pdu->Signature.SecuritySignature,8); 187 memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
182 188
183 cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(expected_sequence_number); 189 cifs_pdu->Signature.Sequence.SequenceNumber =
190 cpu_to_le32(expected_sequence_number);
184 cifs_pdu->Signature.Sequence.Reserved = 0; 191 cifs_pdu->Signature.Sequence.Reserved = 0;
185 192
186 rc = cifs_calculate_signature(cifs_pdu, mac_key, 193 rc = cifs_calculate_signature(cifs_pdu, mac_key,
187 what_we_think_sig_should_be); 194 what_we_think_sig_should_be);
188 195
189 if(rc) 196 if (rc)
190 return rc; 197 return rc;
191 198
192 199/* cifs_dump_mem("what we think it should be: ",
193/* cifs_dump_mem("what we think it should be: ",what_we_think_sig_should_be,16); */ 200 what_we_think_sig_should_be, 16); */
194 201
195 if(memcmp(server_response_sig, what_we_think_sig_should_be, 8)) 202 if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
196 return -EACCES; 203 return -EACCES;
197 else 204 else
198 return 0; 205 return 0;
@@ -200,89 +207,94 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
200} 207}
201 208
202/* We fill in key by putting in 40 byte array which was allocated by caller */ 209/* We fill in key by putting in 40 byte array which was allocated by caller */
203int cifs_calculate_mac_key(char * key, const char * rn, const char * password) 210int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
211 const char *password)
204{ 212{
205 char temp_key[16]; 213 char temp_key[16];
206 if ((key == NULL) || (rn == NULL)) 214 if ((key == NULL) || (rn == NULL))
207 return -EINVAL; 215 return -EINVAL;
208 216
209 E_md4hash(password, temp_key); 217 E_md4hash(password, temp_key);
210 mdfour(key,temp_key,16); 218 mdfour(key->data.ntlm, temp_key, 16);
211 memcpy(key+16,rn, CIFS_SESS_KEY_SIZE); 219 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE);
220 key->len = 40;
212 return 0; 221 return 0;
213} 222}
214 223
215int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, 224int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses,
216 const struct nls_table * nls_info) 225 const struct nls_table *nls_info)
217{ 226{
218 char temp_hash[16]; 227 char temp_hash[16];
219 struct HMACMD5Context ctx; 228 struct HMACMD5Context ctx;
220 char * ucase_buf; 229 char *ucase_buf;
221 __le16 * unicode_buf; 230 __le16 *unicode_buf;
222 unsigned int i,user_name_len,dom_name_len; 231 unsigned int i, user_name_len, dom_name_len;
223 232
224 if(ses == NULL) 233 if (ses == NULL)
225 return -EINVAL; 234 return -EINVAL;
226 235
227 E_md4hash(ses->password, temp_hash); 236 E_md4hash(ses->password, temp_hash);
228 237
229 hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); 238 hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
230 user_name_len = strlen(ses->userName); 239 user_name_len = strlen(ses->userName);
231 if(user_name_len > MAX_USERNAME_SIZE) 240 if (user_name_len > MAX_USERNAME_SIZE)
232 return -EINVAL; 241 return -EINVAL;
233 if(ses->domainName == NULL) 242 if (ses->domainName == NULL)
234 return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ 243 return -EINVAL; /* BB should we use CIFS_LINUX_DOM */
235 dom_name_len = strlen(ses->domainName); 244 dom_name_len = strlen(ses->domainName);
236 if(dom_name_len > MAX_USERNAME_SIZE) 245 if (dom_name_len > MAX_USERNAME_SIZE)
237 return -EINVAL; 246 return -EINVAL;
238 247
239 ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); 248 ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
240 if(ucase_buf == NULL) 249 if (ucase_buf == NULL)
241 return -ENOMEM; 250 return -ENOMEM;
242 unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); 251 unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
243 if(unicode_buf == NULL) { 252 if (unicode_buf == NULL) {
244 kfree(ucase_buf); 253 kfree(ucase_buf);
245 return -ENOMEM; 254 return -ENOMEM;
246 } 255 }
247 256
248 for(i=0;i<user_name_len;i++) 257 for (i = 0; i < user_name_len; i++)
249 ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; 258 ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
250 ucase_buf[i] = 0; 259 ucase_buf[i] = 0;
251 user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); 260 user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf,
261 MAX_USERNAME_SIZE*2, nls_info);
252 unicode_buf[user_name_len] = 0; 262 unicode_buf[user_name_len] = 0;
253 user_name_len++; 263 user_name_len++;
254 264
255 for(i=0;i<dom_name_len;i++) 265 for (i = 0; i < dom_name_len; i++)
256 ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; 266 ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
257 ucase_buf[i] = 0; 267 ucase_buf[i] = 0;
258 dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); 268 dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf,
269 MAX_USERNAME_SIZE*2, nls_info);
259 270
260 unicode_buf[user_name_len + dom_name_len] = 0; 271 unicode_buf[user_name_len + dom_name_len] = 0;
261 hmac_md5_update((const unsigned char *) unicode_buf, 272 hmac_md5_update((const unsigned char *) unicode_buf,
262 (user_name_len+dom_name_len)*2,&ctx); 273 (user_name_len+dom_name_len)*2, &ctx);
263 274
264 hmac_md5_final(ses->server->mac_signing_key,&ctx); 275 hmac_md5_final(ses->server->ntlmv2_hash, &ctx);
265 kfree(ucase_buf); 276 kfree(ucase_buf);
266 kfree(unicode_buf); 277 kfree(unicode_buf);
267 return 0; 278 return 0;
268} 279}
269 280
270#ifdef CONFIG_CIFS_WEAK_PW_HASH 281#ifdef CONFIG_CIFS_WEAK_PW_HASH
271void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key) 282void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key)
272{ 283{
273 int i; 284 int i;
274 char password_with_pad[CIFS_ENCPWD_SIZE]; 285 char password_with_pad[CIFS_ENCPWD_SIZE];
275 286
276 if(ses->server == NULL) 287 if (ses->server == NULL)
277 return; 288 return;
278 289
279 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); 290 memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
280 if(ses->password) 291 if (ses->password)
281 strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); 292 strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
282 293
283 if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0) 294 if ((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0)
284 if(extended_security & CIFSSEC_MAY_PLNTXT) { 295 if (extended_security & CIFSSEC_MAY_PLNTXT) {
285 memcpy(lnm_session_key, password_with_pad, CIFS_ENCPWD_SIZE); 296 memcpy(lnm_session_key, password_with_pad,
297 CIFS_ENCPWD_SIZE);
286 return; 298 return;
287 } 299 }
288 300
@@ -297,7 +309,7 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
297 utf8 and other multibyte codepages each need their own strupper 309 utf8 and other multibyte codepages each need their own strupper
298 function since a byte at a time will ont work. */ 310 function since a byte at a time will ont work. */
299 311
300 for(i = 0; i < CIFS_ENCPWD_SIZE; i++) { 312 for (i = 0; i < CIFS_ENCPWD_SIZE; i++) {
301 password_with_pad[i] = toupper(password_with_pad[i]); 313 password_with_pad[i] = toupper(password_with_pad[i]);
302 } 314 }
303 315
@@ -307,19 +319,19 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
307} 319}
308#endif /* CIFS_WEAK_PW_HASH */ 320#endif /* CIFS_WEAK_PW_HASH */
309 321
310static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 322static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
311 const struct nls_table * nls_cp) 323 const struct nls_table *nls_cp)
312{ 324{
313 int rc = 0; 325 int rc = 0;
314 int len; 326 int len;
315 char nt_hash[16]; 327 char nt_hash[16];
316 struct HMACMD5Context * pctxt; 328 struct HMACMD5Context *pctxt;
317 wchar_t * user; 329 wchar_t *user;
318 wchar_t * domain; 330 wchar_t *domain;
319 331
320 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 332 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
321 333
322 if(pctxt == NULL) 334 if (pctxt == NULL)
323 return -ENOMEM; 335 return -ENOMEM;
324 336
325 /* calculate md4 hash of password */ 337 /* calculate md4 hash of password */
@@ -331,41 +343,45 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
331 /* convert ses->userName to unicode and uppercase */ 343 /* convert ses->userName to unicode and uppercase */
332 len = strlen(ses->userName); 344 len = strlen(ses->userName);
333 user = kmalloc(2 + (len * 2), GFP_KERNEL); 345 user = kmalloc(2 + (len * 2), GFP_KERNEL);
334 if(user == NULL) 346 if (user == NULL)
335 goto calc_exit_2; 347 goto calc_exit_2;
336 len = cifs_strtoUCS(user, ses->userName, len, nls_cp); 348 len = cifs_strtoUCS(user, ses->userName, len, nls_cp);
337 UniStrupr(user); 349 UniStrupr(user);
338 hmac_md5_update((char *)user, 2*len, pctxt); 350 hmac_md5_update((char *)user, 2*len, pctxt);
339 351
340 /* convert ses->domainName to unicode and uppercase */ 352 /* convert ses->domainName to unicode and uppercase */
341 if(ses->domainName) { 353 if (ses->domainName) {
342 len = strlen(ses->domainName); 354 len = strlen(ses->domainName);
343 355
344 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 356 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
345 if(domain == NULL) 357 if (domain == NULL)
346 goto calc_exit_1; 358 goto calc_exit_1;
347 len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); 359 len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp);
348 UniStrupr(domain); 360 /* the following line was removed since it didn't work well
361 with lower cased domain name that passed as an option.
362 Maybe converting the domain name earlier makes sense */
363 /* UniStrupr(domain); */
349 364
350 hmac_md5_update((char *)domain, 2*len, pctxt); 365 hmac_md5_update((char *)domain, 2*len, pctxt);
351 366
352 kfree(domain); 367 kfree(domain);
353 } 368 }
354calc_exit_1: 369calc_exit_1:
355 kfree(user); 370 kfree(user);
356calc_exit_2: 371calc_exit_2:
357 /* BB FIXME what about bytes 24 through 40 of the signing key? 372 /* BB FIXME what about bytes 24 through 40 of the signing key?
358 compare with the NTLM example */ 373 compare with the NTLM example */
359 hmac_md5_final(ses->server->mac_signing_key, pctxt); 374 hmac_md5_final(ses->server->ntlmv2_hash, pctxt);
360 375
361 return rc; 376 return rc;
362} 377}
363 378
364void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, 379void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
365 const struct nls_table * nls_cp) 380 const struct nls_table *nls_cp)
366{ 381{
367 int rc; 382 int rc;
368 struct ntlmv2_resp * buf = (struct ntlmv2_resp *)resp_buf; 383 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
384 struct HMACMD5Context context;
369 385
370 buf->blob_signature = cpu_to_le32(0x00000101); 386 buf->blob_signature = cpu_to_le32(0x00000101);
371 buf->reserved = 0; 387 buf->reserved = 0;
@@ -379,21 +395,31 @@ void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf,
379 395
380 /* calculate buf->ntlmv2_hash */ 396 /* calculate buf->ntlmv2_hash */
381 rc = calc_ntlmv2_hash(ses, nls_cp); 397 rc = calc_ntlmv2_hash(ses, nls_cp);
382 if(rc) 398 if (rc)
383 cERROR(1,("could not get v2 hash rc %d",rc)); 399 cERROR(1, ("could not get v2 hash rc %d", rc));
384 CalcNTLMv2_response(ses, resp_buf); 400 CalcNTLMv2_response(ses, resp_buf);
401
402 /* now calculate the MAC key for NTLMv2 */
403 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
404 hmac_md5_update(resp_buf, 16, &context);
405 hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context);
406
407 memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf,
408 sizeof(struct ntlmv2_resp));
409 ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp);
385} 410}
386 411
387void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_response) 412void CalcNTLMv2_response(const struct cifsSesInfo *ses,
413 char *v2_session_response)
388{ 414{
389 struct HMACMD5Context context; 415 struct HMACMD5Context context;
390 /* rest of v2 struct already generated */ 416 /* rest of v2 struct already generated */
391 memcpy(v2_session_response + 8, ses->server->cryptKey,8); 417 memcpy(v2_session_response + 8, ses->server->cryptKey, 8);
392 hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); 418 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
393 419
394 hmac_md5_update(v2_session_response+8, 420 hmac_md5_update(v2_session_response+8,
395 sizeof(struct ntlmv2_resp) - 8, &context); 421 sizeof(struct ntlmv2_resp) - 8, &context);
396 422
397 hmac_md5_final(v2_session_response,&context); 423 hmac_md5_final(v2_session_response, &context);
398/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 424/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
399} 425}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index bd0f2f2353ce..1fd0dc85f53c 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -64,23 +64,27 @@ unsigned int multiuser_mount = 0;
64unsigned int extended_security = CIFSSEC_DEF; 64unsigned int extended_security = CIFSSEC_DEF;
65/* unsigned int ntlmv2_support = 0; */ 65/* unsigned int ntlmv2_support = 0; */
66unsigned int sign_CIFS_PDUs = 1; 66unsigned int sign_CIFS_PDUs = 1;
67extern struct task_struct * oplockThread; /* remove sparse warning */ 67extern struct task_struct *oplockThread; /* remove sparse warning */
68struct task_struct * oplockThread = NULL; 68struct task_struct *oplockThread = NULL;
69/* extern struct task_struct * dnotifyThread; remove sparse warning */ 69/* extern struct task_struct * dnotifyThread; remove sparse warning */
70static struct task_struct * dnotifyThread = NULL; 70static struct task_struct *dnotifyThread = NULL;
71static const struct super_operations cifs_super_ops; 71static const struct super_operations cifs_super_ops;
72unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 72unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
73module_param(CIFSMaxBufSize, int, 0); 73module_param(CIFSMaxBufSize, int, 0);
74MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); 74MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
75 "Default: 16384 Range: 8192 to 130048");
75unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; 76unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
76module_param(cifs_min_rcv, int, 0); 77module_param(cifs_min_rcv, int, 0);
77MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64"); 78MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
79 "1 to 64");
78unsigned int cifs_min_small = 30; 80unsigned int cifs_min_small = 30;
79module_param(cifs_min_small, int, 0); 81module_param(cifs_min_small, int, 0);
80MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256"); 82MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
83 "Range: 2 to 256");
81unsigned int cifs_max_pending = CIFS_MAX_REQ; 84unsigned int cifs_max_pending = CIFS_MAX_REQ;
82module_param(cifs_max_pending, int, 0); 85module_param(cifs_max_pending, int, 0);
83MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); 86MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
87 "Default: 50 Range: 2 to 256");
84 88
85extern mempool_t *cifs_sm_req_poolp; 89extern mempool_t *cifs_sm_req_poolp;
86extern mempool_t *cifs_req_poolp; 90extern mempool_t *cifs_req_poolp;
@@ -95,10 +99,10 @@ cifs_read_super(struct super_block *sb, void *data,
95 struct inode *inode; 99 struct inode *inode;
96 struct cifs_sb_info *cifs_sb; 100 struct cifs_sb_info *cifs_sb;
97 int rc = 0; 101 int rc = 0;
98 102
99 /* BB should we make this contingent on mount parm? */ 103 /* BB should we make this contingent on mount parm? */
100 sb->s_flags |= MS_NODIRATIME | MS_NOATIME; 104 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
101 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 105 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
102 cifs_sb = CIFS_SB(sb); 106 cifs_sb = CIFS_SB(sb);
103 if (cifs_sb == NULL) 107 if (cifs_sb == NULL)
104 return -ENOMEM; 108 return -ENOMEM;
@@ -114,12 +118,9 @@ cifs_read_super(struct super_block *sb, void *data,
114 118
115 sb->s_magic = CIFS_MAGIC_NUMBER; 119 sb->s_magic = CIFS_MAGIC_NUMBER;
116 sb->s_op = &cifs_super_ops; 120 sb->s_op = &cifs_super_ops;
117#ifdef CONFIG_CIFS_EXPERIMENTAL
118 if (experimEnabled != 0)
119 sb->s_export_op = &cifs_export_ops;
120#endif /* EXPERIMENTAL */
121/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) 121/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
122 sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ 122 sb->s_blocksize =
123 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
123#ifdef CONFIG_CIFS_QUOTA 124#ifdef CONFIG_CIFS_QUOTA
124 sb->s_qcop = &cifs_quotactl_ops; 125 sb->s_qcop = &cifs_quotactl_ops;
125#endif 126#endif
@@ -139,6 +140,13 @@ cifs_read_super(struct super_block *sb, void *data,
139 goto out_no_root; 140 goto out_no_root;
140 } 141 }
141 142
143#ifdef CONFIG_CIFS_EXPERIMENTAL
144 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
145 cFYI(1, ("export ops supported"));
146 sb->s_export_op = &cifs_export_ops;
147 }
148#endif /* EXPERIMENTAL */
149
142 return 0; 150 return 0;
143 151
144out_no_root: 152out_no_root:
@@ -149,7 +157,7 @@ out_no_root:
149out_mount_failed: 157out_mount_failed:
150 if (cifs_sb) { 158 if (cifs_sb) {
151 if (cifs_sb->local_nls) 159 if (cifs_sb->local_nls)
152 unload_nls(cifs_sb->local_nls); 160 unload_nls(cifs_sb->local_nls);
153 kfree(cifs_sb); 161 kfree(cifs_sb);
154 } 162 }
155 return rc; 163 return rc;
@@ -164,10 +172,10 @@ cifs_put_super(struct super_block *sb)
164 cFYI(1, ("In cifs_put_super")); 172 cFYI(1, ("In cifs_put_super"));
165 cifs_sb = CIFS_SB(sb); 173 cifs_sb = CIFS_SB(sb);
166 if (cifs_sb == NULL) { 174 if (cifs_sb == NULL) {
167 cFYI(1,("Empty cifs superblock info passed to unmount")); 175 cFYI(1, ("Empty cifs superblock info passed to unmount"));
168 return; 176 return;
169 } 177 }
170 rc = cifs_umount(sb, cifs_sb); 178 rc = cifs_umount(sb, cifs_sb);
171 if (rc) { 179 if (rc) {
172 cERROR(1, ("cifs_umount failed with return code %d", rc)); 180 cERROR(1, ("cifs_umount failed with return code %d", rc));
173 } 181 }
@@ -180,7 +188,7 @@ static int
180cifs_statfs(struct dentry *dentry, struct kstatfs *buf) 188cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
181{ 189{
182 struct super_block *sb = dentry->d_sb; 190 struct super_block *sb = dentry->d_sb;
183 int xid; 191 int xid;
184 int rc = -EOPNOTSUPP; 192 int rc = -EOPNOTSUPP;
185 struct cifs_sb_info *cifs_sb; 193 struct cifs_sb_info *cifs_sb;
186 struct cifsTconInfo *pTcon; 194 struct cifsTconInfo *pTcon;
@@ -193,7 +201,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
193 buf->f_type = CIFS_MAGIC_NUMBER; 201 buf->f_type = CIFS_MAGIC_NUMBER;
194 202
195 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */ 203 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
196 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would 204 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
197 presumably be total path, but note 205 presumably be total path, but note
198 that some servers (includinng Samba 3) 206 that some servers (includinng Samba 3)
199 have a shorter maximum path */ 207 have a shorter maximum path */
@@ -217,8 +225,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
217 bypassed it because we detected that this was an older LANMAN sess */ 225 bypassed it because we detected that this was an older LANMAN sess */
218 if (rc) 226 if (rc)
219 rc = SMBOldQFSInfo(xid, pTcon, buf); 227 rc = SMBOldQFSInfo(xid, pTcon, buf);
220 /* 228 /* int f_type;
221 int f_type;
222 __fsid_t f_fsid; 229 __fsid_t f_fsid;
223 int f_namelen; */ 230 int f_namelen; */
224 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */ 231 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
@@ -227,7 +234,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
227 longer available? */ 234 longer available? */
228} 235}
229 236
230static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) 237static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
231{ 238{
232 struct cifs_sb_info *cifs_sb; 239 struct cifs_sb_info *cifs_sb;
233 240
@@ -235,10 +242,10 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
235 242
236 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { 243 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
237 return 0; 244 return 0;
238 } else /* file mode might have been restricted at mount time 245 } else /* file mode might have been restricted at mount time
239 on the client (above and beyond ACL on servers) for 246 on the client (above and beyond ACL on servers) for
240 servers which do not support setting and viewing mode bits, 247 servers which do not support setting and viewing mode bits,
241 so allowing client to check permissions is useful */ 248 so allowing client to check permissions is useful */
242 return generic_permission(inode, mask, NULL); 249 return generic_permission(inode, mask, NULL);
243} 250}
244 251
@@ -267,7 +274,7 @@ cifs_alloc_inode(struct super_block *sb)
267 cifs_inode->clientCanCacheRead = FALSE; 274 cifs_inode->clientCanCacheRead = FALSE;
268 cifs_inode->clientCanCacheAll = FALSE; 275 cifs_inode->clientCanCacheAll = FALSE;
269 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 276 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
270 277
271 /* Can not set i_flags here - they get immediately overwritten 278 /* Can not set i_flags here - they get immediately overwritten
272 to zero by the VFS */ 279 to zero by the VFS */
273/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/ 280/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
@@ -309,26 +316,26 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
309 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 316 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
310 seq_printf(s, ",posixpaths"); 317 seq_printf(s, ",posixpaths");
311 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || 318 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
312 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 319 !(cifs_sb->tcon->unix_ext))
313 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); 320 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
314 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || 321 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
315 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) 322 !(cifs_sb->tcon->unix_ext))
316 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); 323 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
317 seq_printf(s, ",rsize=%d",cifs_sb->rsize); 324 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
318 seq_printf(s, ",wsize=%d",cifs_sb->wsize); 325 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
319 } 326 }
320 return 0; 327 return 0;
321} 328}
322 329
323#ifdef CONFIG_CIFS_QUOTA 330#ifdef CONFIG_CIFS_QUOTA
324int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid, 331int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
325 struct fs_disk_quota * pdquota) 332 struct fs_disk_quota *pdquota)
326{ 333{
327 int xid; 334 int xid;
328 int rc = 0; 335 int rc = 0;
329 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 336 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
330 struct cifsTconInfo *pTcon; 337 struct cifsTconInfo *pTcon;
331 338
332 if (cifs_sb) 339 if (cifs_sb)
333 pTcon = cifs_sb->tcon; 340 pTcon = cifs_sb->tcon;
334 else 341 else
@@ -337,7 +344,7 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
337 344
338 xid = GetXid(); 345 xid = GetXid();
339 if (pTcon) { 346 if (pTcon) {
340 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 347 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
341 } else { 348 } else {
342 return -EIO; 349 return -EIO;
343 } 350 }
@@ -346,8 +353,8 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
346 return rc; 353 return rc;
347} 354}
348 355
349int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid, 356int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
350 struct fs_disk_quota * pdquota) 357 struct fs_disk_quota *pdquota)
351{ 358{
352 int xid; 359 int xid;
353 int rc = 0; 360 int rc = 0;
@@ -361,7 +368,7 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
361 368
362 xid = GetXid(); 369 xid = GetXid();
363 if (pTcon) { 370 if (pTcon) {
364 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 371 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
365 } else { 372 } else {
366 rc = -EIO; 373 rc = -EIO;
367 } 374 }
@@ -370,9 +377,9 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
370 return rc; 377 return rc;
371} 378}
372 379
373int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation) 380int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
374{ 381{
375 int xid; 382 int xid;
376 int rc = 0; 383 int rc = 0;
377 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 384 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
378 struct cifsTconInfo *pTcon; 385 struct cifsTconInfo *pTcon;
@@ -384,7 +391,7 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
384 391
385 xid = GetXid(); 392 xid = GetXid();
386 if (pTcon) { 393 if (pTcon) {
387 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); 394 cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
388 } else { 395 } else {
389 rc = -EIO; 396 rc = -EIO;
390 } 397 }
@@ -393,7 +400,7 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
393 return rc; 400 return rc;
394} 401}
395 402
396int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats) 403int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
397{ 404{
398 int xid; 405 int xid;
399 int rc = 0; 406 int rc = 0;
@@ -407,7 +414,7 @@ int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
407 } 414 }
408 xid = GetXid(); 415 xid = GetXid();
409 if (pTcon) { 416 if (pTcon) {
410 cFYI(1,("pqstats %p",qstats)); 417 cFYI(1, ("pqstats %p", qstats));
411 } else { 418 } else {
412 rc = -EIO; 419 rc = -EIO;
413 } 420 }
@@ -424,10 +431,10 @@ static struct quotactl_ops cifs_quotactl_ops = {
424}; 431};
425#endif 432#endif
426 433
427static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) 434static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
428{ 435{
429 struct cifs_sb_info *cifs_sb; 436 struct cifs_sb_info *cifs_sb;
430 struct cifsTconInfo * tcon; 437 struct cifsTconInfo *tcon;
431 438
432 if (!(flags & MNT_FORCE)) 439 if (!(flags & MNT_FORCE))
433 return; 440 return;
@@ -445,9 +452,8 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
445 452
446 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 453 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
447 /* cancel_notify_requests(tcon); */ 454 /* cancel_notify_requests(tcon); */
448 if (tcon->ses && tcon->ses->server) 455 if (tcon->ses && tcon->ses->server) {
449 { 456 cFYI(1, ("wake up tasks now - umount begin not complete"));
450 cFYI(1,("wake up tasks now - umount begin not complete"));
451 wake_up_all(&tcon->ses->server->request_q); 457 wake_up_all(&tcon->ses->server->request_q);
452 wake_up_all(&tcon->ses->server->response_q); 458 wake_up_all(&tcon->ses->server->response_q);
453 msleep(1); /* yield */ 459 msleep(1); /* yield */
@@ -480,10 +486,11 @@ static const struct super_operations cifs_super_ops = {
480 .statfs = cifs_statfs, 486 .statfs = cifs_statfs,
481 .alloc_inode = cifs_alloc_inode, 487 .alloc_inode = cifs_alloc_inode,
482 .destroy_inode = cifs_destroy_inode, 488 .destroy_inode = cifs_destroy_inode,
483/* .drop_inode = generic_delete_inode, 489/* .drop_inode = generic_delete_inode,
484 .delete_inode = cifs_delete_inode, *//* Do not need the above two functions 490 .delete_inode = cifs_delete_inode, */ /* Do not need above two
485 unless later we add lazy close of inodes or unless the kernel forgets to call 491 functions unless later we add lazy close of inodes or unless the
486 us with the same number of releases (closes) as opens */ 492 kernel forgets to call us with the same number of releases (closes)
493 as opens */
487 .show_options = cifs_show_options, 494 .show_options = cifs_show_options,
488 .umount_begin = cifs_umount_begin, 495 .umount_begin = cifs_umount_begin,
489 .remount_fs = cifs_remount, 496 .remount_fs = cifs_remount,
@@ -586,11 +593,11 @@ const struct inode_operations cifs_file_inode_ops = {
586 .getxattr = cifs_getxattr, 593 .getxattr = cifs_getxattr,
587 .listxattr = cifs_listxattr, 594 .listxattr = cifs_listxattr,
588 .removexattr = cifs_removexattr, 595 .removexattr = cifs_removexattr,
589#endif 596#endif
590}; 597};
591 598
592const struct inode_operations cifs_symlink_inode_ops = { 599const struct inode_operations cifs_symlink_inode_ops = {
593 .readlink = generic_readlink, 600 .readlink = generic_readlink,
594 .follow_link = cifs_follow_link, 601 .follow_link = cifs_follow_link,
595 .put_link = cifs_put_link, 602 .put_link = cifs_put_link,
596 .permission = cifs_permission, 603 .permission = cifs_permission,
@@ -602,7 +609,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
602 .getxattr = cifs_getxattr, 609 .getxattr = cifs_getxattr,
603 .listxattr = cifs_listxattr, 610 .listxattr = cifs_listxattr,
604 .removexattr = cifs_removexattr, 611 .removexattr = cifs_removexattr,
605#endif 612#endif
606}; 613};
607 614
608const struct file_operations cifs_file_ops = { 615const struct file_operations cifs_file_ops = {
@@ -628,7 +635,7 @@ const struct file_operations cifs_file_ops = {
628}; 635};
629 636
630const struct file_operations cifs_file_direct_ops = { 637const struct file_operations cifs_file_direct_ops = {
631 /* no mmap, no aio, no readv - 638 /* no mmap, no aio, no readv -
632 BB reevaluate whether they can be done with directio, no cache */ 639 BB reevaluate whether they can be done with directio, no cache */
633 .read = cifs_user_read, 640 .read = cifs_user_read,
634 .write = cifs_user_write, 641 .write = cifs_user_write,
@@ -668,7 +675,7 @@ const struct file_operations cifs_file_nobrl_ops = {
668}; 675};
669 676
670const struct file_operations cifs_file_direct_nobrl_ops = { 677const struct file_operations cifs_file_direct_nobrl_ops = {
671 /* no mmap, no aio, no readv - 678 /* no mmap, no aio, no readv -
672 BB reevaluate whether they can be done with directio, no cache */ 679 BB reevaluate whether they can be done with directio, no cache */
673 .read = cifs_user_read, 680 .read = cifs_user_read,
674 .write = cifs_user_write, 681 .write = cifs_user_write,
@@ -693,11 +700,11 @@ const struct file_operations cifs_dir_ops = {
693#ifdef CONFIG_CIFS_EXPERIMENTAL 700#ifdef CONFIG_CIFS_EXPERIMENTAL
694 .dir_notify = cifs_dir_notify, 701 .dir_notify = cifs_dir_notify,
695#endif /* CONFIG_CIFS_EXPERIMENTAL */ 702#endif /* CONFIG_CIFS_EXPERIMENTAL */
696 .ioctl = cifs_ioctl, 703 .ioctl = cifs_ioctl,
697}; 704};
698 705
699static void 706static void
700cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) 707cifs_init_once(void *inode, struct kmem_cache *cachep, unsigned long flags)
701{ 708{
702 struct cifsInodeInfo *cifsi = inode; 709 struct cifsInodeInfo *cifsi = inode;
703 710
@@ -749,7 +756,7 @@ cifs_init_request_bufs(void)
749 cifs_min_rcv = 1; 756 cifs_min_rcv = 1;
750 else if (cifs_min_rcv > 64) { 757 else if (cifs_min_rcv > 64) {
751 cifs_min_rcv = 64; 758 cifs_min_rcv = 64;
752 cERROR(1,("cifs_min_rcv set to maximum (64)")); 759 cERROR(1, ("cifs_min_rcv set to maximum (64)"));
753 } 760 }
754 761
755 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, 762 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
@@ -762,25 +769,25 @@ cifs_init_request_bufs(void)
762 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and 769 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
763 almost all handle based requests (but not write response, nor is it 770 almost all handle based requests (but not write response, nor is it
764 sufficient for path based requests). A smaller size would have 771 sufficient for path based requests). A smaller size would have
765 been more efficient (compacting multiple slab items on one 4k page) 772 been more efficient (compacting multiple slab items on one 4k page)
766 for the case in which debug was on, but this larger size allows 773 for the case in which debug was on, but this larger size allows
767 more SMBs to use small buffer alloc and is still much more 774 more SMBs to use small buffer alloc and is still much more
768 efficient to alloc 1 per page off the slab compared to 17K (5page) 775 efficient to alloc 1 per page off the slab compared to 17K (5page)
769 alloc of large cifs buffers even when page debugging is on */ 776 alloc of large cifs buffers even when page debugging is on */
770 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq", 777 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
771 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 778 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
772 NULL, NULL); 779 NULL, NULL);
773 if (cifs_sm_req_cachep == NULL) { 780 if (cifs_sm_req_cachep == NULL) {
774 mempool_destroy(cifs_req_poolp); 781 mempool_destroy(cifs_req_poolp);
775 kmem_cache_destroy(cifs_req_cachep); 782 kmem_cache_destroy(cifs_req_cachep);
776 return -ENOMEM; 783 return -ENOMEM;
777 } 784 }
778 785
779 if (cifs_min_small < 2) 786 if (cifs_min_small < 2)
780 cifs_min_small = 2; 787 cifs_min_small = 2;
781 else if (cifs_min_small > 256) { 788 else if (cifs_min_small > 256) {
782 cifs_min_small = 256; 789 cifs_min_small = 256;
783 cFYI(1,("cifs_min_small set to maximum (256)")); 790 cFYI(1, ("cifs_min_small set to maximum (256)"));
784 } 791 }
785 792
786 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, 793 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
@@ -841,42 +848,43 @@ cifs_destroy_mids(void)
841 kmem_cache_destroy(cifs_oplock_cachep); 848 kmem_cache_destroy(cifs_oplock_cachep);
842} 849}
843 850
844static int cifs_oplock_thread(void * dummyarg) 851static int cifs_oplock_thread(void *dummyarg)
845{ 852{
846 struct oplock_q_entry * oplock_item; 853 struct oplock_q_entry *oplock_item;
847 struct cifsTconInfo *pTcon; 854 struct cifsTconInfo *pTcon;
848 struct inode * inode; 855 struct inode *inode;
849 __u16 netfid; 856 __u16 netfid;
850 int rc; 857 int rc;
851 858
852 set_freezable(); 859 set_freezable();
853 do { 860 do {
854 if (try_to_freeze()) 861 if (try_to_freeze())
855 continue; 862 continue;
856 863
857 spin_lock(&GlobalMid_Lock); 864 spin_lock(&GlobalMid_Lock);
858 if (list_empty(&GlobalOplock_Q)) { 865 if (list_empty(&GlobalOplock_Q)) {
859 spin_unlock(&GlobalMid_Lock); 866 spin_unlock(&GlobalMid_Lock);
860 set_current_state(TASK_INTERRUPTIBLE); 867 set_current_state(TASK_INTERRUPTIBLE);
861 schedule_timeout(39*HZ); 868 schedule_timeout(39*HZ);
862 } else { 869 } else {
863 oplock_item = list_entry(GlobalOplock_Q.next, 870 oplock_item = list_entry(GlobalOplock_Q.next,
864 struct oplock_q_entry, qhead); 871 struct oplock_q_entry, qhead);
865 if (oplock_item) { 872 if (oplock_item) {
866 cFYI(1,("found oplock item to write out")); 873 cFYI(1, ("found oplock item to write out"));
867 pTcon = oplock_item->tcon; 874 pTcon = oplock_item->tcon;
868 inode = oplock_item->pinode; 875 inode = oplock_item->pinode;
869 netfid = oplock_item->netfid; 876 netfid = oplock_item->netfid;
870 spin_unlock(&GlobalMid_Lock); 877 spin_unlock(&GlobalMid_Lock);
871 DeleteOplockQEntry(oplock_item); 878 DeleteOplockQEntry(oplock_item);
872 /* can not grab inode sem here since it would 879 /* can not grab inode sem here since it would
873 deadlock when oplock received on delete 880 deadlock when oplock received on delete
874 since vfs_unlink holds the i_mutex across 881 since vfs_unlink holds the i_mutex across
875 the call */ 882 the call */
876 /* mutex_lock(&inode->i_mutex);*/ 883 /* mutex_lock(&inode->i_mutex);*/
877 if (S_ISREG(inode->i_mode)) { 884 if (S_ISREG(inode->i_mode)) {
878 rc = filemap_fdatawrite(inode->i_mapping); 885 rc = filemap_fdatawrite(inode->i_mapping);
879 if (CIFS_I(inode)->clientCanCacheRead == 0) { 886 if (CIFS_I(inode)->clientCanCacheRead
887 == 0) {
880 filemap_fdatawait(inode->i_mapping); 888 filemap_fdatawait(inode->i_mapping);
881 invalidate_remote_inode(inode); 889 invalidate_remote_inode(inode);
882 } 890 }
@@ -885,20 +893,22 @@ static int cifs_oplock_thread(void * dummyarg)
885 /* mutex_unlock(&inode->i_mutex);*/ 893 /* mutex_unlock(&inode->i_mutex);*/
886 if (rc) 894 if (rc)
887 CIFS_I(inode)->write_behind_rc = rc; 895 CIFS_I(inode)->write_behind_rc = rc;
888 cFYI(1,("Oplock flush inode %p rc %d",inode,rc)); 896 cFYI(1, ("Oplock flush inode %p rc %d",
889 897 inode, rc));
890 /* releasing a stale oplock after recent reconnection 898
891 of smb session using a now incorrect file 899 /* releasing stale oplock after recent reconnect
892 handle is not a data integrity issue but do 900 of smb session using a now incorrect file
893 not bother sending an oplock release if session 901 handle is not a data integrity issue but do
894 to server still is disconnected since oplock 902 not bother sending an oplock release if session
903 to server still is disconnected since oplock
895 already released by the server in that case */ 904 already released by the server in that case */
896 if (pTcon->tidStatus != CifsNeedReconnect) { 905 if (pTcon->tidStatus != CifsNeedReconnect) {
897 rc = CIFSSMBLock(0, pTcon, netfid, 906 rc = CIFSSMBLock(0, pTcon, netfid,
898 0 /* len */ , 0 /* offset */, 0, 907 0 /* len */ , 0 /* offset */, 0,
899 0, LOCKING_ANDX_OPLOCK_RELEASE, 908 0, LOCKING_ANDX_OPLOCK_RELEASE,
900 0 /* wait flag */); 909 0 /* wait flag */);
901 cFYI(1,("Oplock release rc = %d ",rc)); 910 cFYI(1,
911 ("Oplock release rc = %d ", rc));
902 } 912 }
903 } else 913 } else
904 spin_unlock(&GlobalMid_Lock); 914 spin_unlock(&GlobalMid_Lock);
@@ -910,7 +920,7 @@ static int cifs_oplock_thread(void * dummyarg)
910 return 0; 920 return 0;
911} 921}
912 922
913static int cifs_dnotify_thread(void * dummyarg) 923static int cifs_dnotify_thread(void *dummyarg)
914{ 924{
915 struct list_head *tmp; 925 struct list_head *tmp;
916 struct cifsSesInfo *ses; 926 struct cifsSesInfo *ses;
@@ -925,9 +935,9 @@ static int cifs_dnotify_thread(void * dummyarg)
925 to be woken up and wakeq so the 935 to be woken up and wakeq so the
926 thread can wake up and error out */ 936 thread can wake up and error out */
927 list_for_each(tmp, &GlobalSMBSessionList) { 937 list_for_each(tmp, &GlobalSMBSessionList) {
928 ses = list_entry(tmp, struct cifsSesInfo, 938 ses = list_entry(tmp, struct cifsSesInfo,
929 cifsSessionList); 939 cifsSessionList);
930 if (ses && ses->server && 940 if (ses && ses->server &&
931 atomic_read(&ses->server->inFlight)) 941 atomic_read(&ses->server->inFlight))
932 wake_up_all(&ses->server->response_q); 942 wake_up_all(&ses->server->response_q);
933 } 943 }
@@ -951,13 +961,13 @@ init_cifs(void)
951#ifdef CONFIG_CIFS_EXPERIMENTAL 961#ifdef CONFIG_CIFS_EXPERIMENTAL
952 INIT_LIST_HEAD(&GlobalDnotifyReqList); 962 INIT_LIST_HEAD(&GlobalDnotifyReqList);
953 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); 963 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
954#endif 964#endif
955/* 965/*
956 * Initialize Global counters 966 * Initialize Global counters
957 */ 967 */
958 atomic_set(&sesInfoAllocCount, 0); 968 atomic_set(&sesInfoAllocCount, 0);
959 atomic_set(&tconInfoAllocCount, 0); 969 atomic_set(&tconInfoAllocCount, 0);
960 atomic_set(&tcpSesAllocCount,0); 970 atomic_set(&tcpSesAllocCount, 0);
961 atomic_set(&tcpSesReconnectCount, 0); 971 atomic_set(&tcpSesReconnectCount, 0);
962 atomic_set(&tconInfoReconnectCount, 0); 972 atomic_set(&tconInfoReconnectCount, 0);
963 973
@@ -978,10 +988,10 @@ init_cifs(void)
978 988
979 if (cifs_max_pending < 2) { 989 if (cifs_max_pending < 2) {
980 cifs_max_pending = 2; 990 cifs_max_pending = 2;
981 cFYI(1,("cifs_max_pending set to min of 2")); 991 cFYI(1, ("cifs_max_pending set to min of 2"));
982 } else if (cifs_max_pending > 256) { 992 } else if (cifs_max_pending > 256) {
983 cifs_max_pending = 256; 993 cifs_max_pending = 256;
984 cFYI(1,("cifs_max_pending set to max of 256")); 994 cFYI(1, ("cifs_max_pending set to max of 256"));
985 } 995 }
986 996
987 rc = cifs_init_inodecache(); 997 rc = cifs_init_inodecache();
@@ -1003,14 +1013,14 @@ init_cifs(void)
1003 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); 1013 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1004 if (IS_ERR(oplockThread)) { 1014 if (IS_ERR(oplockThread)) {
1005 rc = PTR_ERR(oplockThread); 1015 rc = PTR_ERR(oplockThread);
1006 cERROR(1,("error %d create oplock thread", rc)); 1016 cERROR(1, ("error %d create oplock thread", rc));
1007 goto out_unregister_filesystem; 1017 goto out_unregister_filesystem;
1008 } 1018 }
1009 1019
1010 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); 1020 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1011 if (IS_ERR(dnotifyThread)) { 1021 if (IS_ERR(dnotifyThread)) {
1012 rc = PTR_ERR(dnotifyThread); 1022 rc = PTR_ERR(dnotifyThread);
1013 cERROR(1,("error %d create dnotify thread", rc)); 1023 cERROR(1, ("error %d create dnotify thread", rc));
1014 goto out_stop_oplock_thread; 1024 goto out_stop_oplock_thread;
1015 } 1025 }
1016 1026
@@ -1036,7 +1046,7 @@ init_cifs(void)
1036static void __exit 1046static void __exit
1037exit_cifs(void) 1047exit_cifs(void)
1038{ 1048{
1039 cFYI(0, ("In unregister ie exit_cifs")); 1049 cFYI(0, ("exit_cifs"));
1040#ifdef CONFIG_PROC_FS 1050#ifdef CONFIG_PROC_FS
1041 cifs_proc_clean(); 1051 cifs_proc_clean();
1042#endif 1052#endif
@@ -1049,9 +1059,10 @@ exit_cifs(void)
1049} 1059}
1050 1060
1051MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); 1061MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
1052MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */ 1062MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
1053MODULE_DESCRIPTION 1063MODULE_DESCRIPTION
1054 ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows"); 1064 ("VFS to access servers complying with the SNIA CIFS Specification "
1065 "e.g. Samba and Windows");
1055MODULE_VERSION(CIFS_VERSION); 1066MODULE_VERSION(CIFS_VERSION);
1056module_init(init_cifs) 1067module_init(init_cifs)
1057module_exit(exit_cifs) 1068module_exit(exit_cifs)
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index c235d32ad4a8..a20de77a3856 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#ifndef _CIFSFS_H 22#ifndef _CIFSFS_H
@@ -43,9 +43,9 @@ extern void cifs_read_inode(struct inode *);
43 43
44/* Functions related to inodes */ 44/* Functions related to inodes */
45extern const struct inode_operations cifs_dir_inode_ops; 45extern const struct inode_operations cifs_dir_inode_ops;
46extern int cifs_create(struct inode *, struct dentry *, int, 46extern int cifs_create(struct inode *, struct dentry *, int,
47 struct nameidata *); 47 struct nameidata *);
48extern struct dentry * cifs_lookup(struct inode *, struct dentry *, 48extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
49 struct nameidata *); 49 struct nameidata *);
50extern int cifs_unlink(struct inode *, struct dentry *); 50extern int cifs_unlink(struct inode *, struct dentry *);
51extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); 51extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
@@ -63,16 +63,16 @@ extern const struct inode_operations cifs_symlink_inode_ops;
63 63
64/* Functions related to files and directories */ 64/* Functions related to files and directories */
65extern const struct file_operations cifs_file_ops; 65extern const struct file_operations cifs_file_ops;
66extern const struct file_operations cifs_file_direct_ops; /* if directio mount */ 66extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
67extern const struct file_operations cifs_file_nobrl_ops; 67extern const struct file_operations cifs_file_nobrl_ops;
68extern const struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */ 68extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */
69extern int cifs_open(struct inode *inode, struct file *file); 69extern int cifs_open(struct inode *inode, struct file *file);
70extern int cifs_close(struct inode *inode, struct file *file); 70extern int cifs_close(struct inode *inode, struct file *file);
71extern int cifs_closedir(struct inode *inode, struct file *file); 71extern int cifs_closedir(struct inode *inode, struct file *file);
72extern ssize_t cifs_user_read(struct file *file, char __user *read_data, 72extern ssize_t cifs_user_read(struct file *file, char __user *read_data,
73 size_t read_size, loff_t * poffset); 73 size_t read_size, loff_t *poffset);
74extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, 74extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
75 size_t write_size, loff_t * poffset); 75 size_t write_size, loff_t *poffset);
76extern int cifs_lock(struct file *, int, struct file_lock *); 76extern int cifs_lock(struct file *, int, struct file_lock *);
77extern int cifs_fsync(struct file *, struct dentry *, int); 77extern int cifs_fsync(struct file *, struct dentry *, int);
78extern int cifs_flush(struct file *, fl_owner_t id); 78extern int cifs_flush(struct file *, fl_owner_t id);
@@ -88,8 +88,9 @@ extern struct dentry_operations cifs_ci_dentry_ops;
88 88
89/* Functions related to symlinks */ 89/* Functions related to symlinks */
90extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); 90extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
91extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *); 91extern void cifs_put_link(struct dentry *direntry,
92extern int cifs_readlink(struct dentry *direntry, char __user *buffer, 92 struct nameidata *nd, void *);
93extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
93 int buflen); 94 int buflen);
94extern int cifs_symlink(struct inode *inode, struct dentry *direntry, 95extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
95 const char *symname); 96 const char *symname);
@@ -98,7 +99,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
98 size_t, int); 99 size_t, int);
99extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); 100extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
101extern int cifs_ioctl (struct inode * inode, struct file * filep, 102extern int cifs_ioctl (struct inode *inode, struct file *filep,
102 unsigned int command, unsigned long arg); 103 unsigned int command, unsigned long arg);
103#define CIFS_VERSION "1.49" 104#define CIFS_VERSION "1.50"
104#endif /* _CIFSFS_H */ 105#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 23655de2f4a4..b98742fc3b5a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsglob.h 2 * fs/cifs/cifsglob.h
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2006 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 6 * Jeremy Allison (jra@samba.org)
7 * 7 *
@@ -14,7 +14,7 @@
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details. 16 * the GNU Lesser General Public License for more details.
17 * 17 *
18 */ 18 */
19#include <linux/in.h> 19#include <linux/in.h>
20#include <linux/in6.h> 20#include <linux/in6.h>
@@ -28,7 +28,7 @@
28 28
29#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 29#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1
30#define MAX_SERVER_SIZE 15 30#define MAX_SERVER_SIZE 15
31#define MAX_SHARE_SIZE 64 /* used to be 20 - this should still be enough */ 31#define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */
32#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null 32#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null
33 termination then *2 for unicode versions */ 33 termination then *2 for unicode versions */
34#define MAX_PASSWORD_SIZE 16 34#define MAX_PASSWORD_SIZE 16
@@ -38,13 +38,13 @@
38/* 38/*
39 * MAX_REQ is the maximum number of requests that WE will send 39 * MAX_REQ is the maximum number of requests that WE will send
40 * on one socket concurently. It also matches the most common 40 * on one socket concurently. It also matches the most common
41 * value of max multiplex returned by servers. We may 41 * value of max multiplex returned by servers. We may
42 * eventually want to use the negotiated value (in case 42 * eventually want to use the negotiated value (in case
43 * future servers can handle more) when we are more confident that 43 * future servers can handle more) when we are more confident that
44 * we will not have problems oveloading the socket with pending 44 * we will not have problems oveloading the socket with pending
45 * write data. 45 * write data.
46 */ 46 */
47#define CIFS_MAX_REQ 50 47#define CIFS_MAX_REQ 50
48 48
49#define SERVER_NAME_LENGTH 15 49#define SERVER_NAME_LENGTH 15
50#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) 50#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
@@ -104,6 +104,17 @@ enum protocolEnum {
104 /* Netbios frames protocol not supported at this time */ 104 /* Netbios frames protocol not supported at this time */
105}; 105};
106 106
107struct mac_key {
108 unsigned int len;
109 union {
110 char ntlm[CIFS_SESS_KEY_SIZE + 16];
111 struct {
112 char key[16];
113 struct ntlmv2_resp resp;
114 } ntlmv2;
115 } data;
116};
117
107/* 118/*
108 ***************************************************************** 119 *****************************************************************
109 * Except the CIFS PDUs themselves all the 120 * Except the CIFS PDUs themselves all the
@@ -120,13 +131,13 @@ struct TCP_Server_Info {
120 struct sockaddr_in sockAddr; 131 struct sockaddr_in sockAddr;
121 struct sockaddr_in6 sockAddr6; 132 struct sockaddr_in6 sockAddr6;
122 } addr; 133 } addr;
123 wait_queue_head_t response_q; 134 wait_queue_head_t response_q;
124 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 135 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
125 struct list_head pending_mid_q; 136 struct list_head pending_mid_q;
126 void *Server_NlsInfo; /* BB - placeholder for future NLS info */ 137 void *Server_NlsInfo; /* BB - placeholder for future NLS info */
127 unsigned short server_codepage; /* codepage for the server */ 138 unsigned short server_codepage; /* codepage for the server */
128 unsigned long ip_address; /* IP addr for the server if known */ 139 unsigned long ip_address; /* IP addr for the server if known */
129 enum protocolEnum protocolType; 140 enum protocolEnum protocolType;
130 char versionMajor; 141 char versionMajor;
131 char versionMinor; 142 char versionMinor;
132 unsigned svlocal:1; /* local server or remote */ 143 unsigned svlocal:1; /* local server or remote */
@@ -159,14 +170,15 @@ struct TCP_Server_Info {
159 /* 16th byte of RFC1001 workstation name is always null */ 170 /* 16th byte of RFC1001 workstation name is always null */
160 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; 171 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
161 __u32 sequence_number; /* needed for CIFS PDU signature */ 172 __u32 sequence_number; /* needed for CIFS PDU signature */
162 char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 173 struct mac_key mac_signing_key;
174 char ntlmv2_hash[16];
163 unsigned long lstrp; /* when we got last response from this server */ 175 unsigned long lstrp; /* when we got last response from this server */
164}; 176};
165 177
166/* 178/*
167 * The following is our shortcut to user information. We surface the uid, 179 * The following is our shortcut to user information. We surface the uid,
168 * and name. We always get the password on the fly in case it 180 * and name. We always get the password on the fly in case it
169 * has changed. We also hang a list of sessions owned by this user off here. 181 * has changed. We also hang a list of sessions owned by this user off here.
170 */ 182 */
171struct cifsUidInfo { 183struct cifsUidInfo {
172 struct list_head userList; 184 struct list_head userList;
@@ -197,11 +209,11 @@ struct cifsSesInfo {
197 int Suid; /* remote smb uid */ 209 int Suid; /* remote smb uid */
198 uid_t linux_uid; /* local Linux uid */ 210 uid_t linux_uid; /* local Linux uid */
199 int capabilities; 211 int capabilities;
200 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for 212 char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
201 TCP names - will ipv6 and sctp addresses fit? */ 213 TCP names - will ipv6 and sctp addresses fit? */
202 char userName[MAX_USERNAME_SIZE + 1]; 214 char userName[MAX_USERNAME_SIZE + 1];
203 char * domainName; 215 char *domainName;
204 char * password; 216 char *password;
205}; 217};
206/* no more than one of the following three session flags may be set */ 218/* no more than one of the following three session flags may be set */
207#define CIFS_SES_NT4 1 219#define CIFS_SES_NT4 1
@@ -213,7 +225,7 @@ struct cifsSesInfo {
213#define CIFS_SES_LANMAN 8 225#define CIFS_SES_LANMAN 8
214/* 226/*
215 * there is one of these for each connection to a resource on a particular 227 * there is one of these for each connection to a resource on a particular
216 * session 228 * session
217 */ 229 */
218struct cifsTconInfo { 230struct cifsTconInfo {
219 struct list_head cifsConnectionList; 231 struct list_head cifsConnectionList;
@@ -269,7 +281,9 @@ struct cifsTconInfo {
269 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 281 FILE_SYSTEM_UNIX_INFO fsUnixInfo;
270 unsigned retry:1; 282 unsigned retry:1;
271 unsigned nocase:1; 283 unsigned nocase:1;
272 /* BB add field for back pointer to sb struct? */ 284 unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
285 for this mount even if server would support */
286 /* BB add field for back pointer to sb struct(s)? */
273}; 287};
274 288
275/* 289/*
@@ -291,9 +305,9 @@ struct cifs_search_info {
291 __u16 entries_in_buffer; 305 __u16 entries_in_buffer;
292 __u16 info_level; 306 __u16 info_level;
293 __u32 resume_key; 307 __u32 resume_key;
294 char * ntwrk_buf_start; 308 char *ntwrk_buf_start;
295 char * srch_entries_start; 309 char *srch_entries_start;
296 char * presume_name; 310 char *presume_name;
297 unsigned int resume_name_len; 311 unsigned int resume_name_len;
298 unsigned endOfSearch:1; 312 unsigned endOfSearch:1;
299 unsigned emptyDir:1; 313 unsigned emptyDir:1;
@@ -309,15 +323,15 @@ struct cifsFileInfo {
309 __u16 netfid; /* file id from remote */ 323 __u16 netfid; /* file id from remote */
310 /* BB add lock scope info here if needed */ ; 324 /* BB add lock scope info here if needed */ ;
311 /* lock scope id (0 if none) */ 325 /* lock scope id (0 if none) */
312 struct file * pfile; /* needed for writepage */ 326 struct file *pfile; /* needed for writepage */
313 struct inode * pInode; /* needed for oplock break */ 327 struct inode *pInode; /* needed for oplock break */
314 struct mutex lock_mutex; 328 struct mutex lock_mutex;
315 struct list_head llist; /* list of byte range locks we have. */ 329 struct list_head llist; /* list of byte range locks we have. */
316 unsigned closePend:1; /* file is marked to close */ 330 unsigned closePend:1; /* file is marked to close */
317 unsigned invalidHandle:1; /* file closed via session abend */ 331 unsigned invalidHandle:1; /* file closed via session abend */
318 atomic_t wrtPending; /* handle in use - defer close */ 332 atomic_t wrtPending; /* handle in use - defer close */
319 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 333 struct semaphore fh_sem; /* prevents reopen race after dead ses*/
320 char * search_resume_name; /* BB removeme BB */ 334 char *search_resume_name; /* BB removeme BB */
321 struct cifs_search_info srch_inf; 335 struct cifs_search_info srch_inf;
322}; 336};
323 337
@@ -327,7 +341,7 @@ struct cifsFileInfo {
327 341
328struct cifsInodeInfo { 342struct cifsInodeInfo {
329 struct list_head lockList; 343 struct list_head lockList;
330 /* BB add in lists for dirty pages - i.e. write caching info for oplock */ 344 /* BB add in lists for dirty pages i.e. write caching info for oplock */
331 struct list_head openFileList; 345 struct list_head openFileList;
332 int write_behind_rc; 346 int write_behind_rc;
333 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 347 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
@@ -381,9 +395,9 @@ static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
381} 395}
382#else 396#else
383 397
384#define cifs_stats_inc(field) do {} while(0) 398#define cifs_stats_inc(field) do {} while (0)
385#define cifs_stats_bytes_written(tcon, bytes) do {} while(0) 399#define cifs_stats_bytes_written(tcon, bytes) do {} while (0)
386#define cifs_stats_bytes_read(tcon, bytes) do {} while(0) 400#define cifs_stats_bytes_read(tcon, bytes) do {} while (0)
387 401
388#endif 402#endif
389 403
@@ -410,8 +424,8 @@ struct mid_q_entry {
410 424
411struct oplock_q_entry { 425struct oplock_q_entry {
412 struct list_head qhead; 426 struct list_head qhead;
413 struct inode * pinode; 427 struct inode *pinode;
414 struct cifsTconInfo * tcon; 428 struct cifsTconInfo *tcon;
415 __u16 netfid; 429 __u16 netfid;
416}; 430};
417 431
@@ -426,7 +440,7 @@ struct dir_notify_req {
426 __u16 netfid; 440 __u16 netfid;
427 __u32 filter; /* CompletionFilter (for multishot) */ 441 __u32 filter; /* CompletionFilter (for multishot) */
428 int multishot; 442 int multishot;
429 struct file * pfile; 443 struct file *pfile;
430}; 444};
431 445
432#define MID_FREE 0 446#define MID_FREE 0
@@ -464,7 +478,7 @@ require use of the stronger protocol */
464#define CIFSSEC_MUST_LANMAN 0x10010 478#define CIFSSEC_MUST_LANMAN 0x10010
465#define CIFSSEC_MUST_PLNTXT 0x20020 479#define CIFSSEC_MUST_PLNTXT 0x20020
466#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ 480#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */
467#else 481#else
468#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */ 482#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */
469#endif /* WEAK_PW_HASH */ 483#endif /* WEAK_PW_HASH */
470#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ 484#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
@@ -502,7 +516,7 @@ require use of the stronger protocol */
502 * ---------- 516 * ----------
503 * sesSem operations on smb session 517 * sesSem operations on smb session
504 * tconSem operations on tree connection 518 * tconSem operations on tree connection
505 * fh_sem file handle reconnection operations 519 * fh_sem file handle reconnection operations
506 * 520 *
507 ****************************************************************************/ 521 ****************************************************************************/
508 522
@@ -515,7 +529,7 @@ require use of the stronger protocol */
515/* 529/*
516 * The list of servers that did not respond with NT LM 0.12. 530 * The list of servers that did not respond with NT LM 0.12.
517 * This list helps improve performance and eliminate the messages indicating 531 * This list helps improve performance and eliminate the messages indicating
518 * that we had a communications error talking to the server in this list. 532 * that we had a communications error talking to the server in this list.
519 */ 533 */
520/* Feature not supported */ 534/* Feature not supported */
521/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */ 535/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
@@ -568,12 +582,12 @@ GLOBAL_EXTERN atomic_t midCount;
568/* Misc globals */ 582/* Misc globals */
569GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions 583GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
570 to be established on existing mount if we 584 to be established on existing mount if we
571 have the uid/password or Kerberos credential 585 have the uid/password or Kerberos credential
572 or equivalent for current user */ 586 or equivalent for current user */
573GLOBAL_EXTERN unsigned int oplockEnabled; 587GLOBAL_EXTERN unsigned int oplockEnabled;
574GLOBAL_EXTERN unsigned int experimEnabled; 588GLOBAL_EXTERN unsigned int experimEnabled;
575GLOBAL_EXTERN unsigned int lookupCacheEnabled; 589GLOBAL_EXTERN unsigned int lookupCacheEnabled;
576GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 590GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
577 with more secure ntlmssp2 challenge/resp */ 591 with more secure ntlmssp2 challenge/resp */
578GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 592GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
579GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 593GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index d619ca7d1416..6a2056e58ceb 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -144,7 +144,7 @@
144#define SMBOPEN_OAPPEND 0x0001 144#define SMBOPEN_OAPPEND 0x0001
145 145
146/* 146/*
147 * SMB flag definitions 147 * SMB flag definitions
148 */ 148 */
149#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */ 149#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */
150#define SMBFLG_RCV_POSTED 0x02 /* obsolete */ 150#define SMBFLG_RCV_POSTED 0x02 /* obsolete */
@@ -157,9 +157,9 @@
157#define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */ 157#define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */
158 158
159/* 159/*
160 * SMB flag2 definitions 160 * SMB flag2 definitions
161 */ 161 */
162#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) 162#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3)
163 path names in response */ 163 path names in response */
164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2) 164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) 165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
@@ -260,7 +260,7 @@
260#define ATTR_SPARSE 0x0200 260#define ATTR_SPARSE 0x0200
261#define ATTR_REPARSE 0x0400 261#define ATTR_REPARSE 0x0400
262#define ATTR_COMPRESSED 0x0800 262#define ATTR_COMPRESSED 0x0800
263#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - 263#define ATTR_OFFLINE 0x1000 /* ie file not immediately available -
264 on offline storage */ 264 on offline storage */
265#define ATTR_NOT_CONTENT_INDEXED 0x2000 265#define ATTR_NOT_CONTENT_INDEXED 0x2000
266#define ATTR_ENCRYPTED 0x4000 266#define ATTR_ENCRYPTED 0x4000
@@ -300,7 +300,7 @@
300#define CREATE_DELETE_ON_CLOSE 0x00001000 300#define CREATE_DELETE_ON_CLOSE 0x00001000
301#define CREATE_OPEN_BY_ID 0x00002000 301#define CREATE_OPEN_BY_ID 0x00002000
302#define OPEN_REPARSE_POINT 0x00200000 302#define OPEN_REPARSE_POINT 0x00200000
303#define CREATE_OPTIONS_MASK 0x007FFFFF 303#define CREATE_OPTIONS_MASK 0x007FFFFF
304#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ 304#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
305 305
306/* ImpersonationLevel flags */ 306/* ImpersonationLevel flags */
@@ -366,17 +366,19 @@ struct smb_hdr {
366#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) 366#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
367 367
368/* 368/*
369 * Computer Name Length 369 * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
370 * No longer as important, now that TCP names are more commonly used to
371 * resolve hosts.
370 */ 372 */
371#define CNLEN 15 373#define CNLEN 15
372 374
373/* 375/*
374 * Share Name Length @S8A 376 * Share Name Length (SNLEN)
375 * Note: This length is limited by the SMB used to get @S8A 377 * Note: This length was limited by the SMB used to get
376 * the Share info. NetShareEnum only returns 13 @S8A 378 * the Share info. NetShareEnum only returned 13
377 * chars, including the null termination. @S8A 379 * chars, including the null termination.
380 * This was removed because it no longer is limiting.
378 */ 381 */
379#define SNLEN 12 /*@S8A */
380 382
381/* 383/*
382 * Comment Length 384 * Comment Length
@@ -394,8 +396,8 @@ struct smb_hdr {
394 * 396 *
395 * The Naming convention is the lower case version of the 397 * The Naming convention is the lower case version of the
396 * smb command code name for the struct and this is typedef to the 398 * smb command code name for the struct and this is typedef to the
397 * uppercase version of the same name with the prefix SMB_ removed 399 * uppercase version of the same name with the prefix SMB_ removed
398 * for brevity. Although typedefs are not commonly used for 400 * for brevity. Although typedefs are not commonly used for
399 * structure definitions in the Linux kernel, their use in the 401 * structure definitions in the Linux kernel, their use in the
400 * CIFS standards document, which this code is based on, may 402 * CIFS standards document, which this code is based on, may
401 * make this one of the cases where typedefs for structures make 403 * make this one of the cases where typedefs for structures make
@@ -403,7 +405,7 @@ struct smb_hdr {
403 * Typedefs can always be removed later if they are too distracting 405 * Typedefs can always be removed later if they are too distracting
404 * and they are only used for the CIFSs PDUs themselves, not 406 * and they are only used for the CIFSs PDUs themselves, not
405 * internal cifs vfs structures 407 * internal cifs vfs structures
406 * 408 *
407 */ 409 */
408 410
409typedef struct negotiate_req { 411typedef struct negotiate_req {
@@ -511,7 +513,7 @@ typedef union smb_com_session_setup_andx {
511 unsigned char SecurityBlob[1]; /* followed by */ 513 unsigned char SecurityBlob[1]; /* followed by */
512 /* STRING NativeOS */ 514 /* STRING NativeOS */
513 /* STRING NativeLanMan */ 515 /* STRING NativeLanMan */
514 } __attribute__((packed)) req; /* NTLM request format (with 516 } __attribute__((packed)) req; /* NTLM request format (with
515 extended security */ 517 extended security */
516 518
517 struct { /* request format */ 519 struct { /* request format */
@@ -549,7 +551,7 @@ typedef union smb_com_session_setup_andx {
549/* unsigned char * NativeOS; */ 551/* unsigned char * NativeOS; */
550/* unsigned char * NativeLanMan; */ 552/* unsigned char * NativeLanMan; */
551/* unsigned char * PrimaryDomain; */ 553/* unsigned char * PrimaryDomain; */
552 } __attribute__((packed)) resp; /* NTLM response 554 } __attribute__((packed)) resp; /* NTLM response
553 (with or without extended sec) */ 555 (with or without extended sec) */
554 556
555 struct { /* request format */ 557 struct { /* request format */
@@ -618,7 +620,7 @@ struct ntlmv2_resp {
618#define CAP_NT_SMBS 0x00000010 620#define CAP_NT_SMBS 0x00000010
619#define CAP_STATUS32 0x00000040 621#define CAP_STATUS32 0x00000040
620#define CAP_LEVEL_II_OPLOCKS 0x00000080 622#define CAP_LEVEL_II_OPLOCKS 0x00000080
621#define CAP_NT_FIND 0x00000200 /* reserved should be zero 623#define CAP_NT_FIND 0x00000200 /* reserved should be zero
622 (because NT_SMBs implies the same thing?) */ 624 (because NT_SMBs implies the same thing?) */
623#define CAP_BULK_TRANSFER 0x20000000 625#define CAP_BULK_TRANSFER 0x20000000
624#define CAP_EXTENDED_SECURITY 0x80000000 626#define CAP_EXTENDED_SECURITY 0x80000000
@@ -676,7 +678,7 @@ typedef struct smb_com_logoff_andx_rsp {
676 __u16 ByteCount; 678 __u16 ByteCount;
677} __attribute__((packed)) LOGOFF_ANDX_RSP; 679} __attribute__((packed)) LOGOFF_ANDX_RSP;
678 680
679typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on 681typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
680 tree_connect PDU to effect disconnect */ 682 tree_connect PDU to effect disconnect */
681 /* tdis is probably simplest SMB PDU */ 683 /* tdis is probably simplest SMB PDU */
682 struct { 684 struct {
@@ -712,6 +714,7 @@ typedef struct smb_com_findclose_req {
712#define REQ_OPLOCK 0x00000002 714#define REQ_OPLOCK 0x00000002
713#define REQ_BATCHOPLOCK 0x00000004 715#define REQ_BATCHOPLOCK 0x00000004
714#define REQ_OPENDIRONLY 0x00000008 716#define REQ_OPENDIRONLY 0x00000008
717#define REQ_EXTENDED_INFO 0x00000010
715 718
716typedef struct smb_com_open_req { /* also handles create */ 719typedef struct smb_com_open_req { /* also handles create */
717 struct smb_hdr hdr; /* wct = 24 */ 720 struct smb_hdr hdr; /* wct = 24 */
@@ -799,27 +802,28 @@ typedef struct smb_com_openx_rsp {
799 __u32 FileId; 802 __u32 FileId;
800 __u16 Reserved; 803 __u16 Reserved;
801 __u16 ByteCount; 804 __u16 ByteCount;
802} __attribute__((packed)) OPENX_RSP; 805} __attribute__((packed)) OPENX_RSP;
803 806
804/* For encoding of POSIX Open Request - see trans2 function 0x209 data struct */ 807/* For encoding of POSIX Open Request - see trans2 function 0x209 data struct */
805 808
806/* Legacy write request for older servers */ 809/* Legacy write request for older servers */
807typedef struct smb_com_writex_req { 810typedef struct smb_com_writex_req {
808 struct smb_hdr hdr; /* wct = 12 */ 811 struct smb_hdr hdr; /* wct = 12 */
809 __u8 AndXCommand; 812 __u8 AndXCommand;
810 __u8 AndXReserved; 813 __u8 AndXReserved;
811 __le16 AndXOffset; 814 __le16 AndXOffset;
812 __u16 Fid; 815 __u16 Fid;
813 __le32 OffsetLow; 816 __le32 OffsetLow;
814 __u32 Reserved; /* Timeout */ 817 __u32 Reserved; /* Timeout */
815 __le16 WriteMode; /* 1 = write through */ 818 __le16 WriteMode; /* 1 = write through */
816 __le16 Remaining; 819 __le16 Remaining;
817 __le16 Reserved2; 820 __le16 Reserved2;
818 __le16 DataLengthLow; 821 __le16 DataLengthLow;
819 __le16 DataOffset; 822 __le16 DataOffset;
820 __le16 ByteCount; 823 __le16 ByteCount;
821 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 824 __u8 Pad; /* BB check for whether padded to DWORD
822 char Data[0]; 825 boundary and optimum performance here */
826 char Data[0];
823} __attribute__((packed)) WRITEX_REQ; 827} __attribute__((packed)) WRITEX_REQ;
824 828
825typedef struct smb_com_write_req { 829typedef struct smb_com_write_req {
@@ -837,7 +841,8 @@ typedef struct smb_com_write_req {
837 __le16 DataOffset; 841 __le16 DataOffset;
838 __le32 OffsetHigh; 842 __le32 OffsetHigh;
839 __le16 ByteCount; 843 __le16 ByteCount;
840 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 844 __u8 Pad; /* BB check for whether padded to DWORD
845 boundary and optimum performance here */
841 char Data[0]; 846 char Data[0];
842} __attribute__((packed)) WRITE_REQ; 847} __attribute__((packed)) WRITE_REQ;
843 848
@@ -855,17 +860,17 @@ typedef struct smb_com_write_rsp {
855 860
856/* legacy read request for older servers */ 861/* legacy read request for older servers */
857typedef struct smb_com_readx_req { 862typedef struct smb_com_readx_req {
858 struct smb_hdr hdr; /* wct = 10 */ 863 struct smb_hdr hdr; /* wct = 10 */
859 __u8 AndXCommand; 864 __u8 AndXCommand;
860 __u8 AndXReserved; 865 __u8 AndXReserved;
861 __le16 AndXOffset; 866 __le16 AndXOffset;
862 __u16 Fid; 867 __u16 Fid;
863 __le32 OffsetLow; 868 __le32 OffsetLow;
864 __le16 MaxCount; 869 __le16 MaxCount;
865 __le16 MinCount; /* obsolete */ 870 __le16 MinCount; /* obsolete */
866 __le32 Reserved; 871 __le32 Reserved;
867 __le16 Remaining; 872 __le16 Remaining;
868 __le16 ByteCount; 873 __le16 ByteCount;
869} __attribute__((packed)) READX_REQ; 874} __attribute__((packed)) READX_REQ;
870 875
871typedef struct smb_com_read_req { 876typedef struct smb_com_read_req {
@@ -896,7 +901,8 @@ typedef struct smb_com_read_rsp {
896 __le16 DataLengthHigh; 901 __le16 DataLengthHigh;
897 __u64 Reserved2; 902 __u64 Reserved2;
898 __u16 ByteCount; 903 __u16 ByteCount;
899 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 904 __u8 Pad; /* BB check for whether padded to DWORD
905 boundary and optimum performance here */
900 char Data[1]; 906 char Data[1];
901} __attribute__((packed)) READ_RSP; 907} __attribute__((packed)) READ_RSP;
902 908
@@ -967,7 +973,7 @@ typedef struct smb_com_rename_req {
967#define COPY_TARGET_MODE_ASCII 0x0004 /* if not set, binary */ 973#define COPY_TARGET_MODE_ASCII 0x0004 /* if not set, binary */
968#define COPY_SOURCE_MODE_ASCII 0x0008 /* if not set, binary */ 974#define COPY_SOURCE_MODE_ASCII 0x0008 /* if not set, binary */
969#define COPY_VERIFY_WRITES 0x0010 975#define COPY_VERIFY_WRITES 0x0010
970#define COPY_TREE 0x0020 976#define COPY_TREE 0x0020
971 977
972typedef struct smb_com_copy_req { 978typedef struct smb_com_copy_req {
973 struct smb_hdr hdr; /* wct = 3 */ 979 struct smb_hdr hdr; /* wct = 3 */
@@ -975,7 +981,7 @@ typedef struct smb_com_copy_req {
975 __le16 OpenFunction; 981 __le16 OpenFunction;
976 __le16 Flags; 982 __le16 Flags;
977 __le16 ByteCount; 983 __le16 ByteCount;
978 __u8 BufferFormat; /* 4 = ASCII or Unicode */ 984 __u8 BufferFormat; /* 4 = ASCII or Unicode */
979 unsigned char OldFileName[1]; 985 unsigned char OldFileName[1];
980 /* followed by __u8 BufferFormat2 */ 986 /* followed by __u8 BufferFormat2 */
981 /* followed by NewFileName string */ 987 /* followed by NewFileName string */
@@ -1083,28 +1089,28 @@ typedef struct smb_com_setattr_rsp {
1083 1089
1084/*******************************************************/ 1090/*******************************************************/
1085/* NT Transact structure defintions follow */ 1091/* NT Transact structure defintions follow */
1086/* Currently only ioctl, acl (get security descriptor) */ 1092/* Currently only ioctl, acl (get security descriptor) */
1087/* and notify are implemented */ 1093/* and notify are implemented */
1088/*******************************************************/ 1094/*******************************************************/
1089typedef struct smb_com_ntransact_req { 1095typedef struct smb_com_ntransact_req {
1090 struct smb_hdr hdr; /* wct >= 19 */ 1096 struct smb_hdr hdr; /* wct >= 19 */
1091 __u8 MaxSetupCount; 1097 __u8 MaxSetupCount;
1092 __u16 Reserved; 1098 __u16 Reserved;
1093 __le32 TotalParameterCount; 1099 __le32 TotalParameterCount;
1094 __le32 TotalDataCount; 1100 __le32 TotalDataCount;
1095 __le32 MaxParameterCount; 1101 __le32 MaxParameterCount;
1096 __le32 MaxDataCount; 1102 __le32 MaxDataCount;
1097 __le32 ParameterCount; 1103 __le32 ParameterCount;
1098 __le32 ParameterOffset; 1104 __le32 ParameterOffset;
1099 __le32 DataCount; 1105 __le32 DataCount;
1100 __le32 DataOffset; 1106 __le32 DataOffset;
1101 __u8 SetupCount; /* four setup words follow subcommand */ 1107 __u8 SetupCount; /* four setup words follow subcommand */
1102 /* SNIA spec incorrectly included spurious pad here */ 1108 /* SNIA spec incorrectly included spurious pad here */
1103 __le16 SubCommand; /* 2 = IOCTL/FSCTL */ 1109 __le16 SubCommand; /* 2 = IOCTL/FSCTL */
1104 /* SetupCount words follow then */ 1110 /* SetupCount words follow then */
1105 __le16 ByteCount; 1111 __le16 ByteCount;
1106 __u8 Pad[3]; 1112 __u8 Pad[3];
1107 __u8 Parms[0]; 1113 __u8 Parms[0];
1108} __attribute__((packed)) NTRANSACT_REQ; 1114} __attribute__((packed)) NTRANSACT_REQ;
1109 1115
1110typedef struct smb_com_ntransact_rsp { 1116typedef struct smb_com_ntransact_rsp {
@@ -1120,7 +1126,7 @@ typedef struct smb_com_ntransact_rsp {
1120 __le32 DataDisplacement; 1126 __le32 DataDisplacement;
1121 __u8 SetupCount; /* 0 */ 1127 __u8 SetupCount; /* 0 */
1122 __u16 ByteCount; 1128 __u16 ByteCount;
1123 /* __u8 Pad[3]; */ 1129 /* __u8 Pad[3]; */
1124 /* parms and data follow */ 1130 /* parms and data follow */
1125} __attribute__((packed)) NTRANSACT_RSP; 1131} __attribute__((packed)) NTRANSACT_RSP;
1126 1132
@@ -1215,7 +1221,7 @@ typedef struct smb_com_transaction_change_notify_req {
1215/* __u8 Data[1];*/ 1221/* __u8 Data[1];*/
1216} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; 1222} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
1217 1223
1218/* BB eventually change to use generic ntransact rsp struct 1224/* BB eventually change to use generic ntransact rsp struct
1219 and validation routine */ 1225 and validation routine */
1220typedef struct smb_com_transaction_change_notify_rsp { 1226typedef struct smb_com_transaction_change_notify_rsp {
1221 struct smb_hdr hdr; /* wct = 18 */ 1227 struct smb_hdr hdr; /* wct = 18 */
@@ -1262,7 +1268,7 @@ struct file_notify_information {
1262 __le32 Action; 1268 __le32 Action;
1263 __le32 FileNameLength; 1269 __le32 FileNameLength;
1264 __u8 FileName[0]; 1270 __u8 FileName[0];
1265} __attribute__((packed)); 1271} __attribute__((packed));
1266 1272
1267struct reparse_data { 1273struct reparse_data {
1268 __u32 ReparseTag; 1274 __u32 ReparseTag;
@@ -1331,7 +1337,7 @@ struct trans2_resp {
1331 __u8 Reserved1; 1337 __u8 Reserved1;
1332 /* SetupWords[SetupCount]; 1338 /* SetupWords[SetupCount];
1333 __u16 ByteCount; 1339 __u16 ByteCount;
1334 __u16 Reserved2;*/ 1340 __u16 Reserved2;*/
1335 /* data area follows */ 1341 /* data area follows */
1336} __attribute__((packed)); 1342} __attribute__((packed));
1337 1343
@@ -1370,9 +1376,9 @@ struct smb_t2_rsp {
1370#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee 1376#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee
1371#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 1377#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0
1372#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ 1378#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */
1373#define SMB_QUERY_FILE_POSITION_INFO 0x3f6 1379#define SMB_QUERY_FILE_POSITION_INFO 0x3f6
1374#define SMB_QUERY_FILE_MODE_INFO 0x3f8 1380#define SMB_QUERY_FILE_MODE_INFO 0x3f8
1375#define SMB_QUERY_FILE_ALGN_INFO 0x3f9 1381#define SMB_QUERY_FILE_ALGN_INFO 0x3f9
1376 1382
1377 1383
1378#define SMB_SET_FILE_BASIC_INFO 0x101 1384#define SMB_SET_FILE_BASIC_INFO 0x101
@@ -1506,35 +1512,35 @@ struct smb_com_transaction2_sfi_req {
1506 __u16 Pad1; 1512 __u16 Pad1;
1507 __u16 Fid; 1513 __u16 Fid;
1508 __le16 InformationLevel; 1514 __le16 InformationLevel;
1509 __u16 Reserved4; 1515 __u16 Reserved4;
1510} __attribute__((packed)); 1516} __attribute__((packed));
1511 1517
1512struct smb_com_transaction2_sfi_rsp { 1518struct smb_com_transaction2_sfi_rsp {
1513 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1519 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1514 struct trans2_resp t2; 1520 struct trans2_resp t2;
1515 __u16 ByteCount; 1521 __u16 ByteCount;
1516 __u16 Reserved2; /* parameter word reserved - 1522 __u16 Reserved2; /* parameter word reserved -
1517 present for infolevels > 100 */ 1523 present for infolevels > 100 */
1518} __attribute__((packed)); 1524} __attribute__((packed));
1519 1525
1520struct smb_t2_qfi_req { 1526struct smb_t2_qfi_req {
1521 struct smb_hdr hdr; 1527 struct smb_hdr hdr;
1522 struct trans2_req t2; 1528 struct trans2_req t2;
1523 __u8 Pad; 1529 __u8 Pad;
1524 __u16 Fid; 1530 __u16 Fid;
1525 __le16 InformationLevel; 1531 __le16 InformationLevel;
1526} __attribute__((packed)); 1532} __attribute__((packed));
1527 1533
1528struct smb_t2_qfi_rsp { 1534struct smb_t2_qfi_rsp {
1529 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1535 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1530 struct trans2_resp t2; 1536 struct trans2_resp t2;
1531 __u16 ByteCount; 1537 __u16 ByteCount;
1532 __u16 Reserved2; /* parameter word reserved - 1538 __u16 Reserved2; /* parameter word reserved -
1533 present for infolevels > 100 */ 1539 present for infolevels > 100 */
1534} __attribute__((packed)); 1540} __attribute__((packed));
1535 1541
1536/* 1542/*
1537 * Flags on T2 FINDFIRST and FINDNEXT 1543 * Flags on T2 FINDFIRST and FINDNEXT
1538 */ 1544 */
1539#define CIFS_SEARCH_CLOSE_ALWAYS 0x0001 1545#define CIFS_SEARCH_CLOSE_ALWAYS 0x0001
1540#define CIFS_SEARCH_CLOSE_AT_END 0x0002 1546#define CIFS_SEARCH_CLOSE_AT_END 0x0002
@@ -1743,7 +1749,9 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
1743 __u8 Reserved3; 1749 __u8 Reserved3;
1744 __le16 SubCommand; /* one setup word */ 1750 __le16 SubCommand; /* one setup word */
1745 __le16 ByteCount; 1751 __le16 ByteCount;
1746 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */ 1752 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max response length
1753 perhaps?) followed by one byte pad - doesn't
1754 seem to matter though */
1747 __le16 MaxReferralLevel; 1755 __le16 MaxReferralLevel;
1748 char RequestFileName[1]; 1756 char RequestFileName[1];
1749} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ; 1757} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
@@ -1752,7 +1760,10 @@ typedef struct dfs_referral_level_3 {
1752 __le16 VersionNumber; 1760 __le16 VersionNumber;
1753 __le16 ReferralSize; 1761 __le16 ReferralSize;
1754 __le16 ServerType; /* 0x0001 = CIFS server */ 1762 __le16 ServerType; /* 0x0001 = CIFS server */
1755 __le16 ReferralFlags; /* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */ 1763 __le16 ReferralFlags; /* or proximity - not clear which since it is
1764 always set to zero - SNIA spec says 0x01
1765 means strip off PathConsumed chars before
1766 submitting RequestFileName to remote node */
1756 __le16 TimeToLive; 1767 __le16 TimeToLive;
1757 __le16 Proximity; 1768 __le16 Proximity;
1758 __le16 DfsPathOffset; 1769 __le16 DfsPathOffset;
@@ -1778,11 +1789,13 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
1778#define DFSREF_STORAGE_SERVER 0x0002 1789#define DFSREF_STORAGE_SERVER 0x0002
1779 1790
1780/* IOCTL information */ 1791/* IOCTL information */
1781/* List of ioctl function codes that look to be of interest to remote clients like this. */ 1792/*
1782/* Need to do some experimentation to make sure they all work remotely. */ 1793 * List of ioctl function codes that look to be of interest to remote clients
1783/* Some of the following such as the encryption/compression ones would be */ 1794 * like this one. Need to do some experimentation to make sure they all work
1784/* invoked from tools via a specialized hook into the VFS rather than via the */ 1795 * remotely. Some of the following, such as the encryption/compression ones
1785/* standard vfs entry points */ 1796 * would be invoked from tools via a specialized hook into the VFS rather
1797 * than via the standard vfs entry points
1798 */
1786#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000 1799#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000
1787#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004 1800#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004
1788#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008 1801#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008
@@ -1811,7 +1824,7 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
1811/* 1824/*
1812 ************************************************************************ 1825 ************************************************************************
1813 * All structs for everything above the SMB PDUs themselves 1826 * All structs for everything above the SMB PDUs themselves
1814 * (such as the T2 level specific data) go here 1827 * (such as the T2 level specific data) go here
1815 ************************************************************************ 1828 ************************************************************************
1816 */ 1829 */
1817 1830
@@ -1857,7 +1870,7 @@ typedef struct {
1857 __le64 FreeAllocationUnits; 1870 __le64 FreeAllocationUnits;
1858 __le32 SectorsPerAllocationUnit; 1871 __le32 SectorsPerAllocationUnit;
1859 __le32 BytesPerSector; 1872 __le32 BytesPerSector;
1860} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */ 1873} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */
1861 1874
1862typedef struct { 1875typedef struct {
1863 __le32 fsid; 1876 __le32 fsid;
@@ -1871,7 +1884,7 @@ typedef struct {
1871 __le16 MajorVersionNumber; 1884 __le16 MajorVersionNumber;
1872 __le16 MinorVersionNumber; 1885 __le16 MinorVersionNumber;
1873 __le64 Capability; 1886 __le64 Capability;
1874} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ 1887} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extension level 0x200*/
1875 1888
1876/* Version numbers for CIFS UNIX major and minor. */ 1889/* Version numbers for CIFS UNIX major and minor. */
1877#define CIFS_UNIX_MAJOR_VERSION 1 1890#define CIFS_UNIX_MAJOR_VERSION 1
@@ -1885,16 +1898,20 @@ typedef struct {
1885#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */ 1898#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
1886#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based 1899#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based
1887 calls including posix open 1900 calls including posix open
1888 and posix unlink */ 1901 and posix unlink */
1902#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
1903 to 0xFFFF00 */
1904#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
1905
1889#ifdef CONFIG_CIFS_POSIX 1906#ifdef CONFIG_CIFS_POSIX
1890/* Can not set pathnames cap yet until we send new posix create SMB since 1907/* Can not set pathnames cap yet until we send new posix create SMB since
1891 otherwise server can treat such handles opened with older ntcreatex 1908 otherwise server can treat such handles opened with older ntcreatex
1892 (by a new client which knows how to send posix path ops) 1909 (by a new client which knows how to send posix path ops)
1893 as non-posix handles (can affect write behavior with byte range locks. 1910 as non-posix handles (can affect write behavior with byte range locks.
1894 We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ 1911 We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */
1895/* #define CIFS_UNIX_CAP_MASK 0x0000003b */ 1912/* #define CIFS_UNIX_CAP_MASK 0x000000fb */
1896#define CIFS_UNIX_CAP_MASK 0x0000001b 1913#define CIFS_UNIX_CAP_MASK 0x000000db
1897#else 1914#else
1898#define CIFS_UNIX_CAP_MASK 0x00000013 1915#define CIFS_UNIX_CAP_MASK 0x00000013
1899#endif /* CONFIG_CIFS_POSIX */ 1916#endif /* CONFIG_CIFS_POSIX */
1900 1917
@@ -1904,10 +1921,10 @@ typedef struct {
1904typedef struct { 1921typedef struct {
1905 /* For undefined recommended transfer size return -1 in that field */ 1922 /* For undefined recommended transfer size return -1 in that field */
1906 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ 1923 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
1907 __le32 BlockSize; 1924 __le32 BlockSize;
1908 /* The next three fields are in terms of the block size. 1925 /* The next three fields are in terms of the block size.
1909 (above). If block size is unknown, 4096 would be a 1926 (above). If block size is unknown, 4096 would be a
1910 reasonable block size for a server to report. 1927 reasonable block size for a server to report.
1911 Note that returning the blocks/blocksavail removes need 1928 Note that returning the blocks/blocksavail removes need
1912 to make a second call (to QFSInfo level 0x103 to get this info. 1929 to make a second call (to QFSInfo level 0x103 to get this info.
1913 UserBlockAvail is typically less than or equal to BlocksAvail, 1930 UserBlockAvail is typically less than or equal to BlocksAvail,
@@ -2062,9 +2079,9 @@ struct file_alt_name_info {
2062 2079
2063struct file_stream_info { 2080struct file_stream_info {
2064 __le32 number_of_streams; /* BB check sizes and verify location */ 2081 __le32 number_of_streams; /* BB check sizes and verify location */
2065 /* followed by info on streams themselves 2082 /* followed by info on streams themselves
2066 u64 size; 2083 u64 size;
2067 u64 allocation_size 2084 u64 allocation_size
2068 stream info */ 2085 stream info */
2069}; /* level 0x109 */ 2086}; /* level 0x109 */
2070 2087
@@ -2083,7 +2100,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
2083 __u8 cifs_e_tag; 2100 __u8 cifs_e_tag;
2084 __u8 cifs_e_perm; 2101 __u8 cifs_e_perm;
2085 __le64 cifs_uid; /* or gid */ 2102 __le64 cifs_uid; /* or gid */
2086} __attribute__((packed)); 2103} __attribute__((packed));
2087 2104
2088struct cifs_posix_acl { /* access conrol list (ACL) */ 2105struct cifs_posix_acl { /* access conrol list (ACL) */
2089 __le16 version; 2106 __le16 version;
@@ -2138,6 +2155,12 @@ typedef struct {
2138 /* struct following varies based on requested level */ 2155 /* struct following varies based on requested level */
2139} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */ 2156} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */
2140 2157
2158#define SMB_POSIX_UNLINK_FILE_TARGET 0
2159#define SMB_POSIX_UNLINK_DIRECTORY_TARGET 1
2160
2161struct unlink_psx_rq { /* level 0x20a SetPathInfo */
2162 __le16 type;
2163} __attribute__((packed));
2141 2164
2142struct file_internal_info { 2165struct file_internal_info {
2143 __u64 UniqueId; /* inode number */ 2166 __u64 UniqueId; /* inode number */
@@ -2154,7 +2177,7 @@ struct file_attrib_tag {
2154 2177
2155 2178
2156/********************************************************/ 2179/********************************************************/
2157/* FindFirst/FindNext transact2 data buffer formats */ 2180/* FindFirst/FindNext transact2 data buffer formats */
2158/********************************************************/ 2181/********************************************************/
2159 2182
2160typedef struct { 2183typedef struct {
@@ -2232,7 +2255,7 @@ typedef struct {
2232 __le64 EndOfFile; 2255 __le64 EndOfFile;
2233 __le64 AllocationSize; 2256 __le64 AllocationSize;
2234 __le32 ExtFileAttributes; 2257 __le32 ExtFileAttributes;
2235 __le32 FileNameLength; 2258 __le32 FileNameLength;
2236 __le32 EaSize; /* length of the xattrs */ 2259 __le32 EaSize; /* length of the xattrs */
2237 __u8 ShortNameLength; 2260 __u8 ShortNameLength;
2238 __u8 Reserved; 2261 __u8 Reserved;
@@ -2259,7 +2282,7 @@ typedef struct {
2259struct win_dev { 2282struct win_dev {
2260 unsigned char type[8]; /* IntxCHR or IntxBLK */ 2283 unsigned char type[8]; /* IntxCHR or IntxBLK */
2261 __le64 major; 2284 __le64 major;
2262 __le64 minor; 2285 __le64 minor;
2263} __attribute__((packed)); 2286} __attribute__((packed));
2264 2287
2265struct gea { 2288struct gea {
@@ -2291,36 +2314,36 @@ struct fealist {
2291struct data_blob { 2314struct data_blob {
2292 __u8 *data; 2315 __u8 *data;
2293 size_t length; 2316 size_t length;
2294 void (*free) (struct data_blob * data_blob); 2317 void (*free) (struct data_blob *data_blob);
2295} __attribute__((packed)); 2318} __attribute__((packed));
2296 2319
2297 2320
2298#ifdef CONFIG_CIFS_POSIX 2321#ifdef CONFIG_CIFS_POSIX
2299/* 2322/*
2300 For better POSIX semantics from Linux client, (even better 2323 For better POSIX semantics from Linux client, (even better
2301 than the existing CIFS Unix Extensions) we need updated PDUs for: 2324 than the existing CIFS Unix Extensions) we need updated PDUs for:
2302 2325
2303 1) PosixCreateX - to set and return the mode, inode#, device info and 2326 1) PosixCreateX - to set and return the mode, inode#, device info and
2304 perhaps add a CreateDevice - to create Pipes and other special .inodes 2327 perhaps add a CreateDevice - to create Pipes and other special .inodes
2305 Also note POSIX open flags 2328 Also note POSIX open flags
2306 2) Close - to return the last write time to do cache across close 2329 2) Close - to return the last write time to do cache across close
2307 more safely 2330 more safely
2308 3) FindFirst return unique inode number - what about resume key, two 2331 3) FindFirst return unique inode number - what about resume key, two
2309 forms short (matches readdir) and full (enough info to cache inodes) 2332 forms short (matches readdir) and full (enough info to cache inodes)
2310 4) Mkdir - set mode 2333 4) Mkdir - set mode
2311 2334
2312 And under consideration: 2335 And under consideration:
2313 5) FindClose2 (return nanosecond timestamp ??) 2336 5) FindClose2 (return nanosecond timestamp ??)
2314 6) Use nanosecond timestamps throughout all time fields if 2337 6) Use nanosecond timestamps throughout all time fields if
2315 corresponding attribute flag is set 2338 corresponding attribute flag is set
2316 7) sendfile - handle based copy 2339 7) sendfile - handle based copy
2317 8) Direct i/o 2340 8) Direct i/o
2318 9) Misc fcntls? 2341 9) Misc fcntls?
2319 2342
2320 what about fixing 64 bit alignment 2343 what about fixing 64 bit alignment
2321 2344
2322 There are also various legacy SMB/CIFS requests used as is 2345 There are also various legacy SMB/CIFS requests used as is
2323 2346
2324 From existing Lanman and NTLM dialects: 2347 From existing Lanman and NTLM dialects:
2325 -------------------------------------- 2348 --------------------------------------
2326 NEGOTIATE 2349 NEGOTIATE
@@ -2341,48 +2364,48 @@ struct data_blob {
2341 (BB verify that never need to set allocation size) 2364 (BB verify that never need to set allocation size)
2342 SMB_SET_FILE_BASIC_INFO2 (setting times - BB can it be done via 2365 SMB_SET_FILE_BASIC_INFO2 (setting times - BB can it be done via
2343 Unix ext?) 2366 Unix ext?)
2344 2367
2345 COPY (note support for copy across directories) - FUTURE, OPTIONAL 2368 COPY (note support for copy across directories) - FUTURE, OPTIONAL
2346 setting/getting OS/2 EAs - FUTURE (BB can this handle 2369 setting/getting OS/2 EAs - FUTURE (BB can this handle
2347 setting Linux xattrs perfectly) - OPTIONAL 2370 setting Linux xattrs perfectly) - OPTIONAL
2348 dnotify - FUTURE, OPTIONAL 2371 dnotify - FUTURE, OPTIONAL
2349 quota - FUTURE, OPTIONAL 2372 quota - FUTURE, OPTIONAL
2350 2373
2351 Note that various requests implemented for NT interop such as 2374 Note that various requests implemented for NT interop such as
2352 NT_TRANSACT (IOCTL) QueryReparseInfo 2375 NT_TRANSACT (IOCTL) QueryReparseInfo
2353 are unneeded to servers compliant with the CIFS POSIX extensions 2376 are unneeded to servers compliant with the CIFS POSIX extensions
2354 2377
2355 From CIFS Unix Extensions: 2378 From CIFS Unix Extensions:
2356 ------------------------- 2379 -------------------------
2357 T2 SET_PATH_INFO (SMB_SET_FILE_UNIX_LINK) for symlinks 2380 T2 SET_PATH_INFO (SMB_SET_FILE_UNIX_LINK) for symlinks
2358 T2 SET_PATH_INFO (SMB_SET_FILE_BASIC_INFO2) 2381 T2 SET_PATH_INFO (SMB_SET_FILE_BASIC_INFO2)
2359 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_LINK) 2382 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_LINK)
2360 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_BASIC) - BB check for missing inode fields 2383 T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_BASIC) BB check for missing
2361 Actually need QUERY_FILE_UNIX_INFO since has inode num 2384 inode fields
2362 BB what about a) blksize/blkbits/blocks 2385 Actually a need QUERY_FILE_UNIX_INFO
2386 since has inode num
2387 BB what about a) blksize/blkbits/blocks
2363 b) i_version 2388 b) i_version
2364 c) i_rdev 2389 c) i_rdev
2365 d) notify mask? 2390 d) notify mask?
2366 e) generation 2391 e) generation
2367 f) size_seqcount 2392 f) size_seqcount
2368 T2 FIND_FIRST/FIND_NEXT FIND_FILE_UNIX 2393 T2 FIND_FIRST/FIND_NEXT FIND_FILE_UNIX
2369 TRANS2_GET_DFS_REFERRAL - OPTIONAL but recommended 2394 TRANS2_GET_DFS_REFERRAL - OPTIONAL but recommended
2370 T2_QFS_INFO QueryDevice/AttributeInfo - OPTIONAL 2395 T2_QFS_INFO QueryDevice/AttributeInfo - OPTIONAL
2371
2372
2373 */ 2396 */
2374 2397
2375/* xsymlink is a symlink format (used by MacOS) that can be used 2398/* xsymlink is a symlink format (used by MacOS) that can be used
2376 to save symlink info in a regular file when 2399 to save symlink info in a regular file when
2377 mounted to operating systems that do not 2400 mounted to operating systems that do not
2378 support the cifs Unix extensions or EAs (for xattr 2401 support the cifs Unix extensions or EAs (for xattr
2379 based symlinks). For such a file to be recognized 2402 based symlinks). For such a file to be recognized
2380 as containing symlink data: 2403 as containing symlink data:
2381 2404
2382 1) file size must be 1067, 2405 1) file size must be 1067,
2383 2) signature must begin file data, 2406 2) signature must begin file data,
2384 3) length field must be set to ASCII representation 2407 3) length field must be set to ASCII representation
2385 of a number which is less than or equal to 1024, 2408 of a number which is less than or equal to 1024,
2386 4) md5 must match that of the path data */ 2409 4) md5 must match that of the path data */
2387 2410
2388struct xsymlink { 2411struct xsymlink {
@@ -2393,10 +2416,10 @@ struct xsymlink {
2393 char length[4]; 2416 char length[4];
2394 char cr1; /* \n */ 2417 char cr1; /* \n */
2395/* md5 of valid subset of path ie path[0] through path[length-1] */ 2418/* md5 of valid subset of path ie path[0] through path[length-1] */
2396 __u8 md5[32]; 2419 __u8 md5[32];
2397 char cr2; /* \n */ 2420 char cr2; /* \n */
2398/* if room left, then end with \n then 0x20s by convention but not required */ 2421/* if room left, then end with \n then 0x20s by convention but not required */
2399 char path[1024]; 2422 char path[1024];
2400} __attribute__((packed)); 2423} __attribute__((packed));
2401 2424
2402typedef struct file_xattr_info { 2425typedef struct file_xattr_info {
@@ -2405,7 +2428,8 @@ typedef struct file_xattr_info {
2405 __u32 xattr_value_len; 2428 __u32 xattr_value_len;
2406 char xattr_name[0]; 2429 char xattr_name[0];
2407 /* followed by xattr_value[xattr_value_len], no pad */ 2430 /* followed by xattr_value[xattr_value_len], no pad */
2408} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ 2431} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info
2432 level 0x205 */
2409 2433
2410 2434
2411/* flags for chattr command */ 2435/* flags for chattr command */
@@ -2431,8 +2455,9 @@ typedef struct file_xattr_info {
2431typedef struct file_chattr_info { 2455typedef struct file_chattr_info {
2432 __le64 mask; /* list of all possible attribute bits */ 2456 __le64 mask; /* list of all possible attribute bits */
2433 __le64 mode; /* list of actual attribute bits on this inode */ 2457 __le64 mode; /* list of actual attribute bits on this inode */
2434} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ 2458} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes
2459 (chattr, chflags) level 0x206 */
2435 2460
2436#endif 2461#endif
2437 2462
2438#endif /* _CIFSPDU_H */ 2463#endif /* _CIFSPDU_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 5d163e2b6143..04a69dafedba 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#ifndef _CIFSPROTO_H 21#ifndef _CIFSPROTO_H
22#define _CIFSPROTO_H 22#define _CIFSPROTO_H
@@ -49,9 +49,9 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
49 struct smb_hdr * /* out */ , 49 struct smb_hdr * /* out */ ,
50 int * /* bytes returned */ , const int long_op); 50 int * /* bytes returned */ , const int long_op);
51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
52 struct kvec *, int /* nvec to send */, 52 struct kvec *, int /* nvec to send */,
53 int * /* type of buf returned */ , const int long_op); 53 int * /* type of buf returned */ , const int long_op);
54extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 54extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
55 struct cifsTconInfo *, 55 struct cifsTconInfo *,
56 struct smb_hdr * /* input */ , 56 struct smb_hdr * /* input */ ,
57 struct smb_hdr * /* out */ , 57 struct smb_hdr * /* out */ ,
@@ -64,19 +64,19 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
64extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); 64extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
65extern int decode_negTokenInit(unsigned char *security_blob, int length, 65extern int decode_negTokenInit(unsigned char *security_blob, int length,
66 enum securityEnum *secType); 66 enum securityEnum *secType);
67extern int cifs_inet_pton(int, char * source, void *dst); 67extern int cifs_inet_pton(int, char *source, void *dst);
68extern int map_smb_to_linux_error(struct smb_hdr *smb); 68extern int map_smb_to_linux_error(struct smb_hdr *smb);
69extern void header_assemble(struct smb_hdr *, char /* command */ , 69extern void header_assemble(struct smb_hdr *, char /* command */ ,
70 const struct cifsTconInfo *, int /* length of 70 const struct cifsTconInfo *, int /* length of
71 fixed section (word count) in two byte units */); 71 fixed section (word count) in two byte units */);
72extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 72extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
73 struct cifsSesInfo *ses, 73 struct cifsSesInfo *ses,
74 void ** request_buf); 74 void **request_buf);
75extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 75extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
76 const int stage, 76 const int stage,
77 const struct nls_table *nls_cp); 77 const struct nls_table *nls_cp);
78extern __u16 GetNextMid(struct TCP_Server_Info *server); 78extern __u16 GetNextMid(struct TCP_Server_Info *server);
79extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 79extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
80 struct cifsTconInfo *); 80 struct cifsTconInfo *);
81extern void DeleteOplockQEntry(struct oplock_q_entry *); 81extern void DeleteOplockQEntry(struct oplock_q_entry *);
82extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 82extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
@@ -85,12 +85,12 @@ extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
85extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); 85extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
86 86
87extern int cifs_get_inode_info(struct inode **pinode, 87extern int cifs_get_inode_info(struct inode **pinode,
88 const unsigned char *search_path, 88 const unsigned char *search_path,
89 FILE_ALL_INFO * pfile_info, 89 FILE_ALL_INFO * pfile_info,
90 struct super_block *sb, int xid); 90 struct super_block *sb, int xid);
91extern int cifs_get_inode_info_unix(struct inode **pinode, 91extern int cifs_get_inode_info_unix(struct inode **pinode,
92 const unsigned char *search_path, 92 const unsigned char *search_path,
93 struct super_block *sb,int xid); 93 struct super_block *sb, int xid);
94 94
95extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 95extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
96 const char *); 96 const char *);
@@ -98,8 +98,8 @@ extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
98void cifs_proc_init(void); 98void cifs_proc_init(void);
99void cifs_proc_clean(void); 99void cifs_proc_clean(void);
100 100
101extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 101extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
102 struct nls_table * nls_info); 102 struct nls_table *nls_info);
103extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); 103extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
104 104
105extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 105extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
@@ -108,11 +108,11 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
108 108
109extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 109extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
110 const char *searchName, const struct nls_table *nls_codepage, 110 const char *searchName, const struct nls_table *nls_codepage,
111 __u16 *searchHandle, struct cifs_search_info * psrch_inf, 111 __u16 *searchHandle, struct cifs_search_info *psrch_inf,
112 int map, const char dirsep); 112 int map, const char dirsep);
113 113
114extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 114extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
115 __u16 searchHandle, struct cifs_search_info * psrch_inf); 115 __u16 searchHandle, struct cifs_search_info *psrch_inf);
116 116
117extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 117extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
118 const __u16 search_handle); 118 const __u16 search_handle);
@@ -123,9 +123,9 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
123 int legacy /* whether to use old info level */, 123 int legacy /* whether to use old info level */,
124 const struct nls_table *nls_codepage, int remap); 124 const struct nls_table *nls_codepage, int remap);
125extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 125extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
126 const unsigned char *searchName, 126 const unsigned char *searchName,
127 FILE_ALL_INFO * findData, 127 FILE_ALL_INFO *findData,
128 const struct nls_table *nls_codepage, int remap); 128 const struct nls_table *nls_codepage, int remap);
129 129
130extern int CIFSSMBUnixQPathInfo(const int xid, 130extern int CIFSSMBUnixQPathInfo(const int xid,
131 struct cifsTconInfo *tcon, 131 struct cifsTconInfo *tcon,
@@ -143,13 +143,13 @@ extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
143 const char *old_path, 143 const char *old_path,
144 const struct nls_table *nls_codepage, int remap); 144 const struct nls_table *nls_codepage, int remap);
145extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 145extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
146 const char *old_path, 146 const char *old_path,
147 const struct nls_table *nls_codepage, 147 const struct nls_table *nls_codepage,
148 unsigned int *pnum_referrals, 148 unsigned int *pnum_referrals,
149 unsigned char ** preferrals, 149 unsigned char **preferrals,
150 int remap); 150 int remap);
151extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 151extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
152 struct super_block * sb, struct smb_vol * vol); 152 struct super_block *sb, struct smb_vol *vol);
153extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, 153extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
154 struct kstatfs *FSData); 154 struct kstatfs *FSData);
155extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, 155extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
@@ -181,11 +181,11 @@ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
181 const struct nls_table *nls_codepage, 181 const struct nls_table *nls_codepage,
182 int remap_special_chars); 182 int remap_special_chars);
183extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, 183extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
184 __u64 size, __u16 fileHandle,__u32 opener_pid, 184 __u64 size, __u16 fileHandle, __u32 opener_pid,
185 int AllocSizeFlag); 185 int AllocSizeFlag);
186extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, 186extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
187 char *full_path, __u64 mode, __u64 uid, 187 char *full_path, __u64 mode, __u64 uid,
188 __u64 gid, dev_t dev, 188 __u64 gid, dev_t dev,
189 const struct nls_table *nls_codepage, 189 const struct nls_table *nls_codepage,
190 int remap_special_chars); 190 int remap_special_chars);
191 191
@@ -196,7 +196,10 @@ extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
196extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, 196extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
197 const char *name, const struct nls_table *nls_codepage, 197 const char *name, const struct nls_table *nls_codepage,
198 int remap_special_chars); 198 int remap_special_chars);
199 199extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon,
200 const char *name, __u16 type,
201 const struct nls_table *nls_codepage,
202 int remap_special_chars);
200extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, 203extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
201 const char *name, 204 const char *name,
202 const struct nls_table *nls_codepage, 205 const struct nls_table *nls_codepage,
@@ -205,8 +208,8 @@ extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
205 const char *fromName, const char *toName, 208 const char *fromName, const char *toName,
206 const struct nls_table *nls_codepage, 209 const struct nls_table *nls_codepage,
207 int remap_special_chars); 210 int remap_special_chars);
208extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 211extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
209 int netfid, char * target_name, 212 int netfid, char *target_name,
210 const struct nls_table *nls_codepage, 213 const struct nls_table *nls_codepage,
211 int remap_special_chars); 214 int remap_special_chars);
212extern int CIFSCreateHardLink(const int xid, 215extern int CIFSCreateHardLink(const int xid,
@@ -217,7 +220,7 @@ extern int CIFSCreateHardLink(const int xid,
217extern int CIFSUnixCreateHardLink(const int xid, 220extern int CIFSUnixCreateHardLink(const int xid,
218 struct cifsTconInfo *tcon, 221 struct cifsTconInfo *tcon,
219 const char *fromName, const char *toName, 222 const char *fromName, const char *toName,
220 const struct nls_table *nls_codepage, 223 const struct nls_table *nls_codepage,
221 int remap_special_chars); 224 int remap_special_chars);
222extern int CIFSUnixCreateSymLink(const int xid, 225extern int CIFSUnixCreateSymLink(const int xid,
223 struct cifsTconInfo *tcon, 226 struct cifsTconInfo *tcon,
@@ -228,7 +231,7 @@ extern int CIFSSMBUnixQuerySymLink(const int xid,
228 const unsigned char *searchName, 231 const unsigned char *searchName,
229 char *syminfo, const int buflen, 232 char *syminfo, const int buflen,
230 const struct nls_table *nls_codepage); 233 const struct nls_table *nls_codepage);
231extern int CIFSSMBQueryReparseLinkInfo(const int xid, 234extern int CIFSSMBQueryReparseLinkInfo(const int xid,
232 struct cifsTconInfo *tcon, 235 struct cifsTconInfo *tcon,
233 const unsigned char *searchName, 236 const unsigned char *searchName,
234 char *symlinkinfo, const int buflen, __u16 fid, 237 char *symlinkinfo, const int buflen, __u16 fid,
@@ -244,35 +247,35 @@ extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
244 const int access_flags, const int omode, 247 const int access_flags, const int omode,
245 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 248 __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
246 const struct nls_table *nls_codepage, int remap); 249 const struct nls_table *nls_codepage, int remap);
247extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, 250extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
248 u32 posix_flags, __u64 mode, __u16 * netfid, 251 u32 posix_flags, __u64 mode, __u16 * netfid,
249 FILE_UNIX_BASIC_INFO *pRetData, 252 FILE_UNIX_BASIC_INFO *pRetData,
250 __u32 *pOplock, const char *name, 253 __u32 *pOplock, const char *name,
251 const struct nls_table *nls_codepage, int remap); 254 const struct nls_table *nls_codepage, int remap);
252extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 255extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
253 const int smb_file_id); 256 const int smb_file_id);
254 257
255extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 258extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
256 const int netfid, unsigned int count, 259 const int netfid, unsigned int count,
257 const __u64 lseek, unsigned int *nbytes, char **buf, 260 const __u64 lseek, unsigned int *nbytes, char **buf,
258 int * return_buf_type); 261 int *return_buf_type);
259extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 262extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
260 const int netfid, const unsigned int count, 263 const int netfid, const unsigned int count,
261 const __u64 lseek, unsigned int *nbytes, 264 const __u64 lseek, unsigned int *nbytes,
262 const char *buf, const char __user *ubuf, 265 const char *buf, const char __user *ubuf,
263 const int long_op); 266 const int long_op);
264extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 267extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
265 const int netfid, const unsigned int count, 268 const int netfid, const unsigned int count,
266 const __u64 offset, unsigned int *nbytes, 269 const __u64 offset, unsigned int *nbytes,
267 struct kvec *iov, const int nvec, const int long_op); 270 struct kvec *iov, const int nvec, const int long_op);
268extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 271extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
269 const unsigned char *searchName, __u64 * inode_number, 272 const unsigned char *searchName, __u64 * inode_number,
270 const struct nls_table *nls_codepage, 273 const struct nls_table *nls_codepage,
271 int remap_special_chars); 274 int remap_special_chars);
272extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, 275extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
273 const struct nls_table * codepage); 276 const struct nls_table *codepage);
274extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 277extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
275 const struct nls_table * cp, int mapChars); 278 const struct nls_table *cp, int mapChars);
276 279
277extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 280extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
278 const __u16 netfid, const __u64 len, 281 const __u16 netfid, const __u64 len,
@@ -281,7 +284,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
281 const int waitFlag); 284 const int waitFlag);
282extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 285extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
283 const __u16 smb_file_id, const int get_flag, 286 const __u16 smb_file_id, const int get_flag,
284 const __u64 len, struct file_lock *, 287 const __u64 len, struct file_lock *,
285 const __u16 lock_type, const int waitFlag); 288 const __u16 lock_type, const int waitFlag);
286extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 289extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
287extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 290extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
@@ -291,54 +294,56 @@ extern void sesInfoFree(struct cifsSesInfo *);
291extern struct cifsTconInfo *tconInfoAlloc(void); 294extern struct cifsTconInfo *tconInfoAlloc(void);
292extern void tconInfoFree(struct cifsTconInfo *); 295extern void tconInfoFree(struct cifsTconInfo *);
293 296
294extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 297extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
295extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 298extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
296 __u32 *); 299 __u32 *);
297extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, 300extern int cifs_verify_signature(struct smb_hdr *,
298 __u32 expected_sequence_number); 301 const struct mac_key *mac_key,
299extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); 302 __u32 expected_sequence_number);
300extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, 303extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
304 const char *pass);
305extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
301 const struct nls_table *); 306 const struct nls_table *);
302extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); 307extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * );
303extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 308extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
304 const struct nls_table *); 309 const struct nls_table *);
305#ifdef CONFIG_CIFS_WEAK_PW_HASH 310#ifdef CONFIG_CIFS_WEAK_PW_HASH
306extern void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key); 311extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
307#endif /* CIFS_WEAK_PW_HASH */ 312#endif /* CIFS_WEAK_PW_HASH */
308extern int CIFSSMBCopy(int xid, 313extern int CIFSSMBCopy(int xid,
309 struct cifsTconInfo *source_tcon, 314 struct cifsTconInfo *source_tcon,
310 const char *fromName, 315 const char *fromName,
311 const __u16 target_tid, 316 const __u16 target_tid,
312 const char *toName, const int flags, 317 const char *toName, const int flags,
313 const struct nls_table *nls_codepage, 318 const struct nls_table *nls_codepage,
314 int remap_special_chars); 319 int remap_special_chars);
315extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 320extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
316 const int notify_subdirs,const __u16 netfid, 321 const int notify_subdirs, const __u16 netfid,
317 __u32 filter, struct file * file, int multishot, 322 __u32 filter, struct file *file, int multishot,
318 const struct nls_table *nls_codepage); 323 const struct nls_table *nls_codepage);
319extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 324extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
320 const unsigned char *searchName, char * EAData, 325 const unsigned char *searchName, char *EAData,
321 size_t bufsize, const struct nls_table *nls_codepage, 326 size_t bufsize, const struct nls_table *nls_codepage,
322 int remap_special_chars); 327 int remap_special_chars);
323extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, 328extern ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
324 const unsigned char * searchName,const unsigned char * ea_name, 329 const unsigned char *searchName, const unsigned char *ea_name,
325 unsigned char * ea_value, size_t buf_size, 330 unsigned char *ea_value, size_t buf_size,
326 const struct nls_table *nls_codepage, int remap_special_chars); 331 const struct nls_table *nls_codepage, int remap_special_chars);
327extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 332extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
328 const char *fileName, const char * ea_name, 333 const char *fileName, const char *ea_name,
329 const void * ea_value, const __u16 ea_value_len, 334 const void *ea_value, const __u16 ea_value_len,
330 const struct nls_table *nls_codepage, int remap_special_chars); 335 const struct nls_table *nls_codepage, int remap_special_chars);
331extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 336extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
332 __u16 fid, char *acl_inf, const int buflen, 337 __u16 fid, char *acl_inf, const int buflen,
333 const int acl_type /* ACCESS vs. DEFAULT */); 338 const int acl_type /* ACCESS vs. DEFAULT */);
334extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 339extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
335 const unsigned char *searchName, 340 const unsigned char *searchName,
336 char *acl_inf, const int buflen,const int acl_type, 341 char *acl_inf, const int buflen, const int acl_type,
337 const struct nls_table *nls_codepage, int remap_special_chars); 342 const struct nls_table *nls_codepage, int remap_special_chars);
338extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 343extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
339 const unsigned char *fileName, 344 const unsigned char *fileName,
340 const char *local_acl, const int buflen, const int acl_type, 345 const char *local_acl, const int buflen, const int acl_type,
341 const struct nls_table *nls_codepage, int remap_special_chars); 346 const struct nls_table *nls_codepage, int remap_special_chars);
342extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 347extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
343 const int netfid, __u64 * pExtAttrBits, __u64 *pMask); 348 const int netfid, __u64 * pExtAttrBits, __u64 *pMask);
344#endif /* _CIFSPROTO_H */ 349#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 57419a176688..8eb102f940d4 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -48,7 +48,7 @@ static struct {
48 {LANMAN_PROT, "\2LM1.2X002"}, 48 {LANMAN_PROT, "\2LM1.2X002"},
49 {LANMAN2_PROT, "\2LANMAN2.1"}, 49 {LANMAN2_PROT, "\2LANMAN2.1"},
50#endif /* weak password hashing for legacy clients */ 50#endif /* weak password hashing for legacy clients */
51 {CIFS_PROT, "\2NT LM 0.12"}, 51 {CIFS_PROT, "\2NT LM 0.12"},
52 {POSIX_PROT, "\2POSIX 2"}, 52 {POSIX_PROT, "\2POSIX 2"},
53 {BAD_PROT, "\2"} 53 {BAD_PROT, "\2"}
54}; 54};
@@ -61,7 +61,7 @@ static struct {
61 {LANMAN_PROT, "\2LM1.2X002"}, 61 {LANMAN_PROT, "\2LM1.2X002"},
62 {LANMAN2_PROT, "\2LANMAN2.1"}, 62 {LANMAN2_PROT, "\2LANMAN2.1"},
63#endif /* weak password hashing for legacy clients */ 63#endif /* weak password hashing for legacy clients */
64 {CIFS_PROT, "\2NT LM 0.12"}, 64 {CIFS_PROT, "\2NT LM 0.12"},
65 {BAD_PROT, "\2"} 65 {BAD_PROT, "\2"}
66}; 66};
67#endif 67#endif
@@ -84,17 +84,17 @@ static struct {
84 84
85/* Mark as invalid, all open files on tree connections since they 85/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 86 were closed when session to server was lost */
87static void mark_open_files_invalid(struct cifsTconInfo * pTcon) 87static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
88{ 88{
89 struct cifsFileInfo *open_file = NULL; 89 struct cifsFileInfo *open_file = NULL;
90 struct list_head * tmp; 90 struct list_head *tmp;
91 struct list_head * tmp1; 91 struct list_head *tmp1;
92 92
93/* list all files open on tree connection and mark them invalid */ 93/* list all files open on tree connection and mark them invalid */
94 write_lock(&GlobalSMBSeslock); 94 write_lock(&GlobalSMBSeslock);
95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { 95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
96 open_file = list_entry(tmp,struct cifsFileInfo, tlist); 96 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
97 if(open_file) { 97 if (open_file) {
98 open_file->invalidHandle = TRUE; 98 open_file->invalidHandle = TRUE;
99 } 99 }
100 } 100 }
@@ -113,75 +113,78 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
113 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so 113 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
114 check for tcp and smb session status done differently 114 check for tcp and smb session status done differently
115 for those three - in the calling routine */ 115 for those three - in the calling routine */
116 if(tcon) { 116 if (tcon) {
117 if(tcon->tidStatus == CifsExiting) { 117 if (tcon->tidStatus == CifsExiting) {
118 /* only tree disconnect, open, and write, 118 /* only tree disconnect, open, and write,
119 (and ulogoff which does not have tcon) 119 (and ulogoff which does not have tcon)
120 are allowed as we start force umount */ 120 are allowed as we start force umount */
121 if((smb_command != SMB_COM_WRITE_ANDX) && 121 if ((smb_command != SMB_COM_WRITE_ANDX) &&
122 (smb_command != SMB_COM_OPEN_ANDX) && 122 (smb_command != SMB_COM_OPEN_ANDX) &&
123 (smb_command != SMB_COM_TREE_DISCONNECT)) { 123 (smb_command != SMB_COM_TREE_DISCONNECT)) {
124 cFYI(1,("can not send cmd %d while umounting", 124 cFYI(1, ("can not send cmd %d while umounting",
125 smb_command)); 125 smb_command));
126 return -ENODEV; 126 return -ENODEV;
127 } 127 }
128 } 128 }
129 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 129 if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
130 (tcon->ses->server)){ 130 (tcon->ses->server)) {
131 struct nls_table *nls_codepage; 131 struct nls_table *nls_codepage;
132 /* Give Demultiplex thread up to 10 seconds to 132 /* Give Demultiplex thread up to 10 seconds to
133 reconnect, should be greater than cifs socket 133 reconnect, should be greater than cifs socket
134 timeout which is 7 seconds */ 134 timeout which is 7 seconds */
135 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 135 while (tcon->ses->server->tcpStatus ==
136 CifsNeedReconnect) {
136 wait_event_interruptible_timeout(tcon->ses->server->response_q, 137 wait_event_interruptible_timeout(tcon->ses->server->response_q,
137 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 138 (tcon->ses->server->tcpStatus ==
138 if(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 139 CifsGood), 10 * HZ);
140 if (tcon->ses->server->tcpStatus ==
141 CifsNeedReconnect) {
139 /* on "soft" mounts we wait once */ 142 /* on "soft" mounts we wait once */
140 if((tcon->retry == FALSE) || 143 if ((tcon->retry == FALSE) ||
141 (tcon->ses->status == CifsExiting)) { 144 (tcon->ses->status == CifsExiting)) {
142 cFYI(1,("gave up waiting on reconnect in smb_init")); 145 cFYI(1, ("gave up waiting on "
146 "reconnect in smb_init"));
143 return -EHOSTDOWN; 147 return -EHOSTDOWN;
144 } /* else "hard" mount - keep retrying 148 } /* else "hard" mount - keep retrying
145 until process is killed or server 149 until process is killed or server
146 comes back on-line */ 150 comes back on-line */
147 } else /* TCP session is reestablished now */ 151 } else /* TCP session is reestablished now */
148 break; 152 break;
149
150 } 153 }
151 154
152 nls_codepage = load_nls_default(); 155 nls_codepage = load_nls_default();
153 /* need to prevent multiple threads trying to 156 /* need to prevent multiple threads trying to
154 simultaneously reconnect the same SMB session */ 157 simultaneously reconnect the same SMB session */
155 down(&tcon->ses->sesSem); 158 down(&tcon->ses->sesSem);
156 if(tcon->ses->status == CifsNeedReconnect) 159 if (tcon->ses->status == CifsNeedReconnect)
157 rc = cifs_setup_session(0, tcon->ses, 160 rc = cifs_setup_session(0, tcon->ses,
158 nls_codepage); 161 nls_codepage);
159 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 162 if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
160 mark_open_files_invalid(tcon); 163 mark_open_files_invalid(tcon);
161 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 164 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
162 tcon, nls_codepage); 165 tcon, nls_codepage);
163 up(&tcon->ses->sesSem); 166 up(&tcon->ses->sesSem);
164 /* tell server which Unix caps we support */ 167 /* tell server which Unix caps we support */
165 if (tcon->ses->capabilities & CAP_UNIX) 168 if (tcon->ses->capabilities & CAP_UNIX)
166 reset_cifs_unix_caps(0 /* no xid */, 169 reset_cifs_unix_caps(0 /* no xid */,
167 tcon, 170 tcon,
168 NULL /* we do not know sb */, 171 NULL /* we do not know sb */,
169 NULL /* no vol info */); 172 NULL /* no vol info */);
170 /* BB FIXME add code to check if wsize needs 173 /* BB FIXME add code to check if wsize needs
171 update due to negotiated smb buffer size 174 update due to negotiated smb buffer size
172 shrinking */ 175 shrinking */
173 if(rc == 0) 176 if (rc == 0)
174 atomic_inc(&tconInfoReconnectCount); 177 atomic_inc(&tconInfoReconnectCount);
175 178
176 cFYI(1, ("reconnect tcon rc = %d", rc)); 179 cFYI(1, ("reconnect tcon rc = %d", rc));
177 /* Removed call to reopen open files here - 180 /* Removed call to reopen open files here.
178 it is safer (and faster) to reopen files 181 It is safer (and faster) to reopen files
179 one at a time as needed in read and write */ 182 one at a time as needed in read and write */
180 183
181 /* Check if handle based operation so we 184 /* Check if handle based operation so we
182 know whether we can continue or not without 185 know whether we can continue or not without
183 returning to caller to reset file handle */ 186 returning to caller to reset file handle */
184 switch(smb_command) { 187 switch (smb_command) {
185 case SMB_COM_READ_ANDX: 188 case SMB_COM_READ_ANDX:
186 case SMB_COM_WRITE_ANDX: 189 case SMB_COM_WRITE_ANDX:
187 case SMB_COM_CLOSE: 190 case SMB_COM_CLOSE:
@@ -200,7 +203,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
200 return -EIO; 203 return -EIO;
201 } 204 }
202 } 205 }
203 if(rc) 206 if (rc)
204 return rc; 207 return rc;
205 208
206 *request_buf = cifs_small_buf_get(); 209 *request_buf = cifs_small_buf_get();
@@ -209,23 +212,24 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
209 return -ENOMEM; 212 return -ENOMEM;
210 } 213 }
211 214
212 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); 215 header_assemble((struct smb_hdr *) *request_buf, smb_command,
216 tcon, wct);
213 217
214 if(tcon != NULL) 218 if (tcon != NULL)
215 cifs_stats_inc(&tcon->num_smbs_sent); 219 cifs_stats_inc(&tcon->num_smbs_sent);
216 220
217 return rc; 221 return rc;
218} 222}
219 223
220int 224int
221small_smb_init_no_tc(const int smb_command, const int wct, 225small_smb_init_no_tc(const int smb_command, const int wct,
222 struct cifsSesInfo *ses, void **request_buf) 226 struct cifsSesInfo *ses, void **request_buf)
223{ 227{
224 int rc; 228 int rc;
225 struct smb_hdr * buffer; 229 struct smb_hdr *buffer;
226 230
227 rc = small_smb_init(smb_command, wct, NULL, request_buf); 231 rc = small_smb_init(smb_command, wct, NULL, request_buf);
228 if(rc) 232 if (rc)
229 return rc; 233 return rc;
230 234
231 buffer = (struct smb_hdr *)*request_buf; 235 buffer = (struct smb_hdr *)*request_buf;
@@ -237,7 +241,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
237 241
238 /* uid, tid can stay at zero as set in header assemble */ 242 /* uid, tid can stay at zero as set in header assemble */
239 243
240 /* BB add support for turning on the signing when 244 /* BB add support for turning on the signing when
241 this function is used after 1st of session setup requests */ 245 this function is used after 1st of session setup requests */
242 246
243 return rc; 247 return rc;
@@ -254,52 +258,53 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
254 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so 258 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
255 check for tcp and smb session status done differently 259 check for tcp and smb session status done differently
256 for those three - in the calling routine */ 260 for those three - in the calling routine */
257 if(tcon) { 261 if (tcon) {
258 if(tcon->tidStatus == CifsExiting) { 262 if (tcon->tidStatus == CifsExiting) {
259 /* only tree disconnect, open, and write, 263 /* only tree disconnect, open, and write,
260 (and ulogoff which does not have tcon) 264 (and ulogoff which does not have tcon)
261 are allowed as we start force umount */ 265 are allowed as we start force umount */
262 if((smb_command != SMB_COM_WRITE_ANDX) && 266 if ((smb_command != SMB_COM_WRITE_ANDX) &&
263 (smb_command != SMB_COM_OPEN_ANDX) && 267 (smb_command != SMB_COM_OPEN_ANDX) &&
264 (smb_command != SMB_COM_TREE_DISCONNECT)) { 268 (smb_command != SMB_COM_TREE_DISCONNECT)) {
265 cFYI(1,("can not send cmd %d while umounting", 269 cFYI(1, ("can not send cmd %d while umounting",
266 smb_command)); 270 smb_command));
267 return -ENODEV; 271 return -ENODEV;
268 } 272 }
269 } 273 }
270 274
271 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 275 if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
272 (tcon->ses->server)){ 276 (tcon->ses->server)) {
273 struct nls_table *nls_codepage; 277 struct nls_table *nls_codepage;
274 /* Give Demultiplex thread up to 10 seconds to 278 /* Give Demultiplex thread up to 10 seconds to
275 reconnect, should be greater than cifs socket 279 reconnect, should be greater than cifs socket
276 timeout which is 7 seconds */ 280 timeout which is 7 seconds */
277 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 281 while (tcon->ses->server->tcpStatus ==
282 CifsNeedReconnect) {
278 wait_event_interruptible_timeout(tcon->ses->server->response_q, 283 wait_event_interruptible_timeout(tcon->ses->server->response_q,
279 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 284 (tcon->ses->server->tcpStatus ==
280 if(tcon->ses->server->tcpStatus == 285 CifsGood), 10 * HZ);
286 if (tcon->ses->server->tcpStatus ==
281 CifsNeedReconnect) { 287 CifsNeedReconnect) {
282 /* on "soft" mounts we wait once */ 288 /* on "soft" mounts we wait once */
283 if((tcon->retry == FALSE) || 289 if ((tcon->retry == FALSE) ||
284 (tcon->ses->status == CifsExiting)) { 290 (tcon->ses->status == CifsExiting)) {
285 cFYI(1,("gave up waiting on reconnect in smb_init")); 291 cFYI(1, ("gave up waiting on "
292 "reconnect in smb_init"));
286 return -EHOSTDOWN; 293 return -EHOSTDOWN;
287 } /* else "hard" mount - keep retrying 294 } /* else "hard" mount - keep retrying
288 until process is killed or server 295 until process is killed or server
289 comes on-line */ 296 comes on-line */
290 } else /* TCP session is reestablished now */ 297 } else /* TCP session is reestablished now */
291 break; 298 break;
292
293 } 299 }
294
295 nls_codepage = load_nls_default(); 300 nls_codepage = load_nls_default();
296 /* need to prevent multiple threads trying to 301 /* need to prevent multiple threads trying to
297 simultaneously reconnect the same SMB session */ 302 simultaneously reconnect the same SMB session */
298 down(&tcon->ses->sesSem); 303 down(&tcon->ses->sesSem);
299 if(tcon->ses->status == CifsNeedReconnect) 304 if (tcon->ses->status == CifsNeedReconnect)
300 rc = cifs_setup_session(0, tcon->ses, 305 rc = cifs_setup_session(0, tcon->ses,
301 nls_codepage); 306 nls_codepage);
302 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 307 if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
303 mark_open_files_invalid(tcon); 308 mark_open_files_invalid(tcon);
304 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 309 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
305 tcon, nls_codepage); 310 tcon, nls_codepage);
@@ -307,24 +312,24 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
307 /* tell server which Unix caps we support */ 312 /* tell server which Unix caps we support */
308 if (tcon->ses->capabilities & CAP_UNIX) 313 if (tcon->ses->capabilities & CAP_UNIX)
309 reset_cifs_unix_caps(0 /* no xid */, 314 reset_cifs_unix_caps(0 /* no xid */,
310 tcon, 315 tcon,
311 NULL /* do not know sb */, 316 NULL /* do not know sb */,
312 NULL /* no vol info */); 317 NULL /* no vol info */);
313 /* BB FIXME add code to check if wsize needs 318 /* BB FIXME add code to check if wsize needs
314 update due to negotiated smb buffer size 319 update due to negotiated smb buffer size
315 shrinking */ 320 shrinking */
316 if(rc == 0) 321 if (rc == 0)
317 atomic_inc(&tconInfoReconnectCount); 322 atomic_inc(&tconInfoReconnectCount);
318 323
319 cFYI(1, ("reconnect tcon rc = %d", rc)); 324 cFYI(1, ("reconnect tcon rc = %d", rc));
320 /* Removed call to reopen open files here - 325 /* Removed call to reopen open files here.
321 it is safer (and faster) to reopen files 326 It is safer (and faster) to reopen files
322 one at a time as needed in read and write */ 327 one at a time as needed in read and write */
323 328
324 /* Check if handle based operation so we 329 /* Check if handle based operation so we
325 know whether we can continue or not without 330 know whether we can continue or not without
326 returning to caller to reset file handle */ 331 returning to caller to reset file handle */
327 switch(smb_command) { 332 switch (smb_command) {
328 case SMB_COM_READ_ANDX: 333 case SMB_COM_READ_ANDX:
329 case SMB_COM_WRITE_ANDX: 334 case SMB_COM_WRITE_ANDX:
330 case SMB_COM_CLOSE: 335 case SMB_COM_CLOSE:
@@ -343,7 +348,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
343 return -EIO; 348 return -EIO;
344 } 349 }
345 } 350 }
346 if(rc) 351 if (rc)
347 return rc; 352 return rc;
348 353
349 *request_buf = cifs_buf_get(); 354 *request_buf = cifs_buf_get();
@@ -355,48 +360,48 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
355 /* potential retries of smb operations it turns out we can determine */ 360 /* potential retries of smb operations it turns out we can determine */
356 /* from the mid flags when the request buffer can be resent without */ 361 /* from the mid flags when the request buffer can be resent without */
357 /* having to use a second distinct buffer for the response */ 362 /* having to use a second distinct buffer for the response */
358 if(response_buf) 363 if (response_buf)
359 *response_buf = *request_buf; 364 *response_buf = *request_buf;
360 365
361 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 366 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
362 wct /*wct */ ); 367 wct /*wct */ );
363 368
364 if(tcon != NULL) 369 if (tcon != NULL)
365 cifs_stats_inc(&tcon->num_smbs_sent); 370 cifs_stats_inc(&tcon->num_smbs_sent);
366 371
367 return rc; 372 return rc;
368} 373}
369 374
370static int validate_t2(struct smb_t2_rsp * pSMB) 375static int validate_t2(struct smb_t2_rsp *pSMB)
371{ 376{
372 int rc = -EINVAL; 377 int rc = -EINVAL;
373 int total_size; 378 int total_size;
374 char * pBCC; 379 char *pBCC;
375 380
376 /* check for plausible wct, bcc and t2 data and parm sizes */ 381 /* check for plausible wct, bcc and t2 data and parm sizes */
377 /* check for parm and data offset going beyond end of smb */ 382 /* check for parm and data offset going beyond end of smb */
378 if(pSMB->hdr.WordCount >= 10) { 383 if (pSMB->hdr.WordCount >= 10) {
379 if((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) && 384 if ((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) &&
380 (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) { 385 (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) {
381 /* check that bcc is at least as big as parms + data */ 386 /* check that bcc is at least as big as parms + data */
382 /* check that bcc is less than negotiated smb buffer */ 387 /* check that bcc is less than negotiated smb buffer */
383 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); 388 total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount);
384 if(total_size < 512) { 389 if (total_size < 512) {
385 total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); 390 total_size +=
391 le16_to_cpu(pSMB->t2_rsp.DataCount);
386 /* BCC le converted in SendReceive */ 392 /* BCC le converted in SendReceive */
387 pBCC = (pSMB->hdr.WordCount * 2) + 393 pBCC = (pSMB->hdr.WordCount * 2) +
388 sizeof(struct smb_hdr) + 394 sizeof(struct smb_hdr) +
389 (char *)pSMB; 395 (char *)pSMB;
390 if((total_size <= (*(u16 *)pBCC)) && 396 if ((total_size <= (*(u16 *)pBCC)) &&
391 (total_size < 397 (total_size <
392 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) { 398 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {
393 return 0; 399 return 0;
394 } 400 }
395
396 } 401 }
397 } 402 }
398 } 403 }
399 cifs_dump_mem("Invalid transact2 SMB: ",(char *)pSMB, 404 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
400 sizeof(struct smb_t2_rsp) + 16); 405 sizeof(struct smb_t2_rsp) + 16);
401 return rc; 406 return rc;
402} 407}
@@ -408,12 +413,12 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
408 int rc = 0; 413 int rc = 0;
409 int bytes_returned; 414 int bytes_returned;
410 int i; 415 int i;
411 struct TCP_Server_Info * server; 416 struct TCP_Server_Info *server;
412 u16 count; 417 u16 count;
413 unsigned int secFlags; 418 unsigned int secFlags;
414 u16 dialect; 419 u16 dialect;
415 420
416 if(ses->server) 421 if (ses->server)
417 server = ses->server; 422 server = ses->server;
418 else { 423 else {
419 rc = -EIO; 424 rc = -EIO;
@@ -425,20 +430,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
425 return rc; 430 return rc;
426 431
427 /* if any of auth flags (ie not sign or seal) are overriden use them */ 432 /* if any of auth flags (ie not sign or seal) are overriden use them */
428 if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 433 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
429 secFlags = ses->overrideSecFlg; 434 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
430 else /* if override flags set only sign/seal OR them with global auth */ 435 else /* if override flags set only sign/seal OR them with global auth */
431 secFlags = extended_security | ses->overrideSecFlg; 436 secFlags = extended_security | ses->overrideSecFlg;
432 437
433 cFYI(1,("secFlags 0x%x",secFlags)); 438 cFYI(1, ("secFlags 0x%x", secFlags));
434 439
435 pSMB->hdr.Mid = GetNextMid(server); 440 pSMB->hdr.Mid = GetNextMid(server);
436 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 441 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
437 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 442 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
438 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 443 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
439 444
440 count = 0; 445 count = 0;
441 for(i=0;i<CIFS_NUM_PROT;i++) { 446 for (i = 0; i < CIFS_NUM_PROT; i++) {
442 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16); 447 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
443 count += strlen(protocols[i].name) + 1; 448 count += strlen(protocols[i].name) + 1;
444 /* null at end of source and target buffers anyway */ 449 /* null at end of source and target buffers anyway */
@@ -448,26 +453,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
448 453
449 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 454 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
450 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 455 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
451 if (rc != 0) 456 if (rc != 0)
452 goto neg_err_exit; 457 goto neg_err_exit;
453 458
454 dialect = le16_to_cpu(pSMBr->DialectIndex); 459 dialect = le16_to_cpu(pSMBr->DialectIndex);
455 cFYI(1,("Dialect: %d", dialect)); 460 cFYI(1, ("Dialect: %d", dialect));
456 /* Check wct = 1 error case */ 461 /* Check wct = 1 error case */
457 if((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) { 462 if ((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) {
458 /* core returns wct = 1, but we do not ask for core - otherwise 463 /* core returns wct = 1, but we do not ask for core - otherwise
459 small wct just comes when dialect index is -1 indicating we 464 small wct just comes when dialect index is -1 indicating we
460 could not negotiate a common dialect */ 465 could not negotiate a common dialect */
461 rc = -EOPNOTSUPP; 466 rc = -EOPNOTSUPP;
462 goto neg_err_exit; 467 goto neg_err_exit;
463#ifdef CONFIG_CIFS_WEAK_PW_HASH 468#ifdef CONFIG_CIFS_WEAK_PW_HASH
464 } else if((pSMBr->hdr.WordCount == 13) 469 } else if ((pSMBr->hdr.WordCount == 13)
465 && ((dialect == LANMAN_PROT) 470 && ((dialect == LANMAN_PROT)
466 || (dialect == LANMAN2_PROT))) { 471 || (dialect == LANMAN2_PROT))) {
467 __s16 tmp; 472 __s16 tmp;
468 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 473 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
469 474
470 if((secFlags & CIFSSEC_MAY_LANMAN) || 475 if ((secFlags & CIFSSEC_MAY_LANMAN) ||
471 (secFlags & CIFSSEC_MAY_PLNTXT)) 476 (secFlags & CIFSSEC_MAY_PLNTXT))
472 server->secType = LANMAN; 477 server->secType = LANMAN;
473 else { 478 else {
@@ -475,7 +480,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
475 " in /proc/fs/cifs/SecurityFlags")); 480 " in /proc/fs/cifs/SecurityFlags"));
476 rc = -EOPNOTSUPP; 481 rc = -EOPNOTSUPP;
477 goto neg_err_exit; 482 goto neg_err_exit;
478 } 483 }
479 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); 484 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
480 server->maxReq = le16_to_cpu(rsp->MaxMpxCount); 485 server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
481 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), 486 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
@@ -483,7 +488,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
483 GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); 488 GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey);
484 /* even though we do not use raw we might as well set this 489 /* even though we do not use raw we might as well set this
485 accurately, in case we ever find a need for it */ 490 accurately, in case we ever find a need for it */
486 if((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { 491 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
487 server->maxRw = 0xFF00; 492 server->maxRw = 0xFF00;
488 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; 493 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
489 } else { 494 } else {
@@ -504,29 +509,29 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
504 utc = CURRENT_TIME; 509 utc = CURRENT_TIME;
505 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), 510 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
506 le16_to_cpu(rsp->SrvTime.Time)); 511 le16_to_cpu(rsp->SrvTime.Time));
507 cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", 512 cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
508 (int)ts.tv_sec, (int)utc.tv_sec, 513 (int)ts.tv_sec, (int)utc.tv_sec,
509 (int)(utc.tv_sec - ts.tv_sec))); 514 (int)(utc.tv_sec - ts.tv_sec)));
510 val = (int)(utc.tv_sec - ts.tv_sec); 515 val = (int)(utc.tv_sec - ts.tv_sec);
511 seconds = val < 0 ? -val : val; 516 seconds = val < 0 ? -val : val;
512 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; 517 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
513 remain = seconds % MIN_TZ_ADJ; 518 remain = seconds % MIN_TZ_ADJ;
514 if(remain >= (MIN_TZ_ADJ / 2)) 519 if (remain >= (MIN_TZ_ADJ / 2))
515 result += MIN_TZ_ADJ; 520 result += MIN_TZ_ADJ;
516 if(val < 0) 521 if (val < 0)
517 result = - result; 522 result = - result;
518 server->timeAdj = result; 523 server->timeAdj = result;
519 } else { 524 } else {
520 server->timeAdj = (int)tmp; 525 server->timeAdj = (int)tmp;
521 server->timeAdj *= 60; /* also in seconds */ 526 server->timeAdj *= 60; /* also in seconds */
522 } 527 }
523 cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); 528 cFYI(1, ("server->timeAdj: %d seconds", server->timeAdj));
524 529
525 530
526 /* BB get server time for time conversions and add 531 /* BB get server time for time conversions and add
527 code to use it and timezone since this is not UTC */ 532 code to use it and timezone since this is not UTC */
528 533
529 if (rsp->EncryptionKeyLength == 534 if (rsp->EncryptionKeyLength ==
530 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 535 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
531 memcpy(server->cryptKey, rsp->EncryptionKey, 536 memcpy(server->cryptKey, rsp->EncryptionKey,
532 CIFS_CRYPTO_KEY_SIZE); 537 CIFS_CRYPTO_KEY_SIZE);
@@ -535,39 +540,39 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
535 goto neg_err_exit; 540 goto neg_err_exit;
536 } 541 }
537 542
538 cFYI(1,("LANMAN negotiated")); 543 cFYI(1, ("LANMAN negotiated"));
539 /* we will not end up setting signing flags - as no signing 544 /* we will not end up setting signing flags - as no signing
540 was in LANMAN and server did not return the flags on */ 545 was in LANMAN and server did not return the flags on */
541 goto signing_check; 546 goto signing_check;
542#else /* weak security disabled */ 547#else /* weak security disabled */
543 } else if(pSMBr->hdr.WordCount == 13) { 548 } else if (pSMBr->hdr.WordCount == 13) {
544 cERROR(1,("mount failed, cifs module not built " 549 cERROR(1, ("mount failed, cifs module not built "
545 "with CIFS_WEAK_PW_HASH support")); 550 "with CIFS_WEAK_PW_HASH support"));
546 rc = -EOPNOTSUPP; 551 rc = -EOPNOTSUPP;
547#endif /* WEAK_PW_HASH */ 552#endif /* WEAK_PW_HASH */
548 goto neg_err_exit; 553 goto neg_err_exit;
549 } else if(pSMBr->hdr.WordCount != 17) { 554 } else if (pSMBr->hdr.WordCount != 17) {
550 /* unknown wct */ 555 /* unknown wct */
551 rc = -EOPNOTSUPP; 556 rc = -EOPNOTSUPP;
552 goto neg_err_exit; 557 goto neg_err_exit;
553 } 558 }
554 /* else wct == 17 NTLM */ 559 /* else wct == 17 NTLM */
555 server->secMode = pSMBr->SecurityMode; 560 server->secMode = pSMBr->SecurityMode;
556 if((server->secMode & SECMODE_USER) == 0) 561 if ((server->secMode & SECMODE_USER) == 0)
557 cFYI(1,("share mode security")); 562 cFYI(1, ("share mode security"));
558 563
559 if((server->secMode & SECMODE_PW_ENCRYPT) == 0) 564 if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
560#ifdef CONFIG_CIFS_WEAK_PW_HASH 565#ifdef CONFIG_CIFS_WEAK_PW_HASH
561 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) 566 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
562#endif /* CIFS_WEAK_PW_HASH */ 567#endif /* CIFS_WEAK_PW_HASH */
563 cERROR(1,("Server requests plain text password" 568 cERROR(1, ("Server requests plain text password"
564 " but client support disabled")); 569 " but client support disabled"));
565 570
566 if((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) 571 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
567 server->secType = NTLMv2; 572 server->secType = NTLMv2;
568 else if(secFlags & CIFSSEC_MAY_NTLM) 573 else if (secFlags & CIFSSEC_MAY_NTLM)
569 server->secType = NTLM; 574 server->secType = NTLM;
570 else if(secFlags & CIFSSEC_MAY_NTLMV2) 575 else if (secFlags & CIFSSEC_MAY_NTLMV2)
571 server->secType = NTLMv2; 576 server->secType = NTLMv2;
572 /* else krb5 ... any others ... */ 577 /* else krb5 ... any others ... */
573 578
@@ -596,7 +601,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
596 601
597 /* BB might be helpful to save off the domain of server here */ 602 /* BB might be helpful to save off the domain of server here */
598 603
599 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && 604 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
600 (server->capabilities & CAP_EXTENDED_SECURITY)) { 605 (server->capabilities & CAP_EXTENDED_SECURITY)) {
601 count = pSMBr->ByteCount; 606 count = pSMBr->ByteCount;
602 if (count < 16) 607 if (count < 16)
@@ -620,7 +625,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
620 SecurityBlob, 625 SecurityBlob,
621 count - 16, 626 count - 16,
622 &server->secType); 627 &server->secType);
623 if(rc == 1) { 628 if (rc == 1) {
624 /* BB Need to fill struct for sessetup here */ 629 /* BB Need to fill struct for sessetup here */
625 rc = -EOPNOTSUPP; 630 rc = -EOPNOTSUPP;
626 } else { 631 } else {
@@ -633,26 +638,37 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
633#ifdef CONFIG_CIFS_WEAK_PW_HASH 638#ifdef CONFIG_CIFS_WEAK_PW_HASH
634signing_check: 639signing_check:
635#endif 640#endif
636 if(sign_CIFS_PDUs == FALSE) { 641 if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
637 if(server->secMode & SECMODE_SIGN_REQUIRED) 642 /* MUST_SIGN already includes the MAY_SIGN FLAG
638 cERROR(1,("Server requires " 643 so if this is zero it means that signing is disabled */
639 "/proc/fs/cifs/PacketSigningEnabled to be on")); 644 cFYI(1, ("Signing disabled"));
640 server->secMode &= 645 if (server->secMode & SECMODE_SIGN_REQUIRED)
646 cERROR(1, ("Server requires "
647 "/proc/fs/cifs/PacketSigningEnabled "
648 "to be on"));
649 server->secMode &=
641 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 650 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
642 } else if(sign_CIFS_PDUs == 1) { 651 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
643 if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 652 /* signing required */
644 server->secMode &= 653 cFYI(1, ("Must sign - secFlags 0x%x", secFlags));
645 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 654 if ((server->secMode &
646 } else if(sign_CIFS_PDUs == 2) {
647 if((server->secMode &
648 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { 655 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
649 cERROR(1,("signing required but server lacks support")); 656 cERROR(1,
650 } 657 ("signing required but server lacks support"));
658 rc = -EOPNOTSUPP;
659 } else
660 server->secMode |= SECMODE_SIGN_REQUIRED;
661 } else {
662 /* signing optional ie CIFSSEC_MAY_SIGN */
663 if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
664 server->secMode &=
665 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
651 } 666 }
652neg_err_exit: 667
668neg_err_exit:
653 cifs_buf_release(pSMB); 669 cifs_buf_release(pSMB);
654 670
655 cFYI(1,("negprot rc %d",rc)); 671 cFYI(1, ("negprot rc %d", rc));
656 return rc; 672 return rc;
657} 673}
658 674
@@ -669,7 +685,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
669 * If last user of the connection and 685 * If last user of the connection and
670 * connection alive - disconnect it 686 * connection alive - disconnect it
671 * If this is the last connection on the server session disconnect it 687 * If this is the last connection on the server session disconnect it
672 * (and inside session disconnect we should check if tcp socket needs 688 * (and inside session disconnect we should check if tcp socket needs
673 * to be freed and kernel thread woken up). 689 * to be freed and kernel thread woken up).
674 */ 690 */
675 if (tcon) 691 if (tcon)
@@ -683,18 +699,18 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
683 return -EBUSY; 699 return -EBUSY;
684 } 700 }
685 701
686 /* No need to return error on this operation if tid invalidated and 702 /* No need to return error on this operation if tid invalidated and
687 closed on server already e.g. due to tcp session crashing */ 703 closed on server already e.g. due to tcp session crashing */
688 if(tcon->tidStatus == CifsNeedReconnect) { 704 if (tcon->tidStatus == CifsNeedReconnect) {
689 up(&tcon->tconSem); 705 up(&tcon->tconSem);
690 return 0; 706 return 0;
691 } 707 }
692 708
693 if((tcon->ses == NULL) || (tcon->ses->server == NULL)) { 709 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) {
694 up(&tcon->tconSem); 710 up(&tcon->tconSem);
695 return -EIO; 711 return -EIO;
696 } 712 }
697 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 713 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
698 (void **)&smb_buffer); 714 (void **)&smb_buffer);
699 if (rc) { 715 if (rc) {
700 up(&tcon->tconSem); 716 up(&tcon->tconSem);
@@ -711,7 +727,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
711 cifs_small_buf_release(smb_buffer); 727 cifs_small_buf_release(smb_buffer);
712 up(&tcon->tconSem); 728 up(&tcon->tconSem);
713 729
714 /* No need to return error on this operation if tid invalidated and 730 /* No need to return error on this operation if tid invalidated and
715 closed on server already e.g. due to tcp session crashing */ 731 closed on server already e.g. due to tcp session crashing */
716 if (rc == -EAGAIN) 732 if (rc == -EAGAIN)
717 rc = 0; 733 rc = 0;
@@ -745,11 +761,11 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
745 } 761 }
746 762
747 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ 763 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
748 764
749 if(ses->server) { 765 if (ses->server) {
750 pSMB->hdr.Mid = GetNextMid(ses->server); 766 pSMB->hdr.Mid = GetNextMid(ses->server);
751 767
752 if(ses->server->secMode & 768 if (ses->server->secMode &
753 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 769 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
754 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 770 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
755 } 771 }
@@ -772,7 +788,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
772 cifs_small_buf_release(pSMB); 788 cifs_small_buf_release(pSMB);
773 789
774 /* if session dead then we do not need to do ulogoff, 790 /* if session dead then we do not need to do ulogoff,
775 since server closed smb session, no sense reporting 791 since server closed smb session, no sense reporting
776 error */ 792 error */
777 if (rc == -EAGAIN) 793 if (rc == -EAGAIN)
778 rc = 0; 794 rc = 0;
@@ -780,6 +796,82 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
780} 796}
781 797
782int 798int
799CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
800 __u16 type, const struct nls_table *nls_codepage, int remap)
801{
802 TRANSACTION2_SPI_REQ *pSMB = NULL;
803 TRANSACTION2_SPI_RSP *pSMBr = NULL;
804 struct unlink_psx_rq *pRqD;
805 int name_len;
806 int rc = 0;
807 int bytes_returned = 0;
808 __u16 params, param_offset, offset, byte_count;
809
810 cFYI(1, ("In POSIX delete"));
811PsxDelete:
812 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
813 (void **) &pSMBr);
814 if (rc)
815 return rc;
816
817 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
818 name_len =
819 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
820 PATH_MAX, nls_codepage, remap);
821 name_len++; /* trailing null */
822 name_len *= 2;
823 } else { /* BB add path length overrun check */
824 name_len = strnlen(fileName, PATH_MAX);
825 name_len++; /* trailing null */
826 strncpy(pSMB->FileName, fileName, name_len);
827 }
828
829 params = 6 + name_len;
830 pSMB->MaxParameterCount = cpu_to_le16(2);
831 pSMB->MaxDataCount = 0; /* BB double check this with jra */
832 pSMB->MaxSetupCount = 0;
833 pSMB->Reserved = 0;
834 pSMB->Flags = 0;
835 pSMB->Timeout = 0;
836 pSMB->Reserved2 = 0;
837 param_offset = offsetof(struct smb_com_transaction2_spi_req,
838 InformationLevel) - 4;
839 offset = param_offset + params;
840
841 /* Setup pointer to Request Data (inode type) */
842 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
843 pRqD->type = cpu_to_le16(type);
844 pSMB->ParameterOffset = cpu_to_le16(param_offset);
845 pSMB->DataOffset = cpu_to_le16(offset);
846 pSMB->SetupCount = 1;
847 pSMB->Reserved3 = 0;
848 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
849 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
850
851 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
852 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
853 pSMB->ParameterCount = cpu_to_le16(params);
854 pSMB->TotalParameterCount = pSMB->ParameterCount;
855 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
856 pSMB->Reserved4 = 0;
857 pSMB->hdr.smb_buf_length += byte_count;
858 pSMB->ByteCount = cpu_to_le16(byte_count);
859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
860 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
861 if (rc) {
862 cFYI(1, ("Posix delete returned %d", rc));
863 }
864 cifs_buf_release(pSMB);
865
866 cifs_stats_inc(&tcon->num_deletes);
867
868 if (rc == -EAGAIN)
869 goto PsxDelete;
870
871 return rc;
872}
873
874int
783CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 875CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
784 const struct nls_table *nls_codepage, int remap) 876 const struct nls_table *nls_codepage, int remap)
785{ 877{
@@ -797,7 +889,7 @@ DelFileRetry:
797 889
798 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 890 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
799 name_len = 891 name_len =
800 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, 892 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
801 PATH_MAX, nls_codepage, remap); 893 PATH_MAX, nls_codepage, remap);
802 name_len++; /* trailing null */ 894 name_len++; /* trailing null */
803 name_len *= 2; 895 name_len *= 2;
@@ -816,7 +908,7 @@ DelFileRetry:
816 cifs_stats_inc(&tcon->num_deletes); 908 cifs_stats_inc(&tcon->num_deletes);
817 if (rc) { 909 if (rc) {
818 cFYI(1, ("Error in RMFile = %d", rc)); 910 cFYI(1, ("Error in RMFile = %d", rc));
819 } 911 }
820 912
821 cifs_buf_release(pSMB); 913 cifs_buf_release(pSMB);
822 if (rc == -EAGAIN) 914 if (rc == -EAGAIN)
@@ -826,7 +918,7 @@ DelFileRetry:
826} 918}
827 919
828int 920int
829CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, 921CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
830 const struct nls_table *nls_codepage, int remap) 922 const struct nls_table *nls_codepage, int remap)
831{ 923{
832 DELETE_DIRECTORY_REQ *pSMB = NULL; 924 DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -887,7 +979,7 @@ MkDirRetry:
887 return rc; 979 return rc;
888 980
889 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 981 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
890 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, 982 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
891 PATH_MAX, nls_codepage, remap); 983 PATH_MAX, nls_codepage, remap);
892 name_len++; /* trailing null */ 984 name_len++; /* trailing null */
893 name_len *= 2; 985 name_len *= 2;
@@ -916,7 +1008,7 @@ MkDirRetry:
916int 1008int
917CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, 1009CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
918 __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData, 1010 __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData,
919 __u32 *pOplock, const char *name, 1011 __u32 *pOplock, const char *name,
920 const struct nls_table *nls_codepage, int remap) 1012 const struct nls_table *nls_codepage, int remap)
921{ 1013{
922 TRANSACTION2_SPI_REQ *pSMB = NULL; 1014 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -924,7 +1016,6 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
924 int name_len; 1016 int name_len;
925 int rc = 0; 1017 int rc = 0;
926 int bytes_returned = 0; 1018 int bytes_returned = 0;
927 char *data_offset;
928 __u16 params, param_offset, offset, byte_count, count; 1019 __u16 params, param_offset, offset, byte_count, count;
929 OPEN_PSX_REQ * pdata; 1020 OPEN_PSX_REQ * pdata;
930 OPEN_PSX_RSP * psx_rsp; 1021 OPEN_PSX_RSP * psx_rsp;
@@ -958,13 +1049,12 @@ PsxCreat:
958 pSMB->Timeout = 0; 1049 pSMB->Timeout = 0;
959 pSMB->Reserved2 = 0; 1050 pSMB->Reserved2 = 0;
960 param_offset = offsetof(struct smb_com_transaction2_spi_req, 1051 param_offset = offsetof(struct smb_com_transaction2_spi_req,
961 InformationLevel) - 4; 1052 InformationLevel) - 4;
962 offset = param_offset + params; 1053 offset = param_offset + params;
963 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
964 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); 1054 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
965 pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; 1055 pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
966 pdata->Permissions = cpu_to_le64(mode); 1056 pdata->Permissions = cpu_to_le64(mode);
967 pdata->PosixOpenFlags = cpu_to_le32(posix_flags); 1057 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
968 pdata->OpenFlags = cpu_to_le32(*pOplock); 1058 pdata->OpenFlags = cpu_to_le32(*pOplock);
969 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1059 pSMB->ParameterOffset = cpu_to_le16(param_offset);
970 pSMB->DataOffset = cpu_to_le16(offset); 1060 pSMB->DataOffset = cpu_to_le16(offset);
@@ -979,7 +1069,7 @@ PsxCreat:
979 pSMB->TotalParameterCount = pSMB->ParameterCount; 1069 pSMB->TotalParameterCount = pSMB->ParameterCount;
980 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1070 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
981 pSMB->Reserved4 = 0; 1071 pSMB->Reserved4 = 0;
982 pSMB->hdr.smb_buf_length += byte_count; 1072 pSMB->hdr.smb_buf_length += byte_count;
983 pSMB->ByteCount = cpu_to_le16(byte_count); 1073 pSMB->ByteCount = cpu_to_le16(byte_count);
984 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
985 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1075 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -988,7 +1078,7 @@ PsxCreat:
988 goto psx_create_err; 1078 goto psx_create_err;
989 } 1079 }
990 1080
991 cFYI(1,("copying inode info")); 1081 cFYI(1, ("copying inode info"));
992 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1082 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
993 1083
994 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) { 1084 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
@@ -997,34 +1087,33 @@ PsxCreat:
997 } 1087 }
998 1088
999 /* copy return information to pRetData */ 1089 /* copy return information to pRetData */
1000 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol 1090 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1001 + le16_to_cpu(pSMBr->t2.DataOffset)); 1091 + le16_to_cpu(pSMBr->t2.DataOffset));
1002 1092
1003 *pOplock = le16_to_cpu(psx_rsp->OplockFlags); 1093 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1004 if(netfid) 1094 if (netfid)
1005 *netfid = psx_rsp->Fid; /* cifs fid stays in le */ 1095 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1006 /* Let caller know file was created so we can set the mode. */ 1096 /* Let caller know file was created so we can set the mode. */
1007 /* Do we care about the CreateAction in any other cases? */ 1097 /* Do we care about the CreateAction in any other cases? */
1008 if(cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) 1098 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1009 *pOplock |= CIFS_CREATE_ACTION; 1099 *pOplock |= CIFS_CREATE_ACTION;
1010 /* check to make sure response data is there */ 1100 /* check to make sure response data is there */
1011 if(psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { 1101 if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
1012 pRetData->Type = -1; /* unknown */ 1102 pRetData->Type = -1; /* unknown */
1013#ifdef CONFIG_CIFS_DEBUG2 1103#ifdef CONFIG_CIFS_DEBUG2
1014 cFYI(1,("unknown type")); 1104 cFYI(1, ("unknown type"));
1015#endif 1105#endif
1016 } else { 1106 } else {
1017 if(pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) 1107 if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
1018 + sizeof(FILE_UNIX_BASIC_INFO)) { 1108 + sizeof(FILE_UNIX_BASIC_INFO)) {
1019 cERROR(1,("Open response data too small")); 1109 cERROR(1, ("Open response data too small"));
1020 pRetData->Type = -1; 1110 pRetData->Type = -1;
1021 goto psx_create_err; 1111 goto psx_create_err;
1022 } 1112 }
1023 memcpy((char *) pRetData, 1113 memcpy((char *) pRetData,
1024 (char *)psx_rsp + sizeof(OPEN_PSX_RSP), 1114 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1025 sizeof (FILE_UNIX_BASIC_INFO)); 1115 sizeof (FILE_UNIX_BASIC_INFO));
1026 } 1116 }
1027
1028 1117
1029psx_create_err: 1118psx_create_err:
1030 cifs_buf_release(pSMB); 1119 cifs_buf_release(pSMB);
@@ -1034,7 +1123,7 @@ psx_create_err:
1034 if (rc == -EAGAIN) 1123 if (rc == -EAGAIN)
1035 goto PsxCreat; 1124 goto PsxCreat;
1036 1125
1037 return rc; 1126 return rc;
1038} 1127}
1039 1128
1040static __u16 convert_disposition(int disposition) 1129static __u16 convert_disposition(int disposition)
@@ -1061,7 +1150,7 @@ static __u16 convert_disposition(int disposition)
1061 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1150 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
1062 break; 1151 break;
1063 default: 1152 default:
1064 cFYI(1,("unknown disposition %d",disposition)); 1153 cFYI(1, ("unknown disposition %d", disposition));
1065 ofun = SMBOPEN_OAPPEND; /* regular open */ 1154 ofun = SMBOPEN_OAPPEND; /* regular open */
1066 } 1155 }
1067 return ofun; 1156 return ofun;
@@ -1071,7 +1160,7 @@ int
1071SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1160SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
1072 const char *fileName, const int openDisposition, 1161 const char *fileName, const int openDisposition,
1073 const int access_flags, const int create_options, __u16 * netfid, 1162 const int access_flags, const int create_options, __u16 * netfid,
1074 int *pOplock, FILE_ALL_INFO * pfile_info, 1163 int *pOplock, FILE_ALL_INFO * pfile_info,
1075 const struct nls_table *nls_codepage, int remap) 1164 const struct nls_table *nls_codepage, int remap)
1076{ 1165{
1077 int rc = -EACCES; 1166 int rc = -EACCES;
@@ -1113,16 +1202,16 @@ OldOpenRetry:
1113 1 = write 1202 1 = write
1114 2 = rw 1203 2 = rw
1115 3 = execute 1204 3 = execute
1116 */ 1205 */
1117 pSMB->Mode = cpu_to_le16(2); 1206 pSMB->Mode = cpu_to_le16(2);
1118 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1207 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
1119 /* set file as system file if special file such 1208 /* set file as system file if special file such
1120 as fifo and server expecting SFU style and 1209 as fifo and server expecting SFU style and
1121 no Unix extensions */ 1210 no Unix extensions */
1122 1211
1123 if(create_options & CREATE_OPTION_SPECIAL) 1212 if (create_options & CREATE_OPTION_SPECIAL)
1124 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); 1213 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
1125 else 1214 else
1126 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */ 1215 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
1127 1216
1128 /* if ((omode & S_IWUGO) == 0) 1217 /* if ((omode & S_IWUGO) == 0)
@@ -1132,7 +1221,8 @@ OldOpenRetry:
1132 being created */ 1221 being created */
1133 1222
1134 /* BB FIXME BB */ 1223 /* BB FIXME BB */
1135/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */ 1224/* pSMB->CreateOptions = cpu_to_le32(create_options &
1225 CREATE_OPTIONS_MASK); */
1136 /* BB FIXME END BB */ 1226 /* BB FIXME END BB */
1137 1227
1138 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1228 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
@@ -1143,7 +1233,7 @@ OldOpenRetry:
1143 pSMB->ByteCount = cpu_to_le16(count); 1233 pSMB->ByteCount = cpu_to_le16(count);
1144 /* long_op set to 1 to allow for oplock break timeouts */ 1234 /* long_op set to 1 to allow for oplock break timeouts */
1145 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1235 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1146 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1236 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
1147 cifs_stats_inc(&tcon->num_opens); 1237 cifs_stats_inc(&tcon->num_opens);
1148 if (rc) { 1238 if (rc) {
1149 cFYI(1, ("Error in Open = %d", rc)); 1239 cFYI(1, ("Error in Open = %d", rc));
@@ -1156,17 +1246,17 @@ OldOpenRetry:
1156 /* Let caller know file was created so we can set the mode. */ 1246 /* Let caller know file was created so we can set the mode. */
1157 /* Do we care about the CreateAction in any other cases? */ 1247 /* Do we care about the CreateAction in any other cases? */
1158 /* BB FIXME BB */ 1248 /* BB FIXME BB */
1159/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1249/* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1160 *pOplock |= CIFS_CREATE_ACTION; */ 1250 *pOplock |= CIFS_CREATE_ACTION; */
1161 /* BB FIXME END */ 1251 /* BB FIXME END */
1162 1252
1163 if(pfile_info) { 1253 if (pfile_info) {
1164 pfile_info->CreationTime = 0; /* BB convert CreateTime*/ 1254 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
1165 pfile_info->LastAccessTime = 0; /* BB fixme */ 1255 pfile_info->LastAccessTime = 0; /* BB fixme */
1166 pfile_info->LastWriteTime = 0; /* BB fixme */ 1256 pfile_info->LastWriteTime = 0; /* BB fixme */
1167 pfile_info->ChangeTime = 0; /* BB fixme */ 1257 pfile_info->ChangeTime = 0; /* BB fixme */
1168 pfile_info->Attributes = 1258 pfile_info->Attributes =
1169 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 1259 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
1170 /* the file_info buf is endian converted by caller */ 1260 /* the file_info buf is endian converted by caller */
1171 pfile_info->AllocationSize = 1261 pfile_info->AllocationSize =
1172 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); 1262 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
@@ -1185,7 +1275,7 @@ int
1185CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 1275CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
1186 const char *fileName, const int openDisposition, 1276 const char *fileName, const int openDisposition,
1187 const int access_flags, const int create_options, __u16 * netfid, 1277 const int access_flags, const int create_options, __u16 * netfid,
1188 int *pOplock, FILE_ALL_INFO * pfile_info, 1278 int *pOplock, FILE_ALL_INFO * pfile_info,
1189 const struct nls_table *nls_codepage, int remap) 1279 const struct nls_table *nls_codepage, int remap)
1190{ 1280{
1191 int rc = -EACCES; 1281 int rc = -EACCES;
@@ -1228,7 +1318,7 @@ openRetry:
1228 /* set file as system file if special file such 1318 /* set file as system file if special file such
1229 as fifo and server expecting SFU style and 1319 as fifo and server expecting SFU style and
1230 no Unix extensions */ 1320 no Unix extensions */
1231 if(create_options & CREATE_OPTION_SPECIAL) 1321 if (create_options & CREATE_OPTION_SPECIAL)
1232 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1322 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
1233 else 1323 else
1234 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1324 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
@@ -1266,10 +1356,10 @@ openRetry:
1266 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1356 *netfid = pSMBr->Fid; /* cifs fid stays in le */
1267 /* Let caller know file was created so we can set the mode. */ 1357 /* Let caller know file was created so we can set the mode. */
1268 /* Do we care about the CreateAction in any other cases? */ 1358 /* Do we care about the CreateAction in any other cases? */
1269 if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1359 if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
1270 *pOplock |= CIFS_CREATE_ACTION; 1360 *pOplock |= CIFS_CREATE_ACTION;
1271 if(pfile_info) { 1361 if (pfile_info) {
1272 memcpy((char *)pfile_info,(char *)&pSMBr->CreationTime, 1362 memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
1273 36 /* CreationTime to Attributes */); 1363 36 /* CreationTime to Attributes */);
1274 /* the file_info buf is endian converted by caller */ 1364 /* the file_info buf is endian converted by caller */
1275 pfile_info->AllocationSize = pSMBr->AllocationSize; 1365 pfile_info->AllocationSize = pSMBr->AllocationSize;
@@ -1285,10 +1375,9 @@ openRetry:
1285} 1375}
1286 1376
1287int 1377int
1288CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 1378CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1289 const int netfid, const unsigned int count, 1379 const unsigned int count, const __u64 lseek, unsigned int *nbytes,
1290 const __u64 lseek, unsigned int *nbytes, char **buf, 1380 char **buf, int *pbuf_type)
1291 int * pbuf_type)
1292{ 1381{
1293 int rc = -EACCES; 1382 int rc = -EACCES;
1294 READ_REQ *pSMB = NULL; 1383 READ_REQ *pSMB = NULL;
@@ -1298,8 +1387,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1298 int resp_buf_type = 0; 1387 int resp_buf_type = 0;
1299 struct kvec iov[1]; 1388 struct kvec iov[1];
1300 1389
1301 cFYI(1,("Reading %d bytes on fid %d",count,netfid)); 1390 cFYI(1, ("Reading %d bytes on fid %d", count, netfid));
1302 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1391 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1303 wct = 12; 1392 wct = 12;
1304 else 1393 else
1305 wct = 10; /* old style read */ 1394 wct = 10; /* old style read */
@@ -1316,28 +1405,28 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1316 pSMB->AndXCommand = 0xFF; /* none */ 1405 pSMB->AndXCommand = 0xFF; /* none */
1317 pSMB->Fid = netfid; 1406 pSMB->Fid = netfid;
1318 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 1407 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
1319 if(wct == 12) 1408 if (wct == 12)
1320 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 1409 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
1321 else if((lseek >> 32) > 0) /* can not handle this big offset for old */ 1410 else if ((lseek >> 32) > 0) /* can not handle this big offset for old */
1322 return -EIO; 1411 return -EIO;
1323 1412
1324 pSMB->Remaining = 0; 1413 pSMB->Remaining = 0;
1325 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1414 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
1326 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1415 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
1327 if(wct == 12) 1416 if (wct == 12)
1328 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1417 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
1329 else { 1418 else {
1330 /* old style read */ 1419 /* old style read */
1331 struct smb_com_readx_req * pSMBW = 1420 struct smb_com_readx_req *pSMBW =
1332 (struct smb_com_readx_req *)pSMB; 1421 (struct smb_com_readx_req *)pSMB;
1333 pSMBW->ByteCount = 0; 1422 pSMBW->ByteCount = 0;
1334 } 1423 }
1335 1424
1336 iov[0].iov_base = (char *)pSMB; 1425 iov[0].iov_base = (char *)pSMB;
1337 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1426 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1338 rc = SendReceive2(xid, tcon->ses, iov, 1427 rc = SendReceive2(xid, tcon->ses, iov,
1339 1 /* num iovecs */, 1428 1 /* num iovecs */,
1340 &resp_buf_type, 0); 1429 &resp_buf_type, 0);
1341 cifs_stats_inc(&tcon->num_reads); 1430 cifs_stats_inc(&tcon->num_reads);
1342 pSMBr = (READ_RSP *)iov[0].iov_base; 1431 pSMBr = (READ_RSP *)iov[0].iov_base;
1343 if (rc) { 1432 if (rc) {
@@ -1351,33 +1440,34 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1351 /*check that DataLength would not go beyond end of SMB */ 1440 /*check that DataLength would not go beyond end of SMB */
1352 if ((data_length > CIFSMaxBufSize) 1441 if ((data_length > CIFSMaxBufSize)
1353 || (data_length > count)) { 1442 || (data_length > count)) {
1354 cFYI(1,("bad length %d for count %d",data_length,count)); 1443 cFYI(1, ("bad length %d for count %d",
1444 data_length, count));
1355 rc = -EIO; 1445 rc = -EIO;
1356 *nbytes = 0; 1446 *nbytes = 0;
1357 } else { 1447 } else {
1358 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1448 pReadData = (char *) (&pSMBr->hdr.Protocol) +
1359 le16_to_cpu(pSMBr->DataOffset); 1449 le16_to_cpu(pSMBr->DataOffset);
1360/* if(rc = copy_to_user(buf, pReadData, data_length)) { 1450/* if (rc = copy_to_user(buf, pReadData, data_length)) {
1361 cERROR(1,("Faulting on read rc = %d",rc)); 1451 cERROR(1,("Faulting on read rc = %d",rc));
1362 rc = -EFAULT; 1452 rc = -EFAULT;
1363 }*/ /* can not use copy_to_user when using page cache*/ 1453 }*/ /* can not use copy_to_user when using page cache*/
1364 if(*buf) 1454 if (*buf)
1365 memcpy(*buf,pReadData,data_length); 1455 memcpy(*buf, pReadData, data_length);
1366 } 1456 }
1367 } 1457 }
1368 1458
1369/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1459/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1370 if(*buf) { 1460 if (*buf) {
1371 if(resp_buf_type == CIFS_SMALL_BUFFER) 1461 if (resp_buf_type == CIFS_SMALL_BUFFER)
1372 cifs_small_buf_release(iov[0].iov_base); 1462 cifs_small_buf_release(iov[0].iov_base);
1373 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1463 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1374 cifs_buf_release(iov[0].iov_base); 1464 cifs_buf_release(iov[0].iov_base);
1375 } else if(resp_buf_type != CIFS_NO_BUFFER) { 1465 } else if (resp_buf_type != CIFS_NO_BUFFER) {
1376 /* return buffer to caller to free */ 1466 /* return buffer to caller to free */
1377 *buf = iov[0].iov_base; 1467 *buf = iov[0].iov_base;
1378 if(resp_buf_type == CIFS_SMALL_BUFFER) 1468 if (resp_buf_type == CIFS_SMALL_BUFFER)
1379 *pbuf_type = CIFS_SMALL_BUFFER; 1469 *pbuf_type = CIFS_SMALL_BUFFER;
1380 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1470 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1381 *pbuf_type = CIFS_LARGE_BUFFER; 1471 *pbuf_type = CIFS_LARGE_BUFFER;
1382 } /* else no valid buffer on return - leave as null */ 1472 } /* else no valid buffer on return - leave as null */
1383 1473
@@ -1391,7 +1481,7 @@ int
1391CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 1481CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1392 const int netfid, const unsigned int count, 1482 const int netfid, const unsigned int count,
1393 const __u64 offset, unsigned int *nbytes, const char *buf, 1483 const __u64 offset, unsigned int *nbytes, const char *buf,
1394 const char __user * ubuf, const int long_op) 1484 const char __user *ubuf, const int long_op)
1395{ 1485{
1396 int rc = -EACCES; 1486 int rc = -EACCES;
1397 WRITE_REQ *pSMB = NULL; 1487 WRITE_REQ *pSMB = NULL;
@@ -1401,10 +1491,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1401 __u16 byte_count; 1491 __u16 byte_count;
1402 1492
1403 /* cFYI(1,("write at %lld %d bytes",offset,count));*/ 1493 /* cFYI(1,("write at %lld %d bytes",offset,count));*/
1404 if(tcon->ses == NULL) 1494 if (tcon->ses == NULL)
1405 return -ECONNABORTED; 1495 return -ECONNABORTED;
1406 1496
1407 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1497 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1408 wct = 14; 1498 wct = 14;
1409 else 1499 else
1410 wct = 12; 1500 wct = 12;
@@ -1420,20 +1510,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1420 pSMB->AndXCommand = 0xFF; /* none */ 1510 pSMB->AndXCommand = 0xFF; /* none */
1421 pSMB->Fid = netfid; 1511 pSMB->Fid = netfid;
1422 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1512 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1423 if(wct == 14) 1513 if (wct == 14)
1424 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1514 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1425 else if((offset >> 32) > 0) /* can not handle this big offset for old */ 1515 else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
1426 return -EIO; 1516 return -EIO;
1427 1517
1428 pSMB->Reserved = 0xFFFFFFFF; 1518 pSMB->Reserved = 0xFFFFFFFF;
1429 pSMB->WriteMode = 0; 1519 pSMB->WriteMode = 0;
1430 pSMB->Remaining = 0; 1520 pSMB->Remaining = 0;
1431 1521
1432 /* Can increase buffer size if buffer is big enough in some cases - ie we 1522 /* Can increase buffer size if buffer is big enough in some cases ie we
1433 can send more if LARGE_WRITE_X capability returned by the server and if 1523 can send more if LARGE_WRITE_X capability returned by the server and if
1434 our buffer is big enough or if we convert to iovecs on socket writes 1524 our buffer is big enough or if we convert to iovecs on socket writes
1435 and eliminate the copy to the CIFS buffer */ 1525 and eliminate the copy to the CIFS buffer */
1436 if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1526 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1437 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1527 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1438 } else { 1528 } else {
1439 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1529 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
@@ -1443,11 +1533,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1443 if (bytes_sent > count) 1533 if (bytes_sent > count)
1444 bytes_sent = count; 1534 bytes_sent = count;
1445 pSMB->DataOffset = 1535 pSMB->DataOffset =
1446 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1536 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1447 if(buf) 1537 if (buf)
1448 memcpy(pSMB->Data,buf,bytes_sent); 1538 memcpy(pSMB->Data, buf, bytes_sent);
1449 else if(ubuf) { 1539 else if (ubuf) {
1450 if(copy_from_user(pSMB->Data,ubuf,bytes_sent)) { 1540 if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
1451 cifs_buf_release(pSMB); 1541 cifs_buf_release(pSMB);
1452 return -EFAULT; 1542 return -EFAULT;
1453 } 1543 }
@@ -1456,7 +1546,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1456 cifs_buf_release(pSMB); 1546 cifs_buf_release(pSMB);
1457 return -EINVAL; 1547 return -EINVAL;
1458 } /* else setting file size with write of zero bytes */ 1548 } /* else setting file size with write of zero bytes */
1459 if(wct == 14) 1549 if (wct == 14)
1460 byte_count = bytes_sent + 1; /* pad */ 1550 byte_count = bytes_sent + 1; /* pad */
1461 else /* wct == 12 */ { 1551 else /* wct == 12 */ {
1462 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1552 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
@@ -1465,10 +1555,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1465 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1555 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1466 pSMB->hdr.smb_buf_length += byte_count; 1556 pSMB->hdr.smb_buf_length += byte_count;
1467 1557
1468 if(wct == 14) 1558 if (wct == 14)
1469 pSMB->ByteCount = cpu_to_le16(byte_count); 1559 pSMB->ByteCount = cpu_to_le16(byte_count);
1470 else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */ 1560 else { /* old style write has byte count 4 bytes earlier
1471 struct smb_com_writex_req * pSMBW = 1561 so 4 bytes pad */
1562 struct smb_com_writex_req *pSMBW =
1472 (struct smb_com_writex_req *)pSMB; 1563 (struct smb_com_writex_req *)pSMB;
1473 pSMBW->ByteCount = cpu_to_le16(byte_count); 1564 pSMBW->ByteCount = cpu_to_le16(byte_count);
1474 } 1565 }
@@ -1487,7 +1578,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1487 1578
1488 cifs_buf_release(pSMB); 1579 cifs_buf_release(pSMB);
1489 1580
1490 /* Note: On -EAGAIN error only caller can retry on handle based calls 1581 /* Note: On -EAGAIN error only caller can retry on handle based calls
1491 since file handle passed in no longer valid */ 1582 since file handle passed in no longer valid */
1492 1583
1493 return rc; 1584 return rc;
@@ -1505,9 +1596,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1505 int smb_hdr_len; 1596 int smb_hdr_len;
1506 int resp_buf_type = 0; 1597 int resp_buf_type = 0;
1507 1598
1508 cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); 1599 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count));
1509 1600
1510 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1601 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1511 wct = 14; 1602 wct = 14;
1512 else 1603 else
1513 wct = 12; 1604 wct = 12;
@@ -1521,37 +1612,37 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1521 pSMB->AndXCommand = 0xFF; /* none */ 1612 pSMB->AndXCommand = 0xFF; /* none */
1522 pSMB->Fid = netfid; 1613 pSMB->Fid = netfid;
1523 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1614 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1524 if(wct == 14) 1615 if (wct == 14)
1525 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1616 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1526 else if((offset >> 32) > 0) /* can not handle this big offset for old */ 1617 else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
1527 return -EIO; 1618 return -EIO;
1528 pSMB->Reserved = 0xFFFFFFFF; 1619 pSMB->Reserved = 0xFFFFFFFF;
1529 pSMB->WriteMode = 0; 1620 pSMB->WriteMode = 0;
1530 pSMB->Remaining = 0; 1621 pSMB->Remaining = 0;
1531 1622
1532 pSMB->DataOffset = 1623 pSMB->DataOffset =
1533 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1624 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1534 1625
1535 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1626 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1536 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1627 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1537 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ 1628 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
1538 if(wct == 14) 1629 if (wct == 14)
1539 pSMB->hdr.smb_buf_length += count+1; 1630 pSMB->hdr.smb_buf_length += count+1;
1540 else /* wct == 12 */ 1631 else /* wct == 12 */
1541 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 1632 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
1542 if(wct == 14) 1633 if (wct == 14)
1543 pSMB->ByteCount = cpu_to_le16(count + 1); 1634 pSMB->ByteCount = cpu_to_le16(count + 1);
1544 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1635 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1545 struct smb_com_writex_req * pSMBW = 1636 struct smb_com_writex_req *pSMBW =
1546 (struct smb_com_writex_req *)pSMB; 1637 (struct smb_com_writex_req *)pSMB;
1547 pSMBW->ByteCount = cpu_to_le16(count + 5); 1638 pSMBW->ByteCount = cpu_to_le16(count + 5);
1548 } 1639 }
1549 iov[0].iov_base = pSMB; 1640 iov[0].iov_base = pSMB;
1550 if(wct == 14) 1641 if (wct == 14)
1551 iov[0].iov_len = smb_hdr_len + 4; 1642 iov[0].iov_len = smb_hdr_len + 4;
1552 else /* wct == 12 pad bigger by four bytes */ 1643 else /* wct == 12 pad bigger by four bytes */
1553 iov[0].iov_len = smb_hdr_len + 8; 1644 iov[0].iov_len = smb_hdr_len + 8;
1554 1645
1555 1646
1556 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1647 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
1557 long_op); 1648 long_op);
@@ -1559,7 +1650,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1559 if (rc) { 1650 if (rc) {
1560 cFYI(1, ("Send error Write2 = %d", rc)); 1651 cFYI(1, ("Send error Write2 = %d", rc));
1561 *nbytes = 0; 1652 *nbytes = 0;
1562 } else if(resp_buf_type == 0) { 1653 } else if (resp_buf_type == 0) {
1563 /* presumably this can not happen, but best to be safe */ 1654 /* presumably this can not happen, but best to be safe */
1564 rc = -EIO; 1655 rc = -EIO;
1565 *nbytes = 0; 1656 *nbytes = 0;
@@ -1568,15 +1659,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1568 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1659 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1569 *nbytes = (*nbytes) << 16; 1660 *nbytes = (*nbytes) << 16;
1570 *nbytes += le16_to_cpu(pSMBr->Count); 1661 *nbytes += le16_to_cpu(pSMBr->Count);
1571 } 1662 }
1572 1663
1573/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1664/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1574 if(resp_buf_type == CIFS_SMALL_BUFFER) 1665 if (resp_buf_type == CIFS_SMALL_BUFFER)
1575 cifs_small_buf_release(iov[0].iov_base); 1666 cifs_small_buf_release(iov[0].iov_base);
1576 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1667 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1577 cifs_buf_release(iov[0].iov_base); 1668 cifs_buf_release(iov[0].iov_base);
1578 1669
1579 /* Note: On -EAGAIN error only caller can retry on handle based calls 1670 /* Note: On -EAGAIN error only caller can retry on handle based calls
1580 since file handle passed in no longer valid */ 1671 since file handle passed in no longer valid */
1581 1672
1582 return rc; 1673 return rc;
@@ -1596,7 +1687,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1596 int timeout = 0; 1687 int timeout = 0;
1597 __u16 count; 1688 __u16 count;
1598 1689
1599 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock)); 1690 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock));
1600 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1691 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1601 1692
1602 if (rc) 1693 if (rc)
@@ -1604,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1604 1695
1605 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ 1696 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1606 1697
1607 if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1698 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1608 timeout = -1; /* no response expected */ 1699 timeout = -1; /* no response expected */
1609 pSMB->Timeout = 0; 1700 pSMB->Timeout = 0;
1610 } else if (waitFlag == TRUE) { 1701 } else if (waitFlag == TRUE) {
@@ -1620,7 +1711,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1620 pSMB->AndXCommand = 0xFF; /* none */ 1711 pSMB->AndXCommand = 0xFF; /* none */
1621 pSMB->Fid = smb_file_id; /* netfid stays le */ 1712 pSMB->Fid = smb_file_id; /* netfid stays le */
1622 1713
1623 if((numLock != 0) || (numUnlock != 0)) { 1714 if ((numLock != 0) || (numUnlock != 0)) {
1624 pSMB->Locks[0].Pid = cpu_to_le16(current->tgid); 1715 pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
1625 /* BB where to store pid high? */ 1716 /* BB where to store pid high? */
1626 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 1717 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
@@ -1648,7 +1739,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1648 } 1739 }
1649 cifs_small_buf_release(pSMB); 1740 cifs_small_buf_release(pSMB);
1650 1741
1651 /* Note: On -EAGAIN error only caller can retry on handle based calls 1742 /* Note: On -EAGAIN error only caller can retry on handle based calls
1652 since file handle passed in no longer valid */ 1743 since file handle passed in no longer valid */
1653 return rc; 1744 return rc;
1654} 1745}
@@ -1656,12 +1747,11 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1656int 1747int
1657CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 1748CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1658 const __u16 smb_file_id, const int get_flag, const __u64 len, 1749 const __u16 smb_file_id, const int get_flag, const __u64 len,
1659 struct file_lock *pLockData, const __u16 lock_type, 1750 struct file_lock *pLockData, const __u16 lock_type,
1660 const int waitFlag) 1751 const int waitFlag)
1661{ 1752{
1662 struct smb_com_transaction2_sfi_req *pSMB = NULL; 1753 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1663 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1754 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1664 char *data_offset;
1665 struct cifs_posix_lock *parm_data; 1755 struct cifs_posix_lock *parm_data;
1666 int rc = 0; 1756 int rc = 0;
1667 int timeout = 0; 1757 int timeout = 0;
@@ -1670,7 +1760,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1670 1760
1671 cFYI(1, ("Posix Lock")); 1761 cFYI(1, ("Posix Lock"));
1672 1762
1673 if(pLockData == NULL) 1763 if (pLockData == NULL)
1674 return EINVAL; 1764 return EINVAL;
1675 1765
1676 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 1766 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
@@ -1680,7 +1770,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1680 1770
1681 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 1771 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1682 1772
1683 params = 6; 1773 params = 6;
1684 pSMB->MaxSetupCount = 0; 1774 pSMB->MaxSetupCount = 0;
1685 pSMB->Reserved = 0; 1775 pSMB->Reserved = 0;
1686 pSMB->Flags = 0; 1776 pSMB->Flags = 0;
@@ -1688,14 +1778,12 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1688 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 1778 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1689 offset = param_offset + params; 1779 offset = param_offset + params;
1690 1780
1691 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1692
1693 count = sizeof(struct cifs_posix_lock); 1781 count = sizeof(struct cifs_posix_lock);
1694 pSMB->MaxParameterCount = cpu_to_le16(2); 1782 pSMB->MaxParameterCount = cpu_to_le16(2);
1695 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ 1783 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
1696 pSMB->SetupCount = 1; 1784 pSMB->SetupCount = 1;
1697 pSMB->Reserved3 = 0; 1785 pSMB->Reserved3 = 0;
1698 if(get_flag) 1786 if (get_flag)
1699 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 1787 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
1700 else 1788 else
1701 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 1789 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
@@ -1705,11 +1793,11 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1705 pSMB->TotalDataCount = pSMB->DataCount; 1793 pSMB->TotalDataCount = pSMB->DataCount;
1706 pSMB->TotalParameterCount = pSMB->ParameterCount; 1794 pSMB->TotalParameterCount = pSMB->ParameterCount;
1707 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1795 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1708 parm_data = (struct cifs_posix_lock *) 1796 parm_data = (struct cifs_posix_lock *)
1709 (((char *) &pSMB->hdr.Protocol) + offset); 1797 (((char *) &pSMB->hdr.Protocol) + offset);
1710 1798
1711 parm_data->lock_type = cpu_to_le16(lock_type); 1799 parm_data->lock_type = cpu_to_le16(lock_type);
1712 if(waitFlag) { 1800 if (waitFlag) {
1713 timeout = 3; /* blocking operation, no timeout */ 1801 timeout = 3; /* blocking operation, no timeout */
1714 parm_data->lock_flags = cpu_to_le16(1); 1802 parm_data->lock_flags = cpu_to_le16(1);
1715 pSMB->Timeout = cpu_to_le32(-1); 1803 pSMB->Timeout = cpu_to_le32(-1);
@@ -1746,22 +1834,22 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1746 rc = -EIO; /* bad smb */ 1834 rc = -EIO; /* bad smb */
1747 goto plk_err_exit; 1835 goto plk_err_exit;
1748 } 1836 }
1749 if(pLockData == NULL) { 1837 if (pLockData == NULL) {
1750 rc = -EINVAL; 1838 rc = -EINVAL;
1751 goto plk_err_exit; 1839 goto plk_err_exit;
1752 } 1840 }
1753 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 1841 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
1754 data_count = le16_to_cpu(pSMBr->t2.DataCount); 1842 data_count = le16_to_cpu(pSMBr->t2.DataCount);
1755 if(data_count < sizeof(struct cifs_posix_lock)) { 1843 if (data_count < sizeof(struct cifs_posix_lock)) {
1756 rc = -EIO; 1844 rc = -EIO;
1757 goto plk_err_exit; 1845 goto plk_err_exit;
1758 } 1846 }
1759 parm_data = (struct cifs_posix_lock *) 1847 parm_data = (struct cifs_posix_lock *)
1760 ((char *)&pSMBr->hdr.Protocol + data_offset); 1848 ((char *)&pSMBr->hdr.Protocol + data_offset);
1761 if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 1849 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
1762 pLockData->fl_type = F_UNLCK; 1850 pLockData->fl_type = F_UNLCK;
1763 } 1851 }
1764 1852
1765plk_err_exit: 1853plk_err_exit:
1766 if (pSMB) 1854 if (pSMB)
1767 cifs_small_buf_release(pSMB); 1855 cifs_small_buf_release(pSMB);
@@ -1784,7 +1872,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1784 1872
1785/* do not retry on dead session on close */ 1873/* do not retry on dead session on close */
1786 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 1874 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
1787 if(rc == -EAGAIN) 1875 if (rc == -EAGAIN)
1788 return 0; 1876 return 0;
1789 if (rc) 1877 if (rc)
1790 return rc; 1878 return rc;
@@ -1798,7 +1886,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1798 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1886 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1799 cifs_stats_inc(&tcon->num_closes); 1887 cifs_stats_inc(&tcon->num_closes);
1800 if (rc) { 1888 if (rc) {
1801 if(rc!=-EINTR) { 1889 if (rc != -EINTR) {
1802 /* EINTR is expected when user ctl-c to kill app */ 1890 /* EINTR is expected when user ctl-c to kill app */
1803 cERROR(1, ("Send error in Close = %d", rc)); 1891 cERROR(1, ("Send error in Close = %d", rc));
1804 } 1892 }
@@ -1807,7 +1895,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1807 cifs_small_buf_release(pSMB); 1895 cifs_small_buf_release(pSMB);
1808 1896
1809 /* Since session is dead, file will be closed on server already */ 1897 /* Since session is dead, file will be closed on server already */
1810 if(rc == -EAGAIN) 1898 if (rc == -EAGAIN)
1811 rc = 0; 1899 rc = 0;
1812 1900
1813 return rc; 1901 return rc;
@@ -1839,7 +1927,7 @@ renameRetry:
1839 1927
1840 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1928 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1841 name_len = 1929 name_len =
1842 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, 1930 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
1843 PATH_MAX, nls_codepage, remap); 1931 PATH_MAX, nls_codepage, remap);
1844 name_len++; /* trailing null */ 1932 name_len++; /* trailing null */
1845 name_len *= 2; 1933 name_len *= 2;
@@ -1851,7 +1939,7 @@ renameRetry:
1851 toName, PATH_MAX, nls_codepage, remap); 1939 toName, PATH_MAX, nls_codepage, remap);
1852 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1940 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1853 name_len2 *= 2; /* convert to bytes */ 1941 name_len2 *= 2; /* convert to bytes */
1854 } else { /* BB improve the check for buffer overruns BB */ 1942 } else { /* BB improve the check for buffer overruns BB */
1855 name_len = strnlen(fromName, PATH_MAX); 1943 name_len = strnlen(fromName, PATH_MAX);
1856 name_len++; /* trailing null */ 1944 name_len++; /* trailing null */
1857 strncpy(pSMB->OldFileName, fromName, name_len); 1945 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -1872,7 +1960,7 @@ renameRetry:
1872 cifs_stats_inc(&tcon->num_renames); 1960 cifs_stats_inc(&tcon->num_renames);
1873 if (rc) { 1961 if (rc) {
1874 cFYI(1, ("Send error in rename = %d", rc)); 1962 cFYI(1, ("Send error in rename = %d", rc));
1875 } 1963 }
1876 1964
1877 cifs_buf_release(pSMB); 1965 cifs_buf_release(pSMB);
1878 1966
@@ -1882,13 +1970,13 @@ renameRetry:
1882 return rc; 1970 return rc;
1883} 1971}
1884 1972
1885int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 1973int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
1886 int netfid, char * target_name, 1974 int netfid, char *target_name,
1887 const struct nls_table * nls_codepage, int remap) 1975 const struct nls_table *nls_codepage, int remap)
1888{ 1976{
1889 struct smb_com_transaction2_sfi_req *pSMB = NULL; 1977 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1890 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 1978 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1891 struct set_file_rename * rename_info; 1979 struct set_file_rename *rename_info;
1892 char *data_offset; 1980 char *data_offset;
1893 char dummy_string[30]; 1981 char dummy_string[30];
1894 int rc = 0; 1982 int rc = 0;
@@ -1927,13 +2015,14 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1927 rename_info->overwrite = cpu_to_le32(1); 2015 rename_info->overwrite = cpu_to_le32(1);
1928 rename_info->root_fid = 0; 2016 rename_info->root_fid = 0;
1929 /* unicode only call */ 2017 /* unicode only call */
1930 if(target_name == NULL) { 2018 if (target_name == NULL) {
1931 sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); 2019 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
1932 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, 2020 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1933 dummy_string, 24, nls_codepage, remap); 2021 dummy_string, 24, nls_codepage, remap);
1934 } else { 2022 } else {
1935 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, 2023 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1936 target_name, PATH_MAX, nls_codepage, remap); 2024 target_name, PATH_MAX, nls_codepage,
2025 remap);
1937 } 2026 }
1938 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2027 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
1939 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2; 2028 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
@@ -1947,10 +2036,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1947 pSMB->hdr.smb_buf_length += byte_count; 2036 pSMB->hdr.smb_buf_length += byte_count;
1948 pSMB->ByteCount = cpu_to_le16(byte_count); 2037 pSMB->ByteCount = cpu_to_le16(byte_count);
1949 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2038 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
1950 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2039 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1951 cifs_stats_inc(&pTcon->num_t2renames); 2040 cifs_stats_inc(&pTcon->num_t2renames);
1952 if (rc) { 2041 if (rc) {
1953 cFYI(1,("Send error in Rename (by file handle) = %d", rc)); 2042 cFYI(1, ("Send error in Rename (by file handle) = %d", rc));
1954 } 2043 }
1955 2044
1956 cifs_buf_release(pSMB); 2045 cifs_buf_release(pSMB);
@@ -1962,9 +2051,9 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1962} 2051}
1963 2052
1964int 2053int
1965CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 2054CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
1966 const __u16 target_tid, const char *toName, const int flags, 2055 const __u16 target_tid, const char *toName, const int flags,
1967 const struct nls_table *nls_codepage, int remap) 2056 const struct nls_table *nls_codepage, int remap)
1968{ 2057{
1969 int rc = 0; 2058 int rc = 0;
1970 COPY_REQ *pSMB = NULL; 2059 COPY_REQ *pSMB = NULL;
@@ -1986,7 +2075,7 @@ copyRetry:
1986 pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 2075 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
1987 2076
1988 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2077 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1989 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, 2078 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
1990 fromName, PATH_MAX, nls_codepage, 2079 fromName, PATH_MAX, nls_codepage,
1991 remap); 2080 remap);
1992 name_len++; /* trailing null */ 2081 name_len++; /* trailing null */
@@ -1994,11 +2083,12 @@ copyRetry:
1994 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2083 pSMB->OldFileName[name_len] = 0x04; /* pad */
1995 /* protocol requires ASCII signature byte on Unicode string */ 2084 /* protocol requires ASCII signature byte on Unicode string */
1996 pSMB->OldFileName[name_len + 1] = 0x00; 2085 pSMB->OldFileName[name_len + 1] = 0x00;
1997 name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 2086 name_len2 =
2087 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1998 toName, PATH_MAX, nls_codepage, remap); 2088 toName, PATH_MAX, nls_codepage, remap);
1999 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2089 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2000 name_len2 *= 2; /* convert to bytes */ 2090 name_len2 *= 2; /* convert to bytes */
2001 } else { /* BB improve the check for buffer overruns BB */ 2091 } else { /* BB improve the check for buffer overruns BB */
2002 name_len = strnlen(fromName, PATH_MAX); 2092 name_len = strnlen(fromName, PATH_MAX);
2003 name_len++; /* trailing null */ 2093 name_len++; /* trailing null */
2004 strncpy(pSMB->OldFileName, fromName, name_len); 2094 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -2058,7 +2148,7 @@ createSymLinkRetry:
2058 name_len++; /* trailing null */ 2148 name_len++; /* trailing null */
2059 name_len *= 2; 2149 name_len *= 2;
2060 2150
2061 } else { /* BB improve the check for buffer overruns BB */ 2151 } else { /* BB improve the check for buffer overruns BB */
2062 name_len = strnlen(fromName, PATH_MAX); 2152 name_len = strnlen(fromName, PATH_MAX);
2063 name_len++; /* trailing null */ 2153 name_len++; /* trailing null */
2064 strncpy(pSMB->FileName, fromName, name_len); 2154 strncpy(pSMB->FileName, fromName, name_len);
@@ -2070,7 +2160,7 @@ createSymLinkRetry:
2070 pSMB->Timeout = 0; 2160 pSMB->Timeout = 0;
2071 pSMB->Reserved2 = 0; 2161 pSMB->Reserved2 = 0;
2072 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2162 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2073 InformationLevel) - 4; 2163 InformationLevel) - 4;
2074 offset = param_offset + params; 2164 offset = param_offset + params;
2075 2165
2076 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2166 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
@@ -2081,7 +2171,7 @@ createSymLinkRetry:
2081 , nls_codepage); 2171 , nls_codepage);
2082 name_len_target++; /* trailing null */ 2172 name_len_target++; /* trailing null */
2083 name_len_target *= 2; 2173 name_len_target *= 2;
2084 } else { /* BB improve the check for buffer overruns BB */ 2174 } else { /* BB improve the check for buffer overruns BB */
2085 name_len_target = strnlen(toName, PATH_MAX); 2175 name_len_target = strnlen(toName, PATH_MAX);
2086 name_len_target++; /* trailing null */ 2176 name_len_target++; /* trailing null */
2087 strncpy(data_offset, toName, name_len_target); 2177 strncpy(data_offset, toName, name_len_target);
@@ -2108,9 +2198,7 @@ createSymLinkRetry:
2108 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2198 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2109 cifs_stats_inc(&tcon->num_symlinks); 2199 cifs_stats_inc(&tcon->num_symlinks);
2110 if (rc) { 2200 if (rc) {
2111 cFYI(1, 2201 cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
2112 ("Send error in SetPathInfo (create symlink) = %d",
2113 rc));
2114 } 2202 }
2115 2203
2116 if (pSMB) 2204 if (pSMB)
@@ -2149,7 +2237,7 @@ createHardLinkRetry:
2149 name_len++; /* trailing null */ 2237 name_len++; /* trailing null */
2150 name_len *= 2; 2238 name_len *= 2;
2151 2239
2152 } else { /* BB improve the check for buffer overruns BB */ 2240 } else { /* BB improve the check for buffer overruns BB */
2153 name_len = strnlen(toName, PATH_MAX); 2241 name_len = strnlen(toName, PATH_MAX);
2154 name_len++; /* trailing null */ 2242 name_len++; /* trailing null */
2155 strncpy(pSMB->FileName, toName, name_len); 2243 strncpy(pSMB->FileName, toName, name_len);
@@ -2161,7 +2249,7 @@ createHardLinkRetry:
2161 pSMB->Timeout = 0; 2249 pSMB->Timeout = 0;
2162 pSMB->Reserved2 = 0; 2250 pSMB->Reserved2 = 0;
2163 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2251 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2164 InformationLevel) - 4; 2252 InformationLevel) - 4;
2165 offset = param_offset + params; 2253 offset = param_offset + params;
2166 2254
2167 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2255 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
@@ -2171,7 +2259,7 @@ createHardLinkRetry:
2171 nls_codepage, remap); 2259 nls_codepage, remap);
2172 name_len_target++; /* trailing null */ 2260 name_len_target++; /* trailing null */
2173 name_len_target *= 2; 2261 name_len_target *= 2;
2174 } else { /* BB improve the check for buffer overruns BB */ 2262 } else { /* BB improve the check for buffer overruns BB */
2175 name_len_target = strnlen(fromName, PATH_MAX); 2263 name_len_target = strnlen(fromName, PATH_MAX);
2176 name_len_target++; /* trailing null */ 2264 name_len_target++; /* trailing null */
2177 strncpy(data_offset, fromName, name_len_target); 2265 strncpy(data_offset, fromName, name_len_target);
@@ -2243,13 +2331,13 @@ winCreateHardLinkRetry:
2243 name_len++; /* trailing null */ 2331 name_len++; /* trailing null */
2244 name_len *= 2; 2332 name_len *= 2;
2245 pSMB->OldFileName[name_len] = 0; /* pad */ 2333 pSMB->OldFileName[name_len] = 0; /* pad */
2246 pSMB->OldFileName[name_len + 1] = 0x04; 2334 pSMB->OldFileName[name_len + 1] = 0x04;
2247 name_len2 = 2335 name_len2 =
2248 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 2336 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
2249 toName, PATH_MAX, nls_codepage, remap); 2337 toName, PATH_MAX, nls_codepage, remap);
2250 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2338 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
2251 name_len2 *= 2; /* convert to bytes */ 2339 name_len2 *= 2; /* convert to bytes */
2252 } else { /* BB improve the check for buffer overruns BB */ 2340 } else { /* BB improve the check for buffer overruns BB */
2253 name_len = strnlen(fromName, PATH_MAX); 2341 name_len = strnlen(fromName, PATH_MAX);
2254 name_len++; /* trailing null */ 2342 name_len++; /* trailing null */
2255 strncpy(pSMB->OldFileName, fromName, name_len); 2343 strncpy(pSMB->OldFileName, fromName, name_len);
@@ -2302,12 +2390,11 @@ querySymLinkRetry:
2302 2390
2303 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2391 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2304 name_len = 2392 name_len =
2305 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX 2393 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName,
2306 /* find define for this maxpathcomponent */ 2394 PATH_MAX, nls_codepage);
2307 , nls_codepage);
2308 name_len++; /* trailing null */ 2395 name_len++; /* trailing null */
2309 name_len *= 2; 2396 name_len *= 2;
2310 } else { /* BB improve the check for buffer overruns BB */ 2397 } else { /* BB improve the check for buffer overruns BB */
2311 name_len = strnlen(searchName, PATH_MAX); 2398 name_len = strnlen(searchName, PATH_MAX);
2312 name_len++; /* trailing null */ 2399 name_len++; /* trailing null */
2313 strncpy(pSMB->FileName, searchName, name_len); 2400 strncpy(pSMB->FileName, searchName, name_len);
@@ -2324,7 +2411,7 @@ querySymLinkRetry:
2324 pSMB->Timeout = 0; 2411 pSMB->Timeout = 0;
2325 pSMB->Reserved2 = 0; 2412 pSMB->Reserved2 = 0;
2326 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2413 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2327 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 2414 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
2328 pSMB->DataCount = 0; 2415 pSMB->DataCount = 0;
2329 pSMB->DataOffset = 0; 2416 pSMB->DataOffset = 0;
2330 pSMB->SetupCount = 1; 2417 pSMB->SetupCount = 1;
@@ -2355,16 +2442,16 @@ querySymLinkRetry:
2355 2442
2356 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 2443 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2357 name_len = UniStrnlen((wchar_t *) ((char *) 2444 name_len = UniStrnlen((wchar_t *) ((char *)
2358 &pSMBr->hdr.Protocol +data_offset), 2445 &pSMBr->hdr.Protocol + data_offset),
2359 min_t(const int, buflen,count) / 2); 2446 min_t(const int, buflen, count) / 2);
2360 /* BB FIXME investigate remapping reserved chars here */ 2447 /* BB FIXME investigate remapping reserved chars here */
2361 cifs_strfromUCS_le(symlinkinfo, 2448 cifs_strfromUCS_le(symlinkinfo,
2362 (__le16 *) ((char *)&pSMBr->hdr.Protocol + 2449 (__le16 *) ((char *)&pSMBr->hdr.Protocol
2363 data_offset), 2450 + data_offset),
2364 name_len, nls_codepage); 2451 name_len, nls_codepage);
2365 } else { 2452 } else {
2366 strncpy(symlinkinfo, 2453 strncpy(symlinkinfo,
2367 (char *) &pSMBr->hdr.Protocol + 2454 (char *) &pSMBr->hdr.Protocol +
2368 data_offset, 2455 data_offset,
2369 min_t(const int, buflen, count)); 2456 min_t(const int, buflen, count));
2370 } 2457 }
@@ -2385,14 +2472,14 @@ querySymLinkRetry:
2385 Setup words themselves and ByteCount 2472 Setup words themselves and ByteCount
2386 MaxSetupCount (size of returned setup area) and 2473 MaxSetupCount (size of returned setup area) and
2387 MaxParameterCount (returned parms size) must be set by caller */ 2474 MaxParameterCount (returned parms size) must be set by caller */
2388static int 2475static int
2389smb_init_ntransact(const __u16 sub_command, const int setup_count, 2476smb_init_ntransact(const __u16 sub_command, const int setup_count,
2390 const int parm_len, struct cifsTconInfo *tcon, 2477 const int parm_len, struct cifsTconInfo *tcon,
2391 void ** ret_buf) 2478 void **ret_buf)
2392{ 2479{
2393 int rc; 2480 int rc;
2394 __u32 temp_offset; 2481 __u32 temp_offset;
2395 struct smb_com_ntransact_req * pSMB; 2482 struct smb_com_ntransact_req *pSMB;
2396 2483
2397 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 2484 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
2398 (void **)&pSMB); 2485 (void **)&pSMB);
@@ -2416,47 +2503,47 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count,
2416} 2503}
2417 2504
2418static int 2505static int
2419validate_ntransact(char * buf, char ** ppparm, char ** ppdata, 2506validate_ntransact(char *buf, char **ppparm, char **ppdata,
2420 int * pdatalen, int * pparmlen) 2507 int *pdatalen, int *pparmlen)
2421{ 2508{
2422 char * end_of_smb; 2509 char *end_of_smb;
2423 __u32 data_count, data_offset, parm_count, parm_offset; 2510 __u32 data_count, data_offset, parm_count, parm_offset;
2424 struct smb_com_ntransact_rsp * pSMBr; 2511 struct smb_com_ntransact_rsp *pSMBr;
2425 2512
2426 if(buf == NULL) 2513 if (buf == NULL)
2427 return -EINVAL; 2514 return -EINVAL;
2428 2515
2429 pSMBr = (struct smb_com_ntransact_rsp *)buf; 2516 pSMBr = (struct smb_com_ntransact_rsp *)buf;
2430 2517
2431 /* ByteCount was converted from little endian in SendReceive */ 2518 /* ByteCount was converted from little endian in SendReceive */
2432 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + 2519 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
2433 (char *)&pSMBr->ByteCount; 2520 (char *)&pSMBr->ByteCount;
2434 2521
2435
2436 data_offset = le32_to_cpu(pSMBr->DataOffset); 2522 data_offset = le32_to_cpu(pSMBr->DataOffset);
2437 data_count = le32_to_cpu(pSMBr->DataCount); 2523 data_count = le32_to_cpu(pSMBr->DataCount);
2438 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 2524 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
2439 parm_count = le32_to_cpu(pSMBr->ParameterCount); 2525 parm_count = le32_to_cpu(pSMBr->ParameterCount);
2440 2526
2441 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 2527 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
2442 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 2528 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
2443 2529
2444 /* should we also check that parm and data areas do not overlap? */ 2530 /* should we also check that parm and data areas do not overlap? */
2445 if(*ppparm > end_of_smb) { 2531 if (*ppparm > end_of_smb) {
2446 cFYI(1,("parms start after end of smb")); 2532 cFYI(1, ("parms start after end of smb"));
2447 return -EINVAL; 2533 return -EINVAL;
2448 } else if(parm_count + *ppparm > end_of_smb) { 2534 } else if (parm_count + *ppparm > end_of_smb) {
2449 cFYI(1,("parm end after end of smb")); 2535 cFYI(1, ("parm end after end of smb"));
2450 return -EINVAL; 2536 return -EINVAL;
2451 } else if(*ppdata > end_of_smb) { 2537 } else if (*ppdata > end_of_smb) {
2452 cFYI(1,("data starts after end of smb")); 2538 cFYI(1, ("data starts after end of smb"));
2453 return -EINVAL; 2539 return -EINVAL;
2454 } else if(data_count + *ppdata > end_of_smb) { 2540 } else if (data_count + *ppdata > end_of_smb) {
2455 cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", 2541 cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
2456 *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); /* BB FIXME */ 2542 *ppdata, data_count, (data_count + *ppdata),
2543 end_of_smb, pSMBr));
2457 return -EINVAL; 2544 return -EINVAL;
2458 } else if(parm_count + data_count > pSMBr->ByteCount) { 2545 } else if (parm_count + data_count > pSMBr->ByteCount) {
2459 cFYI(1,("parm count and data count larger than SMB")); 2546 cFYI(1, ("parm count and data count larger than SMB"));
2460 return -EINVAL; 2547 return -EINVAL;
2461 } 2548 }
2462 return 0; 2549 return 0;
@@ -2465,14 +2552,14 @@ validate_ntransact(char * buf, char ** ppparm, char ** ppdata,
2465int 2552int
2466CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2553CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2467 const unsigned char *searchName, 2554 const unsigned char *searchName,
2468 char *symlinkinfo, const int buflen,__u16 fid, 2555 char *symlinkinfo, const int buflen, __u16 fid,
2469 const struct nls_table *nls_codepage) 2556 const struct nls_table *nls_codepage)
2470{ 2557{
2471 int rc = 0; 2558 int rc = 0;
2472 int bytes_returned; 2559 int bytes_returned;
2473 int name_len; 2560 int name_len;
2474 struct smb_com_transaction_ioctl_req * pSMB; 2561 struct smb_com_transaction_ioctl_req *pSMB;
2475 struct smb_com_transaction_ioctl_rsp * pSMBr; 2562 struct smb_com_transaction_ioctl_rsp *pSMBr;
2476 2563
2477 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName)); 2564 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
2478 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 2565 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
@@ -2511,47 +2598,53 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2511 /* BB also check enough total bytes returned */ 2598 /* BB also check enough total bytes returned */
2512 rc = -EIO; /* bad smb */ 2599 rc = -EIO; /* bad smb */
2513 else { 2600 else {
2514 if(data_count && (data_count < 2048)) { 2601 if (data_count && (data_count < 2048)) {
2515 char * end_of_smb = 2 /* sizeof byte count */ + 2602 char *end_of_smb = 2 /* sizeof byte count */ +
2516 pSMBr->ByteCount + 2603 pSMBr->ByteCount +
2517 (char *)&pSMBr->ByteCount; 2604 (char *)&pSMBr->ByteCount;
2518 2605
2519 struct reparse_data * reparse_buf = (struct reparse_data *) 2606 struct reparse_data *reparse_buf =
2520 ((char *)&pSMBr->hdr.Protocol + data_offset); 2607 (struct reparse_data *)
2521 if((char*)reparse_buf >= end_of_smb) { 2608 ((char *)&pSMBr->hdr.Protocol
2609 + data_offset);
2610 if ((char *)reparse_buf >= end_of_smb) {
2522 rc = -EIO; 2611 rc = -EIO;
2523 goto qreparse_out; 2612 goto qreparse_out;
2524 } 2613 }
2525 if((reparse_buf->LinkNamesBuf + 2614 if ((reparse_buf->LinkNamesBuf +
2526 reparse_buf->TargetNameOffset + 2615 reparse_buf->TargetNameOffset +
2527 reparse_buf->TargetNameLen) > 2616 reparse_buf->TargetNameLen) >
2528 end_of_smb) { 2617 end_of_smb) {
2529 cFYI(1,("reparse buf extended beyond SMB")); 2618 cFYI(1,("reparse buf goes beyond SMB"));
2530 rc = -EIO; 2619 rc = -EIO;
2531 goto qreparse_out; 2620 goto qreparse_out;
2532 } 2621 }
2533 2622
2534 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 2623 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2535 name_len = UniStrnlen((wchar_t *) 2624 name_len = UniStrnlen((wchar_t *)
2536 (reparse_buf->LinkNamesBuf + 2625 (reparse_buf->LinkNamesBuf +
2537 reparse_buf->TargetNameOffset), 2626 reparse_buf->TargetNameOffset),
2538 min(buflen/2, reparse_buf->TargetNameLen / 2)); 2627 min(buflen/2,
2628 reparse_buf->TargetNameLen / 2));
2539 cifs_strfromUCS_le(symlinkinfo, 2629 cifs_strfromUCS_le(symlinkinfo,
2540 (__le16 *) (reparse_buf->LinkNamesBuf + 2630 (__le16 *) (reparse_buf->LinkNamesBuf +
2541 reparse_buf->TargetNameOffset), 2631 reparse_buf->TargetNameOffset),
2542 name_len, nls_codepage); 2632 name_len, nls_codepage);
2543 } else { /* ASCII names */ 2633 } else { /* ASCII names */
2544 strncpy(symlinkinfo,reparse_buf->LinkNamesBuf + 2634 strncpy(symlinkinfo,
2545 reparse_buf->TargetNameOffset, 2635 reparse_buf->LinkNamesBuf +
2546 min_t(const int, buflen, reparse_buf->TargetNameLen)); 2636 reparse_buf->TargetNameOffset,
2637 min_t(const int, buflen,
2638 reparse_buf->TargetNameLen));
2547 } 2639 }
2548 } else { 2640 } else {
2549 rc = -EIO; 2641 rc = -EIO;
2550 cFYI(1,("Invalid return data count on get reparse info ioctl")); 2642 cFYI(1, ("Invalid return data count on "
2643 "get reparse info ioctl"));
2551 } 2644 }
2552 symlinkinfo[buflen] = 0; /* just in case so the caller 2645 symlinkinfo[buflen] = 0; /* just in case so the caller
2553 does not go off the end of the buffer */ 2646 does not go off the end of the buffer */
2554 cFYI(1,("readlink result - %s",symlinkinfo)); 2647 cFYI(1, ("readlink result - %s", symlinkinfo));
2555 } 2648 }
2556 } 2649 }
2557qreparse_out: 2650qreparse_out:
@@ -2566,7 +2659,8 @@ qreparse_out:
2566#ifdef CONFIG_CIFS_POSIX 2659#ifdef CONFIG_CIFS_POSIX
2567 2660
2568/*Convert an Access Control Entry from wire format to local POSIX xattr format*/ 2661/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
2569static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) 2662static void cifs_convert_ace(posix_acl_xattr_entry *ace,
2663 struct cifs_posix_ace *cifs_ace)
2570{ 2664{
2571 /* u8 cifs fields do not need le conversion */ 2665 /* u8 cifs fields do not need le conversion */
2572 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm); 2666 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
@@ -2578,30 +2672,31 @@ static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace
2578} 2672}
2579 2673
2580/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */ 2674/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
2581static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen, 2675static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
2582 const int acl_type,const int size_of_data_area) 2676 const int acl_type, const int size_of_data_area)
2583{ 2677{
2584 int size = 0; 2678 int size = 0;
2585 int i; 2679 int i;
2586 __u16 count; 2680 __u16 count;
2587 struct cifs_posix_ace * pACE; 2681 struct cifs_posix_ace *pACE;
2588 struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)src; 2682 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
2589 posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)trgt; 2683 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
2590 2684
2591 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 2685 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
2592 return -EOPNOTSUPP; 2686 return -EOPNOTSUPP;
2593 2687
2594 if(acl_type & ACL_TYPE_ACCESS) { 2688 if (acl_type & ACL_TYPE_ACCESS) {
2595 count = le16_to_cpu(cifs_acl->access_entry_count); 2689 count = le16_to_cpu(cifs_acl->access_entry_count);
2596 pACE = &cifs_acl->ace_array[0]; 2690 pACE = &cifs_acl->ace_array[0];
2597 size = sizeof(struct cifs_posix_acl); 2691 size = sizeof(struct cifs_posix_acl);
2598 size += sizeof(struct cifs_posix_ace) * count; 2692 size += sizeof(struct cifs_posix_ace) * count;
2599 /* check if we would go beyond end of SMB */ 2693 /* check if we would go beyond end of SMB */
2600 if(size_of_data_area < size) { 2694 if (size_of_data_area < size) {
2601 cFYI(1,("bad CIFS POSIX ACL size %d vs. %d",size_of_data_area,size)); 2695 cFYI(1, ("bad CIFS POSIX ACL size %d vs. %d",
2696 size_of_data_area, size));
2602 return -EINVAL; 2697 return -EINVAL;
2603 } 2698 }
2604 } else if(acl_type & ACL_TYPE_DEFAULT) { 2699 } else if (acl_type & ACL_TYPE_DEFAULT) {
2605 count = le16_to_cpu(cifs_acl->access_entry_count); 2700 count = le16_to_cpu(cifs_acl->access_entry_count);
2606 size = sizeof(struct cifs_posix_acl); 2701 size = sizeof(struct cifs_posix_acl);
2607 size += sizeof(struct cifs_posix_ace) * count; 2702 size += sizeof(struct cifs_posix_ace) * count;
@@ -2610,7 +2705,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
2610 count = le16_to_cpu(cifs_acl->default_entry_count); 2705 count = le16_to_cpu(cifs_acl->default_entry_count);
2611 size += sizeof(struct cifs_posix_ace) * count; 2706 size += sizeof(struct cifs_posix_ace) * count;
2612 /* check if we would go beyond end of SMB */ 2707 /* check if we would go beyond end of SMB */
2613 if(size_of_data_area < size) 2708 if (size_of_data_area < size)
2614 return -EINVAL; 2709 return -EINVAL;
2615 } else { 2710 } else {
2616 /* illegal type */ 2711 /* illegal type */
@@ -2618,76 +2713,77 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
2618 } 2713 }
2619 2714
2620 size = posix_acl_xattr_size(count); 2715 size = posix_acl_xattr_size(count);
2621 if((buflen == 0) || (local_acl == NULL)) { 2716 if ((buflen == 0) || (local_acl == NULL)) {
2622 /* used to query ACL EA size */ 2717 /* used to query ACL EA size */
2623 } else if(size > buflen) { 2718 } else if (size > buflen) {
2624 return -ERANGE; 2719 return -ERANGE;
2625 } else /* buffer big enough */ { 2720 } else /* buffer big enough */ {
2626 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); 2721 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2627 for(i = 0;i < count ;i++) { 2722 for (i = 0; i < count ; i++) {
2628 cifs_convert_ace(&local_acl->a_entries[i],pACE); 2723 cifs_convert_ace(&local_acl->a_entries[i], pACE);
2629 pACE ++; 2724 pACE++;
2630 } 2725 }
2631 } 2726 }
2632 return size; 2727 return size;
2633} 2728}
2634 2729
2635static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, 2730static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
2636 const posix_acl_xattr_entry * local_ace) 2731 const posix_acl_xattr_entry *local_ace)
2637{ 2732{
2638 __u16 rc = 0; /* 0 = ACL converted ok */ 2733 __u16 rc = 0; /* 0 = ACL converted ok */
2639 2734
2640 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); 2735 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2641 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); 2736 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2642 /* BB is there a better way to handle the large uid? */ 2737 /* BB is there a better way to handle the large uid? */
2643 if(local_ace->e_id == cpu_to_le32(-1)) { 2738 if (local_ace->e_id == cpu_to_le32(-1)) {
2644 /* Probably no need to le convert -1 on any arch but can not hurt */ 2739 /* Probably no need to le convert -1 on any arch but can not hurt */
2645 cifs_ace->cifs_uid = cpu_to_le64(-1); 2740 cifs_ace->cifs_uid = cpu_to_le64(-1);
2646 } else 2741 } else
2647 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id)); 2742 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2648 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ 2743 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
2649 return rc; 2744 return rc;
2650} 2745}
2651 2746
2652/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ 2747/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
2653static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen, 2748static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2654 const int acl_type) 2749 const int buflen, const int acl_type)
2655{ 2750{
2656 __u16 rc = 0; 2751 __u16 rc = 0;
2657 struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)parm_data; 2752 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
2658 posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)pACL; 2753 posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
2659 int count; 2754 int count;
2660 int i; 2755 int i;
2661 2756
2662 if((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL)) 2757 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
2663 return 0; 2758 return 0;
2664 2759
2665 count = posix_acl_xattr_count((size_t)buflen); 2760 count = posix_acl_xattr_count((size_t)buflen);
2666 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", 2761 cFYI(1, ("setting acl with %d entries from buf of length %d and "
2762 "version of %d",
2667 count, buflen, le32_to_cpu(local_acl->a_version))); 2763 count, buflen, le32_to_cpu(local_acl->a_version)));
2668 if(le32_to_cpu(local_acl->a_version) != 2) { 2764 if (le32_to_cpu(local_acl->a_version) != 2) {
2669 cFYI(1,("unknown POSIX ACL version %d", 2765 cFYI(1, ("unknown POSIX ACL version %d",
2670 le32_to_cpu(local_acl->a_version))); 2766 le32_to_cpu(local_acl->a_version)));
2671 return 0; 2767 return 0;
2672 } 2768 }
2673 cifs_acl->version = cpu_to_le16(1); 2769 cifs_acl->version = cpu_to_le16(1);
2674 if(acl_type == ACL_TYPE_ACCESS) 2770 if (acl_type == ACL_TYPE_ACCESS)
2675 cifs_acl->access_entry_count = cpu_to_le16(count); 2771 cifs_acl->access_entry_count = cpu_to_le16(count);
2676 else if(acl_type == ACL_TYPE_DEFAULT) 2772 else if (acl_type == ACL_TYPE_DEFAULT)
2677 cifs_acl->default_entry_count = cpu_to_le16(count); 2773 cifs_acl->default_entry_count = cpu_to_le16(count);
2678 else { 2774 else {
2679 cFYI(1,("unknown ACL type %d",acl_type)); 2775 cFYI(1, ("unknown ACL type %d", acl_type));
2680 return 0; 2776 return 0;
2681 } 2777 }
2682 for(i=0;i<count;i++) { 2778 for (i = 0; i < count; i++) {
2683 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], 2779 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
2684 &local_acl->a_entries[i]); 2780 &local_acl->a_entries[i]);
2685 if(rc != 0) { 2781 if (rc != 0) {
2686 /* ACE not converted */ 2782 /* ACE not converted */
2687 break; 2783 break;
2688 } 2784 }
2689 } 2785 }
2690 if(rc == 0) { 2786 if (rc == 0) {
2691 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 2787 rc = (__u16)(count * sizeof(struct cifs_posix_ace));
2692 rc += sizeof(struct cifs_posix_acl); 2788 rc += sizeof(struct cifs_posix_acl);
2693 /* BB add check to make sure ACL does not overflow SMB */ 2789 /* BB add check to make sure ACL does not overflow SMB */
@@ -2697,9 +2793,9 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
2697 2793
2698int 2794int
2699CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 2795CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
2700 const unsigned char *searchName, 2796 const unsigned char *searchName,
2701 char *acl_inf, const int buflen, const int acl_type, 2797 char *acl_inf, const int buflen, const int acl_type,
2702 const struct nls_table *nls_codepage, int remap) 2798 const struct nls_table *nls_codepage, int remap)
2703{ 2799{
2704/* SMB_QUERY_POSIX_ACL */ 2800/* SMB_QUERY_POSIX_ACL */
2705 TRANSACTION2_QPI_REQ *pSMB = NULL; 2801 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -2708,7 +2804,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
2708 int bytes_returned; 2804 int bytes_returned;
2709 int name_len; 2805 int name_len;
2710 __u16 params, byte_count; 2806 __u16 params, byte_count;
2711 2807
2712 cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName)); 2808 cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName));
2713 2809
2714queryAclRetry: 2810queryAclRetry:
@@ -2716,16 +2812,16 @@ queryAclRetry:
2716 (void **) &pSMBr); 2812 (void **) &pSMBr);
2717 if (rc) 2813 if (rc)
2718 return rc; 2814 return rc;
2719 2815
2720 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2816 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2721 name_len = 2817 name_len =
2722 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 2818 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2723 PATH_MAX, nls_codepage, remap); 2819 PATH_MAX, nls_codepage, remap);
2724 name_len++; /* trailing null */ 2820 name_len++; /* trailing null */
2725 name_len *= 2; 2821 name_len *= 2;
2726 pSMB->FileName[name_len] = 0; 2822 pSMB->FileName[name_len] = 0;
2727 pSMB->FileName[name_len+1] = 0; 2823 pSMB->FileName[name_len+1] = 0;
2728 } else { /* BB improve the check for buffer overruns BB */ 2824 } else { /* BB improve the check for buffer overruns BB */
2729 name_len = strnlen(searchName, PATH_MAX); 2825 name_len = strnlen(searchName, PATH_MAX);
2730 name_len++; /* trailing null */ 2826 name_len++; /* trailing null */
2731 strncpy(pSMB->FileName, searchName, name_len); 2827 strncpy(pSMB->FileName, searchName, name_len);
@@ -2734,7 +2830,7 @@ queryAclRetry:
2734 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2830 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
2735 pSMB->TotalDataCount = 0; 2831 pSMB->TotalDataCount = 0;
2736 pSMB->MaxParameterCount = cpu_to_le16(2); 2832 pSMB->MaxParameterCount = cpu_to_le16(2);
2737 /* BB find exact max data count below from sess structure BB */ 2833 /* BB find exact max data count below from sess structure BB */
2738 pSMB->MaxDataCount = cpu_to_le16(4000); 2834 pSMB->MaxDataCount = cpu_to_le16(4000);
2739 pSMB->MaxSetupCount = 0; 2835 pSMB->MaxSetupCount = 0;
2740 pSMB->Reserved = 0; 2836 pSMB->Reserved = 0;
@@ -2742,7 +2838,8 @@ queryAclRetry:
2742 pSMB->Timeout = 0; 2838 pSMB->Timeout = 0;
2743 pSMB->Reserved2 = 0; 2839 pSMB->Reserved2 = 0;
2744 pSMB->ParameterOffset = cpu_to_le16( 2840 pSMB->ParameterOffset = cpu_to_le16(
2745 offsetof(struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 2841 offsetof(struct smb_com_transaction2_qpi_req,
2842 InformationLevel) - 4);
2746 pSMB->DataCount = 0; 2843 pSMB->DataCount = 0;
2747 pSMB->DataOffset = 0; 2844 pSMB->DataOffset = 0;
2748 pSMB->SetupCount = 1; 2845 pSMB->SetupCount = 1;
@@ -2763,7 +2860,7 @@ queryAclRetry:
2763 cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); 2860 cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
2764 } else { 2861 } else {
2765 /* decode response */ 2862 /* decode response */
2766 2863
2767 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2864 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2768 if (rc || (pSMBr->ByteCount < 2)) 2865 if (rc || (pSMBr->ByteCount < 2))
2769 /* BB also check enough total bytes returned */ 2866 /* BB also check enough total bytes returned */
@@ -2773,7 +2870,7 @@ queryAclRetry:
2773 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2870 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2774 rc = cifs_copy_posix_acl(acl_inf, 2871 rc = cifs_copy_posix_acl(acl_inf,
2775 (char *)&pSMBr->hdr.Protocol+data_offset, 2872 (char *)&pSMBr->hdr.Protocol+data_offset,
2776 buflen,acl_type,count); 2873 buflen, acl_type, count);
2777 } 2874 }
2778 } 2875 }
2779 cifs_buf_release(pSMB); 2876 cifs_buf_release(pSMB);
@@ -2784,10 +2881,10 @@ queryAclRetry:
2784 2881
2785int 2882int
2786CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 2883CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
2787 const unsigned char *fileName, 2884 const unsigned char *fileName,
2788 const char *local_acl, const int buflen, 2885 const char *local_acl, const int buflen,
2789 const int acl_type, 2886 const int acl_type,
2790 const struct nls_table *nls_codepage, int remap) 2887 const struct nls_table *nls_codepage, int remap)
2791{ 2888{
2792 struct smb_com_transaction2_spi_req *pSMB = NULL; 2889 struct smb_com_transaction2_spi_req *pSMB = NULL;
2793 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 2890 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -2800,16 +2897,16 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
2800 cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName)); 2897 cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName));
2801setAclRetry: 2898setAclRetry:
2802 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2899 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2803 (void **) &pSMBr); 2900 (void **) &pSMBr);
2804 if (rc) 2901 if (rc)
2805 return rc; 2902 return rc;
2806 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2903 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2807 name_len = 2904 name_len =
2808 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 2905 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
2809 PATH_MAX, nls_codepage, remap); 2906 PATH_MAX, nls_codepage, remap);
2810 name_len++; /* trailing null */ 2907 name_len++; /* trailing null */
2811 name_len *= 2; 2908 name_len *= 2;
2812 } else { /* BB improve the check for buffer overruns BB */ 2909 } else { /* BB improve the check for buffer overruns BB */
2813 name_len = strnlen(fileName, PATH_MAX); 2910 name_len = strnlen(fileName, PATH_MAX);
2814 name_len++; /* trailing null */ 2911 name_len++; /* trailing null */
2815 strncpy(pSMB->FileName, fileName, name_len); 2912 strncpy(pSMB->FileName, fileName, name_len);
@@ -2823,15 +2920,15 @@ setAclRetry:
2823 pSMB->Timeout = 0; 2920 pSMB->Timeout = 0;
2824 pSMB->Reserved2 = 0; 2921 pSMB->Reserved2 = 0;
2825 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2922 param_offset = offsetof(struct smb_com_transaction2_spi_req,
2826 InformationLevel) - 4; 2923 InformationLevel) - 4;
2827 offset = param_offset + params; 2924 offset = param_offset + params;
2828 parm_data = ((char *) &pSMB->hdr.Protocol) + offset; 2925 parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
2829 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2926 pSMB->ParameterOffset = cpu_to_le16(param_offset);
2830 2927
2831 /* convert to on the wire format for POSIX ACL */ 2928 /* convert to on the wire format for POSIX ACL */
2832 data_count = ACL_to_cifs_posix(parm_data,local_acl,buflen,acl_type); 2929 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
2833 2930
2834 if(data_count == 0) { 2931 if (data_count == 0) {
2835 rc = -EOPNOTSUPP; 2932 rc = -EOPNOTSUPP;
2836 goto setACLerrorExit; 2933 goto setACLerrorExit;
2837 } 2934 }
@@ -2849,7 +2946,7 @@ setAclRetry:
2849 pSMB->hdr.smb_buf_length += byte_count; 2946 pSMB->hdr.smb_buf_length += byte_count;
2850 pSMB->ByteCount = cpu_to_le16(byte_count); 2947 pSMB->ByteCount = cpu_to_le16(byte_count);
2851 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2948 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2852 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2949 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2853 if (rc) { 2950 if (rc) {
2854 cFYI(1, ("Set POSIX ACL returned %d", rc)); 2951 cFYI(1, ("Set POSIX ACL returned %d", rc));
2855 } 2952 }
@@ -2864,86 +2961,85 @@ setACLerrorExit:
2864/* BB fix tabs in this function FIXME BB */ 2961/* BB fix tabs in this function FIXME BB */
2865int 2962int
2866CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 2963CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
2867 const int netfid, __u64 * pExtAttrBits, __u64 *pMask) 2964 const int netfid, __u64 * pExtAttrBits, __u64 *pMask)
2868{ 2965{
2869 int rc = 0; 2966 int rc = 0;
2870 struct smb_t2_qfi_req *pSMB = NULL; 2967 struct smb_t2_qfi_req *pSMB = NULL;
2871 struct smb_t2_qfi_rsp *pSMBr = NULL; 2968 struct smb_t2_qfi_rsp *pSMBr = NULL;
2872 int bytes_returned; 2969 int bytes_returned;
2873 __u16 params, byte_count; 2970 __u16 params, byte_count;
2874 2971
2875 cFYI(1,("In GetExtAttr")); 2972 cFYI(1, ("In GetExtAttr"));
2876 if(tcon == NULL) 2973 if (tcon == NULL)
2877 return -ENODEV; 2974 return -ENODEV;
2878 2975
2879GetExtAttrRetry: 2976GetExtAttrRetry:
2880 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2977 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2881 (void **) &pSMBr); 2978 (void **) &pSMBr);
2882 if (rc) 2979 if (rc)
2883 return rc; 2980 return rc;
2884 2981
2885 params = 2 /* level */ +2 /* fid */; 2982 params = 2 /* level */ +2 /* fid */;
2886 pSMB->t2.TotalDataCount = 0; 2983 pSMB->t2.TotalDataCount = 0;
2887 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 2984 pSMB->t2.MaxParameterCount = cpu_to_le16(4);
2888 /* BB find exact max data count below from sess structure BB */ 2985 /* BB find exact max data count below from sess structure BB */
2889 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 2986 pSMB->t2.MaxDataCount = cpu_to_le16(4000);
2890 pSMB->t2.MaxSetupCount = 0; 2987 pSMB->t2.MaxSetupCount = 0;
2891 pSMB->t2.Reserved = 0; 2988 pSMB->t2.Reserved = 0;
2892 pSMB->t2.Flags = 0; 2989 pSMB->t2.Flags = 0;
2893 pSMB->t2.Timeout = 0; 2990 pSMB->t2.Timeout = 0;
2894 pSMB->t2.Reserved2 = 0; 2991 pSMB->t2.Reserved2 = 0;
2895 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 2992 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
2896 Fid) - 4); 2993 Fid) - 4);
2897 pSMB->t2.DataCount = 0; 2994 pSMB->t2.DataCount = 0;
2898 pSMB->t2.DataOffset = 0; 2995 pSMB->t2.DataOffset = 0;
2899 pSMB->t2.SetupCount = 1; 2996 pSMB->t2.SetupCount = 1;
2900 pSMB->t2.Reserved3 = 0; 2997 pSMB->t2.Reserved3 = 0;
2901 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2998 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
2902 byte_count = params + 1 /* pad */ ; 2999 byte_count = params + 1 /* pad */ ;
2903 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3000 pSMB->t2.TotalParameterCount = cpu_to_le16(params);
2904 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3001 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
2905 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3002 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
2906 pSMB->Pad = 0; 3003 pSMB->Pad = 0;
2907 pSMB->Fid = netfid; 3004 pSMB->Fid = netfid;
2908 pSMB->hdr.smb_buf_length += byte_count; 3005 pSMB->hdr.smb_buf_length += byte_count;
2909 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3006 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
2910 3007
2911 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3008 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2912 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3009 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2913 if (rc) { 3010 if (rc) {
2914 cFYI(1, ("error %d in GetExtAttr", rc)); 3011 cFYI(1, ("error %d in GetExtAttr", rc));
2915 } else { 3012 } else {
2916 /* decode response */ 3013 /* decode response */
2917 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3014 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2918 if (rc || (pSMBr->ByteCount < 2)) 3015 if (rc || (pSMBr->ByteCount < 2))
2919 /* BB also check enough total bytes returned */ 3016 /* BB also check enough total bytes returned */
2920 /* If rc should we check for EOPNOSUPP and 3017 /* If rc should we check for EOPNOSUPP and
2921 disable the srvino flag? or in caller? */ 3018 disable the srvino flag? or in caller? */
2922 rc = -EIO; /* bad smb */ 3019 rc = -EIO; /* bad smb */
2923 else { 3020 else {
2924 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3021 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
2925 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3022 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
2926 struct file_chattr_info * pfinfo; 3023 struct file_chattr_info *pfinfo;
2927 /* BB Do we need a cast or hash here ? */ 3024 /* BB Do we need a cast or hash here ? */
2928 if(count != 16) { 3025 if (count != 16) {
2929 cFYI(1, ("Illegal size ret in GetExtAttr")); 3026 cFYI(1, ("Illegal size ret in GetExtAttr"));
2930 rc = -EIO; 3027 rc = -EIO;
2931 goto GetExtAttrOut; 3028 goto GetExtAttrOut;
2932 } 3029 }
2933 pfinfo = (struct file_chattr_info *) 3030 pfinfo = (struct file_chattr_info *)
2934 (data_offset + (char *) &pSMBr->hdr.Protocol); 3031 (data_offset + (char *) &pSMBr->hdr.Protocol);
2935 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3032 *pExtAttrBits = le64_to_cpu(pfinfo->mode);
2936 *pMask = le64_to_cpu(pfinfo->mask); 3033 *pMask = le64_to_cpu(pfinfo->mask);
2937 } 3034 }
2938 } 3035 }
2939GetExtAttrOut: 3036GetExtAttrOut:
2940 cifs_buf_release(pSMB); 3037 cifs_buf_release(pSMB);
2941 if (rc == -EAGAIN) 3038 if (rc == -EAGAIN)
2942 goto GetExtAttrRetry; 3039 goto GetExtAttrRetry;
2943 return rc; 3040 return rc;
2944} 3041}
2945 3042
2946
2947#endif /* CONFIG_POSIX */ 3043#endif /* CONFIG_POSIX */
2948 3044
2949 3045
@@ -2955,7 +3051,7 @@ static const struct cifs_sid sid_user =
2955 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 3051 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
2956 3052
2957/* Convert CIFS ACL to POSIX form */ 3053/* Convert CIFS ACL to POSIX form */
2958static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) 3054static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
2959{ 3055{
2960 return 0; 3056 return 0;
2961} 3057}
@@ -2963,7 +3059,7 @@ static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
2963/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3059/* Get Security Descriptor (by handle) from remote server for a file or dir */
2964int 3060int
2965CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3061CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2966 /* BB fix up return info */ char *acl_inf, const int buflen, 3062 /* BB fix up return info */ char *acl_inf, const int buflen,
2967 const int acl_type /* ACCESS/DEFAULT not sure implication */) 3063 const int acl_type /* ACCESS/DEFAULT not sure implication */)
2968{ 3064{
2969 int rc = 0; 3065 int rc = 0;
@@ -2973,7 +3069,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2973 3069
2974 cFYI(1, ("GetCifsACL")); 3070 cFYI(1, ("GetCifsACL"));
2975 3071
2976 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3072 rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
2977 8 /* parm len */, tcon, (void **) &pSMB); 3073 8 /* parm len */, tcon, (void **) &pSMB);
2978 if (rc) 3074 if (rc)
2979 return rc; 3075 return rc;
@@ -2994,23 +3090,23 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
2994 if (rc) { 3090 if (rc) {
2995 cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 3091 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
2996 } else { /* decode response */ 3092 } else { /* decode response */
2997 struct cifs_sid * psec_desc; 3093 struct cifs_sid *psec_desc;
2998 __le32 * parm; 3094 __le32 * parm;
2999 int parm_len; 3095 int parm_len;
3000 int data_len; 3096 int data_len;
3001 int acl_len; 3097 int acl_len;
3002 struct smb_com_ntransact_rsp * pSMBr; 3098 struct smb_com_ntransact_rsp *pSMBr;
3003 3099
3004/* validate_nttransact */ 3100/* validate_nttransact */
3005 rc = validate_ntransact(iov[0].iov_base, (char **)&parm, 3101 rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
3006 (char **)&psec_desc, 3102 (char **)&psec_desc,
3007 &parm_len, &data_len); 3103 &parm_len, &data_len);
3008 3104 if (rc)
3009 if(rc)
3010 goto qsec_out; 3105 goto qsec_out;
3011 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; 3106 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3012 3107
3013 cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc)); /* BB removeme BB */ 3108 cERROR(1, ("smb %p parm %p data %p",
3109 pSMBr, parm, psec_desc)); /* BB removeme BB */
3014 3110
3015 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3111 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3016 rc = -EIO; /* bad smb */ 3112 rc = -EIO; /* bad smb */
@@ -3020,14 +3116,14 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3020/* BB check that data area is minimum length and as big as acl_len */ 3116/* BB check that data area is minimum length and as big as acl_len */
3021 3117
3022 acl_len = le32_to_cpu(*(__le32 *)parm); 3118 acl_len = le32_to_cpu(*(__le32 *)parm);
3023 /* BB check if(acl_len > bufsize) */ 3119 /* BB check if (acl_len > bufsize) */
3024 3120
3025 parse_sec_desc(psec_desc, acl_len); 3121 parse_sec_desc(psec_desc, acl_len);
3026 } 3122 }
3027qsec_out: 3123qsec_out:
3028 if(buf_type == CIFS_SMALL_BUFFER) 3124 if (buf_type == CIFS_SMALL_BUFFER)
3029 cifs_small_buf_release(iov[0].iov_base); 3125 cifs_small_buf_release(iov[0].iov_base);
3030 else if(buf_type == CIFS_LARGE_BUFFER) 3126 else if (buf_type == CIFS_LARGE_BUFFER)
3031 cifs_buf_release(iov[0].iov_base); 3127 cifs_buf_release(iov[0].iov_base);
3032/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 3128/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3033 return rc; 3129 return rc;
@@ -3036,9 +3132,9 @@ qsec_out:
3036/* Legacy Query Path Information call for lookup to old servers such 3132/* Legacy Query Path Information call for lookup to old servers such
3037 as Win9x/WinME */ 3133 as Win9x/WinME */
3038int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 3134int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
3039 const unsigned char *searchName, 3135 const unsigned char *searchName,
3040 FILE_ALL_INFO * pFinfo, 3136 FILE_ALL_INFO *pFinfo,
3041 const struct nls_table *nls_codepage, int remap) 3137 const struct nls_table *nls_codepage, int remap)
3042{ 3138{
3043 QUERY_INFORMATION_REQ * pSMB; 3139 QUERY_INFORMATION_REQ * pSMB;
3044 QUERY_INFORMATION_RSP * pSMBr; 3140 QUERY_INFORMATION_RSP * pSMBr;
@@ -3046,31 +3142,31 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
3046 int bytes_returned; 3142 int bytes_returned;
3047 int name_len; 3143 int name_len;
3048 3144
3049 cFYI(1, ("In SMBQPath path %s", searchName)); 3145 cFYI(1, ("In SMBQPath path %s", searchName));
3050QInfRetry: 3146QInfRetry:
3051 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 3147 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
3052 (void **) &pSMBr); 3148 (void **) &pSMBr);
3053 if (rc) 3149 if (rc)
3054 return rc; 3150 return rc;
3055 3151
3056 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3152 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3057 name_len = 3153 name_len =
3058 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3154 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3059 PATH_MAX, nls_codepage, remap); 3155 PATH_MAX, nls_codepage, remap);
3060 name_len++; /* trailing null */ 3156 name_len++; /* trailing null */
3061 name_len *= 2; 3157 name_len *= 2;
3062 } else { 3158 } else {
3063 name_len = strnlen(searchName, PATH_MAX); 3159 name_len = strnlen(searchName, PATH_MAX);
3064 name_len++; /* trailing null */ 3160 name_len++; /* trailing null */
3065 strncpy(pSMB->FileName, searchName, name_len); 3161 strncpy(pSMB->FileName, searchName, name_len);
3066 } 3162 }
3067 pSMB->BufferFormat = 0x04; 3163 pSMB->BufferFormat = 0x04;
3068 name_len++; /* account for buffer type byte */ 3164 name_len++; /* account for buffer type byte */
3069 pSMB->hdr.smb_buf_length += (__u16) name_len; 3165 pSMB->hdr.smb_buf_length += (__u16) name_len;
3070 pSMB->ByteCount = cpu_to_le16(name_len); 3166 pSMB->ByteCount = cpu_to_le16(name_len);
3071 3167
3072 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3168 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3073 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3169 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3074 if (rc) { 3170 if (rc) {
3075 cFYI(1, ("Send error in QueryInfo = %d", rc)); 3171 cFYI(1, ("Send error in QueryInfo = %d", rc));
3076 } else if (pFinfo) { /* decode response */ 3172 } else if (pFinfo) { /* decode response */
@@ -3127,17 +3223,17 @@ QPathInfoRetry:
3127 3223
3128 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3224 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3129 name_len = 3225 name_len =
3130 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3226 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3131 PATH_MAX, nls_codepage, remap); 3227 PATH_MAX, nls_codepage, remap);
3132 name_len++; /* trailing null */ 3228 name_len++; /* trailing null */
3133 name_len *= 2; 3229 name_len *= 2;
3134 } else { /* BB improve the check for buffer overruns BB */ 3230 } else { /* BB improve the check for buffer overruns BB */
3135 name_len = strnlen(searchName, PATH_MAX); 3231 name_len = strnlen(searchName, PATH_MAX);
3136 name_len++; /* trailing null */ 3232 name_len++; /* trailing null */
3137 strncpy(pSMB->FileName, searchName, name_len); 3233 strncpy(pSMB->FileName, searchName, name_len);
3138 } 3234 }
3139 3235
3140 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 3236 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3141 pSMB->TotalDataCount = 0; 3237 pSMB->TotalDataCount = 0;
3142 pSMB->MaxParameterCount = cpu_to_le16(2); 3238 pSMB->MaxParameterCount = cpu_to_le16(2);
3143 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 3239 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -3147,7 +3243,7 @@ QPathInfoRetry:
3147 pSMB->Timeout = 0; 3243 pSMB->Timeout = 0;
3148 pSMB->Reserved2 = 0; 3244 pSMB->Reserved2 = 0;
3149 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3245 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3150 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3246 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3151 pSMB->DataCount = 0; 3247 pSMB->DataCount = 0;
3152 pSMB->DataOffset = 0; 3248 pSMB->DataOffset = 0;
3153 pSMB->SetupCount = 1; 3249 pSMB->SetupCount = 1;
@@ -3156,7 +3252,7 @@ QPathInfoRetry:
3156 byte_count = params + 1 /* pad */ ; 3252 byte_count = params + 1 /* pad */ ;
3157 pSMB->TotalParameterCount = cpu_to_le16(params); 3253 pSMB->TotalParameterCount = cpu_to_le16(params);
3158 pSMB->ParameterCount = pSMB->TotalParameterCount; 3254 pSMB->ParameterCount = pSMB->TotalParameterCount;
3159 if(legacy) 3255 if (legacy)
3160 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 3256 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3161 else 3257 else
3162 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3258 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
@@ -3173,16 +3269,18 @@ QPathInfoRetry:
3173 3269
3174 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3270 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3175 rc = -EIO; 3271 rc = -EIO;
3176 else if (!legacy && (pSMBr->ByteCount < 40)) 3272 else if (!legacy && (pSMBr->ByteCount < 40))
3177 rc = -EIO; /* bad smb */ 3273 rc = -EIO; /* bad smb */
3178 else if(legacy && (pSMBr->ByteCount < 24)) 3274 else if (legacy && (pSMBr->ByteCount < 24))
3179 rc = -EIO; /* 24 or 26 expected but we do not read last field */ 3275 rc = -EIO; /* 24 or 26 expected but we do not read
3180 else if (pFindData){ 3276 last field */
3277 else if (pFindData) {
3181 int size; 3278 int size;
3182 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3279 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3183 if(legacy) /* we do not read the last field, EAsize, fortunately 3280 if (legacy) /* we do not read the last field, EAsize,
3184 since it varies by subdialect and on Set vs. Get, is 3281 fortunately since it varies by subdialect
3185 two bytes or 4 bytes depending but we don't care here */ 3282 and on Set vs. Get, is two bytes or 4
3283 bytes depending but we don't care here */
3186 size = sizeof(FILE_INFO_STANDARD); 3284 size = sizeof(FILE_INFO_STANDARD);
3187 else 3285 else
3188 size = sizeof(FILE_ALL_INFO); 3286 size = sizeof(FILE_ALL_INFO);
@@ -3226,24 +3324,24 @@ UnixQPathInfoRetry:
3226 PATH_MAX, nls_codepage, remap); 3324 PATH_MAX, nls_codepage, remap);
3227 name_len++; /* trailing null */ 3325 name_len++; /* trailing null */
3228 name_len *= 2; 3326 name_len *= 2;
3229 } else { /* BB improve the check for buffer overruns BB */ 3327 } else { /* BB improve the check for buffer overruns BB */
3230 name_len = strnlen(searchName, PATH_MAX); 3328 name_len = strnlen(searchName, PATH_MAX);
3231 name_len++; /* trailing null */ 3329 name_len++; /* trailing null */
3232 strncpy(pSMB->FileName, searchName, name_len); 3330 strncpy(pSMB->FileName, searchName, name_len);
3233 } 3331 }
3234 3332
3235 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 3333 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
3236 pSMB->TotalDataCount = 0; 3334 pSMB->TotalDataCount = 0;
3237 pSMB->MaxParameterCount = cpu_to_le16(2); 3335 pSMB->MaxParameterCount = cpu_to_le16(2);
3238 /* BB find exact max SMB PDU from sess structure BB */ 3336 /* BB find exact max SMB PDU from sess structure BB */
3239 pSMB->MaxDataCount = cpu_to_le16(4000); 3337 pSMB->MaxDataCount = cpu_to_le16(4000);
3240 pSMB->MaxSetupCount = 0; 3338 pSMB->MaxSetupCount = 0;
3241 pSMB->Reserved = 0; 3339 pSMB->Reserved = 0;
3242 pSMB->Flags = 0; 3340 pSMB->Flags = 0;
3243 pSMB->Timeout = 0; 3341 pSMB->Timeout = 0;
3244 pSMB->Reserved2 = 0; 3342 pSMB->Reserved2 = 0;
3245 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3343 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3246 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3344 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3247 pSMB->DataCount = 0; 3345 pSMB->DataCount = 0;
3248 pSMB->DataOffset = 0; 3346 pSMB->DataOffset = 0;
3249 pSMB->SetupCount = 1; 3347 pSMB->SetupCount = 1;
@@ -3303,12 +3401,11 @@ findUniqueRetry:
3303 3401
3304 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3402 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3305 name_len = 3403 name_len =
3306 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX 3404 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3307 /* find define for this maxpathcomponent */ 3405 PATH_MAX, nls_codepage);
3308 , nls_codepage);
3309 name_len++; /* trailing null */ 3406 name_len++; /* trailing null */
3310 name_len *= 2; 3407 name_len *= 2;
3311 } else { /* BB improve the check for buffer overruns BB */ 3408 } else { /* BB improve the check for buffer overruns BB */
3312 name_len = strnlen(searchName, PATH_MAX); 3409 name_len = strnlen(searchName, PATH_MAX);
3313 name_len++; /* trailing null */ 3410 name_len++; /* trailing null */
3314 strncpy(pSMB->FileName, searchName, name_len); 3411 strncpy(pSMB->FileName, searchName, name_len);
@@ -3324,7 +3421,7 @@ findUniqueRetry:
3324 pSMB->Timeout = 0; 3421 pSMB->Timeout = 0;
3325 pSMB->Reserved2 = 0; 3422 pSMB->Reserved2 = 0;
3326 pSMB->ParameterOffset = cpu_to_le16( 3423 pSMB->ParameterOffset = cpu_to_le16(
3327 offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4); 3424 offsetof(struct smb_com_transaction2_ffirst_req, InformationLevel)-4);
3328 pSMB->DataCount = 0; 3425 pSMB->DataCount = 0;
3329 pSMB->DataOffset = 0; 3426 pSMB->DataOffset = 0;
3330 pSMB->SetupCount = 1; /* one byte, no need to le convert */ 3427 pSMB->SetupCount = 1; /* one byte, no need to le convert */
@@ -3364,10 +3461,10 @@ findUniqueRetry:
3364/* xid, tcon, searchName and codepage are input parms, rest are returned */ 3461/* xid, tcon, searchName and codepage are input parms, rest are returned */
3365int 3462int
3366CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 3463CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
3367 const char *searchName, 3464 const char *searchName,
3368 const struct nls_table *nls_codepage, 3465 const struct nls_table *nls_codepage,
3369 __u16 * pnetfid, 3466 __u16 *pnetfid,
3370 struct cifs_search_info * psrch_inf, int remap, const char dirsep) 3467 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
3371{ 3468{
3372/* level 257 SMB_ */ 3469/* level 257 SMB_ */
3373 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 3470 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -3378,7 +3475,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
3378 int name_len; 3475 int name_len;
3379 __u16 params, byte_count; 3476 __u16 params, byte_count;
3380 3477
3381 cFYI(1, ("In FindFirst for %s",searchName)); 3478 cFYI(1, ("In FindFirst for %s", searchName));
3382 3479
3383findFirstRetry: 3480findFirstRetry:
3384 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3481 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3388,7 +3485,7 @@ findFirstRetry:
3388 3485
3389 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3486 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3390 name_len = 3487 name_len =
3391 cifsConvertToUCS((__le16 *) pSMB->FileName,searchName, 3488 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3392 PATH_MAX, nls_codepage, remap); 3489 PATH_MAX, nls_codepage, remap);
3393 /* We can not add the asterik earlier in case 3490 /* We can not add the asterik earlier in case
3394 it got remapped to 0xF03A as if it were part of the 3491 it got remapped to 0xF03A as if it were part of the
@@ -3405,7 +3502,7 @@ findFirstRetry:
3405 } else { /* BB add check for overrun of SMB buf BB */ 3502 } else { /* BB add check for overrun of SMB buf BB */
3406 name_len = strnlen(searchName, PATH_MAX); 3503 name_len = strnlen(searchName, PATH_MAX);
3407/* BB fix here and in unicode clause above ie 3504/* BB fix here and in unicode clause above ie
3408 if(name_len > buffersize-header) 3505 if (name_len > buffersize-header)
3409 free buffer exit; BB */ 3506 free buffer exit; BB */
3410 strncpy(pSMB->FileName, searchName, name_len); 3507 strncpy(pSMB->FileName, searchName, name_len);
3411 pSMB->FileName[name_len] = dirsep; 3508 pSMB->FileName[name_len] = dirsep;
@@ -3438,8 +3535,8 @@ findFirstRetry:
3438 pSMB->SearchAttributes = 3535 pSMB->SearchAttributes =
3439 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 3536 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
3440 ATTR_DIRECTORY); 3537 ATTR_DIRECTORY);
3441 pSMB->SearchCount= cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 3538 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
3442 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | 3539 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
3443 CIFS_SEARCH_RETURN_RESUME); 3540 CIFS_SEARCH_RETURN_RESUME);
3444 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3541 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3445 3542
@@ -3466,7 +3563,7 @@ findFirstRetry:
3466 } else { /* decode response */ 3563 } else { /* decode response */
3467 /* BB remember to free buffer if error BB */ 3564 /* BB remember to free buffer if error BB */
3468 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3565 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3469 if(rc == 0) { 3566 if (rc == 0) {
3470 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3567 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3471 psrch_inf->unicode = TRUE; 3568 psrch_inf->unicode = TRUE;
3472 else 3569 else
@@ -3474,18 +3571,19 @@ findFirstRetry:
3474 3571
3475 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 3572 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
3476 psrch_inf->smallBuf = 0; 3573 psrch_inf->smallBuf = 0;
3477 psrch_inf->srch_entries_start = 3574 psrch_inf->srch_entries_start =
3478 (char *) &pSMBr->hdr.Protocol + 3575 (char *) &pSMBr->hdr.Protocol +
3479 le16_to_cpu(pSMBr->t2.DataOffset); 3576 le16_to_cpu(pSMBr->t2.DataOffset);
3480 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + 3577 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
3481 le16_to_cpu(pSMBr->t2.ParameterOffset)); 3578 le16_to_cpu(pSMBr->t2.ParameterOffset));
3482 3579
3483 if(parms->EndofSearch) 3580 if (parms->EndofSearch)
3484 psrch_inf->endOfSearch = TRUE; 3581 psrch_inf->endOfSearch = TRUE;
3485 else 3582 else
3486 psrch_inf->endOfSearch = FALSE; 3583 psrch_inf->endOfSearch = FALSE;
3487 3584
3488 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3585 psrch_inf->entries_in_buffer =
3586 le16_to_cpu(parms->SearchCount);
3489 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 3587 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
3490 psrch_inf->entries_in_buffer; 3588 psrch_inf->entries_in_buffer;
3491 *pnetfid = parms->SearchHandle; 3589 *pnetfid = parms->SearchHandle;
@@ -3498,7 +3596,7 @@ findFirstRetry:
3498} 3596}
3499 3597
3500int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 3598int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3501 __u16 searchHandle, struct cifs_search_info * psrch_inf) 3599 __u16 searchHandle, struct cifs_search_info *psrch_inf)
3502{ 3600{
3503 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 3601 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
3504 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 3602 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
@@ -3510,7 +3608,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3510 3608
3511 cFYI(1, ("In FindNext")); 3609 cFYI(1, ("In FindNext"));
3512 3610
3513 if(psrch_inf->endOfSearch == TRUE) 3611 if (psrch_inf->endOfSearch == TRUE)
3514 return -ENOENT; 3612 return -ENOENT;
3515 3613
3516 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3614 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3518,12 +3616,13 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3518 if (rc) 3616 if (rc)
3519 return rc; 3617 return rc;
3520 3618
3521 params = 14; /* includes 2 bytes of null string, converted to LE below */ 3619 params = 14; /* includes 2 bytes of null string, converted to LE below*/
3522 byte_count = 0; 3620 byte_count = 0;
3523 pSMB->TotalDataCount = 0; /* no EAs */ 3621 pSMB->TotalDataCount = 0; /* no EAs */
3524 pSMB->MaxParameterCount = cpu_to_le16(8); 3622 pSMB->MaxParameterCount = cpu_to_le16(8);
3525 pSMB->MaxDataCount = 3623 pSMB->MaxDataCount =
3526 cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); 3624 cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) &
3625 0xFFFFFF00);
3527 pSMB->MaxSetupCount = 0; 3626 pSMB->MaxSetupCount = 0;
3528 pSMB->Reserved = 0; 3627 pSMB->Reserved = 0;
3529 pSMB->Flags = 0; 3628 pSMB->Flags = 0;
@@ -3539,15 +3638,6 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3539 pSMB->SearchHandle = searchHandle; /* always kept as le */ 3638 pSMB->SearchHandle = searchHandle; /* always kept as le */
3540 pSMB->SearchCount = 3639 pSMB->SearchCount =
3541 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); 3640 cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
3542 /* test for Unix extensions */
3543/* if (tcon->ses->capabilities & CAP_UNIX) {
3544 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
3545 psrch_inf->info_level = SMB_FIND_FILE_UNIX;
3546 } else {
3547 pSMB->InformationLevel =
3548 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
3549 psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
3550 } */
3551 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3641 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
3552 pSMB->ResumeKey = psrch_inf->resume_key; 3642 pSMB->ResumeKey = psrch_inf->resume_key;
3553 pSMB->SearchFlags = 3643 pSMB->SearchFlags =
@@ -3555,7 +3645,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3555 3645
3556 name_len = psrch_inf->resume_name_len; 3646 name_len = psrch_inf->resume_name_len;
3557 params += name_len; 3647 params += name_len;
3558 if(name_len < PATH_MAX) { 3648 if (name_len < PATH_MAX) {
3559 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 3649 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
3560 byte_count += name_len; 3650 byte_count += name_len;
3561 /* 14 byte parm len above enough for 2 byte null terminator */ 3651 /* 14 byte parm len above enough for 2 byte null terminator */
@@ -3570,20 +3660,20 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3570 pSMB->ParameterCount = pSMB->TotalParameterCount; 3660 pSMB->ParameterCount = pSMB->TotalParameterCount;
3571 pSMB->hdr.smb_buf_length += byte_count; 3661 pSMB->hdr.smb_buf_length += byte_count;
3572 pSMB->ByteCount = cpu_to_le16(byte_count); 3662 pSMB->ByteCount = cpu_to_le16(byte_count);
3573 3663
3574 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3664 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3575 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3665 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3576 cifs_stats_inc(&tcon->num_fnext); 3666 cifs_stats_inc(&tcon->num_fnext);
3577 if (rc) { 3667 if (rc) {
3578 if (rc == -EBADF) { 3668 if (rc == -EBADF) {
3579 psrch_inf->endOfSearch = TRUE; 3669 psrch_inf->endOfSearch = TRUE;
3580 rc = 0; /* search probably was closed at end of search above */ 3670 rc = 0; /* search probably was closed at end of search*/
3581 } else 3671 } else
3582 cFYI(1, ("FindNext returned = %d", rc)); 3672 cFYI(1, ("FindNext returned = %d", rc));
3583 } else { /* decode response */ 3673 } else { /* decode response */
3584 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3674 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3585 3675
3586 if(rc == 0) { 3676 if (rc == 0) {
3587 /* BB fixme add lock for file (srch_info) struct here */ 3677 /* BB fixme add lock for file (srch_info) struct here */
3588 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3678 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
3589 psrch_inf->unicode = TRUE; 3679 psrch_inf->unicode = TRUE;
@@ -3594,7 +3684,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3594 parms = (T2_FNEXT_RSP_PARMS *)response_data; 3684 parms = (T2_FNEXT_RSP_PARMS *)response_data;
3595 response_data = (char *)&pSMBr->hdr.Protocol + 3685 response_data = (char *)&pSMBr->hdr.Protocol +
3596 le16_to_cpu(pSMBr->t2.DataOffset); 3686 le16_to_cpu(pSMBr->t2.DataOffset);
3597 if(psrch_inf->smallBuf) 3687 if (psrch_inf->smallBuf)
3598 cifs_small_buf_release( 3688 cifs_small_buf_release(
3599 psrch_inf->ntwrk_buf_start); 3689 psrch_inf->ntwrk_buf_start);
3600 else 3690 else
@@ -3602,15 +3692,16 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3602 psrch_inf->srch_entries_start = response_data; 3692 psrch_inf->srch_entries_start = response_data;
3603 psrch_inf->ntwrk_buf_start = (char *)pSMB; 3693 psrch_inf->ntwrk_buf_start = (char *)pSMB;
3604 psrch_inf->smallBuf = 0; 3694 psrch_inf->smallBuf = 0;
3605 if(parms->EndofSearch) 3695 if (parms->EndofSearch)
3606 psrch_inf->endOfSearch = TRUE; 3696 psrch_inf->endOfSearch = TRUE;
3607 else 3697 else
3608 psrch_inf->endOfSearch = FALSE; 3698 psrch_inf->endOfSearch = FALSE;
3609 3699 psrch_inf->entries_in_buffer =
3610 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 3700 le16_to_cpu(parms->SearchCount);
3611 psrch_inf->index_of_last_entry += 3701 psrch_inf->index_of_last_entry +=
3612 psrch_inf->entries_in_buffer; 3702 psrch_inf->entries_in_buffer;
3613/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ 3703/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
3704 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
3614 3705
3615 /* BB fixme add unlock here */ 3706 /* BB fixme add unlock here */
3616 } 3707 }
@@ -3625,12 +3716,12 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3625FNext2_err_exit: 3716FNext2_err_exit:
3626 if (rc != 0) 3717 if (rc != 0)
3627 cifs_buf_release(pSMB); 3718 cifs_buf_release(pSMB);
3628
3629 return rc; 3719 return rc;
3630} 3720}
3631 3721
3632int 3722int
3633CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle) 3723CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3724 const __u16 searchHandle)
3634{ 3725{
3635 int rc = 0; 3726 int rc = 0;
3636 FINDCLOSE_REQ *pSMB = NULL; 3727 FINDCLOSE_REQ *pSMB = NULL;
@@ -3642,7 +3733,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
3642 3733
3643 /* no sense returning error if session restarted 3734 /* no sense returning error if session restarted
3644 as file handle has been closed */ 3735 as file handle has been closed */
3645 if(rc == -EAGAIN) 3736 if (rc == -EAGAIN)
3646 return 0; 3737 return 0;
3647 if (rc) 3738 if (rc)
3648 return rc; 3739 return rc;
@@ -3667,9 +3758,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
3667 3758
3668int 3759int
3669CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 3760CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
3670 const unsigned char *searchName, 3761 const unsigned char *searchName,
3671 __u64 * inode_number, 3762 __u64 * inode_number,
3672 const struct nls_table *nls_codepage, int remap) 3763 const struct nls_table *nls_codepage, int remap)
3673{ 3764{
3674 int rc = 0; 3765 int rc = 0;
3675 TRANSACTION2_QPI_REQ *pSMB = NULL; 3766 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -3677,24 +3768,23 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
3677 int name_len, bytes_returned; 3768 int name_len, bytes_returned;
3678 __u16 params, byte_count; 3769 __u16 params, byte_count;
3679 3770
3680 cFYI(1,("In GetSrvInodeNum for %s",searchName)); 3771 cFYI(1, ("In GetSrvInodeNum for %s", searchName));
3681 if(tcon == NULL) 3772 if (tcon == NULL)
3682 return -ENODEV; 3773 return -ENODEV;
3683 3774
3684GetInodeNumberRetry: 3775GetInodeNumberRetry:
3685 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3776 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3686 (void **) &pSMBr); 3777 (void **) &pSMBr);
3687 if (rc) 3778 if (rc)
3688 return rc; 3779 return rc;
3689 3780
3690
3691 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3781 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3692 name_len = 3782 name_len =
3693 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 3783 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3694 PATH_MAX,nls_codepage, remap); 3784 PATH_MAX, nls_codepage, remap);
3695 name_len++; /* trailing null */ 3785 name_len++; /* trailing null */
3696 name_len *= 2; 3786 name_len *= 2;
3697 } else { /* BB improve the check for buffer overruns BB */ 3787 } else { /* BB improve the check for buffer overruns BB */
3698 name_len = strnlen(searchName, PATH_MAX); 3788 name_len = strnlen(searchName, PATH_MAX);
3699 name_len++; /* trailing null */ 3789 name_len++; /* trailing null */
3700 strncpy(pSMB->FileName, searchName, name_len); 3790 strncpy(pSMB->FileName, searchName, name_len);
@@ -3711,7 +3801,7 @@ GetInodeNumberRetry:
3711 pSMB->Timeout = 0; 3801 pSMB->Timeout = 0;
3712 pSMB->Reserved2 = 0; 3802 pSMB->Reserved2 = 0;
3713 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3803 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3714 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 3804 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
3715 pSMB->DataCount = 0; 3805 pSMB->DataCount = 0;
3716 pSMB->DataOffset = 0; 3806 pSMB->DataOffset = 0;
3717 pSMB->SetupCount = 1; 3807 pSMB->SetupCount = 1;
@@ -3737,12 +3827,12 @@ GetInodeNumberRetry:
3737 /* If rc should we check for EOPNOSUPP and 3827 /* If rc should we check for EOPNOSUPP and
3738 disable the srvino flag? or in caller? */ 3828 disable the srvino flag? or in caller? */
3739 rc = -EIO; /* bad smb */ 3829 rc = -EIO; /* bad smb */
3740 else { 3830 else {
3741 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3831 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3742 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3832 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3743 struct file_internal_info * pfinfo; 3833 struct file_internal_info *pfinfo;
3744 /* BB Do we need a cast or hash here ? */ 3834 /* BB Do we need a cast or hash here ? */
3745 if(count < 8) { 3835 if (count < 8) {
3746 cFYI(1, ("Illegal size ret in QryIntrnlInf")); 3836 cFYI(1, ("Illegal size ret in QryIntrnlInf"));
3747 rc = -EIO; 3837 rc = -EIO;
3748 goto GetInodeNumOut; 3838 goto GetInodeNumOut;
@@ -3769,12 +3859,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3769/* TRANS2_GET_DFS_REFERRAL */ 3859/* TRANS2_GET_DFS_REFERRAL */
3770 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 3860 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
3771 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 3861 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
3772 struct dfs_referral_level_3 * referrals = NULL; 3862 struct dfs_referral_level_3 *referrals = NULL;
3773 int rc = 0; 3863 int rc = 0;
3774 int bytes_returned; 3864 int bytes_returned;
3775 int name_len; 3865 int name_len;
3776 unsigned int i; 3866 unsigned int i;
3777 char * temp; 3867 char *temp;
3778 __u16 params, byte_count; 3868 __u16 params, byte_count;
3779 *number_of_UNC_in_array = 0; 3869 *number_of_UNC_in_array = 0;
3780 *targetUNCs = NULL; 3870 *targetUNCs = NULL;
@@ -3787,8 +3877,8 @@ getDFSRetry:
3787 (void **) &pSMBr); 3877 (void **) &pSMBr);
3788 if (rc) 3878 if (rc)
3789 return rc; 3879 return rc;
3790 3880
3791 /* server pointer checked in called function, 3881 /* server pointer checked in called function,
3792 but should never be null here anyway */ 3882 but should never be null here anyway */
3793 pSMB->hdr.Mid = GetNextMid(ses->server); 3883 pSMB->hdr.Mid = GetNextMid(ses->server);
3794 pSMB->hdr.Tid = ses->ipc_tid; 3884 pSMB->hdr.Tid = ses->ipc_tid;
@@ -3807,19 +3897,19 @@ getDFSRetry:
3807 searchName, PATH_MAX, nls_codepage, remap); 3897 searchName, PATH_MAX, nls_codepage, remap);
3808 name_len++; /* trailing null */ 3898 name_len++; /* trailing null */
3809 name_len *= 2; 3899 name_len *= 2;
3810 } else { /* BB improve the check for buffer overruns BB */ 3900 } else { /* BB improve the check for buffer overruns BB */
3811 name_len = strnlen(searchName, PATH_MAX); 3901 name_len = strnlen(searchName, PATH_MAX);
3812 name_len++; /* trailing null */ 3902 name_len++; /* trailing null */
3813 strncpy(pSMB->RequestFileName, searchName, name_len); 3903 strncpy(pSMB->RequestFileName, searchName, name_len);
3814 } 3904 }
3815 3905
3816 if(ses->server) { 3906 if (ses->server) {
3817 if(ses->server->secMode & 3907 if (ses->server->secMode &
3818 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3908 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3819 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3909 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3820 } 3910 }
3821 3911
3822 pSMB->hdr.Uid = ses->Suid; 3912 pSMB->hdr.Uid = ses->Suid;
3823 3913
3824 params = 2 /* level */ + name_len /*includes null */ ; 3914 params = 2 /* level */ + name_len /*includes null */ ;
3825 pSMB->TotalDataCount = 0; 3915 pSMB->TotalDataCount = 0;
@@ -3833,7 +3923,7 @@ getDFSRetry:
3833 pSMB->Timeout = 0; 3923 pSMB->Timeout = 0;
3834 pSMB->Reserved2 = 0; 3924 pSMB->Reserved2 = 0;
3835 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3925 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3836 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 3926 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
3837 pSMB->SetupCount = 1; 3927 pSMB->SetupCount = 1;
3838 pSMB->Reserved3 = 0; 3928 pSMB->Reserved3 = 0;
3839 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 3929 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
@@ -3852,74 +3942,87 @@ getDFSRetry:
3852/* BB Add logic to parse referrals here */ 3942/* BB Add logic to parse referrals here */
3853 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3943 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3854 3944
3855 if (rc || (pSMBr->ByteCount < 17)) /* BB also check enough total bytes returned */ 3945 /* BB Also check if enough total bytes returned? */
3946 if (rc || (pSMBr->ByteCount < 17))
3856 rc = -EIO; /* bad smb */ 3947 rc = -EIO; /* bad smb */
3857 else { 3948 else {
3858 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3949 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3859 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount); 3950 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
3860 3951
3861 cFYI(1, 3952 cFYI(1,
3862 ("Decoding GetDFSRefer response. BCC: %d Offset %d", 3953 ("Decoding GetDFSRefer response BCC: %d Offset %d",
3863 pSMBr->ByteCount, data_offset)); 3954 pSMBr->ByteCount, data_offset));
3864 referrals = 3955 referrals =
3865 (struct dfs_referral_level_3 *) 3956 (struct dfs_referral_level_3 *)
3866 (8 /* sizeof start of data block */ + 3957 (8 /* sizeof start of data block */ +
3867 data_offset + 3958 data_offset +
3868 (char *) &pSMBr->hdr.Protocol); 3959 (char *) &pSMBr->hdr.Protocol);
3869 cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x", 3960 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3870 le16_to_cpu(pSMBr->NumberOfReferrals),le16_to_cpu(pSMBr->DFSFlags), le16_to_cpu(referrals->ReferralSize),le16_to_cpu(referrals->ServerType),le16_to_cpu(referrals->ReferralFlags),le16_to_cpu(referrals->TimeToLive))); 3961 "for referral one refer size: 0x%x srv "
3962 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3963 le16_to_cpu(pSMBr->NumberOfReferrals),
3964 le16_to_cpu(pSMBr->DFSFlags),
3965 le16_to_cpu(referrals->ReferralSize),
3966 le16_to_cpu(referrals->ServerType),
3967 le16_to_cpu(referrals->ReferralFlags),
3968 le16_to_cpu(referrals->TimeToLive)));
3871 /* BB This field is actually two bytes in from start of 3969 /* BB This field is actually two bytes in from start of
3872 data block so we could do safety check that DataBlock 3970 data block so we could do safety check that DataBlock
3873 begins at address of pSMBr->NumberOfReferrals */ 3971 begins at address of pSMBr->NumberOfReferrals */
3874 *number_of_UNC_in_array = le16_to_cpu(pSMBr->NumberOfReferrals); 3972 *number_of_UNC_in_array =
3973 le16_to_cpu(pSMBr->NumberOfReferrals);
3875 3974
3876 /* BB Fix below so can return more than one referral */ 3975 /* BB Fix below so can return more than one referral */
3877 if(*number_of_UNC_in_array > 1) 3976 if (*number_of_UNC_in_array > 1)
3878 *number_of_UNC_in_array = 1; 3977 *number_of_UNC_in_array = 1;
3879 3978
3880 /* get the length of the strings describing refs */ 3979 /* get the length of the strings describing refs */
3881 name_len = 0; 3980 name_len = 0;
3882 for(i=0;i<*number_of_UNC_in_array;i++) { 3981 for (i = 0; i < *number_of_UNC_in_array; i++) {
3883 /* make sure that DfsPathOffset not past end */ 3982 /* make sure that DfsPathOffset not past end */
3884 __u16 offset = le16_to_cpu(referrals->DfsPathOffset); 3983 __u16 offset =
3984 le16_to_cpu(referrals->DfsPathOffset);
3885 if (offset > data_count) { 3985 if (offset > data_count) {
3886 /* if invalid referral, stop here and do 3986 /* if invalid referral, stop here and do
3887 not try to copy any more */ 3987 not try to copy any more */
3888 *number_of_UNC_in_array = i; 3988 *number_of_UNC_in_array = i;
3889 break; 3989 break;
3890 } 3990 }
3891 temp = ((char *)referrals) + offset; 3991 temp = ((char *)referrals) + offset;
3892 3992
3893 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 3993 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3894 name_len += UniStrnlen((wchar_t *)temp,data_count); 3994 name_len += UniStrnlen((wchar_t *)temp,
3995 data_count);
3895 } else { 3996 } else {
3896 name_len += strnlen(temp,data_count); 3997 name_len += strnlen(temp, data_count);
3897 } 3998 }
3898 referrals++; 3999 referrals++;
3899 /* BB add check that referral pointer does not fall off end PDU */ 4000 /* BB add check that referral pointer does
3900 4001 not fall off end PDU */
3901 } 4002 }
3902 /* BB add check for name_len bigger than bcc */ 4003 /* BB add check for name_len bigger than bcc */
3903 *targetUNCs = 4004 *targetUNCs =
3904 kmalloc(name_len+1+ (*number_of_UNC_in_array),GFP_KERNEL); 4005 kmalloc(name_len+1+(*number_of_UNC_in_array),
3905 if(*targetUNCs == NULL) { 4006 GFP_KERNEL);
4007 if (*targetUNCs == NULL) {
3906 rc = -ENOMEM; 4008 rc = -ENOMEM;
3907 goto GetDFSRefExit; 4009 goto GetDFSRefExit;
3908 } 4010 }
3909 /* copy the ref strings */ 4011 /* copy the ref strings */
3910 referrals = 4012 referrals = (struct dfs_referral_level_3 *)
3911 (struct dfs_referral_level_3 *) 4013 (8 /* sizeof data hdr */ + data_offset +
3912 (8 /* sizeof data hdr */ +
3913 data_offset +
3914 (char *) &pSMBr->hdr.Protocol); 4014 (char *) &pSMBr->hdr.Protocol);
3915 4015
3916 for(i=0;i<*number_of_UNC_in_array;i++) { 4016 for (i = 0; i < *number_of_UNC_in_array; i++) {
3917 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); 4017 temp = ((char *)referrals) +
4018 le16_to_cpu(referrals->DfsPathOffset);
3918 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 4019 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3919 cifs_strfromUCS_le(*targetUNCs, 4020 cifs_strfromUCS_le(*targetUNCs,
3920 (__le16 *) temp, name_len, nls_codepage); 4021 (__le16 *) temp,
4022 name_len,
4023 nls_codepage);
3921 } else { 4024 } else {
3922 strncpy(*targetUNCs,temp,name_len); 4025 strncpy(*targetUNCs, temp, name_len);
3923 } 4026 }
3924 /* BB update target_uncs pointers */ 4027 /* BB update target_uncs pointers */
3925 referrals++; 4028 referrals++;
@@ -3996,18 +4099,17 @@ oldQFSInfoRetry:
3996 rc = -EIO; /* bad smb */ 4099 rc = -EIO; /* bad smb */
3997 else { 4100 else {
3998 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4101 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3999 cFYI(1,("qfsinf resp BCC: %d Offset %d", 4102 cFYI(1, ("qfsinf resp BCC: %d Offset %d",
4000 pSMBr->ByteCount, data_offset)); 4103 pSMBr->ByteCount, data_offset));
4001 4104
4002 response_data = 4105 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4003 (FILE_SYSTEM_ALLOC_INFO *)
4004 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4106 (((char *) &pSMBr->hdr.Protocol) + data_offset);
4005 FSData->f_bsize = 4107 FSData->f_bsize =
4006 le16_to_cpu(response_data->BytesPerSector) * 4108 le16_to_cpu(response_data->BytesPerSector) *
4007 le32_to_cpu(response_data-> 4109 le32_to_cpu(response_data->
4008 SectorsPerAllocationUnit); 4110 SectorsPerAllocationUnit);
4009 FSData->f_blocks = 4111 FSData->f_blocks =
4010 le32_to_cpu(response_data->TotalAllocationUnits); 4112 le32_to_cpu(response_data->TotalAllocationUnits);
4011 FSData->f_bfree = FSData->f_bavail = 4113 FSData->f_bfree = FSData->f_bavail =
4012 le32_to_cpu(response_data->FreeAllocationUnits); 4114 le32_to_cpu(response_data->FreeAllocationUnits);
4013 cFYI(1, 4115 cFYI(1,
@@ -4056,7 +4158,7 @@ QFSInfoRetry:
4056 pSMB->TotalParameterCount = cpu_to_le16(params); 4158 pSMB->TotalParameterCount = cpu_to_le16(params);
4057 pSMB->ParameterCount = pSMB->TotalParameterCount; 4159 pSMB->ParameterCount = pSMB->TotalParameterCount;
4058 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4160 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4059 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4161 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4060 pSMB->DataCount = 0; 4162 pSMB->DataCount = 0;
4061 pSMB->DataOffset = 0; 4163 pSMB->DataOffset = 0;
4062 pSMB->SetupCount = 1; 4164 pSMB->SetupCount = 1;
@@ -4071,7 +4173,7 @@ QFSInfoRetry:
4071 if (rc) { 4173 if (rc) {
4072 cFYI(1, ("Send error in QFSInfo = %d", rc)); 4174 cFYI(1, ("Send error in QFSInfo = %d", rc));
4073 } else { /* decode response */ 4175 } else { /* decode response */
4074 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4176 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4075 4177
4076 if (rc || (pSMBr->ByteCount < 24)) 4178 if (rc || (pSMBr->ByteCount < 24))
4077 rc = -EIO; /* bad smb */ 4179 rc = -EIO; /* bad smb */
@@ -4136,7 +4238,7 @@ QFSAttributeRetry:
4136 pSMB->TotalParameterCount = cpu_to_le16(params); 4238 pSMB->TotalParameterCount = cpu_to_le16(params);
4137 pSMB->ParameterCount = pSMB->TotalParameterCount; 4239 pSMB->ParameterCount = pSMB->TotalParameterCount;
4138 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4240 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4139 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4241 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4140 pSMB->DataCount = 0; 4242 pSMB->DataCount = 0;
4141 pSMB->DataOffset = 0; 4243 pSMB->DataOffset = 0;
4142 pSMB->SetupCount = 1; 4244 pSMB->SetupCount = 1;
@@ -4153,7 +4255,8 @@ QFSAttributeRetry:
4153 } else { /* decode response */ 4255 } else { /* decode response */
4154 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4256 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4155 4257
4156 if (rc || (pSMBr->ByteCount < 13)) { /* BB also check enough bytes returned */ 4258 if (rc || (pSMBr->ByteCount < 13)) {
4259 /* BB also check if enough bytes returned */
4157 rc = -EIO; /* bad smb */ 4260 rc = -EIO; /* bad smb */
4158 } else { 4261 } else {
4159 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4262 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4204,7 +4307,7 @@ QFSDeviceRetry:
4204 pSMB->TotalParameterCount = cpu_to_le16(params); 4307 pSMB->TotalParameterCount = cpu_to_le16(params);
4205 pSMB->ParameterCount = pSMB->TotalParameterCount; 4308 pSMB->ParameterCount = pSMB->TotalParameterCount;
4206 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4309 pSMB->ParameterOffset = cpu_to_le16(offsetof(
4207 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4310 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4208 4311
4209 pSMB->DataCount = 0; 4312 pSMB->DataCount = 0;
4210 pSMB->DataOffset = 0; 4313 pSMB->DataOffset = 0;
@@ -4274,8 +4377,8 @@ QFSUnixRetry:
4274 byte_count = params + 1 /* pad */ ; 4377 byte_count = params + 1 /* pad */ ;
4275 pSMB->ParameterCount = cpu_to_le16(params); 4378 pSMB->ParameterCount = cpu_to_le16(params);
4276 pSMB->TotalParameterCount = pSMB->ParameterCount; 4379 pSMB->TotalParameterCount = pSMB->ParameterCount;
4277 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4380 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4278 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4381 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4279 pSMB->SetupCount = 1; 4382 pSMB->SetupCount = 1;
4280 pSMB->Reserved3 = 0; 4383 pSMB->Reserved3 = 0;
4281 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4384 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
@@ -4335,7 +4438,8 @@ SETFSUnixRetry:
4335 pSMB->Flags = 0; 4438 pSMB->Flags = 0;
4336 pSMB->Timeout = 0; 4439 pSMB->Timeout = 0;
4337 pSMB->Reserved2 = 0; 4440 pSMB->Reserved2 = 0;
4338 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4; 4441 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
4442 - 4;
4339 offset = param_offset + params; 4443 offset = param_offset + params;
4340 4444
4341 pSMB->MaxParameterCount = cpu_to_le16(4); 4445 pSMB->MaxParameterCount = cpu_to_le16(4);
@@ -4417,8 +4521,8 @@ QFSPosixRetry:
4417 byte_count = params + 1 /* pad */ ; 4521 byte_count = params + 1 /* pad */ ;
4418 pSMB->ParameterCount = cpu_to_le16(params); 4522 pSMB->ParameterCount = cpu_to_le16(params);
4419 pSMB->TotalParameterCount = pSMB->ParameterCount; 4523 pSMB->TotalParameterCount = pSMB->ParameterCount;
4420 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4524 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
4421 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4525 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
4422 pSMB->SetupCount = 1; 4526 pSMB->SetupCount = 1;
4423 pSMB->Reserved3 = 0; 4527 pSMB->Reserved3 = 0;
4424 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4528 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
@@ -4447,18 +4551,18 @@ QFSPosixRetry:
4447 le64_to_cpu(response_data->TotalBlocks); 4551 le64_to_cpu(response_data->TotalBlocks);
4448 FSData->f_bfree = 4552 FSData->f_bfree =
4449 le64_to_cpu(response_data->BlocksAvail); 4553 le64_to_cpu(response_data->BlocksAvail);
4450 if(response_data->UserBlocksAvail == cpu_to_le64(-1)) { 4554 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
4451 FSData->f_bavail = FSData->f_bfree; 4555 FSData->f_bavail = FSData->f_bfree;
4452 } else { 4556 } else {
4453 FSData->f_bavail = 4557 FSData->f_bavail =
4454 le64_to_cpu(response_data->UserBlocksAvail); 4558 le64_to_cpu(response_data->UserBlocksAvail);
4455 } 4559 }
4456 if(response_data->TotalFileNodes != cpu_to_le64(-1)) 4560 if (response_data->TotalFileNodes != cpu_to_le64(-1))
4457 FSData->f_files = 4561 FSData->f_files =
4458 le64_to_cpu(response_data->TotalFileNodes); 4562 le64_to_cpu(response_data->TotalFileNodes);
4459 if(response_data->FreeFileNodes != cpu_to_le64(-1)) 4563 if (response_data->FreeFileNodes != cpu_to_le64(-1))
4460 FSData->f_ffree = 4564 FSData->f_ffree =
4461 le64_to_cpu(response_data->FreeFileNodes); 4565 le64_to_cpu(response_data->FreeFileNodes);
4462 } 4566 }
4463 } 4567 }
4464 cifs_buf_release(pSMB); 4568 cifs_buf_release(pSMB);
@@ -4470,15 +4574,15 @@ QFSPosixRetry:
4470} 4574}
4471 4575
4472 4576
4473/* We can not use write of zero bytes trick to 4577/* We can not use write of zero bytes trick to
4474 set file size due to need for large file support. Also note that 4578 set file size due to need for large file support. Also note that
4475 this SetPathInfo is preferred to SetFileInfo based method in next 4579 this SetPathInfo is preferred to SetFileInfo based method in next
4476 routine which is only needed to work around a sharing violation bug 4580 routine which is only needed to work around a sharing violation bug
4477 in Samba which this routine can run into */ 4581 in Samba which this routine can run into */
4478 4582
4479int 4583int
4480CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, 4584CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
4481 __u64 size, int SetAllocation, 4585 __u64 size, int SetAllocation,
4482 const struct nls_table *nls_codepage, int remap) 4586 const struct nls_table *nls_codepage, int remap)
4483{ 4587{
4484 struct smb_com_transaction2_spi_req *pSMB = NULL; 4588 struct smb_com_transaction2_spi_req *pSMB = NULL;
@@ -4517,22 +4621,22 @@ SetEOFRetry:
4517 pSMB->Timeout = 0; 4621 pSMB->Timeout = 0;
4518 pSMB->Reserved2 = 0; 4622 pSMB->Reserved2 = 0;
4519 param_offset = offsetof(struct smb_com_transaction2_spi_req, 4623 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4520 InformationLevel) - 4; 4624 InformationLevel) - 4;
4521 offset = param_offset + params; 4625 offset = param_offset + params;
4522 if(SetAllocation) { 4626 if (SetAllocation) {
4523 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4627 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4524 pSMB->InformationLevel = 4628 pSMB->InformationLevel =
4525 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 4629 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
4526 else 4630 else
4527 pSMB->InformationLevel = 4631 pSMB->InformationLevel =
4528 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 4632 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
4529 } else /* Set File Size */ { 4633 } else /* Set File Size */ {
4530 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4634 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4531 pSMB->InformationLevel = 4635 pSMB->InformationLevel =
4532 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 4636 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
4533 else 4637 else
4534 pSMB->InformationLevel = 4638 pSMB->InformationLevel =
4535 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 4639 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4536 } 4640 }
4537 4641
4538 parm_data = 4642 parm_data =
@@ -4567,8 +4671,8 @@ SetEOFRetry:
4567} 4671}
4568 4672
4569int 4673int
4570CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, 4674CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4571 __u16 fid, __u32 pid_of_opener, int SetAllocation) 4675 __u16 fid, __u32 pid_of_opener, int SetAllocation)
4572{ 4676{
4573 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4677 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4574 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 4678 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -4589,7 +4693,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4589 4693
4590 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4694 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4591 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 4695 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4592 4696
4593 params = 6; 4697 params = 6;
4594 pSMB->MaxSetupCount = 0; 4698 pSMB->MaxSetupCount = 0;
4595 pSMB->Reserved = 0; 4699 pSMB->Reserved = 0;
@@ -4599,7 +4703,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4599 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 4703 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4600 offset = param_offset + params; 4704 offset = param_offset + params;
4601 4705
4602 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4706 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4603 4707
4604 count = sizeof(struct file_end_of_file_info); 4708 count = sizeof(struct file_end_of_file_info);
4605 pSMB->MaxParameterCount = cpu_to_le16(2); 4709 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -4614,25 +4718,25 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4614 pSMB->TotalParameterCount = pSMB->ParameterCount; 4718 pSMB->TotalParameterCount = pSMB->ParameterCount;
4615 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4719 pSMB->ParameterOffset = cpu_to_le16(param_offset);
4616 parm_data = 4720 parm_data =
4617 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 4721 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
4618 offset); 4722 + offset);
4619 pSMB->DataOffset = cpu_to_le16(offset); 4723 pSMB->DataOffset = cpu_to_le16(offset);
4620 parm_data->FileSize = cpu_to_le64(size); 4724 parm_data->FileSize = cpu_to_le64(size);
4621 pSMB->Fid = fid; 4725 pSMB->Fid = fid;
4622 if(SetAllocation) { 4726 if (SetAllocation) {
4623 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4727 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4624 pSMB->InformationLevel = 4728 pSMB->InformationLevel =
4625 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 4729 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
4626 else 4730 else
4627 pSMB->InformationLevel = 4731 pSMB->InformationLevel =
4628 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 4732 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
4629 } else /* Set File Size */ { 4733 } else /* Set File Size */ {
4630 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 4734 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
4631 pSMB->InformationLevel = 4735 pSMB->InformationLevel =
4632 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 4736 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
4633 else 4737 else
4634 pSMB->InformationLevel = 4738 pSMB->InformationLevel =
4635 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 4739 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4636 } 4740 }
4637 pSMB->Reserved4 = 0; 4741 pSMB->Reserved4 = 0;
4638 pSMB->hdr.smb_buf_length += byte_count; 4742 pSMB->hdr.smb_buf_length += byte_count;
@@ -4648,21 +4752,21 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4648 if (pSMB) 4752 if (pSMB)
4649 cifs_small_buf_release(pSMB); 4753 cifs_small_buf_release(pSMB);
4650 4754
4651 /* Note: On -EAGAIN error only caller can retry on handle based calls 4755 /* Note: On -EAGAIN error only caller can retry on handle based calls
4652 since file handle passed in no longer valid */ 4756 since file handle passed in no longer valid */
4653 4757
4654 return rc; 4758 return rc;
4655} 4759}
4656 4760
4657/* Some legacy servers such as NT4 require that the file times be set on 4761/* Some legacy servers such as NT4 require that the file times be set on
4658 an open handle, rather than by pathname - this is awkward due to 4762 an open handle, rather than by pathname - this is awkward due to
4659 potential access conflicts on the open, but it is unavoidable for these 4763 potential access conflicts on the open, but it is unavoidable for these
4660 old servers since the only other choice is to go from 100 nanosecond DCE 4764 old servers since the only other choice is to go from 100 nanosecond DCE
4661 time and resort to the original setpathinfo level which takes the ancient 4765 time and resort to the original setpathinfo level which takes the ancient
4662 DOS time format with 2 second granularity */ 4766 DOS time format with 2 second granularity */
4663int 4767int
4664CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_INFO * data, 4768CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4665 __u16 fid) 4769 const FILE_BASIC_INFO *data, __u16 fid)
4666{ 4770{
4667 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4771 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4668 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 4772 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -4684,7 +4788,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4684 use an existing handle (rather than opening one on the fly) */ 4788 use an existing handle (rather than opening one on the fly) */
4685 /* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4789 /* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4686 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/ 4790 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/
4687 4791
4688 params = 6; 4792 params = 6;
4689 pSMB->MaxSetupCount = 0; 4793 pSMB->MaxSetupCount = 0;
4690 pSMB->Reserved = 0; 4794 pSMB->Reserved = 0;
@@ -4694,7 +4798,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4694 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 4798 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
4695 offset = param_offset + params; 4799 offset = param_offset + params;
4696 4800
4697 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4801 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4698 4802
4699 count = sizeof (FILE_BASIC_INFO); 4803 count = sizeof (FILE_BASIC_INFO);
4700 pSMB->MaxParameterCount = cpu_to_le16(2); 4804 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -4717,16 +4821,16 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4717 pSMB->Reserved4 = 0; 4821 pSMB->Reserved4 = 0;
4718 pSMB->hdr.smb_buf_length += byte_count; 4822 pSMB->hdr.smb_buf_length += byte_count;
4719 pSMB->ByteCount = cpu_to_le16(byte_count); 4823 pSMB->ByteCount = cpu_to_le16(byte_count);
4720 memcpy(data_offset,data,sizeof(FILE_BASIC_INFO)); 4824 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
4721 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4825 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
4722 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4826 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4723 if (rc) { 4827 if (rc) {
4724 cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); 4828 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
4725 } 4829 }
4726 4830
4727 cifs_small_buf_release(pSMB); 4831 cifs_small_buf_release(pSMB);
4728 4832
4729 /* Note: On -EAGAIN error only caller can retry on handle based calls 4833 /* Note: On -EAGAIN error only caller can retry on handle based calls
4730 since file handle passed in no longer valid */ 4834 since file handle passed in no longer valid */
4731 4835
4732 return rc; 4836 return rc;
@@ -4735,7 +4839,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_I
4735 4839
4736int 4840int
4737CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, 4841CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName,
4738 const FILE_BASIC_INFO * data, 4842 const FILE_BASIC_INFO *data,
4739 const struct nls_table *nls_codepage, int remap) 4843 const struct nls_table *nls_codepage, int remap)
4740{ 4844{
4741 TRANSACTION2_SPI_REQ *pSMB = NULL; 4845 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -4760,7 +4864,7 @@ SetTimesRetry:
4760 PATH_MAX, nls_codepage, remap); 4864 PATH_MAX, nls_codepage, remap);
4761 name_len++; /* trailing null */ 4865 name_len++; /* trailing null */
4762 name_len *= 2; 4866 name_len *= 2;
4763 } else { /* BB improve the check for buffer overruns BB */ 4867 } else { /* BB improve the check for buffer overruns BB */
4764 name_len = strnlen(fileName, PATH_MAX); 4868 name_len = strnlen(fileName, PATH_MAX);
4765 name_len++; /* trailing null */ 4869 name_len++; /* trailing null */
4766 strncpy(pSMB->FileName, fileName, name_len); 4870 strncpy(pSMB->FileName, fileName, name_len);
@@ -4776,7 +4880,7 @@ SetTimesRetry:
4776 pSMB->Timeout = 0; 4880 pSMB->Timeout = 0;
4777 pSMB->Reserved2 = 0; 4881 pSMB->Reserved2 = 0;
4778 param_offset = offsetof(struct smb_com_transaction2_spi_req, 4882 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4779 InformationLevel) - 4; 4883 InformationLevel) - 4;
4780 offset = param_offset + params; 4884 offset = param_offset + params;
4781 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 4885 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
4782 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4886 pSMB->ParameterOffset = cpu_to_le16(param_offset);
@@ -4837,11 +4941,11 @@ SetAttrLgcyRetry:
4837 4941
4838 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4942 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4839 name_len = 4943 name_len =
4840 ConvertToUCS((__le16 *) pSMB->fileName, fileName, 4944 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
4841 PATH_MAX, nls_codepage); 4945 PATH_MAX, nls_codepage);
4842 name_len++; /* trailing null */ 4946 name_len++; /* trailing null */
4843 name_len *= 2; 4947 name_len *= 2;
4844 } else { /* BB improve the check for buffer overruns BB */ 4948 } else { /* BB improve the check for buffer overruns BB */
4845 name_len = strnlen(fileName, PATH_MAX); 4949 name_len = strnlen(fileName, PATH_MAX);
4846 name_len++; /* trailing null */ 4950 name_len++; /* trailing null */
4847 strncpy(pSMB->fileName, fileName, name_len); 4951 strncpy(pSMB->fileName, fileName, name_len);
@@ -4867,8 +4971,8 @@ SetAttrLgcyRetry:
4867 4971
4868int 4972int
4869CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, 4973CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
4870 char *fileName, __u64 mode, __u64 uid, __u64 gid, 4974 char *fileName, __u64 mode, __u64 uid, __u64 gid,
4871 dev_t device, const struct nls_table *nls_codepage, 4975 dev_t device, const struct nls_table *nls_codepage,
4872 int remap) 4976 int remap)
4873{ 4977{
4874 TRANSACTION2_SPI_REQ *pSMB = NULL; 4978 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -4888,7 +4992,7 @@ setPermsRetry:
4888 4992
4889 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4993 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4890 name_len = 4994 name_len =
4891 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 4995 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
4892 PATH_MAX, nls_codepage, remap); 4996 PATH_MAX, nls_codepage, remap);
4893 name_len++; /* trailing null */ 4997 name_len++; /* trailing null */
4894 name_len *= 2; 4998 name_len *= 2;
@@ -4908,7 +5012,7 @@ setPermsRetry:
4908 pSMB->Timeout = 0; 5012 pSMB->Timeout = 0;
4909 pSMB->Reserved2 = 0; 5013 pSMB->Reserved2 = 0;
4910 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5014 param_offset = offsetof(struct smb_com_transaction2_spi_req,
4911 InformationLevel) - 4; 5015 InformationLevel) - 4;
4912 offset = param_offset + params; 5016 offset = param_offset + params;
4913 data_offset = 5017 data_offset =
4914 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol + 5018 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
@@ -4931,7 +5035,7 @@ setPermsRetry:
4931 older clients, but we should be precise - we use SetFileSize to 5035 older clients, but we should be precise - we use SetFileSize to
4932 set file size and do not want to truncate file size to zero 5036 set file size and do not want to truncate file size to zero
4933 accidently as happened on one Samba server beta by putting 5037 accidently as happened on one Samba server beta by putting
4934 zero instead of -1 here */ 5038 zero instead of -1 here */
4935 data_offset->EndOfFile = NO_CHANGE_64; 5039 data_offset->EndOfFile = NO_CHANGE_64;
4936 data_offset->NumOfBytes = NO_CHANGE_64; 5040 data_offset->NumOfBytes = NO_CHANGE_64;
4937 data_offset->LastStatusChange = NO_CHANGE_64; 5041 data_offset->LastStatusChange = NO_CHANGE_64;
@@ -4943,20 +5047,20 @@ setPermsRetry:
4943 data_offset->DevMajor = cpu_to_le64(MAJOR(device)); 5047 data_offset->DevMajor = cpu_to_le64(MAJOR(device));
4944 data_offset->DevMinor = cpu_to_le64(MINOR(device)); 5048 data_offset->DevMinor = cpu_to_le64(MINOR(device));
4945 data_offset->Permissions = cpu_to_le64(mode); 5049 data_offset->Permissions = cpu_to_le64(mode);
4946 5050
4947 if(S_ISREG(mode)) 5051 if (S_ISREG(mode))
4948 data_offset->Type = cpu_to_le32(UNIX_FILE); 5052 data_offset->Type = cpu_to_le32(UNIX_FILE);
4949 else if(S_ISDIR(mode)) 5053 else if (S_ISDIR(mode))
4950 data_offset->Type = cpu_to_le32(UNIX_DIR); 5054 data_offset->Type = cpu_to_le32(UNIX_DIR);
4951 else if(S_ISLNK(mode)) 5055 else if (S_ISLNK(mode))
4952 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5056 data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
4953 else if(S_ISCHR(mode)) 5057 else if (S_ISCHR(mode))
4954 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5058 data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
4955 else if(S_ISBLK(mode)) 5059 else if (S_ISBLK(mode))
4956 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5060 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
4957 else if(S_ISFIFO(mode)) 5061 else if (S_ISFIFO(mode))
4958 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5062 data_offset->Type = cpu_to_le32(UNIX_FIFO);
4959 else if(S_ISSOCK(mode)) 5063 else if (S_ISSOCK(mode))
4960 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5064 data_offset->Type = cpu_to_le32(UNIX_SOCKET);
4961 5065
4962 5066
@@ -4974,20 +5078,20 @@ setPermsRetry:
4974 return rc; 5078 return rc;
4975} 5079}
4976 5080
4977int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 5081int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
4978 const int notify_subdirs, const __u16 netfid, 5082 const int notify_subdirs, const __u16 netfid,
4979 __u32 filter, struct file * pfile, int multishot, 5083 __u32 filter, struct file *pfile, int multishot,
4980 const struct nls_table *nls_codepage) 5084 const struct nls_table *nls_codepage)
4981{ 5085{
4982 int rc = 0; 5086 int rc = 0;
4983 struct smb_com_transaction_change_notify_req * pSMB = NULL; 5087 struct smb_com_transaction_change_notify_req *pSMB = NULL;
4984 struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL; 5088 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
4985 struct dir_notify_req *dnotify_req; 5089 struct dir_notify_req *dnotify_req;
4986 int bytes_returned; 5090 int bytes_returned;
4987 5091
4988 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); 5092 cFYI(1, ("In CIFSSMBNotify for file handle %d", (int)netfid));
4989 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 5093 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
4990 (void **) &pSMBr); 5094 (void **) &pSMBr);
4991 if (rc) 5095 if (rc)
4992 return rc; 5096 return rc;
4993 5097
@@ -5008,7 +5112,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5008 pSMB->SetupCount = 4; /* single byte does not need le conversion */ 5112 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5009 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE); 5113 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5010 pSMB->ParameterCount = pSMB->TotalParameterCount; 5114 pSMB->ParameterCount = pSMB->TotalParameterCount;
5011 if(notify_subdirs) 5115 if (notify_subdirs)
5012 pSMB->WatchTree = 1; /* one byte - no le conversion needed */ 5116 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5013 pSMB->Reserved2 = 0; 5117 pSMB->Reserved2 = 0;
5014 pSMB->CompletionFilter = cpu_to_le32(filter); 5118 pSMB->CompletionFilter = cpu_to_le32(filter);
@@ -5021,11 +5125,11 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5021 cFYI(1, ("Error in Notify = %d", rc)); 5125 cFYI(1, ("Error in Notify = %d", rc));
5022 } else { 5126 } else {
5023 /* Add file to outstanding requests */ 5127 /* Add file to outstanding requests */
5024 /* BB change to kmem cache alloc */ 5128 /* BB change to kmem cache alloc */
5025 dnotify_req = kmalloc( 5129 dnotify_req = kmalloc(
5026 sizeof(struct dir_notify_req), 5130 sizeof(struct dir_notify_req),
5027 GFP_KERNEL); 5131 GFP_KERNEL);
5028 if(dnotify_req) { 5132 if (dnotify_req) {
5029 dnotify_req->Pid = pSMB->hdr.Pid; 5133 dnotify_req->Pid = pSMB->hdr.Pid;
5030 dnotify_req->PidHigh = pSMB->hdr.PidHigh; 5134 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5031 dnotify_req->Mid = pSMB->hdr.Mid; 5135 dnotify_req->Mid = pSMB->hdr.Mid;
@@ -5036,20 +5140,20 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5036 dnotify_req->filter = filter; 5140 dnotify_req->filter = filter;
5037 dnotify_req->multishot = multishot; 5141 dnotify_req->multishot = multishot;
5038 spin_lock(&GlobalMid_Lock); 5142 spin_lock(&GlobalMid_Lock);
5039 list_add_tail(&dnotify_req->lhead, 5143 list_add_tail(&dnotify_req->lhead,
5040 &GlobalDnotifyReqList); 5144 &GlobalDnotifyReqList);
5041 spin_unlock(&GlobalMid_Lock); 5145 spin_unlock(&GlobalMid_Lock);
5042 } else 5146 } else
5043 rc = -ENOMEM; 5147 rc = -ENOMEM;
5044 } 5148 }
5045 cifs_buf_release(pSMB); 5149 cifs_buf_release(pSMB);
5046 return rc; 5150 return rc;
5047} 5151}
5048#ifdef CONFIG_CIFS_XATTR 5152#ifdef CONFIG_CIFS_XATTR
5049ssize_t 5153ssize_t
5050CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 5154CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
5051 const unsigned char *searchName, 5155 const unsigned char *searchName,
5052 char * EAData, size_t buf_size, 5156 char *EAData, size_t buf_size,
5053 const struct nls_table *nls_codepage, int remap) 5157 const struct nls_table *nls_codepage, int remap)
5054{ 5158{
5055 /* BB assumes one setup word */ 5159 /* BB assumes one setup word */
@@ -5058,8 +5162,8 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
5058 int rc = 0; 5162 int rc = 0;
5059 int bytes_returned; 5163 int bytes_returned;
5060 int name_len; 5164 int name_len;
5061 struct fea * temp_fea; 5165 struct fea *temp_fea;
5062 char * temp_ptr; 5166 char *temp_ptr;
5063 __u16 params, byte_count; 5167 __u16 params, byte_count;
5064 5168
5065 cFYI(1, ("In Query All EAs path %s", searchName)); 5169 cFYI(1, ("In Query All EAs path %s", searchName));
@@ -5071,7 +5175,7 @@ QAllEAsRetry:
5071 5175
5072 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5176 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5073 name_len = 5177 name_len =
5074 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 5178 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
5075 PATH_MAX, nls_codepage, remap); 5179 PATH_MAX, nls_codepage, remap);
5076 name_len++; /* trailing null */ 5180 name_len++; /* trailing null */
5077 name_len *= 2; 5181 name_len *= 2;
@@ -5081,7 +5185,7 @@ QAllEAsRetry:
5081 strncpy(pSMB->FileName, searchName, name_len); 5185 strncpy(pSMB->FileName, searchName, name_len);
5082 } 5186 }
5083 5187
5084 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 5188 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5085 pSMB->TotalDataCount = 0; 5189 pSMB->TotalDataCount = 0;
5086 pSMB->MaxParameterCount = cpu_to_le16(2); 5190 pSMB->MaxParameterCount = cpu_to_le16(2);
5087 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5191 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -5091,7 +5195,7 @@ QAllEAsRetry:
5091 pSMB->Timeout = 0; 5195 pSMB->Timeout = 0;
5092 pSMB->Reserved2 = 0; 5196 pSMB->Reserved2 = 0;
5093 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5197 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5094 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 5198 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5095 pSMB->DataCount = 0; 5199 pSMB->DataCount = 0;
5096 pSMB->DataOffset = 0; 5200 pSMB->DataOffset = 0;
5097 pSMB->SetupCount = 1; 5201 pSMB->SetupCount = 1;
@@ -5115,7 +5219,7 @@ QAllEAsRetry:
5115 /* BB also check enough total bytes returned */ 5219 /* BB also check enough total bytes returned */
5116 /* BB we need to improve the validity checking 5220 /* BB we need to improve the validity checking
5117 of these trans2 responses */ 5221 of these trans2 responses */
5118 if (rc || (pSMBr->ByteCount < 4)) 5222 if (rc || (pSMBr->ByteCount < 4))
5119 rc = -EIO; /* bad smb */ 5223 rc = -EIO; /* bad smb */
5120 /* else if (pFindData){ 5224 /* else if (pFindData){
5121 memcpy((char *) pFindData, 5225 memcpy((char *) pFindData,
@@ -5128,39 +5232,40 @@ QAllEAsRetry:
5128 /* check that each element of each entry does not 5232 /* check that each element of each entry does not
5129 go beyond end of list */ 5233 go beyond end of list */
5130 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5234 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5131 struct fealist * ea_response_data; 5235 struct fealist *ea_response_data;
5132 rc = 0; 5236 rc = 0;
5133 /* validate_trans2_offsets() */ 5237 /* validate_trans2_offsets() */
5134 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/ 5238 /* BB check if start of smb + data_offset > &bcc+ bcc */
5135 ea_response_data = (struct fealist *) 5239 ea_response_data = (struct fealist *)
5136 (((char *) &pSMBr->hdr.Protocol) + 5240 (((char *) &pSMBr->hdr.Protocol) +
5137 data_offset); 5241 data_offset);
5138 name_len = le32_to_cpu(ea_response_data->list_len); 5242 name_len = le32_to_cpu(ea_response_data->list_len);
5139 cFYI(1,("ea length %d", name_len)); 5243 cFYI(1, ("ea length %d", name_len));
5140 if(name_len <= 8) { 5244 if (name_len <= 8) {
5141 /* returned EA size zeroed at top of function */ 5245 /* returned EA size zeroed at top of function */
5142 cFYI(1,("empty EA list returned from server")); 5246 cFYI(1, ("empty EA list returned from server"));
5143 } else { 5247 } else {
5144 /* account for ea list len */ 5248 /* account for ea list len */
5145 name_len -= 4; 5249 name_len -= 4;
5146 temp_fea = ea_response_data->list; 5250 temp_fea = ea_response_data->list;
5147 temp_ptr = (char *)temp_fea; 5251 temp_ptr = (char *)temp_fea;
5148 while(name_len > 0) { 5252 while (name_len > 0) {
5149 __u16 value_len; 5253 __u16 value_len;
5150 name_len -= 4; 5254 name_len -= 4;
5151 temp_ptr += 4; 5255 temp_ptr += 4;
5152 rc += temp_fea->name_len; 5256 rc += temp_fea->name_len;
5153 /* account for prefix user. and trailing null */ 5257 /* account for prefix user. and trailing null */
5154 rc = rc + 5 + 1; 5258 rc = rc + 5 + 1;
5155 if(rc<(int)buf_size) { 5259 if (rc < (int)buf_size) {
5156 memcpy(EAData,"user.",5); 5260 memcpy(EAData, "user.", 5);
5157 EAData+=5; 5261 EAData += 5;
5158 memcpy(EAData,temp_ptr,temp_fea->name_len); 5262 memcpy(EAData, temp_ptr,
5159 EAData+=temp_fea->name_len; 5263 temp_fea->name_len);
5264 EAData += temp_fea->name_len;
5160 /* null terminate name */ 5265 /* null terminate name */
5161 *EAData = 0; 5266 *EAData = 0;
5162 EAData = EAData + 1; 5267 EAData = EAData + 1;
5163 } else if(buf_size == 0) { 5268 } else if (buf_size == 0) {
5164 /* skip copy - calc size only */ 5269 /* skip copy - calc size only */
5165 } else { 5270 } else {
5166 /* stop before overrun buffer */ 5271 /* stop before overrun buffer */
@@ -5172,11 +5277,15 @@ QAllEAsRetry:
5172 /* account for trailing null */ 5277 /* account for trailing null */
5173 name_len--; 5278 name_len--;
5174 temp_ptr++; 5279 temp_ptr++;
5175 value_len = le16_to_cpu(temp_fea->value_len); 5280 value_len =
5281 le16_to_cpu(temp_fea->value_len);
5176 name_len -= value_len; 5282 name_len -= value_len;
5177 temp_ptr += value_len; 5283 temp_ptr += value_len;
5178 /* BB check that temp_ptr is still within smb BB*/ 5284 /* BB check that temp_ptr is still
5179 /* no trailing null to account for in value len */ 5285 within the SMB BB*/
5286
5287 /* no trailing null to account for
5288 in value len */
5180 /* go on to next EA */ 5289 /* go on to next EA */
5181 temp_fea = (struct fea *)temp_ptr; 5290 temp_fea = (struct fea *)temp_ptr;
5182 } 5291 }
@@ -5191,9 +5300,9 @@ QAllEAsRetry:
5191 return (ssize_t)rc; 5300 return (ssize_t)rc;
5192} 5301}
5193 5302
5194ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon, 5303ssize_t CIFSSMBQueryEA(const int xid, struct cifsTconInfo *tcon,
5195 const unsigned char * searchName,const unsigned char * ea_name, 5304 const unsigned char *searchName, const unsigned char *ea_name,
5196 unsigned char * ea_value, size_t buf_size, 5305 unsigned char *ea_value, size_t buf_size,
5197 const struct nls_table *nls_codepage, int remap) 5306 const struct nls_table *nls_codepage, int remap)
5198{ 5307{
5199 TRANSACTION2_QPI_REQ *pSMB = NULL; 5308 TRANSACTION2_QPI_REQ *pSMB = NULL;
@@ -5201,8 +5310,8 @@ ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
5201 int rc = 0; 5310 int rc = 0;
5202 int bytes_returned; 5311 int bytes_returned;
5203 int name_len; 5312 int name_len;
5204 struct fea * temp_fea; 5313 struct fea *temp_fea;
5205 char * temp_ptr; 5314 char *temp_ptr;
5206 __u16 params, byte_count; 5315 __u16 params, byte_count;
5207 5316
5208 cFYI(1, ("In Query EA path %s", searchName)); 5317 cFYI(1, ("In Query EA path %s", searchName));
@@ -5214,7 +5323,7 @@ QEARetry:
5214 5323
5215 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5324 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5216 name_len = 5325 name_len =
5217 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 5326 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
5218 PATH_MAX, nls_codepage, remap); 5327 PATH_MAX, nls_codepage, remap);
5219 name_len++; /* trailing null */ 5328 name_len++; /* trailing null */
5220 name_len *= 2; 5329 name_len *= 2;
@@ -5224,7 +5333,7 @@ QEARetry:
5224 strncpy(pSMB->FileName, searchName, name_len); 5333 strncpy(pSMB->FileName, searchName, name_len);
5225 } 5334 }
5226 5335
5227 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */ ; 5336 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
5228 pSMB->TotalDataCount = 0; 5337 pSMB->TotalDataCount = 0;
5229 pSMB->MaxParameterCount = cpu_to_le16(2); 5338 pSMB->MaxParameterCount = cpu_to_le16(2);
5230 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ 5339 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
@@ -5234,7 +5343,7 @@ QEARetry:
5234 pSMB->Timeout = 0; 5343 pSMB->Timeout = 0;
5235 pSMB->Reserved2 = 0; 5344 pSMB->Reserved2 = 0;
5236 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5345 pSMB->ParameterOffset = cpu_to_le16(offsetof(
5237 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); 5346 struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
5238 pSMB->DataCount = 0; 5347 pSMB->DataCount = 0;
5239 pSMB->DataOffset = 0; 5348 pSMB->DataOffset = 0;
5240 pSMB->SetupCount = 1; 5349 pSMB->SetupCount = 1;
@@ -5258,7 +5367,7 @@ QEARetry:
5258 /* BB also check enough total bytes returned */ 5367 /* BB also check enough total bytes returned */
5259 /* BB we need to improve the validity checking 5368 /* BB we need to improve the validity checking
5260 of these trans2 responses */ 5369 of these trans2 responses */
5261 if (rc || (pSMBr->ByteCount < 4)) 5370 if (rc || (pSMBr->ByteCount < 4))
5262 rc = -EIO; /* bad smb */ 5371 rc = -EIO; /* bad smb */
5263 /* else if (pFindData){ 5372 /* else if (pFindData){
5264 memcpy((char *) pFindData, 5373 memcpy((char *) pFindData,
@@ -5271,18 +5380,18 @@ QEARetry:
5271 /* check that each element of each entry does not 5380 /* check that each element of each entry does not
5272 go beyond end of list */ 5381 go beyond end of list */
5273 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5382 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
5274 struct fealist * ea_response_data; 5383 struct fealist *ea_response_data;
5275 rc = -ENODATA; 5384 rc = -ENODATA;
5276 /* validate_trans2_offsets() */ 5385 /* validate_trans2_offsets() */
5277 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/ 5386 /* BB check if start of smb + data_offset > &bcc+ bcc*/
5278 ea_response_data = (struct fealist *) 5387 ea_response_data = (struct fealist *)
5279 (((char *) &pSMBr->hdr.Protocol) + 5388 (((char *) &pSMBr->hdr.Protocol) +
5280 data_offset); 5389 data_offset);
5281 name_len = le32_to_cpu(ea_response_data->list_len); 5390 name_len = le32_to_cpu(ea_response_data->list_len);
5282 cFYI(1,("ea length %d", name_len)); 5391 cFYI(1, ("ea length %d", name_len));
5283 if(name_len <= 8) { 5392 if (name_len <= 8) {
5284 /* returned EA size zeroed at top of function */ 5393 /* returned EA size zeroed at top of function */
5285 cFYI(1,("empty EA list returned from server")); 5394 cFYI(1, ("empty EA list returned from server"));
5286 } else { 5395 } else {
5287 /* account for ea list len */ 5396 /* account for ea list len */
5288 name_len -= 4; 5397 name_len -= 4;
@@ -5290,28 +5399,30 @@ QEARetry:
5290 temp_ptr = (char *)temp_fea; 5399 temp_ptr = (char *)temp_fea;
5291 /* loop through checking if we have a matching 5400 /* loop through checking if we have a matching
5292 name and then return the associated value */ 5401 name and then return the associated value */
5293 while(name_len > 0) { 5402 while (name_len > 0) {
5294 __u16 value_len; 5403 __u16 value_len;
5295 name_len -= 4; 5404 name_len -= 4;
5296 temp_ptr += 4; 5405 temp_ptr += 4;
5297 value_len = le16_to_cpu(temp_fea->value_len); 5406 value_len =
5298 /* BB validate that value_len falls within SMB, 5407 le16_to_cpu(temp_fea->value_len);
5299 even though maximum for name_len is 255 */ 5408 /* BB validate that value_len falls within SMB,
5300 if(memcmp(temp_fea->name,ea_name, 5409 even though maximum for name_len is 255 */
5410 if (memcmp(temp_fea->name, ea_name,
5301 temp_fea->name_len) == 0) { 5411 temp_fea->name_len) == 0) {
5302 /* found a match */ 5412 /* found a match */
5303 rc = value_len; 5413 rc = value_len;
5304 /* account for prefix user. and trailing null */ 5414 /* account for prefix user. and trailing null */
5305 if(rc<=(int)buf_size) { 5415 if (rc <= (int)buf_size) {
5306 memcpy(ea_value, 5416 memcpy(ea_value,
5307 temp_fea->name+temp_fea->name_len+1, 5417 temp_fea->name+temp_fea->name_len+1,
5308 rc); 5418 rc);
5309 /* ea values, unlike ea names, 5419 /* ea values, unlike ea
5310 are not null terminated */ 5420 names, are not null
5311 } else if(buf_size == 0) { 5421 terminated */
5422 } else if (buf_size == 0) {
5312 /* skip copy - calc size only */ 5423 /* skip copy - calc size only */
5313 } else { 5424 } else {
5314 /* stop before overrun buffer */ 5425 /* stop before overrun buffer */
5315 rc = -ERANGE; 5426 rc = -ERANGE;
5316 } 5427 }
5317 break; 5428 break;
@@ -5323,11 +5434,11 @@ QEARetry:
5323 temp_ptr++; 5434 temp_ptr++;
5324 name_len -= value_len; 5435 name_len -= value_len;
5325 temp_ptr += value_len; 5436 temp_ptr += value_len;
5326 /* no trailing null to account for in value len */ 5437 /* No trailing null to account for in
5327 /* go on to next EA */ 5438 value_len. Go on to next EA */
5328 temp_fea = (struct fea *)temp_ptr; 5439 temp_fea = (struct fea *)temp_ptr;
5329 } 5440 }
5330 } 5441 }
5331 } 5442 }
5332 } 5443 }
5333 if (pSMB) 5444 if (pSMB)
@@ -5340,9 +5451,9 @@ QEARetry:
5340 5451
5341int 5452int
5342CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5453CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
5343 const char * ea_name, const void * ea_value, 5454 const char *ea_name, const void *ea_value,
5344 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5455 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5345 int remap) 5456 int remap)
5346{ 5457{
5347 struct smb_com_transaction2_spi_req *pSMB = NULL; 5458 struct smb_com_transaction2_spi_req *pSMB = NULL;
5348 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5459 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -5361,11 +5472,11 @@ SetEARetry:
5361 5472
5362 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5473 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
5363 name_len = 5474 name_len =
5364 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 5475 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
5365 PATH_MAX, nls_codepage, remap); 5476 PATH_MAX, nls_codepage, remap);
5366 name_len++; /* trailing null */ 5477 name_len++; /* trailing null */
5367 name_len *= 2; 5478 name_len *= 2;
5368 } else { /* BB improve the check for buffer overruns BB */ 5479 } else { /* BB improve the check for buffer overruns BB */
5369 name_len = strnlen(fileName, PATH_MAX); 5480 name_len = strnlen(fileName, PATH_MAX);
5370 name_len++; /* trailing null */ 5481 name_len++; /* trailing null */
5371 strncpy(pSMB->FileName, fileName, name_len); 5482 strncpy(pSMB->FileName, fileName, name_len);
@@ -5376,10 +5487,10 @@ SetEARetry:
5376 /* done calculating parms using name_len of file name, 5487 /* done calculating parms using name_len of file name,
5377 now use name_len to calculate length of ea name 5488 now use name_len to calculate length of ea name
5378 we are going to create in the inode xattrs */ 5489 we are going to create in the inode xattrs */
5379 if(ea_name == NULL) 5490 if (ea_name == NULL)
5380 name_len = 0; 5491 name_len = 0;
5381 else 5492 else
5382 name_len = strnlen(ea_name,255); 5493 name_len = strnlen(ea_name, 255);
5383 5494
5384 count = sizeof(*parm_data) + ea_value_len + name_len + 1; 5495 count = sizeof(*parm_data) + ea_value_len + name_len + 1;
5385 pSMB->MaxParameterCount = cpu_to_le16(2); 5496 pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -5390,7 +5501,7 @@ SetEARetry:
5390 pSMB->Timeout = 0; 5501 pSMB->Timeout = 0;
5391 pSMB->Reserved2 = 0; 5502 pSMB->Reserved2 = 0;
5392 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5503 param_offset = offsetof(struct smb_com_transaction2_spi_req,
5393 InformationLevel) - 4; 5504 InformationLevel) - 4;
5394 offset = param_offset + params; 5505 offset = param_offset + params;
5395 pSMB->InformationLevel = 5506 pSMB->InformationLevel =
5396 cpu_to_le16(SMB_SET_FILE_EA); 5507 cpu_to_le16(SMB_SET_FILE_EA);
@@ -5410,17 +5521,19 @@ SetEARetry:
5410 /* we checked above that name len is less than 255 */ 5521 /* we checked above that name len is less than 255 */
5411 parm_data->list[0].name_len = (__u8)name_len; 5522 parm_data->list[0].name_len = (__u8)name_len;
5412 /* EA names are always ASCII */ 5523 /* EA names are always ASCII */
5413 if(ea_name) 5524 if (ea_name)
5414 strncpy(parm_data->list[0].name,ea_name,name_len); 5525 strncpy(parm_data->list[0].name, ea_name, name_len);
5415 parm_data->list[0].name[name_len] = 0; 5526 parm_data->list[0].name[name_len] = 0;
5416 parm_data->list[0].value_len = cpu_to_le16(ea_value_len); 5527 parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
5417 /* caller ensures that ea_value_len is less than 64K but 5528 /* caller ensures that ea_value_len is less than 64K but
5418 we need to ensure that it fits within the smb */ 5529 we need to ensure that it fits within the smb */
5419 5530
5420 /*BB add length check that it would fit in negotiated SMB buffer size BB */ 5531 /*BB add length check to see if it would fit in
5421 /* if(ea_value_len > buffer_size - 512 (enough for header)) */ 5532 negotiated SMB buffer size BB */
5422 if(ea_value_len) 5533 /* if (ea_value_len > buffer_size - 512 (enough for header)) */
5423 memcpy(parm_data->list[0].name+name_len+1,ea_value,ea_value_len); 5534 if (ea_value_len)
5535 memcpy(parm_data->list[0].name+name_len+1,
5536 ea_value, ea_value_len);
5424 5537
5425 pSMB->TotalDataCount = pSMB->DataCount; 5538 pSMB->TotalDataCount = pSMB->DataCount;
5426 pSMB->ParameterCount = cpu_to_le16(params); 5539 pSMB->ParameterCount = cpu_to_le16(params);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0a1b8bd1dfcb..4af3588c1a96 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2006 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/net.h> 22#include <linux/net.h>
@@ -85,6 +85,7 @@ struct smb_vol {
85 unsigned direct_io:1; 85 unsigned direct_io:1;
86 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 86 unsigned remap:1; /* set to remap seven reserved chars in filenames */
87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ 87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
88 unsigned no_linux_ext:1;
88 unsigned sfu_emul:1; 89 unsigned sfu_emul:1;
89 unsigned nullauth:1; /* attempt to authenticate with null user */ 90 unsigned nullauth:1; /* attempt to authenticate with null user */
90 unsigned nocase; /* request case insensitive filenames */ 91 unsigned nocase; /* request case insensitive filenames */
@@ -93,20 +94,20 @@ struct smb_vol {
93 unsigned int wsize; 94 unsigned int wsize;
94 unsigned int sockopt; 95 unsigned int sockopt;
95 unsigned short int port; 96 unsigned short int port;
96 char * prepath; 97 char *prepath;
97}; 98};
98 99
99static int ipv4_connect(struct sockaddr_in *psin_server, 100static int ipv4_connect(struct sockaddr_in *psin_server,
100 struct socket **csocket, 101 struct socket **csocket,
101 char * netb_name, 102 char *netb_name,
102 char * server_netb_name); 103 char *server_netb_name);
103static int ipv6_connect(struct sockaddr_in6 *psin_server, 104static int ipv6_connect(struct sockaddr_in6 *psin_server,
104 struct socket **csocket); 105 struct socket **csocket);
105 106
106 107
107 /* 108 /*
108 * cifs tcp session reconnection 109 * cifs tcp session reconnection
109 * 110 *
110 * mark tcp session as reconnecting so temporarily locked 111 * mark tcp session as reconnecting so temporarily locked
111 * mark all smb sessions as reconnecting for tcp session 112 * mark all smb sessions as reconnecting for tcp session
112 * reconnect tcp session 113 * reconnect tcp session
@@ -120,11 +121,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
120 struct list_head *tmp; 121 struct list_head *tmp;
121 struct cifsSesInfo *ses; 122 struct cifsSesInfo *ses;
122 struct cifsTconInfo *tcon; 123 struct cifsTconInfo *tcon;
123 struct mid_q_entry * mid_entry; 124 struct mid_q_entry *mid_entry;
124 125
125 spin_lock(&GlobalMid_Lock); 126 spin_lock(&GlobalMid_Lock);
126 if( kthread_should_stop() ) { 127 if ( kthread_should_stop() ) {
127 /* the demux thread will exit normally 128 /* the demux thread will exit normally
128 next time through the loop */ 129 next time through the loop */
129 spin_unlock(&GlobalMid_Lock); 130 spin_unlock(&GlobalMid_Lock);
130 return rc; 131 return rc;
@@ -150,18 +151,19 @@ cifs_reconnect(struct TCP_Server_Info *server)
150 } 151 }
151 list_for_each(tmp, &GlobalTreeConnectionList) { 152 list_for_each(tmp, &GlobalTreeConnectionList) {
152 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 153 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
153 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) { 154 if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
154 tcon->tidStatus = CifsNeedReconnect; 155 tcon->tidStatus = CifsNeedReconnect;
155 } 156 }
156 } 157 }
157 read_unlock(&GlobalSMBSeslock); 158 read_unlock(&GlobalSMBSeslock);
158 /* do not want to be sending data on a socket we are freeing */ 159 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem); 160 down(&server->tcpSem);
160 if(server->ssocket) { 161 if (server->ssocket) {
161 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, 162 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags)); 163 server->ssocket->flags));
163 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN); 164 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
164 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state, 165 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
166 server->ssocket->state,
165 server->ssocket->flags)); 167 server->ssocket->flags));
166 sock_release(server->ssocket); 168 sock_release(server->ssocket);
167 server->ssocket = NULL; 169 server->ssocket = NULL;
@@ -172,8 +174,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
172 mid_entry = list_entry(tmp, struct 174 mid_entry = list_entry(tmp, struct
173 mid_q_entry, 175 mid_q_entry,
174 qhead); 176 qhead);
175 if(mid_entry) { 177 if (mid_entry) {
176 if(mid_entry->midState == MID_REQUEST_SUBMITTED) { 178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
177 /* Mark other intransit requests as needing 179 /* Mark other intransit requests as needing
178 retry so we do not immediately mark the 180 retry so we do not immediately mark the
179 session bad again (ie after we reconnect 181 session bad again (ie after we reconnect
@@ -183,29 +185,29 @@ cifs_reconnect(struct TCP_Server_Info *server)
183 } 185 }
184 } 186 }
185 spin_unlock(&GlobalMid_Lock); 187 spin_unlock(&GlobalMid_Lock);
186 up(&server->tcpSem); 188 up(&server->tcpSem);
187 189
188 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) 190 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
189 {
190 try_to_freeze(); 191 try_to_freeze();
191 if(server->protocolType == IPV6) { 192 if (server->protocolType == IPV6) {
192 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket); 193 rc = ipv6_connect(&server->addr.sockAddr6,
194 &server->ssocket);
193 } else { 195 } else {
194 rc = ipv4_connect(&server->addr.sockAddr, 196 rc = ipv4_connect(&server->addr.sockAddr,
195 &server->ssocket, 197 &server->ssocket,
196 server->workstation_RFC1001_name, 198 server->workstation_RFC1001_name,
197 server->server_RFC1001_name); 199 server->server_RFC1001_name);
198 } 200 }
199 if(rc) { 201 if (rc) {
200 cFYI(1,("reconnect error %d",rc)); 202 cFYI(1, ("reconnect error %d", rc));
201 msleep(3000); 203 msleep(3000);
202 } else { 204 } else {
203 atomic_inc(&tcpSesReconnectCount); 205 atomic_inc(&tcpSesReconnectCount);
204 spin_lock(&GlobalMid_Lock); 206 spin_lock(&GlobalMid_Lock);
205 if( !kthread_should_stop() ) 207 if ( !kthread_should_stop() )
206 server->tcpStatus = CifsGood; 208 server->tcpStatus = CifsGood;
207 server->sequence_number = 0; 209 server->sequence_number = 0;
208 spin_unlock(&GlobalMid_Lock); 210 spin_unlock(&GlobalMid_Lock);
209 /* atomic_set(&server->inFlight,0);*/ 211 /* atomic_set(&server->inFlight,0);*/
210 wake_up(&server->response_q); 212 wake_up(&server->response_q);
211 } 213 }
@@ -213,27 +215,27 @@ cifs_reconnect(struct TCP_Server_Info *server)
213 return rc; 215 return rc;
214} 216}
215 217
216/* 218/*
217 return codes: 219 return codes:
218 0 not a transact2, or all data present 220 0 not a transact2, or all data present
219 >0 transact2 with that much data missing 221 >0 transact2 with that much data missing
220 -EINVAL = invalid transact2 222 -EINVAL = invalid transact2
221 223
222 */ 224 */
223static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize) 225static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
224{ 226{
225 struct smb_t2_rsp * pSMBt; 227 struct smb_t2_rsp *pSMBt;
226 int total_data_size; 228 int total_data_size;
227 int data_in_this_rsp; 229 int data_in_this_rsp;
228 int remaining; 230 int remaining;
229 231
230 if(pSMB->Command != SMB_COM_TRANSACTION2) 232 if (pSMB->Command != SMB_COM_TRANSACTION2)
231 return 0; 233 return 0;
232 234
233 /* check for plausible wct, bcc and t2 data and parm sizes */ 235 /* check for plausible wct, bcc and t2 data and parm sizes */
234 /* check for parm and data offset going beyond end of smb */ 236 /* check for parm and data offset going beyond end of smb */
235 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ 237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
236 cFYI(1,("invalid transact2 word count")); 238 cFYI(1, ("invalid transact2 word count"));
237 return -EINVAL; 239 return -EINVAL;
238 } 240 }
239 241
@@ -244,25 +246,25 @@ static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
244 246
245 remaining = total_data_size - data_in_this_rsp; 247 remaining = total_data_size - data_in_this_rsp;
246 248
247 if(remaining == 0) 249 if (remaining == 0)
248 return 0; 250 return 0;
249 else if(remaining < 0) { 251 else if (remaining < 0) {
250 cFYI(1,("total data %d smaller than data in frame %d", 252 cFYI(1, ("total data %d smaller than data in frame %d",
251 total_data_size, data_in_this_rsp)); 253 total_data_size, data_in_this_rsp));
252 return -EINVAL; 254 return -EINVAL;
253 } else { 255 } else {
254 cFYI(1,("missing %d bytes from transact2, check next response", 256 cFYI(1, ("missing %d bytes from transact2, check next response",
255 remaining)); 257 remaining));
256 if(total_data_size > maxBufSize) { 258 if (total_data_size > maxBufSize) {
257 cERROR(1,("TotalDataSize %d is over maximum buffer %d", 259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
258 total_data_size,maxBufSize)); 260 total_data_size, maxBufSize));
259 return -EINVAL; 261 return -EINVAL;
260 } 262 }
261 return remaining; 263 return remaining;
262 } 264 }
263} 265}
264 266
265static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB) 267static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
266{ 268{
267 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond; 269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
268 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; 270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
@@ -270,43 +272,43 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
270 int total_in_buf; 272 int total_in_buf;
271 int remaining; 273 int remaining;
272 int total_in_buf2; 274 int total_in_buf2;
273 char * data_area_of_target; 275 char *data_area_of_target;
274 char * data_area_of_buf2; 276 char *data_area_of_buf2;
275 __u16 byte_count; 277 __u16 byte_count;
276 278
277 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount); 279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
278 280
279 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) { 281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
280 cFYI(1,("total data sizes of primary and secondary t2 differ")); 282 cFYI(1, ("total data size of primary and secondary t2 differ"));
281 } 283 }
282 284
283 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount); 285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
284 286
285 remaining = total_data_size - total_in_buf; 287 remaining = total_data_size - total_in_buf;
286 288
287 if(remaining < 0) 289 if (remaining < 0)
288 return -EINVAL; 290 return -EINVAL;
289 291
290 if(remaining == 0) /* nothing to do, ignore */ 292 if (remaining == 0) /* nothing to do, ignore */
291 return 0; 293 return 0;
292 294
293 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount); 295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
294 if(remaining < total_in_buf2) { 296 if (remaining < total_in_buf2) {
295 cFYI(1,("transact2 2nd response contains too much data")); 297 cFYI(1, ("transact2 2nd response contains too much data"));
296 } 298 }
297 299
298 /* find end of first SMB data area */ 300 /* find end of first SMB data area */
299 data_area_of_target = (char *)&pSMBt->hdr.Protocol + 301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
300 le16_to_cpu(pSMBt->t2_rsp.DataOffset); 302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
301 /* validate target area */ 303 /* validate target area */
302 304
303 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol + 305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
304 le16_to_cpu(pSMB2->t2_rsp.DataOffset); 306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
305 307
306 data_area_of_target += total_in_buf; 308 data_area_of_target += total_in_buf;
307 309
308 /* copy second buffer into end of first buffer */ 310 /* copy second buffer into end of first buffer */
309 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2); 311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
310 total_in_buf += total_in_buf2; 312 total_in_buf += total_in_buf2;
311 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf); 313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
312 byte_count = le16_to_cpu(BCC_LE(pTargetSMB)); 314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
@@ -317,11 +319,11 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
317 byte_count += total_in_buf2; 319 byte_count += total_in_buf2;
318 320
319 /* BB also add check that we are not beyond maximum buffer size */ 321 /* BB also add check that we are not beyond maximum buffer size */
320 322
321 pTargetSMB->smb_buf_length = byte_count; 323 pTargetSMB->smb_buf_length = byte_count;
322 324
323 if(remaining == total_in_buf2) { 325 if (remaining == total_in_buf2) {
324 cFYI(1,("found the last secondary response")); 326 cFYI(1, ("found the last secondary response"));
325 return 0; /* we are done */ 327 return 0; /* we are done */
326 } else /* more responses to go */ 328 } else /* more responses to go */
327 return 1; 329 return 1;
@@ -348,16 +350,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
348 int isMultiRsp; 350 int isMultiRsp;
349 int reconnect; 351 int reconnect;
350 352
351 allow_signal(SIGKILL);
352 current->flags |= PF_MEMALLOC; 353 current->flags |= PF_MEMALLOC;
353 server->tsk = current; /* save process info to wake at shutdown */ 354 server->tsk = current; /* save process info to wake at shutdown */
354 cFYI(1, ("Demultiplex PID: %d", current->pid)); 355 cFYI(1, ("Demultiplex PID: %d", current->pid));
355 write_lock(&GlobalSMBSeslock); 356 write_lock(&GlobalSMBSeslock);
356 atomic_inc(&tcpSesAllocCount); 357 atomic_inc(&tcpSesAllocCount);
357 length = tcpSesAllocCount.counter; 358 length = tcpSesAllocCount.counter;
358 write_unlock(&GlobalSMBSeslock); 359 write_unlock(&GlobalSMBSeslock);
359 complete(&cifsd_complete); 360 complete(&cifsd_complete);
360 if(length > 1) { 361 if (length > 1) {
361 mempool_resize(cifs_req_poolp, 362 mempool_resize(cifs_req_poolp,
362 length + cifs_min_rcv, 363 length + cifs_min_rcv,
363 GFP_KERNEL); 364 GFP_KERNEL);
@@ -426,10 +427,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
426 break; 427 break;
427 } 428 }
428 if (!try_to_freeze() && (length == -EINTR)) { 429 if (!try_to_freeze() && (length == -EINTR)) {
429 cFYI(1,("cifsd thread killed")); 430 cFYI(1, ("cifsd thread killed"));
430 break; 431 break;
431 } 432 }
432 cFYI(1,("Reconnect after unexpected peek error %d", 433 cFYI(1, ("Reconnect after unexpected peek error %d",
433 length)); 434 length));
434 cifs_reconnect(server); 435 cifs_reconnect(server);
435 csocket = server->ssocket; 436 csocket = server->ssocket;
@@ -453,26 +454,26 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
453 with the most common, zero, as regular data */ 454 with the most common, zero, as regular data */
454 temp = *((char *) smb_buffer); 455 temp = *((char *) smb_buffer);
455 456
456 /* Note that FC 1001 length is big endian on the wire, 457 /* Note that FC 1001 length is big endian on the wire,
457 but we convert it here so it is always manipulated 458 but we convert it here so it is always manipulated
458 as host byte order */ 459 as host byte order */
459 pdu_length = ntohl(smb_buffer->smb_buf_length); 460 pdu_length = ntohl(smb_buffer->smb_buf_length);
460 smb_buffer->smb_buf_length = pdu_length; 461 smb_buffer->smb_buf_length = pdu_length;
461 462
462 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4)); 463 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
463 464
464 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { 465 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
465 continue; 466 continue;
466 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 467 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
467 cFYI(1,("Good RFC 1002 session rsp")); 468 cFYI(1, ("Good RFC 1002 session rsp"));
468 continue; 469 continue;
469 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 470 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
470 /* we get this from Windows 98 instead of 471 /* we get this from Windows 98 instead of
471 an error on SMB negprot response */ 472 an error on SMB negprot response */
472 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", 473 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
473 pdu_length)); 474 pdu_length));
474 if(server->tcpStatus == CifsNew) { 475 if (server->tcpStatus == CifsNew) {
475 /* if nack on negprot (rather than 476 /* if nack on negprot (rather than
476 ret of smb negprot error) reconnecting 477 ret of smb negprot error) reconnecting
477 not going to help, ret error to mount */ 478 not going to help, ret error to mount */
478 break; 479 break;
@@ -482,10 +483,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
482 msleep(1000); 483 msleep(1000);
483 /* always try 445 first on reconnect 484 /* always try 445 first on reconnect
484 since we get NACK on some if we ever 485 since we get NACK on some if we ever
485 connected to port 139 (the NACK is 486 connected to port 139 (the NACK is
486 since we do not begin with RFC1001 487 since we do not begin with RFC1001
487 session initialize frame) */ 488 session initialize frame) */
488 server->addr.sockAddr.sin_port = 489 server->addr.sockAddr.sin_port =
489 htons(CIFS_PORT); 490 htons(CIFS_PORT);
490 cifs_reconnect(server); 491 cifs_reconnect(server);
491 csocket = server->ssocket; 492 csocket = server->ssocket;
@@ -493,7 +494,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
493 continue; 494 continue;
494 } 495 }
495 } else if (temp != (char) 0) { 496 } else if (temp != (char) 0) {
496 cERROR(1,("Unknown RFC 1002 frame")); 497 cERROR(1, ("Unknown RFC 1002 frame"));
497 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 498 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
498 length); 499 length);
499 cifs_reconnect(server); 500 cifs_reconnect(server);
@@ -502,7 +503,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
502 } 503 }
503 504
504 /* else we have an SMB response */ 505 /* else we have an SMB response */
505 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || 506 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
506 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { 507 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
507 cERROR(1, ("Invalid size SMB length %d pdu_length %d", 508 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
508 length, pdu_length+4)); 509 length, pdu_length+4));
@@ -510,12 +511,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
510 csocket = server->ssocket; 511 csocket = server->ssocket;
511 wake_up(&server->response_q); 512 wake_up(&server->response_q);
512 continue; 513 continue;
513 } 514 }
514 515
515 /* else length ok */ 516 /* else length ok */
516 reconnect = 0; 517 reconnect = 0;
517 518
518 if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { 519 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
519 isLargeBuf = TRUE; 520 isLargeBuf = TRUE;
520 memcpy(bigbuf, smallbuf, 4); 521 memcpy(bigbuf, smallbuf, 4);
521 smb_buffer = bigbuf; 522 smb_buffer = bigbuf;
@@ -523,11 +524,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
523 length = 0; 524 length = 0;
524 iov.iov_base = 4 + (char *)smb_buffer; 525 iov.iov_base = 4 + (char *)smb_buffer;
525 iov.iov_len = pdu_length; 526 iov.iov_len = pdu_length;
526 for (total_read = 0; total_read < pdu_length; 527 for (total_read = 0; total_read < pdu_length;
527 total_read += length) { 528 total_read += length) {
528 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, 529 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
529 pdu_length - total_read, 0); 530 pdu_length - total_read, 0);
530 if( kthread_should_stop() || 531 if ( kthread_should_stop() ||
531 (length == -EINTR)) { 532 (length == -EINTR)) {
532 /* then will exit */ 533 /* then will exit */
533 reconnect = 2; 534 reconnect = 2;
@@ -535,19 +536,19 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
535 } else if (server->tcpStatus == CifsNeedReconnect) { 536 } else if (server->tcpStatus == CifsNeedReconnect) {
536 cifs_reconnect(server); 537 cifs_reconnect(server);
537 csocket = server->ssocket; 538 csocket = server->ssocket;
538 /* Reconnect wakes up rspns q */ 539 /* Reconnect wakes up rspns q */
539 /* Now we will reread sock */ 540 /* Now we will reread sock */
540 reconnect = 1; 541 reconnect = 1;
541 break; 542 break;
542 } else if ((length == -ERESTARTSYS) || 543 } else if ((length == -ERESTARTSYS) ||
543 (length == -EAGAIN)) { 544 (length == -EAGAIN)) {
544 msleep(1); /* minimum sleep to prevent looping, 545 msleep(1); /* minimum sleep to prevent looping,
545 allowing socket to clear and app 546 allowing socket to clear and app
546 threads to set tcpStatus 547 threads to set tcpStatus
547 CifsNeedReconnect if server hung*/ 548 CifsNeedReconnect if server hung*/
548 continue; 549 continue;
549 } else if (length <= 0) { 550 } else if (length <= 0) {
550 cERROR(1,("Received no data, expecting %d", 551 cERROR(1, ("Received no data, expecting %d",
551 pdu_length - total_read)); 552 pdu_length - total_read));
552 cifs_reconnect(server); 553 cifs_reconnect(server);
553 csocket = server->ssocket; 554 csocket = server->ssocket;
@@ -555,13 +556,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
555 break; 556 break;
556 } 557 }
557 } 558 }
558 if(reconnect == 2) 559 if (reconnect == 2)
559 break; 560 break;
560 else if(reconnect == 1) 561 else if (reconnect == 1)
561 continue; 562 continue;
562 563
563 length += 4; /* account for rfc1002 hdr */ 564 length += 4; /* account for rfc1002 hdr */
564 565
565 566
566 dump_smb(smb_buffer, length); 567 dump_smb(smb_buffer, length);
567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { 568 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
@@ -575,28 +576,28 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
575 list_for_each(tmp, &server->pending_mid_q) { 576 list_for_each(tmp, &server->pending_mid_q) {
576 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 577 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
577 578
578 if ((mid_entry->mid == smb_buffer->Mid) && 579 if ((mid_entry->mid == smb_buffer->Mid) &&
579 (mid_entry->midState == MID_REQUEST_SUBMITTED) && 580 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
580 (mid_entry->command == smb_buffer->Command)) { 581 (mid_entry->command == smb_buffer->Command)) {
581 if(check2ndT2(smb_buffer,server->maxBuf) > 0) { 582 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
582 /* We have a multipart transact2 resp */ 583 /* We have a multipart transact2 resp */
583 isMultiRsp = TRUE; 584 isMultiRsp = TRUE;
584 if(mid_entry->resp_buf) { 585 if (mid_entry->resp_buf) {
585 /* merge response - fix up 1st*/ 586 /* merge response - fix up 1st*/
586 if(coalesce_t2(smb_buffer, 587 if (coalesce_t2(smb_buffer,
587 mid_entry->resp_buf)) { 588 mid_entry->resp_buf)) {
588 mid_entry->multiRsp = 1; 589 mid_entry->multiRsp = 1;
589 break; 590 break;
590 } else { 591 } else {
591 /* all parts received */ 592 /* all parts received */
592 mid_entry->multiEnd = 1; 593 mid_entry->multiEnd = 1;
593 goto multi_t2_fnd; 594 goto multi_t2_fnd;
594 } 595 }
595 } else { 596 } else {
596 if(!isLargeBuf) { 597 if (!isLargeBuf) {
597 cERROR(1,("1st trans2 resp needs bigbuf")); 598 cERROR(1,("1st trans2 resp needs bigbuf"));
598 /* BB maybe we can fix this up, switch 599 /* BB maybe we can fix this up, switch
599 to already allocated large buffer? */ 600 to already allocated large buffer? */
600 } else { 601 } else {
601 /* Have first buffer */ 602 /* Have first buffer */
602 mid_entry->resp_buf = 603 mid_entry->resp_buf =
@@ -606,9 +607,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
606 } 607 }
607 } 608 }
608 break; 609 break;
609 } 610 }
610 mid_entry->resp_buf = smb_buffer; 611 mid_entry->resp_buf = smb_buffer;
611 if(isLargeBuf) 612 if (isLargeBuf)
612 mid_entry->largeBuf = 1; 613 mid_entry->largeBuf = 1;
613 else 614 else
614 mid_entry->largeBuf = 0; 615 mid_entry->largeBuf = 0;
@@ -628,24 +629,25 @@ multi_t2_fnd:
628 spin_unlock(&GlobalMid_Lock); 629 spin_unlock(&GlobalMid_Lock);
629 if (task_to_wake) { 630 if (task_to_wake) {
630 /* Was previous buf put in mpx struct for multi-rsp? */ 631 /* Was previous buf put in mpx struct for multi-rsp? */
631 if(!isMultiRsp) { 632 if (!isMultiRsp) {
632 /* smb buffer will be freed by user thread */ 633 /* smb buffer will be freed by user thread */
633 if(isLargeBuf) { 634 if (isLargeBuf) {
634 bigbuf = NULL; 635 bigbuf = NULL;
635 } else 636 } else
636 smallbuf = NULL; 637 smallbuf = NULL;
637 } 638 }
638 wake_up_process(task_to_wake); 639 wake_up_process(task_to_wake);
639 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) 640 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
640 && (isMultiRsp == FALSE)) { 641 && (isMultiRsp == FALSE)) {
641 cERROR(1, ("No task to wake, unknown frame rcvd! NumMids %d", midCount.counter)); 642 cERROR(1, ("No task to wake, unknown frame received! "
642 cifs_dump_mem("Received Data is: ",(char *)smb_buffer, 643 "NumMids %d", midCount.counter));
644 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
643 sizeof(struct smb_hdr)); 645 sizeof(struct smb_hdr));
644#ifdef CONFIG_CIFS_DEBUG2 646#ifdef CONFIG_CIFS_DEBUG2
645 cifs_dump_detail(smb_buffer); 647 cifs_dump_detail(smb_buffer);
646 cifs_dump_mids(server); 648 cifs_dump_mids(server);
647#endif /* CIFS_DEBUG2 */ 649#endif /* CIFS_DEBUG2 */
648 650
649 } 651 }
650 } /* end while !EXITING */ 652 } /* end while !EXITING */
651 653
@@ -655,12 +657,12 @@ multi_t2_fnd:
655 /* check if we have blocked requests that need to free */ 657 /* check if we have blocked requests that need to free */
656 /* Note that cifs_max_pending is normally 50, but 658 /* Note that cifs_max_pending is normally 50, but
657 can be set at module install time to as little as two */ 659 can be set at module install time to as little as two */
658 if(atomic_read(&server->inFlight) >= cifs_max_pending) 660 if (atomic_read(&server->inFlight) >= cifs_max_pending)
659 atomic_set(&server->inFlight, cifs_max_pending - 1); 661 atomic_set(&server->inFlight, cifs_max_pending - 1);
660 /* We do not want to set the max_pending too low or we 662 /* We do not want to set the max_pending too low or we
661 could end up with the counter going negative */ 663 could end up with the counter going negative */
662 spin_unlock(&GlobalMid_Lock); 664 spin_unlock(&GlobalMid_Lock);
663 /* Although there should not be any requests blocked on 665 /* Although there should not be any requests blocked on
664 this queue it can not hurt to be paranoid and try to wake up requests 666 this queue it can not hurt to be paranoid and try to wake up requests
665 that may haven been blocked when more than 50 at time were on the wire 667 that may haven been blocked when more than 50 at time were on the wire
666 to the same server - they now will see the session is in exit state 668 to the same server - they now will see the session is in exit state
@@ -668,8 +670,8 @@ multi_t2_fnd:
668 wake_up_all(&server->request_q); 670 wake_up_all(&server->request_q);
669 /* give those requests time to exit */ 671 /* give those requests time to exit */
670 msleep(125); 672 msleep(125);
671 673
672 if(server->ssocket) { 674 if (server->ssocket) {
673 sock_release(csocket); 675 sock_release(csocket);
674 server->ssocket = NULL; 676 server->ssocket = NULL;
675 } 677 }
@@ -709,10 +711,10 @@ multi_t2_fnd:
709 list_for_each(tmp, &server->pending_mid_q) { 711 list_for_each(tmp, &server->pending_mid_q) {
710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 712 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
711 if (mid_entry->midState == MID_REQUEST_SUBMITTED) { 713 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
712 cFYI(1, 714 cFYI(1, ("Clearing Mid 0x%x - waking up ",
713 ("Clearing Mid 0x%x - waking up ",mid_entry->mid)); 715 mid_entry->mid));
714 task_to_wake = mid_entry->tsk; 716 task_to_wake = mid_entry->tsk;
715 if(task_to_wake) { 717 if (task_to_wake) {
716 wake_up_process(task_to_wake); 718 wake_up_process(task_to_wake);
717 } 719 }
718 } 720 }
@@ -724,7 +726,7 @@ multi_t2_fnd:
724 } 726 }
725 727
726 if (!list_empty(&server->pending_mid_q)) { 728 if (!list_empty(&server->pending_mid_q)) {
727 /* mpx threads have not exited yet give them 729 /* mpx threads have not exited yet give them
728 at least the smb send timeout time for long ops */ 730 at least the smb send timeout time for long ops */
729 /* due to delays on oplock break requests, we need 731 /* due to delays on oplock break requests, we need
730 to wait at least 45 seconds before giving up 732 to wait at least 45 seconds before giving up
@@ -742,7 +744,7 @@ multi_t2_fnd:
742 744
743 /* last chance to mark ses pointers invalid 745 /* last chance to mark ses pointers invalid
744 if there are any pointing to this (e.g 746 if there are any pointing to this (e.g
745 if a crazy root user tried to kill cifsd 747 if a crazy root user tried to kill cifsd
746 kernel thread explicitly this might happen) */ 748 kernel thread explicitly this might happen) */
747 list_for_each(tmp, &GlobalSMBSessionList) { 749 list_for_each(tmp, &GlobalSMBSessionList) {
748 ses = list_entry(tmp, struct cifsSesInfo, 750 ses = list_entry(tmp, struct cifsSesInfo,
@@ -754,17 +756,18 @@ multi_t2_fnd:
754 write_unlock(&GlobalSMBSeslock); 756 write_unlock(&GlobalSMBSeslock);
755 757
756 kfree(server); 758 kfree(server);
757 if(length > 0) { 759 if (length > 0) {
758 mempool_resize(cifs_req_poolp, 760 mempool_resize(cifs_req_poolp,
759 length + cifs_min_rcv, 761 length + cifs_min_rcv,
760 GFP_KERNEL); 762 GFP_KERNEL);
761 } 763 }
762 764
763 return 0; 765 return 0;
764} 766}
765 767
766static int 768static int
767cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) 769cifs_parse_mount_options(char *options, const char *devname,
770 struct smb_vol *vol)
768{ 771{
769 char *value; 772 char *value;
770 char *data; 773 char *data;
@@ -772,15 +775,15 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
772 char separator[2]; 775 char separator[2];
773 776
774 separator[0] = ','; 777 separator[0] = ',';
775 separator[1] = 0; 778 separator[1] = 0;
776 779
777 if (Local_System_Name[0] != 0) 780 if (Local_System_Name[0] != 0)
778 memcpy(vol->source_rfc1001_name, Local_System_Name,15); 781 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
779 else { 782 else {
780 char *nodename = utsname()->nodename; 783 char *nodename = utsname()->nodename;
781 int n = strnlen(nodename,15); 784 int n = strnlen(nodename, 15);
782 memset(vol->source_rfc1001_name,0x20,15); 785 memset(vol->source_rfc1001_name, 0x20, 15);
783 for(i=0 ; i < n ; i++) { 786 for (i = 0; i < n; i++) {
784 /* does not have to be perfect mapping since field is 787 /* does not have to be perfect mapping since field is
785 informational, only used for servers that do not support 788 informational, only used for servers that do not support
786 port 445 and it can be overridden at mount time */ 789 port 445 and it can be overridden at mount time */
@@ -805,31 +808,32 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
805 if (!options) 808 if (!options)
806 return 1; 809 return 1;
807 810
808 if(strncmp(options,"sep=",4) == 0) { 811 if (strncmp(options, "sep=", 4) == 0) {
809 if(options[4] != 0) { 812 if (options[4] != 0) {
810 separator[0] = options[4]; 813 separator[0] = options[4];
811 options += 5; 814 options += 5;
812 } else { 815 } else {
813 cFYI(1,("Null separator not allowed")); 816 cFYI(1, ("Null separator not allowed"));
814 } 817 }
815 } 818 }
816 819
817 while ((data = strsep(&options, separator)) != NULL) { 820 while ((data = strsep(&options, separator)) != NULL) {
818 if (!*data) 821 if (!*data)
819 continue; 822 continue;
820 if ((value = strchr(data, '=')) != NULL) 823 if ((value = strchr(data, '=')) != NULL)
821 *value++ = '\0'; 824 *value++ = '\0';
822 825
823 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/ 826 /* Have to parse this before we parse for "user" */
827 if (strnicmp(data, "user_xattr", 10) == 0) {
824 vol->no_xattr = 0; 828 vol->no_xattr = 0;
825 } else if (strnicmp(data, "nouser_xattr",12) == 0) { 829 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
826 vol->no_xattr = 1; 830 vol->no_xattr = 1;
827 } else if (strnicmp(data, "user", 4) == 0) { 831 } else if (strnicmp(data, "user", 4) == 0) {
828 if (!value) { 832 if (!value) {
829 printk(KERN_WARNING 833 printk(KERN_WARNING
830 "CIFS: invalid or missing username\n"); 834 "CIFS: invalid or missing username\n");
831 return 1; /* needs_arg; */ 835 return 1; /* needs_arg; */
832 } else if(!*value) { 836 } else if (!*value) {
833 /* null user, ie anonymous, authentication */ 837 /* null user, ie anonymous, authentication */
834 vol->nullauth = 1; 838 vol->nullauth = 1;
835 } 839 }
@@ -843,12 +847,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
843 if (!value) { 847 if (!value) {
844 vol->password = NULL; 848 vol->password = NULL;
845 continue; 849 continue;
846 } else if(value[0] == 0) { 850 } else if (value[0] == 0) {
847 /* check if string begins with double comma 851 /* check if string begins with double comma
848 since that would mean the password really 852 since that would mean the password really
849 does start with a comma, and would not 853 does start with a comma, and would not
850 indicate an empty string */ 854 indicate an empty string */
851 if(value[1] != separator[0]) { 855 if (value[1] != separator[0]) {
852 vol->password = NULL; 856 vol->password = NULL;
853 continue; 857 continue;
854 } 858 }
@@ -857,7 +861,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
857 /* removed password length check, NTLM passwords 861 /* removed password length check, NTLM passwords
858 can be arbitrarily long */ 862 can be arbitrarily long */
859 863
860 /* if comma in password, the string will be 864 /* if comma in password, the string will be
861 prematurely null terminated. Commas in password are 865 prematurely null terminated. Commas in password are
862 specified across the cifs mount interface by a double 866 specified across the cifs mount interface by a double
863 comma ie ,, and a comma used as in other cases ie ',' 867 comma ie ,, and a comma used as in other cases ie ','
@@ -867,18 +871,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
867 /* NB: password legally can have multiple commas and 871 /* NB: password legally can have multiple commas and
868 the only illegal character in a password is null */ 872 the only illegal character in a password is null */
869 873
870 if ((value[temp_len] == 0) && 874 if ((value[temp_len] == 0) &&
871 (value[temp_len+1] == separator[0])) { 875 (value[temp_len+1] == separator[0])) {
872 /* reinsert comma */ 876 /* reinsert comma */
873 value[temp_len] = separator[0]; 877 value[temp_len] = separator[0];
874 temp_len+=2; /* move after the second comma */ 878 temp_len += 2; /* move after second comma */
875 while(value[temp_len] != 0) { 879 while (value[temp_len] != 0) {
876 if (value[temp_len] == separator[0]) { 880 if (value[temp_len] == separator[0]) {
877 if (value[temp_len+1] == 881 if (value[temp_len+1] ==
878 separator[0]) { 882 separator[0]) {
879 /* skip second comma */ 883 /* skip second comma */
880 temp_len++; 884 temp_len++;
881 } else { 885 } else {
882 /* single comma indicating start 886 /* single comma indicating start
883 of next parm */ 887 of next parm */
884 break; 888 break;
@@ -886,24 +890,25 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
886 } 890 }
887 temp_len++; 891 temp_len++;
888 } 892 }
889 if(value[temp_len] == 0) { 893 if (value[temp_len] == 0) {
890 options = NULL; 894 options = NULL;
891 } else { 895 } else {
892 value[temp_len] = 0; 896 value[temp_len] = 0;
893 /* point option to start of next parm */ 897 /* point option to start of next parm */
894 options = value + temp_len + 1; 898 options = value + temp_len + 1;
895 } 899 }
896 /* go from value to value + temp_len condensing 900 /* go from value to value + temp_len condensing
897 double commas to singles. Note that this ends up 901 double commas to singles. Note that this ends up
898 allocating a few bytes too many, which is ok */ 902 allocating a few bytes too many, which is ok */
899 vol->password = kzalloc(temp_len, GFP_KERNEL); 903 vol->password = kzalloc(temp_len, GFP_KERNEL);
900 if(vol->password == NULL) { 904 if (vol->password == NULL) {
901 printk("CIFS: no memory for pass\n"); 905 printk(KERN_WARNING "CIFS: no memory "
906 "for password\n");
902 return 1; 907 return 1;
903 } 908 }
904 for(i=0,j=0;i<temp_len;i++,j++) { 909 for (i = 0, j = 0; i < temp_len; i++, j++) {
905 vol->password[j] = value[i]; 910 vol->password[j] = value[i];
906 if(value[i] == separator[0] 911 if (value[i] == separator[0]
907 && value[i+1] == separator[0]) { 912 && value[i+1] == separator[0]) {
908 /* skip second comma */ 913 /* skip second comma */
909 i++; 914 i++;
@@ -912,8 +917,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
912 vol->password[j] = 0; 917 vol->password[j] = 0;
913 } else { 918 } else {
914 vol->password = kzalloc(temp_len+1, GFP_KERNEL); 919 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
915 if(vol->password == NULL) { 920 if (vol->password == NULL) {
916 printk("CIFS: no memory for pass\n"); 921 printk(KERN_WARNING "CIFS: no memory "
922 "for password\n");
917 return 1; 923 return 1;
918 } 924 }
919 strcpy(vol->password, value); 925 strcpy(vol->password, value);
@@ -924,20 +930,21 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
924 } else if (strnlen(value, 35) < 35) { 930 } else if (strnlen(value, 35) < 35) {
925 vol->UNCip = value; 931 vol->UNCip = value;
926 } else { 932 } else {
927 printk(KERN_WARNING "CIFS: ip address too long\n"); 933 printk(KERN_WARNING "CIFS: ip address "
934 "too long\n");
928 return 1; 935 return 1;
929 } 936 }
930 } else if (strnicmp(data, "sec", 3) == 0) { 937 } else if (strnicmp(data, "sec", 3) == 0) {
931 if (!value || !*value) { 938 if (!value || !*value) {
932 cERROR(1,("no security value specified")); 939 cERROR(1, ("no security value specified"));
933 continue; 940 continue;
934 } else if (strnicmp(value, "krb5i", 5) == 0) { 941 } else if (strnicmp(value, "krb5i", 5) == 0) {
935 vol->secFlg |= CIFSSEC_MAY_KRB5 | 942 vol->secFlg |= CIFSSEC_MAY_KRB5 |
936 CIFSSEC_MUST_SIGN; 943 CIFSSEC_MUST_SIGN;
937 } else if (strnicmp(value, "krb5p", 5) == 0) { 944 } else if (strnicmp(value, "krb5p", 5) == 0) {
938 /* vol->secFlg |= CIFSSEC_MUST_SEAL | 945 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
939 CIFSSEC_MAY_KRB5; */ 946 CIFSSEC_MAY_KRB5; */
940 cERROR(1,("Krb5 cifs privacy not supported")); 947 cERROR(1, ("Krb5 cifs privacy not supported"));
941 return 1; 948 return 1;
942 } else if (strnicmp(value, "krb5", 4) == 0) { 949 } else if (strnicmp(value, "krb5", 4) == 0) {
943 vol->secFlg |= CIFSSEC_MAY_KRB5; 950 vol->secFlg |= CIFSSEC_MAY_KRB5;
@@ -957,33 +964,34 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
957 vol->secFlg |= CIFSSEC_MAY_NTLMV2; 964 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
958#ifdef CONFIG_CIFS_WEAK_PW_HASH 965#ifdef CONFIG_CIFS_WEAK_PW_HASH
959 } else if (strnicmp(value, "lanman", 6) == 0) { 966 } else if (strnicmp(value, "lanman", 6) == 0) {
960 vol->secFlg |= CIFSSEC_MAY_LANMAN; 967 vol->secFlg |= CIFSSEC_MAY_LANMAN;
961#endif 968#endif
962 } else if (strnicmp(value, "none", 4) == 0) { 969 } else if (strnicmp(value, "none", 4) == 0) {
963 vol->nullauth = 1; 970 vol->nullauth = 1;
964 } else { 971 } else {
965 cERROR(1,("bad security option: %s", value)); 972 cERROR(1, ("bad security option: %s", value));
966 return 1; 973 return 1;
967 } 974 }
968 } else if ((strnicmp(data, "unc", 3) == 0) 975 } else if ((strnicmp(data, "unc", 3) == 0)
969 || (strnicmp(data, "target", 6) == 0) 976 || (strnicmp(data, "target", 6) == 0)
970 || (strnicmp(data, "path", 4) == 0)) { 977 || (strnicmp(data, "path", 4) == 0)) {
971 if (!value || !*value) { 978 if (!value || !*value) {
972 printk(KERN_WARNING 979 printk(KERN_WARNING "CIFS: invalid path to "
973 "CIFS: invalid path to network resource\n"); 980 "network resource\n");
974 return 1; /* needs_arg; */ 981 return 1; /* needs_arg; */
975 } 982 }
976 if ((temp_len = strnlen(value, 300)) < 300) { 983 if ((temp_len = strnlen(value, 300)) < 300) {
977 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 984 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
978 if (vol->UNC == NULL) 985 if (vol->UNC == NULL)
979 return 1; 986 return 1;
980 strcpy(vol->UNC,value); 987 strcpy(vol->UNC, value);
981 if (strncmp(vol->UNC, "//", 2) == 0) { 988 if (strncmp(vol->UNC, "//", 2) == 0) {
982 vol->UNC[0] = '\\'; 989 vol->UNC[0] = '\\';
983 vol->UNC[1] = '\\'; 990 vol->UNC[1] = '\\';
984 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 991 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
985 printk(KERN_WARNING 992 printk(KERN_WARNING
986 "CIFS: UNC Path does not begin with // or \\\\ \n"); 993 "CIFS: UNC Path does not begin "
994 "with // or \\\\ \n");
987 return 1; 995 return 1;
988 } 996 }
989 } else { 997 } else {
@@ -1002,43 +1010,47 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1002 vol->domainname = value; 1010 vol->domainname = value;
1003 cFYI(1, ("Domain name set")); 1011 cFYI(1, ("Domain name set"));
1004 } else { 1012 } else {
1005 printk(KERN_WARNING "CIFS: domain name too long\n"); 1013 printk(KERN_WARNING "CIFS: domain name too "
1014 "long\n");
1006 return 1; 1015 return 1;
1007 } 1016 }
1008 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1017 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1009 if (!value || !*value) { 1018 if (!value || !*value) {
1010 printk(KERN_WARNING 1019 printk(KERN_WARNING
1011 "CIFS: invalid path prefix\n"); 1020 "CIFS: invalid path prefix\n");
1012 return 1; /* needs_arg; */ 1021 return 1; /* needs_argument */
1013 } 1022 }
1014 if ((temp_len = strnlen(value, 1024)) < 1024) { 1023 if ((temp_len = strnlen(value, 1024)) < 1024) {
1015 if (value[0] != '/') 1024 if (value[0] != '/')
1016 temp_len++; /* missing leading slash */ 1025 temp_len++; /* missing leading slash */
1017 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); 1026 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1018 if (vol->prepath == NULL) 1027 if (vol->prepath == NULL)
1019 return 1; 1028 return 1;
1020 if (value[0] != '/') { 1029 if (value[0] != '/') {
1021 vol->prepath[0] = '/'; 1030 vol->prepath[0] = '/';
1022 strcpy(vol->prepath+1,value); 1031 strcpy(vol->prepath+1, value);
1023 } else 1032 } else
1024 strcpy(vol->prepath,value); 1033 strcpy(vol->prepath, value);
1025 cFYI(1,("prefix path %s",vol->prepath)); 1034 cFYI(1, ("prefix path %s", vol->prepath));
1026 } else { 1035 } else {
1027 printk(KERN_WARNING "CIFS: prefix too long\n"); 1036 printk(KERN_WARNING "CIFS: prefix too long\n");
1028 return 1; 1037 return 1;
1029 } 1038 }
1030 } else if (strnicmp(data, "iocharset", 9) == 0) { 1039 } else if (strnicmp(data, "iocharset", 9) == 0) {
1031 if (!value || !*value) { 1040 if (!value || !*value) {
1032 printk(KERN_WARNING "CIFS: invalid iocharset specified\n"); 1041 printk(KERN_WARNING "CIFS: invalid iocharset "
1042 "specified\n");
1033 return 1; /* needs_arg; */ 1043 return 1; /* needs_arg; */
1034 } 1044 }
1035 if (strnlen(value, 65) < 65) { 1045 if (strnlen(value, 65) < 65) {
1036 if (strnicmp(value,"default",7)) 1046 if (strnicmp(value, "default", 7))
1037 vol->iocharset = value; 1047 vol->iocharset = value;
1038 /* if iocharset not set load_nls_default used by caller */ 1048 /* if iocharset not set then load_nls_default
1039 cFYI(1, ("iocharset set to %s",value)); 1049 is used by caller */
1050 cFYI(1, ("iocharset set to %s", value));
1040 } else { 1051 } else {
1041 printk(KERN_WARNING "CIFS: iocharset name too long.\n"); 1052 printk(KERN_WARNING "CIFS: iocharset name "
1053 "too long.\n");
1042 return 1; 1054 return 1;
1043 } 1055 }
1044 } else if (strnicmp(data, "uid", 3) == 0) { 1056 } else if (strnicmp(data, "uid", 3) == 0) {
@@ -1090,54 +1102,59 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1090 } 1102 }
1091 } else if (strnicmp(data, "netbiosname", 4) == 0) { 1103 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1092 if (!value || !*value || (*value == ' ')) { 1104 if (!value || !*value || (*value == ' ')) {
1093 cFYI(1,("invalid (empty) netbiosname specified")); 1105 cFYI(1, ("invalid (empty) netbiosname"));
1094 } else { 1106 } else {
1095 memset(vol->source_rfc1001_name,0x20,15); 1107 memset(vol->source_rfc1001_name, 0x20, 15);
1096 for(i=0;i<15;i++) { 1108 for (i = 0; i < 15; i++) {
1097 /* BB are there cases in which a comma can be 1109 /* BB are there cases in which a comma can be
1098 valid in this workstation netbios name (and need 1110 valid in this workstation netbios name (and need
1099 special handling)? */ 1111 special handling)? */
1100 1112
1101 /* We do not uppercase netbiosname for user */ 1113 /* We do not uppercase netbiosname for user */
1102 if (value[i]==0) 1114 if (value[i] == 0)
1103 break; 1115 break;
1104 else 1116 else
1105 vol->source_rfc1001_name[i] = value[i]; 1117 vol->source_rfc1001_name[i] =
1118 value[i];
1106 } 1119 }
1107 /* The string has 16th byte zero still from 1120 /* The string has 16th byte zero still from
1108 set at top of the function */ 1121 set at top of the function */
1109 if ((i==15) && (value[i] != 0)) 1122 if ((i == 15) && (value[i] != 0))
1110 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); 1123 printk(KERN_WARNING "CIFS: netbiosname"
1124 " longer than 15 truncated.\n");
1111 } 1125 }
1112 } else if (strnicmp(data, "servern", 7) == 0) { 1126 } else if (strnicmp(data, "servern", 7) == 0) {
1113 /* servernetbiosname specified override *SMBSERVER */ 1127 /* servernetbiosname specified override *SMBSERVER */
1114 if (!value || !*value || (*value == ' ')) { 1128 if (!value || !*value || (*value == ' ')) {
1115 cFYI(1,("empty server netbiosname specified")); 1129 cFYI(1, ("empty server netbiosname specified"));
1116 } else { 1130 } else {
1117 /* last byte, type, is 0x20 for servr type */ 1131 /* last byte, type, is 0x20 for servr type */
1118 memset(vol->target_rfc1001_name,0x20,16); 1132 memset(vol->target_rfc1001_name, 0x20, 16);
1119 1133
1120 for(i=0;i<15;i++) { 1134 for (i = 0; i < 15; i++) {
1121 /* BB are there cases in which a comma can be 1135 /* BB are there cases in which a comma can be
1122 valid in this workstation netbios name (and need 1136 valid in this workstation netbios name
1123 special handling)? */ 1137 (and need special handling)? */
1124 1138
1125 /* user or mount helper must uppercase netbiosname */ 1139 /* user or mount helper must uppercase
1126 if (value[i]==0) 1140 the netbiosname */
1141 if (value[i] == 0)
1127 break; 1142 break;
1128 else 1143 else
1129 vol->target_rfc1001_name[i] = value[i]; 1144 vol->target_rfc1001_name[i] =
1145 value[i];
1130 } 1146 }
1131 /* The string has 16th byte zero still from 1147 /* The string has 16th byte zero still from
1132 set at top of the function */ 1148 set at top of the function */
1133 if ((i==15) && (value[i] != 0)) 1149 if ((i == 15) && (value[i] != 0))
1134 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); 1150 printk(KERN_WARNING "CIFS: server net"
1151 "biosname longer than 15 truncated.\n");
1135 } 1152 }
1136 } else if (strnicmp(data, "credentials", 4) == 0) { 1153 } else if (strnicmp(data, "credentials", 4) == 0) {
1137 /* ignore */ 1154 /* ignore */
1138 } else if (strnicmp(data, "version", 3) == 0) { 1155 } else if (strnicmp(data, "version", 3) == 0) {
1139 /* ignore */ 1156 /* ignore */
1140 } else if (strnicmp(data, "guest",5) == 0) { 1157 } else if (strnicmp(data, "guest", 5) == 0) {
1141 /* ignore */ 1158 /* ignore */
1142 } else if (strnicmp(data, "rw", 2) == 0) { 1159 } else if (strnicmp(data, "rw", 2) == 0) {
1143 vol->rw = TRUE; 1160 vol->rw = TRUE;
@@ -1149,11 +1166,11 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1149 (strnicmp(data, "noauto", 6) == 0) || 1166 (strnicmp(data, "noauto", 6) == 0) ||
1150 (strnicmp(data, "dev", 3) == 0)) { 1167 (strnicmp(data, "dev", 3) == 0)) {
1151 /* The mount tool or mount.cifs helper (if present) 1168 /* The mount tool or mount.cifs helper (if present)
1152 uses these opts to set flags, and the flags are read 1169 uses these opts to set flags, and the flags are read
1153 by the kernel vfs layer before we get here (ie 1170 by the kernel vfs layer before we get here (ie
1154 before read super) so there is no point trying to 1171 before read super) so there is no point trying to
1155 parse these options again and set anything and it 1172 parse these options again and set anything and it
1156 is ok to just ignore them */ 1173 is ok to just ignore them */
1157 continue; 1174 continue;
1158 } else if (strnicmp(data, "ro", 2) == 0) { 1175 } else if (strnicmp(data, "ro", 2) == 0) {
1159 vol->rw = FALSE; 1176 vol->rw = FALSE;
@@ -1169,26 +1186,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1169 vol->remap = 1; 1186 vol->remap = 1;
1170 } else if (strnicmp(data, "nomapchars", 10) == 0) { 1187 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1171 vol->remap = 0; 1188 vol->remap = 0;
1172 } else if (strnicmp(data, "sfu", 3) == 0) { 1189 } else if (strnicmp(data, "sfu", 3) == 0) {
1173 vol->sfu_emul = 1; 1190 vol->sfu_emul = 1;
1174 } else if (strnicmp(data, "nosfu", 5) == 0) { 1191 } else if (strnicmp(data, "nosfu", 5) == 0) {
1175 vol->sfu_emul = 0; 1192 vol->sfu_emul = 0;
1176 } else if (strnicmp(data, "posixpaths", 10) == 0) { 1193 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1177 vol->posix_paths = 1; 1194 vol->posix_paths = 1;
1178 } else if (strnicmp(data, "noposixpaths", 12) == 0) { 1195 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1179 vol->posix_paths = 0; 1196 vol->posix_paths = 0;
1180 } else if ((strnicmp(data, "nocase", 6) == 0) || 1197 } else if (strnicmp(data, "nounix", 6) == 0) {
1198 vol->no_linux_ext = 1;
1199 } else if (strnicmp(data, "nolinux", 7) == 0) {
1200 vol->no_linux_ext = 1;
1201 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1181 (strnicmp(data, "ignorecase", 10) == 0)) { 1202 (strnicmp(data, "ignorecase", 10) == 0)) {
1182 vol->nocase = 1; 1203 vol->nocase = 1;
1183 } else if (strnicmp(data, "brl", 3) == 0) { 1204 } else if (strnicmp(data, "brl", 3) == 0) {
1184 vol->nobrl = 0; 1205 vol->nobrl = 0;
1185 } else if ((strnicmp(data, "nobrl", 5) == 0) || 1206 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1186 (strnicmp(data, "nolock", 6) == 0)) { 1207 (strnicmp(data, "nolock", 6) == 0)) {
1187 vol->nobrl = 1; 1208 vol->nobrl = 1;
1188 /* turn off mandatory locking in mode 1209 /* turn off mandatory locking in mode
1189 if remote locking is turned off since the 1210 if remote locking is turned off since the
1190 local vfs will do advisory */ 1211 local vfs will do advisory */
1191 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP))) 1212 if (vol->file_mode ==
1213 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1192 vol->file_mode = S_IALLUGO; 1214 vol->file_mode = S_IALLUGO;
1193 } else if (strnicmp(data, "setuids", 7) == 0) { 1215 } else if (strnicmp(data, "setuids", 7) == 0) {
1194 vol->setuids = 1; 1216 vol->setuids = 1;
@@ -1202,55 +1224,61 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1202 vol->intr = 0; 1224 vol->intr = 0;
1203 } else if (strnicmp(data, "intr", 4) == 0) { 1225 } else if (strnicmp(data, "intr", 4) == 0) {
1204 vol->intr = 1; 1226 vol->intr = 1;
1205 } else if (strnicmp(data, "serverino",7) == 0) { 1227 } else if (strnicmp(data, "serverino", 7) == 0) {
1206 vol->server_ino = 1; 1228 vol->server_ino = 1;
1207 } else if (strnicmp(data, "noserverino",9) == 0) { 1229 } else if (strnicmp(data, "noserverino", 9) == 0) {
1208 vol->server_ino = 0; 1230 vol->server_ino = 0;
1209 } else if (strnicmp(data, "cifsacl",7) == 0) { 1231 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1210 vol->cifs_acl = 1; 1232 vol->cifs_acl = 1;
1211 } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1233 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1212 vol->cifs_acl = 0; 1234 vol->cifs_acl = 0;
1213 } else if (strnicmp(data, "acl",3) == 0) { 1235 } else if (strnicmp(data, "acl", 3) == 0) {
1214 vol->no_psx_acl = 0; 1236 vol->no_psx_acl = 0;
1215 } else if (strnicmp(data, "noacl",5) == 0) { 1237 } else if (strnicmp(data, "noacl", 5) == 0) {
1216 vol->no_psx_acl = 1; 1238 vol->no_psx_acl = 1;
1217 } else if (strnicmp(data, "sign",4) == 0) { 1239 } else if (strnicmp(data, "sign", 4) == 0) {
1218 vol->secFlg |= CIFSSEC_MUST_SIGN; 1240 vol->secFlg |= CIFSSEC_MUST_SIGN;
1219/* } else if (strnicmp(data, "seal",4) == 0) { 1241/* } else if (strnicmp(data, "seal",4) == 0) {
1220 vol->secFlg |= CIFSSEC_MUST_SEAL; */ 1242 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1221 } else if (strnicmp(data, "direct",6) == 0) { 1243 } else if (strnicmp(data, "direct", 6) == 0) {
1222 vol->direct_io = 1; 1244 vol->direct_io = 1;
1223 } else if (strnicmp(data, "forcedirectio",13) == 0) { 1245 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1224 vol->direct_io = 1; 1246 vol->direct_io = 1;
1225 } else if (strnicmp(data, "in6_addr",8) == 0) { 1247 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1226 if (!value || !*value) { 1248 if (!value || !*value) {
1227 vol->in6_addr = NULL; 1249 vol->in6_addr = NULL;
1228 } else if (strnlen(value, 49) == 48) { 1250 } else if (strnlen(value, 49) == 48) {
1229 vol->in6_addr = value; 1251 vol->in6_addr = value;
1230 } else { 1252 } else {
1231 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n"); 1253 printk(KERN_WARNING "CIFS: ip v6 address not "
1254 "48 characters long\n");
1232 return 1; 1255 return 1;
1233 } 1256 }
1234 } else if (strnicmp(data, "noac", 4) == 0) { 1257 } else if (strnicmp(data, "noac", 4) == 0) {
1235 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); 1258 printk(KERN_WARNING "CIFS: Mount option noac not "
1259 "supported. Instead set "
1260 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1236 } else 1261 } else
1237 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); 1262 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1263 data);
1238 } 1264 }
1239 if (vol->UNC == NULL) { 1265 if (vol->UNC == NULL) {
1240 if (devname == NULL) { 1266 if (devname == NULL) {
1241 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); 1267 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1268 "target\n");
1242 return 1; 1269 return 1;
1243 } 1270 }
1244 if ((temp_len = strnlen(devname, 300)) < 300) { 1271 if ((temp_len = strnlen(devname, 300)) < 300) {
1245 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 1272 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1246 if (vol->UNC == NULL) 1273 if (vol->UNC == NULL)
1247 return 1; 1274 return 1;
1248 strcpy(vol->UNC,devname); 1275 strcpy(vol->UNC, devname);
1249 if (strncmp(vol->UNC, "//", 2) == 0) { 1276 if (strncmp(vol->UNC, "//", 2) == 0) {
1250 vol->UNC[0] = '\\'; 1277 vol->UNC[0] = '\\';
1251 vol->UNC[1] = '\\'; 1278 vol->UNC[1] = '\\';
1252 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { 1279 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1253 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n"); 1280 printk(KERN_WARNING "CIFS: UNC Path does not "
1281 "begin with // or \\\\ \n");
1254 return 1; 1282 return 1;
1255 } 1283 }
1256 } else { 1284 } else {
@@ -1258,14 +1286,14 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1258 return 1; 1286 return 1;
1259 } 1287 }
1260 } 1288 }
1261 if(vol->UNCip == NULL) 1289 if (vol->UNCip == NULL)
1262 vol->UNCip = &vol->UNC[2]; 1290 vol->UNCip = &vol->UNC[2];
1263 1291
1264 return 0; 1292 return 0;
1265} 1293}
1266 1294
1267static struct cifsSesInfo * 1295static struct cifsSesInfo *
1268cifs_find_tcp_session(struct in_addr * target_ip_addr, 1296cifs_find_tcp_session(struct in_addr *target_ip_addr,
1269 struct in6_addr *target_ip6_addr, 1297 struct in6_addr *target_ip6_addr,
1270 char *userName, struct TCP_Server_Info **psrvTcp) 1298 char *userName, struct TCP_Server_Info **psrvTcp)
1271{ 1299{
@@ -1277,19 +1305,25 @@ cifs_find_tcp_session(struct in_addr * target_ip_addr,
1277 list_for_each(tmp, &GlobalSMBSessionList) { 1305 list_for_each(tmp, &GlobalSMBSessionList) {
1278 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); 1306 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1279 if (ses->server) { 1307 if (ses->server) {
1280 if((target_ip_addr && 1308 if ((target_ip_addr &&
1281 (ses->server->addr.sockAddr.sin_addr.s_addr 1309 (ses->server->addr.sockAddr.sin_addr.s_addr
1282 == target_ip_addr->s_addr)) || (target_ip6_addr 1310 == target_ip_addr->s_addr)) || (target_ip6_addr
1283 && memcmp(&ses->server->addr.sockAddr6.sin6_addr, 1311 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1284 target_ip6_addr,sizeof(*target_ip6_addr)))){ 1312 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1285 /* BB lock server and tcp session and increment use count here?? */ 1313 /* BB lock server and tcp session and increment
1286 *psrvTcp = ses->server; /* found a match on the TCP session */ 1314 use count here?? */
1315
1316 /* found a match on the TCP session */
1317 *psrvTcp = ses->server;
1318
1287 /* BB check if reconnection needed */ 1319 /* BB check if reconnection needed */
1288 if (strncmp 1320 if (strncmp
1289 (ses->userName, userName, 1321 (ses->userName, userName,
1290 MAX_USERNAME_SIZE) == 0){ 1322 MAX_USERNAME_SIZE) == 0){
1291 read_unlock(&GlobalSMBSeslock); 1323 read_unlock(&GlobalSMBSeslock);
1292 return ses; /* found exact match on both tcp and SMB sessions */ 1324 /* Found exact match on both TCP and
1325 SMB sessions */
1326 return ses;
1293 } 1327 }
1294 } 1328 }
1295 } 1329 }
@@ -1320,7 +1354,8 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1320 /* BB lock tcon, server and tcp session and increment use count here? */ 1354 /* BB lock tcon, server and tcp session and increment use count here? */
1321 /* found a match on the TCP session */ 1355 /* found a match on the TCP session */
1322 /* BB check if reconnection needed */ 1356 /* BB check if reconnection needed */
1323 cFYI(1,("IP match, old UNC: %s new: %s", 1357 cFYI(1,
1358 ("IP match, old UNC: %s new: %s",
1324 tcon->treeName, uncName)); 1359 tcon->treeName, uncName));
1325 if (strncmp 1360 if (strncmp
1326 (tcon->treeName, uncName, 1361 (tcon->treeName, uncName,
@@ -1355,11 +1390,11 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1355 unsigned int num_referrals; 1390 unsigned int num_referrals;
1356 int rc = 0; 1391 int rc = 0;
1357 1392
1358 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 1393 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1359 &num_referrals, &referrals, remap); 1394 &num_referrals, &referrals, remap);
1360 1395
1361 /* BB Add in code to: if valid refrl, if not ip address contact 1396 /* BB Add in code to: if valid refrl, if not ip address contact
1362 the helper that resolves tcp names, mount to it, try to 1397 the helper that resolves tcp names, mount to it, try to
1363 tcon to it unmount it if fail */ 1398 tcon to it unmount it if fail */
1364 1399
1365 kfree(referrals); 1400 kfree(referrals);
@@ -1368,10 +1403,9 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1368} 1403}
1369 1404
1370int 1405int
1371get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 1406get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1372 const char *old_path, const struct nls_table *nls_codepage, 1407 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1373 unsigned int *pnum_referrals, 1408 unsigned char **preferrals, int remap)
1374 unsigned char ** preferrals, int remap)
1375{ 1409{
1376 char *temp_unc; 1410 char *temp_unc;
1377 int rc = 0; 1411 int rc = 0;
@@ -1380,7 +1414,8 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1380 1414
1381 if (pSesInfo->ipc_tid == 0) { 1415 if (pSesInfo->ipc_tid == 0) {
1382 temp_unc = kmalloc(2 /* for slashes */ + 1416 temp_unc = kmalloc(2 /* for slashes */ +
1383 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2) 1417 strnlen(pSesInfo->serverName,
1418 SERVER_NAME_LEN_WITH_NULL * 2)
1384 + 1 + 4 /* slash IPC$ */ + 2, 1419 + 1 + 4 /* slash IPC$ */ + 2,
1385 GFP_KERNEL); 1420 GFP_KERNEL);
1386 if (temp_unc == NULL) 1421 if (temp_unc == NULL)
@@ -1391,7 +1426,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1391 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$"); 1426 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1392 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); 1427 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1393 cFYI(1, 1428 cFYI(1,
1394 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid)); 1429 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1395 kfree(temp_unc); 1430 kfree(temp_unc);
1396 } 1431 }
1397 if (rc == 0) 1432 if (rc == 0)
@@ -1402,62 +1437,63 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1402} 1437}
1403 1438
1404/* See RFC1001 section 14 on representation of Netbios names */ 1439/* See RFC1001 section 14 on representation of Netbios names */
1405static void rfc1002mangle(char * target,char * source, unsigned int length) 1440static void rfc1002mangle(char *target, char *source, unsigned int length)
1406{ 1441{
1407 unsigned int i,j; 1442 unsigned int i, j;
1408 1443
1409 for(i=0,j=0;i<(length);i++) { 1444 for (i = 0, j = 0; i < (length); i++) {
1410 /* mask a nibble at a time and encode */ 1445 /* mask a nibble at a time and encode */
1411 target[j] = 'A' + (0x0F & (source[i] >> 4)); 1446 target[j] = 'A' + (0x0F & (source[i] >> 4));
1412 target[j+1] = 'A' + (0x0F & source[i]); 1447 target[j+1] = 'A' + (0x0F & source[i]);
1413 j+=2; 1448 j += 2;
1414 } 1449 }
1415 1450
1416} 1451}
1417 1452
1418 1453
1419static int 1454static int
1420ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1455ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1421 char * netbios_name, char * target_name) 1456 char *netbios_name, char *target_name)
1422{ 1457{
1423 int rc = 0; 1458 int rc = 0;
1424 int connected = 0; 1459 int connected = 0;
1425 __be16 orig_port = 0; 1460 __be16 orig_port = 0;
1426 1461
1427 if(*csocket == NULL) { 1462 if (*csocket == NULL) {
1428 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); 1463 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1464 IPPROTO_TCP, csocket);
1429 if (rc < 0) { 1465 if (rc < 0) {
1430 cERROR(1, ("Error %d creating socket",rc)); 1466 cERROR(1, ("Error %d creating socket", rc));
1431 *csocket = NULL; 1467 *csocket = NULL;
1432 return rc; 1468 return rc;
1433 } else { 1469 } else {
1434 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1470 /* BB other socket options to set KEEPALIVE, NODELAY? */
1435 cFYI(1,("Socket created")); 1471 cFYI(1, ("Socket created"));
1436 (*csocket)->sk->sk_allocation = GFP_NOFS; 1472 (*csocket)->sk->sk_allocation = GFP_NOFS;
1437 } 1473 }
1438 } 1474 }
1439 1475
1440 psin_server->sin_family = AF_INET; 1476 psin_server->sin_family = AF_INET;
1441 if(psin_server->sin_port) { /* user overrode default port */ 1477 if (psin_server->sin_port) { /* user overrode default port */
1442 rc = (*csocket)->ops->connect(*csocket, 1478 rc = (*csocket)->ops->connect(*csocket,
1443 (struct sockaddr *) psin_server, 1479 (struct sockaddr *) psin_server,
1444 sizeof (struct sockaddr_in),0); 1480 sizeof (struct sockaddr_in), 0);
1445 if (rc >= 0) 1481 if (rc >= 0)
1446 connected = 1; 1482 connected = 1;
1447 } 1483 }
1448 1484
1449 if(!connected) { 1485 if (!connected) {
1450 /* save original port so we can retry user specified port 1486 /* save original port so we can retry user specified port
1451 later if fall back ports fail this time */ 1487 later if fall back ports fail this time */
1452 orig_port = psin_server->sin_port; 1488 orig_port = psin_server->sin_port;
1453 1489
1454 /* do not retry on the same port we just failed on */ 1490 /* do not retry on the same port we just failed on */
1455 if(psin_server->sin_port != htons(CIFS_PORT)) { 1491 if (psin_server->sin_port != htons(CIFS_PORT)) {
1456 psin_server->sin_port = htons(CIFS_PORT); 1492 psin_server->sin_port = htons(CIFS_PORT);
1457 1493
1458 rc = (*csocket)->ops->connect(*csocket, 1494 rc = (*csocket)->ops->connect(*csocket,
1459 (struct sockaddr *) psin_server, 1495 (struct sockaddr *) psin_server,
1460 sizeof (struct sockaddr_in),0); 1496 sizeof (struct sockaddr_in), 0);
1461 if (rc >= 0) 1497 if (rc >= 0)
1462 connected = 1; 1498 connected = 1;
1463 } 1499 }
@@ -1465,60 +1501,63 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1465 if (!connected) { 1501 if (!connected) {
1466 psin_server->sin_port = htons(RFC1001_PORT); 1502 psin_server->sin_port = htons(RFC1001_PORT);
1467 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1503 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1468 psin_server, sizeof (struct sockaddr_in),0); 1504 psin_server,
1469 if (rc >= 0) 1505 sizeof (struct sockaddr_in), 0);
1506 if (rc >= 0)
1470 connected = 1; 1507 connected = 1;
1471 } 1508 }
1472 1509
1473 /* give up here - unless we want to retry on different 1510 /* give up here - unless we want to retry on different
1474 protocol families some day */ 1511 protocol families some day */
1475 if (!connected) { 1512 if (!connected) {
1476 if(orig_port) 1513 if (orig_port)
1477 psin_server->sin_port = orig_port; 1514 psin_server->sin_port = orig_port;
1478 cFYI(1,("Error %d connecting to server via ipv4",rc)); 1515 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1479 sock_release(*csocket); 1516 sock_release(*csocket);
1480 *csocket = NULL; 1517 *csocket = NULL;
1481 return rc; 1518 return rc;
1482 } 1519 }
1483 /* Eventually check for other socket options to change from 1520 /* Eventually check for other socket options to change from
1484 the default. sock_setsockopt not used because it expects 1521 the default. sock_setsockopt not used because it expects
1485 user space buffer */ 1522 user space buffer */
1486 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf, 1523 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1524 (*csocket)->sk->sk_sndbuf,
1487 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); 1525 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1488 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1526 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1489 /* make the bufsizes depend on wsize/rsize and max requests */ 1527 /* make the bufsizes depend on wsize/rsize and max requests */
1490 if((*csocket)->sk->sk_sndbuf < (200 * 1024)) 1528 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1491 (*csocket)->sk->sk_sndbuf = 200 * 1024; 1529 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1492 if((*csocket)->sk->sk_rcvbuf < (140 * 1024)) 1530 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1493 (*csocket)->sk->sk_rcvbuf = 140 * 1024; 1531 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1494 1532
1495 /* send RFC1001 sessinit */ 1533 /* send RFC1001 sessinit */
1496 if(psin_server->sin_port == htons(RFC1001_PORT)) { 1534 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1497 /* some servers require RFC1001 sessinit before sending 1535 /* some servers require RFC1001 sessinit before sending
1498 negprot - BB check reconnection in case where second 1536 negprot - BB check reconnection in case where second
1499 sessinit is sent but no second negprot */ 1537 sessinit is sent but no second negprot */
1500 struct rfc1002_session_packet * ses_init_buf; 1538 struct rfc1002_session_packet *ses_init_buf;
1501 struct smb_hdr * smb_buf; 1539 struct smb_hdr *smb_buf;
1502 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); 1540 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1503 if(ses_init_buf) { 1541 GFP_KERNEL);
1542 if (ses_init_buf) {
1504 ses_init_buf->trailer.session_req.called_len = 32; 1543 ses_init_buf->trailer.session_req.called_len = 32;
1505 if(target_name && (target_name[0] != 0)) { 1544 if (target_name && (target_name[0] != 0)) {
1506 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1545 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1507 target_name, 16); 1546 target_name, 16);
1508 } else { 1547 } else {
1509 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1548 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1510 DEFAULT_CIFS_CALLED_NAME,16); 1549 DEFAULT_CIFS_CALLED_NAME, 16);
1511 } 1550 }
1512 1551
1513 ses_init_buf->trailer.session_req.calling_len = 32; 1552 ses_init_buf->trailer.session_req.calling_len = 32;
1514 /* calling name ends in null (byte 16) from old smb 1553 /* calling name ends in null (byte 16) from old smb
1515 convention. */ 1554 convention. */
1516 if(netbios_name && (netbios_name[0] !=0)) { 1555 if (netbios_name && (netbios_name[0] != 0)) {
1517 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1556 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1518 netbios_name,16); 1557 netbios_name, 16);
1519 } else { 1558 } else {
1520 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1559 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1521 "LINUX_CIFS_CLNT",16); 1560 "LINUX_CIFS_CLNT", 16);
1522 } 1561 }
1523 ses_init_buf->trailer.session_req.scope1 = 0; 1562 ses_init_buf->trailer.session_req.scope1 = 0;
1524 ses_init_buf->trailer.session_req.scope2 = 0; 1563 ses_init_buf->trailer.session_req.scope2 = 0;
@@ -1528,20 +1567,20 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1528 rc = smb_send(*csocket, smb_buf, 0x44, 1567 rc = smb_send(*csocket, smb_buf, 0x44,
1529 (struct sockaddr *)psin_server); 1568 (struct sockaddr *)psin_server);
1530 kfree(ses_init_buf); 1569 kfree(ses_init_buf);
1531 msleep(1); /* RFC1001 layer in at least one server 1570 msleep(1); /* RFC1001 layer in at least one server
1532 requires very short break before negprot 1571 requires very short break before negprot
1533 presumably because not expecting negprot 1572 presumably because not expecting negprot
1534 to follow so fast. This is a simple 1573 to follow so fast. This is a simple
1535 solution that works without 1574 solution that works without
1536 complicating the code and causes no 1575 complicating the code and causes no
1537 significant slowing down on mount 1576 significant slowing down on mount
1538 for everyone else */ 1577 for everyone else */
1539 } 1578 }
1540 /* else the negprot may still work without this 1579 /* else the negprot may still work without this
1541 even though malloc failed */ 1580 even though malloc failed */
1542 1581
1543 } 1582 }
1544 1583
1545 return rc; 1584 return rc;
1546} 1585}
1547 1586
@@ -1552,41 +1591,42 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1552 int connected = 0; 1591 int connected = 0;
1553 __be16 orig_port = 0; 1592 __be16 orig_port = 0;
1554 1593
1555 if(*csocket == NULL) { 1594 if (*csocket == NULL) {
1556 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket); 1595 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1596 IPPROTO_TCP, csocket);
1557 if (rc < 0) { 1597 if (rc < 0) {
1558 cERROR(1, ("Error %d creating ipv6 socket",rc)); 1598 cERROR(1, ("Error %d creating ipv6 socket", rc));
1559 *csocket = NULL; 1599 *csocket = NULL;
1560 return rc; 1600 return rc;
1561 } else { 1601 } else {
1562 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1602 /* BB other socket options to set KEEPALIVE, NODELAY? */
1563 cFYI(1,("ipv6 Socket created")); 1603 cFYI(1, ("ipv6 Socket created"));
1564 (*csocket)->sk->sk_allocation = GFP_NOFS; 1604 (*csocket)->sk->sk_allocation = GFP_NOFS;
1565 } 1605 }
1566 } 1606 }
1567 1607
1568 psin_server->sin6_family = AF_INET6; 1608 psin_server->sin6_family = AF_INET6;
1569 1609
1570 if(psin_server->sin6_port) { /* user overrode default port */ 1610 if (psin_server->sin6_port) { /* user overrode default port */
1571 rc = (*csocket)->ops->connect(*csocket, 1611 rc = (*csocket)->ops->connect(*csocket,
1572 (struct sockaddr *) psin_server, 1612 (struct sockaddr *) psin_server,
1573 sizeof (struct sockaddr_in6),0); 1613 sizeof (struct sockaddr_in6), 0);
1574 if (rc >= 0) 1614 if (rc >= 0)
1575 connected = 1; 1615 connected = 1;
1576 } 1616 }
1577 1617
1578 if(!connected) { 1618 if (!connected) {
1579 /* save original port so we can retry user specified port 1619 /* save original port so we can retry user specified port
1580 later if fall back ports fail this time */ 1620 later if fall back ports fail this time */
1581 1621
1582 orig_port = psin_server->sin6_port; 1622 orig_port = psin_server->sin6_port;
1583 /* do not retry on the same port we just failed on */ 1623 /* do not retry on the same port we just failed on */
1584 if(psin_server->sin6_port != htons(CIFS_PORT)) { 1624 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1585 psin_server->sin6_port = htons(CIFS_PORT); 1625 psin_server->sin6_port = htons(CIFS_PORT);
1586 1626
1587 rc = (*csocket)->ops->connect(*csocket, 1627 rc = (*csocket)->ops->connect(*csocket,
1588 (struct sockaddr *) psin_server, 1628 (struct sockaddr *) psin_server,
1589 sizeof (struct sockaddr_in6),0); 1629 sizeof (struct sockaddr_in6), 0);
1590 if (rc >= 0) 1630 if (rc >= 0)
1591 connected = 1; 1631 connected = 1;
1592 } 1632 }
@@ -1594,31 +1634,31 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1594 if (!connected) { 1634 if (!connected) {
1595 psin_server->sin6_port = htons(RFC1001_PORT); 1635 psin_server->sin6_port = htons(RFC1001_PORT);
1596 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1636 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1597 psin_server, sizeof (struct sockaddr_in6),0); 1637 psin_server, sizeof (struct sockaddr_in6), 0);
1598 if (rc >= 0) 1638 if (rc >= 0)
1599 connected = 1; 1639 connected = 1;
1600 } 1640 }
1601 1641
1602 /* give up here - unless we want to retry on different 1642 /* give up here - unless we want to retry on different
1603 protocol families some day */ 1643 protocol families some day */
1604 if (!connected) { 1644 if (!connected) {
1605 if(orig_port) 1645 if (orig_port)
1606 psin_server->sin6_port = orig_port; 1646 psin_server->sin6_port = orig_port;
1607 cFYI(1,("Error %d connecting to server via ipv6",rc)); 1647 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1608 sock_release(*csocket); 1648 sock_release(*csocket);
1609 *csocket = NULL; 1649 *csocket = NULL;
1610 return rc; 1650 return rc;
1611 } 1651 }
1612 /* Eventually check for other socket options to change from 1652 /* Eventually check for other socket options to change from
1613 the default. sock_setsockopt not used because it expects 1653 the default. sock_setsockopt not used because it expects
1614 user space buffer */ 1654 user space buffer */
1615 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1655 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1616 1656
1617 return rc; 1657 return rc;
1618} 1658}
1619 1659
1620void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon, 1660void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1621 struct super_block * sb, struct smb_vol * vol_info) 1661 struct super_block *sb, struct smb_vol *vol_info)
1622{ 1662{
1623 /* if we are reconnecting then should we check to see if 1663 /* if we are reconnecting then should we check to see if
1624 * any requested capabilities changed locally e.g. via 1664 * any requested capabilities changed locally e.g. via
@@ -1630,65 +1670,87 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon,
1630 * What if we wanted to mount the server share twice once with 1670 * What if we wanted to mount the server share twice once with
1631 * and once without posixacls or posix paths? */ 1671 * and once without posixacls or posix paths? */
1632 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1672 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1633 1673
1634 1674 if (vol_info && vol_info->no_linux_ext) {
1635 if(!CIFSSMBQFSUnixInfo(xid, tcon)) { 1675 tcon->fsUnixInfo.Capability = 0;
1676 tcon->unix_ext = 0; /* Unix Extensions disabled */
1677 cFYI(1, ("Linux protocol extensions disabled"));
1678 return;
1679 } else if (vol_info)
1680 tcon->unix_ext = 1; /* Unix Extensions supported */
1681
1682 if (tcon->unix_ext == 0) {
1683 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1684 return;
1685 }
1686
1687 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1636 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 1688 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1637 1689
1638 /* check for reconnect case in which we do not 1690 /* check for reconnect case in which we do not
1639 want to change the mount behavior if we can avoid it */ 1691 want to change the mount behavior if we can avoid it */
1640 if(vol_info == NULL) { 1692 if (vol_info == NULL) {
1641 /* turn off POSIX ACL and PATHNAMES if not set 1693 /* turn off POSIX ACL and PATHNAMES if not set
1642 originally at mount time */ 1694 originally at mount time */
1643 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) 1695 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1644 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1696 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1645 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) 1697 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1646 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1698 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1647
1648
1649
1650
1651 } 1699 }
1652 1700
1653 cap &= CIFS_UNIX_CAP_MASK; 1701 cap &= CIFS_UNIX_CAP_MASK;
1654 if(vol_info && vol_info->no_psx_acl) 1702 if (vol_info && vol_info->no_psx_acl)
1655 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 1703 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1656 else if(CIFS_UNIX_POSIX_ACL_CAP & cap) { 1704 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1657 cFYI(1,("negotiated posix acl support")); 1705 cFYI(1, ("negotiated posix acl support"));
1658 if(sb) 1706 if (sb)
1659 sb->s_flags |= MS_POSIXACL; 1707 sb->s_flags |= MS_POSIXACL;
1660 } 1708 }
1661 1709
1662 if(vol_info && vol_info->posix_paths == 0) 1710 if (vol_info && vol_info->posix_paths == 0)
1663 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 1711 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1664 else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 1712 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1665 cFYI(1,("negotiate posix pathnames")); 1713 cFYI(1, ("negotiate posix pathnames"));
1666 if(sb) 1714 if (sb)
1667 CIFS_SB(sb)->mnt_cifs_flags |= 1715 CIFS_SB(sb)->mnt_cifs_flags |=
1668 CIFS_MOUNT_POSIX_PATHS; 1716 CIFS_MOUNT_POSIX_PATHS;
1669 } 1717 }
1670 1718
1671 /* We might be setting the path sep back to a different 1719 /* We might be setting the path sep back to a different
1672 form if we are reconnecting and the server switched its 1720 form if we are reconnecting and the server switched its
1673 posix path capability for this share */ 1721 posix path capability for this share */
1674 if(sb && (CIFS_SB(sb)->prepathlen > 0)) 1722 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1675 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); 1723 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1676 1724
1677 cFYI(1,("Negotiate caps 0x%x",(int)cap)); 1725 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1726 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1727 CIFS_SB(sb)->rsize = 127 * 1024;
1728#ifdef CONFIG_CIFS_DEBUG2
1729 cFYI(1, ("larger reads not supported by srv"));
1730#endif
1731 }
1732 }
1733
1734
1735 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1678#ifdef CONFIG_CIFS_DEBUG2 1736#ifdef CONFIG_CIFS_DEBUG2
1679 if(cap & CIFS_UNIX_FCNTL_CAP) 1737 if (cap & CIFS_UNIX_FCNTL_CAP)
1680 cFYI(1,("FCNTL cap")); 1738 cFYI(1, ("FCNTL cap"));
1681 if(cap & CIFS_UNIX_EXTATTR_CAP) 1739 if (cap & CIFS_UNIX_EXTATTR_CAP)
1682 cFYI(1,("EXTATTR cap")); 1740 cFYI(1, ("EXTATTR cap"));
1683 if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 1741 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1684 cFYI(1,("POSIX path cap")); 1742 cFYI(1, ("POSIX path cap"));
1685 if(cap & CIFS_UNIX_XATTR_CAP) 1743 if (cap & CIFS_UNIX_XATTR_CAP)
1686 cFYI(1,("XATTR cap")); 1744 cFYI(1, ("XATTR cap"));
1687 if(cap & CIFS_UNIX_POSIX_ACL_CAP) 1745 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1688 cFYI(1,("POSIX ACL cap")); 1746 cFYI(1, ("POSIX ACL cap"));
1747 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1748 cFYI(1, ("very large read cap"));
1749 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1750 cFYI(1, ("very large write cap"));
1689#endif /* CIFS_DEBUG2 */ 1751#endif /* CIFS_DEBUG2 */
1690 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 1752 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1691 cFYI(1,("setting capabilities failed")); 1753 cFYI(1, ("setting capabilities failed"));
1692 } 1754 }
1693 } 1755 }
1694} 1756}
@@ -1712,8 +1774,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1712 xid = GetXid(); 1774 xid = GetXid();
1713 1775
1714/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ 1776/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1715 1777
1716 memset(&volume_info,0,sizeof(struct smb_vol)); 1778 memset(&volume_info, 0, sizeof(struct smb_vol));
1717 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1779 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1718 kfree(volume_info.UNC); 1780 kfree(volume_info.UNC);
1719 kfree(volume_info.password); 1781 kfree(volume_info.password);
@@ -1723,15 +1785,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1723 } 1785 }
1724 1786
1725 if (volume_info.nullauth) { 1787 if (volume_info.nullauth) {
1726 cFYI(1,("null user")); 1788 cFYI(1, ("null user"));
1727 volume_info.username = NULL; 1789 volume_info.username = NULL;
1728 } else if (volume_info.username) { 1790 } else if (volume_info.username) {
1729 /* BB fixme parse for domain name here */ 1791 /* BB fixme parse for domain name here */
1730 cFYI(1, ("Username: %s ", volume_info.username)); 1792 cFYI(1, ("Username: %s", volume_info.username));
1731 } else { 1793 } else {
1732 cifserror("No username specified"); 1794 cifserror("No username specified");
1733 /* In userspace mount helper we can get user name from alternate 1795 /* In userspace mount helper we can get user name from alternate
1734 locations such as env variables and files on disk */ 1796 locations such as env variables and files on disk */
1735 kfree(volume_info.UNC); 1797 kfree(volume_info.UNC);
1736 kfree(volume_info.password); 1798 kfree(volume_info.password);
1737 kfree(volume_info.prepath); 1799 kfree(volume_info.prepath);
@@ -1740,18 +1802,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1740 } 1802 }
1741 1803
1742 if (volume_info.UNCip && volume_info.UNC) { 1804 if (volume_info.UNCip && volume_info.UNC) {
1743 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr); 1805 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1806 &sin_server.sin_addr.s_addr);
1744 1807
1745 if(rc <= 0) { 1808 if (rc <= 0) {
1746 /* not ipv4 address, try ipv6 */ 1809 /* not ipv4 address, try ipv6 */
1747 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u); 1810 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1748 if(rc > 0) 1811 &sin_server6.sin6_addr.in6_u);
1812 if (rc > 0)
1749 address_type = AF_INET6; 1813 address_type = AF_INET6;
1750 } else { 1814 } else {
1751 address_type = AF_INET; 1815 address_type = AF_INET;
1752 } 1816 }
1753 1817
1754 if(rc <= 0) { 1818 if (rc <= 0) {
1755 /* we failed translating address */ 1819 /* we failed translating address */
1756 kfree(volume_info.UNC); 1820 kfree(volume_info.UNC);
1757 kfree(volume_info.password); 1821 kfree(volume_info.password);
@@ -1763,9 +1827,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1763 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip)); 1827 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1764 /* success */ 1828 /* success */
1765 rc = 0; 1829 rc = 0;
1766 } else if (volume_info.UNCip){ 1830 } else if (volume_info.UNCip) {
1767 /* BB using ip addr as server name connect to the DFS root below */ 1831 /* BB using ip addr as server name to connect to the
1768 cERROR(1,("Connecting to DFS root not implemented yet")); 1832 DFS root below */
1833 cERROR(1, ("Connecting to DFS root not implemented yet"));
1769 kfree(volume_info.UNC); 1834 kfree(volume_info.UNC);
1770 kfree(volume_info.password); 1835 kfree(volume_info.password);
1771 kfree(volume_info.prepath); 1836 kfree(volume_info.prepath);
@@ -1773,7 +1838,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1773 return -EINVAL; 1838 return -EINVAL;
1774 } else /* which servers DFS root would we conect to */ { 1839 } else /* which servers DFS root would we conect to */ {
1775 cERROR(1, 1840 cERROR(1,
1776 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); 1841 ("CIFS mount error: No UNC path (e.g. -o "
1842 "unc=//192.168.1.100/public) specified"));
1777 kfree(volume_info.UNC); 1843 kfree(volume_info.UNC);
1778 kfree(volume_info.password); 1844 kfree(volume_info.password);
1779 kfree(volume_info.prepath); 1845 kfree(volume_info.prepath);
@@ -1782,13 +1848,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1782 } 1848 }
1783 1849
1784 /* this is needed for ASCII cp to Unicode converts */ 1850 /* this is needed for ASCII cp to Unicode converts */
1785 if(volume_info.iocharset == NULL) { 1851 if (volume_info.iocharset == NULL) {
1786 cifs_sb->local_nls = load_nls_default(); 1852 cifs_sb->local_nls = load_nls_default();
1787 /* load_nls_default can not return null */ 1853 /* load_nls_default can not return null */
1788 } else { 1854 } else {
1789 cifs_sb->local_nls = load_nls(volume_info.iocharset); 1855 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1790 if(cifs_sb->local_nls == NULL) { 1856 if (cifs_sb->local_nls == NULL) {
1791 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset)); 1857 cERROR(1, ("CIFS mount error: iocharset %s not found",
1858 volume_info.iocharset));
1792 kfree(volume_info.UNC); 1859 kfree(volume_info.UNC);
1793 kfree(volume_info.password); 1860 kfree(volume_info.password);
1794 kfree(volume_info.prepath); 1861 kfree(volume_info.prepath);
@@ -1797,12 +1864,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1797 } 1864 }
1798 } 1865 }
1799 1866
1800 if(address_type == AF_INET) 1867 if (address_type == AF_INET)
1801 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, 1868 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1802 NULL /* no ipv6 addr */, 1869 NULL /* no ipv6 addr */,
1803 volume_info.username, &srvTcp); 1870 volume_info.username, &srvTcp);
1804 else if(address_type == AF_INET6) { 1871 else if (address_type == AF_INET6) {
1805 cFYI(1,("looking for ipv6 address")); 1872 cFYI(1, ("looking for ipv6 address"));
1806 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, 1873 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1807 &sin_server6.sin6_addr, 1874 &sin_server6.sin6_addr,
1808 volume_info.username, &srvTcp); 1875 volume_info.username, &srvTcp);
@@ -1814,26 +1881,25 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1814 return -EINVAL; 1881 return -EINVAL;
1815 } 1882 }
1816 1883
1817
1818 if (srvTcp) { 1884 if (srvTcp) {
1819 cFYI(1, ("Existing tcp session with server found")); 1885 cFYI(1, ("Existing tcp session with server found"));
1820 } else { /* create socket */ 1886 } else { /* create socket */
1821 if (volume_info.port) 1887 if (volume_info.port)
1822 sin_server.sin_port = htons(volume_info.port); 1888 sin_server.sin_port = htons(volume_info.port);
1823 else 1889 else
1824 sin_server.sin_port = 0; 1890 sin_server.sin_port = 0;
1825 if (address_type == AF_INET6) { 1891 if (address_type == AF_INET6) {
1826 cFYI(1,("attempting ipv6 connect")); 1892 cFYI(1, ("attempting ipv6 connect"));
1827 /* BB should we allow ipv6 on port 139? */ 1893 /* BB should we allow ipv6 on port 139? */
1828 /* other OS never observed in Wild doing 139 with v6 */ 1894 /* other OS never observed in Wild doing 139 with v6 */
1829 rc = ipv6_connect(&sin_server6,&csocket); 1895 rc = ipv6_connect(&sin_server6, &csocket);
1830 } else 1896 } else
1831 rc = ipv4_connect(&sin_server,&csocket, 1897 rc = ipv4_connect(&sin_server, &csocket,
1832 volume_info.source_rfc1001_name, 1898 volume_info.source_rfc1001_name,
1833 volume_info.target_rfc1001_name); 1899 volume_info.target_rfc1001_name);
1834 if (rc < 0) { 1900 if (rc < 0) {
1835 cERROR(1, 1901 cERROR(1, ("Error connecting to IPv4 socket. "
1836 ("Error connecting to IPv4 socket. Aborting operation")); 1902 "Aborting operation"));
1837 if (csocket != NULL) 1903 if (csocket != NULL)
1838 sock_release(csocket); 1904 sock_release(csocket);
1839 kfree(volume_info.UNC); 1905 kfree(volume_info.UNC);
@@ -1854,8 +1920,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1854 return rc; 1920 return rc;
1855 } else { 1921 } else {
1856 memset(srvTcp, 0, sizeof (struct TCP_Server_Info)); 1922 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1857 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in)); 1923 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1858 atomic_set(&srvTcp->inFlight,0); 1924 sizeof (struct sockaddr_in));
1925 atomic_set(&srvTcp->inFlight, 0);
1859 /* BB Add code for ipv6 case too */ 1926 /* BB Add code for ipv6 case too */
1860 srvTcp->ssocket = csocket; 1927 srvTcp->ssocket = csocket;
1861 srvTcp->protocolType = IPV4; 1928 srvTcp->protocolType = IPV4;
@@ -1870,7 +1937,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1870 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); 1937 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1871 if ( IS_ERR(srvTcp->tsk) ) { 1938 if ( IS_ERR(srvTcp->tsk) ) {
1872 rc = PTR_ERR(srvTcp->tsk); 1939 rc = PTR_ERR(srvTcp->tsk);
1873 cERROR(1,("error %d create cifsd thread", rc)); 1940 cERROR(1, ("error %d create cifsd thread", rc));
1874 srvTcp->tsk = NULL; 1941 srvTcp->tsk = NULL;
1875 sock_release(csocket); 1942 sock_release(csocket);
1876 kfree(volume_info.UNC); 1943 kfree(volume_info.UNC);
@@ -1881,8 +1948,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1881 } 1948 }
1882 wait_for_completion(&cifsd_complete); 1949 wait_for_completion(&cifsd_complete);
1883 rc = 0; 1950 rc = 0;
1884 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1951 memcpy(srvTcp->workstation_RFC1001_name,
1885 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16); 1952 volume_info.source_rfc1001_name, 16);
1953 memcpy(srvTcp->server_RFC1001_name,
1954 volume_info.target_rfc1001_name, 16);
1886 srvTcp->sequence_number = 0; 1955 srvTcp->sequence_number = 0;
1887 } 1956 }
1888 } 1957 }
@@ -1903,16 +1972,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1903 NIPQUAD(sin_server.sin_addr.s_addr)); 1972 NIPQUAD(sin_server.sin_addr.s_addr));
1904 } 1973 }
1905 1974
1906 if (!rc){ 1975 if (!rc) {
1907 /* volume_info.password freed at unmount */ 1976 /* volume_info.password freed at unmount */
1908 if (volume_info.password) 1977 if (volume_info.password)
1909 pSesInfo->password = volume_info.password; 1978 pSesInfo->password = volume_info.password;
1910 if (volume_info.username) 1979 if (volume_info.username)
1911 strncpy(pSesInfo->userName, 1980 strncpy(pSesInfo->userName,
1912 volume_info.username,MAX_USERNAME_SIZE); 1981 volume_info.username,
1982 MAX_USERNAME_SIZE);
1913 if (volume_info.domainname) { 1983 if (volume_info.domainname) {
1914 int len = strlen(volume_info.domainname); 1984 int len = strlen(volume_info.domainname);
1915 pSesInfo->domainName = 1985 pSesInfo->domainName =
1916 kmalloc(len + 1, GFP_KERNEL); 1986 kmalloc(len + 1, GFP_KERNEL);
1917 if (pSesInfo->domainName) 1987 if (pSesInfo->domainName)
1918 strcpy(pSesInfo->domainName, 1988 strcpy(pSesInfo->domainName,
@@ -1922,46 +1992,48 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1922 pSesInfo->overrideSecFlg = volume_info.secFlg; 1992 pSesInfo->overrideSecFlg = volume_info.secFlg;
1923 down(&pSesInfo->sesSem); 1993 down(&pSesInfo->sesSem);
1924 /* BB FIXME need to pass vol->secFlgs BB */ 1994 /* BB FIXME need to pass vol->secFlgs BB */
1925 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1995 rc = cifs_setup_session(xid, pSesInfo,
1996 cifs_sb->local_nls);
1926 up(&pSesInfo->sesSem); 1997 up(&pSesInfo->sesSem);
1927 if (!rc) 1998 if (!rc)
1928 atomic_inc(&srvTcp->socketUseCount); 1999 atomic_inc(&srvTcp->socketUseCount);
1929 } else 2000 } else
1930 kfree(volume_info.password); 2001 kfree(volume_info.password);
1931 } 2002 }
1932 2003
1933 /* search for existing tcon to this server share */ 2004 /* search for existing tcon to this server share */
1934 if (!rc) { 2005 if (!rc) {
1935 if (volume_info.rsize > CIFSMaxBufSize) { 2006 if (volume_info.rsize > CIFSMaxBufSize) {
1936 cERROR(1,("rsize %d too large, using MaxBufSize", 2007 cERROR(1, ("rsize %d too large, using MaxBufSize",
1937 volume_info.rsize)); 2008 volume_info.rsize));
1938 cifs_sb->rsize = CIFSMaxBufSize; 2009 cifs_sb->rsize = CIFSMaxBufSize;
1939 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) 2010 } else if ((volume_info.rsize) &&
2011 (volume_info.rsize <= CIFSMaxBufSize))
1940 cifs_sb->rsize = volume_info.rsize; 2012 cifs_sb->rsize = volume_info.rsize;
1941 else /* default */ 2013 else /* default */
1942 cifs_sb->rsize = CIFSMaxBufSize; 2014 cifs_sb->rsize = CIFSMaxBufSize;
1943 2015
1944 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 2016 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1945 cERROR(1,("wsize %d too large using 4096 instead", 2017 cERROR(1, ("wsize %d too large, using 4096 instead",
1946 volume_info.wsize)); 2018 volume_info.wsize));
1947 cifs_sb->wsize = 4096; 2019 cifs_sb->wsize = 4096;
1948 } else if (volume_info.wsize) 2020 } else if (volume_info.wsize)
1949 cifs_sb->wsize = volume_info.wsize; 2021 cifs_sb->wsize = volume_info.wsize;
1950 else 2022 else
1951 cifs_sb->wsize = 2023 cifs_sb->wsize =
1952 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE, 2024 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1953 127*1024); 2025 127*1024);
1954 /* old default of CIFSMaxBufSize was too small now 2026 /* old default of CIFSMaxBufSize was too small now
1955 that SMB Write2 can send multiple pages in kvec. 2027 that SMB Write2 can send multiple pages in kvec.
1956 RFC1001 does not describe what happens when frame 2028 RFC1001 does not describe what happens when frame
1957 bigger than 128K is sent so use that as max in 2029 bigger than 128K is sent so use that as max in
1958 conjunction with 52K kvec constraint on arch with 4K 2030 conjunction with 52K kvec constraint on arch with 4K
1959 page size */ 2031 page size */
1960 2032
1961 if (cifs_sb->rsize < 2048) { 2033 if (cifs_sb->rsize < 2048) {
1962 cifs_sb->rsize = 2048; 2034 cifs_sb->rsize = 2048;
1963 /* Windows ME may prefer this */ 2035 /* Windows ME may prefer this */
1964 cFYI(1,("readsize set to minimum 2048")); 2036 cFYI(1, ("readsize set to minimum: 2048"));
1965 } 2037 }
1966 /* calculate prepath */ 2038 /* calculate prepath */
1967 cifs_sb->prepath = volume_info.prepath; 2039 cifs_sb->prepath = volume_info.prepath;
@@ -1969,14 +2041,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1969 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 2041 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1970 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 2042 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1971 volume_info.prepath = NULL; 2043 volume_info.prepath = NULL;
1972 } else 2044 } else
1973 cifs_sb->prepathlen = 0; 2045 cifs_sb->prepathlen = 0;
1974 cifs_sb->mnt_uid = volume_info.linux_uid; 2046 cifs_sb->mnt_uid = volume_info.linux_uid;
1975 cifs_sb->mnt_gid = volume_info.linux_gid; 2047 cifs_sb->mnt_gid = volume_info.linux_gid;
1976 cifs_sb->mnt_file_mode = volume_info.file_mode; 2048 cifs_sb->mnt_file_mode = volume_info.file_mode;
1977 cifs_sb->mnt_dir_mode = volume_info.dir_mode; 2049 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1978 cFYI(1,("file mode: 0x%x dir mode: 0x%x", 2050 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
1979 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 2051 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
1980 2052
1981 if (volume_info.noperm) 2053 if (volume_info.noperm)
1982 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2054 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -1999,7 +2071,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1999 if (volume_info.override_gid) 2071 if (volume_info.override_gid)
2000 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; 2072 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2001 if (volume_info.direct_io) { 2073 if (volume_info.direct_io) {
2002 cFYI(1,("mounting share using direct i/o")); 2074 cFYI(1, ("mounting share using direct i/o"));
2003 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2075 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2004 } 2076 }
2005 2077
@@ -2010,7 +2082,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2010 cFYI(1, ("Found match on UNC path")); 2082 cFYI(1, ("Found match on UNC path"));
2011 /* we can have only one retry value for a connection 2083 /* we can have only one retry value for a connection
2012 to a share so for resources mounted more than once 2084 to a share so for resources mounted more than once
2013 to the same server share the last value passed in 2085 to the same server share the last value passed in
2014 for the retry flag is used */ 2086 for the retry flag is used */
2015 tcon->retry = volume_info.retry; 2087 tcon->retry = volume_info.retry;
2016 tcon->nocase = volume_info.nocase; 2088 tcon->nocase = volume_info.nocase;
@@ -2019,17 +2091,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2019 if (tcon == NULL) 2091 if (tcon == NULL)
2020 rc = -ENOMEM; 2092 rc = -ENOMEM;
2021 else { 2093 else {
2022 /* check for null share name ie connecting to 2094 /* check for null share name ie connecting to
2023 * dfs root */ 2095 * dfs root */
2024 2096
2025 /* BB check if this works for exactly length 2097 /* BB check if this works for exactly length
2026 * three strings */ 2098 * three strings */
2027 if ((strchr(volume_info.UNC + 3, '\\') == NULL) 2099 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2028 && (strchr(volume_info.UNC + 3, '/') == 2100 && (strchr(volume_info.UNC + 3, '/') ==
2029 NULL)) { 2101 NULL)) {
2030 rc = connect_to_dfs_path(xid, pSesInfo, 2102 rc = connect_to_dfs_path(xid, pSesInfo,
2031 "", cifs_sb->local_nls, 2103 "", cifs_sb->local_nls,
2032 cifs_sb->mnt_cifs_flags & 2104 cifs_sb->mnt_cifs_flags &
2033 CIFS_MOUNT_MAP_SPECIAL_CHR); 2105 CIFS_MOUNT_MAP_SPECIAL_CHR);
2034 kfree(volume_info.UNC); 2106 kfree(volume_info.UNC);
2035 FreeXid(xid); 2107 FreeXid(xid);
@@ -2038,7 +2110,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2038 /* BB Do we need to wrap sesSem around 2110 /* BB Do we need to wrap sesSem around
2039 * this TCon call and Unix SetFS as 2111 * this TCon call and Unix SetFS as
2040 * we do on SessSetup and reconnect? */ 2112 * we do on SessSetup and reconnect? */
2041 rc = CIFSTCon(xid, pSesInfo, 2113 rc = CIFSTCon(xid, pSesInfo,
2042 volume_info.UNC, 2114 volume_info.UNC,
2043 tcon, cifs_sb->local_nls); 2115 tcon, cifs_sb->local_nls);
2044 cFYI(1, ("CIFS Tcon rc = %d", rc)); 2116 cFYI(1, ("CIFS Tcon rc = %d", rc));
@@ -2075,9 +2147,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2075 always wake up processes blocked in 2147 always wake up processes blocked in
2076 tcp in recv_mesg then we could remove the 2148 tcp in recv_mesg then we could remove the
2077 send_sig call */ 2149 send_sig call */
2078 send_sig(SIGKILL,srvTcp->tsk,1); 2150 force_sig(SIGKILL, srvTcp->tsk);
2079 tsk = srvTcp->tsk; 2151 tsk = srvTcp->tsk;
2080 if(tsk) 2152 if (tsk)
2081 kthread_stop(tsk); 2153 kthread_stop(tsk);
2082 } 2154 }
2083 } 2155 }
@@ -2086,15 +2158,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2086 tconInfoFree(tcon); 2158 tconInfoFree(tcon);
2087 if (existingCifsSes == NULL) { 2159 if (existingCifsSes == NULL) {
2088 if (pSesInfo) { 2160 if (pSesInfo) {
2089 if ((pSesInfo->server) && 2161 if ((pSesInfo->server) &&
2090 (pSesInfo->status == CifsGood)) { 2162 (pSesInfo->status == CifsGood)) {
2091 int temp_rc; 2163 int temp_rc;
2092 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 2164 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2093 /* if the socketUseCount is now zero */ 2165 /* if the socketUseCount is now zero */
2094 if ((temp_rc == -ESHUTDOWN) && 2166 if ((temp_rc == -ESHUTDOWN) &&
2095 (pSesInfo->server) && (pSesInfo->server->tsk)) { 2167 (pSesInfo->server) &&
2168 (pSesInfo->server->tsk)) {
2096 struct task_struct *tsk; 2169 struct task_struct *tsk;
2097 send_sig(SIGKILL,pSesInfo->server->tsk,1); 2170 force_sig(SIGKILL,
2171 pSesInfo->server->tsk);
2098 tsk = pSesInfo->server->tsk; 2172 tsk = pSesInfo->server->tsk;
2099 if (tsk) 2173 if (tsk)
2100 kthread_stop(tsk); 2174 kthread_stop(tsk);
@@ -2113,19 +2187,29 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2113 /* do not care if following two calls succeed - informational */ 2187 /* do not care if following two calls succeed - informational */
2114 CIFSSMBQFSDeviceInfo(xid, tcon); 2188 CIFSSMBQFSDeviceInfo(xid, tcon);
2115 CIFSSMBQFSAttributeInfo(xid, tcon); 2189 CIFSSMBQFSAttributeInfo(xid, tcon);
2116 2190
2117 /* tell server which Unix caps we support */ 2191 /* tell server which Unix caps we support */
2118 if (tcon->ses->capabilities & CAP_UNIX) 2192 if (tcon->ses->capabilities & CAP_UNIX)
2193 /* reset of caps checks mount to see if unix extensions
2194 disabled for just this mount */
2119 reset_cifs_unix_caps(xid, tcon, sb, &volume_info); 2195 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2120 2196 else
2197 tcon->unix_ext = 0; /* server does not support them */
2198
2199 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2200 cifs_sb->rsize = 1024 * 127;
2201#ifdef CONFIG_CIFS_DEBUG2
2202 cFYI(1, ("no very large read support, rsize now 127K"));
2203#endif
2204 }
2121 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) 2205 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2122 cifs_sb->wsize = min(cifs_sb->wsize, 2206 cifs_sb->wsize = min(cifs_sb->wsize,
2123 (tcon->ses->server->maxBuf - 2207 (tcon->ses->server->maxBuf -
2124 MAX_CIFS_HDR_SIZE)); 2208 MAX_CIFS_HDR_SIZE));
2125 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) 2209 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2126 cifs_sb->rsize = min(cifs_sb->rsize, 2210 cifs_sb->rsize = min(cifs_sb->rsize,
2127 (tcon->ses->server->maxBuf - 2211 (tcon->ses->server->maxBuf -
2128 MAX_CIFS_HDR_SIZE)); 2212 MAX_CIFS_HDR_SIZE));
2129 } 2213 }
2130 2214
2131 /* volume_info.password is freed above when existing session found 2215 /* volume_info.password is freed above when existing session found
@@ -2178,7 +2262,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2178 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2262 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2179 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2263 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2180 2264
2181 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2265 if (ses->server->secMode &
2266 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2182 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2267 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2183 2268
2184 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2269 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2197,7 +2282,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2197 } 2282 }
2198 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 2283 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2199 2284
2200 pSMB->req_no_secext.CaseInsensitivePasswordLength = 2285 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2201 cpu_to_le16(CIFS_SESS_KEY_SIZE); 2286 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2202 2287
2203 pSMB->req_no_secext.CaseSensitivePasswordLength = 2288 pSMB->req_no_secext.CaseSensitivePasswordLength =
@@ -2215,9 +2300,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2215 } 2300 }
2216 if (user == NULL) 2301 if (user == NULL)
2217 bytes_returned = 0; /* skip null user */ 2302 bytes_returned = 0; /* skip null user */
2218 else 2303 else
2219 bytes_returned = 2304 bytes_returned =
2220 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, 2305 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2221 nls_codepage); 2306 nls_codepage);
2222 /* convert number of 16 bit words to bytes */ 2307 /* convert number of 16 bit words to bytes */
2223 bcc_ptr += 2 * bytes_returned; 2308 bcc_ptr += 2 * bytes_returned;
@@ -2247,7 +2332,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2247 bcc_ptr += 2 * bytes_returned; 2332 bcc_ptr += 2 * bytes_returned;
2248 bcc_ptr += 2; 2333 bcc_ptr += 2;
2249 } else { 2334 } else {
2250 if (user != NULL) { 2335 if (user != NULL) {
2251 strncpy(bcc_ptr, user, 200); 2336 strncpy(bcc_ptr, user, 200);
2252 bcc_ptr += strnlen(user, 200); 2337 bcc_ptr += strnlen(user, 200);
2253 } 2338 }
@@ -2282,11 +2367,12 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2282 __u16 action = le16_to_cpu(pSMBr->resp.Action); 2367 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2283 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2368 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2284 if (action & GUEST_LOGIN) 2369 if (action & GUEST_LOGIN)
2285 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */ 2370 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2286 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */ 2371 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2372 (little endian) */
2287 cFYI(1, ("UID = %d ", ses->Suid)); 2373 cFYI(1, ("UID = %d ", ses->Suid));
2288 /* response can have either 3 or 4 word count - Samba sends 3 */ 2374 /* response can have either 3 or 4 word count - Samba sends 3 */
2289 bcc_ptr = pByteArea(smb_buffer_response); 2375 bcc_ptr = pByteArea(smb_buffer_response);
2290 if ((pSMBr->resp.hdr.WordCount == 3) 2376 if ((pSMBr->resp.hdr.WordCount == 3)
2291 || ((pSMBr->resp.hdr.WordCount == 4) 2377 || ((pSMBr->resp.hdr.WordCount == 4)
2292 && (blob_len < pSMBr->resp.ByteCount))) { 2378 && (blob_len < pSMBr->resp.ByteCount))) {
@@ -2296,8 +2382,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2296 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2382 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2297 if ((long) (bcc_ptr) % 2) { 2383 if ((long) (bcc_ptr) % 2) {
2298 remaining_words = 2384 remaining_words =
2299 (BCC(smb_buffer_response) - 1) /2; 2385 (BCC(smb_buffer_response) - 1) / 2;
2300 bcc_ptr++; /* Unicode strings must be word aligned */ 2386 /* Unicode strings must be word
2387 aligned */
2388 bcc_ptr++;
2301 } else { 2389 } else {
2302 remaining_words = 2390 remaining_words =
2303 BCC(smb_buffer_response) / 2; 2391 BCC(smb_buffer_response) / 2;
@@ -2308,13 +2396,15 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2308/* We look for obvious messed up bcc or strings in response so we do not go off 2396/* We look for obvious messed up bcc or strings in response so we do not go off
2309 the end since (at least) WIN2K and Windows XP have a major bug in not null 2397 the end since (at least) WIN2K and Windows XP have a major bug in not null
2310 terminating last Unicode string in response */ 2398 terminating last Unicode string in response */
2311 if(ses->serverOS) 2399 if (ses->serverOS)
2312 kfree(ses->serverOS); 2400 kfree(ses->serverOS);
2313 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); 2401 ses->serverOS = kzalloc(2 * (len + 1),
2314 if(ses->serverOS == NULL) 2402 GFP_KERNEL);
2403 if (ses->serverOS == NULL)
2315 goto sesssetup_nomem; 2404 goto sesssetup_nomem;
2316 cifs_strfromUCS_le(ses->serverOS, 2405 cifs_strfromUCS_le(ses->serverOS,
2317 (__le16 *)bcc_ptr, len,nls_codepage); 2406 (__le16 *)bcc_ptr,
2407 len, nls_codepage);
2318 bcc_ptr += 2 * (len + 1); 2408 bcc_ptr += 2 * (len + 1);
2319 remaining_words -= len + 1; 2409 remaining_words -= len + 1;
2320 ses->serverOS[2 * len] = 0; 2410 ses->serverOS[2 * len] = 0;
@@ -2323,42 +2413,49 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2323 len = UniStrnlen((wchar_t *)bcc_ptr, 2413 len = UniStrnlen((wchar_t *)bcc_ptr,
2324 remaining_words-1); 2414 remaining_words-1);
2325 kfree(ses->serverNOS); 2415 kfree(ses->serverNOS);
2326 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL); 2416 ses->serverNOS = kzalloc(2 * (len + 1),
2327 if(ses->serverNOS == NULL) 2417 GFP_KERNEL);
2418 if (ses->serverNOS == NULL)
2328 goto sesssetup_nomem; 2419 goto sesssetup_nomem;
2329 cifs_strfromUCS_le(ses->serverNOS, 2420 cifs_strfromUCS_le(ses->serverNOS,
2330 (__le16 *)bcc_ptr,len,nls_codepage); 2421 (__le16 *)bcc_ptr,
2422 len, nls_codepage);
2331 bcc_ptr += 2 * (len + 1); 2423 bcc_ptr += 2 * (len + 1);
2332 ses->serverNOS[2 * len] = 0; 2424 ses->serverNOS[2 * len] = 0;
2333 ses->serverNOS[1 + (2 * len)] = 0; 2425 ses->serverNOS[1 + (2 * len)] = 0;
2334 if(strncmp(ses->serverNOS, 2426 if (strncmp(ses->serverNOS,
2335 "NT LAN Manager 4",16) == 0) { 2427 "NT LAN Manager 4", 16) == 0) {
2336 cFYI(1,("NT4 server")); 2428 cFYI(1, ("NT4 server"));
2337 ses->flags |= CIFS_SES_NT4; 2429 ses->flags |= CIFS_SES_NT4;
2338 } 2430 }
2339 remaining_words -= len + 1; 2431 remaining_words -= len + 1;
2340 if (remaining_words > 0) { 2432 if (remaining_words > 0) {
2341 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2433 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2342 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2434 /* last string is not always null terminated
2343 if(ses->serverDomain) 2435 (for e.g. for Windows XP & 2000) */
2436 if (ses->serverDomain)
2344 kfree(ses->serverDomain); 2437 kfree(ses->serverDomain);
2345 ses->serverDomain = 2438 ses->serverDomain =
2346 kzalloc(2*(len+1),GFP_KERNEL); 2439 kzalloc(2*(len+1),
2347 if(ses->serverDomain == NULL) 2440 GFP_KERNEL);
2441 if (ses->serverDomain == NULL)
2348 goto sesssetup_nomem; 2442 goto sesssetup_nomem;
2349 cifs_strfromUCS_le(ses->serverDomain, 2443 cifs_strfromUCS_le(ses->serverDomain,
2350 (__le16 *)bcc_ptr,len,nls_codepage); 2444 (__le16 *)bcc_ptr,
2445 len, nls_codepage);
2351 bcc_ptr += 2 * (len + 1); 2446 bcc_ptr += 2 * (len + 1);
2352 ses->serverDomain[2*len] = 0; 2447 ses->serverDomain[2*len] = 0;
2353 ses->serverDomain[1+(2*len)] = 0; 2448 ses->serverDomain[1+(2*len)] = 0;
2354 } /* else no more room so create dummy domain string */ 2449 } else { /* else no more room so create
2355 else { 2450 dummy domain string */
2356 if(ses->serverDomain) 2451 if (ses->serverDomain)
2357 kfree(ses->serverDomain); 2452 kfree(ses->serverDomain);
2358 ses->serverDomain = 2453 ses->serverDomain =
2359 kzalloc(2, GFP_KERNEL); 2454 kzalloc(2, GFP_KERNEL);
2360 } 2455 }
2361 } else { /* no room so create dummy domain and NOS string */ 2456 } else { /* no room so create dummy domain
2457 and NOS string */
2458
2362 /* if these kcallocs fail not much we 2459 /* if these kcallocs fail not much we
2363 can do, but better to not fail the 2460 can do, but better to not fail the
2364 sesssetup itself */ 2461 sesssetup itself */
@@ -2375,19 +2472,22 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2375 pByteArea(smb_buffer_response) 2472 pByteArea(smb_buffer_response)
2376 <= BCC(smb_buffer_response)) { 2473 <= BCC(smb_buffer_response)) {
2377 kfree(ses->serverOS); 2474 kfree(ses->serverOS);
2378 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 2475 ses->serverOS = kzalloc(len + 1,
2379 if(ses->serverOS == NULL) 2476 GFP_KERNEL);
2477 if (ses->serverOS == NULL)
2380 goto sesssetup_nomem; 2478 goto sesssetup_nomem;
2381 strncpy(ses->serverOS,bcc_ptr, len); 2479 strncpy(ses->serverOS, bcc_ptr, len);
2382 2480
2383 bcc_ptr += len; 2481 bcc_ptr += len;
2384 bcc_ptr[0] = 0; /* null terminate the string */ 2482 /* null terminate the string */
2483 bcc_ptr[0] = 0;
2385 bcc_ptr++; 2484 bcc_ptr++;
2386 2485
2387 len = strnlen(bcc_ptr, 1024); 2486 len = strnlen(bcc_ptr, 1024);
2388 kfree(ses->serverNOS); 2487 kfree(ses->serverNOS);
2389 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL); 2488 ses->serverNOS = kzalloc(len + 1,
2390 if(ses->serverNOS == NULL) 2489 GFP_KERNEL);
2490 if (ses->serverNOS == NULL)
2391 goto sesssetup_nomem; 2491 goto sesssetup_nomem;
2392 strncpy(ses->serverNOS, bcc_ptr, len); 2492 strncpy(ses->serverNOS, bcc_ptr, len);
2393 bcc_ptr += len; 2493 bcc_ptr += len;
@@ -2395,23 +2495,27 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2395 bcc_ptr++; 2495 bcc_ptr++;
2396 2496
2397 len = strnlen(bcc_ptr, 1024); 2497 len = strnlen(bcc_ptr, 1024);
2398 if(ses->serverDomain) 2498 if (ses->serverDomain)
2399 kfree(ses->serverDomain); 2499 kfree(ses->serverDomain);
2400 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL); 2500 ses->serverDomain = kzalloc(len + 1,
2401 if(ses->serverDomain == NULL) 2501 GFP_KERNEL);
2502 if (ses->serverDomain == NULL)
2402 goto sesssetup_nomem; 2503 goto sesssetup_nomem;
2403 strncpy(ses->serverDomain, bcc_ptr, len); 2504 strncpy(ses->serverDomain, bcc_ptr,
2505 len);
2404 bcc_ptr += len; 2506 bcc_ptr += len;
2405 bcc_ptr[0] = 0; 2507 bcc_ptr[0] = 0;
2406 bcc_ptr++; 2508 bcc_ptr++;
2407 } else 2509 } else
2408 cFYI(1, 2510 cFYI(1,
2409 ("Variable field of length %d extends beyond end of smb ", 2511 ("Variable field of length %d "
2512 "extends beyond end of smb ",
2410 len)); 2513 len));
2411 } 2514 }
2412 } else { 2515 } else {
2413 cERROR(1, 2516 cERROR(1,
2414 (" Security Blob Length extends beyond end of SMB")); 2517 (" Security Blob Length extends beyond "
2518 "end of SMB"));
2415 } 2519 }
2416 } else { 2520 } else {
2417 cERROR(1, 2521 cERROR(1,
@@ -2430,7 +2534,7 @@ sesssetup_nomem: /* do not return an error on nomem for the info strings,
2430 2534
2431static int 2535static int
2432CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, 2536CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2433 struct cifsSesInfo *ses, int * pNTLMv2_flag, 2537 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2434 const struct nls_table *nls_codepage) 2538 const struct nls_table *nls_codepage)
2435{ 2539{
2436 struct smb_hdr *smb_buffer; 2540 struct smb_hdr *smb_buffer;
@@ -2450,7 +2554,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2450 __u16 count; 2554 __u16 count;
2451 2555
2452 cFYI(1, ("In NTLMSSP sesssetup (negotiate)")); 2556 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2453 if(ses == NULL) 2557 if (ses == NULL)
2454 return -EINVAL; 2558 return -EINVAL;
2455 domain = ses->domainName; 2559 domain = ses->domainName;
2456 *pNTLMv2_flag = FALSE; 2560 *pNTLMv2_flag = FALSE;
@@ -2474,7 +2578,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2474 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2578 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2475 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2579 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2476 2580
2477 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2581 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2478 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2582 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2479 2583
2480 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2584 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2502,9 +2606,9 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2502 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 2606 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2503 NTLMSSP_NEGOTIATE_56 | 2607 NTLMSSP_NEGOTIATE_56 |
2504 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2608 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2505 if(sign_CIFS_PDUs) 2609 if (sign_CIFS_PDUs)
2506 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2610 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2507/* if(ntlmv2_support) 2611/* if (ntlmv2_support)
2508 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/ 2612 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2509 /* setup pointers to domain name and workstation name */ 2613 /* setup pointers to domain name and workstation name */
2510 bcc_ptr += SecurityBlobLength; 2614 bcc_ptr += SecurityBlobLength;
@@ -2574,11 +2678,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2574 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2678 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2575 2679
2576 if (action & GUEST_LOGIN) 2680 if (action & GUEST_LOGIN)
2577 cFYI(1, (" Guest login")); 2681 cFYI(1, (" Guest login"));
2578 /* Do we want to set anything in SesInfo struct when guest login? */ 2682 /* Do we want to set anything in SesInfo struct when guest login? */
2579 2683
2580 bcc_ptr = pByteArea(smb_buffer_response); 2684 bcc_ptr = pByteArea(smb_buffer_response);
2581 /* response can have either 3 or 4 word count - Samba sends 3 */ 2685 /* response can have either 3 or 4 word count - Samba sends 3 */
2582 2686
2583 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; 2687 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2584 if (SecurityBlob2->MessageType != NtLmChallenge) { 2688 if (SecurityBlob2->MessageType != NtLmChallenge) {
@@ -2586,7 +2690,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2586 ("Unexpected NTLMSSP message type received %d", 2690 ("Unexpected NTLMSSP message type received %d",
2587 SecurityBlob2->MessageType)); 2691 SecurityBlob2->MessageType));
2588 } else if (ses) { 2692 } else if (ses) {
2589 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2693 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2590 cFYI(1, ("UID = %d", ses->Suid)); 2694 cFYI(1, ("UID = %d", ses->Suid));
2591 if ((pSMBr->resp.hdr.WordCount == 3) 2695 if ((pSMBr->resp.hdr.WordCount == 3)
2592 || ((pSMBr->resp.hdr.WordCount == 4) 2696 || ((pSMBr->resp.hdr.WordCount == 4)
@@ -2604,18 +2708,18 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2604 memcpy(ses->server->cryptKey, 2708 memcpy(ses->server->cryptKey,
2605 SecurityBlob2->Challenge, 2709 SecurityBlob2->Challenge,
2606 CIFS_CRYPTO_KEY_SIZE); 2710 CIFS_CRYPTO_KEY_SIZE);
2607 if(SecurityBlob2->NegotiateFlags & 2711 if (SecurityBlob2->NegotiateFlags &
2608 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2712 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2609 *pNTLMv2_flag = TRUE; 2713 *pNTLMv2_flag = TRUE;
2610 2714
2611 if((SecurityBlob2->NegotiateFlags & 2715 if ((SecurityBlob2->NegotiateFlags &
2612 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) 2716 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2613 || (sign_CIFS_PDUs > 1)) 2717 || (sign_CIFS_PDUs > 1))
2614 ses->server->secMode |= 2718 ses->server->secMode |=
2615 SECMODE_SIGN_REQUIRED; 2719 SECMODE_SIGN_REQUIRED;
2616 if ((SecurityBlob2->NegotiateFlags & 2720 if ((SecurityBlob2->NegotiateFlags &
2617 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs)) 2721 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2618 ses->server->secMode |= 2722 ses->server->secMode |=
2619 SECMODE_SIGN_ENABLED; 2723 SECMODE_SIGN_ENABLED;
2620 2724
2621 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 2725 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -2623,7 +2727,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2623 remaining_words = 2727 remaining_words =
2624 (BCC(smb_buffer_response) 2728 (BCC(smb_buffer_response)
2625 - 1) / 2; 2729 - 1) / 2;
2626 bcc_ptr++; /* Unicode strings must be word aligned */ 2730 /* Must word align unicode strings */
2731 bcc_ptr++;
2627 } else { 2732 } else {
2628 remaining_words = 2733 remaining_words =
2629 BCC 2734 BCC
@@ -2635,7 +2740,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2635/* We look for obvious messed up bcc or strings in response so we do not go off 2740/* We look for obvious messed up bcc or strings in response so we do not go off
2636 the end since (at least) WIN2K and Windows XP have a major bug in not null 2741 the end since (at least) WIN2K and Windows XP have a major bug in not null
2637 terminating last Unicode string in response */ 2742 terminating last Unicode string in response */
2638 if(ses->serverOS) 2743 if (ses->serverOS)
2639 kfree(ses->serverOS); 2744 kfree(ses->serverOS);
2640 ses->serverOS = 2745 ses->serverOS =
2641 kzalloc(2 * (len + 1), GFP_KERNEL); 2746 kzalloc(2 * (len + 1), GFP_KERNEL);
@@ -2668,8 +2773,9 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2668 (2 * len)] = 0; 2773 (2 * len)] = 0;
2669 remaining_words -= len + 1; 2774 remaining_words -= len + 1;
2670 if (remaining_words > 0) { 2775 if (remaining_words > 0) {
2671 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2776 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2672 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2777 /* last string not always null terminated
2778 (for e.g. for Windows XP & 2000) */
2673 kfree(ses->serverDomain); 2779 kfree(ses->serverDomain);
2674 ses->serverDomain = 2780 ses->serverDomain =
2675 kzalloc(2 * 2781 kzalloc(2 *
@@ -2707,7 +2813,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2707 if (((long) bcc_ptr + len) - (long) 2813 if (((long) bcc_ptr + len) - (long)
2708 pByteArea(smb_buffer_response) 2814 pByteArea(smb_buffer_response)
2709 <= BCC(smb_buffer_response)) { 2815 <= BCC(smb_buffer_response)) {
2710 if(ses->serverOS) 2816 if (ses->serverOS)
2711 kfree(ses->serverOS); 2817 kfree(ses->serverOS);
2712 ses->serverOS = 2818 ses->serverOS =
2713 kzalloc(len + 1, 2819 kzalloc(len + 1,
@@ -2734,18 +2840,20 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2734 ses->serverDomain = 2840 ses->serverDomain =
2735 kzalloc(len + 1, 2841 kzalloc(len + 1,
2736 GFP_KERNEL); 2842 GFP_KERNEL);
2737 strncpy(ses->serverDomain, bcc_ptr, len); 2843 strncpy(ses->serverDomain,
2844 bcc_ptr, len);
2738 bcc_ptr += len; 2845 bcc_ptr += len;
2739 bcc_ptr[0] = 0; 2846 bcc_ptr[0] = 0;
2740 bcc_ptr++; 2847 bcc_ptr++;
2741 } else 2848 } else
2742 cFYI(1, 2849 cFYI(1,
2743 ("Variable field of length %d extends beyond end of smb", 2850 ("field of length %d "
2851 "extends beyond end of smb",
2744 len)); 2852 len));
2745 } 2853 }
2746 } else { 2854 } else {
2747 cERROR(1, 2855 cERROR(1, ("Security Blob Length extends beyond"
2748 (" Security Blob Length extends beyond end of SMB")); 2856 " end of SMB"));
2749 } 2857 }
2750 } else { 2858 } else {
2751 cERROR(1, ("No session structure passed in.")); 2859 cERROR(1, ("No session structure passed in."));
@@ -2784,7 +2892,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2784 __u16 count; 2892 __u16 count;
2785 2893
2786 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)")); 2894 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2787 if(ses == NULL) 2895 if (ses == NULL)
2788 return -EINVAL; 2896 return -EINVAL;
2789 user = ses->userName; 2897 user = ses->userName;
2790 domain = ses->domainName; 2898 domain = ses->domainName;
@@ -2809,7 +2917,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2809 2917
2810 pSMB->req.hdr.Uid = ses->Suid; 2918 pSMB->req.hdr.Uid = ses->Suid;
2811 2919
2812 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 2920 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2813 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 2921 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2814 2922
2815 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 2923 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
@@ -2833,13 +2941,13 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2833 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8); 2941 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2834 SecurityBlob->MessageType = NtLmAuthenticate; 2942 SecurityBlob->MessageType = NtLmAuthenticate;
2835 bcc_ptr += SecurityBlobLength; 2943 bcc_ptr += SecurityBlobLength;
2836 negotiate_flags = 2944 negotiate_flags =
2837 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | 2945 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2838 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | 2946 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2839 0x80000000 | NTLMSSP_NEGOTIATE_128; 2947 0x80000000 | NTLMSSP_NEGOTIATE_128;
2840 if(sign_CIFS_PDUs) 2948 if (sign_CIFS_PDUs)
2841 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN; 2949 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2842 if(ntlmv2_flag) 2950 if (ntlmv2_flag)
2843 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2; 2951 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2844 2952
2845/* setup pointers to domain name and workstation name */ 2953/* setup pointers to domain name and workstation name */
@@ -2903,13 +3011,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2903 cpu_to_le16(len); 3011 cpu_to_le16(len);
2904 } 3012 }
2905 3013
2906 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage); 3014 /* SecurityBlob->WorkstationName.Length =
3015 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2907 SecurityBlob->WorkstationName.Length *= 2; 3016 SecurityBlob->WorkstationName.Length *= 2;
2908 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length); 3017 SecurityBlob->WorkstationName.MaximumLength =
2909 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength); 3018 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3019 SecurityBlob->WorkstationName.Buffer =
3020 cpu_to_le32(SecurityBlobLength);
2910 bcc_ptr += SecurityBlob->WorkstationName.Length; 3021 bcc_ptr += SecurityBlob->WorkstationName.Length;
2911 SecurityBlobLength += SecurityBlob->WorkstationName.Length; 3022 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2912 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */ 3023 SecurityBlob->WorkstationName.Length =
3024 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2913 3025
2914 if ((long) bcc_ptr % 2) { 3026 if ((long) bcc_ptr % 2) {
2915 *bcc_ptr = 0; 3027 *bcc_ptr = 0;
@@ -2995,17 +3107,20 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2995 __u16 blob_len = 3107 __u16 blob_len =
2996 le16_to_cpu(pSMBr->resp.SecurityBlobLength); 3108 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2997 if (action & GUEST_LOGIN) 3109 if (action & GUEST_LOGIN)
2998 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */ 3110 cFYI(1, (" Guest login")); /* BB Should we set anything
2999/* if(SecurityBlob2->MessageType != NtLm??){ 3111 in SesInfo struct ? */
3000 cFYI("Unexpected message type on auth response is %d ")); 3112/* if (SecurityBlob2->MessageType != NtLm??) {
3001 } */ 3113 cFYI("Unexpected message type on auth response is %d"));
3114 } */
3115
3002 if (ses) { 3116 if (ses) {
3003 cFYI(1, 3117 cFYI(1,
3004 ("Does UID on challenge %d match auth response UID %d ", 3118 ("Check challenge UID %d vs auth response UID %d",
3005 ses->Suid, smb_buffer_response->Uid)); 3119 ses->Suid, smb_buffer_response->Uid));
3006 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */ 3120 /* UID left in wire format */
3007 bcc_ptr = pByteArea(smb_buffer_response); 3121 ses->Suid = smb_buffer_response->Uid;
3008 /* response can have either 3 or 4 word count - Samba sends 3 */ 3122 bcc_ptr = pByteArea(smb_buffer_response);
3123 /* response can have either 3 or 4 word count - Samba sends 3 */
3009 if ((pSMBr->resp.hdr.WordCount == 3) 3124 if ((pSMBr->resp.hdr.WordCount == 3)
3010 || ((pSMBr->resp.hdr.WordCount == 4) 3125 || ((pSMBr->resp.hdr.WordCount == 4)
3011 && (blob_len < 3126 && (blob_len <
@@ -3035,7 +3150,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3035/* We look for obvious messed up bcc or strings in response so we do not go off 3150/* We look for obvious messed up bcc or strings in response so we do not go off
3036 the end since (at least) WIN2K and Windows XP have a major bug in not null 3151 the end since (at least) WIN2K and Windows XP have a major bug in not null
3037 terminating last Unicode string in response */ 3152 terminating last Unicode string in response */
3038 if(ses->serverOS) 3153 if (ses->serverOS)
3039 kfree(ses->serverOS); 3154 kfree(ses->serverOS);
3040 ses->serverOS = 3155 ses->serverOS =
3041 kzalloc(2 * (len + 1), GFP_KERNEL); 3156 kzalloc(2 * (len + 1), GFP_KERNEL);
@@ -3067,9 +3182,9 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3067 ses->serverNOS[1+(2*len)] = 0; 3182 ses->serverNOS[1+(2*len)] = 0;
3068 remaining_words -= len + 1; 3183 remaining_words -= len + 1;
3069 if (remaining_words > 0) { 3184 if (remaining_words > 0) {
3070 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 3185 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3071 /* last string not always null terminated (e.g. for Windows XP & 2000) */ 3186 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3072 if(ses->serverDomain) 3187 if (ses->serverDomain)
3073 kfree(ses->serverDomain); 3188 kfree(ses->serverDomain);
3074 ses->serverDomain = 3189 ses->serverDomain =
3075 kzalloc(2 * 3190 kzalloc(2 *
@@ -3097,12 +3212,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3097 = 0; 3212 = 0;
3098 } /* else no more room so create dummy domain string */ 3213 } /* else no more room so create dummy domain string */
3099 else { 3214 else {
3100 if(ses->serverDomain) 3215 if (ses->serverDomain)
3101 kfree(ses->serverDomain); 3216 kfree(ses->serverDomain);
3102 ses->serverDomain = kzalloc(2,GFP_KERNEL); 3217 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3103 } 3218 }
3104 } else { /* no room so create dummy domain and NOS string */ 3219 } else { /* no room so create dummy domain and NOS string */
3105 if(ses->serverDomain) 3220 if (ses->serverDomain)
3106 kfree(ses->serverDomain); 3221 kfree(ses->serverDomain);
3107 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3222 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3108 kfree(ses->serverNOS); 3223 kfree(ses->serverNOS);
@@ -3110,10 +3225,10 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3110 } 3225 }
3111 } else { /* ASCII */ 3226 } else { /* ASCII */
3112 len = strnlen(bcc_ptr, 1024); 3227 len = strnlen(bcc_ptr, 1024);
3113 if (((long) bcc_ptr + len) - 3228 if (((long) bcc_ptr + len) -
3114 (long) pByteArea(smb_buffer_response) 3229 (long) pByteArea(smb_buffer_response)
3115 <= BCC(smb_buffer_response)) { 3230 <= BCC(smb_buffer_response)) {
3116 if(ses->serverOS) 3231 if (ses->serverOS)
3117 kfree(ses->serverOS); 3232 kfree(ses->serverOS);
3118 ses->serverOS = kzalloc(len + 1,GFP_KERNEL); 3233 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3119 strncpy(ses->serverOS,bcc_ptr, len); 3234 strncpy(ses->serverOS,bcc_ptr, len);
@@ -3124,28 +3239,35 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3124 3239
3125 len = strnlen(bcc_ptr, 1024); 3240 len = strnlen(bcc_ptr, 1024);
3126 kfree(ses->serverNOS); 3241 kfree(ses->serverNOS);
3127 ses->serverNOS = kzalloc(len+1,GFP_KERNEL); 3242 ses->serverNOS = kzalloc(len+1,
3128 strncpy(ses->serverNOS, bcc_ptr, len); 3243 GFP_KERNEL);
3244 strncpy(ses->serverNOS,
3245 bcc_ptr, len);
3129 bcc_ptr += len; 3246 bcc_ptr += len;
3130 bcc_ptr[0] = 0; 3247 bcc_ptr[0] = 0;
3131 bcc_ptr++; 3248 bcc_ptr++;
3132 3249
3133 len = strnlen(bcc_ptr, 1024); 3250 len = strnlen(bcc_ptr, 1024);
3134 if(ses->serverDomain) 3251 if (ses->serverDomain)
3135 kfree(ses->serverDomain); 3252 kfree(ses->serverDomain);
3136 ses->serverDomain = kzalloc(len+1,GFP_KERNEL); 3253 ses->serverDomain =
3137 strncpy(ses->serverDomain, bcc_ptr, len); 3254 kzalloc(len+1,
3255 GFP_KERNEL);
3256 strncpy(ses->serverDomain,
3257 bcc_ptr, len);
3138 bcc_ptr += len; 3258 bcc_ptr += len;
3139 bcc_ptr[0] = 0; 3259 bcc_ptr[0] = 0;
3140 bcc_ptr++; 3260 bcc_ptr++;
3141 } else 3261 } else
3142 cFYI(1, 3262 cFYI(1,
3143 ("Variable field of length %d extends beyond end of smb ", 3263 ("field of length %d "
3264 "extends beyond end of smb ",
3144 len)); 3265 len));
3145 } 3266 }
3146 } else { 3267 } else {
3147 cERROR(1, 3268 cERROR(1,
3148 (" Security Blob Length extends beyond end of SMB")); 3269 (" Security Blob extends beyond end "
3270 "of SMB"));
3149 } 3271 }
3150 } else { 3272 } else {
3151 cERROR(1, ("No session structure passed in.")); 3273 cERROR(1, ("No session structure passed in."));
@@ -3197,7 +3319,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3197 pSMB->AndXCommand = 0xFF; 3319 pSMB->AndXCommand = 0xFF;
3198 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 3320 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3199 bcc_ptr = &pSMB->Password[0]; 3321 bcc_ptr = &pSMB->Password[0];
3200 if((ses->server->secMode) & SECMODE_USER) { 3322 if ((ses->server->secMode) & SECMODE_USER) {
3201 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3323 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3202 *bcc_ptr = 0; /* password is null byte */ 3324 *bcc_ptr = 0; /* password is null byte */
3203 bcc_ptr++; /* skip password */ 3325 bcc_ptr++; /* skip password */
@@ -3211,7 +3333,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3211 by Samba (not sure whether other servers allow 3333 by Samba (not sure whether other servers allow
3212 NTLMv2 password here) */ 3334 NTLMv2 password here) */
3213#ifdef CONFIG_CIFS_WEAK_PW_HASH 3335#ifdef CONFIG_CIFS_WEAK_PW_HASH
3214 if((extended_security & CIFSSEC_MAY_LANMAN) && 3336 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3215 (ses->server->secType == LANMAN)) 3337 (ses->server->secType == LANMAN))
3216 calc_lanman_hash(ses, bcc_ptr); 3338 calc_lanman_hash(ses, bcc_ptr);
3217 else 3339 else
@@ -3221,14 +3343,14 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3221 bcc_ptr); 3343 bcc_ptr);
3222 3344
3223 bcc_ptr += CIFS_SESS_KEY_SIZE; 3345 bcc_ptr += CIFS_SESS_KEY_SIZE;
3224 if(ses->capabilities & CAP_UNICODE) { 3346 if (ses->capabilities & CAP_UNICODE) {
3225 /* must align unicode strings */ 3347 /* must align unicode strings */
3226 *bcc_ptr = 0; /* null byte password */ 3348 *bcc_ptr = 0; /* null byte password */
3227 bcc_ptr++; 3349 bcc_ptr++;
3228 } 3350 }
3229 } 3351 }
3230 3352
3231 if(ses->server->secMode & 3353 if (ses->server->secMode &
3232 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3354 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3233 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3355 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3234 3356
@@ -3241,8 +3363,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3241 if (ses->capabilities & CAP_UNICODE) { 3363 if (ses->capabilities & CAP_UNICODE) {
3242 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 3364 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3243 length = 3365 length =
3244 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 3366 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3245 6 /* max utf8 char length in bytes */ * 3367 6 /* max utf8 char length in bytes */ *
3246 (/* server len*/ + 256 /* share len */), nls_codepage); 3368 (/* server len*/ + 256 /* share len */), nls_codepage);
3247 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */ 3369 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3248 bcc_ptr += 2; /* skip trailing null */ 3370 bcc_ptr += 2; /* skip trailing null */
@@ -3266,8 +3388,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3266 tcon->tid = smb_buffer_response->Tid; 3388 tcon->tid = smb_buffer_response->Tid;
3267 bcc_ptr = pByteArea(smb_buffer_response); 3389 bcc_ptr = pByteArea(smb_buffer_response);
3268 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); 3390 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3269 /* skip service field (NB: this field is always ASCII) */ 3391 /* skip service field (NB: this field is always ASCII) */
3270 bcc_ptr += length + 1; 3392 bcc_ptr += length + 1;
3271 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 3393 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3272 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { 3394 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3273 length = UniStrnlen((wchar_t *) bcc_ptr, 512); 3395 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
@@ -3285,7 +3407,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3285 bcc_ptr[1] = 0; 3407 bcc_ptr[1] = 0;
3286 bcc_ptr += 2; 3408 bcc_ptr += 2;
3287 } 3409 }
3288 /* else do not bother copying these informational fields */ 3410 /* else do not bother copying these information fields*/
3289 } else { 3411 } else {
3290 length = strnlen(bcc_ptr, 1024); 3412 length = strnlen(bcc_ptr, 1024);
3291 if ((bcc_ptr + length) - 3413 if ((bcc_ptr + length) -
@@ -3297,9 +3419,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3297 strncpy(tcon->nativeFileSystem, bcc_ptr, 3419 strncpy(tcon->nativeFileSystem, bcc_ptr,
3298 length); 3420 length);
3299 } 3421 }
3300 /* else do not bother copying these informational fields */ 3422 /* else do not bother copying these information fields*/
3301 } 3423 }
3302 if((smb_buffer_response->WordCount == 3) || 3424 if ((smb_buffer_response->WordCount == 3) ||
3303 (smb_buffer_response->WordCount == 7)) 3425 (smb_buffer_response->WordCount == 7))
3304 /* field is in same location */ 3426 /* field is in same location */
3305 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3427 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
@@ -3307,7 +3429,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3307 tcon->Flags = 0; 3429 tcon->Flags = 0;
3308 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); 3430 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3309 } else if ((rc == 0) && tcon == NULL) { 3431 } else if ((rc == 0) && tcon == NULL) {
3310 /* all we need to save for IPC$ connection */ 3432 /* all we need to save for IPC$ connection */
3311 ses->ipc_tid = smb_buffer_response->Tid; 3433 ses->ipc_tid = smb_buffer_response->Tid;
3312 } 3434 }
3313 3435
@@ -3323,7 +3445,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3323 int xid; 3445 int xid;
3324 struct cifsSesInfo *ses = NULL; 3446 struct cifsSesInfo *ses = NULL;
3325 struct task_struct *cifsd_task; 3447 struct task_struct *cifsd_task;
3326 char * tmp; 3448 char *tmp;
3327 3449
3328 xid = GetXid(); 3450 xid = GetXid();
3329 3451
@@ -3344,9 +3466,9 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3344 FreeXid(xid); 3466 FreeXid(xid);
3345 return 0; 3467 return 0;
3346 } else if (rc == -ESHUTDOWN) { 3468 } else if (rc == -ESHUTDOWN) {
3347 cFYI(1,("Waking up socket by sending it signal")); 3469 cFYI(1, ("Waking up socket by sending signal"));
3348 if (cifsd_task) { 3470 if (cifsd_task) {
3349 send_sig(SIGKILL,cifsd_task,1); 3471 force_sig(SIGKILL, cifsd_task);
3350 kthread_stop(cifsd_task); 3472 kthread_stop(cifsd_task);
3351 } 3473 }
3352 rc = 0; 3474 rc = 0;
@@ -3355,7 +3477,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3355 } else 3477 } else
3356 cFYI(1, ("No session or bad tcon")); 3478 cFYI(1, ("No session or bad tcon"));
3357 } 3479 }
3358 3480
3359 cifs_sb->tcon = NULL; 3481 cifs_sb->tcon = NULL;
3360 tmp = cifs_sb->prepath; 3482 tmp = cifs_sb->prepath;
3361 cifs_sb->prepathlen = 0; 3483 cifs_sb->prepathlen = 0;
@@ -3367,11 +3489,11 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3367 sesInfoFree(ses); 3489 sesInfoFree(ses);
3368 3490
3369 FreeXid(xid); 3491 FreeXid(xid);
3370 return rc; /* BB check if we should always return zero here */ 3492 return rc; /* BB check if we should always return zero here */
3371} 3493}
3372 3494
3373int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 3495int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3374 struct nls_table * nls_info) 3496 struct nls_table *nls_info)
3375{ 3497{
3376 int rc = 0; 3498 int rc = 0;
3377 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 3499 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
@@ -3379,16 +3501,16 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3379 int first_time = 0; 3501 int first_time = 0;
3380 3502
3381 /* what if server changes its buffer size after dropping the session? */ 3503 /* what if server changes its buffer size after dropping the session? */
3382 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { 3504 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3383 rc = CIFSSMBNegotiate(xid, pSesInfo); 3505 rc = CIFSSMBNegotiate(xid, pSesInfo);
3384 if(rc == -EAGAIN) /* retry only once on 1st time connection */ { 3506 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3385 rc = CIFSSMBNegotiate(xid, pSesInfo); 3507 rc = CIFSSMBNegotiate(xid, pSesInfo);
3386 if(rc == -EAGAIN) 3508 if (rc == -EAGAIN)
3387 rc = -EHOSTDOWN; 3509 rc = -EHOSTDOWN;
3388 } 3510 }
3389 if(rc == 0) { 3511 if (rc == 0) {
3390 spin_lock(&GlobalMid_Lock); 3512 spin_lock(&GlobalMid_Lock);
3391 if(pSesInfo->server->tcpStatus != CifsExiting) 3513 if (pSesInfo->server->tcpStatus != CifsExiting)
3392 pSesInfo->server->tcpStatus = CifsGood; 3514 pSesInfo->server->tcpStatus = CifsGood;
3393 else 3515 else
3394 rc = -EHOSTDOWN; 3516 rc = -EHOSTDOWN;
@@ -3400,18 +3522,19 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3400 if (!rc) { 3522 if (!rc) {
3401 pSesInfo->flags = 0; 3523 pSesInfo->flags = 0;
3402 pSesInfo->capabilities = pSesInfo->server->capabilities; 3524 pSesInfo->capabilities = pSesInfo->server->capabilities;
3403 if(linuxExtEnabled == 0) 3525 if (linuxExtEnabled == 0)
3404 pSesInfo->capabilities &= (~CAP_UNIX); 3526 pSesInfo->capabilities &= (~CAP_UNIX);
3405 /* pSesInfo->sequence_number = 0;*/ 3527 /* pSesInfo->sequence_number = 0;*/
3406 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3528 cFYI(1,
3529 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3407 pSesInfo->server->secMode, 3530 pSesInfo->server->secMode,
3408 pSesInfo->server->capabilities, 3531 pSesInfo->server->capabilities,
3409 pSesInfo->server->timeAdj)); 3532 pSesInfo->server->timeAdj));
3410 if(experimEnabled < 2) 3533 if (experimEnabled < 2)
3411 rc = CIFS_SessSetup(xid, pSesInfo, 3534 rc = CIFS_SessSetup(xid, pSesInfo,
3412 first_time, nls_info); 3535 first_time, nls_info);
3413 else if (extended_security 3536 else if (extended_security
3414 && (pSesInfo->capabilities 3537 && (pSesInfo->capabilities
3415 & CAP_EXTENDED_SECURITY) 3538 & CAP_EXTENDED_SECURITY)
3416 && (pSesInfo->server->secType == NTLMSSP)) { 3539 && (pSesInfo->server->secType == NTLMSSP)) {
3417 rc = -EOPNOTSUPP; 3540 rc = -EOPNOTSUPP;
@@ -3424,21 +3547,22 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3424 &ntlmv2_flag, 3547 &ntlmv2_flag,
3425 nls_info); 3548 nls_info);
3426 if (!rc) { 3549 if (!rc) {
3427 if(ntlmv2_flag) { 3550 if (ntlmv2_flag) {
3428 char * v2_response; 3551 char *v2_response;
3429 cFYI(1,("more secure NTLM ver2 hash")); 3552 cFYI(1, ("more secure NTLM ver2 hash"));
3430 if(CalcNTLMv2_partial_mac_key(pSesInfo, 3553 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3431 nls_info)) { 3554 nls_info)) {
3432 rc = -ENOMEM; 3555 rc = -ENOMEM;
3433 goto ss_err_exit; 3556 goto ss_err_exit;
3434 } else 3557 } else
3435 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); 3558 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3436 if(v2_response) { 3559 if (v2_response) {
3437 CalcNTLMv2_response(pSesInfo,v2_response); 3560 CalcNTLMv2_response(pSesInfo,
3438 /* if(first_time) 3561 v2_response);
3439 cifs_calculate_ntlmv2_mac_key( 3562 /* if (first_time)
3440 pSesInfo->server->mac_signing_key, 3563 cifs_calculate_ntlmv2_mac_key(
3441 response, ntlm_session_key, */ 3564 pSesInfo->server->mac_signing_key,
3565 response, ntlm_session_key,*/
3442 kfree(v2_response); 3566 kfree(v2_response);
3443 /* BB Put dummy sig in SessSetup PDU? */ 3567 /* BB Put dummy sig in SessSetup PDU? */
3444 } else { 3568 } else {
@@ -3451,9 +3575,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3451 pSesInfo->server->cryptKey, 3575 pSesInfo->server->cryptKey,
3452 ntlm_session_key); 3576 ntlm_session_key);
3453 3577
3454 if(first_time) 3578 if (first_time)
3455 cifs_calculate_mac_key( 3579 cifs_calculate_mac_key(
3456 pSesInfo->server->mac_signing_key, 3580 &pSesInfo->server->mac_signing_key,
3457 ntlm_session_key, 3581 ntlm_session_key,
3458 pSesInfo->password); 3582 pSesInfo->password);
3459 } 3583 }
@@ -3471,18 +3595,18 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3471 pSesInfo->server->cryptKey, 3595 pSesInfo->server->cryptKey,
3472 ntlm_session_key); 3596 ntlm_session_key);
3473 3597
3474 if(first_time) 3598 if (first_time)
3475 cifs_calculate_mac_key( 3599 cifs_calculate_mac_key(
3476 pSesInfo->server->mac_signing_key, 3600 &pSesInfo->server->mac_signing_key,
3477 ntlm_session_key, pSesInfo->password); 3601 ntlm_session_key, pSesInfo->password);
3478 3602
3479 rc = CIFSSessSetup(xid, pSesInfo, 3603 rc = CIFSSessSetup(xid, pSesInfo,
3480 ntlm_session_key, nls_info); 3604 ntlm_session_key, nls_info);
3481 } 3605 }
3482 if (rc) { 3606 if (rc) {
3483 cERROR(1,("Send error in SessSetup = %d",rc)); 3607 cERROR(1, ("Send error in SessSetup = %d", rc));
3484 } else { 3608 } else {
3485 cFYI(1,("CIFS Session Established successfully")); 3609 cFYI(1, ("CIFS Session Established successfully"));
3486 pSesInfo->status = CifsGood; 3610 pSesInfo->status = CifsGood;
3487 } 3611 }
3488 } 3612 }
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 8e86aaceb68a..4830acc86d74 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -135,10 +135,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
135 struct cifs_sb_info *cifs_sb; 135 struct cifs_sb_info *cifs_sb;
136 struct cifsTconInfo *pTcon; 136 struct cifsTconInfo *pTcon;
137 char *full_path = NULL; 137 char *full_path = NULL;
138 FILE_ALL_INFO * buf = NULL; 138 FILE_ALL_INFO *buf = NULL;
139 struct inode *newinode = NULL; 139 struct inode *newinode = NULL;
140 struct cifsFileInfo * pCifsFile = NULL; 140 struct cifsFileInfo *pCifsFile = NULL;
141 struct cifsInodeInfo * pCifsInode; 141 struct cifsInodeInfo *pCifsInode;
142 int disposition = FILE_OVERWRITE_IF; 142 int disposition = FILE_OVERWRITE_IF;
143 int write_only = FALSE; 143 int write_only = FALSE;
144 144
@@ -207,8 +207,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
207 } else { 207 } else {
208 /* If Open reported that we actually created a file 208 /* If Open reported that we actually created a file
209 then we now have to set the mode if possible */ 209 then we now have to set the mode if possible */
210 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && 210 if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
211 (oplock & CIFS_CREATE_ACTION)) {
212 mode &= ~current->fs->umask; 211 mode &= ~current->fs->umask;
213 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 212 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
214 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 213 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -235,8 +234,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
235 /* Could set r/o dos attribute if mode & 0222 == 0 */ 234 /* Could set r/o dos attribute if mode & 0222 == 0 */
236 } 235 }
237 236
238 /* BB server might mask mode so we have to query for Unix case*/ 237 /* server might mask mode so we have to query for it */
239 if (pTcon->ses->capabilities & CAP_UNIX) 238 if (pTcon->unix_ext)
240 rc = cifs_get_inode_info_unix(&newinode, full_path, 239 rc = cifs_get_inode_info_unix(&newinode, full_path,
241 inode->i_sb, xid); 240 inode->i_sb, xid);
242 else { 241 else {
@@ -264,7 +263,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
264 direntry->d_op = &cifs_dentry_ops; 263 direntry->d_op = &cifs_dentry_ops;
265 d_instantiate(direntry, newinode); 264 d_instantiate(direntry, newinode);
266 } 265 }
267 if ((nd->flags & LOOKUP_OPEN) == FALSE) { 266 if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
267 ((nd->flags & LOOKUP_OPEN) == FALSE)) {
268 /* mknod case - do not leave file open */ 268 /* mknod case - do not leave file open */
269 CIFSSMBClose(xid, pTcon, fileHandle); 269 CIFSSMBClose(xid, pTcon, fileHandle);
270 } else if (newinode) { 270 } else if (newinode) {
@@ -323,7 +323,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
323 struct cifs_sb_info *cifs_sb; 323 struct cifs_sb_info *cifs_sb;
324 struct cifsTconInfo *pTcon; 324 struct cifsTconInfo *pTcon;
325 char *full_path = NULL; 325 char *full_path = NULL;
326 struct inode * newinode = NULL; 326 struct inode *newinode = NULL;
327 327
328 if (!old_valid_dev(device_number)) 328 if (!old_valid_dev(device_number))
329 return -EINVAL; 329 return -EINVAL;
@@ -336,7 +336,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
336 full_path = build_path_from_dentry(direntry); 336 full_path = build_path_from_dentry(direntry);
337 if (full_path == NULL) 337 if (full_path == NULL)
338 rc = -ENOMEM; 338 rc = -ENOMEM;
339 else if (pTcon->ses->capabilities & CAP_UNIX) { 339 else if (pTcon->unix_ext) {
340 mode &= ~current->fs->umask; 340 mode &= ~current->fs->umask;
341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 342 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -490,7 +490,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
490 cFYI(1, 490 cFYI(1,
491 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 491 (" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
492 492
493 if (pTcon->ses->capabilities & CAP_UNIX) 493 if (pTcon->unix_ext)
494 rc = cifs_get_inode_info_unix(&newInode, full_path, 494 rc = cifs_get_inode_info_unix(&newInode, full_path,
495 parent_dir_inode->i_sb, xid); 495 parent_dir_inode->i_sb, xid);
496 else 496 else
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 96df1d51fdc3..893fd0aebff8 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -5,7 +5,7 @@
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Common Internet FileSystem (CIFS) client 7 * Common Internet FileSystem (CIFS) client
8 * 8 *
9 * Operations related to support for exporting files via NFSD 9 * Operations related to support for exporting files via NFSD
10 * 10 *
11 * This library is free software; you can redistribute it and/or modify 11 * This library is free software; you can redistribute it and/or modify
@@ -22,32 +22,45 @@
22 * along with this library; if not, write to the Free Software 22 * along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 25
26 /* 26 /*
27 * See Documentation/filesystems/Exporting 27 * See Documentation/filesystems/Exporting
28 * and examples in fs/exportfs 28 * and examples in fs/exportfs
29 *
30 * Since cifs is a network file system, an "fsid" must be included for
31 * any nfs exports file entries which refer to cifs paths. In addition
32 * the cifs mount must be mounted with the "serverino" option (ie use stable
33 * server inode numbers instead of locally generated temporary ones).
34 * Although cifs inodes do not use generation numbers (have generation number
35 * of zero) - the inode number alone should be good enough for simple cases
36 * in which users want to export cifs shares with NFS. The decode and encode
37 * could be improved by using a new routine which expects 64 bit inode numbers
38 * instead of the default 32 bit routines in fs/exportfs
39 *
29 */ 40 */
30 41
31#include <linux/fs.h> 42#include <linux/fs.h>
32#include <linux/exportfs.h> 43#include <linux/exportfs.h>
33 44#include "cifsglob.h"
45#include "cifs_debug.h"
46
34#ifdef CONFIG_CIFS_EXPERIMENTAL 47#ifdef CONFIG_CIFS_EXPERIMENTAL
35
36static struct dentry *cifs_get_parent(struct dentry *dentry) 48static struct dentry *cifs_get_parent(struct dentry *dentry)
37{ 49{
38 /* BB need to add code here eventually to enable export via NFSD */ 50 /* BB need to add code here eventually to enable export via NFSD */
39 return ERR_PTR(-EACCES); 51 cFYI(1, ("get parent for %p", dentry));
52 return ERR_PTR(-EACCES);
40} 53}
41 54
42struct export_operations cifs_export_ops = { 55struct export_operations cifs_export_ops = {
43 .get_parent = cifs_get_parent, 56 .get_parent = cifs_get_parent,
44/* Following five export operations are unneeded so far and can default */ 57/* Following five export operations are unneeded so far and can default:
45/* .get_dentry = 58 .get_dentry =
46 .get_name = 59 .get_name =
47 .find_exported_dentry = 60 .find_exported_dentry =
48 .decode_fh = 61 .decode_fh =
49 .encode_fs = */ 62 .encode_fs = */
50 }; 63};
51 64
52#endif /* EXPERIMENTAL */ 65#endif /* EXPERIMENTAL */
53 66
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 8e375bb4b379..995474c90885 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -66,7 +66,7 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
66 return cifs_ntfy_flags; 66 return cifs_ntfy_flags;
67} 67}
68 68
69int cifs_dir_notify(struct file * file, unsigned long arg) 69int cifs_dir_notify(struct file *file, unsigned long arg)
70{ 70{
71 int xid; 71 int xid;
72 int rc = -EINVAL; 72 int rc = -EINVAL;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 94d5b49049df..e13592afca9c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2,8 +2,8 @@
2 * fs/cifs/file.c 2 * fs/cifs/file.c
3 * 3 *
4 * vfs operations that deal with files 4 * vfs operations that deal with files
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2002,2003 6 * Copyright (C) International Business Machines Corp., 2002,2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * Jeremy Allison (jra@samba.org) 8 * Jeremy Allison (jra@samba.org)
9 * 9 *
@@ -45,7 +45,7 @@ static inline struct cifsFileInfo *cifs_init_private(
45{ 45{
46 memset(private_data, 0, sizeof(struct cifsFileInfo)); 46 memset(private_data, 0, sizeof(struct cifsFileInfo));
47 private_data->netfid = netfid; 47 private_data->netfid = netfid;
48 private_data->pid = current->tgid; 48 private_data->pid = current->tgid;
49 init_MUTEX(&private_data->fh_sem); 49 init_MUTEX(&private_data->fh_sem);
50 mutex_init(&private_data->lock_mutex); 50 mutex_init(&private_data->lock_mutex);
51 INIT_LIST_HEAD(&private_data->llist); 51 INIT_LIST_HEAD(&private_data->llist);
@@ -57,7 +57,7 @@ static inline struct cifsFileInfo *cifs_init_private(
57 does not tell us which handle the write is for so there can 57 does not tell us which handle the write is for so there can
58 be a close (overlapping with write) of the filehandle that 58 be a close (overlapping with write) of the filehandle that
59 cifs_writepages chose to use */ 59 cifs_writepages chose to use */
60 atomic_set(&private_data->wrtPending,0); 60 atomic_set(&private_data->wrtPending, 0);
61 61
62 return private_data; 62 return private_data;
63} 63}
@@ -105,7 +105,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
105 in the list so we do not have to walk the 105 in the list so we do not have to walk the
106 list to search for one in prepare_write */ 106 list to search for one in prepare_write */
107 if ((file->f_flags & O_ACCMODE) == O_WRONLY) { 107 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
108 list_add_tail(&pCifsFile->flist, 108 list_add_tail(&pCifsFile->flist,
109 &pCifsInode->openFileList); 109 &pCifsInode->openFileList);
110 } else { 110 } else {
111 list_add(&pCifsFile->flist, 111 list_add(&pCifsFile->flist,
@@ -138,7 +138,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
138 } 138 }
139 139
140client_can_cache: 140client_can_cache:
141 if (pTcon->ses->capabilities & CAP_UNIX) 141 if (pTcon->unix_ext)
142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, 142 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode,
143 full_path, inode->i_sb, xid); 143 full_path, inode->i_sb, xid);
144 else 144 else
@@ -189,7 +189,7 @@ int cifs_open(struct inode *inode, struct file *file)
189 189
190 /* needed for writepage */ 190 /* needed for writepage */
191 pCifsFile->pfile = file; 191 pCifsFile->pfile = file;
192 192
193 file->private_data = pCifsFile; 193 file->private_data = pCifsFile;
194 break; 194 break;
195 } 195 }
@@ -212,15 +212,15 @@ int cifs_open(struct inode *inode, struct file *file)
212 return -ENOMEM; 212 return -ENOMEM;
213 } 213 }
214 214
215 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", 215 cFYI(1, ("inode = 0x%p file flags are 0x%x for %s",
216 inode, file->f_flags, full_path)); 216 inode, file->f_flags, full_path));
217 desiredAccess = cifs_convert_flags(file->f_flags); 217 desiredAccess = cifs_convert_flags(file->f_flags);
218 218
219/********************************************************************* 219/*********************************************************************
220 * open flag mapping table: 220 * open flag mapping table:
221 * 221 *
222 * POSIX Flag CIFS Disposition 222 * POSIX Flag CIFS Disposition
223 * ---------- ---------------- 223 * ---------- ----------------
224 * O_CREAT FILE_OPEN_IF 224 * O_CREAT FILE_OPEN_IF
225 * O_CREAT | O_EXCL FILE_CREATE 225 * O_CREAT | O_EXCL FILE_CREATE
226 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF 226 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
@@ -228,12 +228,12 @@ int cifs_open(struct inode *inode, struct file *file)
228 * none of the above FILE_OPEN 228 * none of the above FILE_OPEN
229 * 229 *
230 * Note that there is not a direct match between disposition 230 * Note that there is not a direct match between disposition
231 * FILE_SUPERSEDE (ie create whether or not file exists although 231 * FILE_SUPERSEDE (ie create whether or not file exists although
232 * O_CREAT | O_TRUNC is similar but truncates the existing 232 * O_CREAT | O_TRUNC is similar but truncates the existing
233 * file rather than creating a new file as FILE_SUPERSEDE does 233 * file rather than creating a new file as FILE_SUPERSEDE does
234 * (which uses the attributes / metadata passed in on open call) 234 * (which uses the attributes / metadata passed in on open call)
235 *? 235 *?
236 *? O_SYNC is a reasonable match to CIFS writethrough flag 236 *? O_SYNC is a reasonable match to CIFS writethrough flag
237 *? and the read write flags match reasonably. O_LARGEFILE 237 *? and the read write flags match reasonably. O_LARGEFILE
238 *? is irrelevant because largefile support is always used 238 *? is irrelevant because largefile support is always used
239 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, 239 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
@@ -253,8 +253,8 @@ int cifs_open(struct inode *inode, struct file *file)
253 and calling get_inode_info with returned buf (at least helps 253 and calling get_inode_info with returned buf (at least helps
254 non-Unix server case) */ 254 non-Unix server case) */
255 255
256 /* BB we can not do this if this is the second open of a file 256 /* BB we can not do this if this is the second open of a file
257 and the first handle has writebehind data, we might be 257 and the first handle has writebehind data, we might be
258 able to simply do a filemap_fdatawrite/filemap_fdatawait first */ 258 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
259 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 259 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
260 if (!buf) { 260 if (!buf) {
@@ -263,7 +263,7 @@ int cifs_open(struct inode *inode, struct file *file)
263 } 263 }
264 264
265 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 265 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
266 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 266 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
267 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, 267 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
268 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 268 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
269 & CIFS_MOUNT_MAP_SPECIAL_CHR); 269 & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -300,15 +300,15 @@ int cifs_open(struct inode *inode, struct file *file)
300 write_unlock(&GlobalSMBSeslock); 300 write_unlock(&GlobalSMBSeslock);
301 } 301 }
302 302
303 if (oplock & CIFS_CREATE_ACTION) { 303 if (oplock & CIFS_CREATE_ACTION) {
304 /* time to set mode which we can not set earlier due to 304 /* time to set mode which we can not set earlier due to
305 problems creating new read-only files */ 305 problems creating new read-only files */
306 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 306 if (pTcon->unix_ext) {
307 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 307 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
308 inode->i_mode, 308 inode->i_mode,
309 (__u64)-1, (__u64)-1, 0 /* dev */, 309 (__u64)-1, (__u64)-1, 0 /* dev */,
310 cifs_sb->local_nls, 310 cifs_sb->local_nls,
311 cifs_sb->mnt_cifs_flags & 311 cifs_sb->mnt_cifs_flags &
312 CIFS_MOUNT_MAP_SPECIAL_CHR); 312 CIFS_MOUNT_MAP_SPECIAL_CHR);
313 } else { 313 } else {
314 /* BB implement via Windows security descriptors eg 314 /* BB implement via Windows security descriptors eg
@@ -345,7 +345,7 @@ static int cifs_reopen_file(struct file *file, int can_flush)
345 struct cifsTconInfo *pTcon; 345 struct cifsTconInfo *pTcon;
346 struct cifsFileInfo *pCifsFile; 346 struct cifsFileInfo *pCifsFile;
347 struct cifsInodeInfo *pCifsInode; 347 struct cifsInodeInfo *pCifsInode;
348 struct inode * inode; 348 struct inode *inode;
349 char *full_path = NULL; 349 char *full_path = NULL;
350 int desiredAccess; 350 int desiredAccess;
351 int disposition = FILE_OPEN; 351 int disposition = FILE_OPEN;
@@ -372,13 +372,13 @@ static int cifs_reopen_file(struct file *file, int can_flush)
372 } 372 }
373 373
374 inode = file->f_path.dentry->d_inode; 374 inode = file->f_path.dentry->d_inode;
375 if(inode == NULL) { 375 if (inode == NULL) {
376 cERROR(1, ("inode not valid")); 376 cERROR(1, ("inode not valid"));
377 dump_stack(); 377 dump_stack();
378 rc = -EBADF; 378 rc = -EBADF;
379 goto reopen_error_exit; 379 goto reopen_error_exit;
380 } 380 }
381 381
382 cifs_sb = CIFS_SB(inode->i_sb); 382 cifs_sb = CIFS_SB(inode->i_sb);
383 pTcon = cifs_sb->tcon; 383 pTcon = cifs_sb->tcon;
384 384
@@ -396,7 +396,7 @@ reopen_error_exit:
396 } 396 }
397 397
398 cFYI(1, ("inode = 0x%p file flags 0x%x for %s", 398 cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
399 inode, file->f_flags,full_path)); 399 inode, file->f_flags, full_path));
400 desiredAccess = cifs_convert_flags(file->f_flags); 400 desiredAccess = cifs_convert_flags(file->f_flags);
401 401
402 if (oplockEnabled) 402 if (oplockEnabled)
@@ -405,14 +405,14 @@ reopen_error_exit:
405 oplock = FALSE; 405 oplock = FALSE;
406 406
407 /* Can not refresh inode by passing in file_info buf to be returned 407 /* Can not refresh inode by passing in file_info buf to be returned
408 by SMBOpen and then calling get_inode_info with returned buf 408 by SMBOpen and then calling get_inode_info with returned buf
409 since file might have write behind data that needs to be flushed 409 since file might have write behind data that needs to be flushed
410 and server version of file size can be stale. If we knew for sure 410 and server version of file size can be stale. If we knew for sure
411 that inode was not dirty locally we could do this */ 411 that inode was not dirty locally we could do this */
412 412
413 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, 413 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
414 CREATE_NOT_DIR, &netfid, &oplock, NULL, 414 CREATE_NOT_DIR, &netfid, &oplock, NULL,
415 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 415 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
416 CIFS_MOUNT_MAP_SPECIAL_CHR); 416 CIFS_MOUNT_MAP_SPECIAL_CHR);
417 if (rc) { 417 if (rc) {
418 up(&pCifsFile->fh_sem); 418 up(&pCifsFile->fh_sem);
@@ -430,7 +430,7 @@ reopen_error_exit:
430 go to server to get inode info */ 430 go to server to get inode info */
431 pCifsInode->clientCanCacheAll = FALSE; 431 pCifsInode->clientCanCacheAll = FALSE;
432 pCifsInode->clientCanCacheRead = FALSE; 432 pCifsInode->clientCanCacheRead = FALSE;
433 if (pTcon->ses->capabilities & CAP_UNIX) 433 if (pTcon->unix_ext)
434 rc = cifs_get_inode_info_unix(&inode, 434 rc = cifs_get_inode_info_unix(&inode,
435 full_path, inode->i_sb, xid); 435 full_path, inode->i_sb, xid);
436 else 436 else
@@ -486,23 +486,24 @@ int cifs_close(struct inode *inode, struct file *file)
486 already closed */ 486 already closed */
487 if (pTcon->tidStatus != CifsNeedReconnect) { 487 if (pTcon->tidStatus != CifsNeedReconnect) {
488 int timeout = 2; 488 int timeout = 2;
489 while((atomic_read(&pSMBFile->wrtPending) != 0) 489 while ((atomic_read(&pSMBFile->wrtPending) != 0)
490 && (timeout < 1000) ) { 490 && (timeout < 1000) ) {
491 /* Give write a better chance to get to 491 /* Give write a better chance to get to
492 server ahead of the close. We do not 492 server ahead of the close. We do not
493 want to add a wait_q here as it would 493 want to add a wait_q here as it would
494 increase the memory utilization as 494 increase the memory utilization as
495 the struct would be in each open file, 495 the struct would be in each open file,
496 but this should give enough time to 496 but this should give enough time to
497 clear the socket */ 497 clear the socket */
498#ifdef CONFIG_CIFS_DEBUG2 498#ifdef CONFIG_CIFS_DEBUG2
499 cFYI(1,("close delay, write pending")); 499 cFYI(1, ("close delay, write pending"));
500#endif /* DEBUG2 */ 500#endif /* DEBUG2 */
501 msleep(timeout); 501 msleep(timeout);
502 timeout *= 4; 502 timeout *= 4;
503 } 503 }
504 if(atomic_read(&pSMBFile->wrtPending)) 504 if (atomic_read(&pSMBFile->wrtPending))
505 cERROR(1,("close with pending writes")); 505 cERROR(1,
506 ("close with pending writes"));
506 rc = CIFSSMBClose(xid, pTcon, 507 rc = CIFSSMBClose(xid, pTcon,
507 pSMBFile->netfid); 508 pSMBFile->netfid);
508 } 509 }
@@ -534,7 +535,7 @@ int cifs_close(struct inode *inode, struct file *file)
534 CIFS_I(inode)->clientCanCacheRead = FALSE; 535 CIFS_I(inode)->clientCanCacheRead = FALSE;
535 CIFS_I(inode)->clientCanCacheAll = FALSE; 536 CIFS_I(inode)->clientCanCacheAll = FALSE;
536 } 537 }
537 if ((rc ==0) && CIFS_I(inode)->write_behind_rc) 538 if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
538 rc = CIFS_I(inode)->write_behind_rc; 539 rc = CIFS_I(inode)->write_behind_rc;
539 FreeXid(xid); 540 FreeXid(xid);
540 return rc; 541 return rc;
@@ -554,7 +555,8 @@ int cifs_closedir(struct inode *inode, struct file *file)
554 555
555 if (pCFileStruct) { 556 if (pCFileStruct) {
556 struct cifsTconInfo *pTcon; 557 struct cifsTconInfo *pTcon;
557 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 558 struct cifs_sb_info *cifs_sb =
559 CIFS_SB(file->f_path.dentry->d_sb);
558 560
559 pTcon = cifs_sb->tcon; 561 pTcon = cifs_sb->tcon;
560 562
@@ -572,7 +574,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
572 if (ptmp) { 574 if (ptmp) {
573 cFYI(1, ("closedir free smb buf in srch struct")); 575 cFYI(1, ("closedir free smb buf in srch struct"));
574 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 576 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
575 if(pCFileStruct->srch_inf.smallBuf) 577 if (pCFileStruct->srch_inf.smallBuf)
576 cifs_small_buf_release(ptmp); 578 cifs_small_buf_release(ptmp);
577 else 579 else
578 cifs_buf_release(ptmp); 580 cifs_buf_release(ptmp);
@@ -594,7 +596,8 @@ int cifs_closedir(struct inode *inode, struct file *file)
594static int store_file_lock(struct cifsFileInfo *fid, __u64 len, 596static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
595 __u64 offset, __u8 lockType) 597 __u64 offset, __u8 lockType)
596{ 598{
597 struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); 599 struct cifsLockInfo *li =
600 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
598 if (li == NULL) 601 if (li == NULL)
599 return -ENOMEM; 602 return -ENOMEM;
600 li->offset = offset; 603 li->offset = offset;
@@ -625,8 +628,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
625 628
626 cFYI(1, ("Lock parm: 0x%x flockflags: " 629 cFYI(1, ("Lock parm: 0x%x flockflags: "
627 "0x%x flocktype: 0x%x start: %lld end: %lld", 630 "0x%x flocktype: 0x%x start: %lld end: %lld",
628 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, 631 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
629 pfLock->fl_end)); 632 pfLock->fl_end));
630 633
631 if (pfLock->fl_flags & FL_POSIX) 634 if (pfLock->fl_flags & FL_POSIX)
632 cFYI(1, ("Posix")); 635 cFYI(1, ("Posix"));
@@ -641,7 +644,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
641 "not implemented yet")); 644 "not implemented yet"));
642 if (pfLock->fl_flags & FL_LEASE) 645 if (pfLock->fl_flags & FL_LEASE)
643 cFYI(1, ("Lease on file - not implemented yet")); 646 cFYI(1, ("Lease on file - not implemented yet"));
644 if (pfLock->fl_flags & 647 if (pfLock->fl_flags &
645 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) 648 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
646 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); 649 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
647 650
@@ -683,9 +686,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
683 account for negative length which we can not accept over the 686 account for negative length which we can not accept over the
684 wire */ 687 wire */
685 if (IS_GETLK(cmd)) { 688 if (IS_GETLK(cmd)) {
686 if(posix_locking) { 689 if (posix_locking) {
687 int posix_lock_type; 690 int posix_lock_type;
688 if(lockType & LOCKING_ANDX_SHARED_LOCK) 691 if (lockType & LOCKING_ANDX_SHARED_LOCK)
689 posix_lock_type = CIFS_RDLCK; 692 posix_lock_type = CIFS_RDLCK;
690 else 693 else
691 posix_lock_type = CIFS_WRLCK; 694 posix_lock_type = CIFS_WRLCK;
@@ -700,7 +703,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
700 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 703 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
701 0, 1, lockType, 0 /* wait flag */ ); 704 0, 1, lockType, 0 /* wait flag */ );
702 if (rc == 0) { 705 if (rc == 0) {
703 rc = CIFSSMBLock(xid, pTcon, netfid, length, 706 rc = CIFSSMBLock(xid, pTcon, netfid, length,
704 pfLock->fl_start, 1 /* numUnlock */ , 707 pfLock->fl_start, 1 /* numUnlock */ ,
705 0 /* numLock */ , lockType, 708 0 /* numLock */ , lockType,
706 0 /* wait flag */ ); 709 0 /* wait flag */ );
@@ -729,22 +732,24 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
729 732
730 if (posix_locking) { 733 if (posix_locking) {
731 int posix_lock_type; 734 int posix_lock_type;
732 if(lockType & LOCKING_ANDX_SHARED_LOCK) 735 if (lockType & LOCKING_ANDX_SHARED_LOCK)
733 posix_lock_type = CIFS_RDLCK; 736 posix_lock_type = CIFS_RDLCK;
734 else 737 else
735 posix_lock_type = CIFS_WRLCK; 738 posix_lock_type = CIFS_WRLCK;
736 739
737 if(numUnlock == 1) 740 if (numUnlock == 1)
738 posix_lock_type = CIFS_UNLCK; 741 posix_lock_type = CIFS_UNLCK;
739 742
740 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, 743 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
741 length, pfLock, 744 length, pfLock,
742 posix_lock_type, wait_flag); 745 posix_lock_type, wait_flag);
743 } else { 746 } else {
744 struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data; 747 struct cifsFileInfo *fid =
748 (struct cifsFileInfo *)file->private_data;
745 749
746 if (numLock) { 750 if (numLock) {
747 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, 751 rc = CIFSSMBLock(xid, pTcon, netfid, length,
752 pfLock->fl_start,
748 0, numLock, lockType, wait_flag); 753 0, numLock, lockType, wait_flag);
749 754
750 if (rc == 0) { 755 if (rc == 0) {
@@ -763,7 +768,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
763 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 768 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
764 if (pfLock->fl_start <= li->offset && 769 if (pfLock->fl_start <= li->offset &&
765 length >= li->length) { 770 length >= li->length) {
766 stored_rc = CIFSSMBLock(xid, pTcon, netfid, 771 stored_rc = CIFSSMBLock(xid, pTcon,
772 netfid,
767 li->length, li->offset, 773 li->length, li->offset,
768 1, 0, li->type, FALSE); 774 1, 0, li->type, FALSE);
769 if (stored_rc) 775 if (stored_rc)
@@ -805,7 +811,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
805 if (file->private_data == NULL) 811 if (file->private_data == NULL)
806 return -EBADF; 812 return -EBADF;
807 open_file = (struct cifsFileInfo *) file->private_data; 813 open_file = (struct cifsFileInfo *) file->private_data;
808 814
809 xid = GetXid(); 815 xid = GetXid();
810 816
811 if (*poffset > file->f_path.dentry->d_inode->i_size) 817 if (*poffset > file->f_path.dentry->d_inode->i_size)
@@ -824,7 +830,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
824 and blocked, and the file has been freed on us while 830 and blocked, and the file has been freed on us while
825 we blocked so return what we managed to write */ 831 we blocked so return what we managed to write */
826 return total_written; 832 return total_written;
827 } 833 }
828 if (open_file->closePend) { 834 if (open_file->closePend) {
829 FreeXid(xid); 835 FreeXid(xid);
830 if (total_written) 836 if (total_written)
@@ -867,8 +873,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
867 /* since the write may have blocked check these pointers again */ 873 /* since the write may have blocked check these pointers again */
868 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { 874 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
869 struct inode *inode = file->f_path.dentry->d_inode; 875 struct inode *inode = file->f_path.dentry->d_inode;
870/* Do not update local mtime - server will set its actual value on write 876/* Do not update local mtime - server will set its actual value on write
871 * inode->i_ctime = inode->i_mtime = 877 * inode->i_ctime = inode->i_mtime =
872 * current_fs_time(inode->i_sb);*/ 878 * current_fs_time(inode->i_sb);*/
873 if (total_written > 0) { 879 if (total_written > 0) {
874 spin_lock(&inode->i_lock); 880 spin_lock(&inode->i_lock);
@@ -877,7 +883,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
877 *poffset); 883 *poffset);
878 spin_unlock(&inode->i_lock); 884 spin_unlock(&inode->i_lock);
879 } 885 }
880 mark_inode_dirty_sync(file->f_path.dentry->d_inode); 886 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
881 } 887 }
882 FreeXid(xid); 888 FreeXid(xid);
883 return total_written; 889 return total_written;
@@ -898,13 +904,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
898 904
899 pTcon = cifs_sb->tcon; 905 pTcon = cifs_sb->tcon;
900 906
901 cFYI(1,("write %zd bytes to offset %lld of %s", write_size, 907 cFYI(1, ("write %zd bytes to offset %lld of %s", write_size,
902 *poffset, file->f_path.dentry->d_name.name)); 908 *poffset, file->f_path.dentry->d_name.name));
903 909
904 if (file->private_data == NULL) 910 if (file->private_data == NULL)
905 return -EBADF; 911 return -EBADF;
906 open_file = (struct cifsFileInfo *)file->private_data; 912 open_file = (struct cifsFileInfo *)file->private_data;
907 913
908 xid = GetXid(); 914 xid = GetXid();
909 915
910 if (*poffset > file->f_path.dentry->d_inode->i_size) 916 if (*poffset > file->f_path.dentry->d_inode->i_size)
@@ -921,10 +927,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
921 FreeXid(xid); 927 FreeXid(xid);
922 /* if we have gotten here we have written some data 928 /* if we have gotten here we have written some data
923 and blocked, and the file has been freed on us 929 and blocked, and the file has been freed on us
924 while we blocked so return what we managed to 930 while we blocked so return what we managed to
925 write */ 931 write */
926 return total_written; 932 return total_written;
927 } 933 }
928 if (open_file->closePend) { 934 if (open_file->closePend) {
929 FreeXid(xid); 935 FreeXid(xid);
930 if (total_written) 936 if (total_written)
@@ -935,14 +941,14 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
935 if (open_file->invalidHandle) { 941 if (open_file->invalidHandle) {
936 /* we could deadlock if we called 942 /* we could deadlock if we called
937 filemap_fdatawait from here so tell 943 filemap_fdatawait from here so tell
938 reopen_file not to flush data to 944 reopen_file not to flush data to
939 server now */ 945 server now */
940 rc = cifs_reopen_file(file, FALSE); 946 rc = cifs_reopen_file(file, FALSE);
941 if (rc != 0) 947 if (rc != 0)
942 break; 948 break;
943 } 949 }
944 if(experimEnabled || (pTcon->ses->server && 950 if (experimEnabled || (pTcon->ses->server &&
945 ((pTcon->ses->server->secMode & 951 ((pTcon->ses->server->secMode &
946 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 952 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
947 == 0))) { 953 == 0))) {
948 struct kvec iov[2]; 954 struct kvec iov[2];
@@ -976,7 +982,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
976 } 982 }
977 } else 983 } else
978 *poffset += bytes_written; 984 *poffset += bytes_written;
979 long_op = FALSE; /* subsequent writes fast - 985 long_op = FALSE; /* subsequent writes fast -
980 15 seconds is plenty */ 986 15 seconds is plenty */
981 } 987 }
982 988
@@ -1009,8 +1015,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1009 the VFS or MM) should not happen but we had reports of on oops (due to 1015 the VFS or MM) should not happen but we had reports of on oops (due to
1010 it being zero) during stress testcases so we need to check for it */ 1016 it being zero) during stress testcases so we need to check for it */
1011 1017
1012 if(cifs_inode == NULL) { 1018 if (cifs_inode == NULL) {
1013 cERROR(1,("Null inode passed to cifs_writeable_file")); 1019 cERROR(1, ("Null inode passed to cifs_writeable_file"));
1014 dump_stack(); 1020 dump_stack();
1015 return NULL; 1021 return NULL;
1016 } 1022 }
@@ -1024,13 +1030,14 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1024 (open_file->pfile->f_flags & O_WRONLY))) { 1030 (open_file->pfile->f_flags & O_WRONLY))) {
1025 atomic_inc(&open_file->wrtPending); 1031 atomic_inc(&open_file->wrtPending);
1026 read_unlock(&GlobalSMBSeslock); 1032 read_unlock(&GlobalSMBSeslock);
1027 if((open_file->invalidHandle) && 1033 if ((open_file->invalidHandle) &&
1028 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { 1034 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
1029 rc = cifs_reopen_file(open_file->pfile, FALSE); 1035 rc = cifs_reopen_file(open_file->pfile, FALSE);
1030 /* if it fails, try another handle - might be */ 1036 /* if it fails, try another handle - might be */
1031 /* dangerous to hold up writepages with retry */ 1037 /* dangerous to hold up writepages with retry */
1032 if(rc) { 1038 if (rc) {
1033 cFYI(1,("failed on reopen file in wp")); 1039 cFYI(1,
1040 ("failed on reopen file in wp"));
1034 read_lock(&GlobalSMBSeslock); 1041 read_lock(&GlobalSMBSeslock);
1035 /* can not use this handle, no write 1042 /* can not use this handle, no write
1036 pending on this one after all */ 1043 pending on this one after all */
@@ -1082,7 +1089,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1082 1089
1083 /* check to make sure that we are not extending the file */ 1090 /* check to make sure that we are not extending the file */
1084 if (mapping->host->i_size - offset < (loff_t)to) 1091 if (mapping->host->i_size - offset < (loff_t)to)
1085 to = (unsigned)(mapping->host->i_size - offset); 1092 to = (unsigned)(mapping->host->i_size - offset);
1086 1093
1087 open_file = find_writable_file(CIFS_I(mapping->host)); 1094 open_file = find_writable_file(CIFS_I(mapping->host));
1088 if (open_file) { 1095 if (open_file) {
@@ -1116,8 +1123,8 @@ static int cifs_writepages(struct address_space *mapping,
1116 int done = 0; 1123 int done = 0;
1117 pgoff_t end; 1124 pgoff_t end;
1118 pgoff_t index; 1125 pgoff_t index;
1119 int range_whole = 0; 1126 int range_whole = 0;
1120 struct kvec * iov; 1127 struct kvec *iov;
1121 int len; 1128 int len;
1122 int n_iov = 0; 1129 int n_iov = 0;
1123 pgoff_t next; 1130 pgoff_t next;
@@ -1131,7 +1138,7 @@ static int cifs_writepages(struct address_space *mapping,
1131 int xid; 1138 int xid;
1132 1139
1133 cifs_sb = CIFS_SB(mapping->host->i_sb); 1140 cifs_sb = CIFS_SB(mapping->host->i_sb);
1134 1141
1135 /* 1142 /*
1136 * If wsize is smaller that the page cache size, default to writing 1143 * If wsize is smaller that the page cache size, default to writing
1137 * one page at a time via cifs_writepage 1144 * one page at a time via cifs_writepage
@@ -1139,14 +1146,14 @@ static int cifs_writepages(struct address_space *mapping,
1139 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1146 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1140 return generic_writepages(mapping, wbc); 1147 return generic_writepages(mapping, wbc);
1141 1148
1142 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) 1149 if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1143 if(cifs_sb->tcon->ses->server->secMode & 1150 if (cifs_sb->tcon->ses->server->secMode &
1144 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 1151 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1145 if(!experimEnabled) 1152 if (!experimEnabled)
1146 return generic_writepages(mapping, wbc); 1153 return generic_writepages(mapping, wbc);
1147 1154
1148 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); 1155 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1149 if(iov == NULL) 1156 if (iov == NULL)
1150 return generic_writepages(mapping, wbc); 1157 return generic_writepages(mapping, wbc);
1151 1158
1152 1159
@@ -1279,7 +1286,7 @@ retry:
1279 1); 1286 1);
1280 atomic_dec(&open_file->wrtPending); 1287 atomic_dec(&open_file->wrtPending);
1281 if (rc || bytes_written < bytes_to_write) { 1288 if (rc || bytes_written < bytes_to_write) {
1282 cERROR(1,("Write2 ret %d, written = %d", 1289 cERROR(1, ("Write2 ret %d, wrote %d",
1283 rc, bytes_written)); 1290 rc, bytes_written));
1284 /* BB what if continued retry is 1291 /* BB what if continued retry is
1285 requested via mount flags? */ 1292 requested via mount flags? */
@@ -1295,8 +1302,8 @@ retry:
1295 success rc but too little data written? */ 1302 success rc but too little data written? */
1296 /* BB investigate retry logic on temporary 1303 /* BB investigate retry logic on temporary
1297 server crash cases and how recovery works 1304 server crash cases and how recovery works
1298 when page marked as error */ 1305 when page marked as error */
1299 if(rc) 1306 if (rc)
1300 SetPageError(page); 1307 SetPageError(page);
1301 kunmap(page); 1308 kunmap(page);
1302 unlock_page(page); 1309 unlock_page(page);
@@ -1326,7 +1333,7 @@ retry:
1326 return rc; 1333 return rc;
1327} 1334}
1328 1335
1329static int cifs_writepage(struct page* page, struct writeback_control *wbc) 1336static int cifs_writepage(struct page *page, struct writeback_control *wbc)
1330{ 1337{
1331 int rc = -EFAULT; 1338 int rc = -EFAULT;
1332 int xid; 1339 int xid;
@@ -1334,7 +1341,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1334 xid = GetXid(); 1341 xid = GetXid();
1335/* BB add check for wbc flags */ 1342/* BB add check for wbc flags */
1336 page_cache_get(page); 1343 page_cache_get(page);
1337 if (!PageUptodate(page)) { 1344 if (!PageUptodate(page)) {
1338 cFYI(1, ("ppw - page not up to date")); 1345 cFYI(1, ("ppw - page not up to date"));
1339 } 1346 }
1340 1347
@@ -1348,7 +1355,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1348 * Just unlocking the page will cause the radix tree tag-bits 1355 * Just unlocking the page will cause the radix tree tag-bits
1349 * to fail to update with the state of the page correctly. 1356 * to fail to update with the state of the page correctly.
1350 */ 1357 */
1351 set_page_writeback(page); 1358 set_page_writeback(page);
1352 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); 1359 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
1353 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ 1360 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
1354 unlock_page(page); 1361 unlock_page(page);
@@ -1368,7 +1375,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1368 char *page_data; 1375 char *page_data;
1369 1376
1370 xid = GetXid(); 1377 xid = GetXid();
1371 cFYI(1, ("commit write for page %p up to position %lld for %d", 1378 cFYI(1, ("commit write for page %p up to position %lld for %d",
1372 page, position, to)); 1379 page, position, to));
1373 spin_lock(&inode->i_lock); 1380 spin_lock(&inode->i_lock);
1374 if (position > inode->i_size) { 1381 if (position > inode->i_size) {
@@ -1396,7 +1403,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1396 rc = 0; 1403 rc = 0;
1397 /* else if (rc < 0) should we set writebehind rc? */ 1404 /* else if (rc < 0) should we set writebehind rc? */
1398 kunmap(page); 1405 kunmap(page);
1399 } else { 1406 } else {
1400 set_page_dirty(page); 1407 set_page_dirty(page);
1401 } 1408 }
1402 1409
@@ -1412,9 +1419,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1412 1419
1413 xid = GetXid(); 1420 xid = GetXid();
1414 1421
1415 cFYI(1, ("Sync file - name: %s datasync: 0x%x", 1422 cFYI(1, ("Sync file - name: %s datasync: 0x%x",
1416 dentry->d_name.name, datasync)); 1423 dentry->d_name.name, datasync));
1417 1424
1418 rc = filemap_fdatawrite(inode->i_mapping); 1425 rc = filemap_fdatawrite(inode->i_mapping);
1419 if (rc == 0) 1426 if (rc == 0)
1420 CIFS_I(inode)->write_behind_rc = 0; 1427 CIFS_I(inode)->write_behind_rc = 0;
@@ -1438,7 +1445,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1438 if (!inode) 1445 if (!inode)
1439 return; */ 1446 return; */
1440 1447
1441/* fill in rpages then 1448/* fill in rpages then
1442 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ 1449 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1443 1450
1444/* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); 1451/* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index));
@@ -1456,7 +1463,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1456 */ 1463 */
1457int cifs_flush(struct file *file, fl_owner_t id) 1464int cifs_flush(struct file *file, fl_owner_t id)
1458{ 1465{
1459 struct inode * inode = file->f_path.dentry->d_inode; 1466 struct inode *inode = file->f_path.dentry->d_inode;
1460 int rc = 0; 1467 int rc = 0;
1461 1468
1462 /* Rather than do the steps manually: 1469 /* Rather than do the steps manually:
@@ -1471,8 +1478,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
1471 rc = filemap_fdatawrite(inode->i_mapping); 1478 rc = filemap_fdatawrite(inode->i_mapping);
1472 if (!rc) /* reset wb rc if we were able to write out dirty pages */ 1479 if (!rc) /* reset wb rc if we were able to write out dirty pages */
1473 CIFS_I(inode)->write_behind_rc = 0; 1480 CIFS_I(inode)->write_behind_rc = 0;
1474 1481
1475 cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc)); 1482 cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
1476 1483
1477 return rc; 1484 return rc;
1478} 1485}
@@ -1508,13 +1515,13 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1508 for (total_read = 0, current_offset = read_data; 1515 for (total_read = 0, current_offset = read_data;
1509 read_size > total_read; 1516 read_size > total_read;
1510 total_read += bytes_read, current_offset += bytes_read) { 1517 total_read += bytes_read, current_offset += bytes_read) {
1511 current_read_size = min_t(const int, read_size - total_read, 1518 current_read_size = min_t(const int, read_size - total_read,
1512 cifs_sb->rsize); 1519 cifs_sb->rsize);
1513 rc = -EAGAIN; 1520 rc = -EAGAIN;
1514 smb_read_data = NULL; 1521 smb_read_data = NULL;
1515 while (rc == -EAGAIN) { 1522 while (rc == -EAGAIN) {
1516 int buf_type = CIFS_NO_BUFFER; 1523 int buf_type = CIFS_NO_BUFFER;
1517 if ((open_file->invalidHandle) && 1524 if ((open_file->invalidHandle) &&
1518 (!open_file->closePend)) { 1525 (!open_file->closePend)) {
1519 rc = cifs_reopen_file(file, TRUE); 1526 rc = cifs_reopen_file(file, TRUE);
1520 if (rc != 0) 1527 if (rc != 0)
@@ -1535,9 +1542,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1535 rc = -EFAULT; 1542 rc = -EFAULT;
1536 } 1543 }
1537 1544
1538 if(buf_type == CIFS_SMALL_BUFFER) 1545 if (buf_type == CIFS_SMALL_BUFFER)
1539 cifs_small_buf_release(smb_read_data); 1546 cifs_small_buf_release(smb_read_data);
1540 else if(buf_type == CIFS_LARGE_BUFFER) 1547 else if (buf_type == CIFS_LARGE_BUFFER)
1541 cifs_buf_release(smb_read_data); 1548 cifs_buf_release(smb_read_data);
1542 smb_read_data = NULL; 1549 smb_read_data = NULL;
1543 } 1550 }
@@ -1586,21 +1593,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1586 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1593 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1587 cFYI(1, ("attempting read on write only file instance")); 1594 cFYI(1, ("attempting read on write only file instance"));
1588 1595
1589 for (total_read = 0, current_offset = read_data; 1596 for (total_read = 0, current_offset = read_data;
1590 read_size > total_read; 1597 read_size > total_read;
1591 total_read += bytes_read, current_offset += bytes_read) { 1598 total_read += bytes_read, current_offset += bytes_read) {
1592 current_read_size = min_t(const int, read_size - total_read, 1599 current_read_size = min_t(const int, read_size - total_read,
1593 cifs_sb->rsize); 1600 cifs_sb->rsize);
1594 /* For windows me and 9x we do not want to request more 1601 /* For windows me and 9x we do not want to request more
1595 than it negotiated since it will refuse the read then */ 1602 than it negotiated since it will refuse the read then */
1596 if((pTcon->ses) && 1603 if ((pTcon->ses) &&
1597 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { 1604 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
1598 current_read_size = min_t(const int, current_read_size, 1605 current_read_size = min_t(const int, current_read_size,
1599 pTcon->ses->server->maxBuf - 128); 1606 pTcon->ses->server->maxBuf - 128);
1600 } 1607 }
1601 rc = -EAGAIN; 1608 rc = -EAGAIN;
1602 while (rc == -EAGAIN) { 1609 while (rc == -EAGAIN) {
1603 if ((open_file->invalidHandle) && 1610 if ((open_file->invalidHandle) &&
1604 (!open_file->closePend)) { 1611 (!open_file->closePend)) {
1605 rc = cifs_reopen_file(file, TRUE); 1612 rc = cifs_reopen_file(file, TRUE);
1606 if (rc != 0) 1613 if (rc != 0)
@@ -1646,7 +1653,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1646} 1653}
1647 1654
1648 1655
1649static void cifs_copy_cache_pages(struct address_space *mapping, 1656static void cifs_copy_cache_pages(struct address_space *mapping,
1650 struct list_head *pages, int bytes_read, char *data, 1657 struct list_head *pages, int bytes_read, char *data,
1651 struct pagevec *plru_pvec) 1658 struct pagevec *plru_pvec)
1652{ 1659{
@@ -1669,12 +1676,12 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1669 continue; 1676 continue;
1670 } 1677 }
1671 1678
1672 target = kmap_atomic(page,KM_USER0); 1679 target = kmap_atomic(page, KM_USER0);
1673 1680
1674 if (PAGE_CACHE_SIZE > bytes_read) { 1681 if (PAGE_CACHE_SIZE > bytes_read) {
1675 memcpy(target, data, bytes_read); 1682 memcpy(target, data, bytes_read);
1676 /* zero the tail end of this partial page */ 1683 /* zero the tail end of this partial page */
1677 memset(target + bytes_read, 0, 1684 memset(target + bytes_read, 0,
1678 PAGE_CACHE_SIZE - bytes_read); 1685 PAGE_CACHE_SIZE - bytes_read);
1679 bytes_read = 0; 1686 bytes_read = 0;
1680 } else { 1687 } else {
@@ -1703,7 +1710,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1703 struct cifs_sb_info *cifs_sb; 1710 struct cifs_sb_info *cifs_sb;
1704 struct cifsTconInfo *pTcon; 1711 struct cifsTconInfo *pTcon;
1705 int bytes_read = 0; 1712 int bytes_read = 0;
1706 unsigned int read_size,i; 1713 unsigned int read_size, i;
1707 char *smb_read_data = NULL; 1714 char *smb_read_data = NULL;
1708 struct smb_com_read_rsp *pSMBr; 1715 struct smb_com_read_rsp *pSMBr;
1709 struct pagevec lru_pvec; 1716 struct pagevec lru_pvec;
@@ -1720,7 +1727,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1720 pTcon = cifs_sb->tcon; 1727 pTcon = cifs_sb->tcon;
1721 1728
1722 pagevec_init(&lru_pvec, 0); 1729 pagevec_init(&lru_pvec, 0);
1723 1730#ifdef CONFIG_CIFS_DEBUG2
1731 cFYI(1, ("rpages: num pages %d", num_pages));
1732#endif
1724 for (i = 0; i < num_pages; ) { 1733 for (i = 0; i < num_pages; ) {
1725 unsigned contig_pages; 1734 unsigned contig_pages;
1726 struct page *tmp_page; 1735 struct page *tmp_page;
@@ -1734,14 +1743,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1734 1743
1735 /* count adjacent pages that we will read into */ 1744 /* count adjacent pages that we will read into */
1736 contig_pages = 0; 1745 contig_pages = 0;
1737 expected_index = 1746 expected_index =
1738 list_entry(page_list->prev, struct page, lru)->index; 1747 list_entry(page_list->prev, struct page, lru)->index;
1739 list_for_each_entry_reverse(tmp_page,page_list,lru) { 1748 list_for_each_entry_reverse(tmp_page, page_list, lru) {
1740 if (tmp_page->index == expected_index) { 1749 if (tmp_page->index == expected_index) {
1741 contig_pages++; 1750 contig_pages++;
1742 expected_index++; 1751 expected_index++;
1743 } else 1752 } else
1744 break; 1753 break;
1745 } 1754 }
1746 if (contig_pages + i > num_pages) 1755 if (contig_pages + i > num_pages)
1747 contig_pages = num_pages - i; 1756 contig_pages = num_pages - i;
@@ -1753,10 +1762,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1753 /* Read size needs to be in multiples of one page */ 1762 /* Read size needs to be in multiples of one page */
1754 read_size = min_t(const unsigned int, read_size, 1763 read_size = min_t(const unsigned int, read_size,
1755 cifs_sb->rsize & PAGE_CACHE_MASK); 1764 cifs_sb->rsize & PAGE_CACHE_MASK);
1756 1765#ifdef CONFIG_CIFS_DEBUG2
1766 cFYI(1, ("rpages: read size 0x%x contiguous pages %d",
1767 read_size, contig_pages));
1768#endif
1757 rc = -EAGAIN; 1769 rc = -EAGAIN;
1758 while (rc == -EAGAIN) { 1770 while (rc == -EAGAIN) {
1759 if ((open_file->invalidHandle) && 1771 if ((open_file->invalidHandle) &&
1760 (!open_file->closePend)) { 1772 (!open_file->closePend)) {
1761 rc = cifs_reopen_file(file, TRUE); 1773 rc = cifs_reopen_file(file, TRUE);
1762 if (rc != 0) 1774 if (rc != 0)
@@ -1769,11 +1781,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1769 &bytes_read, &smb_read_data, 1781 &bytes_read, &smb_read_data,
1770 &buf_type); 1782 &buf_type);
1771 /* BB more RC checks ? */ 1783 /* BB more RC checks ? */
1772 if (rc== -EAGAIN) { 1784 if (rc == -EAGAIN) {
1773 if (smb_read_data) { 1785 if (smb_read_data) {
1774 if(buf_type == CIFS_SMALL_BUFFER) 1786 if (buf_type == CIFS_SMALL_BUFFER)
1775 cifs_small_buf_release(smb_read_data); 1787 cifs_small_buf_release(smb_read_data);
1776 else if(buf_type == CIFS_LARGE_BUFFER) 1788 else if (buf_type == CIFS_LARGE_BUFFER)
1777 cifs_buf_release(smb_read_data); 1789 cifs_buf_release(smb_read_data);
1778 smb_read_data = NULL; 1790 smb_read_data = NULL;
1779 } 1791 }
@@ -1794,10 +1806,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1794 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { 1806 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1795 i++; /* account for partial page */ 1807 i++; /* account for partial page */
1796 1808
1797 /* server copy of file can have smaller size 1809 /* server copy of file can have smaller size
1798 than client */ 1810 than client */
1799 /* BB do we need to verify this common case ? 1811 /* BB do we need to verify this common case ?
1800 this case is ok - if we are at server EOF 1812 this case is ok - if we are at server EOF
1801 we will hit it on next read */ 1813 we will hit it on next read */
1802 1814
1803 /* break; */ 1815 /* break; */
@@ -1806,14 +1818,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1806 cFYI(1, ("No bytes read (%d) at offset %lld . " 1818 cFYI(1, ("No bytes read (%d) at offset %lld . "
1807 "Cleaning remaining pages from readahead list", 1819 "Cleaning remaining pages from readahead list",
1808 bytes_read, offset)); 1820 bytes_read, offset));
1809 /* BB turn off caching and do new lookup on 1821 /* BB turn off caching and do new lookup on
1810 file size at server? */ 1822 file size at server? */
1811 break; 1823 break;
1812 } 1824 }
1813 if (smb_read_data) { 1825 if (smb_read_data) {
1814 if(buf_type == CIFS_SMALL_BUFFER) 1826 if (buf_type == CIFS_SMALL_BUFFER)
1815 cifs_small_buf_release(smb_read_data); 1827 cifs_small_buf_release(smb_read_data);
1816 else if(buf_type == CIFS_LARGE_BUFFER) 1828 else if (buf_type == CIFS_LARGE_BUFFER)
1817 cifs_buf_release(smb_read_data); 1829 cifs_buf_release(smb_read_data);
1818 smb_read_data = NULL; 1830 smb_read_data = NULL;
1819 } 1831 }
@@ -1824,12 +1836,12 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1824 1836
1825/* need to free smb_read_data buf before exit */ 1837/* need to free smb_read_data buf before exit */
1826 if (smb_read_data) { 1838 if (smb_read_data) {
1827 if(buf_type == CIFS_SMALL_BUFFER) 1839 if (buf_type == CIFS_SMALL_BUFFER)
1828 cifs_small_buf_release(smb_read_data); 1840 cifs_small_buf_release(smb_read_data);
1829 else if(buf_type == CIFS_LARGE_BUFFER) 1841 else if (buf_type == CIFS_LARGE_BUFFER)
1830 cifs_buf_release(smb_read_data); 1842 cifs_buf_release(smb_read_data);
1831 smb_read_data = NULL; 1843 smb_read_data = NULL;
1832 } 1844 }
1833 1845
1834 FreeXid(xid); 1846 FreeXid(xid);
1835 return rc; 1847 return rc;
@@ -1844,26 +1856,26 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
1844 page_cache_get(page); 1856 page_cache_get(page);
1845 read_data = kmap(page); 1857 read_data = kmap(page);
1846 /* for reads over a certain size could initiate async read ahead */ 1858 /* for reads over a certain size could initiate async read ahead */
1847 1859
1848 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); 1860 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1849 1861
1850 if (rc < 0) 1862 if (rc < 0)
1851 goto io_error; 1863 goto io_error;
1852 else 1864 else
1853 cFYI(1, ("Bytes read %d",rc)); 1865 cFYI(1, ("Bytes read %d", rc));
1854 1866
1855 file->f_path.dentry->d_inode->i_atime = 1867 file->f_path.dentry->d_inode->i_atime =
1856 current_fs_time(file->f_path.dentry->d_inode->i_sb); 1868 current_fs_time(file->f_path.dentry->d_inode->i_sb);
1857 1869
1858 if (PAGE_CACHE_SIZE > rc) 1870 if (PAGE_CACHE_SIZE > rc)
1859 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); 1871 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);
1860 1872
1861 flush_dcache_page(page); 1873 flush_dcache_page(page);
1862 SetPageUptodate(page); 1874 SetPageUptodate(page);
1863 rc = 0; 1875 rc = 0;
1864 1876
1865io_error: 1877io_error:
1866 kunmap(page); 1878 kunmap(page);
1867 page_cache_release(page); 1879 page_cache_release(page);
1868 return rc; 1880 return rc;
1869} 1881}
@@ -1881,7 +1893,7 @@ static int cifs_readpage(struct file *file, struct page *page)
1881 return -EBADF; 1893 return -EBADF;
1882 } 1894 }
1883 1895
1884 cFYI(1, ("readpage %p at offset %d 0x%x\n", 1896 cFYI(1, ("readpage %p at offset %d 0x%x\n",
1885 page, (int)offset, (int)offset)); 1897 page, (int)offset, (int)offset));
1886 1898
1887 rc = cifs_readpage_worker(file, page, &offset); 1899 rc = cifs_readpage_worker(file, page, &offset);
@@ -1895,7 +1907,7 @@ static int cifs_readpage(struct file *file, struct page *page)
1895/* We do not want to update the file size from server for inodes 1907/* We do not want to update the file size from server for inodes
1896 open for write - to avoid races with writepage extending 1908 open for write - to avoid races with writepage extending
1897 the file - in the future we could consider allowing 1909 the file - in the future we could consider allowing
1898 refreshing the inode only on increases in the file size 1910 refreshing the inode only on increases in the file size
1899 but this is tricky to do without racing with writebehind 1911 but this is tricky to do without racing with writebehind
1900 page caching in the current Linux kernel design */ 1912 page caching in the current Linux kernel design */
1901int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) 1913int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
@@ -1904,8 +1916,8 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1904 1916
1905 if (cifsInode) 1917 if (cifsInode)
1906 open_file = find_writable_file(cifsInode); 1918 open_file = find_writable_file(cifsInode);
1907 1919
1908 if(open_file) { 1920 if (open_file) {
1909 struct cifs_sb_info *cifs_sb; 1921 struct cifs_sb_info *cifs_sb;
1910 1922
1911 /* there is not actually a write pending so let 1923 /* there is not actually a write pending so let
@@ -1915,12 +1927,12 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1915 1927
1916 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); 1928 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
1917 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { 1929 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
1918 /* since no page cache to corrupt on directio 1930 /* since no page cache to corrupt on directio
1919 we can change size safely */ 1931 we can change size safely */
1920 return 1; 1932 return 1;
1921 } 1933 }
1922 1934
1923 if(i_size_read(&cifsInode->vfs_inode) < end_of_file) 1935 if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
1924 return 1; 1936 return 1;
1925 1937
1926 return 0; 1938 return 0;
@@ -1935,7 +1947,7 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1935 loff_t i_size; 1947 loff_t i_size;
1936 loff_t offset; 1948 loff_t offset;
1937 1949
1938 cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); 1950 cFYI(1, ("prepare write for page %p from %d to %d", page, from, to));
1939 if (PageUptodate(page)) 1951 if (PageUptodate(page))
1940 return 0; 1952 return 0;
1941 1953
@@ -1955,14 +1967,7 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1955 * We don't need to read data beyond the end of the file. 1967 * We don't need to read data beyond the end of the file.
1956 * zero it, and set the page uptodate 1968 * zero it, and set the page uptodate
1957 */ 1969 */
1958 void *kaddr = kmap_atomic(page, KM_USER0); 1970 simple_prepare_write(file, page, from, to);
1959
1960 if (from)
1961 memset(kaddr, 0, from);
1962 if (to < PAGE_CACHE_SIZE)
1963 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1964 flush_dcache_page(page);
1965 kunmap_atomic(kaddr, KM_USER0);
1966 SetPageUptodate(page); 1971 SetPageUptodate(page);
1967 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { 1972 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
1968 /* might as well read a page, it is fast enough */ 1973 /* might as well read a page, it is fast enough */
@@ -1974,8 +1979,8 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1974 this will be written out by commit_write so is fine */ 1979 this will be written out by commit_write so is fine */
1975 } 1980 }
1976 1981
1977 /* we do not need to pass errors back 1982 /* we do not need to pass errors back
1978 e.g. if we do not have read access to the file 1983 e.g. if we do not have read access to the file
1979 because cifs_commit_write will do the right thing. -- shaggy */ 1984 because cifs_commit_write will do the right thing. -- shaggy */
1980 1985
1981 return 0; 1986 return 0;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f0ff12b3f398..dd4167762a8e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -57,14 +57,14 @@ int cifs_get_inode_info_unix(struct inode **pinode,
57 if (tmp_path == NULL) { 57 if (tmp_path == NULL) {
58 return -ENOMEM; 58 return -ENOMEM;
59 } 59 }
60 /* have to skip first of the double backslash of 60 /* have to skip first of the double backslash of
61 UNC name */ 61 UNC name */
62 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 62 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
63 strncat(tmp_path, search_path, MAX_PATHCONF); 63 strncat(tmp_path, search_path, MAX_PATHCONF);
64 rc = connect_to_dfs_path(xid, pTcon->ses, 64 rc = connect_to_dfs_path(xid, pTcon->ses,
65 /* treename + */ tmp_path, 65 /* treename + */ tmp_path,
66 cifs_sb->local_nls, 66 cifs_sb->local_nls,
67 cifs_sb->mnt_cifs_flags & 67 cifs_sb->mnt_cifs_flags &
68 CIFS_MOUNT_MAP_SPECIAL_CHR); 68 CIFS_MOUNT_MAP_SPECIAL_CHR);
69 kfree(tmp_path); 69 kfree(tmp_path);
70 70
@@ -81,7 +81,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
81 /* get new inode */ 81 /* get new inode */
82 if (*pinode == NULL) { 82 if (*pinode == NULL) {
83 *pinode = new_inode(sb); 83 *pinode = new_inode(sb);
84 if (*pinode == NULL) 84 if (*pinode == NULL)
85 return -ENOMEM; 85 return -ENOMEM;
86 /* Is an i_ino of zero legal? */ 86 /* Is an i_ino of zero legal? */
87 /* Are there sanity checks we can use to ensure that 87 /* Are there sanity checks we can use to ensure that
@@ -92,7 +92,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
92 } /* note ino incremented to unique num in new_inode */ 92 } /* note ino incremented to unique num in new_inode */
93 if (sb->s_flags & MS_NOATIME) 93 if (sb->s_flags & MS_NOATIME)
94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 94 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
95 95
96 insert_inode_hash(*pinode); 96 insert_inode_hash(*pinode);
97 } 97 }
98 98
@@ -103,7 +103,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
103 cifsInfo->time = jiffies; 103 cifsInfo->time = jiffies;
104 cFYI(1, ("New time %ld", cifsInfo->time)); 104 cFYI(1, ("New time %ld", cifsInfo->time));
105 /* this is ok to set on every inode revalidate */ 105 /* this is ok to set on every inode revalidate */
106 atomic_set(&cifsInfo->inUse,1); 106 atomic_set(&cifsInfo->inUse, 1);
107 107
108 inode->i_atime = 108 inode->i_atime =
109 cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); 109 cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
@@ -114,8 +114,8 @@ int cifs_get_inode_info_unix(struct inode **pinode,
114 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); 114 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
115 inode->i_mode = le64_to_cpu(findData.Permissions); 115 inode->i_mode = le64_to_cpu(findData.Permissions);
116 /* since we set the inode type below we need to mask off 116 /* since we set the inode type below we need to mask off
117 to avoid strange results if bits set above */ 117 to avoid strange results if bits set above */
118 inode->i_mode &= ~S_IFMT; 118 inode->i_mode &= ~S_IFMT;
119 if (type == UNIX_FILE) { 119 if (type == UNIX_FILE) {
120 inode->i_mode |= S_IFREG; 120 inode->i_mode |= S_IFREG;
121 } else if (type == UNIX_SYMLINK) { 121 } else if (type == UNIX_SYMLINK) {
@@ -137,9 +137,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
137 } else { 137 } else {
138 /* safest to call it a file if we do not know */ 138 /* safest to call it a file if we do not know */
139 inode->i_mode |= S_IFREG; 139 inode->i_mode |= S_IFREG;
140 cFYI(1,("unknown type %d",type)); 140 cFYI(1, ("unknown type %d", type));
141 } 141 }
142 142
143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
144 inode->i_uid = cifs_sb->mnt_uid; 144 inode->i_uid = cifs_sb->mnt_uid;
145 else 145 else
@@ -149,7 +149,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
149 inode->i_gid = cifs_sb->mnt_gid; 149 inode->i_gid = cifs_sb->mnt_gid;
150 else 150 else
151 inode->i_gid = le64_to_cpu(findData.Gid); 151 inode->i_gid = le64_to_cpu(findData.Gid);
152 152
153 inode->i_nlink = le64_to_cpu(findData.Nlinks); 153 inode->i_nlink = le64_to_cpu(findData.Nlinks);
154 154
155 spin_lock(&inode->i_lock); 155 spin_lock(&inode->i_lock);
@@ -183,17 +183,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
183 inode->i_op = &cifs_file_inode_ops; 183 inode->i_op = &cifs_file_inode_ops;
184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
186 inode->i_fop = 186 inode->i_fop =
187 &cifs_file_direct_nobrl_ops; 187 &cifs_file_direct_nobrl_ops;
188 else 188 else
189 inode->i_fop = &cifs_file_direct_ops; 189 inode->i_fop = &cifs_file_direct_ops;
190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
191 inode->i_fop = &cifs_file_nobrl_ops; 191 inode->i_fop = &cifs_file_nobrl_ops;
192 else /* not direct, send byte range locks */ 192 else /* not direct, send byte range locks */
193 inode->i_fop = &cifs_file_ops; 193 inode->i_fop = &cifs_file_ops;
194 194
195 /* check if server can support readpages */ 195 /* check if server can support readpages */
196 if (pTcon->ses->server->maxBuf < 196 if (pTcon->ses->server->maxBuf <
197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
199 else 199 else
@@ -215,7 +215,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
215 return rc; 215 return rc;
216} 216}
217 217
218static int decode_sfu_inode(struct inode * inode, __u64 size, 218static int decode_sfu_inode(struct inode *inode, __u64 size,
219 const unsigned char *path, 219 const unsigned char *path,
220 struct cifs_sb_info *cifs_sb, int xid) 220 struct cifs_sb_info *cifs_sb, int xid)
221{ 221{
@@ -225,7 +225,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
225 struct cifsTconInfo *pTcon = cifs_sb->tcon; 225 struct cifsTconInfo *pTcon = cifs_sb->tcon;
226 char buf[24]; 226 char buf[24];
227 unsigned int bytes_read; 227 unsigned int bytes_read;
228 char * pbuf; 228 char *pbuf;
229 229
230 pbuf = buf; 230 pbuf = buf;
231 231
@@ -235,22 +235,22 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
235 } else if (size < 8) { 235 } else if (size < 8) {
236 return -EINVAL; /* EOPNOTSUPP? */ 236 return -EINVAL; /* EOPNOTSUPP? */
237 } 237 }
238 238
239 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, 239 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
240 CREATE_NOT_DIR, &netfid, &oplock, NULL, 240 CREATE_NOT_DIR, &netfid, &oplock, NULL,
241 cifs_sb->local_nls, 241 cifs_sb->local_nls,
242 cifs_sb->mnt_cifs_flags & 242 cifs_sb->mnt_cifs_flags &
243 CIFS_MOUNT_MAP_SPECIAL_CHR); 243 CIFS_MOUNT_MAP_SPECIAL_CHR);
244 if (rc==0) { 244 if (rc == 0) {
245 int buf_type = CIFS_NO_BUFFER; 245 int buf_type = CIFS_NO_BUFFER;
246 /* Read header */ 246 /* Read header */
247 rc = CIFSSMBRead(xid, pTcon, 247 rc = CIFSSMBRead(xid, pTcon,
248 netfid, 248 netfid,
249 24 /* length */, 0 /* offset */, 249 24 /* length */, 0 /* offset */,
250 &bytes_read, &pbuf, &buf_type); 250 &bytes_read, &pbuf, &buf_type);
251 if ((rc == 0) && (bytes_read >= 8)) { 251 if ((rc == 0) && (bytes_read >= 8)) {
252 if (memcmp("IntxBLK", pbuf, 8) == 0) { 252 if (memcmp("IntxBLK", pbuf, 8) == 0) {
253 cFYI(1,("Block device")); 253 cFYI(1, ("Block device"));
254 inode->i_mode |= S_IFBLK; 254 inode->i_mode |= S_IFBLK;
255 if (bytes_read == 24) { 255 if (bytes_read == 24) {
256 /* we have enough to decode dev num */ 256 /* we have enough to decode dev num */
@@ -261,7 +261,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
261 inode->i_rdev = MKDEV(mjr, mnr); 261 inode->i_rdev = MKDEV(mjr, mnr);
262 } 262 }
263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
264 cFYI(1,("Char device")); 264 cFYI(1, ("Char device"));
265 inode->i_mode |= S_IFCHR; 265 inode->i_mode |= S_IFCHR;
266 if (bytes_read == 24) { 266 if (bytes_read == 24) {
267 /* we have enough to decode dev num */ 267 /* we have enough to decode dev num */
@@ -270,27 +270,26 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
270 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 270 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
272 inode->i_rdev = MKDEV(mjr, mnr); 272 inode->i_rdev = MKDEV(mjr, mnr);
273 } 273 }
274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
275 cFYI(1,("Symlink")); 275 cFYI(1, ("Symlink"));
276 inode->i_mode |= S_IFLNK; 276 inode->i_mode |= S_IFLNK;
277 } else { 277 } else {
278 inode->i_mode |= S_IFREG; /* file? */ 278 inode->i_mode |= S_IFREG; /* file? */
279 rc = -EOPNOTSUPP; 279 rc = -EOPNOTSUPP;
280 } 280 }
281 } else { 281 } else {
282 inode->i_mode |= S_IFREG; /* then it is a file */ 282 inode->i_mode |= S_IFREG; /* then it is a file */
283 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 283 rc = -EOPNOTSUPP; /* or some unknown SFU type */
284 } 284 }
285 CIFSSMBClose(xid, pTcon, netfid); 285 CIFSSMBClose(xid, pTcon, netfid);
286 } 286 }
287 return rc; 287 return rc;
288
289} 288}
290 289
291#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 290#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
292 291
293static int get_sfu_uid_mode(struct inode * inode, 292static int get_sfu_uid_mode(struct inode *inode,
294 const unsigned char *path, 293 const unsigned char *path,
295 struct cifs_sb_info *cifs_sb, int xid) 294 struct cifs_sb_info *cifs_sb, int xid)
296{ 295{
@@ -301,15 +300,15 @@ static int get_sfu_uid_mode(struct inode * inode,
301 300
302 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 301 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
303 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 302 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
304 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 303 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
305 if (rc < 0) 304 if (rc < 0)
306 return (int)rc; 305 return (int)rc;
307 else if (rc > 3) { 306 else if (rc > 3) {
308 mode = le32_to_cpu(*((__le32 *)ea_value)); 307 mode = le32_to_cpu(*((__le32 *)ea_value));
309 inode->i_mode &= ~SFBITS_MASK; 308 inode->i_mode &= ~SFBITS_MASK;
310 cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode)); 309 cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode));
311 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 310 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
312 cFYI(1,("special mode bits 0%o", mode)); 311 cFYI(1, ("special mode bits 0%o", mode));
313 return 0; 312 return 0;
314 } else { 313 } else {
315 return 0; 314 return 0;
@@ -317,8 +316,6 @@ static int get_sfu_uid_mode(struct inode * inode,
317#else 316#else
318 return -EOPNOTSUPP; 317 return -EOPNOTSUPP;
319#endif 318#endif
320
321
322} 319}
323 320
324int cifs_get_inode_info(struct inode **pinode, 321int cifs_get_inode_info(struct inode **pinode,
@@ -334,11 +331,11 @@ int cifs_get_inode_info(struct inode **pinode,
334 int adjustTZ = FALSE; 331 int adjustTZ = FALSE;
335 332
336 pTcon = cifs_sb->tcon; 333 pTcon = cifs_sb->tcon;
337 cFYI(1,("Getting info on %s", search_path)); 334 cFYI(1, ("Getting info on %s", search_path));
338 335
339 if ((pfindData == NULL) && (*pinode != NULL)) { 336 if ((pfindData == NULL) && (*pinode != NULL)) {
340 if (CIFS_I(*pinode)->clientCanCacheRead) { 337 if (CIFS_I(*pinode)->clientCanCacheRead) {
341 cFYI(1,("No need to revalidate cached inode sizes")); 338 cFYI(1, ("No need to revalidate cached inode sizes"));
342 return rc; 339 return rc;
343 } 340 }
344 } 341 }
@@ -359,12 +356,11 @@ int cifs_get_inode_info(struct inode **pinode,
359 failed at least once - set flag in tcon or mount */ 356 failed at least once - set flag in tcon or mount */
360 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 357 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
361 rc = SMBQueryInformation(xid, pTcon, search_path, 358 rc = SMBQueryInformation(xid, pTcon, search_path,
362 pfindData, cifs_sb->local_nls, 359 pfindData, cifs_sb->local_nls,
363 cifs_sb->mnt_cifs_flags & 360 cifs_sb->mnt_cifs_flags &
364 CIFS_MOUNT_MAP_SPECIAL_CHR); 361 CIFS_MOUNT_MAP_SPECIAL_CHR);
365 adjustTZ = TRUE; 362 adjustTZ = TRUE;
366 } 363 }
367
368 } 364 }
369 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 365 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
370 if (rc) { 366 if (rc) {
@@ -384,8 +380,8 @@ int cifs_get_inode_info(struct inode **pinode,
384 strncat(tmp_path, search_path, MAX_PATHCONF); 380 strncat(tmp_path, search_path, MAX_PATHCONF);
385 rc = connect_to_dfs_path(xid, pTcon->ses, 381 rc = connect_to_dfs_path(xid, pTcon->ses,
386 /* treename + */ tmp_path, 382 /* treename + */ tmp_path,
387 cifs_sb->local_nls, 383 cifs_sb->local_nls,
388 cifs_sb->mnt_cifs_flags & 384 cifs_sb->mnt_cifs_flags &
389 CIFS_MOUNT_MAP_SPECIAL_CHR); 385 CIFS_MOUNT_MAP_SPECIAL_CHR);
390 kfree(tmp_path); 386 kfree(tmp_path);
391 /* BB fix up inode etc. */ 387 /* BB fix up inode etc. */
@@ -419,17 +415,17 @@ int cifs_get_inode_info(struct inode **pinode,
419 there Windows server or network appliances for which 415 there Windows server or network appliances for which
420 IndexNumber field is not guaranteed unique? */ 416 IndexNumber field is not guaranteed unique? */
421 417
422 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ 418 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
423 int rc1 = 0; 419 int rc1 = 0;
424 __u64 inode_num; 420 __u64 inode_num;
425 421
426 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 422 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
427 search_path, &inode_num, 423 search_path, &inode_num,
428 cifs_sb->local_nls, 424 cifs_sb->local_nls,
429 cifs_sb->mnt_cifs_flags & 425 cifs_sb->mnt_cifs_flags &
430 CIFS_MOUNT_MAP_SPECIAL_CHR); 426 CIFS_MOUNT_MAP_SPECIAL_CHR);
431 if (rc1) { 427 if (rc1) {
432 cFYI(1,("GetSrvInodeNum rc %d", rc1)); 428 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
433 /* BB EOPNOSUPP disable SERVER_INUM? */ 429 /* BB EOPNOSUPP disable SERVER_INUM? */
434 } else /* do we need cast or hash to ino? */ 430 } else /* do we need cast or hash to ino? */
435 (*pinode)->i_ino = inode_num; 431 (*pinode)->i_ino = inode_num;
@@ -463,7 +459,7 @@ int cifs_get_inode_info(struct inode **pinode,
463 cFYI(0, ("Attributes came in as 0x%x", attr)); 459 cFYI(0, ("Attributes came in as 0x%x", attr));
464 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 460 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
465 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 461 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
466 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 462 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
467 } 463 }
468 464
469 /* set default mode. will override for dirs below */ 465 /* set default mode. will override for dirs below */
@@ -471,8 +467,9 @@ int cifs_get_inode_info(struct inode **pinode,
471 /* new inode, can safely set these fields */ 467 /* new inode, can safely set these fields */
472 inode->i_mode = cifs_sb->mnt_file_mode; 468 inode->i_mode = cifs_sb->mnt_file_mode;
473 else /* since we set the inode type below we need to mask off 469 else /* since we set the inode type below we need to mask off
474 to avoid strange results if type changes and both get orred in */ 470 to avoid strange results if type changes and both
475 inode->i_mode &= ~S_IFMT; 471 get orred in */
472 inode->i_mode &= ~S_IFMT;
476/* if (attr & ATTR_REPARSE) */ 473/* if (attr & ATTR_REPARSE) */
477 /* We no longer handle these as symlinks because we could not 474 /* We no longer handle these as symlinks because we could not
478 follow them due to the absolute path with drive letter */ 475 follow them due to the absolute path with drive letter */
@@ -490,13 +487,13 @@ int cifs_get_inode_info(struct inode **pinode,
490/* BB Finish for SFU style symlinks and devices */ 487/* BB Finish for SFU style symlinks and devices */
491 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 488 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
492 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { 489 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
493 if (decode_sfu_inode(inode, 490 if (decode_sfu_inode(inode,
494 le64_to_cpu(pfindData->EndOfFile), 491 le64_to_cpu(pfindData->EndOfFile),
495 search_path, 492 search_path,
496 cifs_sb, xid)) { 493 cifs_sb, xid)) {
497 cFYI(1,("Unrecognized sfu inode type")); 494 cFYI(1, ("Unrecognized sfu inode type"));
498 } 495 }
499 cFYI(1,("sfu mode 0%o",inode->i_mode)); 496 cFYI(1, ("sfu mode 0%o", inode->i_mode));
500 } else { 497 } else {
501 inode->i_mode |= S_IFREG; 498 inode->i_mode |= S_IFREG;
502 /* treat the dos attribute of read-only as read-only 499 /* treat the dos attribute of read-only as read-only
@@ -512,12 +509,12 @@ int cifs_get_inode_info(struct inode **pinode,
512 /* BB add code here - 509 /* BB add code here -
513 validate if device or weird share or device type? */ 510 validate if device or weird share or device type? */
514 } 511 }
515 512
516 spin_lock(&inode->i_lock); 513 spin_lock(&inode->i_lock);
517 if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) { 514 if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) {
518 /* can not safely shrink the file size here if the 515 /* can not safely shrink the file size here if the
519 client is writing to it due to potential races */ 516 client is writing to it due to potential races */
520 i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); 517 i_size_write(inode, le64_to_cpu(pfindData->EndOfFile));
521 518
522 /* 512 bytes (2**9) is the fake blocksize that must be 519 /* 512 bytes (2**9) is the fake blocksize that must be
523 used for this calculation */ 520 used for this calculation */
@@ -528,7 +525,7 @@ int cifs_get_inode_info(struct inode **pinode,
528 525
529 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); 526 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
530 527
531 /* BB fill in uid and gid here? with help from winbind? 528 /* BB fill in uid and gid here? with help from winbind?
532 or retrieve from NTFS stream extended attribute */ 529 or retrieve from NTFS stream extended attribute */
533 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 530 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
534 /* fill in uid, gid, mode from server ACL */ 531 /* fill in uid, gid, mode from server ACL */
@@ -540,7 +537,7 @@ int cifs_get_inode_info(struct inode **pinode,
540 inode->i_gid = cifs_sb->mnt_gid; 537 inode->i_gid = cifs_sb->mnt_gid;
541 /* set so we do not keep refreshing these fields with 538 /* set so we do not keep refreshing these fields with
542 bad data after user has changed them in memory */ 539 bad data after user has changed them in memory */
543 atomic_set(&cifsInfo->inUse,1); 540 atomic_set(&cifsInfo->inUse, 1);
544 } 541 }
545 542
546 if (S_ISREG(inode->i_mode)) { 543 if (S_ISREG(inode->i_mode)) {
@@ -557,7 +554,7 @@ int cifs_get_inode_info(struct inode **pinode,
557 else /* not direct, send byte range locks */ 554 else /* not direct, send byte range locks */
558 inode->i_fop = &cifs_file_ops; 555 inode->i_fop = &cifs_file_ops;
559 556
560 if (pTcon->ses->server->maxBuf < 557 if (pTcon->ses->server->maxBuf <
561 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 558 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
562 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 559 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
563 else 560 else
@@ -586,10 +583,11 @@ void cifs_read_inode(struct inode *inode)
586 583
587 cifs_sb = CIFS_SB(inode->i_sb); 584 cifs_sb = CIFS_SB(inode->i_sb);
588 xid = GetXid(); 585 xid = GetXid();
589 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 586
590 cifs_get_inode_info_unix(&inode, "", inode->i_sb,xid); 587 if (cifs_sb->tcon->unix_ext)
588 cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
591 else 589 else
592 cifs_get_inode_info(&inode, "", NULL, inode->i_sb,xid); 590 cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
593 /* can not call macro FreeXid here since in a void func */ 591 /* can not call macro FreeXid here since in a void func */
594 _FreeXid(xid); 592 _FreeXid(xid);
595} 593}
@@ -623,9 +621,21 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
623 FreeXid(xid); 621 FreeXid(xid);
624 return -ENOMEM; 622 return -ENOMEM;
625 } 623 }
626 rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls, 624
625 if ((pTcon->ses->capabilities & CAP_UNIX) &&
626 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
627 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
628 rc = CIFSPOSIXDelFile(xid, pTcon, full_path,
629 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
627 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 630 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
631 cFYI(1, ("posix del rc %d", rc));
632 if ((rc == 0) || (rc == -ENOENT))
633 goto psx_del_no_retry;
634 }
628 635
636 rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
637 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
638psx_del_no_retry:
629 if (!rc) { 639 if (!rc) {
630 if (direntry->d_inode) 640 if (direntry->d_inode)
631 drop_nlink(direntry->d_inode); 641 drop_nlink(direntry->d_inode);
@@ -638,12 +648,12 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
638 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, 648 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
639 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, 649 CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
640 &netfid, &oplock, NULL, cifs_sb->local_nls, 650 &netfid, &oplock, NULL, cifs_sb->local_nls,
641 cifs_sb->mnt_cifs_flags & 651 cifs_sb->mnt_cifs_flags &
642 CIFS_MOUNT_MAP_SPECIAL_CHR); 652 CIFS_MOUNT_MAP_SPECIAL_CHR);
643 if (rc==0) { 653 if (rc == 0) {
644 CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL, 654 CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
645 cifs_sb->local_nls, 655 cifs_sb->local_nls,
646 cifs_sb->mnt_cifs_flags & 656 cifs_sb->mnt_cifs_flags &
647 CIFS_MOUNT_MAP_SPECIAL_CHR); 657 CIFS_MOUNT_MAP_SPECIAL_CHR);
648 CIFSSMBClose(xid, pTcon, netfid); 658 CIFSSMBClose(xid, pTcon, netfid);
649 if (direntry->d_inode) 659 if (direntry->d_inode)
@@ -659,7 +669,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
659 rc = CIFSSMBSetTimes(xid, pTcon, full_path, 669 rc = CIFSSMBSetTimes(xid, pTcon, full_path,
660 pinfo_buf, 670 pinfo_buf,
661 cifs_sb->local_nls, 671 cifs_sb->local_nls,
662 cifs_sb->mnt_cifs_flags & 672 cifs_sb->mnt_cifs_flags &
663 CIFS_MOUNT_MAP_SPECIAL_CHR); 673 CIFS_MOUNT_MAP_SPECIAL_CHR);
664 else 674 else
665 rc = -EOPNOTSUPP; 675 rc = -EOPNOTSUPP;
@@ -670,7 +680,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
670 /* rc = CIFSSMBSetAttrLegacy(xid, pTcon, 680 /* rc = CIFSSMBSetAttrLegacy(xid, pTcon,
671 full_path, 681 full_path,
672 (__u16)ATTR_NORMAL, 682 (__u16)ATTR_NORMAL,
673 cifs_sb->local_nls); 683 cifs_sb->local_nls);
674 For some strange reason it seems that NT4 eats the 684 For some strange reason it seems that NT4 eats the
675 old setattr call without actually setting the 685 old setattr call without actually setting the
676 attributes so on to the third attempted workaround 686 attributes so on to the third attempted workaround
@@ -683,9 +693,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
683 FILE_WRITE_ATTRIBUTES, 0, 693 FILE_WRITE_ATTRIBUTES, 0,
684 &netfid, &oplock, NULL, 694 &netfid, &oplock, NULL,
685 cifs_sb->local_nls, 695 cifs_sb->local_nls,
686 cifs_sb->mnt_cifs_flags & 696 cifs_sb->mnt_cifs_flags &
687 CIFS_MOUNT_MAP_SPECIAL_CHR); 697 CIFS_MOUNT_MAP_SPECIAL_CHR);
688 if (rc==0) { 698 if (rc == 0) {
689 rc = CIFSSMBSetFileTimes(xid, pTcon, 699 rc = CIFSSMBSetFileTimes(xid, pTcon,
690 pinfo_buf, 700 pinfo_buf,
691 netfid); 701 netfid);
@@ -694,10 +704,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
694 } 704 }
695 kfree(pinfo_buf); 705 kfree(pinfo_buf);
696 } 706 }
697 if (rc==0) { 707 if (rc == 0) {
698 rc = CIFSSMBDelFile(xid, pTcon, full_path, 708 rc = CIFSSMBDelFile(xid, pTcon, full_path,
699 cifs_sb->local_nls, 709 cifs_sb->local_nls,
700 cifs_sb->mnt_cifs_flags & 710 cifs_sb->mnt_cifs_flags &
701 CIFS_MOUNT_MAP_SPECIAL_CHR); 711 CIFS_MOUNT_MAP_SPECIAL_CHR);
702 if (!rc) { 712 if (!rc) {
703 if (direntry->d_inode) 713 if (direntry->d_inode)
@@ -711,10 +721,10 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
711 CREATE_NOT_DIR | 721 CREATE_NOT_DIR |
712 CREATE_DELETE_ON_CLOSE, 722 CREATE_DELETE_ON_CLOSE,
713 &netfid, &oplock, NULL, 723 &netfid, &oplock, NULL,
714 cifs_sb->local_nls, 724 cifs_sb->local_nls,
715 cifs_sb->mnt_cifs_flags & 725 cifs_sb->mnt_cifs_flags &
716 CIFS_MOUNT_MAP_SPECIAL_CHR); 726 CIFS_MOUNT_MAP_SPECIAL_CHR);
717 if (rc==0) { 727 if (rc == 0) {
718 CIFSSMBRenameOpenFile(xid, pTcon, 728 CIFSSMBRenameOpenFile(xid, pTcon,
719 netfid, NULL, 729 netfid, NULL,
720 cifs_sb->local_nls, 730 cifs_sb->local_nls,
@@ -773,8 +783,8 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
773 783
774 tmp_inode->i_mode = le64_to_cpu(pData->Permissions); 784 tmp_inode->i_mode = le64_to_cpu(pData->Permissions);
775 /* since we set the inode type below we need to mask off type 785 /* since we set the inode type below we need to mask off type
776 to avoid strange results if bits above were corrupt */ 786 to avoid strange results if bits above were corrupt */
777 tmp_inode->i_mode &= ~S_IFMT; 787 tmp_inode->i_mode &= ~S_IFMT;
778 if (type == UNIX_FILE) { 788 if (type == UNIX_FILE) {
779 *pobject_type = DT_REG; 789 *pobject_type = DT_REG;
780 tmp_inode->i_mode |= S_IFREG; 790 tmp_inode->i_mode |= S_IFREG;
@@ -804,11 +814,11 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
804 /* safest to just call it a file */ 814 /* safest to just call it a file */
805 *pobject_type = DT_REG; 815 *pobject_type = DT_REG;
806 tmp_inode->i_mode |= S_IFREG; 816 tmp_inode->i_mode |= S_IFREG;
807 cFYI(1,("unknown inode type %d",type)); 817 cFYI(1, ("unknown inode type %d", type));
808 } 818 }
809 819
810#ifdef CONFIG_CIFS_DEBUG2 820#ifdef CONFIG_CIFS_DEBUG2
811 cFYI(1,("object type: %d", type)); 821 cFYI(1, ("object type: %d", type));
812#endif 822#endif
813 tmp_inode->i_uid = le64_to_cpu(pData->Uid); 823 tmp_inode->i_uid = le64_to_cpu(pData->Uid);
814 tmp_inode->i_gid = le64_to_cpu(pData->Gid); 824 tmp_inode->i_gid = le64_to_cpu(pData->Gid);
@@ -816,7 +826,7 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
816 826
817 spin_lock(&tmp_inode->i_lock); 827 spin_lock(&tmp_inode->i_lock);
818 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 828 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
819 /* can not safely change the file size here if the 829 /* can not safely change the file size here if the
820 client is writing to it due to potential races */ 830 client is writing to it due to potential races */
821 i_size_write(tmp_inode, end_of_file); 831 i_size_write(tmp_inode, end_of_file);
822 832
@@ -830,27 +840,28 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
830 cFYI(1, ("File inode")); 840 cFYI(1, ("File inode"));
831 tmp_inode->i_op = &cifs_file_inode_ops; 841 tmp_inode->i_op = &cifs_file_inode_ops;
832 842
833 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 843 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
834 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 844 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
835 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 845 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
836 else 846 else
837 tmp_inode->i_fop = &cifs_file_direct_ops; 847 tmp_inode->i_fop = &cifs_file_direct_ops;
838 848
839 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 849 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
840 tmp_inode->i_fop = &cifs_file_nobrl_ops; 850 tmp_inode->i_fop = &cifs_file_nobrl_ops;
841 else 851 else
842 tmp_inode->i_fop = &cifs_file_ops; 852 tmp_inode->i_fop = &cifs_file_ops;
843 853
844 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 854 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
845 (cifs_sb->tcon->ses->server->maxBuf < 855 (cifs_sb->tcon->ses->server->maxBuf <
846 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 856 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
847 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 857 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
848 else 858 else
849 tmp_inode->i_data.a_ops = &cifs_addr_ops; 859 tmp_inode->i_data.a_ops = &cifs_addr_ops;
850 860
851 if(isNewInode) 861 if (isNewInode)
852 return; /* No sense invalidating pages for new inode since we 862 return; /* No sense invalidating pages for new inode
853 have not started caching readahead file data yet */ 863 since we we have not started caching
864 readahead file data yet */
854 865
855 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 866 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
856 (local_size == tmp_inode->i_size)) { 867 (local_size == tmp_inode->i_size)) {
@@ -869,10 +880,10 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
869 tmp_inode->i_op = &cifs_symlink_inode_ops; 880 tmp_inode->i_op = &cifs_symlink_inode_ops;
870/* tmp_inode->i_fop = *//* do not need to set to anything */ 881/* tmp_inode->i_fop = *//* do not need to set to anything */
871 } else { 882 } else {
872 cFYI(1, ("Special inode")); 883 cFYI(1, ("Special inode"));
873 init_special_inode(tmp_inode, tmp_inode->i_mode, 884 init_special_inode(tmp_inode, tmp_inode->i_mode,
874 tmp_inode->i_rdev); 885 tmp_inode->i_rdev);
875 } 886 }
876} 887}
877 888
878int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 889int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
@@ -896,22 +907,22 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
896 FreeXid(xid); 907 FreeXid(xid);
897 return -ENOMEM; 908 return -ENOMEM;
898 } 909 }
899 910
900 if((pTcon->ses->capabilities & CAP_UNIX) && 911 if ((pTcon->ses->capabilities & CAP_UNIX) &&
901 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 912 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
902 le64_to_cpu(pTcon->fsUnixInfo.Capability))) { 913 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
903 u32 oplock = 0; 914 u32 oplock = 0;
904 FILE_UNIX_BASIC_INFO * pInfo = 915 FILE_UNIX_BASIC_INFO * pInfo =
905 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 916 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
906 if(pInfo == NULL) { 917 if (pInfo == NULL) {
907 rc = -ENOMEM; 918 rc = -ENOMEM;
908 goto mkdir_out; 919 goto mkdir_out;
909 } 920 }
910 921
911 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, 922 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
912 mode, NULL /* netfid */, pInfo, &oplock, 923 mode, NULL /* netfid */, pInfo, &oplock,
913 full_path, cifs_sb->local_nls, 924 full_path, cifs_sb->local_nls,
914 cifs_sb->mnt_cifs_flags & 925 cifs_sb->mnt_cifs_flags &
915 CIFS_MOUNT_MAP_SPECIAL_CHR); 926 CIFS_MOUNT_MAP_SPECIAL_CHR);
916 if (rc) { 927 if (rc) {
917 cFYI(1, ("posix mkdir returned 0x%x", rc)); 928 cFYI(1, ("posix mkdir returned 0x%x", rc));
@@ -919,8 +930,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
919 } else { 930 } else {
920 int obj_type; 931 int obj_type;
921 if (pInfo->Type == -1) /* no return info - go query */ 932 if (pInfo->Type == -1) /* no return info - go query */
922 goto mkdir_get_info; 933 goto mkdir_get_info;
923/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */ 934/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
935 to set uid/gid */
924 inc_nlink(inode); 936 inc_nlink(inode);
925 if (pTcon->nocase) 937 if (pTcon->nocase)
926 direntry->d_op = &cifs_ci_dentry_ops; 938 direntry->d_op = &cifs_ci_dentry_ops;
@@ -937,7 +949,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
937 newinode->i_ino = 949 newinode->i_ino =
938 (unsigned long)pInfo->UniqueId; 950 (unsigned long)pInfo->UniqueId;
939 } /* note ino incremented to unique num in new_inode */ 951 } /* note ino incremented to unique num in new_inode */
940 if(inode->i_sb->s_flags & MS_NOATIME) 952 if (inode->i_sb->s_flags & MS_NOATIME)
941 newinode->i_flags |= S_NOATIME | S_NOCMTIME; 953 newinode->i_flags |= S_NOATIME | S_NOCMTIME;
942 newinode->i_nlink = 2; 954 newinode->i_nlink = 2;
943 955
@@ -949,18 +961,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
949 posix_fill_in_inode(direntry->d_inode, 961 posix_fill_in_inode(direntry->d_inode,
950 pInfo, &obj_type, 1 /* NewInode */); 962 pInfo, &obj_type, 1 /* NewInode */);
951#ifdef CONFIG_CIFS_DEBUG2 963#ifdef CONFIG_CIFS_DEBUG2
952 cFYI(1,("instantiated dentry %p %s to inode %p", 964 cFYI(1, ("instantiated dentry %p %s to inode %p",
953 direntry, direntry->d_name.name, newinode)); 965 direntry, direntry->d_name.name, newinode));
954 966
955 if(newinode->i_nlink != 2) 967 if (newinode->i_nlink != 2)
956 cFYI(1,("unexpected number of links %d", 968 cFYI(1, ("unexpected number of links %d",
957 newinode->i_nlink)); 969 newinode->i_nlink));
958#endif 970#endif
959 } 971 }
960 kfree(pInfo); 972 kfree(pInfo);
961 goto mkdir_out; 973 goto mkdir_out;
962 } 974 }
963 975
964 /* BB add setting the equivalent of mode via CreateX w/ACLs */ 976 /* BB add setting the equivalent of mode via CreateX w/ACLs */
965 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, 977 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
966 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 978 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -968,14 +980,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
968 cFYI(1, ("cifs_mkdir returned 0x%x", rc)); 980 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
969 d_drop(direntry); 981 d_drop(direntry);
970 } else { 982 } else {
971mkdir_get_info: 983mkdir_get_info:
972 inc_nlink(inode); 984 inc_nlink(inode);
973 if (pTcon->ses->capabilities & CAP_UNIX) 985 if (pTcon->unix_ext)
974 rc = cifs_get_inode_info_unix(&newinode, full_path, 986 rc = cifs_get_inode_info_unix(&newinode, full_path,
975 inode->i_sb,xid); 987 inode->i_sb, xid);
976 else 988 else
977 rc = cifs_get_inode_info(&newinode, full_path, NULL, 989 rc = cifs_get_inode_info(&newinode, full_path, NULL,
978 inode->i_sb,xid); 990 inode->i_sb, xid);
979 991
980 if (pTcon->nocase) 992 if (pTcon->nocase)
981 direntry->d_op = &cifs_ci_dentry_ops; 993 direntry->d_op = &cifs_ci_dentry_ops;
@@ -983,10 +995,10 @@ mkdir_get_info:
983 direntry->d_op = &cifs_dentry_ops; 995 direntry->d_op = &cifs_dentry_ops;
984 d_instantiate(direntry, newinode); 996 d_instantiate(direntry, newinode);
985 /* setting nlink not necessary except in cases where we 997 /* setting nlink not necessary except in cases where we
986 * failed to get it from the server or was set bogus */ 998 * failed to get it from the server or was set bogus */
987 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) 999 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
988 direntry->d_inode->i_nlink = 2; 1000 direntry->d_inode->i_nlink = 2;
989 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1001 if (pTcon->unix_ext) {
990 mode &= ~current->fs->umask; 1002 mode &= ~current->fs->umask;
991 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1003 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
992 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 1004 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -1002,27 +1014,27 @@ mkdir_get_info:
1002 mode, (__u64)-1, 1014 mode, (__u64)-1,
1003 (__u64)-1, 0 /* dev_t */, 1015 (__u64)-1, 0 /* dev_t */,
1004 cifs_sb->local_nls, 1016 cifs_sb->local_nls,
1005 cifs_sb->mnt_cifs_flags & 1017 cifs_sb->mnt_cifs_flags &
1006 CIFS_MOUNT_MAP_SPECIAL_CHR); 1018 CIFS_MOUNT_MAP_SPECIAL_CHR);
1007 } 1019 }
1008 } else { 1020 } else {
1009 /* BB to be implemented via Windows secrty descriptors 1021 /* BB to be implemented via Windows secrty descriptors
1010 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, 1022 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
1011 -1, -1, local_nls); */ 1023 -1, -1, local_nls); */
1012 if(direntry->d_inode) { 1024 if (direntry->d_inode) {
1013 direntry->d_inode->i_mode = mode; 1025 direntry->d_inode->i_mode = mode;
1014 direntry->d_inode->i_mode |= S_IFDIR; 1026 direntry->d_inode->i_mode |= S_IFDIR;
1015 if(cifs_sb->mnt_cifs_flags & 1027 if (cifs_sb->mnt_cifs_flags &
1016 CIFS_MOUNT_SET_UID) { 1028 CIFS_MOUNT_SET_UID) {
1017 direntry->d_inode->i_uid = 1029 direntry->d_inode->i_uid =
1018 current->fsuid; 1030 current->fsuid;
1019 direntry->d_inode->i_gid = 1031 direntry->d_inode->i_gid =
1020 current->fsgid; 1032 current->fsgid;
1021 } 1033 }
1022 } 1034 }
1023 } 1035 }
1024 } 1036 }
1025mkdir_out: 1037mkdir_out:
1026 kfree(full_path); 1038 kfree(full_path);
1027 FreeXid(xid); 1039 FreeXid(xid);
1028 return rc; 1040 return rc;
@@ -1056,7 +1068,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1056 if (!rc) { 1068 if (!rc) {
1057 drop_nlink(inode); 1069 drop_nlink(inode);
1058 spin_lock(&direntry->d_inode->i_lock); 1070 spin_lock(&direntry->d_inode->i_lock);
1059 i_size_write(direntry->d_inode,0); 1071 i_size_write(direntry->d_inode, 0);
1060 clear_nlink(direntry->d_inode); 1072 clear_nlink(direntry->d_inode);
1061 spin_unlock(&direntry->d_inode->i_lock); 1073 spin_unlock(&direntry->d_inode->i_lock);
1062 } 1074 }
@@ -1119,9 +1131,9 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1119 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 1131 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1120 if (info_buf_source != NULL) { 1132 if (info_buf_source != NULL) {
1121 info_buf_target = info_buf_source + 1; 1133 info_buf_target = info_buf_source + 1;
1122 if (pTcon->ses->capabilities & CAP_UNIX) 1134 if (pTcon->unix_ext)
1123 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 1135 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1124 info_buf_source, 1136 info_buf_source,
1125 cifs_sb_source->local_nls, 1137 cifs_sb_source->local_nls,
1126 cifs_sb_source->mnt_cifs_flags & 1138 cifs_sb_source->mnt_cifs_flags &
1127 CIFS_MOUNT_MAP_SPECIAL_CHR); 1139 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1171,12 +1183,12 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1171 might not right be right access to request */ 1183 might not right be right access to request */
1172 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, 1184 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
1173 CREATE_NOT_DIR, &netfid, &oplock, NULL, 1185 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1174 cifs_sb_source->local_nls, 1186 cifs_sb_source->local_nls,
1175 cifs_sb_source->mnt_cifs_flags & 1187 cifs_sb_source->mnt_cifs_flags &
1176 CIFS_MOUNT_MAP_SPECIAL_CHR); 1188 CIFS_MOUNT_MAP_SPECIAL_CHR);
1177 if (rc==0) { 1189 if (rc == 0) {
1178 rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, 1190 rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
1179 cifs_sb_source->local_nls, 1191 cifs_sb_source->local_nls,
1180 cifs_sb_source->mnt_cifs_flags & 1192 cifs_sb_source->mnt_cifs_flags &
1181 CIFS_MOUNT_MAP_SPECIAL_CHR); 1193 CIFS_MOUNT_MAP_SPECIAL_CHR);
1182 CIFSSMBClose(xid, pTcon, netfid); 1194 CIFSSMBClose(xid, pTcon, netfid);
@@ -1247,9 +1259,9 @@ int cifs_revalidate(struct dentry *direntry)
1247 local_mtime = direntry->d_inode->i_mtime; 1259 local_mtime = direntry->d_inode->i_mtime;
1248 local_size = direntry->d_inode->i_size; 1260 local_size = direntry->d_inode->i_size;
1249 1261
1250 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { 1262 if (cifs_sb->tcon->unix_ext) {
1251 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, 1263 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1252 direntry->d_sb,xid); 1264 direntry->d_sb, xid);
1253 if (rc) { 1265 if (rc) {
1254 cFYI(1, ("error on getting revalidate info %d", rc)); 1266 cFYI(1, ("error on getting revalidate info %d", rc));
1255/* if (rc != -ENOENT) 1267/* if (rc != -ENOENT)
@@ -1258,7 +1270,7 @@ int cifs_revalidate(struct dentry *direntry)
1258 } 1270 }
1259 } else { 1271 } else {
1260 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, 1272 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1261 direntry->d_sb,xid); 1273 direntry->d_sb, xid);
1262 if (rc) { 1274 if (rc) {
1263 cFYI(1, ("error on getting revalidate info %d", rc)); 1275 cFYI(1, ("error on getting revalidate info %d", rc));
1264/* if (rc != -ENOENT) 1276/* if (rc != -ENOENT)
@@ -1271,7 +1283,7 @@ int cifs_revalidate(struct dentry *direntry)
1271 /* if not oplocked, we invalidate inode pages if mtime or file size 1283 /* if not oplocked, we invalidate inode pages if mtime or file size
1272 had changed on server */ 1284 had changed on server */
1273 1285
1274 if (timespec_equal(&local_mtime,&direntry->d_inode->i_mtime) && 1286 if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1275 (local_size == direntry->d_inode->i_size)) { 1287 (local_size == direntry->d_inode->i_size)) {
1276 cFYI(1, ("cifs_revalidate - inode unchanged")); 1288 cFYI(1, ("cifs_revalidate - inode unchanged"));
1277 } else { 1289 } else {
@@ -1298,7 +1310,7 @@ int cifs_revalidate(struct dentry *direntry)
1298 if (invalidate_inode) { 1310 if (invalidate_inode) {
1299 /* shrink_dcache not necessary now that cifs dentry ops 1311 /* shrink_dcache not necessary now that cifs dentry ops
1300 are exported for negative dentries */ 1312 are exported for negative dentries */
1301/* if(S_ISDIR(direntry->d_inode->i_mode)) 1313/* if (S_ISDIR(direntry->d_inode->i_mode))
1302 shrink_dcache_parent(direntry); */ 1314 shrink_dcache_parent(direntry); */
1303 if (S_ISREG(direntry->d_inode->i_mode)) { 1315 if (S_ISREG(direntry->d_inode->i_mode)) {
1304 if (direntry->d_inode->i_mapping) 1316 if (direntry->d_inode->i_mapping)
@@ -1313,7 +1325,7 @@ int cifs_revalidate(struct dentry *direntry)
1313 } 1325 }
1314 } 1326 }
1315/* mutex_unlock(&direntry->d_inode->i_mutex); */ 1327/* mutex_unlock(&direntry->d_inode->i_mutex); */
1316 1328
1317 kfree(full_path); 1329 kfree(full_path);
1318 FreeXid(xid); 1330 FreeXid(xid);
1319 return rc; 1331 return rc;
@@ -1335,23 +1347,19 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1335 pgoff_t index = from >> PAGE_CACHE_SHIFT; 1347 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1336 unsigned offset = from & (PAGE_CACHE_SIZE - 1); 1348 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1337 struct page *page; 1349 struct page *page;
1338 char *kaddr;
1339 int rc = 0; 1350 int rc = 0;
1340 1351
1341 page = grab_cache_page(mapping, index); 1352 page = grab_cache_page(mapping, index);
1342 if (!page) 1353 if (!page)
1343 return -ENOMEM; 1354 return -ENOMEM;
1344 1355
1345 kaddr = kmap_atomic(page, KM_USER0); 1356 zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0);
1346 memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
1347 flush_dcache_page(page);
1348 kunmap_atomic(kaddr, KM_USER0);
1349 unlock_page(page); 1357 unlock_page(page);
1350 page_cache_release(page); 1358 page_cache_release(page);
1351 return rc; 1359 return rc;
1352} 1360}
1353 1361
1354static int cifs_vmtruncate(struct inode * inode, loff_t offset) 1362static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1355{ 1363{
1356 struct address_space *mapping = inode->i_mapping; 1364 struct address_space *mapping = inode->i_mapping;
1357 unsigned long limit; 1365 unsigned long limit;
@@ -1424,13 +1432,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1424 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1432 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1425 /* check if we have permission to change attrs */ 1433 /* check if we have permission to change attrs */
1426 rc = inode_change_ok(direntry->d_inode, attrs); 1434 rc = inode_change_ok(direntry->d_inode, attrs);
1427 if(rc < 0) { 1435 if (rc < 0) {
1428 FreeXid(xid); 1436 FreeXid(xid);
1429 return rc; 1437 return rc;
1430 } else 1438 } else
1431 rc = 0; 1439 rc = 0;
1432 } 1440 }
1433 1441
1434 full_path = build_path_from_dentry(direntry); 1442 full_path = build_path_from_dentry(direntry);
1435 if (full_path == NULL) { 1443 if (full_path == NULL) {
1436 FreeXid(xid); 1444 FreeXid(xid);
@@ -1459,16 +1467,16 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1459 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, 1467 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
1460 nfid, npid, FALSE); 1468 nfid, npid, FALSE);
1461 atomic_dec(&open_file->wrtPending); 1469 atomic_dec(&open_file->wrtPending);
1462 cFYI(1,("SetFSize for attrs rc = %d", rc)); 1470 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1463 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1471 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1464 int bytes_written; 1472 int bytes_written;
1465 rc = CIFSSMBWrite(xid, pTcon, 1473 rc = CIFSSMBWrite(xid, pTcon,
1466 nfid, 0, attrs->ia_size, 1474 nfid, 0, attrs->ia_size,
1467 &bytes_written, NULL, NULL, 1475 &bytes_written, NULL, NULL,
1468 1 /* 45 seconds */); 1476 1 /* 45 seconds */);
1469 cFYI(1,("Wrt seteof rc %d", rc)); 1477 cFYI(1, ("Wrt seteof rc %d", rc));
1470 } 1478 }
1471 } else 1479 } else
1472 rc = -EINVAL; 1480 rc = -EINVAL;
1473 1481
1474 if (rc != 0) { 1482 if (rc != 0) {
@@ -1478,11 +1486,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1478 it by handle */ 1486 it by handle */
1479 rc = CIFSSMBSetEOF(xid, pTcon, full_path, 1487 rc = CIFSSMBSetEOF(xid, pTcon, full_path,
1480 attrs->ia_size, FALSE, 1488 attrs->ia_size, FALSE,
1481 cifs_sb->local_nls, 1489 cifs_sb->local_nls,
1482 cifs_sb->mnt_cifs_flags & 1490 cifs_sb->mnt_cifs_flags &
1483 CIFS_MOUNT_MAP_SPECIAL_CHR); 1491 CIFS_MOUNT_MAP_SPECIAL_CHR);
1484 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); 1492 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1485 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1493 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1486 __u16 netfid; 1494 __u16 netfid;
1487 int oplock = FALSE; 1495 int oplock = FALSE;
1488 1496
@@ -1493,14 +1501,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1493 NULL, cifs_sb->local_nls, 1501 NULL, cifs_sb->local_nls,
1494 cifs_sb->mnt_cifs_flags & 1502 cifs_sb->mnt_cifs_flags &
1495 CIFS_MOUNT_MAP_SPECIAL_CHR); 1503 CIFS_MOUNT_MAP_SPECIAL_CHR);
1496 if (rc==0) { 1504 if (rc == 0) {
1497 int bytes_written; 1505 int bytes_written;
1498 rc = CIFSSMBWrite(xid, pTcon, 1506 rc = CIFSSMBWrite(xid, pTcon,
1499 netfid, 0, 1507 netfid, 0,
1500 attrs->ia_size, 1508 attrs->ia_size,
1501 &bytes_written, NULL, 1509 &bytes_written, NULL,
1502 NULL, 1 /* 45 sec */); 1510 NULL, 1 /* 45 sec */);
1503 cFYI(1,("wrt seteof rc %d",rc)); 1511 cFYI(1, ("wrt seteof rc %d", rc));
1504 CIFSSMBClose(xid, pTcon, netfid); 1512 CIFSSMBClose(xid, pTcon, netfid);
1505 } 1513 }
1506 1514
@@ -1517,7 +1525,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1517 rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size); 1525 rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
1518 cifs_truncate_page(direntry->d_inode->i_mapping, 1526 cifs_truncate_page(direntry->d_inode->i_mapping,
1519 direntry->d_inode->i_size); 1527 direntry->d_inode->i_size);
1520 } else 1528 } else
1521 goto cifs_setattr_exit; 1529 goto cifs_setattr_exit;
1522 } 1530 }
1523 if (attrs->ia_valid & ATTR_UID) { 1531 if (attrs->ia_valid & ATTR_UID) {
@@ -1535,11 +1543,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1535 mode = attrs->ia_mode; 1543 mode = attrs->ia_mode;
1536 } 1544 }
1537 1545
1538 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) 1546 if ((pTcon->unix_ext)
1539 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID))) 1547 && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1540 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid, 1548 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1541 0 /* dev_t */, cifs_sb->local_nls, 1549 0 /* dev_t */, cifs_sb->local_nls,
1542 cifs_sb->mnt_cifs_flags & 1550 cifs_sb->mnt_cifs_flags &
1543 CIFS_MOUNT_MAP_SPECIAL_CHR); 1551 CIFS_MOUNT_MAP_SPECIAL_CHR);
1544 else if (attrs->ia_valid & ATTR_MODE) { 1552 else if (attrs->ia_valid & ATTR_MODE) {
1545 rc = 0; 1553 rc = 0;
@@ -1559,7 +1567,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1559 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs & 1567 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1560 (~ATTR_READONLY)); 1568 (~ATTR_READONLY));
1561 /* Windows ignores set to zero */ 1569 /* Windows ignores set to zero */
1562 if(time_buf.Attributes == 0) 1570 if (time_buf.Attributes == 0)
1563 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); 1571 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1564 } 1572 }
1565 /* BB to be implemented - 1573 /* BB to be implemented -
@@ -1585,7 +1593,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1585 stamps are changed explicitly (i.e. by utime() 1593 stamps are changed explicitly (i.e. by utime()
1586 since we would then have a mix of client and 1594 since we would then have a mix of client and
1587 server times */ 1595 server times */
1588 1596
1589 if (set_time && (attrs->ia_valid & ATTR_CTIME)) { 1597 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1590 set_time = TRUE; 1598 set_time = TRUE;
1591 /* Although Samba throws this field away 1599 /* Although Samba throws this field away
@@ -1624,7 +1632,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1624 NULL, cifs_sb->local_nls, 1632 NULL, cifs_sb->local_nls,
1625 cifs_sb->mnt_cifs_flags & 1633 cifs_sb->mnt_cifs_flags &
1626 CIFS_MOUNT_MAP_SPECIAL_CHR); 1634 CIFS_MOUNT_MAP_SPECIAL_CHR);
1627 if (rc==0) { 1635 if (rc == 0) {
1628 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf, 1636 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
1629 netfid); 1637 netfid);
1630 CIFSSMBClose(xid, pTcon, netfid); 1638 CIFSSMBClose(xid, pTcon, netfid);
@@ -1634,7 +1642,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1634 granularity */ 1642 granularity */
1635 1643
1636 /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path, 1644 /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
1637 &time_buf, cifs_sb->local_nls); */ 1645 &time_buf, cifs_sb->local_nls); */
1638 } 1646 }
1639 } 1647 }
1640 /* Even if error on time set, no sense failing the call if 1648 /* Even if error on time set, no sense failing the call if
@@ -1642,7 +1650,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1642 and this check ensures that we are not being called from 1650 and this check ensures that we are not being called from
1643 sys_utimes in which case we ought to fail the call back to 1651 sys_utimes in which case we ought to fail the call back to
1644 the user when the server rejects the call */ 1652 the user when the server rejects the call */
1645 if((rc) && (attrs->ia_valid & 1653 if ((rc) && (attrs->ia_valid &
1646 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) 1654 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1647 rc = 0; 1655 rc = 0;
1648 } 1656 }
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index a414f1775ae0..d24fe6880a04 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * vfs operations that deal with io control 4 * vfs operations that deal with io control
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2005 6 * Copyright (C) International Business Machines Corp., 2005,2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -30,7 +30,7 @@
30 30
31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) 31#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
32 32
33int cifs_ioctl (struct inode * inode, struct file * filep, 33int cifs_ioctl (struct inode *inode, struct file *filep,
34 unsigned int command, unsigned long arg) 34 unsigned int command, unsigned long arg)
35{ 35{
36 int rc = -ENOTTY; /* strange error - but the precedent */ 36 int rc = -ENOTTY; /* strange error - but the precedent */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6baea85d726e..6a85ef7b8797 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -50,32 +50,33 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
50 50
51 fromName = build_path_from_dentry(old_file); 51 fromName = build_path_from_dentry(old_file);
52 toName = build_path_from_dentry(direntry); 52 toName = build_path_from_dentry(direntry);
53 if((fromName == NULL) || (toName == NULL)) { 53 if ((fromName == NULL) || (toName == NULL)) {
54 rc = -ENOMEM; 54 rc = -ENOMEM;
55 goto cifs_hl_exit; 55 goto cifs_hl_exit;
56 } 56 }
57 57
58 if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) 58/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/
59 if (pTcon->unix_ext)
59 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 60 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
60 cifs_sb_target->local_nls, 61 cifs_sb_target->local_nls,
61 cifs_sb_target->mnt_cifs_flags & 62 cifs_sb_target->mnt_cifs_flags &
62 CIFS_MOUNT_MAP_SPECIAL_CHR); 63 CIFS_MOUNT_MAP_SPECIAL_CHR);
63 else { 64 else {
64 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, 65 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
65 cifs_sb_target->local_nls, 66 cifs_sb_target->local_nls,
66 cifs_sb_target->mnt_cifs_flags & 67 cifs_sb_target->mnt_cifs_flags &
67 CIFS_MOUNT_MAP_SPECIAL_CHR); 68 CIFS_MOUNT_MAP_SPECIAL_CHR);
68 if((rc == -EIO) || (rc == -EINVAL)) 69 if ((rc == -EIO) || (rc == -EINVAL))
69 rc = -EOPNOTSUPP; 70 rc = -EOPNOTSUPP;
70 } 71 }
71 72
72 d_drop(direntry); /* force new lookup from server of target */ 73 d_drop(direntry); /* force new lookup from server of target */
73 74
74 /* if source file is cached (oplocked) revalidate will not go to server 75 /* if source file is cached (oplocked) revalidate will not go to server
75 until the file is closed or oplock broken so update nlinks locally */ 76 until the file is closed or oplock broken so update nlinks locally */
76 if(old_file->d_inode) { 77 if (old_file->d_inode) {
77 cifsInode = CIFS_I(old_file->d_inode); 78 cifsInode = CIFS_I(old_file->d_inode);
78 if(rc == 0) { 79 if (rc == 0) {
79 old_file->d_inode->i_nlink++; 80 old_file->d_inode->i_nlink++;
80/* BB should we make this contingent on superblock flag NOATIME? */ 81/* BB should we make this contingent on superblock flag NOATIME? */
81/* old_file->d_inode->i_ctime = CURRENT_TIME;*/ 82/* old_file->d_inode->i_ctime = CURRENT_TIME;*/
@@ -84,14 +85,14 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
84 to set the parent dir cifs inode time to zero 85 to set the parent dir cifs inode time to zero
85 to force revalidate (faster) for it too? */ 86 to force revalidate (faster) for it too? */
86 } 87 }
87 /* if not oplocked will force revalidate to get info 88 /* if not oplocked will force revalidate to get info
88 on source file from srv */ 89 on source file from srv */
89 cifsInode->time = 0; 90 cifsInode->time = 0;
90 91
91 /* Will update parent dir timestamps from srv within a second. 92 /* Will update parent dir timestamps from srv within a second.
92 Would it really be worth it to set the parent dir (cifs 93 Would it really be worth it to set the parent dir (cifs
93 inode) time field to zero to force revalidate on parent 94 inode) time field to zero to force revalidate on parent
94 directory faster ie 95 directory faster ie
95 CIFS_I(inode)->time = 0; */ 96 CIFS_I(inode)->time = 0; */
96 } 97 }
97 98
@@ -109,7 +110,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
109 int rc = -EACCES; 110 int rc = -EACCES;
110 int xid; 111 int xid;
111 char *full_path = NULL; 112 char *full_path = NULL;
112 char * target_path = ERR_PTR(-ENOMEM); 113 char *target_path = ERR_PTR(-ENOMEM);
113 struct cifs_sb_info *cifs_sb; 114 struct cifs_sb_info *cifs_sb;
114 struct cifsTconInfo *pTcon; 115 struct cifsTconInfo *pTcon;
115 116
@@ -129,13 +130,19 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
129 goto out; 130 goto out;
130 } 131 }
131 132
132/* BB add read reparse point symlink code and Unix extensions symlink code here BB */ 133 /* We could change this to:
134 if (pTcon->unix_ext)
135 but there does not seem any point in refusing to
136 get symlink info if we can, even if unix extensions
137 turned off for this mount */
138
133 if (pTcon->ses->capabilities & CAP_UNIX) 139 if (pTcon->ses->capabilities & CAP_UNIX)
134 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 140 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
135 target_path, 141 target_path,
136 PATH_MAX-1, 142 PATH_MAX-1,
137 cifs_sb->local_nls); 143 cifs_sb->local_nls);
138 else { 144 else {
145 /* BB add read reparse point symlink code here */
139 /* rc = CIFSSMBQueryReparseLinkInfo */ 146 /* rc = CIFSSMBQueryReparseLinkInfo */
140 /* BB Add code to Query ReparsePoint info */ 147 /* BB Add code to Query ReparsePoint info */
141 /* BB Add MAC style xsymlink check here if enabled */ 148 /* BB Add MAC style xsymlink check here if enabled */
@@ -176,7 +183,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
176 183
177 full_path = build_path_from_dentry(direntry); 184 full_path = build_path_from_dentry(direntry);
178 185
179 if(full_path == NULL) { 186 if (full_path == NULL) {
180 FreeXid(xid); 187 FreeXid(xid);
181 return -ENOMEM; 188 return -ENOMEM;
182 } 189 }
@@ -185,19 +192,20 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
185 cFYI(1, ("symname is %s", symname)); 192 cFYI(1, ("symname is %s", symname));
186 193
187 /* BB what if DFS and this volume is on different share? BB */ 194 /* BB what if DFS and this volume is on different share? BB */
188 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 195 if (pTcon->unix_ext)
189 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 196 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
190 cifs_sb->local_nls); 197 cifs_sb->local_nls);
191 /* else 198 /* else
192 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,cifs_sb_target->local_nls); */ 199 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
200 cifs_sb_target->local_nls); */
193 201
194 if (rc == 0) { 202 if (rc == 0) {
195 if (pTcon->ses->capabilities & CAP_UNIX) 203 if (pTcon->unix_ext)
196 rc = cifs_get_inode_info_unix(&newinode, full_path, 204 rc = cifs_get_inode_info_unix(&newinode, full_path,
197 inode->i_sb,xid); 205 inode->i_sb, xid);
198 else 206 else
199 rc = cifs_get_inode_info(&newinode, full_path, NULL, 207 rc = cifs_get_inode_info(&newinode, full_path, NULL,
200 inode->i_sb,xid); 208 inode->i_sb, xid);
201 209
202 if (rc != 0) { 210 if (rc != 0) {
203 cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", 211 cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d",
@@ -226,9 +234,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
226 struct cifs_sb_info *cifs_sb; 234 struct cifs_sb_info *cifs_sb;
227 struct cifsTconInfo *pTcon; 235 struct cifsTconInfo *pTcon;
228 char *full_path = NULL; 236 char *full_path = NULL;
229 char *tmp_path = NULL; 237 char *tmp_path = NULL;
230 char * tmpbuffer; 238 char *tmpbuffer;
231 unsigned char * referrals = NULL; 239 unsigned char *referrals = NULL;
232 int num_referrals = 0; 240 int num_referrals = 0;
233 int len; 241 int len;
234 __u16 fid; 242 __u16 fid;
@@ -237,13 +245,13 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
237 cifs_sb = CIFS_SB(inode->i_sb); 245 cifs_sb = CIFS_SB(inode->i_sb);
238 pTcon = cifs_sb->tcon; 246 pTcon = cifs_sb->tcon;
239 247
240/* BB would it be safe against deadlock to grab this sem 248/* BB would it be safe against deadlock to grab this sem
241 even though rename itself grabs the sem and calls lookup? */ 249 even though rename itself grabs the sem and calls lookup? */
242/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/ 250/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
243 full_path = build_path_from_dentry(direntry); 251 full_path = build_path_from_dentry(direntry);
244/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/ 252/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
245 253
246 if(full_path == NULL) { 254 if (full_path == NULL) {
247 FreeXid(xid); 255 FreeXid(xid);
248 return -ENOMEM; 256 return -ENOMEM;
249 } 257 }
@@ -251,70 +259,80 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
251 cFYI(1, 259 cFYI(1,
252 ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d", 260 ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
253 full_path, inode, pBuffer, buflen)); 261 full_path, inode, pBuffer, buflen));
254 if(buflen > PATH_MAX) 262 if (buflen > PATH_MAX)
255 len = PATH_MAX; 263 len = PATH_MAX;
256 else 264 else
257 len = buflen; 265 len = buflen;
258 tmpbuffer = kmalloc(len,GFP_KERNEL); 266 tmpbuffer = kmalloc(len, GFP_KERNEL);
259 if(tmpbuffer == NULL) { 267 if (tmpbuffer == NULL) {
260 kfree(full_path); 268 kfree(full_path);
261 FreeXid(xid); 269 FreeXid(xid);
262 return -ENOMEM; 270 return -ENOMEM;
263 } 271 }
264 272
265/* BB add read reparse point symlink code and Unix extensions symlink code here BB */ 273/* BB add read reparse point symlink code and
274 Unix extensions symlink code here BB */
275/* We could disable this based on pTcon->unix_ext flag instead ... but why? */
266 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 276 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
267 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path, 277 rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
268 tmpbuffer, 278 tmpbuffer,
269 len - 1, 279 len - 1,
270 cifs_sb->local_nls); 280 cifs_sb->local_nls);
271 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 281 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
272 cERROR(1,("SFU style symlinks not implemented yet")); 282 cERROR(1, ("SFU style symlinks not implemented yet"));
273 /* add open and read as in fs/cifs/inode.c */ 283 /* add open and read as in fs/cifs/inode.c */
274
275 } else { 284 } else {
276 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 285 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
277 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 286 OPEN_REPARSE_POINT, &fid, &oplock, NULL,
278 cifs_sb->local_nls, 287 cifs_sb->local_nls,
279 cifs_sb->mnt_cifs_flags & 288 cifs_sb->mnt_cifs_flags &
280 CIFS_MOUNT_MAP_SPECIAL_CHR); 289 CIFS_MOUNT_MAP_SPECIAL_CHR);
281 if(!rc) { 290 if (!rc) {
282 rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, 291 rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
283 tmpbuffer, 292 tmpbuffer,
284 len - 1, 293 len - 1,
285 fid, 294 fid,
286 cifs_sb->local_nls); 295 cifs_sb->local_nls);
287 if(CIFSSMBClose(xid, pTcon, fid)) { 296 if (CIFSSMBClose(xid, pTcon, fid)) {
288 cFYI(1,("Error closing junction point (open for ioctl)")); 297 cFYI(1, ("Error closing junction point "
298 "(open for ioctl)"));
289 } 299 }
290 if(rc == -EIO) { 300 if (rc == -EIO) {
291 /* Query if DFS Junction */ 301 /* Query if DFS Junction */
292 tmp_path = 302 tmp_path =
293 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1, 303 kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,
294 GFP_KERNEL); 304 GFP_KERNEL);
295 if (tmp_path) { 305 if (tmp_path) {
296 strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 306 strncpy(tmp_path, pTcon->treeName,
297 strncat(tmp_path, full_path, MAX_PATHCONF); 307 MAX_TREE_SIZE);
298 rc = get_dfs_path(xid, pTcon->ses, tmp_path, 308 strncat(tmp_path, full_path,
309 MAX_PATHCONF);
310 rc = get_dfs_path(xid, pTcon->ses,
311 tmp_path,
299 cifs_sb->local_nls, 312 cifs_sb->local_nls,
300 &num_referrals, &referrals, 313 &num_referrals, &referrals,
301 cifs_sb->mnt_cifs_flags & 314 cifs_sb->mnt_cifs_flags &
302 CIFS_MOUNT_MAP_SPECIAL_CHR); 315 CIFS_MOUNT_MAP_SPECIAL_CHR);
303 cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc)); 316 cFYI(1, ("Get DFS for %s rc = %d ",
304 if((num_referrals == 0) && (rc == 0)) 317 tmp_path, rc));
318 if ((num_referrals == 0) && (rc == 0))
305 rc = -EACCES; 319 rc = -EACCES;
306 else { 320 else {
307 cFYI(1,("num referral: %d",num_referrals)); 321 cFYI(1, ("num referral: %d",
308 if(referrals) { 322 num_referrals));
309 cFYI(1,("referral string: %s",referrals)); 323 if (referrals) {
310 strncpy(tmpbuffer, referrals, len-1); 324 cFYI(1,("referral string: %s", referrals));
325 strncpy(tmpbuffer,
326 referrals,
327 len-1);
311 } 328 }
312 } 329 }
313 kfree(referrals); 330 kfree(referrals);
314 kfree(tmp_path); 331 kfree(tmp_path);
315} 332}
316 /* BB add code like else decode referrals then memcpy to 333 /* BB add code like else decode referrals
317 tmpbuffer and free referrals string array BB */ 334 then memcpy to tmpbuffer and free referrals
335 string array BB */
318 } 336 }
319 } 337 }
320 } 338 }
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c
index 46d62c9dda0f..a2415c1a14db 100644
--- a/fs/cifs/md4.c
+++ b/fs/cifs/md4.c
@@ -1,20 +1,20 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 a implementation of MD4 designed for use in the SMB authentication protocol 4 a implementation of MD4 designed for use in the SMB authentication protocol
5 Copyright (C) Andrew Tridgell 1997-1998. 5 Copyright (C) Andrew Tridgell 1997-1998.
6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003 6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -170,7 +170,7 @@ mdfour(unsigned char *out, unsigned char *in, int n)
170 170
171 while (n > 64) { 171 while (n > 64) {
172 copy64(M, in); 172 copy64(M, in);
173 mdfour64(M,&A,&B, &C, &D); 173 mdfour64(M, &A, &B, &C, &D);
174 in += 64; 174 in += 64;
175 n -= 64; 175 n -= 64;
176 } 176 }
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
index ccebf9b7eb86..e5c3e1212697 100644
--- a/fs/cifs/md5.c
+++ b/fs/cifs/md5.c
@@ -15,9 +15,9 @@
15 * will fill a supplied 16-byte array with the digest. 15 * will fill a supplied 16-byte array with the digest.
16 */ 16 */
17 17
18/* This code slightly modified to fit into Samba by 18/* This code slightly modified to fit into Samba by
19 abartlet@samba.org Jun 2001 19 abartlet@samba.org Jun 2001
20 and to fit the cifs vfs by 20 and to fit the cifs vfs by
21 Steve French sfrench@us.ibm.com */ 21 Steve French sfrench@us.ibm.com */
22 22
23#include <linux/string.h> 23#include <linux/string.h>
@@ -106,7 +106,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
106} 106}
107 107
108/* 108/*
109 * Final wrapup - pad to 64-byte boundary with the bit pattern 109 * Final wrapup - pad to 64-byte boundary with the bit pattern
110 * 1 0* (64-bit count of bits processed, MSB-first) 110 * 1 0* (64-bit count of bits processed, MSB-first)
111 */ 111 */
112void 112void
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 19cc294c7c70..0bcec0844bee 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/misc.c 2 * fs/cifs/misc.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/slab.h> 22#include <linux/slab.h>
@@ -32,12 +32,12 @@
32 32
33extern mempool_t *cifs_sm_req_poolp; 33extern mempool_t *cifs_sm_req_poolp;
34extern mempool_t *cifs_req_poolp; 34extern mempool_t *cifs_req_poolp;
35extern struct task_struct * oplockThread; 35extern struct task_struct *oplockThread;
36 36
37/* The xid serves as a useful identifier for each incoming vfs request, 37/* The xid serves as a useful identifier for each incoming vfs request,
38 in a similar way to the mid which is useful to track each sent smb, 38 in a similar way to the mid which is useful to track each sent smb,
39 and CurrentXid can also provide a running counter (although it 39 and CurrentXid can also provide a running counter (although it
40 will eventually wrap past zero) of the total vfs operations handled 40 will eventually wrap past zero) of the total vfs operations handled
41 since the cifs fs was mounted */ 41 since the cifs fs was mounted */
42 42
43unsigned int 43unsigned int
@@ -47,10 +47,12 @@ _GetXid(void)
47 47
48 spin_lock(&GlobalMid_Lock); 48 spin_lock(&GlobalMid_Lock);
49 GlobalTotalActiveXid++; 49 GlobalTotalActiveXid++;
50
51 /* keep high water mark for number of simultaneous ops in filesystem */
50 if (GlobalTotalActiveXid > GlobalMaxActiveXid) 52 if (GlobalTotalActiveXid > GlobalMaxActiveXid)
51 GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ 53 GlobalMaxActiveXid = GlobalTotalActiveXid;
52 if(GlobalTotalActiveXid > 65000) 54 if (GlobalTotalActiveXid > 65000)
53 cFYI(1,("warning: more than 65000 requests active")); 55 cFYI(1, ("warning: more than 65000 requests active"));
54 xid = GlobalCurrentXid++; 56 xid = GlobalCurrentXid++;
55 spin_unlock(&GlobalMid_Lock); 57 spin_unlock(&GlobalMid_Lock);
56 return xid; 58 return xid;
@@ -60,7 +62,7 @@ void
60_FreeXid(unsigned int xid) 62_FreeXid(unsigned int xid)
61{ 63{
62 spin_lock(&GlobalMid_Lock); 64 spin_lock(&GlobalMid_Lock);
63 /* if(GlobalTotalActiveXid == 0) 65 /* if (GlobalTotalActiveXid == 0)
64 BUG(); */ 66 BUG(); */
65 GlobalTotalActiveXid--; 67 GlobalTotalActiveXid--;
66 spin_unlock(&GlobalMid_Lock); 68 spin_unlock(&GlobalMid_Lock);
@@ -144,12 +146,12 @@ cifs_buf_get(void)
144{ 146{
145 struct smb_hdr *ret_buf = NULL; 147 struct smb_hdr *ret_buf = NULL;
146 148
147/* We could use negotiated size instead of max_msgsize - 149/* We could use negotiated size instead of max_msgsize -
148 but it may be more efficient to always alloc same size 150 but it may be more efficient to always alloc same size
149 albeit slightly larger than necessary and maxbuffersize 151 albeit slightly larger than necessary and maxbuffersize
150 defaults to this and can not be bigger */ 152 defaults to this and can not be bigger */
151 ret_buf = 153 ret_buf = (struct smb_hdr *) mempool_alloc(cifs_req_poolp,
152 (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); 154 GFP_KERNEL | GFP_NOFS);
153 155
154 /* clear the first few header bytes */ 156 /* clear the first few header bytes */
155 /* for most paths, more is cleared in header_assemble */ 157 /* for most paths, more is cleared in header_assemble */
@@ -172,7 +174,7 @@ cifs_buf_release(void *buf_to_free)
172 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ 174 /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
173 return; 175 return;
174 } 176 }
175 mempool_free(buf_to_free,cifs_req_poolp); 177 mempool_free(buf_to_free, cifs_req_poolp);
176 178
177 atomic_dec(&bufAllocCount); 179 atomic_dec(&bufAllocCount);
178 return; 180 return;
@@ -183,12 +185,12 @@ cifs_small_buf_get(void)
183{ 185{
184 struct smb_hdr *ret_buf = NULL; 186 struct smb_hdr *ret_buf = NULL;
185 187
186/* We could use negotiated size instead of max_msgsize - 188/* We could use negotiated size instead of max_msgsize -
187 but it may be more efficient to always alloc same size 189 but it may be more efficient to always alloc same size
188 albeit slightly larger than necessary and maxbuffersize 190 albeit slightly larger than necessary and maxbuffersize
189 defaults to this and can not be bigger */ 191 defaults to this and can not be bigger */
190 ret_buf = 192 ret_buf = (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp,
191 (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); 193 GFP_KERNEL | GFP_NOFS);
192 if (ret_buf) { 194 if (ret_buf) {
193 /* No need to clear memory here, cleared in header assemble */ 195 /* No need to clear memory here, cleared in header assemble */
194 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ 196 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
@@ -209,30 +211,30 @@ cifs_small_buf_release(void *buf_to_free)
209 cFYI(1, ("Null buffer passed to cifs_small_buf_release")); 211 cFYI(1, ("Null buffer passed to cifs_small_buf_release"));
210 return; 212 return;
211 } 213 }
212 mempool_free(buf_to_free,cifs_sm_req_poolp); 214 mempool_free(buf_to_free, cifs_sm_req_poolp);
213 215
214 atomic_dec(&smBufAllocCount); 216 atomic_dec(&smBufAllocCount);
215 return; 217 return;
216} 218}
217 219
218/* 220/*
219 Find a free multiplex id (SMB mid). Otherwise there could be 221 Find a free multiplex id (SMB mid). Otherwise there could be
220 mid collisions which might cause problems, demultiplexing the 222 mid collisions which might cause problems, demultiplexing the
221 wrong response to this request. Multiplex ids could collide if 223 wrong response to this request. Multiplex ids could collide if
222 one of a series requests takes much longer than the others, or 224 one of a series requests takes much longer than the others, or
223 if a very large number of long lived requests (byte range 225 if a very large number of long lived requests (byte range
224 locks or FindNotify requests) are pending. No more than 226 locks or FindNotify requests) are pending. No more than
225 64K-1 requests can be outstanding at one time. If no 227 64K-1 requests can be outstanding at one time. If no
226 mids are available, return zero. A future optimization 228 mids are available, return zero. A future optimization
227 could make the combination of mids and uid the key we use 229 could make the combination of mids and uid the key we use
228 to demultiplex on (rather than mid alone). 230 to demultiplex on (rather than mid alone).
229 In addition to the above check, the cifs demultiplex 231 In addition to the above check, the cifs demultiplex
230 code already used the command code as a secondary 232 code already used the command code as a secondary
231 check of the frame and if signing is negotiated the 233 check of the frame and if signing is negotiated the
232 response would be discarded if the mid were the same 234 response would be discarded if the mid were the same
233 but the signature was wrong. Since the mid is not put in the 235 but the signature was wrong. Since the mid is not put in the
234 pending queue until later (when it is about to be dispatched) 236 pending queue until later (when it is about to be dispatched)
235 we do have to limit the number of outstanding requests 237 we do have to limit the number of outstanding requests
236 to somewhat less than 64K-1 although it is hard to imagine 238 to somewhat less than 64K-1 although it is hard to imagine
237 so many threads being in the vfs at one time. 239 so many threads being in the vfs at one time.
238*/ 240*/
@@ -240,27 +242,27 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
240{ 242{
241 __u16 mid = 0; 243 __u16 mid = 0;
242 __u16 last_mid; 244 __u16 last_mid;
243 int collision; 245 int collision;
244 246
245 if(server == NULL) 247 if (server == NULL)
246 return mid; 248 return mid;
247 249
248 spin_lock(&GlobalMid_Lock); 250 spin_lock(&GlobalMid_Lock);
249 last_mid = server->CurrentMid; /* we do not want to loop forever */ 251 last_mid = server->CurrentMid; /* we do not want to loop forever */
250 server->CurrentMid++; 252 server->CurrentMid++;
251 /* This nested loop looks more expensive than it is. 253 /* This nested loop looks more expensive than it is.
252 In practice the list of pending requests is short, 254 In practice the list of pending requests is short,
253 fewer than 50, and the mids are likely to be unique 255 fewer than 50, and the mids are likely to be unique
254 on the first pass through the loop unless some request 256 on the first pass through the loop unless some request
255 takes longer than the 64 thousand requests before it 257 takes longer than the 64 thousand requests before it
256 (and it would also have to have been a request that 258 (and it would also have to have been a request that
257 did not time out) */ 259 did not time out) */
258 while(server->CurrentMid != last_mid) { 260 while (server->CurrentMid != last_mid) {
259 struct list_head *tmp; 261 struct list_head *tmp;
260 struct mid_q_entry *mid_entry; 262 struct mid_q_entry *mid_entry;
261 263
262 collision = 0; 264 collision = 0;
263 if(server->CurrentMid == 0) 265 if (server->CurrentMid == 0)
264 server->CurrentMid++; 266 server->CurrentMid++;
265 267
266 list_for_each(tmp, &server->pending_mid_q) { 268 list_for_each(tmp, &server->pending_mid_q) {
@@ -273,7 +275,7 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
273 break; 275 break;
274 } 276 }
275 } 277 }
276 if(collision == 0) { 278 if (collision == 0) {
277 mid = server->CurrentMid; 279 mid = server->CurrentMid;
278 break; 280 break;
279 } 281 }
@@ -290,11 +292,11 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
290 const struct cifsTconInfo *treeCon, int word_count 292 const struct cifsTconInfo *treeCon, int word_count
291 /* length of fixed section (word count) in two byte units */) 293 /* length of fixed section (word count) in two byte units */)
292{ 294{
293 struct list_head* temp_item; 295 struct list_head *temp_item;
294 struct cifsSesInfo * ses; 296 struct cifsSesInfo *ses;
295 char *temp = (char *) buffer; 297 char *temp = (char *) buffer;
296 298
297 memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */ 299 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
298 300
299 buffer->smb_buf_length = 301 buffer->smb_buf_length =
300 (2 * word_count) + sizeof (struct smb_hdr) - 302 (2 * word_count) + sizeof (struct smb_hdr) -
@@ -325,7 +327,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
325 /* Uid is not converted */ 327 /* Uid is not converted */
326 buffer->Uid = treeCon->ses->Suid; 328 buffer->Uid = treeCon->ses->Suid;
327 buffer->Mid = GetNextMid(treeCon->ses->server); 329 buffer->Mid = GetNextMid(treeCon->ses->server);
328 if(multiuser_mount != 0) { 330 if (multiuser_mount != 0) {
329 /* For the multiuser case, there are few obvious technically */ 331 /* For the multiuser case, there are few obvious technically */
330 /* possible mechanisms to match the local linux user (uid) */ 332 /* possible mechanisms to match the local linux user (uid) */
331 /* to a valid remote smb user (smb_uid): */ 333 /* to a valid remote smb user (smb_uid): */
@@ -348,21 +350,22 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
348 /* flag were disabled. */ 350 /* flag were disabled. */
349 351
350 /* BB Add support for establishing new tCon and SMB Session */ 352 /* BB Add support for establishing new tCon and SMB Session */
351 /* with userid/password pairs found on the smb session */ 353 /* with userid/password pairs found on the smb session */
352 /* for other target tcp/ip addresses BB */ 354 /* for other target tcp/ip addresses BB */
353 if(current->fsuid != treeCon->ses->linux_uid) { 355 if (current->fsuid != treeCon->ses->linux_uid) {
354 cFYI(1,("Multiuser mode and UID did not match tcon uid")); 356 cFYI(1, ("Multiuser mode and UID "
357 "did not match tcon uid"));
355 read_lock(&GlobalSMBSeslock); 358 read_lock(&GlobalSMBSeslock);
356 list_for_each(temp_item, &GlobalSMBSessionList) { 359 list_for_each(temp_item, &GlobalSMBSessionList) {
357 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 360 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
358 if(ses->linux_uid == current->fsuid) { 361 if (ses->linux_uid == current->fsuid) {
359 if(ses->server == treeCon->ses->server) { 362 if (ses->server == treeCon->ses->server) {
360 cFYI(1,("found matching uid substitute right smb_uid")); 363 cFYI(1, ("found matching uid substitute right smb_uid"));
361 buffer->Uid = ses->Suid; 364 buffer->Uid = ses->Suid;
362 break; 365 break;
363 } else { 366 } else {
364 /* BB eventually call cifs_setup_session here */ 367 /* BB eventually call cifs_setup_session here */
365 cFYI(1,("local UID found but smb sess with this server does not exist")); 368 cFYI(1, ("local UID found but no smb sess with this server exists"));
366 } 369 }
367 } 370 }
368 } 371 }
@@ -374,8 +377,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
374 buffer->Flags2 |= SMBFLG2_DFS; 377 buffer->Flags2 |= SMBFLG2_DFS;
375 if (treeCon->nocase) 378 if (treeCon->nocase)
376 buffer->Flags |= SMBFLG_CASELESS; 379 buffer->Flags |= SMBFLG_CASELESS;
377 if((treeCon->ses) && (treeCon->ses->server)) 380 if ((treeCon->ses) && (treeCon->ses->server))
378 if(treeCon->ses->server->secMode & 381 if (treeCon->ses->server->secMode &
379 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 382 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
380 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 383 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
381 } 384 }
@@ -388,18 +391,18 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
388static int 391static int
389checkSMBhdr(struct smb_hdr *smb, __u16 mid) 392checkSMBhdr(struct smb_hdr *smb, __u16 mid)
390{ 393{
391 /* Make sure that this really is an SMB, that it is a response, 394 /* Make sure that this really is an SMB, that it is a response,
392 and that the message ids match */ 395 and that the message ids match */
393 if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && 396 if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) &&
394 (mid == smb->Mid)) { 397 (mid == smb->Mid)) {
395 if(smb->Flags & SMBFLG_RESPONSE) 398 if (smb->Flags & SMBFLG_RESPONSE)
396 return 0; 399 return 0;
397 else { 400 else {
398 /* only one valid case where server sends us request */ 401 /* only one valid case where server sends us request */
399 if(smb->Command == SMB_COM_LOCKING_ANDX) 402 if (smb->Command == SMB_COM_LOCKING_ANDX)
400 return 0; 403 return 0;
401 else 404 else
402 cERROR(1, ("Rcvd Request not response")); 405 cERROR(1, ("Received Request not response"));
403 } 406 }
404 } else { /* bad signature or mid */ 407 } else { /* bad signature or mid */
405 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) 408 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
@@ -426,9 +429,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
426 smb->WordCount = 0; 429 smb->WordCount = 0;
427 /* some error cases do not return wct and bcc */ 430 /* some error cases do not return wct and bcc */
428 return 0; 431 return 0;
429 } else if ((length == sizeof(struct smb_hdr) + 1) && 432 } else if ((length == sizeof(struct smb_hdr) + 1) &&
430 (smb->WordCount == 0)) { 433 (smb->WordCount == 0)) {
431 char * tmp = (char *)smb; 434 char *tmp = (char *)smb;
432 /* Need to work around a bug in two servers here */ 435 /* Need to work around a bug in two servers here */
433 /* First, check if the part of bcc they sent was zero */ 436 /* First, check if the part of bcc they sent was zero */
434 if (tmp[sizeof(struct smb_hdr)] == 0) { 437 if (tmp[sizeof(struct smb_hdr)] == 0) {
@@ -442,7 +445,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
442 tmp[sizeof(struct smb_hdr)+1] = 0; 445 tmp[sizeof(struct smb_hdr)+1] = 0;
443 return 0; 446 return 0;
444 } 447 }
445 cERROR(1,("rcvd invalid byte count (bcc)")); 448 cERROR(1, ("rcvd invalid byte count (bcc)"));
446 } else { 449 } else {
447 cERROR(1, ("Length less than smb header size")); 450 cERROR(1, ("Length less than smb header size"));
448 } 451 }
@@ -458,32 +461,33 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
458 return 1; 461 return 1;
459 clc_len = smbCalcSize_LE(smb); 462 clc_len = smbCalcSize_LE(smb);
460 463
461 if(4 + len != length) { 464 if (4 + len != length) {
462 cERROR(1, ("Length read does not match RFC1001 length %d",len)); 465 cERROR(1, ("Length read does not match RFC1001 length %d",
466 len));
463 return 1; 467 return 1;
464 } 468 }
465 469
466 if (4 + len != clc_len) { 470 if (4 + len != clc_len) {
467 /* check if bcc wrapped around for large read responses */ 471 /* check if bcc wrapped around for large read responses */
468 if((len > 64 * 1024) && (len > clc_len)) { 472 if ((len > 64 * 1024) && (len > clc_len)) {
469 /* check if lengths match mod 64K */ 473 /* check if lengths match mod 64K */
470 if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) 474 if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
471 return 0; /* bcc wrapped */ 475 return 0; /* bcc wrapped */
472 } 476 }
473 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d", 477 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
474 clc_len, 4 + len, smb->Mid)); 478 clc_len, 4 + len, smb->Mid));
475 /* Windows XP can return a few bytes too much, presumably 479 /* Windows XP can return a few bytes too much, presumably
476 an illegal pad, at the end of byte range lock responses 480 an illegal pad, at the end of byte range lock responses
477 so we allow for that three byte pad, as long as actual 481 so we allow for that three byte pad, as long as actual
478 received length is as long or longer than calculated length */ 482 received length is as long or longer than calculated length */
479 /* We have now had to extend this more, since there is a 483 /* We have now had to extend this more, since there is a
480 case in which it needs to be bigger still to handle a 484 case in which it needs to be bigger still to handle a
481 malformed response to transact2 findfirst from WinXP when 485 malformed response to transact2 findfirst from WinXP when
482 access denied is returned and thus bcc and wct are zero 486 access denied is returned and thus bcc and wct are zero
483 but server says length is 0x21 bytes too long as if the server 487 but server says length is 0x21 bytes too long as if the server
484 forget to reset the smb rfc1001 length when it reset the 488 forget to reset the smb rfc1001 length when it reset the
485 wct and bcc to minimum size and drop the t2 parms and data */ 489 wct and bcc to minimum size and drop the t2 parms and data */
486 if((4+len > clc_len) && (len <= clc_len + 512)) 490 if ((4+len > clc_len) && (len <= clc_len + 512))
487 return 0; 491 return 0;
488 else { 492 else {
489 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d", 493 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
@@ -495,61 +499,64 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
495} 499}
496int 500int
497is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) 501is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
498{ 502{
499 struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; 503 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
500 struct list_head *tmp; 504 struct list_head *tmp;
501 struct list_head *tmp1; 505 struct list_head *tmp1;
502 struct cifsTconInfo *tcon; 506 struct cifsTconInfo *tcon;
503 struct cifsFileInfo *netfile; 507 struct cifsFileInfo *netfile;
504 508
505 cFYI(1,("Checking for oplock break or dnotify response")); 509 cFYI(1, ("Checking for oplock break or dnotify response"));
506 if((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) && 510 if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
507 (pSMB->hdr.Flags & SMBFLG_RESPONSE)) { 511 (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
508 struct smb_com_transaction_change_notify_rsp * pSMBr = 512 struct smb_com_transaction_change_notify_rsp *pSMBr =
509 (struct smb_com_transaction_change_notify_rsp *)buf; 513 (struct smb_com_transaction_change_notify_rsp *)buf;
510 struct file_notify_information * pnotify; 514 struct file_notify_information *pnotify;
511 __u32 data_offset = 0; 515 __u32 data_offset = 0;
512 if(pSMBr->ByteCount > sizeof(struct file_notify_information)) { 516 if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {
513 data_offset = le32_to_cpu(pSMBr->DataOffset); 517 data_offset = le32_to_cpu(pSMBr->DataOffset);
514 518
515 pnotify = (struct file_notify_information *) 519 pnotify = (struct file_notify_information *)
516 ((char *)&pSMBr->hdr.Protocol + data_offset); 520 ((char *)&pSMBr->hdr.Protocol + data_offset);
517 cFYI(1,("dnotify on %s Action: 0x%x",pnotify->FileName, 521 cFYI(1, ("dnotify on %s Action: 0x%x",
522 pnotify->FileName,
518 pnotify->Action)); /* BB removeme BB */ 523 pnotify->Action)); /* BB removeme BB */
519 /* cifs_dump_mem("Rcvd notify Data: ",buf, 524 /* cifs_dump_mem("Rcvd notify Data: ",buf,
520 sizeof(struct smb_hdr)+60); */ 525 sizeof(struct smb_hdr)+60); */
521 return TRUE; 526 return TRUE;
522 } 527 }
523 if(pSMBr->hdr.Status.CifsError) { 528 if (pSMBr->hdr.Status.CifsError) {
524 cFYI(1,("notify err 0x%d",pSMBr->hdr.Status.CifsError)); 529 cFYI(1, ("notify err 0x%d",
530 pSMBr->hdr.Status.CifsError));
525 return TRUE; 531 return TRUE;
526 } 532 }
527 return FALSE; 533 return FALSE;
528 } 534 }
529 if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) 535 if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
530 return FALSE; 536 return FALSE;
531 if(pSMB->hdr.Flags & SMBFLG_RESPONSE) { 537 if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
532 /* no sense logging error on invalid handle on oplock 538 /* no sense logging error on invalid handle on oplock
533 break - harmless race between close request and oplock 539 break - harmless race between close request and oplock
534 break response is expected from time to time writing out 540 break response is expected from time to time writing out
535 large dirty files cached on the client */ 541 large dirty files cached on the client */
536 if ((NT_STATUS_INVALID_HANDLE) == 542 if ((NT_STATUS_INVALID_HANDLE) ==
537 le32_to_cpu(pSMB->hdr.Status.CifsError)) { 543 le32_to_cpu(pSMB->hdr.Status.CifsError)) {
538 cFYI(1,("invalid handle on oplock break")); 544 cFYI(1, ("invalid handle on oplock break"));
539 return TRUE; 545 return TRUE;
540 } else if (ERRbadfid == 546 } else if (ERRbadfid ==
541 le16_to_cpu(pSMB->hdr.Status.DosError.Error)) { 547 le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
542 return TRUE; 548 return TRUE;
543 } else { 549 } else {
544 return FALSE; /* on valid oplock brk we get "request" */ 550 return FALSE; /* on valid oplock brk we get "request" */
545 } 551 }
546 } 552 }
547 if(pSMB->hdr.WordCount != 8) 553 if (pSMB->hdr.WordCount != 8)
548 return FALSE; 554 return FALSE;
549 555
550 cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel)); 556 cFYI(1, ("oplock type 0x%d level 0x%d",
551 if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) 557 pSMB->LockType, pSMB->OplockLevel));
552 return FALSE; 558 if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
559 return FALSE;
553 560
554 /* look up tcon based on tid & uid */ 561 /* look up tcon based on tid & uid */
555 read_lock(&GlobalSMBSeslock); 562 read_lock(&GlobalSMBSeslock);
@@ -557,36 +564,38 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
557 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 564 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
558 if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { 565 if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) {
559 cifs_stats_inc(&tcon->num_oplock_brks); 566 cifs_stats_inc(&tcon->num_oplock_brks);
560 list_for_each(tmp1,&tcon->openFileList){ 567 list_for_each(tmp1, &tcon->openFileList) {
561 netfile = list_entry(tmp1,struct cifsFileInfo, 568 netfile = list_entry(tmp1, struct cifsFileInfo,
562 tlist); 569 tlist);
563 if(pSMB->Fid == netfile->netfid) { 570 if (pSMB->Fid == netfile->netfid) {
564 struct cifsInodeInfo *pCifsInode; 571 struct cifsInodeInfo *pCifsInode;
565 read_unlock(&GlobalSMBSeslock); 572 read_unlock(&GlobalSMBSeslock);
566 cFYI(1,("file id match, oplock break")); 573 cFYI(1,
567 pCifsInode = 574 ("file id match, oplock break"));
575 pCifsInode =
568 CIFS_I(netfile->pInode); 576 CIFS_I(netfile->pInode);
569 pCifsInode->clientCanCacheAll = FALSE; 577 pCifsInode->clientCanCacheAll = FALSE;
570 if(pSMB->OplockLevel == 0) 578 if (pSMB->OplockLevel == 0)
571 pCifsInode->clientCanCacheRead 579 pCifsInode->clientCanCacheRead
572 = FALSE; 580 = FALSE;
573 pCifsInode->oplockPending = TRUE; 581 pCifsInode->oplockPending = TRUE;
574 AllocOplockQEntry(netfile->pInode, 582 AllocOplockQEntry(netfile->pInode,
575 netfile->netfid, 583 netfile->netfid,
576 tcon); 584 tcon);
577 cFYI(1,("about to wake up oplock thd")); 585 cFYI(1,
578 if(oplockThread) 586 ("about to wake up oplock thread"));
587 if (oplockThread)
579 wake_up_process(oplockThread); 588 wake_up_process(oplockThread);
580 return TRUE; 589 return TRUE;
581 } 590 }
582 } 591 }
583 read_unlock(&GlobalSMBSeslock); 592 read_unlock(&GlobalSMBSeslock);
584 cFYI(1,("No matching file for oplock break")); 593 cFYI(1, ("No matching file for oplock break"));
585 return TRUE; 594 return TRUE;
586 } 595 }
587 } 596 }
588 read_unlock(&GlobalSMBSeslock); 597 read_unlock(&GlobalSMBSeslock);
589 cFYI(1,("Can not process oplock break for non-existent connection")); 598 cFYI(1, ("Can not process oplock break for non-existent connection"));
590 return TRUE; 599 return TRUE;
591} 600}
592 601
@@ -643,13 +652,13 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
643 only legal in POSIX-like OS (if they are present in the string). Path 652 only legal in POSIX-like OS (if they are present in the string). Path
644 names are little endian 16 bit Unicode on the wire */ 653 names are little endian 16 bit Unicode on the wire */
645int 654int
646cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, 655cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
647 const struct nls_table * cp) 656 const struct nls_table *cp)
648{ 657{
649 int i,j,len; 658 int i, j, len;
650 __u16 src_char; 659 __u16 src_char;
651 660
652 for(i = 0, j = 0; i < maxlen; i++) { 661 for (i = 0, j = 0; i < maxlen; i++) {
653 src_char = le16_to_cpu(source[i]); 662 src_char = le16_to_cpu(source[i]);
654 switch (src_char) { 663 switch (src_char) {
655 case 0: 664 case 0:
@@ -678,10 +687,10 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
678 case UNI_LESSTHAN: 687 case UNI_LESSTHAN:
679 target[j] = '<'; 688 target[j] = '<';
680 break; 689 break;
681 default: 690 default:
682 len = cp->uni2char(src_char, &target[j], 691 len = cp->uni2char(src_char, &target[j],
683 NLS_MAX_CHARSET_SIZE); 692 NLS_MAX_CHARSET_SIZE);
684 if(len > 0) { 693 if (len > 0) {
685 j += len; 694 j += len;
686 continue; 695 continue;
687 } else { 696 } else {
@@ -690,7 +699,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
690 } 699 }
691 j++; 700 j++;
692 /* make sure we do not overrun callers allocated temp buffer */ 701 /* make sure we do not overrun callers allocated temp buffer */
693 if(j >= (2 * NAME_MAX)) 702 if (j >= (2 * NAME_MAX))
694 break; 703 break;
695 } 704 }
696cUCS_out: 705cUCS_out:
@@ -703,18 +712,18 @@ cUCS_out:
703 only legal in POSIX-like OS (if they are present in the string). Path 712 only legal in POSIX-like OS (if they are present in the string). Path
704 names are little endian 16 bit Unicode on the wire */ 713 names are little endian 16 bit Unicode on the wire */
705int 714int
706cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 715cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
707 const struct nls_table * cp, int mapChars) 716 const struct nls_table *cp, int mapChars)
708{ 717{
709 int i,j,charlen; 718 int i, j, charlen;
710 int len_remaining = maxlen; 719 int len_remaining = maxlen;
711 char src_char; 720 char src_char;
712 __u16 temp; 721 __u16 temp;
713 722
714 if(!mapChars) 723 if (!mapChars)
715 return cifs_strtoUCS(target, source, PATH_MAX, cp); 724 return cifs_strtoUCS(target, source, PATH_MAX, cp);
716 725
717 for(i = 0, j = 0; i < maxlen; j++) { 726 for (i = 0, j = 0; i < maxlen; j++) {
718 src_char = source[i]; 727 src_char = source[i];
719 switch (src_char) { 728 switch (src_char) {
720 case 0: 729 case 0:
@@ -737,7 +746,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
737 break; 746 break;
738 case '|': 747 case '|':
739 target[j] = cpu_to_le16(UNI_PIPE); 748 target[j] = cpu_to_le16(UNI_PIPE);
740 break; 749 break;
741 /* BB We can not handle remapping slash until 750 /* BB We can not handle remapping slash until
742 all the calls to build_path_from_dentry 751 all the calls to build_path_from_dentry
743 are modified, as they use slash as separator BB */ 752 are modified, as they use slash as separator BB */
@@ -749,7 +758,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
749 len_remaining, &temp); 758 len_remaining, &temp);
750 /* if no match, use question mark, which 759 /* if no match, use question mark, which
751 at least in some cases servers as wild card */ 760 at least in some cases servers as wild card */
752 if(charlen < 1) { 761 if (charlen < 1) {
753 target[j] = cpu_to_le16(0x003f); 762 target[j] = cpu_to_le16(0x003f);
754 charlen = 1; 763 charlen = 1;
755 } else 764 } else
@@ -758,7 +767,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
758 /* character may take more than one byte in the 767 /* character may take more than one byte in the
759 the source string, but will take exactly two 768 the source string, but will take exactly two
760 bytes in the target string */ 769 bytes in the target string */
761 i+= charlen; 770 i += charlen;
762 continue; 771 continue;
763 } 772 }
764 i++; /* move to next char in source string */ 773 i++; /* move to next char in source string */
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 53e304d59544..2bfed3f45d0f 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -3,23 +3,22 @@
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002 4 * Copyright (c) International Business Machines Corp., 2002
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Error mapping routines from Samba libsmb/errormap.c 7 * Error mapping routines from Samba libsmb/errormap.c
8 * Copyright (C) Andrew Tridgell 2001 8 * Copyright (C) Andrew Tridgell 2001
9 * 9 *
10 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 13 * (at your option) any later version.
15 * 14 *
16 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License for more details. 18 * the GNU General Public License for more details.
20 * 19 *
21 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 23 */
25 24
@@ -30,9 +29,7 @@
30#include <linux/fs.h> 29#include <linux/fs.h>
31#include <asm/div64.h> 30#include <asm/div64.h>
32#include <asm/byteorder.h> 31#include <asm/byteorder.h>
33#ifdef CONFIG_CIFS_EXPERIMENTAL
34#include <linux/inet.h> 32#include <linux/inet.h>
35#endif
36#include "cifsfs.h" 33#include "cifsfs.h"
37#include "cifspdu.h" 34#include "cifspdu.h"
38#include "cifsglob.h" 35#include "cifsglob.h"
@@ -67,22 +64,22 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
67 {ERRbadshare, -ETXTBSY}, 64 {ERRbadshare, -ETXTBSY},
68 {ERRlock, -EACCES}, 65 {ERRlock, -EACCES},
69 {ERRunsup, -EINVAL}, 66 {ERRunsup, -EINVAL},
70 {ERRnosuchshare,-ENXIO}, 67 {ERRnosuchshare, -ENXIO},
71 {ERRfilexists, -EEXIST}, 68 {ERRfilexists, -EEXIST},
72 {ERRinvparm, -EINVAL}, 69 {ERRinvparm, -EINVAL},
73 {ERRdiskfull, -ENOSPC}, 70 {ERRdiskfull, -ENOSPC},
74 {ERRinvname, -ENOENT}, 71 {ERRinvname, -ENOENT},
75 {ERRinvlevel,-EOPNOTSUPP}, 72 {ERRinvlevel, -EOPNOTSUPP},
76 {ERRdirnotempty, -ENOTEMPTY}, 73 {ERRdirnotempty, -ENOTEMPTY},
77 {ERRnotlocked, -ENOLCK}, 74 {ERRnotlocked, -ENOLCK},
78 {ERRcancelviolation, -ENOLCK}, 75 {ERRcancelviolation, -ENOLCK},
79 {ERRalreadyexists, -EEXIST}, 76 {ERRalreadyexists, -EEXIST},
80 {ERRmoredata, -EOVERFLOW}, 77 {ERRmoredata, -EOVERFLOW},
81 {ERReasnotsupported,-EOPNOTSUPP}, 78 {ERReasnotsupported, -EOPNOTSUPP},
82 {ErrQuota, -EDQUOT}, 79 {ErrQuota, -EDQUOT},
83 {ErrNotALink, -ENOLINK}, 80 {ErrNotALink, -ENOLINK},
84 {ERRnetlogonNotStarted,-ENOPROTOOPT}, 81 {ERRnetlogonNotStarted, -ENOPROTOOPT},
85 {ErrTooManyLinks,-EMLINK}, 82 {ErrTooManyLinks, -EMLINK},
86 {0, 0} 83 {0, 0}
87}; 84};
88 85
@@ -133,85 +130,24 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
133/* returns 0 if invalid address */ 130/* returns 0 if invalid address */
134 131
135int 132int
136cifs_inet_pton(int address_family, char *cp,void *dst) 133cifs_inet_pton(int address_family, char *cp, void *dst)
137{ 134{
138#ifdef CONFIG_CIFS_EXPERIMENTAL
139 int ret = 0; 135 int ret = 0;
140 136
141 /* calculate length by finding first slash or NULL */ 137 /* calculate length by finding first slash or NULL */
142 /* BB Should we convert '/' slash to '\' here since it seems already done 138 /* BB Should we convert '/' slash to '\' here since it seems already
143 before this */ 139 * done before this */
144 if( address_family == AF_INET ){ 140 if ( address_family == AF_INET ) {
145 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); 141 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
146 } else if( address_family == AF_INET6 ){ 142 } else if ( address_family == AF_INET6 ) {
147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); 143 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
148 } 144 }
149#ifdef CONFIG_CIFS_DEBUG2 145#ifdef CONFIG_CIFS_DEBUG2
150 cFYI(1,("address conversion returned %d for %s", ret, cp)); 146 cFYI(1, ("address conversion returned %d for %s", ret, cp));
151#endif 147#endif
152 if (ret > 0) 148 if (ret > 0)
153 ret = 1; 149 ret = 1;
154 return ret; 150 return ret;
155#else
156 int value;
157 int digit;
158 int i;
159 char temp;
160 char bytes[4];
161 char *end = bytes;
162 static const int addr_class_max[4] =
163 { 0xffffffff, 0xffffff, 0xffff, 0xff };
164
165 if(address_family != AF_INET)
166 return -EAFNOSUPPORT;
167
168 for (i = 0; i < 4; i++) {
169 bytes[i] = 0;
170 }
171
172 temp = *cp;
173
174 while (TRUE) {
175 if (!isdigit(temp))
176 return 0;
177
178 value = 0;
179 digit = 0;
180 for (;;) {
181 if (isascii(temp) && isdigit(temp)) {
182 value = (value * 10) + temp - '0';
183 temp = *++cp;
184 digit = 1;
185 } else
186 break;
187 }
188
189 if (temp == '.') {
190 if ((end > bytes + 2) || (value > 255))
191 return 0;
192 *end++ = value;
193 temp = *++cp;
194 } else if (temp == ':') {
195 cFYI(1,("IPv6 addresses not supported for CIFS mounts yet"));
196 return -1;
197 } else
198 break;
199 }
200
201 /* check for last characters */
202 if (temp != '\0' && (!isascii(temp) || !isspace(temp)))
203 if (temp != '\\') {
204 if (temp != '/')
205 return 0;
206 else
207 (*cp = '\\'); /* switch the slash the expected way */
208 }
209 if (value > addr_class_max[end - bytes])
210 return 0;
211
212 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
213 return 1; /* success */
214#endif /* EXPERIMENTAL */
215} 151}
216 152
217/***************************************************************************** 153/*****************************************************************************
@@ -246,7 +182,7 @@ static const struct {
246 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, { 182 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {
247 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, 183 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR},
248/* { This NT error code was 'sqashed' 184/* { This NT error code was 'sqashed'
249 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK 185 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK
250 during the session setup } */ 186 during the session setup } */
251 { 187 {
252 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, { 188 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {
@@ -261,7 +197,7 @@ static const struct {
261 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, { 197 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {
262 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, 198 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED},
263/* { This NT error code was 'sqashed' 199/* { This NT error code was 'sqashed'
264 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 200 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE
265 during the session setup } */ 201 during the session setup } */
266 { 202 {
267 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, { 203 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {
@@ -331,7 +267,7 @@ static const struct {
331 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, { 267 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {
332 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, 268 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS},
333/* { This NT error code was 'sqashed' 269/* { This NT error code was 'sqashed'
334 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE 270 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
335 during the session setup } */ 271 during the session setup } */
336 { 272 {
337 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { 273 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
@@ -341,7 +277,7 @@ static const struct {
341 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, { 277 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {
342 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, 278 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN},
343/* { This NT error code was 'sqashed' 279/* { This NT error code was 'sqashed'
344 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE 280 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE
345 during the session setup } */ 281 during the session setup } */
346 { 282 {
347 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, { 283 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {
@@ -393,8 +329,8 @@ static const struct {
393 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, { 329 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {
394 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, 330 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED},
395/* { This NT error code was 'sqashed' 331/* { This NT error code was 'sqashed'
396 from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES 332 from NT_STATUS_INSUFFICIENT_RESOURCES to
397 during the session setup } */ 333 NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */
398 { 334 {
399 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, { 335 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {
400 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, { 336 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {
@@ -638,8 +574,8 @@ static const struct {
638 ERRDOS, 19, NT_STATUS_TOO_LATE}, { 574 ERRDOS, 19, NT_STATUS_TOO_LATE}, {
639 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, 575 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET},
640/* { This NT error code was 'sqashed' 576/* { This NT error code was 'sqashed'
641 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 577 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to
642 during the session setup } */ 578 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE during the session setup } */
643 { 579 {
644 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, { 580 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {
645 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, { 581 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {
@@ -658,7 +594,7 @@ static const struct {
658 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, { 594 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {
659 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, 595 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},
660/* { This NT error code was 'sqashed' 596/* { This NT error code was 'sqashed'
661 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE 597 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE
662 during the session setup } */ 598 during the session setup } */
663 { 599 {
664 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, { 600 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {
@@ -789,7 +725,7 @@ cifs_print_status(__u32 status_code)
789 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == 725 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
790 (status_code & 0xFFFFFF)) { 726 (status_code & 0xFFFFFF)) {
791 printk(KERN_NOTICE "Status code returned 0x%08x %s\n", 727 printk(KERN_NOTICE "Status code returned 0x%08x %s\n",
792 status_code,nt_errs[idx].nt_errstr); 728 status_code, nt_errs[idx].nt_errstr);
793 } 729 }
794 idx++; 730 idx++;
795 } 731 }
@@ -821,7 +757,7 @@ int
821map_smb_to_linux_error(struct smb_hdr *smb) 757map_smb_to_linux_error(struct smb_hdr *smb)
822{ 758{
823 unsigned int i; 759 unsigned int i;
824 int rc = -EIO; /* if transport error smb error may not be set */ 760 int rc = -EIO; /* if transport error smb error may not be set */
825 __u8 smberrclass; 761 __u8 smberrclass;
826 __u16 smberrcode; 762 __u16 smberrcode;
827 763
@@ -832,9 +768,10 @@ map_smb_to_linux_error(struct smb_hdr *smb)
832 return 0; 768 return 0;
833 769
834 if (smb->Flags2 & SMBFLG2_ERR_STATUS) { 770 if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
835 /* translate the newer STATUS codes to old style errors and then to POSIX errors */ 771 /* translate the newer STATUS codes to old style SMB errors
772 * and then to POSIX errors */
836 __u32 err = le32_to_cpu(smb->Status.CifsError); 773 __u32 err = le32_to_cpu(smb->Status.CifsError);
837 if(cifsFYI & CIFS_RC) 774 if (cifsFYI & CIFS_RC)
838 cifs_print_status(err); 775 cifs_print_status(err);
839 ntstatus_to_dos(err, &smberrclass, &smberrcode); 776 ntstatus_to_dos(err, &smberrclass, &smberrcode);
840 } else { 777 } else {
@@ -845,38 +782,42 @@ map_smb_to_linux_error(struct smb_hdr *smb)
845 /* old style errors */ 782 /* old style errors */
846 783
847 /* DOS class smb error codes - map DOS */ 784 /* DOS class smb error codes - map DOS */
848 if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */ 785 if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */
849 for (i = 0; 786 for (i = 0;
850 i < 787 i <
851 sizeof (mapping_table_ERRDOS) / 788 sizeof (mapping_table_ERRDOS) /
852 sizeof (struct smb_to_posix_error); i++) { 789 sizeof (struct smb_to_posix_error); i++) {
853 if (mapping_table_ERRDOS[i].smb_err == 0) 790 if (mapping_table_ERRDOS[i].smb_err == 0)
854 break; 791 break;
855 else if (mapping_table_ERRDOS[i].smb_err == smberrcode) { 792 else if (mapping_table_ERRDOS[i].smb_err ==
793 smberrcode) {
856 rc = mapping_table_ERRDOS[i].posix_code; 794 rc = mapping_table_ERRDOS[i].posix_code;
857 break; 795 break;
858 } 796 }
859 /* else try the next error mapping one to see if it will match */ 797 /* else try next error mapping one to see if match */
860 } 798 }
861 } else if (smberrclass == ERRSRV) { /* server class of error codes */ 799 } else if (smberrclass == ERRSRV) { /* server class of error codes */
862 for (i = 0; 800 for (i = 0;
863 i < 801 i <
864 sizeof (mapping_table_ERRSRV) / 802 sizeof (mapping_table_ERRSRV) /
865 sizeof (struct smb_to_posix_error); i++) { 803 sizeof (struct smb_to_posix_error); i++) {
866 if (mapping_table_ERRSRV[i].smb_err == 0) 804 if (mapping_table_ERRSRV[i].smb_err == 0)
867 break; 805 break;
868 else if (mapping_table_ERRSRV[i].smb_err == smberrcode) { 806 else if (mapping_table_ERRSRV[i].smb_err ==
807 smberrcode) {
869 rc = mapping_table_ERRSRV[i].posix_code; 808 rc = mapping_table_ERRSRV[i].posix_code;
870 break; 809 break;
871 } 810 }
872 /* else try the next error mapping one to see if it will match */ 811 /* else try next error mapping to see if match */
873 } 812 }
874 } 813 }
875 /* else ERRHRD class errors or junk - return EIO */ 814 /* else ERRHRD class errors or junk - return EIO */
876 815
877 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc)); 816 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
817 smberrcode, rc));
878 818
879 /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */ 819 /* generic corrective action e.g. reconnect SMB session on
820 * ERRbaduid could be added */
880 821
881 return rc; 822 return rc;
882} 823}
@@ -910,7 +851,7 @@ smbCalcSize_LE(struct smb_hdr *ptr)
910struct timespec 851struct timespec
911cifs_NTtimeToUnix(u64 ntutc) 852cifs_NTtimeToUnix(u64 ntutc)
912{ 853{
913 struct timespec ts; 854 struct timespec ts;
914 /* BB what about the timezone? BB */ 855 /* BB what about the timezone? BB */
915 856
916 /* Subtract the NTFS time offset, then convert to 1s intervals. */ 857 /* Subtract the NTFS time offset, then convert to 1s intervals. */
@@ -918,7 +859,7 @@ cifs_NTtimeToUnix(u64 ntutc)
918 859
919 t = ntutc - NTFS_TIME_OFFSET; 860 t = ntutc - NTFS_TIME_OFFSET;
920 ts.tv_nsec = do_div(t, 10000000) * 100; 861 ts.tv_nsec = do_div(t, 10000000) * 100;
921 ts.tv_sec = t; 862 ts.tv_sec = t;
922 return ts; 863 return ts;
923} 864}
924 865
@@ -946,20 +887,20 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
946 SMB_TIME * st = (SMB_TIME *)&time; 887 SMB_TIME * st = (SMB_TIME *)&time;
947 SMB_DATE * sd = (SMB_DATE *)&date; 888 SMB_DATE * sd = (SMB_DATE *)&date;
948 889
949 cFYI(1,("date %d time %d",date, time)); 890 cFYI(1, ("date %d time %d", date, time));
950 891
951 sec = 2 * st->TwoSeconds; 892 sec = 2 * st->TwoSeconds;
952 min = st->Minutes; 893 min = st->Minutes;
953 if((sec > 59) || (min > 59)) 894 if ((sec > 59) || (min > 59))
954 cERROR(1,("illegal time min %d sec %d", min, sec)); 895 cERROR(1, ("illegal time min %d sec %d", min, sec));
955 sec += (min * 60); 896 sec += (min * 60);
956 sec += 60 * 60 * st->Hours; 897 sec += 60 * 60 * st->Hours;
957 if(st->Hours > 24) 898 if (st->Hours > 24)
958 cERROR(1,("illegal hours %d",st->Hours)); 899 cERROR(1, ("illegal hours %d", st->Hours));
959 days = sd->Day; 900 days = sd->Day;
960 month = sd->Month; 901 month = sd->Month;
961 if((days > 31) || (month > 12)) 902 if ((days > 31) || (month > 12))
962 cERROR(1,("illegal date, month %d day: %d", month, days)); 903 cERROR(1, ("illegal date, month %d day: %d", month, days));
963 month -= 1; 904 month -= 1;
964 days += total_days_of_prev_months[month]; 905 days += total_days_of_prev_months[month];
965 days += 3652; /* account for difference in days between 1980 and 1970 */ 906 days += 3652; /* account for difference in days between 1980 and 1970 */
@@ -970,15 +911,15 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
970 for years/100 except for years/400, but since the maximum number for DOS 911 for years/100 except for years/400, but since the maximum number for DOS
971 year is 2**7, the last year is 1980+127, which means we need only 912 year is 2**7, the last year is 1980+127, which means we need only
972 consider 2 special case years, ie the years 2000 and 2100, and only 913 consider 2 special case years, ie the years 2000 and 2100, and only
973 adjust for the lack of leap year for the year 2100, as 2000 was a 914 adjust for the lack of leap year for the year 2100, as 2000 was a
974 leap year (divisable by 400) */ 915 leap year (divisable by 400) */
975 if(year >= 120) /* the year 2100 */ 916 if (year >= 120) /* the year 2100 */
976 days = days - 1; /* do not count leap year for the year 2100 */ 917 days = days - 1; /* do not count leap year for the year 2100 */
977 918
978 /* adjust for leap year where we are still before leap day */ 919 /* adjust for leap year where we are still before leap day */
979 if(year != 120) 920 if (year != 120)
980 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); 921 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
981 sec += 24 * 60 * 60 * days; 922 sec += 24 * 60 * 60 * days;
982 923
983 ts.tv_sec = sec; 924 ts.tv_sec = sec;
984 925
@@ -986,4 +927,4 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
986 927
987 ts.tv_nsec = 0; 928 ts.tv_nsec = 0;
988 return ts; 929 return ts;
989} 930}
diff --git a/fs/cifs/nterr.c b/fs/cifs/nterr.c
index 4da50cd34469..819fd994b121 100644
--- a/fs/cifs/nterr.c
+++ b/fs/cifs/nterr.c
@@ -1,19 +1,19 @@
1/* 1/*
2 * Unix SMB/Netbios implementation. 2 * Unix SMB/Netbios implementation.
3 * Version 1.9. 3 * Version 1.9.
4 * RPC Pipe client / server routines 4 * RPC Pipe client / server routines
5 * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. 5 * Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/fs/cifs/nterr.h b/fs/cifs/nterr.h
index d2fb06c97dfa..588abbb9d08c 100644
--- a/fs/cifs/nterr.h
+++ b/fs/cifs/nterr.h
@@ -1,4 +1,4 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 NT error code constants 4 NT error code constants
@@ -6,17 +6,17 @@
6 Copyright (C) John H Terpstra 1996-2000 6 Copyright (C) John H Terpstra 1996-2000
7 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 7 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
8 Copyright (C) Paul Ashton 1998-2000 8 Copyright (C) Paul Ashton 1998-2000
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or 12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version. 13 (at your option) any later version.
14 14
15 This program is distributed in the hope that it will be useful, 15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details. 18 GNU General Public License for more details.
19 19
20 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software 21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index d39b712a11c5..7170a9b70f1e 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/ntlmssp.h 2 * fs/cifs/ntlmssp.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2006 4 * Copyright (c) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -16,7 +16,7 @@
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public License 17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software 18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#define NTLMSSP_SIGNATURE "NTLMSSP" 22#define NTLMSSP_SIGNATURE "NTLMSSP"
@@ -27,18 +27,18 @@
27#define UnknownMessage cpu_to_le32(8) 27#define UnknownMessage cpu_to_le32(8)
28 28
29/* Negotiate Flags */ 29/* Negotiate Flags */
30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 // Text strings are in unicode 30#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are in unicode */
31#define NTLMSSP_NEGOTIATE_OEM 0x02 // Text strings are in OEM 31#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
32#define NTLMSSP_REQUEST_TARGET 0x04 // Server return its auth realm 32#define NTLMSSP_REQUEST_TARGET 0x04 /* Server return its auth realm */
33#define NTLMSSP_NEGOTIATE_SIGN 0x0010 // Request signature capability 33#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signature capability */
34#define NTLMSSP_NEGOTIATE_SEAL 0x0020 // Request confidentiality 34#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
35#define NTLMSSP_NEGOTIATE_DGRAM 0x0040 35#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
36#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 // Use LM session key for sign/seal 36#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Sign/seal use LM session key */
37#define NTLMSSP_NEGOTIATE_NTLM 0x0200 // NTLM authentication 37#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
38#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 38#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000
39#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000 39#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
40#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 // client/server on same machine 40#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server on same machine */
41#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 // Sign for all security levels 41#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign for all security levels */
42#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000 42#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
43#define NTLMSSP_TARGET_TYPE_SERVER 0x20000 43#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
44#define NTLMSSP_TARGET_TYPE_SHARE 0x40000 44#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index c08bda9fcac6..916df9431336 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -2,7 +2,7 @@
2 * fs/cifs/readdir.c 2 * fs/cifs/readdir.c
3 * 3 *
4 * Directory search handling 4 * Directory search handling
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2004, 2007 6 * Copyright (C) International Business Machines Corp., 2004, 2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
@@ -34,24 +34,23 @@
34#ifdef CONFIG_CIFS_DEBUG2 34#ifdef CONFIG_CIFS_DEBUG2
35static void dump_cifs_file_struct(struct file *file, char *label) 35static void dump_cifs_file_struct(struct file *file, char *label)
36{ 36{
37 struct cifsFileInfo * cf; 37 struct cifsFileInfo *cf;
38 38
39 if (file) { 39 if (file) {
40 cf = file->private_data; 40 cf = file->private_data;
41 if (cf == NULL) { 41 if (cf == NULL) {
42 cFYI(1,("empty cifs private file data")); 42 cFYI(1, ("empty cifs private file data"));
43 return; 43 return;
44 } 44 }
45 if (cf->invalidHandle) { 45 if (cf->invalidHandle) {
46 cFYI(1,("invalid handle")); 46 cFYI(1, ("invalid handle"));
47 } 47 }
48 if (cf->srch_inf.endOfSearch) { 48 if (cf->srch_inf.endOfSearch) {
49 cFYI(1,("end of search")); 49 cFYI(1, ("end of search"));
50 } 50 }
51 if (cf->srch_inf.emptyDir) { 51 if (cf->srch_inf.emptyDir) {
52 cFYI(1,("empty dir")); 52 cFYI(1, ("empty dir"));
53 } 53 }
54
55 } 54 }
56} 55}
57#endif /* DEBUG2 */ 56#endif /* DEBUG2 */
@@ -73,7 +72,8 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
73 qstring->hash = full_name_hash(qstring->name, qstring->len); 72 qstring->hash = full_name_hash(qstring->name, qstring->len);
74 tmp_dentry = d_lookup(file->f_path.dentry, qstring); 73 tmp_dentry = d_lookup(file->f_path.dentry, qstring);
75 if (tmp_dentry) { 74 if (tmp_dentry) {
76 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); 75 cFYI(0, ("existing dentry with inode 0x%p",
76 tmp_dentry->d_inode));
77 *ptmp_inode = tmp_dentry->d_inode; 77 *ptmp_inode = tmp_dentry->d_inode;
78/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ 78/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
79 if (*ptmp_inode == NULL) { 79 if (*ptmp_inode == NULL) {
@@ -87,7 +87,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
87 } else { 87 } else {
88 tmp_dentry = d_alloc(file->f_path.dentry, qstring); 88 tmp_dentry = d_alloc(file->f_path.dentry, qstring);
89 if (tmp_dentry == NULL) { 89 if (tmp_dentry == NULL) {
90 cERROR(1,("Failed allocating dentry")); 90 cERROR(1, ("Failed allocating dentry"));
91 *ptmp_inode = NULL; 91 *ptmp_inode = NULL;
92 return rc; 92 return rc;
93 } 93 }
@@ -100,7 +100,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
100 if (*ptmp_inode == NULL) 100 if (*ptmp_inode == NULL)
101 return rc; 101 return rc;
102 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 102 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
103 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 103 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
104 rc = 2; 104 rc = 2;
105 } 105 }
106 106
@@ -109,7 +109,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
109 return rc; 109 return rc;
110} 110}
111 111
112static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) 112static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
113{ 113{
114 if ((tcon) && (tcon->ses) && (tcon->ses->server)) { 114 if ((tcon) && (tcon->ses) && (tcon->ses->server)) {
115 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; 115 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
@@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
121 121
122 122
123static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 123static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
124 char * buf, int *pobject_type, int isNewInode) 124 char *buf, int *pobject_type, int isNewInode)
125{ 125{
126 loff_t local_size; 126 loff_t local_size;
127 struct timespec local_mtime; 127 struct timespec local_mtime;
@@ -150,7 +150,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
150 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 150 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
151 } else { /* legacy, OS2 and DOS style */ 151 } else { /* legacy, OS2 and DOS style */
152/* struct timespec ts;*/ 152/* struct timespec ts;*/
153 FIND_FILE_STANDARD_INFO * pfindData = 153 FIND_FILE_STANDARD_INFO * pfindData =
154 (FIND_FILE_STANDARD_INFO *)buf; 154 (FIND_FILE_STANDARD_INFO *)buf;
155 155
156 tmp_inode->i_mtime = cnvrtDosUnixTm( 156 tmp_inode->i_mtime = cnvrtDosUnixTm(
@@ -175,7 +175,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
175 175
176 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 176 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
177 /* 2767 perms - indicate mandatory locking */ 177 /* 2767 perms - indicate mandatory locking */
178 /* BB fill in uid and gid here? with help from winbind? 178 /* BB fill in uid and gid here? with help from winbind?
179 or retrieve from NTFS stream extended attribute */ 179 or retrieve from NTFS stream extended attribute */
180 if (atomic_read(&cifsInfo->inUse) == 0) { 180 if (atomic_read(&cifsInfo->inUse) == 0) {
181 tmp_inode->i_uid = cifs_sb->mnt_uid; 181 tmp_inode->i_uid = cifs_sb->mnt_uid;
@@ -196,7 +196,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
196 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 196 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
197 } 197 }
198 tmp_inode->i_mode |= S_IFDIR; 198 tmp_inode->i_mode |= S_IFDIR;
199 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 199 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
200 (attr & ATTR_SYSTEM)) { 200 (attr & ATTR_SYSTEM)) {
201 if (end_of_file == 0) { 201 if (end_of_file == 0) {
202 *pobject_type = DT_FIFO; 202 *pobject_type = DT_FIFO;
@@ -206,13 +206,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
206 inode as needing revalidate and get the real type 206 inode as needing revalidate and get the real type
207 (blk vs chr vs. symlink) later ie in lookup */ 207 (blk vs chr vs. symlink) later ie in lookup */
208 *pobject_type = DT_REG; 208 *pobject_type = DT_REG;
209 tmp_inode->i_mode |= S_IFREG; 209 tmp_inode->i_mode |= S_IFREG;
210 cifsInfo->time = 0; 210 cifsInfo->time = 0;
211 } 211 }
212/* we no longer mark these because we could not follow them */ 212/* we no longer mark these because we could not follow them */
213/* } else if (attr & ATTR_REPARSE) { 213/* } else if (attr & ATTR_REPARSE) {
214 *pobject_type = DT_LNK; 214 *pobject_type = DT_LNK;
215 tmp_inode->i_mode |= S_IFLNK; */ 215 tmp_inode->i_mode |= S_IFLNK; */
216 } else { 216 } else {
217 *pobject_type = DT_REG; 217 *pobject_type = DT_REG;
218 tmp_inode->i_mode |= S_IFREG; 218 tmp_inode->i_mode |= S_IFREG;
@@ -220,7 +220,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
220 tmp_inode->i_mode &= ~(S_IWUGO); 220 tmp_inode->i_mode &= ~(S_IWUGO);
221 else if ((tmp_inode->i_mode & S_IWUGO) == 0) 221 else if ((tmp_inode->i_mode & S_IWUGO) == 0)
222 /* the ATTR_READONLY flag may have been changed on */ 222 /* the ATTR_READONLY flag may have been changed on */
223 /* server -- set any w bits allowed by mnt_file_mode */ 223 /* server -- set any w bits allowed by mnt_file_mode */
224 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); 224 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
225 } /* could add code here - to validate if device or weird share type? */ 225 } /* could add code here - to validate if device or weird share type? */
226 226
@@ -231,7 +231,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
231 231
232 spin_lock(&tmp_inode->i_lock); 232 spin_lock(&tmp_inode->i_lock);
233 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 233 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
234 /* can not safely change the file size here if the 234 /* can not safely change the file size here if the
235 client is writing to it due to potential races */ 235 client is writing to it due to potential races */
236 i_size_write(tmp_inode, end_of_file); 236 i_size_write(tmp_inode, end_of_file);
237 237
@@ -254,7 +254,6 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
254 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 254 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
255 else 255 else
256 tmp_inode->i_fop = &cifs_file_direct_ops; 256 tmp_inode->i_fop = &cifs_file_direct_ops;
257
258 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 257 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
259 tmp_inode->i_fop = &cifs_file_nobrl_ops; 258 tmp_inode->i_fop = &cifs_file_nobrl_ops;
260 else 259 else
@@ -322,8 +321,8 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
322 321
323 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 322 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
324 /* since we set the inode type below we need to mask off type 323 /* since we set the inode type below we need to mask off type
325 to avoid strange results if bits above were corrupt */ 324 to avoid strange results if bits above were corrupt */
326 tmp_inode->i_mode &= ~S_IFMT; 325 tmp_inode->i_mode &= ~S_IFMT;
327 if (type == UNIX_FILE) { 326 if (type == UNIX_FILE) {
328 *pobject_type = DT_REG; 327 *pobject_type = DT_REG;
329 tmp_inode->i_mode |= S_IFREG; 328 tmp_inode->i_mode |= S_IFREG;
@@ -353,7 +352,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
353 /* safest to just call it a file */ 352 /* safest to just call it a file */
354 *pobject_type = DT_REG; 353 *pobject_type = DT_REG;
355 tmp_inode->i_mode |= S_IFREG; 354 tmp_inode->i_mode |= S_IFREG;
356 cFYI(1,("unknown inode type %d",type)); 355 cFYI(1, ("unknown inode type %d", type));
357 } 356 }
358 357
359 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 358 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
@@ -368,7 +367,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
368 367
369 spin_lock(&tmp_inode->i_lock); 368 spin_lock(&tmp_inode->i_lock);
370 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 369 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
371 /* can not safely change the file size here if the 370 /* can not safely change the file size here if the
372 client is writing to it due to potential races */ 371 client is writing to it due to potential races */
373 i_size_write(tmp_inode, end_of_file); 372 i_size_write(tmp_inode, end_of_file);
374 373
@@ -393,15 +392,16 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
393 tmp_inode->i_fop = &cifs_file_ops; 392 tmp_inode->i_fop = &cifs_file_ops;
394 393
395 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 394 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
396 (cifs_sb->tcon->ses->server->maxBuf < 395 (cifs_sb->tcon->ses->server->maxBuf <
397 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 396 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
398 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 397 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
399 else 398 else
400 tmp_inode->i_data.a_ops = &cifs_addr_ops; 399 tmp_inode->i_data.a_ops = &cifs_addr_ops;
401 400
402 if (isNewInode) 401 if (isNewInode)
403 return; /* No sense invalidating pages for new inode since we 402 return; /* No sense invalidating pages for new inode
404 have not started caching readahead file data yet */ 403 since we have not started caching readahead
404 file data for it yet */
405 405
406 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 406 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
407 (local_size == tmp_inode->i_size)) { 407 (local_size == tmp_inode->i_size)) {
@@ -420,7 +420,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
420 tmp_inode->i_op = &cifs_symlink_inode_ops; 420 tmp_inode->i_op = &cifs_symlink_inode_ops;
421/* tmp_inode->i_fop = *//* do not need to set to anything */ 421/* tmp_inode->i_fop = *//* do not need to set to anything */
422 } else { 422 } else {
423 cFYI(1, ("Special inode")); 423 cFYI(1, ("Special inode"));
424 init_special_inode(tmp_inode, tmp_inode->i_mode, 424 init_special_inode(tmp_inode, tmp_inode->i_mode,
425 tmp_inode->i_rdev); 425 tmp_inode->i_rdev);
426 } 426 }
@@ -429,14 +429,14 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
429static int initiate_cifs_search(const int xid, struct file *file) 429static int initiate_cifs_search(const int xid, struct file *file)
430{ 430{
431 int rc = 0; 431 int rc = 0;
432 char * full_path; 432 char *full_path;
433 struct cifsFileInfo * cifsFile; 433 struct cifsFileInfo *cifsFile;
434 struct cifs_sb_info *cifs_sb; 434 struct cifs_sb_info *cifs_sb;
435 struct cifsTconInfo *pTcon; 435 struct cifsTconInfo *pTcon;
436 436
437 if (file->private_data == NULL) { 437 if (file->private_data == NULL) {
438 file->private_data = 438 file->private_data =
439 kzalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); 439 kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
440 } 440 }
441 441
442 if (file->private_data == NULL) 442 if (file->private_data == NULL)
@@ -463,9 +463,11 @@ static int initiate_cifs_search(const int xid, struct file *file)
463 463
464ffirst_retry: 464ffirst_retry:
465 /* test for Unix extensions */ 465 /* test for Unix extensions */
466 if (pTcon->ses->capabilities & CAP_UNIX) { 466 /* but now check for them on the share/mount not on the SMB session */
467/* if (pTcon->ses->capabilities & CAP_UNIX) { */
468 if (pTcon->unix_ext) {
467 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; 469 cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
468 } else if ((pTcon->ses->capabilities & 470 } else if ((pTcon->ses->capabilities &
469 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { 471 (CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
470 cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; 472 cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
471 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 473 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
@@ -474,13 +476,13 @@ ffirst_retry:
474 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; 476 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
475 } 477 }
476 478
477 rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, 479 rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
478 &cifsFile->netfid, &cifsFile->srch_inf, 480 &cifsFile->netfid, &cifsFile->srch_inf,
479 cifs_sb->mnt_cifs_flags & 481 cifs_sb->mnt_cifs_flags &
480 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 482 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
481 if (rc == 0) 483 if (rc == 0)
482 cifsFile->invalidHandle = FALSE; 484 cifsFile->invalidHandle = FALSE;
483 if ((rc == -EOPNOTSUPP) && 485 if ((rc == -EOPNOTSUPP) &&
484 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { 486 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
485 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 487 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
486 goto ffirst_retry; 488 goto ffirst_retry;
@@ -495,17 +497,17 @@ static int cifs_unicode_bytelen(char *str)
495 int len; 497 int len;
496 __le16 * ustr = (__le16 *)str; 498 __le16 * ustr = (__le16 *)str;
497 499
498 for(len=0;len <= PATH_MAX;len++) { 500 for (len = 0; len <= PATH_MAX; len++) {
499 if (ustr[len] == 0) 501 if (ustr[len] == 0)
500 return len << 1; 502 return len << 1;
501 } 503 }
502 cFYI(1,("Unicode string longer than PATH_MAX found")); 504 cFYI(1, ("Unicode string longer than PATH_MAX found"));
503 return len << 1; 505 return len << 1;
504} 506}
505 507
506static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) 508static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
507{ 509{
508 char * new_entry; 510 char *new_entry;
509 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 511 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
510 512
511 if (level == SMB_FIND_FILE_INFO_STANDARD) { 513 if (level == SMB_FIND_FILE_INFO_STANDARD) {
@@ -516,21 +518,21 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
516 pfData->FileNameLength; 518 pfData->FileNameLength;
517 } else 519 } else
518 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 520 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
519 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 521 cFYI(1, ("new entry %p old entry %p", new_entry, old_entry));
520 /* validate that new_entry is not past end of SMB */ 522 /* validate that new_entry is not past end of SMB */
521 if (new_entry >= end_of_smb) { 523 if (new_entry >= end_of_smb) {
522 cERROR(1, 524 cERROR(1,
523 ("search entry %p began after end of SMB %p old entry %p", 525 ("search entry %p began after end of SMB %p old entry %p",
524 new_entry, end_of_smb, old_entry)); 526 new_entry, end_of_smb, old_entry));
525 return NULL; 527 return NULL;
526 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) && 528 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
527 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || 529 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
528 ((level != SMB_FIND_FILE_INFO_STANDARD) && 530 || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
529 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { 531 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
530 cERROR(1,("search entry %p extends after end of SMB %p", 532 cERROR(1, ("search entry %p extends after end of SMB %p",
531 new_entry, end_of_smb)); 533 new_entry, end_of_smb));
532 return NULL; 534 return NULL;
533 } else 535 } else
534 return new_entry; 536 return new_entry;
535 537
536} 538}
@@ -541,8 +543,8 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
541static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) 543static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
542{ 544{
543 int rc = 0; 545 int rc = 0;
544 char * filename = NULL; 546 char *filename = NULL;
545 int len = 0; 547 int len = 0;
546 548
547 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 549 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
548 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 550 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
@@ -554,25 +556,25 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
554 len = strnlen(filename, 5); 556 len = strnlen(filename, 5);
555 } 557 }
556 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { 558 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
557 FILE_DIRECTORY_INFO * pFindData = 559 FILE_DIRECTORY_INFO * pFindData =
558 (FILE_DIRECTORY_INFO *)current_entry; 560 (FILE_DIRECTORY_INFO *)current_entry;
559 filename = &pFindData->FileName[0]; 561 filename = &pFindData->FileName[0];
560 len = le32_to_cpu(pFindData->FileNameLength); 562 len = le32_to_cpu(pFindData->FileNameLength);
561 } else if (cfile->srch_inf.info_level == 563 } else if (cfile->srch_inf.info_level ==
562 SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 564 SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
563 FILE_FULL_DIRECTORY_INFO * pFindData = 565 FILE_FULL_DIRECTORY_INFO * pFindData =
564 (FILE_FULL_DIRECTORY_INFO *)current_entry; 566 (FILE_FULL_DIRECTORY_INFO *)current_entry;
565 filename = &pFindData->FileName[0]; 567 filename = &pFindData->FileName[0];
566 len = le32_to_cpu(pFindData->FileNameLength); 568 len = le32_to_cpu(pFindData->FileNameLength);
567 } else if (cfile->srch_inf.info_level == 569 } else if (cfile->srch_inf.info_level ==
568 SMB_FIND_FILE_ID_FULL_DIR_INFO) { 570 SMB_FIND_FILE_ID_FULL_DIR_INFO) {
569 SEARCH_ID_FULL_DIR_INFO * pFindData = 571 SEARCH_ID_FULL_DIR_INFO * pFindData =
570 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 572 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
571 filename = &pFindData->FileName[0]; 573 filename = &pFindData->FileName[0];
572 len = le32_to_cpu(pFindData->FileNameLength); 574 len = le32_to_cpu(pFindData->FileNameLength);
573 } else if (cfile->srch_inf.info_level == 575 } else if (cfile->srch_inf.info_level ==
574 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 576 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
575 FILE_BOTH_DIRECTORY_INFO * pFindData = 577 FILE_BOTH_DIRECTORY_INFO * pFindData =
576 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 578 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
577 filename = &pFindData->FileName[0]; 579 filename = &pFindData->FileName[0];
578 len = le32_to_cpu(pFindData->FileNameLength); 580 len = le32_to_cpu(pFindData->FileNameLength);
@@ -582,7 +584,8 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
582 filename = &pFindData->FileName[0]; 584 filename = &pFindData->FileName[0];
583 len = pFindData->FileNameLength; 585 len = pFindData->FileNameLength;
584 } else { 586 } else {
585 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); 587 cFYI(1, ("Unknown findfirst level %d",
588 cfile->srch_inf.info_level));
586 } 589 }
587 590
588 if (filename) { 591 if (filename) {
@@ -595,15 +598,15 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
595 } else if (len == 4) { 598 } else if (len == 4) {
596 /* check for .. */ 599 /* check for .. */
597 if ((ufilename[0] == UNICODE_DOT) 600 if ((ufilename[0] == UNICODE_DOT)
598 &&(ufilename[1] == UNICODE_DOT)) 601 && (ufilename[1] == UNICODE_DOT))
599 rc = 2; 602 rc = 2;
600 } 603 }
601 } else /* ASCII */ { 604 } else /* ASCII */ {
602 if (len == 1) { 605 if (len == 1) {
603 if (filename[0] == '.') 606 if (filename[0] == '.')
604 rc = 1; 607 rc = 1;
605 } else if (len == 2) { 608 } else if (len == 2) {
606 if((filename[0] == '.') && (filename[1] == '.')) 609 if ((filename[0] == '.') && (filename[1] == '.'))
607 rc = 2; 610 rc = 2;
608 } 611 }
609 } 612 }
@@ -614,7 +617,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
614 617
615/* Check if directory that we are searching has changed so we can decide 618/* Check if directory that we are searching has changed so we can decide
616 whether we can use the cached search results from the previous search */ 619 whether we can use the cached search results from the previous search */
617static int is_dir_changed(struct file * file) 620static int is_dir_changed(struct file *file)
618{ 621{
619 struct inode *inode = file->f_path.dentry->d_inode; 622 struct inode *inode = file->f_path.dentry->d_inode;
620 struct cifsInodeInfo *cifsInfo = CIFS_I(inode); 623 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
@@ -633,22 +636,22 @@ static int is_dir_changed(struct file * file)
633/* We start counting in the buffer with entry 2 and increment for every 636/* We start counting in the buffer with entry 2 and increment for every
634 entry (do not increment for . or .. entry) */ 637 entry (do not increment for . or .. entry) */
635static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, 638static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
636 struct file *file, char **ppCurrentEntry, int *num_to_ret) 639 struct file *file, char **ppCurrentEntry, int *num_to_ret)
637{ 640{
638 int rc = 0; 641 int rc = 0;
639 int pos_in_buf = 0; 642 int pos_in_buf = 0;
640 loff_t first_entry_in_buffer; 643 loff_t first_entry_in_buffer;
641 loff_t index_to_find = file->f_pos; 644 loff_t index_to_find = file->f_pos;
642 struct cifsFileInfo * cifsFile = file->private_data; 645 struct cifsFileInfo *cifsFile = file->private_data;
643 /* check if index in the buffer */ 646 /* check if index in the buffer */
644 647
645 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || 648 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
646 (num_to_ret == NULL)) 649 (num_to_ret == NULL))
647 return -ENOENT; 650 return -ENOENT;
648 651
649 *ppCurrentEntry = NULL; 652 *ppCurrentEntry = NULL;
650 first_entry_in_buffer = 653 first_entry_in_buffer =
651 cifsFile->srch_inf.index_of_last_entry - 654 cifsFile->srch_inf.index_of_last_entry -
652 cifsFile->srch_inf.entries_in_buffer; 655 cifsFile->srch_inf.entries_in_buffer;
653 656
654 /* if first entry in buf is zero then is first buffer 657 /* if first entry in buf is zero then is first buffer
@@ -660,17 +663,17 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
660#ifdef CONFIG_CIFS_DEBUG2 663#ifdef CONFIG_CIFS_DEBUG2
661 dump_cifs_file_struct(file, "In fce "); 664 dump_cifs_file_struct(file, "In fce ");
662#endif 665#endif
663 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 666 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
664 is_dir_changed(file)) || 667 is_dir_changed(file)) ||
665 (index_to_find < first_entry_in_buffer)) { 668 (index_to_find < first_entry_in_buffer)) {
666 /* close and restart search */ 669 /* close and restart search */
667 cFYI(1,("search backing up - close and restart search")); 670 cFYI(1, ("search backing up - close and restart search"));
668 cifsFile->invalidHandle = TRUE; 671 cifsFile->invalidHandle = TRUE;
669 CIFSFindClose(xid, pTcon, cifsFile->netfid); 672 CIFSFindClose(xid, pTcon, cifsFile->netfid);
670 kfree(cifsFile->search_resume_name); 673 kfree(cifsFile->search_resume_name);
671 cifsFile->search_resume_name = NULL; 674 cifsFile->search_resume_name = NULL;
672 if (cifsFile->srch_inf.ntwrk_buf_start) { 675 if (cifsFile->srch_inf.ntwrk_buf_start) {
673 cFYI(1,("freeing SMB ff cache buf on search rewind")); 676 cFYI(1, ("freeing SMB ff cache buf on search rewind"));
674 if (cifsFile->srch_inf.smallBuf) 677 if (cifsFile->srch_inf.smallBuf)
675 cifs_small_buf_release(cifsFile->srch_inf. 678 cifs_small_buf_release(cifsFile->srch_inf.
676 ntwrk_buf_start); 679 ntwrk_buf_start);
@@ -678,17 +681,18 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
678 cifs_buf_release(cifsFile->srch_inf. 681 cifs_buf_release(cifsFile->srch_inf.
679 ntwrk_buf_start); 682 ntwrk_buf_start);
680 } 683 }
681 rc = initiate_cifs_search(xid,file); 684 rc = initiate_cifs_search(xid, file);
682 if (rc) { 685 if (rc) {
683 cFYI(1,("error %d reinitiating a search on rewind",rc)); 686 cFYI(1, ("error %d reinitiating a search on rewind",
687 rc));
684 return rc; 688 return rc;
685 } 689 }
686 } 690 }
687 691
688 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 692 while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
689 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ 693 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
690 cFYI(1,("calling findnext2")); 694 cFYI(1, ("calling findnext2"));
691 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 695 rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
692 &cifsFile->srch_inf); 696 &cifsFile->srch_inf);
693 if (rc) 697 if (rc)
694 return -ENOENT; 698 return -ENOENT;
@@ -697,8 +701,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
697 /* we found the buffer that contains the entry */ 701 /* we found the buffer that contains the entry */
698 /* scan and find it */ 702 /* scan and find it */
699 int i; 703 int i;
700 char * current_entry; 704 char *current_entry;
701 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 705 char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
702 smbCalcSize((struct smb_hdr *) 706 smbCalcSize((struct smb_hdr *)
703 cifsFile->srch_inf.ntwrk_buf_start); 707 cifsFile->srch_inf.ntwrk_buf_start);
704 708
@@ -706,28 +710,28 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
706 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 710 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
707 - cifsFile->srch_inf.entries_in_buffer; 711 - cifsFile->srch_inf.entries_in_buffer;
708 pos_in_buf = index_to_find - first_entry_in_buffer; 712 pos_in_buf = index_to_find - first_entry_in_buffer;
709 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 713 cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
710 714
711 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 715 for (i=0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
712 /* go entry by entry figuring out which is first */ 716 /* go entry by entry figuring out which is first */
713 current_entry = nxt_dir_entry(current_entry,end_of_smb, 717 current_entry = nxt_dir_entry(current_entry, end_of_smb,
714 cifsFile->srch_inf.info_level); 718 cifsFile->srch_inf.info_level);
715 } 719 }
716 if((current_entry == NULL) && (i < pos_in_buf)) { 720 if ((current_entry == NULL) && (i < pos_in_buf)) {
717 /* BB fixme - check if we should flag this error */ 721 /* BB fixme - check if we should flag this error */
718 cERROR(1,("reached end of buf searching for pos in buf" 722 cERROR(1, ("reached end of buf searching for pos in buf"
719 " %d index to find %lld rc %d", 723 " %d index to find %lld rc %d",
720 pos_in_buf,index_to_find,rc)); 724 pos_in_buf, index_to_find, rc));
721 } 725 }
722 rc = 0; 726 rc = 0;
723 *ppCurrentEntry = current_entry; 727 *ppCurrentEntry = current_entry;
724 } else { 728 } else {
725 cFYI(1,("index not in buffer - could not findnext into it")); 729 cFYI(1, ("index not in buffer - could not findnext into it"));
726 return 0; 730 return 0;
727 } 731 }
728 732
729 if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { 733 if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
730 cFYI(1,("can not return entries pos_in_buf beyond last entry")); 734 cFYI(1, ("can not return entries pos_in_buf beyond last"));
731 *num_to_ret = 0; 735 *num_to_ret = 0;
732 } else 736 } else
733 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; 737 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
@@ -738,81 +742,81 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
738/* inode num, inode type and filename returned */ 742/* inode num, inode type and filename returned */
739static int cifs_get_name_from_search_buf(struct qstr *pqst, 743static int cifs_get_name_from_search_buf(struct qstr *pqst,
740 char *current_entry, __u16 level, unsigned int unicode, 744 char *current_entry, __u16 level, unsigned int unicode,
741 struct cifs_sb_info * cifs_sb, int max_len, ino_t *pinum) 745 struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum)
742{ 746{
743 int rc = 0; 747 int rc = 0;
744 unsigned int len = 0; 748 unsigned int len = 0;
745 char * filename; 749 char *filename;
746 struct nls_table * nlt = cifs_sb->local_nls; 750 struct nls_table *nlt = cifs_sb->local_nls;
747 751
748 *pinum = 0; 752 *pinum = 0;
749 753
750 if(level == SMB_FIND_FILE_UNIX) { 754 if (level == SMB_FIND_FILE_UNIX) {
751 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 755 FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
752 756
753 filename = &pFindData->FileName[0]; 757 filename = &pFindData->FileName[0];
754 if(unicode) { 758 if (unicode) {
755 len = cifs_unicode_bytelen(filename); 759 len = cifs_unicode_bytelen(filename);
756 } else { 760 } else {
757 /* BB should we make this strnlen of PATH_MAX? */ 761 /* BB should we make this strnlen of PATH_MAX? */
758 len = strnlen(filename, PATH_MAX); 762 len = strnlen(filename, PATH_MAX);
759 } 763 }
760 764
761 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB fixme */ 765 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */
762 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 766 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
763 *pinum = pFindData->UniqueId; 767 *pinum = pFindData->UniqueId;
764 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 768 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
765 FILE_DIRECTORY_INFO * pFindData = 769 FILE_DIRECTORY_INFO *pFindData =
766 (FILE_DIRECTORY_INFO *)current_entry; 770 (FILE_DIRECTORY_INFO *)current_entry;
767 filename = &pFindData->FileName[0]; 771 filename = &pFindData->FileName[0];
768 len = le32_to_cpu(pFindData->FileNameLength); 772 len = le32_to_cpu(pFindData->FileNameLength);
769 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 773 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
770 FILE_FULL_DIRECTORY_INFO * pFindData = 774 FILE_FULL_DIRECTORY_INFO *pFindData =
771 (FILE_FULL_DIRECTORY_INFO *)current_entry; 775 (FILE_FULL_DIRECTORY_INFO *)current_entry;
772 filename = &pFindData->FileName[0]; 776 filename = &pFindData->FileName[0];
773 len = le32_to_cpu(pFindData->FileNameLength); 777 len = le32_to_cpu(pFindData->FileNameLength);
774 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 778 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
775 SEARCH_ID_FULL_DIR_INFO * pFindData = 779 SEARCH_ID_FULL_DIR_INFO *pFindData =
776 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 780 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
777 filename = &pFindData->FileName[0]; 781 filename = &pFindData->FileName[0];
778 len = le32_to_cpu(pFindData->FileNameLength); 782 len = le32_to_cpu(pFindData->FileNameLength);
779 *pinum = pFindData->UniqueId; 783 *pinum = pFindData->UniqueId;
780 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 784 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
781 FILE_BOTH_DIRECTORY_INFO * pFindData = 785 FILE_BOTH_DIRECTORY_INFO *pFindData =
782 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 786 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
783 filename = &pFindData->FileName[0]; 787 filename = &pFindData->FileName[0];
784 len = le32_to_cpu(pFindData->FileNameLength); 788 len = le32_to_cpu(pFindData->FileNameLength);
785 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 789 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
786 FIND_FILE_STANDARD_INFO * pFindData = 790 FIND_FILE_STANDARD_INFO * pFindData =
787 (FIND_FILE_STANDARD_INFO *)current_entry; 791 (FIND_FILE_STANDARD_INFO *)current_entry;
788 filename = &pFindData->FileName[0]; 792 filename = &pFindData->FileName[0];
789 /* one byte length, no name conversion */ 793 /* one byte length, no name conversion */
790 len = (unsigned int)pFindData->FileNameLength; 794 len = (unsigned int)pFindData->FileNameLength;
791 } else { 795 } else {
792 cFYI(1,("Unknown findfirst level %d",level)); 796 cFYI(1, ("Unknown findfirst level %d", level));
793 return -EINVAL; 797 return -EINVAL;
794 } 798 }
795 799
796 if(len > max_len) { 800 if (len > max_len) {
797 cERROR(1,("bad search response length %d past smb end", len)); 801 cERROR(1, ("bad search response length %d past smb end", len));
798 return -EINVAL; 802 return -EINVAL;
799 } 803 }
800 804
801 if(unicode) { 805 if (unicode) {
802 /* BB fixme - test with long names */ 806 /* BB fixme - test with long names */
803 /* Note converted filename can be longer than in unicode */ 807 /* Note converted filename can be longer than in unicode */
804 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) 808 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
805 pqst->len = cifs_convertUCSpath((char *)pqst->name, 809 pqst->len = cifs_convertUCSpath((char *)pqst->name,
806 (__le16 *)filename, len/2, nlt); 810 (__le16 *)filename, len/2, nlt);
807 else 811 else
808 pqst->len = cifs_strfromUCS_le((char *)pqst->name, 812 pqst->len = cifs_strfromUCS_le((char *)pqst->name,
809 (__le16 *)filename,len/2,nlt); 813 (__le16 *)filename, len/2, nlt);
810 } else { 814 } else {
811 pqst->name = filename; 815 pqst->name = filename;
812 pqst->len = len; 816 pqst->len = len;
813 } 817 }
814 pqst->hash = full_name_hash(pqst->name,pqst->len); 818 pqst->hash = full_name_hash(pqst->name, pqst->len);
815/* cFYI(1,("filldir on %s",pqst->name)); */ 819/* cFYI(1, ("filldir on %s",pqst->name)); */
816 return rc; 820 return rc;
817} 821}
818 822
@@ -821,49 +825,50 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
821{ 825{
822 int rc = 0; 826 int rc = 0;
823 struct qstr qstring; 827 struct qstr qstring;
824 struct cifsFileInfo * pCifsF; 828 struct cifsFileInfo *pCifsF;
825 unsigned obj_type; 829 unsigned obj_type;
826 ino_t inum; 830 ino_t inum;
827 struct cifs_sb_info * cifs_sb; 831 struct cifs_sb_info *cifs_sb;
828 struct inode *tmp_inode; 832 struct inode *tmp_inode;
829 struct dentry *tmp_dentry; 833 struct dentry *tmp_dentry;
830 834
831 /* get filename and len into qstring */ 835 /* get filename and len into qstring */
832 /* get dentry */ 836 /* get dentry */
833 /* decide whether to create and populate ionde */ 837 /* decide whether to create and populate ionde */
834 if((direntry == NULL) || (file == NULL)) 838 if ((direntry == NULL) || (file == NULL))
835 return -EINVAL; 839 return -EINVAL;
836 840
837 pCifsF = file->private_data; 841 pCifsF = file->private_data;
838 842
839 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) 843 if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
840 return -ENOENT; 844 return -ENOENT;
841 845
842 rc = cifs_entry_is_dot(pfindEntry,pCifsF); 846 rc = cifs_entry_is_dot(pfindEntry, pCifsF);
843 /* skip . and .. since we added them first */ 847 /* skip . and .. since we added them first */
844 if(rc != 0) 848 if (rc != 0)
845 return 0; 849 return 0;
846 850
847 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 851 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
848 852
849 qstring.name = scratch_buf; 853 qstring.name = scratch_buf;
850 rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, 854 rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
851 pCifsF->srch_inf.info_level, 855 pCifsF->srch_inf.info_level,
852 pCifsF->srch_inf.unicode,cifs_sb, 856 pCifsF->srch_inf.unicode, cifs_sb,
853 max_len, 857 max_len,
854 &inum /* returned */); 858 &inum /* returned */);
855 859
856 if(rc) 860 if (rc)
857 return rc; 861 return rc;
858 862
859 rc = construct_dentry(&qstring,file,&tmp_inode, &tmp_dentry); 863 rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry);
860 if((tmp_inode == NULL) || (tmp_dentry == NULL)) 864 if ((tmp_inode == NULL) || (tmp_dentry == NULL))
861 return -ENOMEM; 865 return -ENOMEM;
862 866
863 if(rc) { 867 if (rc) {
864 /* inode created, we need to hash it with right inode number */ 868 /* inode created, we need to hash it with right inode number */
865 if(inum != 0) { 869 if (inum != 0) {
866 /* BB fixme - hash the 2 32 quantities bits together if necessary BB */ 870 /* BB fixme - hash the 2 32 quantities bits together if
871 * necessary BB */
867 tmp_inode->i_ino = inum; 872 tmp_inode->i_ino = inum;
868 } 873 }
869 insert_inode_hash(tmp_inode); 874 insert_inode_hash(tmp_inode);
@@ -872,27 +877,27 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
872 /* we pass in rc below, indicating whether it is a new inode, 877 /* we pass in rc below, indicating whether it is a new inode,
873 so we can figure out whether to invalidate the inode cached 878 so we can figure out whether to invalidate the inode cached
874 data if the file has changed */ 879 data if the file has changed */
875 if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 880 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
876 unix_fill_in_inode(tmp_inode, 881 unix_fill_in_inode(tmp_inode,
877 (FILE_UNIX_INFO *)pfindEntry, 882 (FILE_UNIX_INFO *)pfindEntry,
878 &obj_type, rc); 883 &obj_type, rc);
879 else if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 884 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
880 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, 885 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */,
881 pfindEntry, &obj_type, rc); 886 pfindEntry, &obj_type, rc);
882 else 887 else
883 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); 888 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc);
884 889
885 if(rc) /* new inode - needs to be tied to dentry */ { 890 if (rc) /* new inode - needs to be tied to dentry */ {
886 d_instantiate(tmp_dentry, tmp_inode); 891 d_instantiate(tmp_dentry, tmp_inode);
887 if(rc == 2) 892 if (rc == 2)
888 d_rehash(tmp_dentry); 893 d_rehash(tmp_dentry);
889 } 894 }
890 895
891 896
892 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, 897 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
893 tmp_inode->i_ino,obj_type); 898 tmp_inode->i_ino, obj_type);
894 if(rc) { 899 if (rc) {
895 cFYI(1,("filldir rc = %d",rc)); 900 cFYI(1, ("filldir rc = %d", rc));
896 /* we can not return filldir errors to the caller 901 /* we can not return filldir errors to the caller
897 since they are "normal" when the stat blocksize 902 since they are "normal" when the stat blocksize
898 is too small - we return remapped error instead */ 903 is too small - we return remapped error instead */
@@ -909,57 +914,57 @@ static int cifs_save_resume_key(const char *current_entry,
909 int rc = 0; 914 int rc = 0;
910 unsigned int len = 0; 915 unsigned int len = 0;
911 __u16 level; 916 __u16 level;
912 char * filename; 917 char *filename;
913 918
914 if((cifsFile == NULL) || (current_entry == NULL)) 919 if ((cifsFile == NULL) || (current_entry == NULL))
915 return -EINVAL; 920 return -EINVAL;
916 921
917 level = cifsFile->srch_inf.info_level; 922 level = cifsFile->srch_inf.info_level;
918 923
919 if(level == SMB_FIND_FILE_UNIX) { 924 if (level == SMB_FIND_FILE_UNIX) {
920 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 925 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
921 926
922 filename = &pFindData->FileName[0]; 927 filename = &pFindData->FileName[0];
923 if(cifsFile->srch_inf.unicode) { 928 if (cifsFile->srch_inf.unicode) {
924 len = cifs_unicode_bytelen(filename); 929 len = cifs_unicode_bytelen(filename);
925 } else { 930 } else {
926 /* BB should we make this strnlen of PATH_MAX? */ 931 /* BB should we make this strnlen of PATH_MAX? */
927 len = strnlen(filename, PATH_MAX); 932 len = strnlen(filename, PATH_MAX);
928 } 933 }
929 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 934 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
930 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 935 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
931 FILE_DIRECTORY_INFO * pFindData = 936 FILE_DIRECTORY_INFO *pFindData =
932 (FILE_DIRECTORY_INFO *)current_entry; 937 (FILE_DIRECTORY_INFO *)current_entry;
933 filename = &pFindData->FileName[0]; 938 filename = &pFindData->FileName[0];
934 len = le32_to_cpu(pFindData->FileNameLength); 939 len = le32_to_cpu(pFindData->FileNameLength);
935 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 940 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
936 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 941 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
937 FILE_FULL_DIRECTORY_INFO * pFindData = 942 FILE_FULL_DIRECTORY_INFO *pFindData =
938 (FILE_FULL_DIRECTORY_INFO *)current_entry; 943 (FILE_FULL_DIRECTORY_INFO *)current_entry;
939 filename = &pFindData->FileName[0]; 944 filename = &pFindData->FileName[0];
940 len = le32_to_cpu(pFindData->FileNameLength); 945 len = le32_to_cpu(pFindData->FileNameLength);
941 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 946 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
942 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 947 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
943 SEARCH_ID_FULL_DIR_INFO * pFindData = 948 SEARCH_ID_FULL_DIR_INFO *pFindData =
944 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 949 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
945 filename = &pFindData->FileName[0]; 950 filename = &pFindData->FileName[0];
946 len = le32_to_cpu(pFindData->FileNameLength); 951 len = le32_to_cpu(pFindData->FileNameLength);
947 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 952 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
948 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 953 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
949 FILE_BOTH_DIRECTORY_INFO * pFindData = 954 FILE_BOTH_DIRECTORY_INFO *pFindData =
950 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 955 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
951 filename = &pFindData->FileName[0]; 956 filename = &pFindData->FileName[0];
952 len = le32_to_cpu(pFindData->FileNameLength); 957 len = le32_to_cpu(pFindData->FileNameLength);
953 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 958 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
954 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 959 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
955 FIND_FILE_STANDARD_INFO * pFindData = 960 FIND_FILE_STANDARD_INFO *pFindData =
956 (FIND_FILE_STANDARD_INFO *)current_entry; 961 (FIND_FILE_STANDARD_INFO *)current_entry;
957 filename = &pFindData->FileName[0]; 962 filename = &pFindData->FileName[0];
958 /* one byte length, no name conversion */ 963 /* one byte length, no name conversion */
959 len = (unsigned int)pFindData->FileNameLength; 964 len = (unsigned int)pFindData->FileNameLength;
960 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 965 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
961 } else { 966 } else {
962 cFYI(1,("Unknown findfirst level %d",level)); 967 cFYI(1, ("Unknown findfirst level %d", level));
963 return -EINVAL; 968 return -EINVAL;
964 } 969 }
965 cifsFile->srch_inf.resume_name_len = len; 970 cifsFile->srch_inf.resume_name_len = len;
@@ -970,21 +975,21 @@ static int cifs_save_resume_key(const char *current_entry,
970int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) 975int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
971{ 976{
972 int rc = 0; 977 int rc = 0;
973 int xid,i; 978 int xid, i;
974 struct cifs_sb_info *cifs_sb; 979 struct cifs_sb_info *cifs_sb;
975 struct cifsTconInfo *pTcon; 980 struct cifsTconInfo *pTcon;
976 struct cifsFileInfo *cifsFile = NULL; 981 struct cifsFileInfo *cifsFile = NULL;
977 char * current_entry; 982 char *current_entry;
978 int num_to_fill = 0; 983 int num_to_fill = 0;
979 char * tmp_buf = NULL; 984 char *tmp_buf = NULL;
980 char * end_of_smb; 985 char *end_of_smb;
981 int max_len; 986 int max_len;
982 987
983 xid = GetXid(); 988 xid = GetXid();
984 989
985 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 990 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
986 pTcon = cifs_sb->tcon; 991 pTcon = cifs_sb->tcon;
987 if(pTcon == NULL) 992 if (pTcon == NULL)
988 return -EINVAL; 993 return -EINVAL;
989 994
990 switch ((int) file->f_pos) { 995 switch ((int) file->f_pos) {
@@ -1005,27 +1010,27 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1005 } 1010 }
1006 file->f_pos++; 1011 file->f_pos++;
1007 default: 1012 default:
1008 /* 1) If search is active, 1013 /* 1) If search is active,
1009 is in current search buffer? 1014 is in current search buffer?
1010 if it before then restart search 1015 if it before then restart search
1011 if after then keep searching till find it */ 1016 if after then keep searching till find it */
1012 1017
1013 if(file->private_data == NULL) { 1018 if (file->private_data == NULL) {
1014 rc = initiate_cifs_search(xid,file); 1019 rc = initiate_cifs_search(xid, file);
1015 cFYI(1,("initiate cifs search rc %d",rc)); 1020 cFYI(1, ("initiate cifs search rc %d", rc));
1016 if(rc) { 1021 if (rc) {
1017 FreeXid(xid); 1022 FreeXid(xid);
1018 return rc; 1023 return rc;
1019 } 1024 }
1020 } 1025 }
1021 if(file->private_data == NULL) { 1026 if (file->private_data == NULL) {
1022 rc = -EINVAL; 1027 rc = -EINVAL;
1023 FreeXid(xid); 1028 FreeXid(xid);
1024 return rc; 1029 return rc;
1025 } 1030 }
1026 cifsFile = file->private_data; 1031 cifsFile = file->private_data;
1027 if (cifsFile->srch_inf.endOfSearch) { 1032 if (cifsFile->srch_inf.endOfSearch) {
1028 if(cifsFile->srch_inf.emptyDir) { 1033 if (cifsFile->srch_inf.emptyDir) {
1029 cFYI(1, ("End of search, empty dir")); 1034 cFYI(1, ("End of search, empty dir"));
1030 rc = 0; 1035 rc = 0;
1031 break; 1036 break;
@@ -1033,23 +1038,23 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1033 } /* else { 1038 } /* else {
1034 cifsFile->invalidHandle = TRUE; 1039 cifsFile->invalidHandle = TRUE;
1035 CIFSFindClose(xid, pTcon, cifsFile->netfid); 1040 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1036 } 1041 }
1037 kfree(cifsFile->search_resume_name); 1042 kfree(cifsFile->search_resume_name);
1038 cifsFile->search_resume_name = NULL; */ 1043 cifsFile->search_resume_name = NULL; */
1039 1044
1040 rc = find_cifs_entry(xid,pTcon, file, 1045 rc = find_cifs_entry(xid, pTcon, file,
1041 &current_entry,&num_to_fill); 1046 &current_entry, &num_to_fill);
1042 if(rc) { 1047 if (rc) {
1043 cFYI(1,("fce error %d",rc)); 1048 cFYI(1, ("fce error %d", rc));
1044 goto rddir2_exit; 1049 goto rddir2_exit;
1045 } else if (current_entry != NULL) { 1050 } else if (current_entry != NULL) {
1046 cFYI(1,("entry %lld found",file->f_pos)); 1051 cFYI(1, ("entry %lld found", file->f_pos));
1047 } else { 1052 } else {
1048 cFYI(1,("could not find entry")); 1053 cFYI(1, ("could not find entry"));
1049 goto rddir2_exit; 1054 goto rddir2_exit;
1050 } 1055 }
1051 cFYI(1,("loop through %d times filling dir for net buf %p", 1056 cFYI(1, ("loop through %d times filling dir for net buf %p",
1052 num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); 1057 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));
1053 max_len = smbCalcSize((struct smb_hdr *) 1058 max_len = smbCalcSize((struct smb_hdr *)
1054 cifsFile->srch_inf.ntwrk_buf_start); 1059 cifsFile->srch_inf.ntwrk_buf_start);
1055 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 1060 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
@@ -1059,8 +1064,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1059 such multibyte target UTF-8 characters. cifs_unicode.c, 1064 such multibyte target UTF-8 characters. cifs_unicode.c,
1060 which actually does the conversion, has the same limit */ 1065 which actually does the conversion, has the same limit */
1061 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL); 1066 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
1062 for(i=0;(i<num_to_fill) && (rc == 0);i++) { 1067 for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
1063 if(current_entry == NULL) { 1068 if (current_entry == NULL) {
1064 /* evaluate whether this case is an error */ 1069 /* evaluate whether this case is an error */
1065 cERROR(1,("past end of SMB num to fill %d i %d", 1070 cERROR(1,("past end of SMB num to fill %d i %d",
1066 num_to_fill, i)); 1071 num_to_fill, i));
@@ -1070,20 +1075,20 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1070 we want to check for that here? */ 1075 we want to check for that here? */
1071 rc = cifs_filldir(current_entry, file, 1076 rc = cifs_filldir(current_entry, file,
1072 filldir, direntry, tmp_buf, max_len); 1077 filldir, direntry, tmp_buf, max_len);
1073 if(rc == -EOVERFLOW) { 1078 if (rc == -EOVERFLOW) {
1074 rc = 0; 1079 rc = 0;
1075 break; 1080 break;
1076 } 1081 }
1077 1082
1078 file->f_pos++; 1083 file->f_pos++;
1079 if(file->f_pos == 1084 if (file->f_pos ==
1080 cifsFile->srch_inf.index_of_last_entry) { 1085 cifsFile->srch_inf.index_of_last_entry) {
1081 cFYI(1,("last entry in buf at pos %lld %s", 1086 cFYI(1, ("last entry in buf at pos %lld %s",
1082 file->f_pos,tmp_buf)); 1087 file->f_pos, tmp_buf));
1083 cifs_save_resume_key(current_entry,cifsFile); 1088 cifs_save_resume_key(current_entry, cifsFile);
1084 break; 1089 break;
1085 } else 1090 } else
1086 current_entry = 1091 current_entry =
1087 nxt_dir_entry(current_entry, end_of_smb, 1092 nxt_dir_entry(current_entry, end_of_smb,
1088 cifsFile->srch_inf.info_level); 1093 cifsFile->srch_inf.info_level);
1089 } 1094 }
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 758464630893..2ea027dda215 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * SMB/CIFS session setup handling routines 4 * SMB/CIFS session setup handling routines
5 * 5 *
6 * Copyright (c) International Business Machines Corp., 2006 6 * Copyright (c) International Business Machines Corp., 2006, 2007
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
31#include <linux/utsname.h> 31#include <linux/utsname.h>
32 32
33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
34 unsigned char *p24); 34 unsigned char *p24);
35 35
36static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 36static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
37{ 37{
@@ -45,13 +45,14 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
45 45
46 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ 46 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
47 47
48 /* BB verify whether signing required on neg or just on auth frame 48 /* BB verify whether signing required on neg or just on auth frame
49 (and NTLM case) */ 49 (and NTLM case) */
50 50
51 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 51 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
52 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 52 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
53 53
54 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 54 if (ses->server->secMode &
55 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
55 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 56 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
56 57
57 if (ses->capabilities & CAP_UNICODE) { 58 if (ses->capabilities & CAP_UNICODE) {
@@ -74,10 +75,10 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
74 return capabilities; 75 return capabilities;
75} 76}
76 77
77static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 78static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
78 const struct nls_table * nls_cp) 79 const struct nls_table *nls_cp)
79{ 80{
80 char * bcc_ptr = *pbcc_area; 81 char *bcc_ptr = *pbcc_area;
81 int bytes_ret = 0; 82 int bytes_ret = 0;
82 83
83 /* BB FIXME add check that strings total less 84 /* BB FIXME add check that strings total less
@@ -89,7 +90,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
89 bcc_ptr++; 90 bcc_ptr++;
90 } */ 91 } */
91 /* copy user */ 92 /* copy user */
92 if(ses->userName == NULL) { 93 if (ses->userName == NULL) {
93 /* null user mount */ 94 /* null user mount */
94 *bcc_ptr = 0; 95 *bcc_ptr = 0;
95 *(bcc_ptr+1) = 0; 96 *(bcc_ptr+1) = 0;
@@ -100,14 +101,14 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
100 bcc_ptr += 2 * bytes_ret; 101 bcc_ptr += 2 * bytes_ret;
101 bcc_ptr += 2; /* account for null termination */ 102 bcc_ptr += 2; /* account for null termination */
102 /* copy domain */ 103 /* copy domain */
103 if(ses->domainName == NULL) { 104 if (ses->domainName == NULL) {
104 /* Sending null domain better than using a bogus domain name (as 105 /* Sending null domain better than using a bogus domain name (as
105 we did briefly in 2.6.18) since server will use its default */ 106 we did briefly in 2.6.18) since server will use its default */
106 *bcc_ptr = 0; 107 *bcc_ptr = 0;
107 *(bcc_ptr+1) = 0; 108 *(bcc_ptr+1) = 0;
108 bytes_ret = 0; 109 bytes_ret = 0;
109 } else 110 } else
110 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 111 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
111 256, nls_cp); 112 256, nls_cp);
112 bcc_ptr += 2 * bytes_ret; 113 bcc_ptr += 2 * bytes_ret;
113 bcc_ptr += 2; /* account for null terminator */ 114 bcc_ptr += 2; /* account for null terminator */
@@ -122,37 +123,37 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
122 bcc_ptr += 2; /* trailing null */ 123 bcc_ptr += 2; /* trailing null */
123 124
124 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 125 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
125 32, nls_cp); 126 32, nls_cp);
126 bcc_ptr += 2 * bytes_ret; 127 bcc_ptr += 2 * bytes_ret;
127 bcc_ptr += 2; /* trailing null */ 128 bcc_ptr += 2; /* trailing null */
128 129
129 *pbcc_area = bcc_ptr; 130 *pbcc_area = bcc_ptr;
130} 131}
131 132
132static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 133static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
133 const struct nls_table * nls_cp) 134 const struct nls_table *nls_cp)
134{ 135{
135 char * bcc_ptr = *pbcc_area; 136 char *bcc_ptr = *pbcc_area;
136 137
137 /* copy user */ 138 /* copy user */
138 /* BB what about null user mounts - check that we do this BB */ 139 /* BB what about null user mounts - check that we do this BB */
139 /* copy user */ 140 /* copy user */
140 if(ses->userName == NULL) { 141 if (ses->userName == NULL) {
141 /* BB what about null user mounts - check that we do this BB */ 142 /* BB what about null user mounts - check that we do this BB */
142 } else { /* 300 should be long enough for any conceivable user name */ 143 } else { /* 300 should be long enough for any conceivable user name */
143 strncpy(bcc_ptr, ses->userName, 300); 144 strncpy(bcc_ptr, ses->userName, 300);
144 } 145 }
145 /* BB improve check for overflow */ 146 /* BB improve check for overflow */
146 bcc_ptr += strnlen(ses->userName, 300); 147 bcc_ptr += strnlen(ses->userName, 300);
147 *bcc_ptr = 0; 148 *bcc_ptr = 0;
148 bcc_ptr++; /* account for null termination */ 149 bcc_ptr++; /* account for null termination */
149 150
150 /* copy domain */ 151 /* copy domain */
151 152
152 if(ses->domainName != NULL) { 153 if (ses->domainName != NULL) {
153 strncpy(bcc_ptr, ses->domainName, 256); 154 strncpy(bcc_ptr, ses->domainName, 256);
154 bcc_ptr += strnlen(ses->domainName, 256); 155 bcc_ptr += strnlen(ses->domainName, 256);
155 } /* else we will send a null domain name 156 } /* else we will send a null domain name
156 so the server will default to its own domain */ 157 so the server will default to its own domain */
157 *bcc_ptr = 0; 158 *bcc_ptr = 0;
158 bcc_ptr++; 159 bcc_ptr++;
@@ -167,19 +168,20 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
167 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); 168 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
168 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; 169 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
169 170
170 *pbcc_area = bcc_ptr; 171 *pbcc_area = bcc_ptr;
171} 172}
172 173
173static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 174static int decode_unicode_ssetup(char **pbcc_area, int bleft,
174 const struct nls_table * nls_cp) 175 struct cifsSesInfo *ses,
176 const struct nls_table *nls_cp)
175{ 177{
176 int rc = 0; 178 int rc = 0;
177 int words_left, len; 179 int words_left, len;
178 char * data = *pbcc_area; 180 char *data = *pbcc_area;
179 181
180 182
181 183
182 cFYI(1,("bleft %d",bleft)); 184 cFYI(1, ("bleft %d", bleft));
183 185
184 186
185 /* SMB header is unaligned, so cifs servers word align start of 187 /* SMB header is unaligned, so cifs servers word align start of
@@ -189,7 +191,7 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
189 their final Unicode string - in which case we 191 their final Unicode string - in which case we
190 now will not attempt to decode the byte of junk 192 now will not attempt to decode the byte of junk
191 which follows it */ 193 which follows it */
192 194
193 words_left = bleft / 2; 195 words_left = bleft / 2;
194 196
195 /* save off server operating system */ 197 /* save off server operating system */
@@ -198,14 +200,14 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
198/* We look for obvious messed up bcc or strings in response so we do not go off 200/* We look for obvious messed up bcc or strings in response so we do not go off
199 the end since (at least) WIN2K and Windows XP have a major bug in not null 201 the end since (at least) WIN2K and Windows XP have a major bug in not null
200 terminating last Unicode string in response */ 202 terminating last Unicode string in response */
201 if(len >= words_left) 203 if (len >= words_left)
202 return rc; 204 return rc;
203 205
204 if(ses->serverOS) 206 if (ses->serverOS)
205 kfree(ses->serverOS); 207 kfree(ses->serverOS);
206 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 208 /* UTF-8 string will not grow more than four times as big as UCS-16 */
207 ses->serverOS = kzalloc(4 * len, GFP_KERNEL); 209 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
208 if(ses->serverOS != NULL) { 210 if (ses->serverOS != NULL) {
209 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, 211 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
210 nls_cp); 212 nls_cp);
211 } 213 }
@@ -215,67 +217,68 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
215 /* save off server network operating system */ 217 /* save off server network operating system */
216 len = UniStrnlen((wchar_t *) data, words_left); 218 len = UniStrnlen((wchar_t *) data, words_left);
217 219
218 if(len >= words_left) 220 if (len >= words_left)
219 return rc; 221 return rc;
220 222
221 if(ses->serverNOS) 223 if (ses->serverNOS)
222 kfree(ses->serverNOS); 224 kfree(ses->serverNOS);
223 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ 225 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
224 if(ses->serverNOS != NULL) { 226 if (ses->serverNOS != NULL) {
225 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 227 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
226 nls_cp); 228 nls_cp);
227 if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) { 229 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
228 cFYI(1,("NT4 server")); 230 cFYI(1, ("NT4 server"));
229 ses->flags |= CIFS_SES_NT4; 231 ses->flags |= CIFS_SES_NT4;
230 } 232 }
231 } 233 }
232 data += 2 * (len + 1); 234 data += 2 * (len + 1);
233 words_left -= len + 1; 235 words_left -= len + 1;
234 236
235 /* save off server domain */ 237 /* save off server domain */
236 len = UniStrnlen((wchar_t *) data, words_left); 238 len = UniStrnlen((wchar_t *) data, words_left);
237 239
238 if(len > words_left) 240 if (len > words_left)
239 return rc; 241 return rc;
240 242
241 if(ses->serverDomain) 243 if (ses->serverDomain)
242 kfree(ses->serverDomain); 244 kfree(ses->serverDomain);
243 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 245 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
244 if(ses->serverDomain != NULL) { 246 if (ses->serverDomain != NULL) {
245 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 247 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
246 nls_cp); 248 nls_cp);
247 ses->serverDomain[2*len] = 0; 249 ses->serverDomain[2*len] = 0;
248 ses->serverDomain[(2*len) + 1] = 0; 250 ses->serverDomain[(2*len) + 1] = 0;
249 } 251 }
250 data += 2 * (len + 1); 252 data += 2 * (len + 1);
251 words_left -= len + 1; 253 words_left -= len + 1;
252 254
253 cFYI(1,("words left: %d",words_left)); 255 cFYI(1, ("words left: %d", words_left));
254 256
255 return rc; 257 return rc;
256} 258}
257 259
258static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 260static int decode_ascii_ssetup(char **pbcc_area, int bleft,
259 const struct nls_table * nls_cp) 261 struct cifsSesInfo *ses,
262 const struct nls_table *nls_cp)
260{ 263{
261 int rc = 0; 264 int rc = 0;
262 int len; 265 int len;
263 char * bcc_ptr = *pbcc_area; 266 char *bcc_ptr = *pbcc_area;
267
268 cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
264 269
265 cFYI(1,("decode sessetup ascii. bleft %d", bleft));
266
267 len = strnlen(bcc_ptr, bleft); 270 len = strnlen(bcc_ptr, bleft);
268 if(len >= bleft) 271 if (len >= bleft)
269 return rc; 272 return rc;
270 273
271 if(ses->serverOS) 274 if (ses->serverOS)
272 kfree(ses->serverOS); 275 kfree(ses->serverOS);
273 276
274 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 277 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
275 if(ses->serverOS) 278 if (ses->serverOS)
276 strncpy(ses->serverOS, bcc_ptr, len); 279 strncpy(ses->serverOS, bcc_ptr, len);
277 if(strncmp(ses->serverOS, "OS/2",4) == 0) { 280 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
278 cFYI(1,("OS/2 server")); 281 cFYI(1, ("OS/2 server"));
279 ses->flags |= CIFS_SES_OS2; 282 ses->flags |= CIFS_SES_OS2;
280 } 283 }
281 284
@@ -283,34 +286,34 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
283 bleft -= len + 1; 286 bleft -= len + 1;
284 287
285 len = strnlen(bcc_ptr, bleft); 288 len = strnlen(bcc_ptr, bleft);
286 if(len >= bleft) 289 if (len >= bleft)
287 return rc; 290 return rc;
288 291
289 if(ses->serverNOS) 292 if (ses->serverNOS)
290 kfree(ses->serverNOS); 293 kfree(ses->serverNOS);
291 294
292 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); 295 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
293 if(ses->serverNOS) 296 if (ses->serverNOS)
294 strncpy(ses->serverNOS, bcc_ptr, len); 297 strncpy(ses->serverNOS, bcc_ptr, len);
295 298
296 bcc_ptr += len + 1; 299 bcc_ptr += len + 1;
297 bleft -= len + 1; 300 bleft -= len + 1;
298 301
299 len = strnlen(bcc_ptr, bleft); 302 len = strnlen(bcc_ptr, bleft);
300 if(len > bleft) 303 if (len > bleft)
301 return rc; 304 return rc;
302 305
303 /* No domain field in LANMAN case. Domain is 306 /* No domain field in LANMAN case. Domain is
304 returned by old servers in the SMB negprot response */ 307 returned by old servers in the SMB negprot response */
305 /* BB For newer servers which do not support Unicode, 308 /* BB For newer servers which do not support Unicode,
306 but thus do return domain here we could add parsing 309 but thus do return domain here we could add parsing
307 for it later, but it is not very important */ 310 for it later, but it is not very important */
308 cFYI(1,("ascii: bytes left %d",bleft)); 311 cFYI(1, ("ascii: bytes left %d", bleft));
309 312
310 return rc; 313 return rc;
311} 314}
312 315
313int 316int
314CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, 317CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
315 const struct nls_table *nls_cp) 318 const struct nls_table *nls_cp)
316{ 319{
@@ -328,13 +331,13 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
328 __u16 action; 331 __u16 action;
329 int bytes_remaining; 332 int bytes_remaining;
330 333
331 if(ses == NULL) 334 if (ses == NULL)
332 return -EINVAL; 335 return -EINVAL;
333 336
334 type = ses->server->secType; 337 type = ses->server->secType;
335 338
336 cFYI(1,("sess setup type %d",type)); 339 cFYI(1, ("sess setup type %d", type));
337 if(type == LANMAN) { 340 if (type == LANMAN) {
338#ifndef CONFIG_CIFS_WEAK_PW_HASH 341#ifndef CONFIG_CIFS_WEAK_PW_HASH
339 /* LANMAN and plaintext are less secure and off by default. 342 /* LANMAN and plaintext are less secure and off by default.
340 So we make this explicitly be turned on in kconfig (in the 343 So we make this explicitly be turned on in kconfig (in the
@@ -344,15 +347,15 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
344 return -EOPNOTSUPP; 347 return -EOPNOTSUPP;
345#endif 348#endif
346 wct = 10; /* lanman 2 style sessionsetup */ 349 wct = 10; /* lanman 2 style sessionsetup */
347 } else if((type == NTLM) || (type == NTLMv2)) { 350 } else if ((type == NTLM) || (type == NTLMv2)) {
348 /* For NTLMv2 failures eventually may need to retry NTLM */ 351 /* For NTLMv2 failures eventually may need to retry NTLM */
349 wct = 13; /* old style NTLM sessionsetup */ 352 wct = 13; /* old style NTLM sessionsetup */
350 } else /* same size for negotiate or auth, NTLMSSP or extended security */ 353 } else /* same size: negotiate or auth, NTLMSSP or extended security */
351 wct = 12; 354 wct = 12;
352 355
353 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, 356 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
354 (void **)&smb_buf); 357 (void **)&smb_buf);
355 if(rc) 358 if (rc)
356 return rc; 359 return rc;
357 360
358 pSMB = (SESSION_SETUP_ANDX *)smb_buf; 361 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
@@ -364,8 +367,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
364 second part which will include the strings 367 second part which will include the strings
365 and rest of bcc area, in order to avoid having 368 and rest of bcc area, in order to avoid having
366 to do a large buffer 17K allocation */ 369 to do a large buffer 17K allocation */
367 iov[0].iov_base = (char *)pSMB; 370 iov[0].iov_base = (char *)pSMB;
368 iov[0].iov_len = smb_buf->smb_buf_length + 4; 371 iov[0].iov_len = smb_buf->smb_buf_length + 4;
369 372
370 /* 2000 big enough to fit max user, domain, NOS name etc. */ 373 /* 2000 big enough to fit max user, domain, NOS name etc. */
371 str_area = kmalloc(2000, GFP_KERNEL); 374 str_area = kmalloc(2000, GFP_KERNEL);
@@ -373,18 +376,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
373 376
374 ses->flags &= ~CIFS_SES_LANMAN; 377 ses->flags &= ~CIFS_SES_LANMAN;
375 378
376 if(type == LANMAN) { 379 if (type == LANMAN) {
377#ifdef CONFIG_CIFS_WEAK_PW_HASH 380#ifdef CONFIG_CIFS_WEAK_PW_HASH
378 char lnm_session_key[CIFS_SESS_KEY_SIZE]; 381 char lnm_session_key[CIFS_SESS_KEY_SIZE];
379 382
380 /* no capabilities flags in old lanman negotiation */ 383 /* no capabilities flags in old lanman negotiation */
381 384
382 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 385 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
383 /* BB calculate hash with password */ 386 /* BB calculate hash with password */
384 /* and copy into bcc */ 387 /* and copy into bcc */
385 388
386 calc_lanman_hash(ses, lnm_session_key); 389 calc_lanman_hash(ses, lnm_session_key);
387 ses->flags |= CIFS_SES_LANMAN; 390 ses->flags |= CIFS_SES_LANMAN;
388/* #ifdef CONFIG_CIFS_DEBUG2 391/* #ifdef CONFIG_CIFS_DEBUG2
389 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 392 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
390 CIFS_SESS_KEY_SIZE); 393 CIFS_SESS_KEY_SIZE);
@@ -397,10 +400,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
397 changed to do higher than lanman dialect and 400 changed to do higher than lanman dialect and
398 we reconnected would we ever calc signing_key? */ 401 we reconnected would we ever calc signing_key? */
399 402
400 cFYI(1,("Negotiating LANMAN setting up strings")); 403 cFYI(1, ("Negotiating LANMAN setting up strings"));
401 /* Unicode not allowed for LANMAN dialects */ 404 /* Unicode not allowed for LANMAN dialects */
402 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 405 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
403#endif 406#endif
404 } else if (type == NTLM) { 407 } else if (type == NTLM) {
405 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 408 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
406 409
@@ -409,38 +412,38 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
409 cpu_to_le16(CIFS_SESS_KEY_SIZE); 412 cpu_to_le16(CIFS_SESS_KEY_SIZE);
410 pSMB->req_no_secext.CaseSensitivePasswordLength = 413 pSMB->req_no_secext.CaseSensitivePasswordLength =
411 cpu_to_le16(CIFS_SESS_KEY_SIZE); 414 cpu_to_le16(CIFS_SESS_KEY_SIZE);
412 415
413 /* calculate session key */ 416 /* calculate session key */
414 SMBNTencrypt(ses->password, ses->server->cryptKey, 417 SMBNTencrypt(ses->password, ses->server->cryptKey,
415 ntlm_session_key); 418 ntlm_session_key);
416 419
417 if(first_time) /* should this be moved into common code 420 if (first_time) /* should this be moved into common code
418 with similar ntlmv2 path? */ 421 with similar ntlmv2 path? */
419 cifs_calculate_mac_key(ses->server->mac_signing_key, 422 cifs_calculate_mac_key(&ses->server->mac_signing_key,
420 ntlm_session_key, ses->password); 423 ntlm_session_key, ses->password);
421 /* copy session key */ 424 /* copy session key */
422 425
423 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 426 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
424 bcc_ptr += CIFS_SESS_KEY_SIZE; 427 bcc_ptr += CIFS_SESS_KEY_SIZE;
425 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); 428 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
426 bcc_ptr += CIFS_SESS_KEY_SIZE; 429 bcc_ptr += CIFS_SESS_KEY_SIZE;
427 if(ses->capabilities & CAP_UNICODE) { 430 if (ses->capabilities & CAP_UNICODE) {
428 /* unicode strings must be word aligned */ 431 /* unicode strings must be word aligned */
429 if (iov[0].iov_len % 2) { 432 if (iov[0].iov_len % 2) {
430 *bcc_ptr = 0; 433 *bcc_ptr = 0;
431 bcc_ptr++; 434 bcc_ptr++;
432 } 435 }
433 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 436 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
434 } else 437 } else
435 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 438 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
436 } else if (type == NTLMv2) { 439 } else if (type == NTLMv2) {
437 char * v2_sess_key = 440 char *v2_sess_key =
438 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL); 441 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
439 442
440 /* BB FIXME change all users of v2_sess_key to 443 /* BB FIXME change all users of v2_sess_key to
441 struct ntlmv2_resp */ 444 struct ntlmv2_resp */
442 445
443 if(v2_sess_key == NULL) { 446 if (v2_sess_key == NULL) {
444 cifs_small_buf_release(smb_buf); 447 cifs_small_buf_release(smb_buf);
445 return -ENOMEM; 448 return -ENOMEM;
446 } 449 }
@@ -456,8 +459,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
456 459
457 /* calculate session key */ 460 /* calculate session key */
458 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 461 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
459 if(first_time) /* should this be moved into common code 462 if (first_time) /* should this be moved into common code
460 with similar ntlmv2 path? */ 463 with similar ntlmv2 path? */
461 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, 464 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
462 response BB FIXME, v2_sess_key); */ 465 response BB FIXME, v2_sess_key); */
463 466
@@ -465,11 +468,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
465 468
466 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); 469 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
467 bcc_ptr += LM2_SESS_KEY_SIZE; */ 470 bcc_ptr += LM2_SESS_KEY_SIZE; */
468 memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); 471 memcpy(bcc_ptr, (char *)v2_sess_key,
472 sizeof(struct ntlmv2_resp));
469 bcc_ptr += sizeof(struct ntlmv2_resp); 473 bcc_ptr += sizeof(struct ntlmv2_resp);
470 kfree(v2_sess_key); 474 kfree(v2_sess_key);
471 if(ses->capabilities & CAP_UNICODE) { 475 if (ses->capabilities & CAP_UNICODE) {
472 if(iov[0].iov_len % 2) { 476 if (iov[0].iov_len % 2) {
473 *bcc_ptr = 0; 477 *bcc_ptr = 0;
474 } bcc_ptr++; 478 } bcc_ptr++;
475 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 479 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -488,20 +492,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
488 BCC_LE(smb_buf) = cpu_to_le16(count); 492 BCC_LE(smb_buf) = cpu_to_le16(count);
489 493
490 iov[1].iov_base = str_area; 494 iov[1].iov_base = str_area;
491 iov[1].iov_len = count; 495 iov[1].iov_len = count;
492 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); 496 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
493 /* SMB request buf freed in SendReceive2 */ 497 /* SMB request buf freed in SendReceive2 */
494 498
495 cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); 499 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
496 if(rc) 500 if (rc)
497 goto ssetup_exit; 501 goto ssetup_exit;
498 502
499 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; 503 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
500 smb_buf = (struct smb_hdr *)iov[0].iov_base; 504 smb_buf = (struct smb_hdr *)iov[0].iov_base;
501 505
502 if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { 506 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
503 rc = -EIO; 507 rc = -EIO;
504 cERROR(1,("bad word count %d", smb_buf->WordCount)); 508 cERROR(1, ("bad word count %d", smb_buf->WordCount));
505 goto ssetup_exit; 509 goto ssetup_exit;
506 } 510 }
507 action = le16_to_cpu(pSMB->resp.Action); 511 action = le16_to_cpu(pSMB->resp.Action);
@@ -514,31 +518,32 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
514 bytes_remaining = BCC(smb_buf); 518 bytes_remaining = BCC(smb_buf);
515 bcc_ptr = pByteArea(smb_buf); 519 bcc_ptr = pByteArea(smb_buf);
516 520
517 if(smb_buf->WordCount == 4) { 521 if (smb_buf->WordCount == 4) {
518 __u16 blob_len; 522 __u16 blob_len;
519 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); 523 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
520 bcc_ptr += blob_len; 524 bcc_ptr += blob_len;
521 if(blob_len > bytes_remaining) { 525 if (blob_len > bytes_remaining) {
522 cERROR(1,("bad security blob length %d", blob_len)); 526 cERROR(1, ("bad security blob length %d", blob_len));
523 rc = -EINVAL; 527 rc = -EINVAL;
524 goto ssetup_exit; 528 goto ssetup_exit;
525 } 529 }
526 bytes_remaining -= blob_len; 530 bytes_remaining -= blob_len;
527 } 531 }
528 532
529 /* BB check if Unicode and decode strings */ 533 /* BB check if Unicode and decode strings */
530 if(smb_buf->Flags2 & SMBFLG2_UNICODE) 534 if (smb_buf->Flags2 & SMBFLG2_UNICODE)
531 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 535 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
532 ses, nls_cp); 536 ses, nls_cp);
533 else 537 else
534 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp); 538 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
535 539 ses, nls_cp);
540
536ssetup_exit: 541ssetup_exit:
537 kfree(str_area); 542 kfree(str_area);
538 if(resp_buf_type == CIFS_SMALL_BUFFER) { 543 if (resp_buf_type == CIFS_SMALL_BUFFER) {
539 cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base)); 544 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
540 cifs_small_buf_release(iov[0].iov_base); 545 cifs_small_buf_release(iov[0].iov_base);
541 } else if(resp_buf_type == CIFS_LARGE_BUFFER) 546 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
542 cifs_buf_release(iov[0].iov_base); 547 cifs_buf_release(iov[0].iov_base);
543 548
544 return rc; 549 return rc;
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index 1b1daf63f062..cfa6d21fb4e8 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -1,32 +1,32 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 4
5 a partial implementation of DES designed for use in the 5 a partial implementation of DES designed for use in the
6 SMB authentication protocol 6 SMB authentication protocol
7 7
8 Copyright (C) Andrew Tridgell 1998 8 Copyright (C) Andrew Tridgell 1998
9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004 9 Modified by Steve French (sfrench@us.ibm.com) 2002,2004
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/ 24*/
25 25
26/* NOTES: 26/* NOTES:
27 27
28 This code makes no attempt to be fast! In fact, it is a very 28 This code makes no attempt to be fast! In fact, it is a very
29 slow implementation 29 slow implementation
30 30
31 This code is NOT a complete DES implementation. It implements only 31 This code is NOT a complete DES implementation. It implements only
32 the minimum necessary for SMB authentication, as used by all SMB 32 the minimum necessary for SMB authentication, as used by all SMB
@@ -153,7 +153,7 @@ static uchar sbox[8][4][16] = {
153}; 153};
154 154
155static void 155static void
156permute(char *out, char *in, uchar * p, int n) 156permute(char *out, char *in, uchar *p, int n)
157{ 157{
158 int i; 158 int i;
159 for (i = 0; i < n; i++) 159 for (i = 0; i < n; i++)
@@ -202,18 +202,18 @@ dohash(char *out, char *in, char *key, int forw)
202 char *rl; 202 char *rl;
203 203
204 /* Have to reduce stack usage */ 204 /* Have to reduce stack usage */
205 pk1 = kmalloc(56+56+64+64,GFP_KERNEL); 205 pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
206 if(pk1 == NULL) 206 if (pk1 == NULL)
207 return; 207 return;
208 208
209 ki = kmalloc(16*48, GFP_KERNEL); 209 ki = kmalloc(16*48, GFP_KERNEL);
210 if(ki == NULL) { 210 if (ki == NULL) {
211 kfree(pk1); 211 kfree(pk1);
212 return; 212 return;
213 } 213 }
214 214
215 cd = pk1 + 56; 215 cd = pk1 + 56;
216 pd1= cd + 56; 216 pd1 = cd + 56;
217 rl = pd1 + 64; 217 rl = pd1 + 64;
218 218
219 permute(pk1, key, perm1, 56); 219 permute(pk1, key, perm1, 56);
@@ -247,7 +247,7 @@ dohash(char *out, char *in, char *key, int forw)
247 char *r2; /* r2[32] */ 247 char *r2; /* r2[32] */
248 248
249 er = kmalloc(48+48+32+32+32, GFP_KERNEL); 249 er = kmalloc(48+48+32+32+32, GFP_KERNEL);
250 if(er == NULL) { 250 if (er == NULL) {
251 kfree(pk1); 251 kfree(pk1);
252 kfree(ki); 252 kfree(ki);
253 return; 253 return;
@@ -327,8 +327,8 @@ smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
327 char *keyb; /* keyb[64] */ 327 char *keyb; /* keyb[64] */
328 unsigned char key2[8]; 328 unsigned char key2[8];
329 329
330 outb = kmalloc(64 * 3,GFP_KERNEL); 330 outb = kmalloc(64 * 3, GFP_KERNEL);
331 if(outb == NULL) 331 if (outb == NULL)
332 return; 332 return;
333 333
334 inb = outb + 64; 334 inb = outb + 64;
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 4b25ba92180d..90542a39be17 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -1,4 +1,4 @@
1/* 1/*
2 Unix SMB/Netbios implementation. 2 Unix SMB/Netbios implementation.
3 Version 1.9. 3 Version 1.9.
4 SMB parameters and setup 4 SMB parameters and setup
@@ -7,17 +7,17 @@
7 Modified by Jeremy Allison 1995. 7 Modified by Jeremy Allison 1995.
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003 9 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -57,7 +57,7 @@ void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
57 57
58/* 58/*
59 This implements the X/Open SMB password encryption 59 This implements the X/Open SMB password encryption
60 It takes a password, a 8 byte "crypt key" and puts 24 bytes of 60 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
61 encrypted password into p24 */ 61 encrypted password into p24 */
62/* Note that password must be uppercased and null terminated */ 62/* Note that password must be uppercased and null terminated */
63void 63void
@@ -73,9 +73,9 @@ SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
73 E_P16(p14, p21); 73 E_P16(p14, p21);
74 74
75 SMBOWFencrypt(p21, c8, p24); 75 SMBOWFencrypt(p21, c8, p24);
76 76
77 memset(p14,0,15); 77 memset(p14, 0, 15);
78 memset(p21,0,21); 78 memset(p21, 0, 21);
79} 79}
80 80
81/* Routines for Windows NT MD4 Hash functions. */ 81/* Routines for Windows NT MD4 Hash functions. */
@@ -90,14 +90,14 @@ _my_wcslen(__u16 * str)
90 90
91/* 91/*
92 * Convert a string into an NT UNICODE string. 92 * Convert a string into an NT UNICODE string.
93 * Note that regardless of processor type 93 * Note that regardless of processor type
94 * this must be in intel (little-endian) 94 * this must be in intel (little-endian)
95 * format. 95 * format.
96 */ 96 */
97 97
98static int 98static int
99_my_mbstowcs(__u16 * dst, const unsigned char *src, int len) 99_my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
100{ /* not a very good conversion routine - change/fix */ 100{ /* BB not a very good conversion routine - change/fix */
101 int i; 101 int i;
102 __u16 val; 102 __u16 val;
103 103
@@ -112,7 +112,7 @@ _my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
112 return i; 112 return i;
113} 113}
114 114
115/* 115/*
116 * Creates the MD4 Hash of the users password in NT UNICODE. 116 * Creates the MD4 Hash of the users password in NT UNICODE.
117 */ 117 */
118 118
@@ -123,7 +123,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
123 __u16 wpwd[129]; 123 __u16 wpwd[129];
124 124
125 /* Password cannot be longer than 128 characters */ 125 /* Password cannot be longer than 128 characters */
126 if(passwd) { 126 if (passwd) {
127 len = strlen((char *) passwd); 127 len = strlen((char *) passwd);
128 if (len > 128) { 128 if (len > 128) {
129 len = 128; 129 len = 128;
@@ -138,7 +138,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
138 len = _my_wcslen(wpwd) * sizeof (__u16); 138 len = _my_wcslen(wpwd) * sizeof (__u16);
139 139
140 mdfour(p16, (unsigned char *) wpwd, len); 140 mdfour(p16, (unsigned char *) wpwd, len);
141 memset(wpwd,0,129 * 2); 141 memset(wpwd, 0, 129 * 2);
142} 142}
143 143
144#if 0 /* currently unused */ 144#if 0 /* currently unused */
@@ -178,17 +178,17 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
178 const char *domain_n, unsigned char kr_buf[16], 178 const char *domain_n, unsigned char kr_buf[16],
179 const struct nls_table *nls_codepage) 179 const struct nls_table *nls_codepage)
180{ 180{
181 wchar_t * user_u; 181 wchar_t *user_u;
182 wchar_t * dom_u; 182 wchar_t *dom_u;
183 int user_l, domain_l; 183 int user_l, domain_l;
184 struct HMACMD5Context ctx; 184 struct HMACMD5Context ctx;
185 185
186 /* might as well do one alloc to hold both (user_u and dom_u) */ 186 /* might as well do one alloc to hold both (user_u and dom_u) */
187 user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL); 187 user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);
188 if(user_u == NULL) 188 if (user_u == NULL)
189 return; 189 return;
190 dom_u = user_u + 1024; 190 dom_u = user_u + 1024;
191 191
192 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); 192 /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
193 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */ 193 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
194 194
@@ -206,7 +206,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
206 206
207 kfree(user_u); 207 kfree(user_u);
208} 208}
209#endif 209#endif
210 210
211/* Does the des encryption from the NT or LM MD4 hash. */ 211/* Does the des encryption from the NT or LM MD4 hash. */
212static void 212static void
@@ -256,15 +256,15 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
256#if 0 256#if 0
257static void 257static void
258SMBOWFencrypt_ntv2(const unsigned char kr[16], 258SMBOWFencrypt_ntv2(const unsigned char kr[16],
259 const struct data_blob * srv_chal, 259 const struct data_blob *srv_chal,
260 const struct data_blob * cli_chal, unsigned char resp_buf[16]) 260 const struct data_blob *cli_chal, unsigned char resp_buf[16])
261{ 261{
262 struct HMACMD5Context ctx; 262 struct HMACMD5Context ctx;
263 263
264 hmac_md5_init_limK_to_64(kr, 16, &ctx); 264 hmac_md5_init_limK_to_64(kr, 16, &ctx);
265 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); 265 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
266 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); 266 hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
267 hmac_md5_final(resp_buf, &ctx); 267 hmac_md5_final(resp_buf, &ctx);
268} 268}
269 269
270static void 270static void
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 212c3c296409..2ef0be288820 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -4,8 +4,8 @@
4 * Copyright (c) International Business Machines Corp., 2002,2004 4 * Copyright (c) International Business Machines Corp., 2002,2004
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * See Error Codes section of the SNIA CIFS Specification 7 * See Error Codes section of the SNIA CIFS Specification
8 * for more information 8 * for more information
9 * 9 *
10 * This library is free software; you can redistribute it and/or modify 10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published 11 * it under the terms of the GNU Lesser General Public License as published
@@ -19,7 +19,7 @@
19 * 19 *
20 * You should have received a copy of the GNU Lesser General Public License 20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software 21 * along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 23 */
24 24
25#define SUCCESS 0x00 /* The request was successful. */ 25#define SUCCESS 0x00 /* The request was successful. */
@@ -110,7 +110,7 @@
110 110
111/* Below errors are used internally (do not come over the wire) for passthrough 111/* Below errors are used internally (do not come over the wire) for passthrough
112 from STATUS codes to POSIX only */ 112 from STATUS codes to POSIX only */
113#define ErrTooManyLinks 0xFFFE 113#define ErrTooManyLinks 0xFFFE
114 114
115/* Following error codes may be generated with the ERRSRV error class.*/ 115/* Following error codes may be generated with the ERRSRV error class.*/
116 116
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 5f468459a1e2..746bc9405db1 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * fs/cifs/transport.c 2 * fs/cifs/transport.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 2006. 6 * Jeremy Allison (jra@samba.org) 2006.
7 * 7 *
8 * This library is free software; you can redistribute it and/or modify 8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published 9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or 10 * by the Free Software Foundation; either version 2.1 of the License, or
@@ -17,7 +17,7 @@
17 * 17 *
18 * You should have received a copy of the GNU Lesser General Public License 18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software 19 * along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <linux/fs.h> 23#include <linux/fs.h>
@@ -32,7 +32,7 @@
32#include "cifsglob.h" 32#include "cifsglob.h"
33#include "cifsproto.h" 33#include "cifsproto.h"
34#include "cifs_debug.h" 34#include "cifs_debug.h"
35 35
36extern mempool_t *cifs_mid_poolp; 36extern mempool_t *cifs_mid_poolp;
37extern struct kmem_cache *cifs_oplock_cachep; 37extern struct kmem_cache *cifs_oplock_cachep;
38 38
@@ -49,7 +49,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
49 cERROR(1, ("Null TCP session in AllocMidQEntry")); 49 cERROR(1, ("Null TCP session in AllocMidQEntry"));
50 return NULL; 50 return NULL;
51 } 51 }
52 52
53 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, 53 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
54 GFP_KERNEL | GFP_NOFS); 54 GFP_KERNEL | GFP_NOFS);
55 if (temp == NULL) 55 if (temp == NULL)
@@ -86,7 +86,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
86 list_del(&midEntry->qhead); 86 list_del(&midEntry->qhead);
87 atomic_dec(&midCount); 87 atomic_dec(&midCount);
88 spin_unlock(&GlobalMid_Lock); 88 spin_unlock(&GlobalMid_Lock);
89 if(midEntry->largeBuf) 89 if (midEntry->largeBuf)
90 cifs_buf_release(midEntry->resp_buf); 90 cifs_buf_release(midEntry->resp_buf);
91 else 91 else
92 cifs_small_buf_release(midEntry->resp_buf); 92 cifs_small_buf_release(midEntry->resp_buf);
@@ -94,8 +94,8 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
94 now = jiffies; 94 now = jiffies;
95 /* commands taking longer than one second are indications that 95 /* commands taking longer than one second are indications that
96 something is wrong, unless it is quite a slow link or server */ 96 something is wrong, unless it is quite a slow link or server */
97 if((now - midEntry->when_alloc) > HZ) { 97 if ((now - midEntry->when_alloc) > HZ) {
98 if((cifsFYI & CIFS_TIMER) && 98 if ((cifsFYI & CIFS_TIMER) &&
99 (midEntry->command != SMB_COM_LOCKING_ANDX)) { 99 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
100 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d", 100 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
101 midEntry->command, midEntry->mid); 101 midEntry->command, midEntry->mid);
@@ -110,10 +110,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
110} 110}
111 111
112struct oplock_q_entry * 112struct oplock_q_entry *
113AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) 113AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
114{ 114{
115 struct oplock_q_entry *temp; 115 struct oplock_q_entry *temp;
116 if ((pinode== NULL) || (tcon == NULL)) { 116 if ((pinode == NULL) || (tcon == NULL)) {
117 cERROR(1, ("Null parms passed to AllocOplockQEntry")); 117 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
118 return NULL; 118 return NULL;
119 } 119 }
@@ -133,9 +133,9 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
133 133
134} 134}
135 135
136void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry) 136void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
137{ 137{
138 spin_lock(&GlobalMid_Lock); 138 spin_lock(&GlobalMid_Lock);
139 /* should we check if list empty first? */ 139 /* should we check if list empty first? */
140 list_del(&oplockEntry->qhead); 140 list_del(&oplockEntry->qhead);
141 spin_unlock(&GlobalMid_Lock); 141 spin_unlock(&GlobalMid_Lock);
@@ -152,7 +152,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
152 struct kvec iov; 152 struct kvec iov;
153 unsigned len = smb_buf_length + 4; 153 unsigned len = smb_buf_length + 4;
154 154
155 if(ssocket == NULL) 155 if (ssocket == NULL)
156 return -ENOTSOCK; /* BB eventually add reconnect code here */ 156 return -ENOTSOCK; /* BB eventually add reconnect code here */
157 iov.iov_base = smb_buffer; 157 iov.iov_base = smb_buffer;
158 iov.iov_len = len; 158 iov.iov_len = len;
@@ -164,8 +164,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
164 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 164 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
165 165
166 /* smb header is converted in header_assemble. bcc and rest of SMB word 166 /* smb header is converted in header_assemble. bcc and rest of SMB word
167 area, and byte area if necessary, is converted to littleendian in 167 area, and byte area if necessary, is converted to littleendian in
168 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 168 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
169 Flags2 is converted in SendReceive */ 169 Flags2 is converted in SendReceive */
170 170
171 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 171 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
@@ -177,9 +177,9 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
177 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 177 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
178 i++; 178 i++;
179 /* smaller timeout here than send2 since smaller size */ 179 /* smaller timeout here than send2 since smaller size */
180 /* Although it may not be required, this also is smaller 180 /* Although it may not be required, this also is smaller
181 oplock break time */ 181 oplock break time */
182 if(i > 12) { 182 if (i > 12) {
183 cERROR(1, 183 cERROR(1,
184 ("sends on sock %p stuck for 7 seconds", 184 ("sends on sock %p stuck for 7 seconds",
185 ssocket)); 185 ssocket));
@@ -189,7 +189,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
189 msleep(1 << i); 189 msleep(1 << i);
190 continue; 190 continue;
191 } 191 }
192 if (rc < 0) 192 if (rc < 0)
193 break; 193 break;
194 else 194 else
195 i = 0; /* reset i after each successful send */ 195 i = 0; /* reset i after each successful send */
@@ -199,7 +199,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
199 } 199 }
200 200
201 if (rc < 0) { 201 if (rc < 0) {
202 cERROR(1,("Error %d sending data on socket to server", rc)); 202 cERROR(1, ("Error %d sending data on socket to server", rc));
203 } else { 203 } else {
204 rc = 0; 204 rc = 0;
205 } 205 }
@@ -223,8 +223,8 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
223 unsigned int total_len; 223 unsigned int total_len;
224 int first_vec = 0; 224 int first_vec = 0;
225 unsigned int smb_buf_length = smb_buffer->smb_buf_length; 225 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
226 226
227 if(ssocket == NULL) 227 if (ssocket == NULL)
228 return -ENOTSOCK; /* BB eventually add reconnect code here */ 228 return -ENOTSOCK; /* BB eventually add reconnect code here */
229 229
230 smb_msg.msg_name = sin; 230 smb_msg.msg_name = sin;
@@ -234,8 +234,8 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
234 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ 234 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
235 235
236 /* smb header is converted in header_assemble. bcc and rest of SMB word 236 /* smb header is converted in header_assemble. bcc and rest of SMB word
237 area, and byte area if necessary, is converted to littleendian in 237 area, and byte area if necessary, is converted to littleendian in
238 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 238 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
239 Flags2 is converted in SendReceive */ 239 Flags2 is converted in SendReceive */
240 240
241 241
@@ -252,7 +252,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
252 n_vec - first_vec, total_len); 252 n_vec - first_vec, total_len);
253 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 253 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
254 i++; 254 i++;
255 if(i >= 14) { 255 if (i >= 14) {
256 cERROR(1, 256 cERROR(1,
257 ("sends on sock %p stuck for 15 seconds", 257 ("sends on sock %p stuck for 15 seconds",
258 ssocket)); 258 ssocket));
@@ -262,17 +262,17 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
262 msleep(1 << i); 262 msleep(1 << i);
263 continue; 263 continue;
264 } 264 }
265 if (rc < 0) 265 if (rc < 0)
266 break; 266 break;
267 267
268 if (rc >= total_len) { 268 if (rc >= total_len) {
269 WARN_ON(rc > total_len); 269 WARN_ON(rc > total_len);
270 break; 270 break;
271 } 271 }
272 if(rc == 0) { 272 if (rc == 0) {
273 /* should never happen, letting socket clear before 273 /* should never happen, letting socket clear before
274 retrying is our only obvious option here */ 274 retrying is our only obvious option here */
275 cERROR(1,("tcp sent no data")); 275 cERROR(1, ("tcp sent no data"));
276 msleep(500); 276 msleep(500);
277 continue; 277 continue;
278 } 278 }
@@ -295,7 +295,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
295 } 295 }
296 296
297 if (rc < 0) { 297 if (rc < 0) {
298 cERROR(1,("Error %d sending data on socket to server", rc)); 298 cERROR(1, ("Error %d sending data on socket to server", rc));
299 } else 299 } else
300 rc = 0; 300 rc = 0;
301 301
@@ -308,13 +308,13 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
308 308
309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) 309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
310{ 310{
311 if(long_op == -1) { 311 if (long_op == -1) {
312 /* oplock breaks must not be held up */ 312 /* oplock breaks must not be held up */
313 atomic_inc(&ses->server->inFlight); 313 atomic_inc(&ses->server->inFlight);
314 } else { 314 } else {
315 spin_lock(&GlobalMid_Lock); 315 spin_lock(&GlobalMid_Lock);
316 while(1) { 316 while (1) {
317 if(atomic_read(&ses->server->inFlight) >= 317 if (atomic_read(&ses->server->inFlight) >=
318 cifs_max_pending){ 318 cifs_max_pending){
319 spin_unlock(&GlobalMid_Lock); 319 spin_unlock(&GlobalMid_Lock);
320#ifdef CONFIG_CIFS_STATS2 320#ifdef CONFIG_CIFS_STATS2
@@ -328,14 +328,14 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
328#endif 328#endif
329 spin_lock(&GlobalMid_Lock); 329 spin_lock(&GlobalMid_Lock);
330 } else { 330 } else {
331 if(ses->server->tcpStatus == CifsExiting) { 331 if (ses->server->tcpStatus == CifsExiting) {
332 spin_unlock(&GlobalMid_Lock); 332 spin_unlock(&GlobalMid_Lock);
333 return -ENOENT; 333 return -ENOENT;
334 } 334 }
335 335
336 /* can not count locking commands against total since 336 /* can not count locking commands against total
337 they are allowed to block on server */ 337 as they are allowed to block on server */
338 338
339 /* update # of requests on the wire to server */ 339 /* update # of requests on the wire to server */
340 if (long_op < 3) 340 if (long_op < 3)
341 atomic_inc(&ses->server->inFlight); 341 atomic_inc(&ses->server->inFlight);
@@ -353,11 +353,11 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
353 if (ses->server->tcpStatus == CifsExiting) { 353 if (ses->server->tcpStatus == CifsExiting) {
354 return -ENOENT; 354 return -ENOENT;
355 } else if (ses->server->tcpStatus == CifsNeedReconnect) { 355 } else if (ses->server->tcpStatus == CifsNeedReconnect) {
356 cFYI(1,("tcp session dead - return to caller to retry")); 356 cFYI(1, ("tcp session dead - return to caller to retry"));
357 return -EAGAIN; 357 return -EAGAIN;
358 } else if (ses->status != CifsGood) { 358 } else if (ses->status != CifsGood) {
359 /* check if SMB session is bad because we are setting it up */ 359 /* check if SMB session is bad because we are setting it up */
360 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 360 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
361 (in_buf->Command != SMB_COM_NEGOTIATE)) { 361 (in_buf->Command != SMB_COM_NEGOTIATE)) {
362 return -EAGAIN; 362 return -EAGAIN;
363 } /* else ok - we are setting up session */ 363 } /* else ok - we are setting up session */
@@ -369,7 +369,7 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
369 return 0; 369 return 0;
370} 370}
371 371
372static int wait_for_response(struct cifsSesInfo *ses, 372static int wait_for_response(struct cifsSesInfo *ses,
373 struct mid_q_entry *midQ, 373 struct mid_q_entry *midQ,
374 unsigned long timeout, 374 unsigned long timeout,
375 unsigned long time_to_wait) 375 unsigned long time_to_wait)
@@ -379,8 +379,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
379 for (;;) { 379 for (;;) {
380 curr_timeout = timeout + jiffies; 380 curr_timeout = timeout + jiffies;
381 wait_event(ses->server->response_q, 381 wait_event(ses->server->response_q,
382 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 382 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
383 time_after(jiffies, curr_timeout) || 383 time_after(jiffies, curr_timeout) ||
384 ((ses->server->tcpStatus != CifsGood) && 384 ((ses->server->tcpStatus != CifsGood) &&
385 (ses->server->tcpStatus != CifsNew))); 385 (ses->server->tcpStatus != CifsNew)));
386 386
@@ -398,16 +398,16 @@ static int wait_for_response(struct cifsSesInfo *ses,
398 spin_unlock(&GlobalMid_Lock); 398 spin_unlock(&GlobalMid_Lock);
399 399
400 /* Calculate time_to_wait past last receive time. 400 /* Calculate time_to_wait past last receive time.
401 Although we prefer not to time out if the 401 Although we prefer not to time out if the
402 server is still responding - we will time 402 server is still responding - we will time
403 out if the server takes more than 15 (or 45 403 out if the server takes more than 15 (or 45
404 or 180) seconds to respond to this request 404 or 180) seconds to respond to this request
405 and has not responded to any request from 405 and has not responded to any request from
406 other threads on the client within 10 seconds */ 406 other threads on the client within 10 seconds */
407 lrt += time_to_wait; 407 lrt += time_to_wait;
408 if (time_after(jiffies, lrt)) { 408 if (time_after(jiffies, lrt)) {
409 /* No replies for time_to_wait. */ 409 /* No replies for time_to_wait. */
410 cERROR(1,("server not responding")); 410 cERROR(1, ("server not responding"));
411 return -1; 411 return -1;
412 } 412 }
413 } else { 413 } else {
@@ -417,8 +417,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
417} 417}
418 418
419int 419int
420SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 420SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
421 struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 421 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
422 const int long_op) 422 const int long_op)
423{ 423{
424 int rc = 0; 424 int rc = 0;
@@ -426,21 +426,21 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
426 unsigned long timeout; 426 unsigned long timeout;
427 struct mid_q_entry *midQ; 427 struct mid_q_entry *midQ;
428 struct smb_hdr *in_buf = iov[0].iov_base; 428 struct smb_hdr *in_buf = iov[0].iov_base;
429 429
430 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 430 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
431 431
432 if ((ses == NULL) || (ses->server == NULL)) { 432 if ((ses == NULL) || (ses->server == NULL)) {
433 cifs_small_buf_release(in_buf); 433 cifs_small_buf_release(in_buf);
434 cERROR(1,("Null session")); 434 cERROR(1, ("Null session"));
435 return -EIO; 435 return -EIO;
436 } 436 }
437 437
438 if(ses->server->tcpStatus == CifsExiting) { 438 if (ses->server->tcpStatus == CifsExiting) {
439 cifs_small_buf_release(in_buf); 439 cifs_small_buf_release(in_buf);
440 return -ENOENT; 440 return -ENOENT;
441 } 441 }
442 442
443 /* Ensure that we do not send more than 50 overlapping requests 443 /* Ensure that we do not send more than 50 overlapping requests
444 to the same server. We may make this configurable later or 444 to the same server. We may make this configurable later or
445 use ses->maxReq */ 445 use ses->maxReq */
446 446
@@ -450,23 +450,23 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
450 return rc; 450 return rc;
451 } 451 }
452 452
453 /* make sure that we sign in the same order that we send on this socket 453 /* make sure that we sign in the same order that we send on this socket
454 and avoid races inside tcp sendmsg code that could cause corruption 454 and avoid races inside tcp sendmsg code that could cause corruption
455 of smb data */ 455 of smb data */
456 456
457 down(&ses->server->tcpSem); 457 down(&ses->server->tcpSem);
458 458
459 rc = allocate_mid(ses, in_buf, &midQ); 459 rc = allocate_mid(ses, in_buf, &midQ);
460 if (rc) { 460 if (rc) {
461 up(&ses->server->tcpSem); 461 up(&ses->server->tcpSem);
462 cifs_small_buf_release(in_buf); 462 cifs_small_buf_release(in_buf);
463 /* Update # of requests on wire to server */ 463 /* Update # of requests on wire to server */
464 atomic_dec(&ses->server->inFlight); 464 atomic_dec(&ses->server->inFlight);
465 wake_up(&ses->server->request_q); 465 wake_up(&ses->server->request_q);
466 return rc; 466 return rc;
467 } 467 }
468 468
469 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); 469 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
470 470
471 midQ->midState = MID_REQUEST_SUBMITTED; 471 midQ->midState = MID_REQUEST_SUBMITTED;
472#ifdef CONFIG_CIFS_STATS2 472#ifdef CONFIG_CIFS_STATS2
@@ -482,7 +482,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
482 up(&ses->server->tcpSem); 482 up(&ses->server->tcpSem);
483 cifs_small_buf_release(in_buf); 483 cifs_small_buf_release(in_buf);
484 484
485 if(rc < 0) 485 if (rc < 0)
486 goto out; 486 goto out;
487 487
488 if (long_op == -1) 488 if (long_op == -1)
@@ -490,18 +490,18 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
490 else if (long_op == 2) /* writes past end of file can take loong time */ 490 else if (long_op == 2) /* writes past end of file can take loong time */
491 timeout = 180 * HZ; 491 timeout = 180 * HZ;
492 else if (long_op == 1) 492 else if (long_op == 1)
493 timeout = 45 * HZ; /* should be greater than 493 timeout = 45 * HZ; /* should be greater than
494 servers oplock break timeout (about 43 seconds) */ 494 servers oplock break timeout (about 43 seconds) */
495 else 495 else
496 timeout = 15 * HZ; 496 timeout = 15 * HZ;
497 497
498 /* wait for 15 seconds or until woken up due to response arriving or 498 /* wait for 15 seconds or until woken up due to response arriving or
499 due to last connection to this server being unmounted */ 499 due to last connection to this server being unmounted */
500 if (signal_pending(current)) { 500 if (signal_pending(current)) {
501 /* if signal pending do not hold up user for full smb timeout 501 /* if signal pending do not hold up user for full smb timeout
502 but we still give response a chance to complete */ 502 but we still give response a chance to complete */
503 timeout = 2 * HZ; 503 timeout = 2 * HZ;
504 } 504 }
505 505
506 /* No user interrupts in wait - wreaks havoc with performance */ 506 /* No user interrupts in wait - wreaks havoc with performance */
507 wait_for_response(ses, midQ, timeout, 10 * HZ); 507 wait_for_response(ses, midQ, timeout, 10 * HZ);
@@ -511,10 +511,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
511 spin_unlock(&GlobalMid_Lock); 511 spin_unlock(&GlobalMid_Lock);
512 receive_len = midQ->resp_buf->smb_buf_length; 512 receive_len = midQ->resp_buf->smb_buf_length;
513 } else { 513 } else {
514 cERROR(1,("No response to cmd %d mid %d", 514 cERROR(1, ("No response to cmd %d mid %d",
515 midQ->command, midQ->mid)); 515 midQ->command, midQ->mid));
516 if(midQ->midState == MID_REQUEST_SUBMITTED) { 516 if (midQ->midState == MID_REQUEST_SUBMITTED) {
517 if(ses->server->tcpStatus == CifsExiting) 517 if (ses->server->tcpStatus == CifsExiting)
518 rc = -EHOSTDOWN; 518 rc = -EHOSTDOWN;
519 else { 519 else {
520 ses->server->tcpStatus = CifsNeedReconnect; 520 ses->server->tcpStatus = CifsNeedReconnect;
@@ -523,9 +523,9 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
523 } 523 }
524 524
525 if (rc != -EHOSTDOWN) { 525 if (rc != -EHOSTDOWN) {
526 if(midQ->midState == MID_RETRY_NEEDED) { 526 if (midQ->midState == MID_RETRY_NEEDED) {
527 rc = -EAGAIN; 527 rc = -EAGAIN;
528 cFYI(1,("marking request for retry")); 528 cFYI(1, ("marking request for retry"));
529 } else { 529 } else {
530 rc = -EIO; 530 rc = -EIO;
531 } 531 }
@@ -533,21 +533,21 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
533 spin_unlock(&GlobalMid_Lock); 533 spin_unlock(&GlobalMid_Lock);
534 DeleteMidQEntry(midQ); 534 DeleteMidQEntry(midQ);
535 /* Update # of requests on wire to server */ 535 /* Update # of requests on wire to server */
536 atomic_dec(&ses->server->inFlight); 536 atomic_dec(&ses->server->inFlight);
537 wake_up(&ses->server->request_q); 537 wake_up(&ses->server->request_q);
538 return rc; 538 return rc;
539 } 539 }
540 540
541 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 541 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
542 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 542 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
543 receive_len, xid)); 543 receive_len, xid));
544 rc = -EIO; 544 rc = -EIO;
545 } else { /* rcvd frame is ok */ 545 } else { /* rcvd frame is ok */
546 if (midQ->resp_buf && 546 if (midQ->resp_buf &&
547 (midQ->midState == MID_RESPONSE_RECEIVED)) { 547 (midQ->midState == MID_RESPONSE_RECEIVED)) {
548 548
549 iov[0].iov_base = (char *)midQ->resp_buf; 549 iov[0].iov_base = (char *)midQ->resp_buf;
550 if(midQ->largeBuf) 550 if (midQ->largeBuf)
551 *pRespBufType = CIFS_LARGE_BUFFER; 551 *pRespBufType = CIFS_LARGE_BUFFER;
552 else 552 else
553 *pRespBufType = CIFS_SMALL_BUFFER; 553 *pRespBufType = CIFS_SMALL_BUFFER;
@@ -555,14 +555,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
555 555
556 dump_smb(midQ->resp_buf, 80); 556 dump_smb(midQ->resp_buf, 80);
557 /* convert the length into a more usable form */ 557 /* convert the length into a more usable form */
558 if((receive_len > 24) && 558 if ((receive_len > 24) &&
559 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 559 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
560 SECMODE_SIGN_ENABLED))) { 560 SECMODE_SIGN_ENABLED))) {
561 rc = cifs_verify_signature(midQ->resp_buf, 561 rc = cifs_verify_signature(midQ->resp_buf,
562 ses->server->mac_signing_key, 562 &ses->server->mac_signing_key,
563 midQ->sequence_number+1); 563 midQ->sequence_number+1);
564 if(rc) { 564 if (rc) {
565 cERROR(1,("Unexpected SMB signature")); 565 cERROR(1, ("Unexpected SMB signature"));
566 /* BB FIXME add code to kill session */ 566 /* BB FIXME add code to kill session */
567 } 567 }
568 } 568 }
@@ -576,19 +576,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
576 sizeof (struct smb_hdr) - 576 sizeof (struct smb_hdr) -
577 4 /* do not count RFC1001 header */ + 577 4 /* do not count RFC1001 header */ +
578 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 578 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
579 BCC(midQ->resp_buf) = 579 BCC(midQ->resp_buf) =
580 le16_to_cpu(BCC_LE(midQ->resp_buf)); 580 le16_to_cpu(BCC_LE(midQ->resp_buf));
581 midQ->resp_buf = NULL; /* mark it so will not be freed 581 midQ->resp_buf = NULL; /* mark it so will not be freed
582 by DeleteMidQEntry */ 582 by DeleteMidQEntry */
583 } else { 583 } else {
584 rc = -EIO; 584 rc = -EIO;
585 cFYI(1,("Bad MID state?")); 585 cFYI(1, ("Bad MID state?"));
586 } 586 }
587 } 587 }
588 588
589out: 589out:
590 DeleteMidQEntry(midQ); 590 DeleteMidQEntry(midQ);
591 atomic_dec(&ses->server->inFlight); 591 atomic_dec(&ses->server->inFlight);
592 wake_up(&ses->server->request_q); 592 wake_up(&ses->server->request_q);
593 593
594 return rc; 594 return rc;
@@ -605,18 +605,18 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
605 struct mid_q_entry *midQ; 605 struct mid_q_entry *midQ;
606 606
607 if (ses == NULL) { 607 if (ses == NULL) {
608 cERROR(1,("Null smb session")); 608 cERROR(1, ("Null smb session"));
609 return -EIO; 609 return -EIO;
610 } 610 }
611 if(ses->server == NULL) { 611 if (ses->server == NULL) {
612 cERROR(1,("Null tcp session")); 612 cERROR(1, ("Null tcp session"));
613 return -EIO; 613 return -EIO;
614 } 614 }
615 615
616 if(ses->server->tcpStatus == CifsExiting) 616 if (ses->server->tcpStatus == CifsExiting)
617 return -ENOENT; 617 return -ENOENT;
618 618
619 /* Ensure that we do not send more than 50 overlapping requests 619 /* Ensure that we do not send more than 50 overlapping requests
620 to the same server. We may make this configurable later or 620 to the same server. We may make this configurable later or
621 use ses->maxReq */ 621 use ses->maxReq */
622 622
@@ -624,17 +624,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
624 if (rc) 624 if (rc)
625 return rc; 625 return rc;
626 626
627 /* make sure that we sign in the same order that we send on this socket 627 /* make sure that we sign in the same order that we send on this socket
628 and avoid races inside tcp sendmsg code that could cause corruption 628 and avoid races inside tcp sendmsg code that could cause corruption
629 of smb data */ 629 of smb data */
630 630
631 down(&ses->server->tcpSem); 631 down(&ses->server->tcpSem);
632 632
633 rc = allocate_mid(ses, in_buf, &midQ); 633 rc = allocate_mid(ses, in_buf, &midQ);
634 if (rc) { 634 if (rc) {
635 up(&ses->server->tcpSem); 635 up(&ses->server->tcpSem);
636 /* Update # of requests on wire to server */ 636 /* Update # of requests on wire to server */
637 atomic_dec(&ses->server->inFlight); 637 atomic_dec(&ses->server->inFlight);
638 wake_up(&ses->server->request_q); 638 wake_up(&ses->server->request_q);
639 return rc; 639 return rc;
640 } 640 }
@@ -645,7 +645,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
645 DeleteMidQEntry(midQ); 645 DeleteMidQEntry(midQ);
646 up(&ses->server->tcpSem); 646 up(&ses->server->tcpSem);
647 /* Update # of requests on wire to server */ 647 /* Update # of requests on wire to server */
648 atomic_dec(&ses->server->inFlight); 648 atomic_dec(&ses->server->inFlight);
649 wake_up(&ses->server->request_q); 649 wake_up(&ses->server->request_q);
650 return -EIO; 650 return -EIO;
651 } 651 }
@@ -664,7 +664,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
664#endif 664#endif
665 up(&ses->server->tcpSem); 665 up(&ses->server->tcpSem);
666 666
667 if(rc < 0) 667 if (rc < 0)
668 goto out; 668 goto out;
669 669
670 if (long_op == -1) 670 if (long_op == -1)
@@ -672,17 +672,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
672 else if (long_op == 2) /* writes past end of file can take loong time */ 672 else if (long_op == 2) /* writes past end of file can take loong time */
673 timeout = 180 * HZ; 673 timeout = 180 * HZ;
674 else if (long_op == 1) 674 else if (long_op == 1)
675 timeout = 45 * HZ; /* should be greater than 675 timeout = 45 * HZ; /* should be greater than
676 servers oplock break timeout (about 43 seconds) */ 676 servers oplock break timeout (about 43 seconds) */
677 else 677 else
678 timeout = 15 * HZ; 678 timeout = 15 * HZ;
679 /* wait for 15 seconds or until woken up due to response arriving or 679 /* wait for 15 seconds or until woken up due to response arriving or
680 due to last connection to this server being unmounted */ 680 due to last connection to this server being unmounted */
681 if (signal_pending(current)) { 681 if (signal_pending(current)) {
682 /* if signal pending do not hold up user for full smb timeout 682 /* if signal pending do not hold up user for full smb timeout
683 but we still give response a chance to complete */ 683 but we still give response a chance to complete */
684 timeout = 2 * HZ; 684 timeout = 2 * HZ;
685 } 685 }
686 686
687 /* No user interrupts in wait - wreaks havoc with performance */ 687 /* No user interrupts in wait - wreaks havoc with performance */
688 wait_for_response(ses, midQ, timeout, 10 * HZ); 688 wait_for_response(ses, midQ, timeout, 10 * HZ);
@@ -692,10 +692,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
692 spin_unlock(&GlobalMid_Lock); 692 spin_unlock(&GlobalMid_Lock);
693 receive_len = midQ->resp_buf->smb_buf_length; 693 receive_len = midQ->resp_buf->smb_buf_length;
694 } else { 694 } else {
695 cERROR(1,("No response for cmd %d mid %d", 695 cERROR(1, ("No response for cmd %d mid %d",
696 midQ->command, midQ->mid)); 696 midQ->command, midQ->mid));
697 if(midQ->midState == MID_REQUEST_SUBMITTED) { 697 if (midQ->midState == MID_REQUEST_SUBMITTED) {
698 if(ses->server->tcpStatus == CifsExiting) 698 if (ses->server->tcpStatus == CifsExiting)
699 rc = -EHOSTDOWN; 699 rc = -EHOSTDOWN;
700 else { 700 else {
701 ses->server->tcpStatus = CifsNeedReconnect; 701 ses->server->tcpStatus = CifsNeedReconnect;
@@ -704,9 +704,9 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
704 } 704 }
705 705
706 if (rc != -EHOSTDOWN) { 706 if (rc != -EHOSTDOWN) {
707 if(midQ->midState == MID_RETRY_NEEDED) { 707 if (midQ->midState == MID_RETRY_NEEDED) {
708 rc = -EAGAIN; 708 rc = -EAGAIN;
709 cFYI(1,("marking request for retry")); 709 cFYI(1, ("marking request for retry"));
710 } else { 710 } else {
711 rc = -EIO; 711 rc = -EIO;
712 } 712 }
@@ -714,11 +714,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
714 spin_unlock(&GlobalMid_Lock); 714 spin_unlock(&GlobalMid_Lock);
715 DeleteMidQEntry(midQ); 715 DeleteMidQEntry(midQ);
716 /* Update # of requests on wire to server */ 716 /* Update # of requests on wire to server */
717 atomic_dec(&ses->server->inFlight); 717 atomic_dec(&ses->server->inFlight);
718 wake_up(&ses->server->request_q); 718 wake_up(&ses->server->request_q);
719 return rc; 719 return rc;
720 } 720 }
721 721
722 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 722 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
723 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 723 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
724 receive_len, xid)); 724 receive_len, xid));
@@ -734,14 +734,14 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
734 734
735 dump_smb(out_buf, 92); 735 dump_smb(out_buf, 92);
736 /* convert the length into a more usable form */ 736 /* convert the length into a more usable form */
737 if((receive_len > 24) && 737 if ((receive_len > 24) &&
738 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 738 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
739 SECMODE_SIGN_ENABLED))) { 739 SECMODE_SIGN_ENABLED))) {
740 rc = cifs_verify_signature(out_buf, 740 rc = cifs_verify_signature(out_buf,
741 ses->server->mac_signing_key, 741 &ses->server->mac_signing_key,
742 midQ->sequence_number+1); 742 midQ->sequence_number+1);
743 if(rc) { 743 if (rc) {
744 cERROR(1,("Unexpected SMB signature")); 744 cERROR(1, ("Unexpected SMB signature"));
745 /* BB FIXME add code to kill session */ 745 /* BB FIXME add code to kill session */
746 } 746 }
747 } 747 }
@@ -759,13 +759,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
759 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 759 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
760 } else { 760 } else {
761 rc = -EIO; 761 rc = -EIO;
762 cERROR(1,("Bad MID state?")); 762 cERROR(1, ("Bad MID state?"));
763 } 763 }
764 } 764 }
765 765
766out: 766out:
767 DeleteMidQEntry(midQ); 767 DeleteMidQEntry(midQ);
768 atomic_dec(&ses->server->inFlight); 768 atomic_dec(&ses->server->inFlight);
769 wake_up(&ses->server->request_q); 769 wake_up(&ses->server->request_q);
770 770
771 return rc; 771 return rc;
@@ -783,7 +783,7 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
783 783
784 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); 784 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
785 in_buf->Mid = mid; 785 in_buf->Mid = mid;
786 down(&ses->server->tcpSem); 786 down(&ses->server->tcpSem);
787 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 787 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
788 if (rc) { 788 if (rc) {
789 up(&ses->server->tcpSem); 789 up(&ses->server->tcpSem);
@@ -832,20 +832,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
832 struct cifsSesInfo *ses; 832 struct cifsSesInfo *ses;
833 833
834 if (tcon == NULL || tcon->ses == NULL) { 834 if (tcon == NULL || tcon->ses == NULL) {
835 cERROR(1,("Null smb session")); 835 cERROR(1, ("Null smb session"));
836 return -EIO; 836 return -EIO;
837 } 837 }
838 ses = tcon->ses; 838 ses = tcon->ses;
839 839
840 if(ses->server == NULL) { 840 if (ses->server == NULL) {
841 cERROR(1,("Null tcp session")); 841 cERROR(1, ("Null tcp session"));
842 return -EIO; 842 return -EIO;
843 } 843 }
844 844
845 if(ses->server->tcpStatus == CifsExiting) 845 if (ses->server->tcpStatus == CifsExiting)
846 return -ENOENT; 846 return -ENOENT;
847 847
848 /* Ensure that we do not send more than 50 overlapping requests 848 /* Ensure that we do not send more than 50 overlapping requests
849 to the same server. We may make this configurable later or 849 to the same server. We may make this configurable later or
850 use ses->maxReq */ 850 use ses->maxReq */
851 851
@@ -853,11 +853,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
853 if (rc) 853 if (rc)
854 return rc; 854 return rc;
855 855
856 /* make sure that we sign in the same order that we send on this socket 856 /* make sure that we sign in the same order that we send on this socket
857 and avoid races inside tcp sendmsg code that could cause corruption 857 and avoid races inside tcp sendmsg code that could cause corruption
858 of smb data */ 858 of smb data */
859 859
860 down(&ses->server->tcpSem); 860 down(&ses->server->tcpSem);
861 861
862 rc = allocate_mid(ses, in_buf, &midQ); 862 rc = allocate_mid(ses, in_buf, &midQ);
863 if (rc) { 863 if (rc) {
@@ -887,14 +887,14 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
887#endif 887#endif
888 up(&ses->server->tcpSem); 888 up(&ses->server->tcpSem);
889 889
890 if(rc < 0) { 890 if (rc < 0) {
891 DeleteMidQEntry(midQ); 891 DeleteMidQEntry(midQ);
892 return rc; 892 return rc;
893 } 893 }
894 894
895 /* Wait for a reply - allow signals to interrupt. */ 895 /* Wait for a reply - allow signals to interrupt. */
896 rc = wait_event_interruptible(ses->server->response_q, 896 rc = wait_event_interruptible(ses->server->response_q,
897 (!(midQ->midState == MID_REQUEST_SUBMITTED)) || 897 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
898 ((ses->server->tcpStatus != CifsGood) && 898 ((ses->server->tcpStatus != CifsGood) &&
899 (ses->server->tcpStatus != CifsNew))); 899 (ses->server->tcpStatus != CifsNew)));
900 900
@@ -928,7 +928,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
928 } 928 }
929 929
930 /* Wait 5 seconds for the response. */ 930 /* Wait 5 seconds for the response. */
931 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) { 931 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
932 /* We got the response - restart system call. */ 932 /* We got the response - restart system call. */
933 rstart = 1; 933 rstart = 1;
934 } 934 }
@@ -939,10 +939,10 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
939 spin_unlock(&GlobalMid_Lock); 939 spin_unlock(&GlobalMid_Lock);
940 receive_len = midQ->resp_buf->smb_buf_length; 940 receive_len = midQ->resp_buf->smb_buf_length;
941 } else { 941 } else {
942 cERROR(1,("No response for cmd %d mid %d", 942 cERROR(1, ("No response for cmd %d mid %d",
943 midQ->command, midQ->mid)); 943 midQ->command, midQ->mid));
944 if(midQ->midState == MID_REQUEST_SUBMITTED) { 944 if (midQ->midState == MID_REQUEST_SUBMITTED) {
945 if(ses->server->tcpStatus == CifsExiting) 945 if (ses->server->tcpStatus == CifsExiting)
946 rc = -EHOSTDOWN; 946 rc = -EHOSTDOWN;
947 else { 947 else {
948 ses->server->tcpStatus = CifsNeedReconnect; 948 ses->server->tcpStatus = CifsNeedReconnect;
@@ -951,9 +951,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
951 } 951 }
952 952
953 if (rc != -EHOSTDOWN) { 953 if (rc != -EHOSTDOWN) {
954 if(midQ->midState == MID_RETRY_NEEDED) { 954 if (midQ->midState == MID_RETRY_NEEDED) {
955 rc = -EAGAIN; 955 rc = -EAGAIN;
956 cFYI(1,("marking request for retry")); 956 cFYI(1, ("marking request for retry"));
957 } else { 957 } else {
958 rc = -EIO; 958 rc = -EIO;
959 } 959 }
@@ -962,7 +962,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
962 DeleteMidQEntry(midQ); 962 DeleteMidQEntry(midQ);
963 return rc; 963 return rc;
964 } 964 }
965 965
966 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { 966 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
967 cERROR(1, ("Frame too large received. Length: %d Xid: %d", 967 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
968 receive_len, xid)); 968 receive_len, xid));
@@ -978,14 +978,14 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
978 978
979 dump_smb(out_buf, 92); 979 dump_smb(out_buf, 92);
980 /* convert the length into a more usable form */ 980 /* convert the length into a more usable form */
981 if((receive_len > 24) && 981 if ((receive_len > 24) &&
982 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 982 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
983 SECMODE_SIGN_ENABLED))) { 983 SECMODE_SIGN_ENABLED))) {
984 rc = cifs_verify_signature(out_buf, 984 rc = cifs_verify_signature(out_buf,
985 ses->server->mac_signing_key, 985 &ses->server->mac_signing_key,
986 midQ->sequence_number+1); 986 midQ->sequence_number+1);
987 if(rc) { 987 if (rc) {
988 cERROR(1,("Unexpected SMB signature")); 988 cERROR(1, ("Unexpected SMB signature"));
989 /* BB FIXME add code to kill session */ 989 /* BB FIXME add code to kill session */
990 } 990 }
991 } 991 }
@@ -1003,7 +1003,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
1003 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 1003 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
1004 } else { 1004 } else {
1005 rc = -EIO; 1005 rc = -EIO;
1006 cERROR(1,("Bad MID state?")); 1006 cERROR(1, ("Bad MID state?"));
1007 } 1007 }
1008 } 1008 }
1009 DeleteMidQEntry(midQ); 1009 DeleteMidQEntry(midQ);
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 18fcec190f8b..f61e433d281c 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/xattr.c 2 * fs/cifs/xattr.c
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2003 4 * Copyright (c) International Business Machines Corp., 2003, 2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -37,50 +37,52 @@
37#define XATTR_TRUSTED_PREFIX_LEN 8 37#define XATTR_TRUSTED_PREFIX_LEN 8
38#define XATTR_SECURITY_PREFIX_LEN 9 38#define XATTR_SECURITY_PREFIX_LEN 9
39/* BB need to add server (Samba e.g) support for security and trusted prefix */ 39/* BB need to add server (Samba e.g) support for security and trusted prefix */
40
41 40
42 41
43int cifs_removexattr(struct dentry * direntry, const char * ea_name) 42
43int cifs_removexattr(struct dentry *direntry, const char *ea_name)
44{ 44{
45 int rc = -EOPNOTSUPP; 45 int rc = -EOPNOTSUPP;
46#ifdef CONFIG_CIFS_XATTR 46#ifdef CONFIG_CIFS_XATTR
47 int xid; 47 int xid;
48 struct cifs_sb_info *cifs_sb; 48 struct cifs_sb_info *cifs_sb;
49 struct cifsTconInfo *pTcon; 49 struct cifsTconInfo *pTcon;
50 struct super_block * sb; 50 struct super_block *sb;
51 char * full_path; 51 char *full_path;
52 52
53 if(direntry == NULL) 53 if (direntry == NULL)
54 return -EIO; 54 return -EIO;
55 if(direntry->d_inode == NULL) 55 if (direntry->d_inode == NULL)
56 return -EIO; 56 return -EIO;
57 sb = direntry->d_inode->i_sb; 57 sb = direntry->d_inode->i_sb;
58 if(sb == NULL) 58 if (sb == NULL)
59 return -EIO; 59 return -EIO;
60 xid = GetXid(); 60 xid = GetXid();
61 61
62 cifs_sb = CIFS_SB(sb); 62 cifs_sb = CIFS_SB(sb);
63 pTcon = cifs_sb->tcon; 63 pTcon = cifs_sb->tcon;
64 64
65 full_path = build_path_from_dentry(direntry); 65 full_path = build_path_from_dentry(direntry);
66 if(full_path == NULL) { 66 if (full_path == NULL) {
67 FreeXid(xid); 67 FreeXid(xid);
68 return -ENOMEM; 68 return -ENOMEM;
69 } 69 }
70 if(ea_name == NULL) { 70 if (ea_name == NULL) {
71 cFYI(1,("Null xattr names not supported")); 71 cFYI(1, ("Null xattr names not supported"));
72 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) 72 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
73 && (strncmp(ea_name,CIFS_XATTR_OS2_PREFIX,4))) { 73 && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
74 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name)); 74 cFYI(1,
75 ("illegal xattr request %s (only user namespace supported)",
76 ea_name));
75 /* BB what if no namespace prefix? */ 77 /* BB what if no namespace prefix? */
76 /* Should we just pass them to server, except for 78 /* Should we just pass them to server, except for
77 system and perhaps security prefixes? */ 79 system and perhaps security prefixes? */
78 } else { 80 } else {
79 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 81 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
80 goto remove_ea_exit; 82 goto remove_ea_exit;
81 83
82 ea_name+=5; /* skip past user. prefix */ 84 ea_name += 5; /* skip past user. prefix */
83 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL, 85 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
84 (__u16)0, cifs_sb->local_nls, 86 (__u16)0, cifs_sb->local_nls,
85 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 87 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
86 } 88 }
@@ -91,23 +93,23 @@ remove_ea_exit:
91 return rc; 93 return rc;
92} 94}
93 95
94int cifs_setxattr(struct dentry * direntry, const char * ea_name, 96int cifs_setxattr(struct dentry *direntry, const char *ea_name,
95 const void * ea_value, size_t value_size, int flags) 97 const void *ea_value, size_t value_size, int flags)
96{ 98{
97 int rc = -EOPNOTSUPP; 99 int rc = -EOPNOTSUPP;
98#ifdef CONFIG_CIFS_XATTR 100#ifdef CONFIG_CIFS_XATTR
99 int xid; 101 int xid;
100 struct cifs_sb_info *cifs_sb; 102 struct cifs_sb_info *cifs_sb;
101 struct cifsTconInfo *pTcon; 103 struct cifsTconInfo *pTcon;
102 struct super_block * sb; 104 struct super_block *sb;
103 char * full_path; 105 char *full_path;
104 106
105 if(direntry == NULL) 107 if (direntry == NULL)
106 return -EIO; 108 return -EIO;
107 if(direntry->d_inode == NULL) 109 if (direntry->d_inode == NULL)
108 return -EIO; 110 return -EIO;
109 sb = direntry->d_inode->i_sb; 111 sb = direntry->d_inode->i_sb;
110 if(sb == NULL) 112 if (sb == NULL)
111 return -EIO; 113 return -EIO;
112 xid = GetXid(); 114 xid = GetXid();
113 115
@@ -115,7 +117,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
115 pTcon = cifs_sb->tcon; 117 pTcon = cifs_sb->tcon;
116 118
117 full_path = build_path_from_dentry(direntry); 119 full_path = build_path_from_dentry(direntry);
118 if(full_path == NULL) { 120 if (full_path == NULL) {
119 FreeXid(xid); 121 FreeXid(xid);
120 return -ENOMEM; 122 return -ENOMEM;
121 } 123 }
@@ -123,67 +125,69 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
123 /* return alt name if available as pseudo attr */ 125 /* return alt name if available as pseudo attr */
124 126
125 /* if proc/fs/cifs/streamstoxattr is set then 127 /* if proc/fs/cifs/streamstoxattr is set then
126 search server for EAs or streams to 128 search server for EAs or streams to
127 returns as xattrs */ 129 returns as xattrs */
128 if(value_size > MAX_EA_VALUE_SIZE) { 130 if (value_size > MAX_EA_VALUE_SIZE) {
129 cFYI(1,("size of EA value too large")); 131 cFYI(1, ("size of EA value too large"));
130 kfree(full_path); 132 kfree(full_path);
131 FreeXid(xid); 133 FreeXid(xid);
132 return -EOPNOTSUPP; 134 return -EOPNOTSUPP;
133 } 135 }
134 136
135 if(ea_name == NULL) { 137 if (ea_name == NULL) {
136 cFYI(1,("Null xattr names not supported")); 138 cFYI(1, ("Null xattr names not supported"));
137 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { 139 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
138 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 140 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
139 goto set_ea_exit; 141 goto set_ea_exit;
140 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { 142 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
141 cFYI(1,("attempt to set cifs inode metadata")); 143 cFYI(1, ("attempt to set cifs inode metadata"));
142 } 144 }
143 ea_name += 5; /* skip past user. prefix */ 145 ea_name += 5; /* skip past user. prefix */
144 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, 146 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
145 (__u16)value_size, cifs_sb->local_nls, 147 (__u16)value_size, cifs_sb->local_nls,
146 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 148 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
147 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { 149 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
148 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 150 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
149 goto set_ea_exit; 151 goto set_ea_exit;
150 152
151 ea_name += 4; /* skip past os2. prefix */ 153 ea_name += 4; /* skip past os2. prefix */
152 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, 154 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
153 (__u16)value_size, cifs_sb->local_nls, 155 (__u16)value_size, cifs_sb->local_nls,
154 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 156 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
155 } else { 157 } else {
156 int temp; 158 int temp;
157 temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, 159 temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
158 strlen(POSIX_ACL_XATTR_ACCESS)); 160 strlen(POSIX_ACL_XATTR_ACCESS));
159 if (temp == 0) { 161 if (temp == 0) {
160#ifdef CONFIG_CIFS_POSIX 162#ifdef CONFIG_CIFS_POSIX
161 if(sb->s_flags & MS_POSIXACL) 163 if (sb->s_flags & MS_POSIXACL)
162 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 164 rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
163 ea_value, (const int)value_size, 165 ea_value, (const int)value_size,
164 ACL_TYPE_ACCESS,cifs_sb->local_nls, 166 ACL_TYPE_ACCESS, cifs_sb->local_nls,
165 cifs_sb->mnt_cifs_flags & 167 cifs_sb->mnt_cifs_flags &
166 CIFS_MOUNT_MAP_SPECIAL_CHR); 168 CIFS_MOUNT_MAP_SPECIAL_CHR);
167 cFYI(1,("set POSIX ACL rc %d",rc)); 169 cFYI(1, ("set POSIX ACL rc %d", rc));
168#else 170#else
169 cFYI(1,("set POSIX ACL not supported")); 171 cFYI(1, ("set POSIX ACL not supported"));
170#endif 172#endif
171 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 173 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
174 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
172#ifdef CONFIG_CIFS_POSIX 175#ifdef CONFIG_CIFS_POSIX
173 if(sb->s_flags & MS_POSIXACL) 176 if (sb->s_flags & MS_POSIXACL)
174 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path, 177 rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
175 ea_value, (const int)value_size, 178 ea_value, (const int)value_size,
176 ACL_TYPE_DEFAULT, cifs_sb->local_nls, 179 ACL_TYPE_DEFAULT, cifs_sb->local_nls,
177 cifs_sb->mnt_cifs_flags & 180 cifs_sb->mnt_cifs_flags &
178 CIFS_MOUNT_MAP_SPECIAL_CHR); 181 CIFS_MOUNT_MAP_SPECIAL_CHR);
179 cFYI(1,("set POSIX default ACL rc %d",rc)); 182 cFYI(1, ("set POSIX default ACL rc %d", rc));
180#else 183#else
181 cFYI(1,("set default POSIX ACL not supported")); 184 cFYI(1, ("set default POSIX ACL not supported"));
182#endif 185#endif
183 } else { 186 } else {
184 cFYI(1,("illegal xattr request %s (only user namespace supported)",ea_name)); 187 cFYI(1, ("illegal xattr request %s (only user namespace"
188 " supported)", ea_name));
185 /* BB what if no namespace prefix? */ 189 /* BB what if no namespace prefix? */
186 /* Should we just pass them to server, except for 190 /* Should we just pass them to server, except for
187 system and perhaps security prefixes? */ 191 system and perhaps security prefixes? */
188 } 192 }
189 } 193 }
@@ -195,23 +199,23 @@ set_ea_exit:
195 return rc; 199 return rc;
196} 200}
197 201
198ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, 202ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
199 void * ea_value, size_t buf_size) 203 void *ea_value, size_t buf_size)
200{ 204{
201 ssize_t rc = -EOPNOTSUPP; 205 ssize_t rc = -EOPNOTSUPP;
202#ifdef CONFIG_CIFS_XATTR 206#ifdef CONFIG_CIFS_XATTR
203 int xid; 207 int xid;
204 struct cifs_sb_info *cifs_sb; 208 struct cifs_sb_info *cifs_sb;
205 struct cifsTconInfo *pTcon; 209 struct cifsTconInfo *pTcon;
206 struct super_block * sb; 210 struct super_block *sb;
207 char * full_path; 211 char *full_path;
208 212
209 if(direntry == NULL) 213 if (direntry == NULL)
210 return -EIO; 214 return -EIO;
211 if(direntry->d_inode == NULL) 215 if (direntry->d_inode == NULL)
212 return -EIO; 216 return -EIO;
213 sb = direntry->d_inode->i_sb; 217 sb = direntry->d_inode->i_sb;
214 if(sb == NULL) 218 if (sb == NULL)
215 return -EIO; 219 return -EIO;
216 220
217 xid = GetXid(); 221 xid = GetXid();
@@ -220,42 +224,42 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
220 pTcon = cifs_sb->tcon; 224 pTcon = cifs_sb->tcon;
221 225
222 full_path = build_path_from_dentry(direntry); 226 full_path = build_path_from_dentry(direntry);
223 if(full_path == NULL) { 227 if (full_path == NULL) {
224 FreeXid(xid); 228 FreeXid(xid);
225 return -ENOMEM; 229 return -ENOMEM;
226 } 230 }
227 /* return dos attributes as pseudo xattr */ 231 /* return dos attributes as pseudo xattr */
228 /* return alt name if available as pseudo attr */ 232 /* return alt name if available as pseudo attr */
229 if(ea_name == NULL) { 233 if (ea_name == NULL) {
230 cFYI(1,("Null xattr names not supported")); 234 cFYI(1, ("Null xattr names not supported"));
231 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { 235 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
232 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 236 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
233 goto get_ea_exit; 237 goto get_ea_exit;
234 238
235 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { 239 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
236 cFYI(1,("attempt to query cifs inode metadata")); 240 cFYI(1, ("attempt to query cifs inode metadata"));
237 /* revalidate/getattr then populate from inode */ 241 /* revalidate/getattr then populate from inode */
238 } /* BB add else when above is implemented */ 242 } /* BB add else when above is implemented */
239 ea_name += 5; /* skip past user. prefix */ 243 ea_name += 5; /* skip past user. prefix */
240 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 244 rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
241 buf_size, cifs_sb->local_nls, 245 buf_size, cifs_sb->local_nls,
242 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 246 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
243 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { 247 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
244 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 248 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
245 goto get_ea_exit; 249 goto get_ea_exit;
246 250
247 ea_name += 4; /* skip past os2. prefix */ 251 ea_name += 4; /* skip past os2. prefix */
248 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, 252 rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
249 buf_size, cifs_sb->local_nls, 253 buf_size, cifs_sb->local_nls,
250 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
251 } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, 255 } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
252 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { 256 strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
253#ifdef CONFIG_CIFS_POSIX 257#ifdef CONFIG_CIFS_POSIX
254 if(sb->s_flags & MS_POSIXACL) 258 if (sb->s_flags & MS_POSIXACL)
255 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 259 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
256 ea_value, buf_size, ACL_TYPE_ACCESS, 260 ea_value, buf_size, ACL_TYPE_ACCESS,
257 cifs_sb->local_nls, 261 cifs_sb->local_nls,
258 cifs_sb->mnt_cifs_flags & 262 cifs_sb->mnt_cifs_flags &
259 CIFS_MOUNT_MAP_SPECIAL_CHR); 263 CIFS_MOUNT_MAP_SPECIAL_CHR);
260/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 264/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
261 __u16 fid; 265 __u16 fid;
@@ -272,39 +276,40 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
272 CIFSSMBClose(xid, pTcon, fid); 276 CIFSSMBClose(xid, pTcon, fid);
273 } 277 }
274 } */ /* BB enable after fixing up return data */ 278 } */ /* BB enable after fixing up return data */
275 279#else
276#else 280 cFYI(1, ("query POSIX ACL not supported yet"));
277 cFYI(1,("query POSIX ACL not supported yet"));
278#endif /* CONFIG_CIFS_POSIX */ 281#endif /* CONFIG_CIFS_POSIX */
279 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT, 282 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
280 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 283 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
281#ifdef CONFIG_CIFS_POSIX 284#ifdef CONFIG_CIFS_POSIX
282 if(sb->s_flags & MS_POSIXACL) 285 if (sb->s_flags & MS_POSIXACL)
283 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, 286 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
284 ea_value, buf_size, ACL_TYPE_DEFAULT, 287 ea_value, buf_size, ACL_TYPE_DEFAULT,
285 cifs_sb->local_nls, 288 cifs_sb->local_nls,
286 cifs_sb->mnt_cifs_flags & 289 cifs_sb->mnt_cifs_flags &
287 CIFS_MOUNT_MAP_SPECIAL_CHR); 290 CIFS_MOUNT_MAP_SPECIAL_CHR);
288#else 291#else
289 cFYI(1,("query POSIX default ACL not supported yet")); 292 cFYI(1, ("query POSIX default ACL not supported yet"));
290#endif 293#endif
291 } else if(strncmp(ea_name, 294 } else if (strncmp(ea_name,
292 CIFS_XATTR_TRUSTED_PREFIX,XATTR_TRUSTED_PREFIX_LEN) == 0) { 295 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
293 cFYI(1,("Trusted xattr namespace not supported yet")); 296 cFYI(1, ("Trusted xattr namespace not supported yet"));
294 } else if(strncmp(ea_name, 297 } else if (strncmp(ea_name,
295 CIFS_XATTR_SECURITY_PREFIX,XATTR_SECURITY_PREFIX_LEN) == 0) { 298 CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
296 cFYI(1,("Security xattr namespace not supported yet")); 299 cFYI(1, ("Security xattr namespace not supported yet"));
297 } else { 300 } else {
298 cFYI(1,("illegal xattr name request %s (only user namespace supported)",ea_name)); 301 cFYI(1,
302 ("illegal xattr request %s (only user namespace supported)",
303 ea_name));
299 } 304 }
300 305
301 /* We could add an additional check for streams ie 306 /* We could add an additional check for streams ie
302 if proc/fs/cifs/streamstoxattr is set then 307 if proc/fs/cifs/streamstoxattr is set then
303 search server for EAs or streams to 308 search server for EAs or streams to
304 returns as xattrs */ 309 returns as xattrs */
305 310
306 if(rc == -EINVAL) 311 if (rc == -EINVAL)
307 rc = -EOPNOTSUPP; 312 rc = -EOPNOTSUPP;
308 313
309get_ea_exit: 314get_ea_exit:
310 kfree(full_path); 315 kfree(full_path);
@@ -313,34 +318,34 @@ get_ea_exit:
313 return rc; 318 return rc;
314} 319}
315 320
316ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) 321ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
317{ 322{
318 ssize_t rc = -EOPNOTSUPP; 323 ssize_t rc = -EOPNOTSUPP;
319#ifdef CONFIG_CIFS_XATTR 324#ifdef CONFIG_CIFS_XATTR
320 int xid; 325 int xid;
321 struct cifs_sb_info *cifs_sb; 326 struct cifs_sb_info *cifs_sb;
322 struct cifsTconInfo *pTcon; 327 struct cifsTconInfo *pTcon;
323 struct super_block * sb; 328 struct super_block *sb;
324 char * full_path; 329 char *full_path;
325 330
326 if(direntry == NULL) 331 if (direntry == NULL)
327 return -EIO; 332 return -EIO;
328 if(direntry->d_inode == NULL) 333 if (direntry->d_inode == NULL)
329 return -EIO; 334 return -EIO;
330 sb = direntry->d_inode->i_sb; 335 sb = direntry->d_inode->i_sb;
331 if(sb == NULL) 336 if (sb == NULL)
332 return -EIO; 337 return -EIO;
333 338
334 cifs_sb = CIFS_SB(sb); 339 cifs_sb = CIFS_SB(sb);
335 pTcon = cifs_sb->tcon; 340 pTcon = cifs_sb->tcon;
336 341
337 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 342 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
338 return -EOPNOTSUPP; 343 return -EOPNOTSUPP;
339 344
340 xid = GetXid(); 345 xid = GetXid();
341 346
342 full_path = build_path_from_dentry(direntry); 347 full_path = build_path_from_dentry(direntry);
343 if(full_path == NULL) { 348 if (full_path == NULL) {
344 FreeXid(xid); 349 FreeXid(xid);
345 return -ENOMEM; 350 return -ENOMEM;
346 } 351 }
@@ -348,11 +353,11 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
348 /* return alt name if available as pseudo attr */ 353 /* return alt name if available as pseudo attr */
349 354
350 /* if proc/fs/cifs/streamstoxattr is set then 355 /* if proc/fs/cifs/streamstoxattr is set then
351 search server for EAs or streams to 356 search server for EAs or streams to
352 returns as xattrs */ 357 returns as xattrs */
353 rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size, 358 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, data, buf_size,
354 cifs_sb->local_nls, 359 cifs_sb->local_nls,
355 cifs_sb->mnt_cifs_flags & 360 cifs_sb->mnt_cifs_flags &
356 CIFS_MOUNT_MAP_SPECIAL_CHR); 361 CIFS_MOUNT_MAP_SPECIAL_CHR);
357 362
358 kfree(full_path); 363 kfree(full_path);
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 1d533a2ec3a6..11be8a325e26 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -345,11 +345,6 @@ void debugfs_remove(struct dentry *dentry)
345 switch (dentry->d_inode->i_mode & S_IFMT) { 345 switch (dentry->d_inode->i_mode & S_IFMT) {
346 case S_IFDIR: 346 case S_IFDIR:
347 ret = simple_rmdir(parent->d_inode, dentry); 347 ret = simple_rmdir(parent->d_inode, dentry);
348 if (ret)
349 printk(KERN_ERR
350 "DebugFS rmdir on %s failed : "
351 "directory not empty.\n",
352 dentry->d_name.name);
353 break; 348 break;
354 case S_IFLNK: 349 case S_IFLNK:
355 kfree(dentry->d_inode->i_private); 350 kfree(dentry->d_inode->i_private);
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 196d83266e34..1a5e8e893d75 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -489,6 +489,29 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
489} 489}
490 490
491/** 491/**
492 * gfs2_setlease - acquire/release a file lease
493 * @file: the file pointer
494 * @arg: lease type
495 * @fl: file lock
496 *
497 * Returns: errno
498 */
499
500static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
501{
502 struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
503
504 /*
505 * We don't currently have a way to enforce a lease across the whole
506 * cluster; until we do, disable leases (by just returning -EINVAL),
507 * unless the administrator has requested purely local locking.
508 */
509 if (!sdp->sd_args.ar_localflocks)
510 return -EINVAL;
511 return setlease(file, arg, fl);
512}
513
514/**
492 * gfs2_lock - acquire/release a posix lock on a file 515 * gfs2_lock - acquire/release a posix lock on a file
493 * @file: the file pointer 516 * @file: the file pointer
494 * @cmd: either modify or retrieve lock state, possibly wait 517 * @cmd: either modify or retrieve lock state, possibly wait
@@ -638,6 +661,7 @@ const struct file_operations gfs2_file_fops = {
638 .flock = gfs2_flock, 661 .flock = gfs2_flock,
639 .splice_read = generic_file_splice_read, 662 .splice_read = generic_file_splice_read,
640 .splice_write = generic_file_splice_write, 663 .splice_write = generic_file_splice_write,
664 .setlease = gfs2_setlease,
641}; 665};
642 666
643const struct file_operations gfs2_dir_fops = { 667const struct file_operations gfs2_dir_fops = {
diff --git a/fs/locks.c b/fs/locks.c
index 431a8b871fce..4f2d749ac624 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -458,22 +458,20 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
458} 458}
459 459
460/* Allocate a file_lock initialised to this type of lease */ 460/* Allocate a file_lock initialised to this type of lease */
461static int lease_alloc(struct file *filp, int type, struct file_lock **flp) 461static struct file_lock *lease_alloc(struct file *filp, int type)
462{ 462{
463 struct file_lock *fl = locks_alloc_lock(); 463 struct file_lock *fl = locks_alloc_lock();
464 int error = -ENOMEM; 464 int error = -ENOMEM;
465 465
466 if (fl == NULL) 466 if (fl == NULL)
467 goto out; 467 return ERR_PTR(error);
468 468
469 error = lease_init(filp, type, fl); 469 error = lease_init(filp, type, fl);
470 if (error) { 470 if (error) {
471 locks_free_lock(fl); 471 locks_free_lock(fl);
472 fl = NULL; 472 return ERR_PTR(error);
473 } 473 }
474out: 474 return fl;
475 *flp = fl;
476 return error;
477} 475}
478 476
479/* Check if two locks overlap each other. 477/* Check if two locks overlap each other.
@@ -661,7 +659,7 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w
661 return result; 659 return result;
662} 660}
663 661
664int 662void
665posix_test_lock(struct file *filp, struct file_lock *fl) 663posix_test_lock(struct file *filp, struct file_lock *fl)
666{ 664{
667 struct file_lock *cfl; 665 struct file_lock *cfl;
@@ -673,14 +671,12 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
673 if (posix_locks_conflict(cfl, fl)) 671 if (posix_locks_conflict(cfl, fl))
674 break; 672 break;
675 } 673 }
676 if (cfl) { 674 if (cfl)
677 __locks_copy_lock(fl, cfl); 675 __locks_copy_lock(fl, cfl);
678 unlock_kernel(); 676 else
679 return 1;
680 } else
681 fl->fl_type = F_UNLCK; 677 fl->fl_type = F_UNLCK;
682 unlock_kernel(); 678 unlock_kernel();
683 return 0; 679 return;
684} 680}
685 681
686EXPORT_SYMBOL(posix_test_lock); 682EXPORT_SYMBOL(posix_test_lock);
@@ -1169,9 +1165,9 @@ static void time_out_leases(struct inode *inode)
1169 * @inode: the inode of the file to return 1165 * @inode: the inode of the file to return
1170 * @mode: the open mode (read or write) 1166 * @mode: the open mode (read or write)
1171 * 1167 *
1172 * break_lease (inlined for speed) has checked there already 1168 * break_lease (inlined for speed) has checked there already is at least
1173 * is a lease on this file. Leases are broken on a call to open() 1169 * some kind of lock (maybe a lease) on this file. Leases are broken on
1174 * or truncate(). This function can sleep unless you 1170 * a call to open() or truncate(). This function can sleep unless you
1175 * specified %O_NONBLOCK to your open(). 1171 * specified %O_NONBLOCK to your open().
1176 */ 1172 */
1177int __break_lease(struct inode *inode, unsigned int mode) 1173int __break_lease(struct inode *inode, unsigned int mode)
@@ -1179,12 +1175,10 @@ int __break_lease(struct inode *inode, unsigned int mode)
1179 int error = 0, future; 1175 int error = 0, future;
1180 struct file_lock *new_fl, *flock; 1176 struct file_lock *new_fl, *flock;
1181 struct file_lock *fl; 1177 struct file_lock *fl;
1182 int alloc_err;
1183 unsigned long break_time; 1178 unsigned long break_time;
1184 int i_have_this_lease = 0; 1179 int i_have_this_lease = 0;
1185 1180
1186 alloc_err = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK, 1181 new_fl = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK);
1187 &new_fl);
1188 1182
1189 lock_kernel(); 1183 lock_kernel();
1190 1184
@@ -1212,8 +1206,9 @@ int __break_lease(struct inode *inode, unsigned int mode)
1212 goto out; 1206 goto out;
1213 } 1207 }
1214 1208
1215 if (alloc_err && !i_have_this_lease && ((mode & O_NONBLOCK) == 0)) { 1209 if (IS_ERR(new_fl) && !i_have_this_lease
1216 error = alloc_err; 1210 && ((mode & O_NONBLOCK) == 0)) {
1211 error = PTR_ERR(new_fl);
1217 goto out; 1212 goto out;
1218 } 1213 }
1219 1214
@@ -1260,7 +1255,7 @@ restart:
1260 1255
1261out: 1256out:
1262 unlock_kernel(); 1257 unlock_kernel();
1263 if (!alloc_err) 1258 if (!IS_ERR(new_fl))
1264 locks_free_lock(new_fl); 1259 locks_free_lock(new_fl);
1265 return error; 1260 return error;
1266} 1261}
@@ -1329,7 +1324,7 @@ int fcntl_getlease(struct file *filp)
1329} 1324}
1330 1325
1331/** 1326/**
1332 * __setlease - sets a lease on an open file 1327 * setlease - sets a lease on an open file
1333 * @filp: file pointer 1328 * @filp: file pointer
1334 * @arg: type of lease to obtain 1329 * @arg: type of lease to obtain
1335 * @flp: input - file_lock to use, output - file_lock inserted 1330 * @flp: input - file_lock to use, output - file_lock inserted
@@ -1339,18 +1334,24 @@ int fcntl_getlease(struct file *filp)
1339 * 1334 *
1340 * Called with kernel lock held. 1335 * Called with kernel lock held.
1341 */ 1336 */
1342static int __setlease(struct file *filp, long arg, struct file_lock **flp) 1337int setlease(struct file *filp, long arg, struct file_lock **flp)
1343{ 1338{
1344 struct file_lock *fl, **before, **my_before = NULL, *lease; 1339 struct file_lock *fl, **before, **my_before = NULL, *lease;
1345 struct dentry *dentry = filp->f_path.dentry; 1340 struct dentry *dentry = filp->f_path.dentry;
1346 struct inode *inode = dentry->d_inode; 1341 struct inode *inode = dentry->d_inode;
1347 int error, rdlease_count = 0, wrlease_count = 0; 1342 int error, rdlease_count = 0, wrlease_count = 0;
1348 1343
1344 if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
1345 return -EACCES;
1346 if (!S_ISREG(inode->i_mode))
1347 return -EINVAL;
1348 error = security_file_lock(filp, arg);
1349 if (error)
1350 return error;
1351
1349 time_out_leases(inode); 1352 time_out_leases(inode);
1350 1353
1351 error = -EINVAL; 1354 BUG_ON(!(*flp)->fl_lmops->fl_break);
1352 if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break)
1353 goto out;
1354 1355
1355 lease = *flp; 1356 lease = *flp;
1356 1357
@@ -1418,39 +1419,49 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
1418out: 1419out:
1419 return error; 1420 return error;
1420} 1421}
1422EXPORT_SYMBOL(setlease);
1421 1423
1422 /** 1424 /**
1423 * setlease - sets a lease on an open file 1425 * vfs_setlease - sets a lease on an open file
1424 * @filp: file pointer 1426 * @filp: file pointer
1425 * @arg: type of lease to obtain 1427 * @arg: type of lease to obtain
1426 * @lease: file_lock to use 1428 * @lease: file_lock to use
1427 * 1429 *
1428 * Call this to establish a lease on the file. 1430 * Call this to establish a lease on the file.
1429 * The fl_lmops fl_break function is required by break_lease 1431 * The (*lease)->fl_lmops->fl_break operation must be set; if not,
1432 * break_lease will oops!
1433 *
1434 * This will call the filesystem's setlease file method, if
1435 * defined. Note that there is no getlease method; instead, the
1436 * filesystem setlease method should call back to setlease() to
1437 * add a lease to the inode's lease list, where fcntl_getlease() can
1438 * find it. Since fcntl_getlease() only reports whether the current
1439 * task holds a lease, a cluster filesystem need only do this for
1440 * leases held by processes on this node.
1441 *
1442 * There is also no break_lease method; filesystems that
1443 * handle their own leases shoud break leases themselves from the
1444 * filesystem's open, create, and (on truncate) setattr methods.
1445 *
1446 * Warning: the only current setlease methods exist only to disable
1447 * leases in certain cases. More vfs changes may be required to
1448 * allow a full filesystem lease implementation.
1430 */ 1449 */
1431 1450
1432int setlease(struct file *filp, long arg, struct file_lock **lease) 1451int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
1433{ 1452{
1434 struct dentry *dentry = filp->f_path.dentry;
1435 struct inode *inode = dentry->d_inode;
1436 int error; 1453 int error;
1437 1454
1438 if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
1439 return -EACCES;
1440 if (!S_ISREG(inode->i_mode))
1441 return -EINVAL;
1442 error = security_file_lock(filp, arg);
1443 if (error)
1444 return error;
1445
1446 lock_kernel(); 1455 lock_kernel();
1447 error = __setlease(filp, arg, lease); 1456 if (filp->f_op && filp->f_op->setlease)
1457 error = filp->f_op->setlease(filp, arg, lease);
1458 else
1459 error = setlease(filp, arg, lease);
1448 unlock_kernel(); 1460 unlock_kernel();
1449 1461
1450 return error; 1462 return error;
1451} 1463}
1452 1464EXPORT_SYMBOL_GPL(vfs_setlease);
1453EXPORT_SYMBOL(setlease);
1454 1465
1455/** 1466/**
1456 * fcntl_setlease - sets a lease on an open file 1467 * fcntl_setlease - sets a lease on an open file
@@ -1469,14 +1480,6 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
1469 struct inode *inode = dentry->d_inode; 1480 struct inode *inode = dentry->d_inode;
1470 int error; 1481 int error;
1471 1482
1472 if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
1473 return -EACCES;
1474 if (!S_ISREG(inode->i_mode))
1475 return -EINVAL;
1476 error = security_file_lock(filp, arg);
1477 if (error)
1478 return error;
1479
1480 locks_init_lock(&fl); 1483 locks_init_lock(&fl);
1481 error = lease_init(filp, arg, &fl); 1484 error = lease_init(filp, arg, &fl);
1482 if (error) 1485 if (error)
@@ -1484,15 +1487,15 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
1484 1487
1485 lock_kernel(); 1488 lock_kernel();
1486 1489
1487 error = __setlease(filp, arg, &flp); 1490 error = vfs_setlease(filp, arg, &flp);
1488 if (error || arg == F_UNLCK) 1491 if (error || arg == F_UNLCK)
1489 goto out_unlock; 1492 goto out_unlock;
1490 1493
1491 error = fasync_helper(fd, filp, 1, &flp->fl_fasync); 1494 error = fasync_helper(fd, filp, 1, &flp->fl_fasync);
1492 if (error < 0) { 1495 if (error < 0) {
1493 /* remove lease just inserted by __setlease */ 1496 /* remove lease just inserted by setlease */
1494 flp->fl_type = F_UNLCK | F_INPROGRESS; 1497 flp->fl_type = F_UNLCK | F_INPROGRESS;
1495 flp->fl_break_time = jiffies- 10; 1498 flp->fl_break_time = jiffies - 10;
1496 time_out_leases(inode); 1499 time_out_leases(inode);
1497 goto out_unlock; 1500 goto out_unlock;
1498 } 1501 }
@@ -1597,8 +1600,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1597/** 1600/**
1598 * vfs_test_lock - test file byte range lock 1601 * vfs_test_lock - test file byte range lock
1599 * @filp: The file to test lock for 1602 * @filp: The file to test lock for
1600 * @fl: The lock to test 1603 * @fl: The lock to test; also used to hold result
1601 * @conf: Place to return a copy of the conflicting lock, if found
1602 * 1604 *
1603 * Returns -ERRNO on failure. Indicates presence of conflicting lock by 1605 * Returns -ERRNO on failure. Indicates presence of conflicting lock by
1604 * setting conf->fl_type to something other than F_UNLCK. 1606 * setting conf->fl_type to something other than F_UNLCK.
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8689b736fdd9..c87dc713b5d7 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -53,6 +53,7 @@ static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
53static int nfs_check_flags(int flags); 53static int nfs_check_flags(int flags);
54static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 54static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
55static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 55static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
56static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
56 57
57const struct file_operations nfs_file_operations = { 58const struct file_operations nfs_file_operations = {
58 .llseek = nfs_file_llseek, 59 .llseek = nfs_file_llseek,
@@ -69,6 +70,7 @@ const struct file_operations nfs_file_operations = {
69 .flock = nfs_flock, 70 .flock = nfs_flock,
70 .splice_read = nfs_file_splice_read, 71 .splice_read = nfs_file_splice_read,
71 .check_flags = nfs_check_flags, 72 .check_flags = nfs_check_flags,
73 .setlease = nfs_setlease,
72}; 74};
73 75
74const struct inode_operations nfs_file_inode_operations = { 76const struct inode_operations nfs_file_inode_operations = {
@@ -400,7 +402,9 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
400 402
401 lock_kernel(); 403 lock_kernel();
402 /* Try local locking first */ 404 /* Try local locking first */
403 if (posix_test_lock(filp, fl)) { 405 posix_test_lock(filp, fl);
406 if (fl->fl_type != F_UNLCK) {
407 /* found a conflict */
404 goto out; 408 goto out;
405 } 409 }
406 410
@@ -558,3 +562,13 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
558 return do_unlk(filp, cmd, fl); 562 return do_unlk(filp, cmd, fl);
559 return do_setlk(filp, cmd, fl); 563 return do_setlk(filp, cmd, fl);
560} 564}
565
566static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
567{
568 /*
569 * There is no protocol support for leases, so we have no way
570 * to implement them correctly in the face of opens by other
571 * clients.
572 */
573 return -EINVAL;
574}
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e4a4c87ec8c6..6284807bd37e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -256,7 +256,7 @@ nfs4_close_delegation(struct nfs4_delegation *dp)
256 /* The following nfsd_close may not actually close the file, 256 /* The following nfsd_close may not actually close the file,
257 * but we want to remove the lease in any case. */ 257 * but we want to remove the lease in any case. */
258 if (dp->dl_flock) 258 if (dp->dl_flock)
259 setlease(filp, F_UNLCK, &dp->dl_flock); 259 vfs_setlease(filp, F_UNLCK, &dp->dl_flock);
260 nfsd_close(filp); 260 nfsd_close(filp);
261} 261}
262 262
@@ -1402,7 +1402,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
1402/* 1402/*
1403 * Set the delegation file_lock back pointer. 1403 * Set the delegation file_lock back pointer.
1404 * 1404 *
1405 * Called from __setlease() with lock_kernel() held. 1405 * Called from setlease() with lock_kernel() held.
1406 */ 1406 */
1407static 1407static
1408void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) 1408void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
@@ -1416,7 +1416,7 @@ void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
1416} 1416}
1417 1417
1418/* 1418/*
1419 * Called from __setlease() with lock_kernel() held 1419 * Called from setlease() with lock_kernel() held
1420 */ 1420 */
1421static 1421static
1422int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) 1422int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
@@ -1716,10 +1716,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
1716 fl.fl_file = stp->st_vfs_file; 1716 fl.fl_file = stp->st_vfs_file;
1717 fl.fl_pid = current->tgid; 1717 fl.fl_pid = current->tgid;
1718 1718
1719 /* setlease checks to see if delegation should be handed out. 1719 /* vfs_setlease checks to see if delegation should be handed out.
1720 * the lock_manager callbacks fl_mylease and fl_change are used 1720 * the lock_manager callbacks fl_mylease and fl_change are used
1721 */ 1721 */
1722 if ((status = setlease(stp->st_vfs_file, 1722 if ((status = vfs_setlease(stp->st_vfs_file,
1723 flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) { 1723 flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
1724 dprintk("NFSD: setlease failed [%d], no delegation\n", status); 1724 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
1725 unhash_delegation(dp); 1725 unhash_delegation(dp);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index aee966c44aac..048e6054c2fd 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -361,20 +361,20 @@ static struct dentry_operations sysfs_dentry_ops = {
361struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) 361struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
362{ 362{
363 char *dup_name = NULL; 363 char *dup_name = NULL;
364 struct sysfs_dirent *sd = NULL; 364 struct sysfs_dirent *sd;
365 365
366 if (type & SYSFS_COPY_NAME) { 366 if (type & SYSFS_COPY_NAME) {
367 name = dup_name = kstrdup(name, GFP_KERNEL); 367 name = dup_name = kstrdup(name, GFP_KERNEL);
368 if (!name) 368 if (!name)
369 goto err_out; 369 return NULL;
370 } 370 }
371 371
372 sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); 372 sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
373 if (!sd) 373 if (!sd)
374 goto err_out; 374 goto err_out1;
375 375
376 if (sysfs_alloc_ino(&sd->s_ino)) 376 if (sysfs_alloc_ino(&sd->s_ino))
377 goto err_out; 377 goto err_out2;
378 378
379 atomic_set(&sd->s_count, 1); 379 atomic_set(&sd->s_count, 1);
380 atomic_set(&sd->s_active, 0); 380 atomic_set(&sd->s_active, 0);
@@ -386,9 +386,10 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
386 386
387 return sd; 387 return sd;
388 388
389 err_out: 389 err_out2:
390 kfree(dup_name);
391 kmem_cache_free(sysfs_dir_cachep, sd); 390 kmem_cache_free(sysfs_dir_cachep, sd);
391 err_out1:
392 kfree(dup_name);
392 return NULL; 393 return NULL;
393} 394}
394 395
@@ -698,17 +699,19 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
698 699
699 /* link in */ 700 /* link in */
700 sysfs_addrm_start(&acxt, parent_sd); 701 sysfs_addrm_start(&acxt, parent_sd);
702
701 if (!sysfs_find_dirent(parent_sd, name)) { 703 if (!sysfs_find_dirent(parent_sd, name)) {
702 sysfs_add_one(&acxt, sd); 704 sysfs_add_one(&acxt, sd);
703 sysfs_link_sibling(sd); 705 sysfs_link_sibling(sd);
704 } 706 }
705 if (sysfs_addrm_finish(&acxt)) { 707
706 *p_sd = sd; 708 if (!sysfs_addrm_finish(&acxt)) {
707 return 0; 709 sysfs_put(sd);
710 return -EEXIST;
708 } 711 }
709 712
710 sysfs_put(sd); 713 *p_sd = sd;
711 return -EEXIST; 714 return 0;
712} 715}
713 716
714int sysfs_create_subdir(struct kobject *kobj, const char *name, 717int sysfs_create_subdir(struct kobject *kobj, const char *name,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index cc497994b2a8..3e1cc062a740 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -410,11 +410,12 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
410 sysfs_link_sibling(sd); 410 sysfs_link_sibling(sd);
411 } 411 }
412 412
413 if (sysfs_addrm_finish(&acxt)) 413 if (!sysfs_addrm_finish(&acxt)) {
414 return 0; 414 sysfs_put(sd);
415 return -EEXIST;
416 }
415 417
416 sysfs_put(sd); 418 return 0;
417 return -EEXIST;
418} 419}
419 420
420 421
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 3756e152285a..10d1b52899f1 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -133,7 +133,7 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
133 */ 133 */
134static struct lock_class_key sysfs_inode_imutex_key; 134static struct lock_class_key sysfs_inode_imutex_key;
135 135
136void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 136static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
137{ 137{
138 inode->i_blocks = 0; 138 inode->i_blocks = 0;
139 inode->i_mapping->a_ops = &sysfs_aops; 139 inode->i_mapping->a_ops = &sysfs_aops;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 402cc356203c..60714d075c2f 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -43,19 +43,19 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
43 sb->s_time_gran = 1; 43 sb->s_time_gran = 1;
44 sysfs_sb = sb; 44 sysfs_sb = sb;
45 45
46 inode = new_inode(sysfs_sb); 46 /* get root inode, initialize and unlock it */
47 inode = sysfs_get_inode(&sysfs_root);
47 if (!inode) { 48 if (!inode) {
48 pr_debug("sysfs: could not get root inode\n"); 49 pr_debug("sysfs: could not get root inode\n");
49 return -ENOMEM; 50 return -ENOMEM;
50 } 51 }
51 52
52 sysfs_init_inode(&sysfs_root, inode);
53
54 inode->i_op = &sysfs_dir_inode_operations; 53 inode->i_op = &sysfs_dir_inode_operations;
55 inode->i_fop = &sysfs_dir_operations; 54 inode->i_fop = &sysfs_dir_operations;
56 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 55 inc_nlink(inode); /* directory, account for "." */
57 inc_nlink(inode); 56 unlock_new_inode(inode);
58 57
58 /* instantiate and link root dentry */
59 root = d_alloc_root(inode); 59 root = d_alloc_root(inode);
60 if (!root) { 60 if (!root) {
61 pr_debug("%s: could not get root dentry!\n",__FUNCTION__); 61 pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 2f86e0422290..4ce687f0b5d0 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -86,7 +86,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
86 sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); 86 sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
87 if (!sd) 87 if (!sd)
88 goto out_put; 88 goto out_put;
89
89 sd->s_elem.symlink.target_sd = target_sd; 90 sd->s_elem.symlink.target_sd = target_sd;
91 target_sd = NULL; /* reference is now owned by the symlink */
90 92
91 sysfs_addrm_start(&acxt, parent_sd); 93 sysfs_addrm_start(&acxt, parent_sd);
92 94
@@ -95,11 +97,13 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
95 sysfs_link_sibling(sd); 97 sysfs_link_sibling(sd);
96 } 98 }
97 99
98 if (sysfs_addrm_finish(&acxt)) 100 if (!sysfs_addrm_finish(&acxt)) {
99 return 0; 101 error = -EEXIST;
102 goto out_put;
103 }
104
105 return 0;
100 106
101 error = -EEXIST;
102 /* fall through */
103 out_put: 107 out_put:
104 sysfs_put(target_sd); 108 sysfs_put(target_sd);
105 sysfs_put(sd); 109 sysfs_put(sd);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 6a37f2386a8d..6b8c8d76d308 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -71,7 +71,6 @@ extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
71extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); 71extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
72 72
73extern void sysfs_delete_inode(struct inode *inode); 73extern void sysfs_delete_inode(struct inode *inode);
74extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
75extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd); 74extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
76extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode); 75extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
77 76
diff --git a/include/linux/device.h b/include/linux/device.h
index be2debed70d2..d9f0a57f5a2f 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -572,6 +572,16 @@ dev_dbg(struct device * dev, const char * fmt, ...)
572} 572}
573#endif 573#endif
574 574
575#ifdef VERBOSE_DEBUG
576#define dev_vdbg dev_dbg
577#else
578static inline int __attribute__ ((format (printf, 2, 3)))
579dev_vdbg(struct device * dev, const char * fmt, ...)
580{
581 return 0;
582}
583#endif
584
575#define dev_err(dev, format, arg...) \ 585#define dev_err(dev, format, arg...) \
576 dev_printk(KERN_ERR , dev , format , ## arg) 586 dev_printk(KERN_ERR , dev , format , ## arg)
577#define dev_info(dev, format, arg...) \ 587#define dev_info(dev, format, arg...) \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0b806c5e32eb..9562a59b3703 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -862,7 +862,7 @@ extern void locks_init_lock(struct file_lock *);
862extern void locks_copy_lock(struct file_lock *, struct file_lock *); 862extern void locks_copy_lock(struct file_lock *, struct file_lock *);
863extern void locks_remove_posix(struct file *, fl_owner_t); 863extern void locks_remove_posix(struct file *, fl_owner_t);
864extern void locks_remove_flock(struct file *); 864extern void locks_remove_flock(struct file *);
865extern int posix_test_lock(struct file *, struct file_lock *); 865extern void posix_test_lock(struct file *, struct file_lock *);
866extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); 866extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
867extern int posix_lock_file_wait(struct file *, struct file_lock *); 867extern int posix_lock_file_wait(struct file *, struct file_lock *);
868extern int posix_unblock_lock(struct file *, struct file_lock *); 868extern int posix_unblock_lock(struct file *, struct file_lock *);
@@ -873,6 +873,7 @@ extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
873extern int __break_lease(struct inode *inode, unsigned int flags); 873extern int __break_lease(struct inode *inode, unsigned int flags);
874extern void lease_get_mtime(struct inode *, struct timespec *time); 874extern void lease_get_mtime(struct inode *, struct timespec *time);
875extern int setlease(struct file *, long, struct file_lock **); 875extern int setlease(struct file *, long, struct file_lock **);
876extern int vfs_setlease(struct file *, long, struct file_lock **);
876extern int lease_modify(struct file_lock **, int); 877extern int lease_modify(struct file_lock **, int);
877extern int lock_may_read(struct inode *, loff_t start, unsigned long count); 878extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
878extern int lock_may_write(struct inode *, loff_t start, unsigned long count); 879extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
@@ -1122,6 +1123,7 @@ struct file_operations {
1122 int (*flock) (struct file *, int, struct file_lock *); 1123 int (*flock) (struct file *, int, struct file_lock *);
1123 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 1124 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
1124 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 1125 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
1126 int (*setlease)(struct file *, long, struct file_lock **);
1125}; 1127};
1126 1128
1127struct inode_operations { 1129struct inode_operations {
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 695741b0e420..1831b196c70a 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -53,6 +53,7 @@ struct gianfar_platform_data {
53 u32 bus_id; 53 u32 bus_id;
54 u32 phy_id; 54 u32 phy_id;
55 u8 mac_addr[6]; 55 u8 mac_addr[6];
56 phy_interface_t interface;
56}; 57};
57 58
58struct gianfar_mdio_data { 59struct gianfar_mdio_data {
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 06cbf41d32d2..aa2fe22b1baa 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -36,15 +36,24 @@ extern char uevent_helper[];
36/* counter to tag the uevent, read only except for the kobject core */ 36/* counter to tag the uevent, read only except for the kobject core */
37extern u64 uevent_seqnum; 37extern u64 uevent_seqnum;
38 38
39/* the actions here must match the proper string in lib/kobject_uevent.c */ 39/*
40typedef int __bitwise kobject_action_t; 40 * The actions here must match the index to the string array
41 * in lib/kobject_uevent.c
42 *
43 * Do not add new actions here without checking with the driver-core
44 * maintainers. Action strings are not meant to express subsystem
45 * or device specific properties. In most cases you want to send a
46 * kobject_uevent_env(kobj, KOBJ_CHANGE, env) with additional event
47 * specific variables added to the event environment.
48 */
41enum kobject_action { 49enum kobject_action {
42 KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ 50 KOBJ_ADD,
43 KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ 51 KOBJ_REMOVE,
44 KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ 52 KOBJ_CHANGE,
45 KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */ 53 KOBJ_MOVE,
46 KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */ 54 KOBJ_ONLINE,
47 KOBJ_MOVE = (__force kobject_action_t) 0x06, /* device move */ 55 KOBJ_OFFLINE,
56 KOBJ_MAX
48}; 57};
49 58
50struct kobject { 59struct kobject {
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 273781c82e4d..2735b7cadd20 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -284,8 +284,6 @@ extern int device_prepare_suspend(pm_message_t state);
284#define device_may_wakeup(dev) \ 284#define device_may_wakeup(dev) \
285 (device_can_wakeup(dev) && (dev)->power.should_wakeup) 285 (device_can_wakeup(dev) && (dev)->power.should_wakeup)
286 286
287extern int dpm_runtime_suspend(struct device *, pm_message_t);
288extern void dpm_runtime_resume(struct device *);
289extern void __suspend_report_result(const char *function, void *fn, int ret); 287extern void __suspend_report_result(const char *function, void *fn, int ret);
290 288
291#define suspend_report_result(fn, ret) \ 289#define suspend_report_result(fn, ret) \
@@ -317,15 +315,6 @@ static inline int device_suspend(pm_message_t state)
317#define device_set_wakeup_enable(dev,val) do{}while(0) 315#define device_set_wakeup_enable(dev,val) do{}while(0)
318#define device_may_wakeup(dev) (0) 316#define device_may_wakeup(dev) (0)
319 317
320static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
321{
322 return 0;
323}
324
325static inline void dpm_runtime_resume(struct device * dev)
326{
327}
328
329#define suspend_report_result(fn, ret) do { } while (0) 318#define suspend_report_result(fn, ret) do { } while (0)
330 319
331static inline int call_platform_enable_wakeup(struct device *dev, int is_on) 320static inline int call_platform_enable_wakeup(struct device *dev, int is_on)
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
new file mode 100644
index 000000000000..44c28e94df50
--- /dev/null
+++ b/include/linux/uio_driver.h
@@ -0,0 +1,91 @@
1/*
2 * include/linux/uio_driver.h
3 *
4 * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
5 * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
6 * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
7 * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
8 *
9 * Userspace IO driver.
10 *
11 * Licensed under the GPLv2 only.
12 */
13
14#ifndef _UIO_DRIVER_H_
15#define _UIO_DRIVER_H_
16
17#include <linux/module.h>
18#include <linux/fs.h>
19#include <linux/interrupt.h>
20
21/**
22 * struct uio_mem - description of a UIO memory region
23 * @kobj: kobject for this mapping
24 * @addr: address of the device's memory
25 * @size: size of IO
26 * @memtype: type of memory addr points to
27 * @internal_addr: ioremap-ped version of addr, for driver internal use
28 */
29struct uio_mem {
30 struct kobject kobj;
31 unsigned long addr;
32 unsigned long size;
33 int memtype;
34 void __iomem *internal_addr;
35};
36
37#define MAX_UIO_MAPS 5
38
39struct uio_device;
40
41/**
42 * struct uio_info - UIO device capabilities
43 * @uio_dev: the UIO device this info belongs to
44 * @name: device name
45 * @version: device driver version
46 * @mem: list of mappable memory regions, size==0 for end of list
47 * @irq: interrupt number or UIO_IRQ_CUSTOM
48 * @irq_flags: flags for request_irq()
49 * @priv: optional private data
50 * @handler: the device's irq handler
51 * @mmap: mmap operation for this uio device
52 * @open: open operation for this uio device
53 * @release: release operation for this uio device
54 */
55struct uio_info {
56 struct uio_device *uio_dev;
57 char *name;
58 char *version;
59 struct uio_mem mem[MAX_UIO_MAPS];
60 long irq;
61 unsigned long irq_flags;
62 void *priv;
63 irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
64 int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
65 int (*open)(struct uio_info *info, struct inode *inode);
66 int (*release)(struct uio_info *info, struct inode *inode);
67};
68
69extern int __must_check
70 __uio_register_device(struct module *owner,
71 struct device *parent,
72 struct uio_info *info);
73static inline int __must_check
74 uio_register_device(struct device *parent, struct uio_info *info)
75{
76 return __uio_register_device(THIS_MODULE, parent, info);
77}
78extern void uio_unregister_device(struct uio_info *info);
79extern void uio_event_notify(struct uio_info *info);
80
81/* defines for uio_device->irq */
82#define UIO_IRQ_CUSTOM -1
83#define UIO_IRQ_NONE -2
84
85/* defines for uio_device->memtype */
86#define UIO_MEM_NONE 0
87#define UIO_MEM_PHYS 1
88#define UIO_MEM_LOGICAL 2
89#define UIO_MEM_VIRTUAL 3
90
91#endif /* _LINUX_UIO_DRIVER_H_ */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 495b7d4dd330..73328476761c 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -65,18 +65,6 @@ config PM_TRACE
65 CAUTION: this option will cause your machine's real-time clock to be 65 CAUTION: this option will cause your machine's real-time clock to be
66 set to an invalid time after a resume. 66 set to an invalid time after a resume.
67 67
68config PM_SYSFS_DEPRECATED
69 bool "Driver model /sys/devices/.../power/state files (DEPRECATED)"
70 depends on PM && SYSFS
71 default n
72 help
73 The driver model started out with a sysfs file intended to provide
74 a userspace hook for device power management. This feature has never
75 worked very well, except for limited testing purposes, and so it will
76 be removed. It's not clear that a generic mechanism could really
77 handle the wide variability of device power states; any replacements
78 are likely to be bus or driver specific.
79
80config SOFTWARE_SUSPEND 68config SOFTWARE_SUSPEND
81 bool "Software Suspend (Hibernation)" 69 bool "Software Suspend (Hibernation)"
82 depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) 70 depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index bd5ecbbafab1..6a80c784a8fb 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -33,25 +33,15 @@ static DEFINE_SPINLOCK(sequence_lock);
33static struct sock *uevent_sock; 33static struct sock *uevent_sock;
34#endif 34#endif
35 35
36static char *action_to_string(enum kobject_action action) 36/* the strings here must match the enum in include/linux/kobject.h */
37{ 37const char *kobject_actions[] = {
38 switch (action) { 38 "add",
39 case KOBJ_ADD: 39 "remove",
40 return "add"; 40 "change",
41 case KOBJ_REMOVE: 41 "move",
42 return "remove"; 42 "online",
43 case KOBJ_CHANGE: 43 "offline",
44 return "change"; 44};
45 case KOBJ_OFFLINE:
46 return "offline";
47 case KOBJ_ONLINE:
48 return "online";
49 case KOBJ_MOVE:
50 return "move";
51 default:
52 return NULL;
53 }
54}
55 45
56/** 46/**
57 * kobject_uevent_env - send an uevent with environmental data 47 * kobject_uevent_env - send an uevent with environmental data
@@ -83,7 +73,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
83 73
84 pr_debug("%s\n", __FUNCTION__); 74 pr_debug("%s\n", __FUNCTION__);
85 75
86 action_string = action_to_string(action); 76 action_string = kobject_actions[action];
87 if (!action_string) { 77 if (!action_string) {
88 pr_debug("kobject attempted to send uevent without action_string!\n"); 78 pr_debug("kobject attempted to send uevent without action_string!\n");
89 return -EINVAL; 79 return -EINVAL;
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 523a137d49dd..465b73d50532 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -90,14 +90,11 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
90 } 90 }
91 91
92 /* Add channel and frequency */ 92 /* Add channel and frequency */
93 /* Note : userspace automatically computes channel using iwrange */
93 iwe.cmd = SIOCGIWFREQ; 94 iwe.cmd = SIOCGIWFREQ;
94 iwe.u.freq.m = network->channel;
95 iwe.u.freq.e = 0;
96 iwe.u.freq.i = 0;
97 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
98
99 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel); 95 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
100 iwe.u.freq.e = 6; 96 iwe.u.freq.e = 6;
97 iwe.u.freq.i = 0;
101 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); 98 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
102 99
103 /* Add encryption capability */ 100 /* Add encryption capability */