aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-05 18:30:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-05 18:30:53 -0400
commitb7405e16435f710edfae6ba32bef4ca20d3de145 (patch)
treee79fd7560d8c093cb975ed61b24d009a080872c5 /fs
parentea62ccd00fd0b6720b033adfc9984f31130ce195 (diff)
parent0ec54aa8af5e6faa346aa55a1ad15ee6c25bb42d (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] Fix typo in cifs readme from previous commit [CIFS] Make sec=none force an anonymous mount [CIFS] Change semaphore to mutex for cifs lock_sem [CIFS] Fix oops in reset_cifs_unix_caps on reconnect [CIFS] UID/GID override on CIFS mounts to Samba [CIFS] prefixpath mounts to servers supporting posix paths used wrong slash [CIFS] Update cifs version to 1.49 [CIFS] Replace kmalloc/memset combination with kzalloc [CIFS] Add IPv6 support [CIFS] New CIFS POSIX mkdir performance improvement (part 2) [CIFS] New CIFS POSIX mkdir performance improvement [CIFS] Add write perm for usr to file on windows should remove r/o dos attr [CIFS] Remove unnecessary parm to cifs_reopen_file [CIFS] Switch cifsd to kthread_run from kernel_thread [CIFS] Remove unnecessary checks
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES22
-rw-r--r--fs/cifs/README43
-rw-r--r--fs/cifs/TODO69
-rw-r--r--fs/cifs/cifs_fs_sb.h14
-rw-r--r--fs/cifs/cifs_unicode.c4
-rw-r--r--fs/cifs/cifsfs.c79
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifspdu.h32
-rw-r--r--fs/cifs/cifsproto.h7
-rw-r--r--fs/cifs/cifssmb.c130
-rw-r--r--fs/cifs/connect.c140
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/cifs/file.c129
-rw-r--r--fs/cifs/inode.c282
-rw-r--r--fs/cifs/netmisc.c24
-rw-r--r--fs/cifs/readdir.c161
17 files changed, 748 insertions, 394 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 5d1f4873d701..a9b6bc5157b8 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,4 +1,16 @@
1Verison 1.48 1Version 1.49
2------------
3IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
4address after the "ip=" mount option, at least until mount.cifs is fixed to
5handle DNS host to ipv6 name translation). Accept override of uid or gid
6on mount even when Unix Extensions are negotiated (it used to be ignored
7when Unix Extensions were ignored). This allows users to override the
8default 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"
10mount override username (so that null user connection is attempted)
11to match what documentation said.
12
13Version 1.48
2------------ 14------------
3Fix mtime bouncing around from local idea of last write times to remote time. 15Fix mtime bouncing around from local idea of last write times to remote time.
4Fix hang (in i_size_read) when simultaneous size update of same remote file 16Fix hang (in i_size_read) when simultaneous size update of same remote file
@@ -9,7 +21,13 @@ from read-only back to read-write, reflect this change in default file mode
9(we had been leaving a file's mode read-only until the inode were reloaded). 21(we had been leaving a file's mode read-only until the inode were reloaded).
10Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute 22Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute
11when archive dos attribute not set and we are changing mode back to writeable 23when archive dos attribute not set and we are changing mode back to writeable
12on server which does not support the Unix Extensions). 24on server which does not support the Unix Extensions). Remove read only dos
25attribute on chmod when adding any write permission (ie on any of
26user/group/other (not all of user/group/other ie 0222) when
27mounted to windows. Add support for POSIX MkDir (slight performance
28enhancement and eliminates the network race between the mkdir and set
29path info of the mode).
30
13 31
14Version 1.47 32Version 1.47
15------------ 33------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 080c5eba112b..4d01697722cc 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -257,13 +257,19 @@ A partial list of the supported mount options follows:
257 mount. 257 mount.
258 domain Set the SMB/CIFS workgroup name prepended to the 258 domain Set the SMB/CIFS workgroup name prepended to the
259 username during CIFS session establishment 259 username during CIFS session establishment
260 uid If CIFS Unix extensions are not supported by the server 260 uid Set the default uid for inodes. For mounts to servers
261 this overrides the default uid for inodes. For mounts to 261 which do support the CIFS Unix extensions, such as a
262 servers which do support the CIFS Unix extensions, such 262 properly configured Samba server, the server provides
263 as a properly configured Samba server, the server provides 263 the uid, gid and mode so this parameter should not be
264 the uid, gid and mode. For servers which do not support 264 specified unless the server and clients uid and gid
265 the Unix extensions, the default uid (and gid) returned on 265 numbering differ. If the server and client are in the
266 lookup of existing files is the uid (gid) of the person 266 same domain (e.g. running winbind or nss_ldap) and
267 the server supports the Unix Extensions then the uid
268 and gid can be retrieved from the server (and uid
269 and gid would not have to be specifed on the mount.
270 For servers which do not support the CIFS Unix
271 extensions, the default uid (and gid) returned on lookup
272 of existing files will be the uid (gid) of the person
267 who executed the mount (root, except when mount.cifs 273 who executed the mount (root, except when mount.cifs
268 is configured setuid for user mounts) unless the "uid=" 274 is configured setuid for user mounts) unless the "uid="
269 (gid) mount option is specified. For the uid (gid) of newly 275 (gid) mount option is specified. For the uid (gid) of newly
@@ -281,8 +287,7 @@ A partial list of the supported mount options follows:
281 the client. Note that the mount.cifs helper must be 287 the client. Note that the mount.cifs helper must be
282 at version 1.10 or higher to support specifying the uid 288 at version 1.10 or higher to support specifying the uid
283 (or gid) in non-numberic form. 289 (or gid) in non-numberic form.
284 gid If CIFS Unix extensions are not supported by the server 290 gid Set the default gid for inodes (similar to above).
285 this overrides the default gid for inodes.
286 file_mode If CIFS Unix extensions are not supported by the server 291 file_mode If CIFS Unix extensions are not supported by the server
287 this overrides the default mode for file inodes. 292 this overrides the default mode for file inodes.
288 dir_mode If CIFS Unix extensions are not supported by the server 293 dir_mode If CIFS Unix extensions are not supported by the server
@@ -467,7 +472,7 @@ including:
467 -V print mount.cifs version 472 -V print mount.cifs version
468 -? display simple usage information 473 -? display simple usage information
469 474
470With recent 2.6 kernel versions of modutils, the version of the cifs kernel 475With most 2.6 kernel versions of modutils, the version of the cifs kernel
471module can be displayed via modinfo. 476module can be displayed via modinfo.
472 477
473Misc /proc/fs/cifs Flags and Debug Info 478Misc /proc/fs/cifs Flags and Debug Info
@@ -516,8 +521,22 @@ SecurityFlags Flags which control security negotiation and
516 must use plaintext passwords 0x20020 521 must use plaintext passwords 0x20020
517 (reserved for future packet encryption) 0x00040 522 (reserved for future packet encryption) 0x00040
518 523
519cifsFYI If set to one, additional debug information is 524cifsFYI If set to non-zero value, additional debug information
520 logged to the system error log. (default 0) 525 will be logged to the system error log. This field
526 contains three flags controlling different classes of
527 debugging entries. The maximum value it can be set
528 to is 7 which enables all debugging points (default 0).
529 Some debugging statements are not compiled into the
530 cifs kernel unless CONFIG_CIFS_DEBUG2 is enabled in the
531 kernel configuration. cifsFYI may be set to one or
532 nore of the following flags (7 sets them all):
533
534 log cifs informational messages 0x01
535 log return codes from cifs entry points 0x02
536 log slow responses (ie which take longer than 1 second)
537 CONFIG_CIFS_STATS2 must be enabled in .config 0x04
538
539
521traceSMB If set to one, debug information is logged to the 540traceSMB If set to one, debug information is logged to the
522 system error log with the start of smb requests 541 system error log with the start of smb requests
523 and responses (default 0) 542 and responses (default 0)
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index d7b9c27c942d..78b620e332bd 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
1Version 1.39 November 30, 2005 1Version 1.49 April 26, 2007
2 2
3A Partial List of Missing Features 3A Partial List of Missing Features
4================================== 4==================================
@@ -18,7 +18,7 @@ better)
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Kerberos/SPNEGO session setup support - (started)
20 20
21e) NTLMv2 authentication (mostly implemented - double check 21e) More testing of NTLMv2 authentication (mostly implemented - double check
22that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in 22that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in
23fs/cifs/connect.c) 23fs/cifs/connect.c)
24 24
@@ -27,55 +27,44 @@ used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
27and raw NTLMSSP already. This is important when enabling 27and raw NTLMSSP already. This is important when enabling
28extended security and mounting to Windows 2003 Servers 28extended security and mounting to Windows 2003 Servers
29 29
30f) Directory entry caching relies on a 1 second timer, rather than 30g) Directory entry caching relies on a 1 second timer, rather than
31using FindNotify or equivalent. - (started) 31using FindNotify or equivalent. - (started)
32 32
33g) A few byte range testcases fail due to POSIX vs. Windows/CIFS 33h) quota support (needs minor kernel change since quota calls
34style byte range lock differences. Save byte range locks so
35reconnect can replay them.
36
37h) Support unlock all (unlock 0,MAX_OFFSET)
38by unlocking all known byte range locks that we locked on the file.
39
40i) quota support (needs minor kernel change since quota calls
41to make it to network filesystems or deviceless filesystems) 34to make it to network filesystems or deviceless filesystems)
42 35
43j) investigate sync behavior (including syncpage) and check 36i) investigate sync behavior (including syncpage) and check
44for proper behavior of intr/nointr 37for proper behavior of intr/nointr
45 38
46k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the 39j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
47extra copy in/out of the socket buffers in some cases. 40extra copy in/out of the socket buffers in some cases.
48 41
49l) finish support for IPv6. This is mostly complete but 42k) Better optimize open (and pathbased setfilesize) to reduce the
50needs a simple conversion of ipv6 to sin6_addr from the
51address in string representation.
52
53m) Better optimize open (and pathbased setfilesize) to reduce the
54oplock breaks coming from windows srv. Piggyback identical file 43oplock breaks coming from windows srv. Piggyback identical file
55opens on top of each other by incrementing reference count rather 44opens on top of each other by incrementing reference count rather
56than resending (helps reduce server resource utilization and avoid 45than resending (helps reduce server resource utilization and avoid
57spurious oplock breaks). 46spurious oplock breaks).
58 47
59o) Improve performance of readpages by sending more than one read 48l) Improve performance of readpages by sending more than one read
60at a time when 8 pages or more are requested. In conjuntion 49at a time when 8 pages or more are requested. In conjuntion
61add support for async_cifs_readpages. 50add support for async_cifs_readpages.
62 51
63p) Add support for storing symlink info to Windows servers 52m) Add support for storing symlink info to Windows servers
64in the Extended Attribute format their SFU clients would recognize. 53in the Extended Attribute format their SFU clients would recognize.
65 54
66q) Finish fcntl D_NOTIFY support so kde and gnome file list windows 55n) Finish fcntl D_NOTIFY support so kde and gnome file list windows
67will autorefresh (partially complete by Asser). Needs minor kernel 56will autorefresh (partially complete by Asser). Needs minor kernel
68vfs change to support removing D_NOTIFY on a file. 57vfs change to support removing D_NOTIFY on a file.
69 58
70r) Add GUI tool to configure /proc/fs/cifs settings and for display of 59o) Add GUI tool to configure /proc/fs/cifs settings and for display of
71the CIFS statistics (started) 60the CIFS statistics (started)
72 61
73s) implement support for security and trusted categories of xattrs 62p) implement support for security and trusted categories of xattrs
74(requires minor protocol extension) to enable better support for SELINUX 63(requires minor protocol extension) to enable better support for SELINUX
75 64
76t) Implement O_DIRECT flag on open (already supported on mount) 65q) Implement O_DIRECT flag on open (already supported on mount)
77 66
78u) Create UID mapping facility so server UIDs can be mapped on a per 67r) Create UID mapping facility so server UIDs can be mapped on a per
79mount or a per server basis to client UIDs or nobody if no mapping 68mount or a per server basis to client UIDs or nobody if no mapping
80exists. This is helpful when Unix extensions are negotiated to 69exists. This is helpful when Unix extensions are negotiated to
81allow better permission checking when UIDs differ on the server 70allow better permission checking when UIDs differ on the server
@@ -83,19 +72,26 @@ and client. Add new protocol request to the CIFS protocol
83standard for asking the server for the corresponding name of a 72standard for asking the server for the corresponding name of a
84particular uid. 73particular uid.
85 74
86v) Add support for CIFS Unix and also the newer POSIX extensions to the 75s) Add support for CIFS Unix and also the newer POSIX extensions to the
87server side for Samba 4. 76server side for Samba 4.
88 77
89w) Finish up the dos time conversion routines needed to return old server 78t) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
90time to the client (default time, of now or time 0 is used now for these
91very old servers)
92
93x) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
94need to add ability to set time to server (utimes command) 79need to add ability to set time to server (utimes command)
95 80
96y) Finish testing of Windows 9x/Windows ME server support (started). 81u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)
82
83v) mount check for unmatched uids
84
85w) Add mount option for Linux extension disable per mount, and partial
86disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?)
97 87
98KNOWN BUGS (updated February 26, 2007) 88x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of
89processes can proceed better in parallel (on the server)
90
91y) Fix Samba 3 to handle reads/writes over 127K (and remove the cifs mount
92restriction of wsize max being 127K)
93
94KNOWN BUGS (updated April 24, 2007)
99==================================== 95====================================
100See http://bugzilla.samba.org - search on product "CifsVFS" for 96See http://bugzilla.samba.org - search on product "CifsVFS" for
101current bug list. 97current bug list.
@@ -127,10 +123,3 @@ negotiated size) and send larger write sizes to modern servers.
1274) More exhaustively test against less common servers. More testing 1234) More exhaustively test against less common servers. More testing
128against Windows 9x, Windows ME servers. 124against Windows 9x, Windows ME servers.
129 125
130DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)
131
132mount check for unmatched uids - and uid override
133
134Add mount option for Linux extension disable per mount, and partial disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?)
135
136Free threads at umount --force that are stuck on the sesSem
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index fd1e52ebcee6..4cc2012e9322 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -22,12 +22,14 @@
22#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ 22#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ 23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ 24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ 25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ 26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
27#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ 27#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible*/
28#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ 28#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
29#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ 29#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
30#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ 30#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
31#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
32#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
31 33
32struct cifs_sb_info { 34struct cifs_sb_info {
33 struct cifsTconInfo *tcon; /* primary mount */ 35 struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index d2a8b2941fc2..793c4b95c164 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -74,8 +74,8 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
74 charlen = codepage->char2uni(from, len, &wchar_to[i]); 74 charlen = codepage->char2uni(from, len, &wchar_to[i]);
75 if (charlen < 1) { 75 if (charlen < 1) {
76 cERROR(1, 76 cERROR(1,
77 ("cifs_strtoUCS: char2uni returned %d", 77 ("strtoUCS: char2uni of %d returned %d",
78 charlen)); 78 (int)*from, charlen));
79 /* A question mark */ 79 /* A question mark */
80 to[i] = cpu_to_le16(0x003f); 80 to[i] = cpu_to_le16(0x003f);
81 charlen = 1; 81 charlen = 1;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index faba4d69fe91..5036dae09cd7 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -100,7 +100,7 @@ cifs_read_super(struct super_block *sb, void *data,
100 sb->s_flags |= MS_NODIRATIME | MS_NOATIME; 100 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
101 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 101 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
102 cifs_sb = CIFS_SB(sb); 102 cifs_sb = CIFS_SB(sb);
103 if(cifs_sb == NULL) 103 if (cifs_sb == NULL)
104 return -ENOMEM; 104 return -ENOMEM;
105 105
106 rc = cifs_mount(sb, cifs_sb, data, devname); 106 rc = cifs_mount(sb, cifs_sb, data, devname);
@@ -115,10 +115,10 @@ cifs_read_super(struct super_block *sb, void *data,
115 sb->s_magic = CIFS_MAGIC_NUMBER; 115 sb->s_magic = CIFS_MAGIC_NUMBER;
116 sb->s_op = &cifs_super_ops; 116 sb->s_op = &cifs_super_ops;
117#ifdef CONFIG_CIFS_EXPERIMENTAL 117#ifdef CONFIG_CIFS_EXPERIMENTAL
118 if(experimEnabled != 0) 118 if (experimEnabled != 0)
119 sb->s_export_op = &cifs_export_ops; 119 sb->s_export_op = &cifs_export_ops;
120#endif /* EXPERIMENTAL */ 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 = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
123#ifdef CONFIG_CIFS_QUOTA 123#ifdef CONFIG_CIFS_QUOTA
124 sb->s_qcop = &cifs_quotactl_ops; 124 sb->s_qcop = &cifs_quotactl_ops;
@@ -147,8 +147,8 @@ out_no_root:
147 iput(inode); 147 iput(inode);
148 148
149out_mount_failed: 149out_mount_failed:
150 if(cifs_sb) { 150 if (cifs_sb) {
151 if(cifs_sb->local_nls) 151 if (cifs_sb->local_nls)
152 unload_nls(cifs_sb->local_nls); 152 unload_nls(cifs_sb->local_nls);
153 kfree(cifs_sb); 153 kfree(cifs_sb);
154 } 154 }
@@ -163,7 +163,7 @@ cifs_put_super(struct super_block *sb)
163 163
164 cFYI(1, ("In cifs_put_super")); 164 cFYI(1, ("In cifs_put_super"));
165 cifs_sb = CIFS_SB(sb); 165 cifs_sb = CIFS_SB(sb);
166 if(cifs_sb == NULL) { 166 if (cifs_sb == NULL) {
167 cFYI(1,("Empty cifs superblock info passed to unmount")); 167 cFYI(1,("Empty cifs superblock info passed to unmount"));
168 return; 168 return;
169 } 169 }
@@ -208,14 +208,14 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
208 208
209 /* Only need to call the old QFSInfo if failed 209 /* Only need to call the old QFSInfo if failed
210 on newer one */ 210 on newer one */
211 if(rc) 211 if (rc)
212 if(pTcon->ses->capabilities & CAP_NT_SMBS) 212 if (pTcon->ses->capabilities & CAP_NT_SMBS)
213 rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ 213 rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
214 214
215 /* Some old Windows servers also do not support level 103, retry with 215 /* Some old Windows servers also do not support level 103, retry with
216 older level one if old server failed the previous call or we 216 older level one if old server failed the previous call or we
217 bypassed it because we detected that this was an older LANMAN sess */ 217 bypassed it because we detected that this was an older LANMAN sess */
218 if(rc) 218 if (rc)
219 rc = SMBOldQFSInfo(xid, pTcon, buf); 219 rc = SMBOldQFSInfo(xid, pTcon, buf);
220 /* 220 /*
221 int f_type; 221 int f_type;
@@ -301,11 +301,19 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
301 if (cifs_sb->tcon->ses->userName) 301 if (cifs_sb->tcon->ses->userName)
302 seq_printf(s, ",username=%s", 302 seq_printf(s, ",username=%s",
303 cifs_sb->tcon->ses->userName); 303 cifs_sb->tcon->ses->userName);
304 if(cifs_sb->tcon->ses->domainName) 304 if (cifs_sb->tcon->ses->domainName)
305 seq_printf(s, ",domain=%s", 305 seq_printf(s, ",domain=%s",
306 cifs_sb->tcon->ses->domainName); 306 cifs_sb->tcon->ses->domainName);
307 } 307 }
308 } 308 }
309 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
310 seq_printf(s, ",posixpaths");
311 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
312 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX))
313 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
314 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
315 !(cifs_sb->tcon->ses->capabilities & CAP_UNIX))
316 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
309 seq_printf(s, ",rsize=%d",cifs_sb->rsize); 317 seq_printf(s, ",rsize=%d",cifs_sb->rsize);
310 seq_printf(s, ",wsize=%d",cifs_sb->wsize); 318 seq_printf(s, ",wsize=%d",cifs_sb->wsize);
311 } 319 }
@@ -321,14 +329,14 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
321 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 329 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
322 struct cifsTconInfo *pTcon; 330 struct cifsTconInfo *pTcon;
323 331
324 if(cifs_sb) 332 if (cifs_sb)
325 pTcon = cifs_sb->tcon; 333 pTcon = cifs_sb->tcon;
326 else 334 else
327 return -EIO; 335 return -EIO;
328 336
329 337
330 xid = GetXid(); 338 xid = GetXid();
331 if(pTcon) { 339 if (pTcon) {
332 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 340 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
333 } else { 341 } else {
334 return -EIO; 342 return -EIO;
@@ -346,13 +354,13 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
346 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 354 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
347 struct cifsTconInfo *pTcon; 355 struct cifsTconInfo *pTcon;
348 356
349 if(cifs_sb) 357 if (cifs_sb)
350 pTcon = cifs_sb->tcon; 358 pTcon = cifs_sb->tcon;
351 else 359 else
352 return -EIO; 360 return -EIO;
353 361
354 xid = GetXid(); 362 xid = GetXid();
355 if(pTcon) { 363 if (pTcon) {
356 cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); 364 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
357 } else { 365 } else {
358 rc = -EIO; 366 rc = -EIO;
@@ -369,13 +377,13 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
369 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 377 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
370 struct cifsTconInfo *pTcon; 378 struct cifsTconInfo *pTcon;
371 379
372 if(cifs_sb) 380 if (cifs_sb)
373 pTcon = cifs_sb->tcon; 381 pTcon = cifs_sb->tcon;
374 else 382 else
375 return -EIO; 383 return -EIO;
376 384
377 xid = GetXid(); 385 xid = GetXid();
378 if(pTcon) { 386 if (pTcon) {
379 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); 387 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
380 } else { 388 } else {
381 rc = -EIO; 389 rc = -EIO;
@@ -392,13 +400,13 @@ int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
392 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 400 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
393 struct cifsTconInfo *pTcon; 401 struct cifsTconInfo *pTcon;
394 402
395 if(cifs_sb) { 403 if (cifs_sb) {
396 pTcon = cifs_sb->tcon; 404 pTcon = cifs_sb->tcon;
397 } else { 405 } else {
398 return -EIO; 406 return -EIO;
399 } 407 }
400 xid = GetXid(); 408 xid = GetXid();
401 if(pTcon) { 409 if (pTcon) {
402 cFYI(1,("pqstats %p",qstats)); 410 cFYI(1,("pqstats %p",qstats));
403 } else { 411 } else {
404 rc = -EIO; 412 rc = -EIO;
@@ -424,11 +432,11 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
424 if (!(flags & MNT_FORCE)) 432 if (!(flags & MNT_FORCE))
425 return; 433 return;
426 cifs_sb = CIFS_SB(vfsmnt->mnt_sb); 434 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
427 if(cifs_sb == NULL) 435 if (cifs_sb == NULL)
428 return; 436 return;
429 437
430 tcon = cifs_sb->tcon; 438 tcon = cifs_sb->tcon;
431 if(tcon == NULL) 439 if (tcon == NULL)
432 return; 440 return;
433 down(&tcon->tconSem); 441 down(&tcon->tconSem);
434 if (atomic_read(&tcon->useCount) == 1) 442 if (atomic_read(&tcon->useCount) == 1)
@@ -437,7 +445,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
437 445
438 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 446 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
439 /* cancel_notify_requests(tcon); */ 447 /* cancel_notify_requests(tcon); */
440 if(tcon->ses && tcon->ses->server) 448 if (tcon->ses && tcon->ses->server)
441 { 449 {
442 cFYI(1,("wake up tasks now - umount begin not complete")); 450 cFYI(1,("wake up tasks now - umount begin not complete"));
443 wake_up_all(&tcon->ses->server->request_q); 451 wake_up_all(&tcon->ses->server->request_q);
@@ -529,8 +537,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
529 /* some applications poll for the file length in this strange 537 /* some applications poll for the file length in this strange
530 way so we must seek to end on non-oplocked files by 538 way so we must seek to end on non-oplocked files by
531 setting the revalidate time to zero */ 539 setting the revalidate time to zero */
532 if(file->f_path.dentry->d_inode) 540 CIFS_I(file->f_path.dentry->d_inode)->time = 0;
533 CIFS_I(file->f_path.dentry->d_inode)->time = 0;
534 541
535 retval = cifs_revalidate(file->f_path.dentry); 542 retval = cifs_revalidate(file->f_path.dentry);
536 if (retval < 0) 543 if (retval < 0)
@@ -724,7 +731,7 @@ cifs_destroy_inodecache(void)
724static int 731static int
725cifs_init_request_bufs(void) 732cifs_init_request_bufs(void)
726{ 733{
727 if(CIFSMaxBufSize < 8192) { 734 if (CIFSMaxBufSize < 8192) {
728 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum 735 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
729 Unicode path name has to fit in any SMB/CIFS path based frames */ 736 Unicode path name has to fit in any SMB/CIFS path based frames */
730 CIFSMaxBufSize = 8192; 737 CIFSMaxBufSize = 8192;
@@ -741,7 +748,7 @@ cifs_init_request_bufs(void)
741 if (cifs_req_cachep == NULL) 748 if (cifs_req_cachep == NULL)
742 return -ENOMEM; 749 return -ENOMEM;
743 750
744 if(cifs_min_rcv < 1) 751 if (cifs_min_rcv < 1)
745 cifs_min_rcv = 1; 752 cifs_min_rcv = 1;
746 else if (cifs_min_rcv > 64) { 753 else if (cifs_min_rcv > 64) {
747 cifs_min_rcv = 64; 754 cifs_min_rcv = 64;
@@ -751,7 +758,7 @@ cifs_init_request_bufs(void)
751 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, 758 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
752 cifs_req_cachep); 759 cifs_req_cachep);
753 760
754 if(cifs_req_poolp == NULL) { 761 if (cifs_req_poolp == NULL) {
755 kmem_cache_destroy(cifs_req_cachep); 762 kmem_cache_destroy(cifs_req_cachep);
756 return -ENOMEM; 763 return -ENOMEM;
757 } 764 }
@@ -772,7 +779,7 @@ cifs_init_request_bufs(void)
772 return -ENOMEM; 779 return -ENOMEM;
773 } 780 }
774 781
775 if(cifs_min_small < 2) 782 if (cifs_min_small < 2)
776 cifs_min_small = 2; 783 cifs_min_small = 2;
777 else if (cifs_min_small > 256) { 784 else if (cifs_min_small > 256) {
778 cifs_min_small = 256; 785 cifs_min_small = 256;
@@ -782,7 +789,7 @@ cifs_init_request_bufs(void)
782 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, 789 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
783 cifs_sm_req_cachep); 790 cifs_sm_req_cachep);
784 791
785 if(cifs_sm_req_poolp == NULL) { 792 if (cifs_sm_req_poolp == NULL) {
786 mempool_destroy(cifs_req_poolp); 793 mempool_destroy(cifs_req_poolp);
787 kmem_cache_destroy(cifs_req_cachep); 794 kmem_cache_destroy(cifs_req_cachep);
788 kmem_cache_destroy(cifs_sm_req_cachep); 795 kmem_cache_destroy(cifs_sm_req_cachep);
@@ -812,7 +819,7 @@ cifs_init_mids(void)
812 819
813 /* 3 is a reasonable minimum number of simultaneous operations */ 820 /* 3 is a reasonable minimum number of simultaneous operations */
814 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep); 821 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
815 if(cifs_mid_poolp == NULL) { 822 if (cifs_mid_poolp == NULL) {
816 kmem_cache_destroy(cifs_mid_cachep); 823 kmem_cache_destroy(cifs_mid_cachep);
817 return -ENOMEM; 824 return -ENOMEM;
818 } 825 }
@@ -850,14 +857,14 @@ static int cifs_oplock_thread(void * dummyarg)
850 continue; 857 continue;
851 858
852 spin_lock(&GlobalMid_Lock); 859 spin_lock(&GlobalMid_Lock);
853 if(list_empty(&GlobalOplock_Q)) { 860 if (list_empty(&GlobalOplock_Q)) {
854 spin_unlock(&GlobalMid_Lock); 861 spin_unlock(&GlobalMid_Lock);
855 set_current_state(TASK_INTERRUPTIBLE); 862 set_current_state(TASK_INTERRUPTIBLE);
856 schedule_timeout(39*HZ); 863 schedule_timeout(39*HZ);
857 } else { 864 } else {
858 oplock_item = list_entry(GlobalOplock_Q.next, 865 oplock_item = list_entry(GlobalOplock_Q.next,
859 struct oplock_q_entry, qhead); 866 struct oplock_q_entry, qhead);
860 if(oplock_item) { 867 if (oplock_item) {
861 cFYI(1,("found oplock item to write out")); 868 cFYI(1,("found oplock item to write out"));
862 pTcon = oplock_item->tcon; 869 pTcon = oplock_item->tcon;
863 inode = oplock_item->pinode; 870 inode = oplock_item->pinode;
@@ -871,7 +878,7 @@ static int cifs_oplock_thread(void * dummyarg)
871 /* mutex_lock(&inode->i_mutex);*/ 878 /* mutex_lock(&inode->i_mutex);*/
872 if (S_ISREG(inode->i_mode)) { 879 if (S_ISREG(inode->i_mode)) {
873 rc = filemap_fdatawrite(inode->i_mapping); 880 rc = filemap_fdatawrite(inode->i_mapping);
874 if(CIFS_I(inode)->clientCanCacheRead == 0) { 881 if (CIFS_I(inode)->clientCanCacheRead == 0) {
875 filemap_fdatawait(inode->i_mapping); 882 filemap_fdatawait(inode->i_mapping);
876 invalidate_remote_inode(inode); 883 invalidate_remote_inode(inode);
877 } 884 }
@@ -888,7 +895,7 @@ static int cifs_oplock_thread(void * dummyarg)
888 not bother sending an oplock release if session 895 not bother sending an oplock release if session
889 to server still is disconnected since oplock 896 to server still is disconnected since oplock
890 already released by the server in that case */ 897 already released by the server in that case */
891 if(pTcon->tidStatus != CifsNeedReconnect) { 898 if (pTcon->tidStatus != CifsNeedReconnect) {
892 rc = CIFSSMBLock(0, pTcon, netfid, 899 rc = CIFSSMBLock(0, pTcon, netfid,
893 0 /* len */ , 0 /* offset */, 0, 900 0 /* len */ , 0 /* offset */, 0,
894 0, LOCKING_ANDX_OPLOCK_RELEASE, 901 0, LOCKING_ANDX_OPLOCK_RELEASE,
@@ -922,7 +929,7 @@ static int cifs_dnotify_thread(void * dummyarg)
922 list_for_each(tmp, &GlobalSMBSessionList) { 929 list_for_each(tmp, &GlobalSMBSessionList) {
923 ses = list_entry(tmp, struct cifsSesInfo, 930 ses = list_entry(tmp, struct cifsSesInfo,
924 cifsSessionList); 931 cifsSessionList);
925 if(ses && ses->server && 932 if (ses && ses->server &&
926 atomic_read(&ses->server->inFlight)) 933 atomic_read(&ses->server->inFlight))
927 wake_up_all(&ses->server->response_q); 934 wake_up_all(&ses->server->response_q);
928 } 935 }
@@ -971,10 +978,10 @@ init_cifs(void)
971 rwlock_init(&GlobalSMBSeslock); 978 rwlock_init(&GlobalSMBSeslock);
972 spin_lock_init(&GlobalMid_Lock); 979 spin_lock_init(&GlobalMid_Lock);
973 980
974 if(cifs_max_pending < 2) { 981 if (cifs_max_pending < 2) {
975 cifs_max_pending = 2; 982 cifs_max_pending = 2;
976 cFYI(1,("cifs_max_pending set to min of 2")); 983 cFYI(1,("cifs_max_pending set to min of 2"));
977 } else if(cifs_max_pending > 256) { 984 } else if (cifs_max_pending > 256) {
978 cifs_max_pending = 256; 985 cifs_max_pending = 256;
979 cFYI(1,("cifs_max_pending set to max of 256")); 986 cFYI(1,("cifs_max_pending set to max of 256"));
980 } 987 }
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 2c2c384894d8..c235d32ad4a8 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
101extern int cifs_ioctl (struct inode * inode, struct file * filep, 101extern int cifs_ioctl (struct inode * inode, struct file * filep,
102 unsigned int command, unsigned long arg); 102 unsigned int command, unsigned long arg);
103#define CIFS_VERSION "1.48" 103#define CIFS_VERSION "1.49"
104#endif /* _CIFSFS_H */ 104#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index e4de8eba4780..23655de2f4a4 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -311,7 +311,7 @@ struct cifsFileInfo {
311 /* lock scope id (0 if none) */ 311 /* lock scope id (0 if none) */
312 struct file * pfile; /* needed for writepage */ 312 struct file * pfile; /* needed for writepage */
313 struct inode * pInode; /* needed for oplock break */ 313 struct inode * pInode; /* needed for oplock break */
314 struct semaphore lock_sem; 314 struct mutex lock_mutex;
315 struct list_head llist; /* list of byte range locks we have. */ 315 struct list_head llist; /* list of byte range locks we have. */
316 unsigned closePend:1; /* file is marked to close */ 316 unsigned closePend:1; /* file is marked to close */
317 unsigned invalidHandle:1; /* file closed via session abend */ 317 unsigned invalidHandle:1; /* file closed via session abend */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 4d8948e8762c..d619ca7d1416 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -1388,7 +1388,7 @@ struct smb_t2_rsp {
1388#define SMB_SET_POSIX_LOCK 0x208 1388#define SMB_SET_POSIX_LOCK 0x208
1389#define SMB_POSIX_OPEN 0x209 1389#define SMB_POSIX_OPEN 0x209
1390#define SMB_POSIX_UNLINK 0x20a 1390#define SMB_POSIX_UNLINK 0x20a
1391#define SMB_SET_FILE_UNIX_INFO2 1391#define SMB_SET_FILE_UNIX_INFO2 0x20b
1392#define SMB_SET_FILE_BASIC_INFO2 0x3ec 1392#define SMB_SET_FILE_BASIC_INFO2 0x3ec
1393#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo too */ 1393#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo too */
1394#define SMB_FILE_ALL_INFO2 0x3fa 1394#define SMB_FILE_ALL_INFO2 0x3fa
@@ -2109,22 +2109,40 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
2109 2109
2110/* end of POSIX ACL definitions */ 2110/* end of POSIX ACL definitions */
2111 2111
2112/* POSIX Open Flags */
2113#define SMB_O_RDONLY 0x1
2114#define SMB_O_WRONLY 0x2
2115#define SMB_O_RDWR 0x4
2116#define SMB_O_CREAT 0x10
2117#define SMB_O_EXCL 0x20
2118#define SMB_O_TRUNC 0x40
2119#define SMB_O_APPEND 0x80
2120#define SMB_O_SYNC 0x100
2121#define SMB_O_DIRECTORY 0x200
2122#define SMB_O_NOFOLLOW 0x400
2123#define SMB_O_DIRECT 0x800
2124
2112typedef struct { 2125typedef struct {
2113 __u32 OpenFlags; /* same as NT CreateX */ 2126 __le32 OpenFlags; /* same as NT CreateX */
2114 __u32 PosixOpenFlags; 2127 __le32 PosixOpenFlags;
2115 __u32 Mode; 2128 __le64 Permissions;
2116 __u16 Level; /* reply level requested (see QPathInfo levels) */ 2129 __le16 Level; /* reply level requested (see QPathInfo levels) */
2117 __u16 Pad; /* reserved - MBZ */
2118} __attribute__((packed)) OPEN_PSX_REQ; /* level 0x209 SetPathInfo data */ 2130} __attribute__((packed)) OPEN_PSX_REQ; /* level 0x209 SetPathInfo data */
2119 2131
2120typedef struct { 2132typedef struct {
2121 /* reply varies based on requested level */ 2133 __le16 OplockFlags;
2134 __u16 Fid;
2135 __le32 CreateAction;
2136 __le16 ReturnedLevel;
2137 __le16 Pad;
2138 /* struct following varies based on requested level */
2122} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */ 2139} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */
2123 2140
2124 2141
2125struct file_internal_info { 2142struct file_internal_info {
2126 __u64 UniqueId; /* inode number */ 2143 __u64 UniqueId; /* inode number */
2127} __attribute__((packed)); /* level 0x3ee */ 2144} __attribute__((packed)); /* level 0x3ee */
2145
2128struct file_mode_info { 2146struct file_mode_info {
2129 __le32 Mode; 2147 __le32 Mode;
2130} __attribute__((packed)); /* level 0x3f8 */ 2148} __attribute__((packed)); /* level 0x3f8 */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 32eb1acab630..5d163e2b6143 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsproto.h 2 * fs/cifs/cifsproto.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
@@ -244,6 +244,11 @@ extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
244 const int access_flags, const int omode, 244 const int access_flags, const int omode,
245 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 245 __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
246 const struct nls_table *nls_codepage, int remap); 246 const struct nls_table *nls_codepage, int remap);
247extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
248 u32 posix_flags, __u64 mode, __u16 * netfid,
249 FILE_UNIX_BASIC_INFO *pRetData,
250 __u32 *pOplock, const char *name,
251 const struct nls_table *nls_codepage, int remap);
247extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 252extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
248 const int smb_file_id); 253 const int smb_file_id);
249 254
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 48fc0c2ab0e5..14de58fa1437 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifssmb.c 2 * fs/cifs/cifssmb.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 * Contains the routines for constructing the SMB PDUs themselves 7 * Contains the routines for constructing the SMB PDUs themselves
@@ -24,8 +24,8 @@
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ 24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */ 25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */ 26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly different for reconnection purposes since we never want */ 27 /* treated slightly differently for reconnection purposes since we never */
28 /* to reuse a stale file handle and the caller knows the file handle */ 28 /* want to reuse a stale file handle and only the caller knows the file info */
29 29
30#include <linux/fs.h> 30#include <linux/fs.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
@@ -913,6 +913,130 @@ MkDirRetry:
913 return rc; 913 return rc;
914} 914}
915 915
916int
917CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
918 __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData,
919 __u32 *pOplock, const char *name,
920 const struct nls_table *nls_codepage, int remap)
921{
922 TRANSACTION2_SPI_REQ *pSMB = NULL;
923 TRANSACTION2_SPI_RSP *pSMBr = NULL;
924 int name_len;
925 int rc = 0;
926 int bytes_returned = 0;
927 char *data_offset;
928 __u16 params, param_offset, offset, byte_count, count;
929 OPEN_PSX_REQ * pdata;
930 OPEN_PSX_RSP * psx_rsp;
931
932 cFYI(1, ("In POSIX Create"));
933PsxCreat:
934 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
935 (void **) &pSMBr);
936 if (rc)
937 return rc;
938
939 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
940 name_len =
941 cifsConvertToUCS((__le16 *) pSMB->FileName, name,
942 PATH_MAX, nls_codepage, remap);
943 name_len++; /* trailing null */
944 name_len *= 2;
945 } else { /* BB improve the check for buffer overruns BB */
946 name_len = strnlen(name, PATH_MAX);
947 name_len++; /* trailing null */
948 strncpy(pSMB->FileName, name, name_len);
949 }
950
951 params = 6 + name_len;
952 count = sizeof(OPEN_PSX_REQ);
953 pSMB->MaxParameterCount = cpu_to_le16(2);
954 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
955 pSMB->MaxSetupCount = 0;
956 pSMB->Reserved = 0;
957 pSMB->Flags = 0;
958 pSMB->Timeout = 0;
959 pSMB->Reserved2 = 0;
960 param_offset = offsetof(struct smb_com_transaction2_spi_req,
961 InformationLevel) - 4;
962 offset = param_offset + params;
963 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
964 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
965 pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
966 pdata->Permissions = cpu_to_le64(mode);
967 pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
968 pdata->OpenFlags = cpu_to_le32(*pOplock);
969 pSMB->ParameterOffset = cpu_to_le16(param_offset);
970 pSMB->DataOffset = cpu_to_le16(offset);
971 pSMB->SetupCount = 1;
972 pSMB->Reserved3 = 0;
973 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
974 byte_count = 3 /* pad */ + params + count;
975
976 pSMB->DataCount = cpu_to_le16(count);
977 pSMB->ParameterCount = cpu_to_le16(params);
978 pSMB->TotalDataCount = pSMB->DataCount;
979 pSMB->TotalParameterCount = pSMB->ParameterCount;
980 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
981 pSMB->Reserved4 = 0;
982 pSMB->hdr.smb_buf_length += byte_count;
983 pSMB->ByteCount = cpu_to_le16(byte_count);
984 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
985 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
986 if (rc) {
987 cFYI(1, ("Posix create returned %d", rc));
988 goto psx_create_err;
989 }
990
991 cFYI(1,("copying inode info"));
992 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
993
994 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
995 rc = -EIO; /* bad smb */
996 goto psx_create_err;
997 }
998
999 /* copy return information to pRetData */
1000 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
1001 + le16_to_cpu(pSMBr->t2.DataOffset));
1002
1003 *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
1004 if(netfid)
1005 *netfid = psx_rsp->Fid; /* cifs fid stays in le */
1006 /* Let caller know file was created so we can set the mode. */
1007 /* Do we care about the CreateAction in any other cases? */
1008 if(cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
1009 *pOplock |= CIFS_CREATE_ACTION;
1010 /* check to make sure response data is there */
1011 if(psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
1012 pRetData->Type = -1; /* unknown */
1013#ifdef CONFIG_CIFS_DEBUG2
1014 cFYI(1,("unknown type"));
1015#endif
1016 } else {
1017 if(pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
1018 + sizeof(FILE_UNIX_BASIC_INFO)) {
1019 cERROR(1,("Open response data too small"));
1020 pRetData->Type = -1;
1021 goto psx_create_err;
1022 }
1023 memcpy((char *) pRetData,
1024 (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
1025 sizeof (FILE_UNIX_BASIC_INFO));
1026 }
1027
1028
1029psx_create_err:
1030 cifs_buf_release(pSMB);
1031
1032 cifs_stats_inc(&tcon->num_mkdirs);
1033
1034 if (rc == -EAGAIN)
1035 goto PsxCreat;
1036
1037 return rc;
1038}
1039
916static __u16 convert_disposition(int disposition) 1040static __u16 convert_disposition(int disposition)
917{ 1041{
918 __u16 ofun = 0; 1042 __u16 ofun = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 20ba7dcc9959..216fb625843f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -30,6 +30,7 @@
30#include <linux/mempool.h> 30#include <linux/mempool.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/completion.h> 32#include <linux/completion.h>
33#include <linux/kthread.h>
33#include <linux/pagevec.h> 34#include <linux/pagevec.h>
34#include <linux/freezer.h> 35#include <linux/freezer.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
@@ -74,6 +75,8 @@ struct smb_vol {
74 unsigned retry:1; 75 unsigned retry:1;
75 unsigned intr:1; 76 unsigned intr:1;
76 unsigned setuids:1; 77 unsigned setuids:1;
78 unsigned override_uid:1;
79 unsigned override_gid:1;
77 unsigned noperm:1; 80 unsigned noperm:1;
78 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ 81 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
79 unsigned cifs_acl:1; 82 unsigned cifs_acl:1;
@@ -120,7 +123,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
120 struct mid_q_entry * mid_entry; 123 struct mid_q_entry * mid_entry;
121 124
122 spin_lock(&GlobalMid_Lock); 125 spin_lock(&GlobalMid_Lock);
123 if(server->tcpStatus == CifsExiting) { 126 if( kthread_should_stop() ) {
124 /* the demux thread will exit normally 127 /* the demux thread will exit normally
125 next time through the loop */ 128 next time through the loop */
126 spin_unlock(&GlobalMid_Lock); 129 spin_unlock(&GlobalMid_Lock);
@@ -182,7 +185,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
182 spin_unlock(&GlobalMid_Lock); 185 spin_unlock(&GlobalMid_Lock);
183 up(&server->tcpSem); 186 up(&server->tcpSem);
184 187
185 while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) 188 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood))
186 { 189 {
187 try_to_freeze(); 190 try_to_freeze();
188 if(server->protocolType == IPV6) { 191 if(server->protocolType == IPV6) {
@@ -199,7 +202,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
199 } else { 202 } else {
200 atomic_inc(&tcpSesReconnectCount); 203 atomic_inc(&tcpSesReconnectCount);
201 spin_lock(&GlobalMid_Lock); 204 spin_lock(&GlobalMid_Lock);
202 if(server->tcpStatus != CifsExiting) 205 if( !kthread_should_stop() )
203 server->tcpStatus = CifsGood; 206 server->tcpStatus = CifsGood;
204 server->sequence_number = 0; 207 server->sequence_number = 0;
205 spin_unlock(&GlobalMid_Lock); 208 spin_unlock(&GlobalMid_Lock);
@@ -345,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
345 int isMultiRsp; 348 int isMultiRsp;
346 int reconnect; 349 int reconnect;
347 350
348 daemonize("cifsd");
349 allow_signal(SIGKILL); 351 allow_signal(SIGKILL);
350 current->flags |= PF_MEMALLOC; 352 current->flags |= PF_MEMALLOC;
351 server->tsk = current; /* save process info to wake at shutdown */ 353 server->tsk = current; /* save process info to wake at shutdown */
@@ -361,7 +363,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
361 GFP_KERNEL); 363 GFP_KERNEL);
362 } 364 }
363 365
364 while (server->tcpStatus != CifsExiting) { 366 while (!kthread_should_stop()) {
365 if (try_to_freeze()) 367 if (try_to_freeze())
366 continue; 368 continue;
367 if (bigbuf == NULL) { 369 if (bigbuf == NULL) {
@@ -400,7 +402,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
400 kernel_recvmsg(csocket, &smb_msg, 402 kernel_recvmsg(csocket, &smb_msg,
401 &iov, 1, 4, 0 /* BB see socket.h flags */); 403 &iov, 1, 4, 0 /* BB see socket.h flags */);
402 404
403 if (server->tcpStatus == CifsExiting) { 405 if ( kthread_should_stop() ) {
404 break; 406 break;
405 } else if (server->tcpStatus == CifsNeedReconnect) { 407 } else if (server->tcpStatus == CifsNeedReconnect) {
406 cFYI(1, ("Reconnect after server stopped responding")); 408 cFYI(1, ("Reconnect after server stopped responding"));
@@ -524,7 +526,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
524 total_read += length) { 526 total_read += length) {
525 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, 527 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
526 pdu_length - total_read, 0); 528 pdu_length - total_read, 0);
527 if((server->tcpStatus == CifsExiting) || 529 if( kthread_should_stop() ||
528 (length == -EINTR)) { 530 (length == -EINTR)) {
529 /* then will exit */ 531 /* then will exit */
530 reconnect = 2; 532 reconnect = 2;
@@ -757,7 +759,6 @@ multi_t2_fnd:
757 GFP_KERNEL); 759 GFP_KERNEL);
758 } 760 }
759 761
760 complete_and_exit(&cifsd_complete, 0);
761 return 0; 762 return 0;
762} 763}
763 764
@@ -973,7 +974,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
973 } 974 }
974 if ((temp_len = strnlen(value, 300)) < 300) { 975 if ((temp_len = strnlen(value, 300)) < 300) {
975 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 976 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
976 if(vol->UNC == NULL) 977 if (vol->UNC == NULL)
977 return 1; 978 return 1;
978 strcpy(vol->UNC,value); 979 strcpy(vol->UNC,value);
979 if (strncmp(vol->UNC, "//", 2) == 0) { 980 if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1010,12 +1011,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1010 return 1; /* needs_arg; */ 1011 return 1; /* needs_arg; */
1011 } 1012 }
1012 if ((temp_len = strnlen(value, 1024)) < 1024) { 1013 if ((temp_len = strnlen(value, 1024)) < 1024) {
1013 if(value[0] != '/') 1014 if (value[0] != '/')
1014 temp_len++; /* missing leading slash */ 1015 temp_len++; /* missing leading slash */
1015 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); 1016 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
1016 if(vol->prepath == NULL) 1017 if (vol->prepath == NULL)
1017 return 1; 1018 return 1;
1018 if(value[0] != '/') { 1019 if (value[0] != '/') {
1019 vol->prepath[0] = '/'; 1020 vol->prepath[0] = '/';
1020 strcpy(vol->prepath+1,value); 1021 strcpy(vol->prepath+1,value);
1021 } else 1022 } else
@@ -1031,7 +1032,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1031 return 1; /* needs_arg; */ 1032 return 1; /* needs_arg; */
1032 } 1033 }
1033 if (strnlen(value, 65) < 65) { 1034 if (strnlen(value, 65) < 65) {
1034 if(strnicmp(value,"default",7)) 1035 if (strnicmp(value,"default",7))
1035 vol->iocharset = value; 1036 vol->iocharset = value;
1036 /* if iocharset not set load_nls_default used by caller */ 1037 /* if iocharset not set load_nls_default used by caller */
1037 cFYI(1, ("iocharset set to %s",value)); 1038 cFYI(1, ("iocharset set to %s",value));
@@ -1043,11 +1044,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1043 if (value && *value) { 1044 if (value && *value) {
1044 vol->linux_uid = 1045 vol->linux_uid =
1045 simple_strtoul(value, &value, 0); 1046 simple_strtoul(value, &value, 0);
1047 vol->override_uid = 1;
1046 } 1048 }
1047 } else if (strnicmp(data, "gid", 3) == 0) { 1049 } else if (strnicmp(data, "gid", 3) == 0) {
1048 if (value && *value) { 1050 if (value && *value) {
1049 vol->linux_gid = 1051 vol->linux_gid =
1050 simple_strtoul(value, &value, 0); 1052 simple_strtoul(value, &value, 0);
1053 vol->override_gid = 1;
1051 } 1054 }
1052 } else if (strnicmp(data, "file_mode", 4) == 0) { 1055 } else if (strnicmp(data, "file_mode", 4) == 0) {
1053 if (value && *value) { 1056 if (value && *value) {
@@ -1102,7 +1105,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1102 } 1105 }
1103 /* The string has 16th byte zero still from 1106 /* The string has 16th byte zero still from
1104 set at top of the function */ 1107 set at top of the function */
1105 if((i==15) && (value[i] != 0)) 1108 if ((i==15) && (value[i] != 0))
1106 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); 1109 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1107 } 1110 }
1108 } else if (strnicmp(data, "servern", 7) == 0) { 1111 } else if (strnicmp(data, "servern", 7) == 0) {
@@ -1126,7 +1129,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1126 } 1129 }
1127 /* The string has 16th byte zero still from 1130 /* The string has 16th byte zero still from
1128 set at top of the function */ 1131 set at top of the function */
1129 if((i==15) && (value[i] != 0)) 1132 if ((i==15) && (value[i] != 0))
1130 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); 1133 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1131 } 1134 }
1132 } else if (strnicmp(data, "credentials", 4) == 0) { 1135 } else if (strnicmp(data, "credentials", 4) == 0) {
@@ -1233,13 +1236,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1233 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); 1236 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1234 } 1237 }
1235 if (vol->UNC == NULL) { 1238 if (vol->UNC == NULL) {
1236 if(devname == NULL) { 1239 if (devname == NULL) {
1237 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); 1240 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1238 return 1; 1241 return 1;
1239 } 1242 }
1240 if ((temp_len = strnlen(devname, 300)) < 300) { 1243 if ((temp_len = strnlen(devname, 300)) < 300) {
1241 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 1244 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1242 if(vol->UNC == NULL) 1245 if (vol->UNC == NULL)
1243 return 1; 1246 return 1;
1244 strcpy(vol->UNC,devname); 1247 strcpy(vol->UNC,devname);
1245 if (strncmp(vol->UNC, "//", 2) == 0) { 1248 if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1663,7 +1666,13 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon,
1663 CIFS_SB(sb)->mnt_cifs_flags |= 1666 CIFS_SB(sb)->mnt_cifs_flags |=
1664 CIFS_MOUNT_POSIX_PATHS; 1667 CIFS_MOUNT_POSIX_PATHS;
1665 } 1668 }
1666 1669
1670 /* We might be setting the path sep back to a different
1671 form if we are reconnecting and the server switched its
1672 posix path capability for this share */
1673 if(sb && (CIFS_SB(sb)->prepathlen > 0))
1674 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1675
1667 cFYI(1,("Negotiate caps 0x%x",(int)cap)); 1676 cFYI(1,("Negotiate caps 0x%x",(int)cap));
1668#ifdef CONFIG_CIFS_DEBUG2 1677#ifdef CONFIG_CIFS_DEBUG2
1669 if(cap & CIFS_UNIX_FCNTL_CAP) 1678 if(cap & CIFS_UNIX_FCNTL_CAP)
@@ -1712,12 +1721,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1712 return -EINVAL; 1721 return -EINVAL;
1713 } 1722 }
1714 1723
1715 if (volume_info.username) { 1724 if (volume_info.nullauth) {
1725 cFYI(1,("null user"));
1726 volume_info.username = NULL;
1727 } else if (volume_info.username) {
1716 /* BB fixme parse for domain name here */ 1728 /* BB fixme parse for domain name here */
1717 cFYI(1, ("Username: %s ", volume_info.username)); 1729 cFYI(1, ("Username: %s ", volume_info.username));
1718
1719 } else if (volume_info.nullauth) {
1720 cFYI(1,("null user"));
1721 } else { 1730 } else {
1722 cifserror("No username specified"); 1731 cifserror("No username specified");
1723 /* In userspace mount helper we can get user name from alternate 1732 /* In userspace mount helper we can get user name from alternate
@@ -1791,11 +1800,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1791 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, 1800 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1792 NULL /* no ipv6 addr */, 1801 NULL /* no ipv6 addr */,
1793 volume_info.username, &srvTcp); 1802 volume_info.username, &srvTcp);
1794 else if(address_type == AF_INET6) 1803 else if(address_type == AF_INET6) {
1804 cFYI(1,("looking for ipv6 address"));
1795 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, 1805 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1796 &sin_server6.sin6_addr, 1806 &sin_server6.sin6_addr,
1797 volume_info.username, &srvTcp); 1807 volume_info.username, &srvTcp);
1798 else { 1808 } else {
1799 kfree(volume_info.UNC); 1809 kfree(volume_info.UNC);
1800 kfree(volume_info.password); 1810 kfree(volume_info.password);
1801 kfree(volume_info.prepath); 1811 kfree(volume_info.prepath);
@@ -1807,17 +1817,23 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1807 if (srvTcp) { 1817 if (srvTcp) {
1808 cFYI(1, ("Existing tcp session with server found")); 1818 cFYI(1, ("Existing tcp session with server found"));
1809 } else { /* create socket */ 1819 } else { /* create socket */
1810 if(volume_info.port) 1820 if (volume_info.port)
1811 sin_server.sin_port = htons(volume_info.port); 1821 sin_server.sin_port = htons(volume_info.port);
1812 else 1822 else
1813 sin_server.sin_port = 0; 1823 sin_server.sin_port = 0;
1814 rc = ipv4_connect(&sin_server,&csocket, 1824 if (address_type == AF_INET6) {
1825 cFYI(1,("attempting ipv6 connect"));
1826 /* BB should we allow ipv6 on port 139? */
1827 /* other OS never observed in Wild doing 139 with v6 */
1828 rc = ipv6_connect(&sin_server6,&csocket);
1829 } else
1830 rc = ipv4_connect(&sin_server,&csocket,
1815 volume_info.source_rfc1001_name, 1831 volume_info.source_rfc1001_name,
1816 volume_info.target_rfc1001_name); 1832 volume_info.target_rfc1001_name);
1817 if (rc < 0) { 1833 if (rc < 0) {
1818 cERROR(1, 1834 cERROR(1,
1819 ("Error connecting to IPv4 socket. Aborting operation")); 1835 ("Error connecting to IPv4 socket. Aborting operation"));
1820 if(csocket != NULL) 1836 if (csocket != NULL)
1821 sock_release(csocket); 1837 sock_release(csocket);
1822 kfree(volume_info.UNC); 1838 kfree(volume_info.UNC);
1823 kfree(volume_info.password); 1839 kfree(volume_info.password);
@@ -1850,10 +1866,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1850 so no need to spinlock this init of tcpStatus */ 1866 so no need to spinlock this init of tcpStatus */
1851 srvTcp->tcpStatus = CifsNew; 1867 srvTcp->tcpStatus = CifsNew;
1852 init_MUTEX(&srvTcp->tcpSem); 1868 init_MUTEX(&srvTcp->tcpSem);
1853 rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, 1869 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1854 CLONE_FS | CLONE_FILES | CLONE_VM); 1870 if ( IS_ERR(srvTcp->tsk) ) {
1855 if(rc < 0) { 1871 rc = PTR_ERR(srvTcp->tsk);
1856 rc = -ENOMEM; 1872 cERROR(1,("error %d create cifsd thread", rc));
1873 srvTcp->tsk = NULL;
1857 sock_release(csocket); 1874 sock_release(csocket);
1858 kfree(volume_info.UNC); 1875 kfree(volume_info.UNC);
1859 kfree(volume_info.password); 1876 kfree(volume_info.password);
@@ -1896,7 +1913,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1896 int len = strlen(volume_info.domainname); 1913 int len = strlen(volume_info.domainname);
1897 pSesInfo->domainName = 1914 pSesInfo->domainName =
1898 kmalloc(len + 1, GFP_KERNEL); 1915 kmalloc(len + 1, GFP_KERNEL);
1899 if(pSesInfo->domainName) 1916 if (pSesInfo->domainName)
1900 strcpy(pSesInfo->domainName, 1917 strcpy(pSesInfo->domainName,
1901 volume_info.domainname); 1918 volume_info.domainname);
1902 } 1919 }
@@ -1906,7 +1923,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1906 /* BB FIXME need to pass vol->secFlgs BB */ 1923 /* BB FIXME need to pass vol->secFlgs BB */
1907 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1924 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1908 up(&pSesInfo->sesSem); 1925 up(&pSesInfo->sesSem);
1909 if(!rc) 1926 if (!rc)
1910 atomic_inc(&srvTcp->socketUseCount); 1927 atomic_inc(&srvTcp->socketUseCount);
1911 } else 1928 } else
1912 kfree(volume_info.password); 1929 kfree(volume_info.password);
@@ -1914,7 +1931,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1914 1931
1915 /* search for existing tcon to this server share */ 1932 /* search for existing tcon to this server share */
1916 if (!rc) { 1933 if (!rc) {
1917 if(volume_info.rsize > CIFSMaxBufSize) { 1934 if (volume_info.rsize > CIFSMaxBufSize) {
1918 cERROR(1,("rsize %d too large, using MaxBufSize", 1935 cERROR(1,("rsize %d too large, using MaxBufSize",
1919 volume_info.rsize)); 1936 volume_info.rsize));
1920 cifs_sb->rsize = CIFSMaxBufSize; 1937 cifs_sb->rsize = CIFSMaxBufSize;
@@ -1923,11 +1940,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1923 else /* default */ 1940 else /* default */
1924 cifs_sb->rsize = CIFSMaxBufSize; 1941 cifs_sb->rsize = CIFSMaxBufSize;
1925 1942
1926 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 1943 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1927 cERROR(1,("wsize %d too large using 4096 instead", 1944 cERROR(1,("wsize %d too large using 4096 instead",
1928 volume_info.wsize)); 1945 volume_info.wsize));
1929 cifs_sb->wsize = 4096; 1946 cifs_sb->wsize = 4096;
1930 } else if(volume_info.wsize) 1947 } else if (volume_info.wsize)
1931 cifs_sb->wsize = volume_info.wsize; 1948 cifs_sb->wsize = volume_info.wsize;
1932 else 1949 else
1933 cifs_sb->wsize = 1950 cifs_sb->wsize =
@@ -1940,14 +1957,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1940 conjunction with 52K kvec constraint on arch with 4K 1957 conjunction with 52K kvec constraint on arch with 4K
1941 page size */ 1958 page size */
1942 1959
1943 if(cifs_sb->rsize < 2048) { 1960 if (cifs_sb->rsize < 2048) {
1944 cifs_sb->rsize = 2048; 1961 cifs_sb->rsize = 2048;
1945 /* Windows ME may prefer this */ 1962 /* Windows ME may prefer this */
1946 cFYI(1,("readsize set to minimum 2048")); 1963 cFYI(1,("readsize set to minimum 2048"));
1947 } 1964 }
1948 /* calculate prepath */ 1965 /* calculate prepath */
1949 cifs_sb->prepath = volume_info.prepath; 1966 cifs_sb->prepath = volume_info.prepath;
1950 if(cifs_sb->prepath) { 1967 if (cifs_sb->prepath) {
1951 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 1968 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1952 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 1969 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1953 volume_info.prepath = NULL; 1970 volume_info.prepath = NULL;
@@ -1960,24 +1977,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1960 cFYI(1,("file mode: 0x%x dir mode: 0x%x", 1977 cFYI(1,("file mode: 0x%x dir mode: 0x%x",
1961 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 1978 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1962 1979
1963 if(volume_info.noperm) 1980 if (volume_info.noperm)
1964 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 1981 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1965 if(volume_info.setuids) 1982 if (volume_info.setuids)
1966 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; 1983 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1967 if(volume_info.server_ino) 1984 if (volume_info.server_ino)
1968 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; 1985 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1969 if(volume_info.remap) 1986 if (volume_info.remap)
1970 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; 1987 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1971 if(volume_info.no_xattr) 1988 if (volume_info.no_xattr)
1972 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 1989 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1973 if(volume_info.sfu_emul) 1990 if (volume_info.sfu_emul)
1974 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 1991 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1975 if(volume_info.nobrl) 1992 if (volume_info.nobrl)
1976 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 1993 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1977 if(volume_info.cifs_acl) 1994 if (volume_info.cifs_acl)
1978 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 1995 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1979 1996 if (volume_info.override_uid)
1980 if(volume_info.direct_io) { 1997 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
1998 if (volume_info.override_gid)
1999 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2000 if (volume_info.direct_io) {
1981 cFYI(1,("mounting share using direct i/o")); 2001 cFYI(1,("mounting share using direct i/o"));
1982 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2002 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1983 } 2003 }
@@ -2030,7 +2050,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2030 } 2050 }
2031 } 2051 }
2032 } 2052 }
2033 if(pSesInfo) { 2053 if (pSesInfo) {
2034 if (pSesInfo->capabilities & CAP_LARGE_FILES) { 2054 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2035 sb->s_maxbytes = (u64) 1 << 63; 2055 sb->s_maxbytes = (u64) 1 << 63;
2036 } else 2056 } else
@@ -2044,13 +2064,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2044 if (rc) { 2064 if (rc) {
2045 /* if session setup failed, use count is zero but 2065 /* if session setup failed, use count is zero but
2046 we still need to free cifsd thread */ 2066 we still need to free cifsd thread */
2047 if(atomic_read(&srvTcp->socketUseCount) == 0) { 2067 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2048 spin_lock(&GlobalMid_Lock); 2068 spin_lock(&GlobalMid_Lock);
2049 srvTcp->tcpStatus = CifsExiting; 2069 srvTcp->tcpStatus = CifsExiting;
2050 spin_unlock(&GlobalMid_Lock); 2070 spin_unlock(&GlobalMid_Lock);
2051 if(srvTcp->tsk) { 2071 if (srvTcp->tsk) {
2052 send_sig(SIGKILL,srvTcp->tsk,1); 2072 send_sig(SIGKILL,srvTcp->tsk,1);
2053 wait_for_completion(&cifsd_complete); 2073 kthread_stop(srvTcp->tsk);
2054 } 2074 }
2055 } 2075 }
2056 /* If find_unc succeeded then rc == 0 so we can not end */ 2076 /* If find_unc succeeded then rc == 0 so we can not end */
@@ -2063,10 +2083,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2063 int temp_rc; 2083 int temp_rc;
2064 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 2084 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2065 /* if the socketUseCount is now zero */ 2085 /* if the socketUseCount is now zero */
2066 if((temp_rc == -ESHUTDOWN) && 2086 if ((temp_rc == -ESHUTDOWN) &&
2067 (pSesInfo->server->tsk)) { 2087 (pSesInfo->server) && (pSesInfo->server->tsk)) {
2068 send_sig(SIGKILL,pSesInfo->server->tsk,1); 2088 send_sig(SIGKILL,pSesInfo->server->tsk,1);
2069 wait_for_completion(&cifsd_complete); 2089 kthread_stop(pSesInfo->server->tsk);
2070 } 2090 }
2071 } else 2091 } else
2072 cFYI(1, ("No session or bad tcon")); 2092 cFYI(1, ("No session or bad tcon"));
@@ -2127,7 +2147,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2127 __u16 count; 2147 __u16 count;
2128 2148
2129 cFYI(1, ("In sesssetup")); 2149 cFYI(1, ("In sesssetup"));
2130 if(ses == NULL) 2150 if (ses == NULL)
2131 return -EINVAL; 2151 return -EINVAL;
2132 user = ses->userName; 2152 user = ses->userName;
2133 domain = ses->domainName; 2153 domain = ses->domainName;
@@ -2182,7 +2202,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2182 *bcc_ptr = 0; 2202 *bcc_ptr = 0;
2183 bcc_ptr++; 2203 bcc_ptr++;
2184 } 2204 }
2185 if(user == NULL) 2205 if (user == NULL)
2186 bytes_returned = 0; /* skip null user */ 2206 bytes_returned = 0; /* skip null user */
2187 else 2207 else
2188 bytes_returned = 2208 bytes_returned =
@@ -2216,7 +2236,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2216 bcc_ptr += 2 * bytes_returned; 2236 bcc_ptr += 2 * bytes_returned;
2217 bcc_ptr += 2; 2237 bcc_ptr += 2;
2218 } else { 2238 } else {
2219 if(user != NULL) { 2239 if (user != NULL) {
2220 strncpy(bcc_ptr, user, 200); 2240 strncpy(bcc_ptr, user, 200);
2221 bcc_ptr += strnlen(user, 200); 2241 bcc_ptr += strnlen(user, 200);
2222 } 2242 }
@@ -3316,7 +3336,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3316 cFYI(1,("Waking up socket by sending it signal")); 3336 cFYI(1,("Waking up socket by sending it signal"));
3317 if(cifsd_task) { 3337 if(cifsd_task) {
3318 send_sig(SIGKILL,cifsd_task,1); 3338 send_sig(SIGKILL,cifsd_task,1);
3319 wait_for_completion(&cifsd_complete); 3339 kthread_stop(cifsd_task);
3320 } 3340 }
3321 rc = 0; 3341 rc = 0;
3322 } /* else - we have an smb session 3342 } /* else - we have an smb session
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 3fad638d26d3..e5210519ac4b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -274,7 +274,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
274 pCifsFile->invalidHandle = FALSE; 274 pCifsFile->invalidHandle = FALSE;
275 pCifsFile->closePend = FALSE; 275 pCifsFile->closePend = FALSE;
276 init_MUTEX(&pCifsFile->fh_sem); 276 init_MUTEX(&pCifsFile->fh_sem);
277 init_MUTEX(&pCifsFile->lock_sem); 277 mutex_init(&pCifsFile->lock_mutex);
278 INIT_LIST_HEAD(&pCifsFile->llist); 278 INIT_LIST_HEAD(&pCifsFile->llist);
279 atomic_set(&pCifsFile->wrtPending,0); 279 atomic_set(&pCifsFile->wrtPending,0);
280 280
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 2d3275bedb55..b570530f97bf 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -48,7 +48,7 @@ static inline struct cifsFileInfo *cifs_init_private(
48 private_data->netfid = netfid; 48 private_data->netfid = netfid;
49 private_data->pid = current->tgid; 49 private_data->pid = current->tgid;
50 init_MUTEX(&private_data->fh_sem); 50 init_MUTEX(&private_data->fh_sem);
51 init_MUTEX(&private_data->lock_sem); 51 mutex_init(&private_data->lock_mutex);
52 INIT_LIST_HEAD(&private_data->llist); 52 INIT_LIST_HEAD(&private_data->llist);
53 private_data->pfile = file; /* needed for writepage */ 53 private_data->pfile = file; /* needed for writepage */
54 private_data->pInode = inode; 54 private_data->pInode = inode;
@@ -338,8 +338,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile)
338 return rc; 338 return rc;
339} 339}
340 340
341static int cifs_reopen_file(struct inode *inode, struct file *file, 341static int cifs_reopen_file(struct file *file, int can_flush)
342 int can_flush)
343{ 342{
344 int rc = -EACCES; 343 int rc = -EACCES;
345 int xid, oplock; 344 int xid, oplock;
@@ -347,13 +346,12 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
347 struct cifsTconInfo *pTcon; 346 struct cifsTconInfo *pTcon;
348 struct cifsFileInfo *pCifsFile; 347 struct cifsFileInfo *pCifsFile;
349 struct cifsInodeInfo *pCifsInode; 348 struct cifsInodeInfo *pCifsInode;
349 struct inode * inode;
350 char *full_path = NULL; 350 char *full_path = NULL;
351 int desiredAccess; 351 int desiredAccess;
352 int disposition = FILE_OPEN; 352 int disposition = FILE_OPEN;
353 __u16 netfid; 353 __u16 netfid;
354 354
355 if (inode == NULL)
356 return -EBADF;
357 if (file->private_data) { 355 if (file->private_data) {
358 pCifsFile = (struct cifsFileInfo *)file->private_data; 356 pCifsFile = (struct cifsFileInfo *)file->private_data;
359 } else 357 } else
@@ -368,25 +366,37 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
368 } 366 }
369 367
370 if (file->f_path.dentry == NULL) { 368 if (file->f_path.dentry == NULL) {
371 up(&pCifsFile->fh_sem); 369 cERROR(1, ("no valid name if dentry freed"));
372 cFYI(1, ("failed file reopen, no valid name if dentry freed")); 370 dump_stack();
373 FreeXid(xid); 371 rc = -EBADF;
374 return -EBADF; 372 goto reopen_error_exit;
375 } 373 }
374
375 inode = file->f_path.dentry->d_inode;
376 if(inode == NULL) {
377 cERROR(1, ("inode not valid"));
378 dump_stack();
379 rc = -EBADF;
380 goto reopen_error_exit;
381 }
382
376 cifs_sb = CIFS_SB(inode->i_sb); 383 cifs_sb = CIFS_SB(inode->i_sb);
377 pTcon = cifs_sb->tcon; 384 pTcon = cifs_sb->tcon;
385
378/* can not grab rename sem here because various ops, including 386/* can not grab rename sem here because various ops, including
379 those that already have the rename sem can end up causing writepage 387 those that already have the rename sem can end up causing writepage
380 to get called and if the server was down that means we end up here, 388 to get called and if the server was down that means we end up here,
381 and we can never tell if the caller already has the rename_sem */ 389 and we can never tell if the caller already has the rename_sem */
382 full_path = build_path_from_dentry(file->f_path.dentry); 390 full_path = build_path_from_dentry(file->f_path.dentry);
383 if (full_path == NULL) { 391 if (full_path == NULL) {
392 rc = -ENOMEM;
393reopen_error_exit:
384 up(&pCifsFile->fh_sem); 394 up(&pCifsFile->fh_sem);
385 FreeXid(xid); 395 FreeXid(xid);
386 return -ENOMEM; 396 return rc;
387 } 397 }
388 398
389 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", 399 cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
390 inode, file->f_flags,full_path)); 400 inode, file->f_flags,full_path));
391 desiredAccess = cifs_convert_flags(file->f_flags); 401 desiredAccess = cifs_convert_flags(file->f_flags);
392 402
@@ -401,13 +411,6 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
401 and server version of file size can be stale. If we knew for sure 411 and server version of file size can be stale. If we knew for sure
402 that inode was not dirty locally we could do this */ 412 that inode was not dirty locally we could do this */
403 413
404/* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
405 if (buf == 0) {
406 up(&pCifsFile->fh_sem);
407 kfree(full_path);
408 FreeXid(xid);
409 return -ENOMEM;
410 } */
411 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, 414 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
412 CREATE_NOT_DIR, &netfid, &oplock, NULL, 415 CREATE_NOT_DIR, &netfid, &oplock, NULL,
413 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 416 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -508,12 +511,12 @@ int cifs_close(struct inode *inode, struct file *file)
508 511
509 /* Delete any outstanding lock records. 512 /* Delete any outstanding lock records.
510 We'll lose them when the file is closed anyway. */ 513 We'll lose them when the file is closed anyway. */
511 down(&pSMBFile->lock_sem); 514 mutex_lock(&pSMBFile->lock_mutex);
512 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { 515 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) {
513 list_del(&li->llist); 516 list_del(&li->llist);
514 kfree(li); 517 kfree(li);
515 } 518 }
516 up(&pSMBFile->lock_sem); 519 mutex_unlock(&pSMBFile->lock_mutex);
517 520
518 write_lock(&GlobalSMBSeslock); 521 write_lock(&GlobalSMBSeslock);
519 list_del(&pSMBFile->flist); 522 list_del(&pSMBFile->flist);
@@ -598,9 +601,9 @@ static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
598 li->offset = offset; 601 li->offset = offset;
599 li->length = len; 602 li->length = len;
600 li->type = lockType; 603 li->type = lockType;
601 down(&fid->lock_sem); 604 mutex_lock(&fid->lock_mutex);
602 list_add(&li->llist, &fid->llist); 605 list_add(&li->llist, &fid->llist);
603 up(&fid->lock_sem); 606 mutex_unlock(&fid->lock_mutex);
604 return 0; 607 return 0;
605} 608}
606 609
@@ -757,7 +760,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
757 struct cifsLockInfo *li, *tmp; 760 struct cifsLockInfo *li, *tmp;
758 761
759 rc = 0; 762 rc = 0;
760 down(&fid->lock_sem); 763 mutex_lock(&fid->lock_mutex);
761 list_for_each_entry_safe(li, tmp, &fid->llist, llist) { 764 list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
762 if (pfLock->fl_start <= li->offset && 765 if (pfLock->fl_start <= li->offset &&
763 length >= li->length) { 766 length >= li->length) {
@@ -771,7 +774,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
771 kfree(li); 774 kfree(li);
772 } 775 }
773 } 776 }
774 up(&fid->lock_sem); 777 mutex_unlock(&fid->lock_mutex);
775 } 778 }
776 } 779 }
777 780
@@ -792,12 +795,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
792 int xid, long_op; 795 int xid, long_op;
793 struct cifsFileInfo *open_file; 796 struct cifsFileInfo *open_file;
794 797
795 if (file->f_path.dentry == NULL)
796 return -EBADF;
797
798 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 798 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
799 if (cifs_sb == NULL)
800 return -EBADF;
801 799
802 pTcon = cifs_sb->tcon; 800 pTcon = cifs_sb->tcon;
803 801
@@ -807,14 +805,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
807 805
808 if (file->private_data == NULL) 806 if (file->private_data == NULL)
809 return -EBADF; 807 return -EBADF;
810 else 808 open_file = (struct cifsFileInfo *) file->private_data;
811 open_file = (struct cifsFileInfo *) file->private_data;
812 809
813 xid = GetXid(); 810 xid = GetXid();
814 if (file->f_path.dentry->d_inode == NULL) {
815 FreeXid(xid);
816 return -EBADF;
817 }
818 811
819 if (*poffset > file->f_path.dentry->d_inode->i_size) 812 if (*poffset > file->f_path.dentry->d_inode->i_size)
820 long_op = 2; /* writes past end of file can take a long time */ 813 long_op = 2; /* writes past end of file can take a long time */
@@ -841,17 +834,11 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
841 return -EBADF; 834 return -EBADF;
842 } 835 }
843 if (open_file->invalidHandle) { 836 if (open_file->invalidHandle) {
844 if ((file->f_path.dentry == NULL) ||
845 (file->f_path.dentry->d_inode == NULL)) {
846 FreeXid(xid);
847 return total_written;
848 }
849 /* we could deadlock if we called 837 /* we could deadlock if we called
850 filemap_fdatawait from here so tell 838 filemap_fdatawait from here so tell
851 reopen_file not to flush data to server 839 reopen_file not to flush data to server
852 now */ 840 now */
853 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 841 rc = cifs_reopen_file(file, FALSE);
854 file, FALSE);
855 if (rc != 0) 842 if (rc != 0)
856 break; 843 break;
857 } 844 }
@@ -908,12 +895,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
908 int xid, long_op; 895 int xid, long_op;
909 struct cifsFileInfo *open_file; 896 struct cifsFileInfo *open_file;
910 897
911 if (file->f_path.dentry == NULL)
912 return -EBADF;
913
914 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 898 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
915 if (cifs_sb == NULL)
916 return -EBADF;
917 899
918 pTcon = cifs_sb->tcon; 900 pTcon = cifs_sb->tcon;
919 901
@@ -922,14 +904,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
922 904
923 if (file->private_data == NULL) 905 if (file->private_data == NULL)
924 return -EBADF; 906 return -EBADF;
925 else 907 open_file = (struct cifsFileInfo *)file->private_data;
926 open_file = (struct cifsFileInfo *)file->private_data;
927 908
928 xid = GetXid(); 909 xid = GetXid();
929 if (file->f_path.dentry->d_inode == NULL) {
930 FreeXid(xid);
931 return -EBADF;
932 }
933 910
934 if (*poffset > file->f_path.dentry->d_inode->i_size) 911 if (*poffset > file->f_path.dentry->d_inode->i_size)
935 long_op = 2; /* writes past end of file can take a long time */ 912 long_op = 2; /* writes past end of file can take a long time */
@@ -957,17 +934,11 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
957 return -EBADF; 934 return -EBADF;
958 } 935 }
959 if (open_file->invalidHandle) { 936 if (open_file->invalidHandle) {
960 if ((file->f_path.dentry == NULL) ||
961 (file->f_path.dentry->d_inode == NULL)) {
962 FreeXid(xid);
963 return total_written;
964 }
965 /* we could deadlock if we called 937 /* we could deadlock if we called
966 filemap_fdatawait from here so tell 938 filemap_fdatawait from here so tell
967 reopen_file not to flush data to 939 reopen_file not to flush data to
968 server now */ 940 server now */
969 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 941 rc = cifs_reopen_file(file, FALSE);
970 file, FALSE);
971 if (rc != 0) 942 if (rc != 0)
972 break; 943 break;
973 } 944 }
@@ -1056,8 +1027,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1056 read_unlock(&GlobalSMBSeslock); 1027 read_unlock(&GlobalSMBSeslock);
1057 if((open_file->invalidHandle) && 1028 if((open_file->invalidHandle) &&
1058 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { 1029 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
1059 rc = cifs_reopen_file(&cifs_inode->vfs_inode, 1030 rc = cifs_reopen_file(open_file->pfile, FALSE);
1060 open_file->pfile, FALSE);
1061 /* if it fails, try another handle - might be */ 1031 /* if it fails, try another handle - might be */
1062 /* dangerous to hold up writepages with retry */ 1032 /* dangerous to hold up writepages with retry */
1063 if(rc) { 1033 if(rc) {
@@ -1404,32 +1374,6 @@ static int cifs_commit_write(struct file *file, struct page *page,
1404 spin_lock(&inode->i_lock); 1374 spin_lock(&inode->i_lock);
1405 if (position > inode->i_size) { 1375 if (position > inode->i_size) {
1406 i_size_write(inode, position); 1376 i_size_write(inode, position);
1407 /* if (file->private_data == NULL) {
1408 rc = -EBADF;
1409 } else {
1410 open_file = (struct cifsFileInfo *)file->private_data;
1411 cifs_sb = CIFS_SB(inode->i_sb);
1412 rc = -EAGAIN;
1413 while (rc == -EAGAIN) {
1414 if ((open_file->invalidHandle) &&
1415 (!open_file->closePend)) {
1416 rc = cifs_reopen_file(
1417 file->f_path.dentry->d_inode, file);
1418 if (rc != 0)
1419 break;
1420 }
1421 if (!open_file->closePend) {
1422 rc = CIFSSMBSetFileSize(xid,
1423 cifs_sb->tcon, position,
1424 open_file->netfid,
1425 open_file->pid, FALSE);
1426 } else {
1427 rc = -EBADF;
1428 break;
1429 }
1430 }
1431 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1432 } */
1433 } 1377 }
1434 spin_unlock(&inode->i_lock); 1378 spin_unlock(&inode->i_lock);
1435 if (!PageUptodate(page)) { 1379 if (!PageUptodate(page)) {
@@ -1573,8 +1517,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1573 int buf_type = CIFS_NO_BUFFER; 1517 int buf_type = CIFS_NO_BUFFER;
1574 if ((open_file->invalidHandle) && 1518 if ((open_file->invalidHandle) &&
1575 (!open_file->closePend)) { 1519 (!open_file->closePend)) {
1576 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1520 rc = cifs_reopen_file(file, TRUE);
1577 file, TRUE);
1578 if (rc != 0) 1521 if (rc != 0)
1579 break; 1522 break;
1580 } 1523 }
@@ -1660,8 +1603,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1660 while (rc == -EAGAIN) { 1603 while (rc == -EAGAIN) {
1661 if ((open_file->invalidHandle) && 1604 if ((open_file->invalidHandle) &&
1662 (!open_file->closePend)) { 1605 (!open_file->closePend)) {
1663 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1606 rc = cifs_reopen_file(file, TRUE);
1664 file, TRUE);
1665 if (rc != 0) 1607 if (rc != 0)
1666 break; 1608 break;
1667 } 1609 }
@@ -1817,8 +1759,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1817 while (rc == -EAGAIN) { 1759 while (rc == -EAGAIN) {
1818 if ((open_file->invalidHandle) && 1760 if ((open_file->invalidHandle) &&
1819 (!open_file->closePend)) { 1761 (!open_file->closePend)) {
1820 rc = cifs_reopen_file(file->f_path.dentry->d_inode, 1762 rc = cifs_reopen_file(file, TRUE);
1821 file, TRUE);
1822 if (rc != 0) 1763 if (rc != 0)
1823 break; 1764 break;
1824 } 1765 }
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f414526e476a..3e87dad3367c 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/inode.c 2 * fs/cifs/inode.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
@@ -90,7 +90,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
90 (*pinode)->i_ino = 90 (*pinode)->i_ino =
91 (unsigned long)findData.UniqueId; 91 (unsigned long)findData.UniqueId;
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);
@@ -139,8 +139,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
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 inode->i_uid = le64_to_cpu(findData.Uid); 142
143 inode->i_gid = le64_to_cpu(findData.Gid); 143 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
144 inode->i_uid = cifs_sb->mnt_uid;
145 else
146 inode->i_uid = le64_to_cpu(findData.Uid);
147
148 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
149 inode->i_gid = cifs_sb->mnt_gid;
150 else
151 inode->i_gid = le64_to_cpu(findData.Gid);
152
144 inode->i_nlink = le64_to_cpu(findData.Nlinks); 153 inode->i_nlink = le64_to_cpu(findData.Nlinks);
145 154
146 spin_lock(&inode->i_lock); 155 spin_lock(&inode->i_lock);
@@ -178,13 +187,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
178 &cifs_file_direct_nobrl_ops; 187 &cifs_file_direct_nobrl_ops;
179 else 188 else
180 inode->i_fop = &cifs_file_direct_ops; 189 inode->i_fop = &cifs_file_direct_ops;
181 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 190 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
182 inode->i_fop = &cifs_file_nobrl_ops; 191 inode->i_fop = &cifs_file_nobrl_ops;
183 else /* not direct, send byte range locks */ 192 else /* not direct, send byte range locks */
184 inode->i_fop = &cifs_file_ops; 193 inode->i_fop = &cifs_file_ops;
185 194
186 /* check if server can support readpages */ 195 /* check if server can support readpages */
187 if(pTcon->ses->server->maxBuf < 196 if (pTcon->ses->server->maxBuf <
188 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 197 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
189 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 198 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
190 else 199 else
@@ -220,7 +229,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
220 229
221 pbuf = buf; 230 pbuf = buf;
222 231
223 if(size == 0) { 232 if (size == 0) {
224 inode->i_mode |= S_IFIFO; 233 inode->i_mode |= S_IFIFO;
225 return 0; 234 return 0;
226 } else if (size < 8) { 235 } else if (size < 8) {
@@ -239,11 +248,11 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
239 netfid, 248 netfid,
240 24 /* length */, 0 /* offset */, 249 24 /* length */, 0 /* offset */,
241 &bytes_read, &pbuf, &buf_type); 250 &bytes_read, &pbuf, &buf_type);
242 if((rc == 0) && (bytes_read >= 8)) { 251 if ((rc == 0) && (bytes_read >= 8)) {
243 if(memcmp("IntxBLK", pbuf, 8) == 0) { 252 if (memcmp("IntxBLK", pbuf, 8) == 0) {
244 cFYI(1,("Block device")); 253 cFYI(1,("Block device"));
245 inode->i_mode |= S_IFBLK; 254 inode->i_mode |= S_IFBLK;
246 if(bytes_read == 24) { 255 if (bytes_read == 24) {
247 /* we have enough to decode dev num */ 256 /* we have enough to decode dev num */
248 __u64 mjr; /* major */ 257 __u64 mjr; /* major */
249 __u64 mnr; /* minor */ 258 __u64 mnr; /* minor */
@@ -251,10 +260,10 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
251 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 260 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
252 inode->i_rdev = MKDEV(mjr, mnr); 261 inode->i_rdev = MKDEV(mjr, mnr);
253 } 262 }
254 } else if(memcmp("IntxCHR", pbuf, 8) == 0) { 263 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
255 cFYI(1,("Char device")); 264 cFYI(1,("Char device"));
256 inode->i_mode |= S_IFCHR; 265 inode->i_mode |= S_IFCHR;
257 if(bytes_read == 24) { 266 if (bytes_read == 24) {
258 /* we have enough to decode dev num */ 267 /* we have enough to decode dev num */
259 __u64 mjr; /* major */ 268 __u64 mjr; /* major */
260 __u64 mnr; /* minor */ 269 __u64 mnr; /* minor */
@@ -262,7 +271,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
262 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 271 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
263 inode->i_rdev = MKDEV(mjr, mnr); 272 inode->i_rdev = MKDEV(mjr, mnr);
264 } 273 }
265 } else if(memcmp("IntxLNK", pbuf, 7) == 0) { 274 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
266 cFYI(1,("Symlink")); 275 cFYI(1,("Symlink"));
267 inode->i_mode |= S_IFLNK; 276 inode->i_mode |= S_IFLNK;
268 } else { 277 } else {
@@ -293,7 +302,7 @@ static int get_sfu_uid_mode(struct inode * inode,
293 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 302 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
294 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 303 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
295 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 304 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
296 if(rc < 0) 305 if (rc < 0)
297 return (int)rc; 306 return (int)rc;
298 else if (rc > 3) { 307 else if (rc > 3) {
299 mode = le32_to_cpu(*((__le32 *)ea_value)); 308 mode = le32_to_cpu(*((__le32 *)ea_value));
@@ -348,7 +357,7 @@ int cifs_get_inode_info(struct inode **pinode,
348 /* BB optimize code so we do not make the above call 357 /* BB optimize code so we do not make the above call
349 when server claims no NT SMB support and the above call 358 when server claims no NT SMB support and the above call
350 failed at least once - set flag in tcon or mount */ 359 failed at least once - set flag in tcon or mount */
351 if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 360 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
352 rc = SMBQueryInformation(xid, pTcon, search_path, 361 rc = SMBQueryInformation(xid, pTcon, search_path,
353 pfindData, cifs_sb->local_nls, 362 pfindData, cifs_sb->local_nls,
354 cifs_sb->mnt_cifs_flags & 363 cifs_sb->mnt_cifs_flags &
@@ -425,7 +434,7 @@ int cifs_get_inode_info(struct inode **pinode,
425 } else /* do we need cast or hash to ino? */ 434 } else /* do we need cast or hash to ino? */
426 (*pinode)->i_ino = inode_num; 435 (*pinode)->i_ino = inode_num;
427 } /* else ino incremented to unique num in new_inode*/ 436 } /* else ino incremented to unique num in new_inode*/
428 if(sb->s_flags & MS_NOATIME) 437 if (sb->s_flags & MS_NOATIME)
429 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 438 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
430 insert_inode_hash(*pinode); 439 insert_inode_hash(*pinode);
431 } 440 }
@@ -442,7 +451,7 @@ int cifs_get_inode_info(struct inode **pinode,
442 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 451 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
443 452
444 /* Linux can not store file creation time so ignore it */ 453 /* Linux can not store file creation time so ignore it */
445 if(pfindData->LastAccessTime) 454 if (pfindData->LastAccessTime)
446 inode->i_atime = cifs_NTtimeToUnix 455 inode->i_atime = cifs_NTtimeToUnix
447 (le64_to_cpu(pfindData->LastAccessTime)); 456 (le64_to_cpu(pfindData->LastAccessTime));
448 else /* do not need to use current_fs_time - time not stored */ 457 else /* do not need to use current_fs_time - time not stored */
@@ -452,7 +461,7 @@ int cifs_get_inode_info(struct inode **pinode,
452 inode->i_ctime = 461 inode->i_ctime =
453 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 462 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
454 cFYI(0, ("Attributes came in as 0x%x", attr)); 463 cFYI(0, ("Attributes came in as 0x%x", attr));
455 if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 464 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
456 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 465 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
457 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 466 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
458 } 467 }
@@ -521,8 +530,10 @@ int cifs_get_inode_info(struct inode **pinode,
521 530
522 /* BB fill in uid and gid here? with help from winbind? 531 /* BB fill in uid and gid here? with help from winbind?
523 or retrieve from NTFS stream extended attribute */ 532 or retrieve from NTFS stream extended attribute */
524 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 533 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
525 /* fill in uid, gid, mode from server ACL */ 534 /* fill in uid, gid, mode from server ACL */
535 /* BB FIXME this should also take into account the
536 * default uid specified on mount if present */
526 get_sfu_uid_mode(inode, search_path, cifs_sb, xid); 537 get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
527 } else if (atomic_read(&cifsInfo->inUse) == 0) { 538 } else if (atomic_read(&cifsInfo->inUse) == 0) {
528 inode->i_uid = cifs_sb->mnt_uid; 539 inode->i_uid = cifs_sb->mnt_uid;
@@ -541,12 +552,12 @@ int cifs_get_inode_info(struct inode **pinode,
541 &cifs_file_direct_nobrl_ops; 552 &cifs_file_direct_nobrl_ops;
542 else 553 else
543 inode->i_fop = &cifs_file_direct_ops; 554 inode->i_fop = &cifs_file_direct_ops;
544 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 555 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
545 inode->i_fop = &cifs_file_nobrl_ops; 556 inode->i_fop = &cifs_file_nobrl_ops;
546 else /* not direct, send byte range locks */ 557 else /* not direct, send byte range locks */
547 inode->i_fop = &cifs_file_ops; 558 inode->i_fop = &cifs_file_ops;
548 559
549 if(pTcon->ses->server->maxBuf < 560 if (pTcon->ses->server->maxBuf <
550 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 561 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
551 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 562 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
552 else 563 else
@@ -597,7 +608,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
597 608
598 xid = GetXid(); 609 xid = GetXid();
599 610
600 if(inode) 611 if (inode)
601 cifs_sb = CIFS_SB(inode->i_sb); 612 cifs_sb = CIFS_SB(inode->i_sb);
602 else 613 else
603 cifs_sb = CIFS_SB(direntry->d_sb); 614 cifs_sb = CIFS_SB(direntry->d_sb);
@@ -723,7 +734,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
723 when needed */ 734 when needed */
724 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 735 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
725 } 736 }
726 if(inode) { 737 if (inode) {
727 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 738 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
728 cifsInode = CIFS_I(inode); 739 cifsInode = CIFS_I(inode);
729 cifsInode->time = 0; /* force revalidate of dir as well */ 740 cifsInode->time = 0; /* force revalidate of dir as well */
@@ -734,6 +745,136 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
734 return rc; 745 return rc;
735} 746}
736 747
748static void posix_fill_in_inode(struct inode *tmp_inode,
749 FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode)
750{
751 loff_t local_size;
752 struct timespec local_mtime;
753
754 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
755 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
756
757 __u32 type = le32_to_cpu(pData->Type);
758 __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes);
759 __u64 end_of_file = le64_to_cpu(pData->EndOfFile);
760 cifsInfo->time = jiffies;
761 atomic_inc(&cifsInfo->inUse);
762
763 /* save mtime and size */
764 local_mtime = tmp_inode->i_mtime;
765 local_size = tmp_inode->i_size;
766
767 tmp_inode->i_atime =
768 cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime));
769 tmp_inode->i_mtime =
770 cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime));
771 tmp_inode->i_ctime =
772 cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange));
773
774 tmp_inode->i_mode = le64_to_cpu(pData->Permissions);
775 /* since we set the inode type below we need to mask off type
776 to avoid strange results if bits above were corrupt */
777 tmp_inode->i_mode &= ~S_IFMT;
778 if (type == UNIX_FILE) {
779 *pobject_type = DT_REG;
780 tmp_inode->i_mode |= S_IFREG;
781 } else if (type == UNIX_SYMLINK) {
782 *pobject_type = DT_LNK;
783 tmp_inode->i_mode |= S_IFLNK;
784 } else if (type == UNIX_DIR) {
785 *pobject_type = DT_DIR;
786 tmp_inode->i_mode |= S_IFDIR;
787 } else if (type == UNIX_CHARDEV) {
788 *pobject_type = DT_CHR;
789 tmp_inode->i_mode |= S_IFCHR;
790 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
791 le64_to_cpu(pData->DevMinor) & MINORMASK);
792 } else if (type == UNIX_BLOCKDEV) {
793 *pobject_type = DT_BLK;
794 tmp_inode->i_mode |= S_IFBLK;
795 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
796 le64_to_cpu(pData->DevMinor) & MINORMASK);
797 } else if (type == UNIX_FIFO) {
798 *pobject_type = DT_FIFO;
799 tmp_inode->i_mode |= S_IFIFO;
800 } else if (type == UNIX_SOCKET) {
801 *pobject_type = DT_SOCK;
802 tmp_inode->i_mode |= S_IFSOCK;
803 } else {
804 /* safest to just call it a file */
805 *pobject_type = DT_REG;
806 tmp_inode->i_mode |= S_IFREG;
807 cFYI(1,("unknown inode type %d",type));
808 }
809
810#ifdef CONFIG_CIFS_DEBUG2
811 cFYI(1,("object type: %d", type));
812#endif
813 tmp_inode->i_uid = le64_to_cpu(pData->Uid);
814 tmp_inode->i_gid = le64_to_cpu(pData->Gid);
815 tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks);
816
817 spin_lock(&tmp_inode->i_lock);
818 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
819 /* can not safely change the file size here if the
820 client is writing to it due to potential races */
821 i_size_write(tmp_inode, end_of_file);
822
823 /* 512 bytes (2**9) is the fake blocksize that must be used */
824 /* for this calculation, not the real blocksize */
825 tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
826 }
827 spin_unlock(&tmp_inode->i_lock);
828
829 if (S_ISREG(tmp_inode->i_mode)) {
830 cFYI(1, ("File inode"));
831 tmp_inode->i_op = &cifs_file_inode_ops;
832
833 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
834 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
835 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
836 else
837 tmp_inode->i_fop = &cifs_file_direct_ops;
838
839 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
840 tmp_inode->i_fop = &cifs_file_nobrl_ops;
841 else
842 tmp_inode->i_fop = &cifs_file_ops;
843
844 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
845 (cifs_sb->tcon->ses->server->maxBuf <
846 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
847 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
848 else
849 tmp_inode->i_data.a_ops = &cifs_addr_ops;
850
851 if(isNewInode)
852 return; /* No sense invalidating pages for new inode since we
853 have not started caching readahead file data yet */
854
855 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
856 (local_size == tmp_inode->i_size)) {
857 cFYI(1, ("inode exists but unchanged"));
858 } else {
859 /* file may have changed on server */
860 cFYI(1, ("invalidate inode, readdir detected change"));
861 invalidate_remote_inode(tmp_inode);
862 }
863 } else if (S_ISDIR(tmp_inode->i_mode)) {
864 cFYI(1, ("Directory inode"));
865 tmp_inode->i_op = &cifs_dir_inode_ops;
866 tmp_inode->i_fop = &cifs_dir_ops;
867 } else if (S_ISLNK(tmp_inode->i_mode)) {
868 cFYI(1, ("Symbolic Link inode"));
869 tmp_inode->i_op = &cifs_symlink_inode_ops;
870/* tmp_inode->i_fop = *//* do not need to set to anything */
871 } else {
872 cFYI(1, ("Special inode"));
873 init_special_inode(tmp_inode, tmp_inode->i_mode,
874 tmp_inode->i_rdev);
875 }
876}
877
737int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 878int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
738{ 879{
739 int rc = 0; 880 int rc = 0;
@@ -755,6 +896,71 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
755 FreeXid(xid); 896 FreeXid(xid);
756 return -ENOMEM; 897 return -ENOMEM;
757 } 898 }
899
900 if((pTcon->ses->capabilities & CAP_UNIX) &&
901 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
902 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
903 u32 oplock = 0;
904 FILE_UNIX_BASIC_INFO * pInfo =
905 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
906 if(pInfo == NULL) {
907 rc = -ENOMEM;
908 goto mkdir_out;
909 }
910
911 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
912 mode, NULL /* netfid */, pInfo, &oplock,
913 full_path, cifs_sb->local_nls,
914 cifs_sb->mnt_cifs_flags &
915 CIFS_MOUNT_MAP_SPECIAL_CHR);
916 if (rc) {
917 cFYI(1, ("posix mkdir returned 0x%x", rc));
918 d_drop(direntry);
919 } else {
920 int obj_type;
921 if (pInfo->Type == -1) /* no return info - go query */
922 goto mkdir_get_info;
923/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */
924 inc_nlink(inode);
925 if (pTcon->nocase)
926 direntry->d_op = &cifs_ci_dentry_ops;
927 else
928 direntry->d_op = &cifs_dentry_ops;
929
930 newinode = new_inode(inode->i_sb);
931 if (newinode == NULL)
932 goto mkdir_get_info;
933 /* Is an i_ino of zero legal? */
934 /* Are there sanity checks we can use to ensure that
935 the server is really filling in that field? */
936 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
937 newinode->i_ino =
938 (unsigned long)pInfo->UniqueId;
939 } /* note ino incremented to unique num in new_inode */
940 if(inode->i_sb->s_flags & MS_NOATIME)
941 newinode->i_flags |= S_NOATIME | S_NOCMTIME;
942 newinode->i_nlink = 2;
943
944 insert_inode_hash(newinode);
945 d_instantiate(direntry, newinode);
946
947 /* we already checked in POSIXCreate whether
948 frame was long enough */
949 posix_fill_in_inode(direntry->d_inode,
950 pInfo, &obj_type, 1 /* NewInode */);
951#ifdef CONFIG_CIFS_DEBUG2
952 cFYI(1,("instantiated dentry %p %s to inode %p",
953 direntry, direntry->d_name.name, newinode));
954
955 if(newinode->i_nlink != 2)
956 cFYI(1,("unexpected number of links %d",
957 newinode->i_nlink));
958#endif
959 }
960 kfree(pInfo);
961 goto mkdir_out;
962 }
963
758 /* BB add setting the equivalent of mode via CreateX w/ACLs */ 964 /* BB add setting the equivalent of mode via CreateX w/ACLs */
759 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, 965 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
760 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 966 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -762,6 +968,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
762 cFYI(1, ("cifs_mkdir returned 0x%x", rc)); 968 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
763 d_drop(direntry); 969 d_drop(direntry);
764 } else { 970 } else {
971mkdir_get_info:
765 inc_nlink(inode); 972 inc_nlink(inode);
766 if (pTcon->ses->capabilities & CAP_UNIX) 973 if (pTcon->ses->capabilities & CAP_UNIX)
767 rc = cifs_get_inode_info_unix(&newinode, full_path, 974 rc = cifs_get_inode_info_unix(&newinode, full_path,
@@ -775,8 +982,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
775 else 982 else
776 direntry->d_op = &cifs_dentry_ops; 983 direntry->d_op = &cifs_dentry_ops;
777 d_instantiate(direntry, newinode); 984 d_instantiate(direntry, newinode);
778 if (direntry->d_inode) 985 /* setting nlink not necessary except in cases where we
779 direntry->d_inode->i_nlink = 2; 986 * failed to get it from the server or was set bogus */
987 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
988 direntry->d_inode->i_nlink = 2;
780 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 989 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
781 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 990 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
782 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 991 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
@@ -812,6 +1021,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
812 } 1021 }
813 } 1022 }
814 } 1023 }
1024mkdir_out:
815 kfree(full_path); 1025 kfree(full_path);
816 FreeXid(xid); 1026 FreeXid(xid);
817 return rc; 1027 return rc;
@@ -1339,17 +1549,17 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1339 cpu_to_le32(cifsInode->cifsAttrs | 1549 cpu_to_le32(cifsInode->cifsAttrs |
1340 ATTR_READONLY); 1550 ATTR_READONLY);
1341 } 1551 }
1342 } else if ((mode & S_IWUGO) == S_IWUGO) { 1552 } else if (cifsInode->cifsAttrs & ATTR_READONLY) {
1343 if (cifsInode->cifsAttrs & ATTR_READONLY) { 1553 /* If file is readonly on server, we would
1344 set_dosattr = TRUE; 1554 not be able to write to it - so if any write
1345 time_buf.Attributes = 1555 bit is enabled for user or group or other we
1346 cpu_to_le32(cifsInode->cifsAttrs & 1556 need to at least try to remove r/o dos attr */
1347 (~ATTR_READONLY)); 1557 set_dosattr = TRUE;
1348 /* Windows ignores set to zero */ 1558 time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1349 if(time_buf.Attributes == 0) 1559 (~ATTR_READONLY));
1350 time_buf.Attributes |= 1560 /* Windows ignores set to zero */
1351 cpu_to_le32(ATTR_NORMAL); 1561 if(time_buf.Attributes == 0)
1352 } 1562 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1353 } 1563 }
1354 /* BB to be implemented - 1564 /* BB to be implemented -
1355 via Windows security descriptors or streams */ 1565 via Windows security descriptors or streams */
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 992e80edc720..53e304d59544 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -30,6 +30,9 @@
30#include <linux/fs.h> 30#include <linux/fs.h>
31#include <asm/div64.h> 31#include <asm/div64.h>
32#include <asm/byteorder.h> 32#include <asm/byteorder.h>
33#ifdef CONFIG_CIFS_EXPERIMENTAL
34#include <linux/inet.h>
35#endif
33#include "cifsfs.h" 36#include "cifsfs.h"
34#include "cifspdu.h" 37#include "cifspdu.h"
35#include "cifsglob.h" 38#include "cifsglob.h"
@@ -129,11 +132,27 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
129/* Convert string containing dotted ip address to binary form */ 132/* Convert string containing dotted ip address to binary form */
130/* returns 0 if invalid address */ 133/* returns 0 if invalid address */
131 134
132/* BB add address family, change rc to status flag and return union or for ipv6 */
133/* will need parent to call something like inet_pton to convert ipv6 address BB */
134int 135int
135cifs_inet_pton(int address_family, char *cp,void *dst) 136cifs_inet_pton(int address_family, char *cp,void *dst)
136{ 137{
138#ifdef CONFIG_CIFS_EXPERIMENTAL
139 int ret = 0;
140
141 /* calculate length by finding first slash or NULL */
142 /* BB Should we convert '/' slash to '\' here since it seems already done
143 before this */
144 if( address_family == AF_INET ){
145 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
146 } else if( address_family == AF_INET6 ){
147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
148 }
149#ifdef CONFIG_CIFS_DEBUG2
150 cFYI(1,("address conversion returned %d for %s", ret, cp));
151#endif
152 if (ret > 0)
153 ret = 1;
154 return ret;
155#else
137 int value; 156 int value;
138 int digit; 157 int digit;
139 int i; 158 int i;
@@ -192,6 +211,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst)
192 211
193 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value); 212 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
194 return 1; /* success */ 213 return 1; /* success */
214#endif /* EXPERIMENTAL */
195} 215}
196 216
197/***************************************************************************** 217/*****************************************************************************
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 2a374d5215ab..b5364f90d551 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -37,19 +37,19 @@ static void dump_cifs_file_struct(struct file *file, char *label)
37{ 37{
38 struct cifsFileInfo * cf; 38 struct cifsFileInfo * cf;
39 39
40 if(file) { 40 if (file) {
41 cf = file->private_data; 41 cf = file->private_data;
42 if(cf == NULL) { 42 if (cf == NULL) {
43 cFYI(1,("empty cifs private file data")); 43 cFYI(1,("empty cifs private file data"));
44 return; 44 return;
45 } 45 }
46 if(cf->invalidHandle) { 46 if (cf->invalidHandle) {
47 cFYI(1,("invalid handle")); 47 cFYI(1,("invalid handle"));
48 } 48 }
49 if(cf->srch_inf.endOfSearch) { 49 if (cf->srch_inf.endOfSearch) {
50 cFYI(1,("end of search")); 50 cFYI(1,("end of search"));
51 } 51 }
52 if(cf->srch_inf.emptyDir) { 52 if (cf->srch_inf.emptyDir) {
53 cFYI(1,("empty dir")); 53 cFYI(1,("empty dir"));
54 } 54 }
55 55
@@ -77,17 +77,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
77 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); 77 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode));
78 *ptmp_inode = tmp_dentry->d_inode; 78 *ptmp_inode = tmp_dentry->d_inode;
79/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ 79/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
80 if(*ptmp_inode == NULL) { 80 if (*ptmp_inode == NULL) {
81 *ptmp_inode = new_inode(file->f_path.dentry->d_sb); 81 *ptmp_inode = new_inode(file->f_path.dentry->d_sb);
82 if(*ptmp_inode == NULL) 82 if (*ptmp_inode == NULL)
83 return rc; 83 return rc;
84 rc = 1; 84 rc = 1;
85 } 85 }
86 if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 86 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
87 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 87 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
88 } else { 88 } else {
89 tmp_dentry = d_alloc(file->f_path.dentry, qstring); 89 tmp_dentry = d_alloc(file->f_path.dentry, qstring);
90 if(tmp_dentry == NULL) { 90 if (tmp_dentry == NULL) {
91 cERROR(1,("Failed allocating dentry")); 91 cERROR(1,("Failed allocating dentry"));
92 *ptmp_inode = NULL; 92 *ptmp_inode = NULL;
93 return rc; 93 return rc;
@@ -98,9 +98,9 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
98 tmp_dentry->d_op = &cifs_ci_dentry_ops; 98 tmp_dentry->d_op = &cifs_ci_dentry_ops;
99 else 99 else
100 tmp_dentry->d_op = &cifs_dentry_ops; 100 tmp_dentry->d_op = &cifs_dentry_ops;
101 if(*ptmp_inode == NULL) 101 if (*ptmp_inode == NULL)
102 return rc; 102 return rc;
103 if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 103 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
104 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 104 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
105 rc = 2; 105 rc = 2;
106 } 106 }
@@ -112,7 +112,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
112 112
113static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) 113static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
114{ 114{
115 if((tcon) && (tcon->ses) && (tcon->ses->server)) { 115 if ((tcon) && (tcon->ses) && (tcon->ses->server)) {
116 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; 116 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
117 inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; 117 inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
118 inode->i_atime.tv_sec += tcon->ses->server->timeAdj; 118 inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
@@ -137,7 +137,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
137 local_mtime = tmp_inode->i_mtime; 137 local_mtime = tmp_inode->i_mtime;
138 local_size = tmp_inode->i_size; 138 local_size = tmp_inode->i_size;
139 139
140 if(new_buf_type) { 140 if (new_buf_type) {
141 FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; 141 FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf;
142 142
143 attr = le32_to_cpu(pfindData->ExtFileAttributes); 143 attr = le32_to_cpu(pfindData->ExtFileAttributes);
@@ -193,7 +193,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
193 if (attr & ATTR_DIRECTORY) { 193 if (attr & ATTR_DIRECTORY) {
194 *pobject_type = DT_DIR; 194 *pobject_type = DT_DIR;
195 /* override default perms since we do not lock dirs */ 195 /* override default perms since we do not lock dirs */
196 if(atomic_read(&cifsInfo->inUse) == 0) { 196 if (atomic_read(&cifsInfo->inUse) == 0) {
197 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 197 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
198 } 198 }
199 tmp_inode->i_mode |= S_IFDIR; 199 tmp_inode->i_mode |= S_IFDIR;
@@ -250,25 +250,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
250 if (S_ISREG(tmp_inode->i_mode)) { 250 if (S_ISREG(tmp_inode->i_mode)) {
251 cFYI(1, ("File inode")); 251 cFYI(1, ("File inode"));
252 tmp_inode->i_op = &cifs_file_inode_ops; 252 tmp_inode->i_op = &cifs_file_inode_ops;
253 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 253 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
254 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 254 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
255 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 255 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
256 else 256 else
257 tmp_inode->i_fop = &cifs_file_direct_ops; 257 tmp_inode->i_fop = &cifs_file_direct_ops;
258 258
259 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 259 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
260 tmp_inode->i_fop = &cifs_file_nobrl_ops; 260 tmp_inode->i_fop = &cifs_file_nobrl_ops;
261 else 261 else
262 tmp_inode->i_fop = &cifs_file_ops; 262 tmp_inode->i_fop = &cifs_file_ops;
263 263
264 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 264 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
265 (cifs_sb->tcon->ses->server->maxBuf < 265 (cifs_sb->tcon->ses->server->maxBuf <
266 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 266 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
267 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 267 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
268 else 268 else
269 tmp_inode->i_data.a_ops = &cifs_addr_ops; 269 tmp_inode->i_data.a_ops = &cifs_addr_ops;
270 270
271 if(isNewInode) 271 if (isNewInode)
272 return; /* No sense invalidating pages for new inode 272 return; /* No sense invalidating pages for new inode
273 since have not started caching readahead file 273 since have not started caching readahead file
274 data yet */ 274 data yet */
@@ -357,8 +357,14 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
357 cFYI(1,("unknown inode type %d",type)); 357 cFYI(1,("unknown inode type %d",type));
358 } 358 }
359 359
360 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 360 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
361 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 361 tmp_inode->i_uid = cifs_sb->mnt_uid;
362 else
363 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
365 tmp_inode->i_gid = cifs_sb->mnt_gid;
366 else
367 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
362 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 368 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
363 369
364 spin_lock(&tmp_inode->i_lock); 370 spin_lock(&tmp_inode->i_lock);
@@ -377,25 +383,24 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
377 cFYI(1, ("File inode")); 383 cFYI(1, ("File inode"));
378 tmp_inode->i_op = &cifs_file_inode_ops; 384 tmp_inode->i_op = &cifs_file_inode_ops;
379 385
380 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 386 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
381 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 387 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
382 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 388 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
383 else 389 else
384 tmp_inode->i_fop = &cifs_file_direct_ops; 390 tmp_inode->i_fop = &cifs_file_direct_ops;
385 391 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
386 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
387 tmp_inode->i_fop = &cifs_file_nobrl_ops; 392 tmp_inode->i_fop = &cifs_file_nobrl_ops;
388 else 393 else
389 tmp_inode->i_fop = &cifs_file_ops; 394 tmp_inode->i_fop = &cifs_file_ops;
390 395
391 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 396 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
392 (cifs_sb->tcon->ses->server->maxBuf < 397 (cifs_sb->tcon->ses->server->maxBuf <
393 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 398 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
394 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 399 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
395 else 400 else
396 tmp_inode->i_data.a_ops = &cifs_addr_ops; 401 tmp_inode->i_data.a_ops = &cifs_addr_ops;
397 402
398 if(isNewInode) 403 if (isNewInode)
399 return; /* No sense invalidating pages for new inode since we 404 return; /* No sense invalidating pages for new inode since we
400 have not started caching readahead file data yet */ 405 have not started caching readahead file data yet */
401 406
@@ -430,34 +435,28 @@ static int initiate_cifs_search(const int xid, struct file *file)
430 struct cifs_sb_info *cifs_sb; 435 struct cifs_sb_info *cifs_sb;
431 struct cifsTconInfo *pTcon; 436 struct cifsTconInfo *pTcon;
432 437
433 if(file->private_data == NULL) { 438 if (file->private_data == NULL) {
434 file->private_data = 439 file->private_data =
435 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); 440 kzalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
436 } 441 }
437 442
438 if(file->private_data == NULL) { 443 if (file->private_data == NULL)
439 return -ENOMEM; 444 return -ENOMEM;
440 } else {
441 memset(file->private_data,0,sizeof(struct cifsFileInfo));
442 }
443 cifsFile = file->private_data; 445 cifsFile = file->private_data;
444 cifsFile->invalidHandle = TRUE; 446 cifsFile->invalidHandle = TRUE;
445 cifsFile->srch_inf.endOfSearch = FALSE; 447 cifsFile->srch_inf.endOfSearch = FALSE;
446 448
447 if(file->f_path.dentry == NULL)
448 return -ENOENT;
449
450 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 449 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
451 if(cifs_sb == NULL) 450 if (cifs_sb == NULL)
452 return -EINVAL; 451 return -EINVAL;
453 452
454 pTcon = cifs_sb->tcon; 453 pTcon = cifs_sb->tcon;
455 if(pTcon == NULL) 454 if (pTcon == NULL)
456 return -EINVAL; 455 return -EINVAL;
457 456
458 full_path = build_path_from_dentry(file->f_path.dentry); 457 full_path = build_path_from_dentry(file->f_path.dentry);
459 458
460 if(full_path == NULL) { 459 if (full_path == NULL) {
461 return -ENOMEM; 460 return -ENOMEM;
462 } 461 }
463 462
@@ -480,9 +479,9 @@ ffirst_retry:
480 &cifsFile->netfid, &cifsFile->srch_inf, 479 &cifsFile->netfid, &cifsFile->srch_inf,
481 cifs_sb->mnt_cifs_flags & 480 cifs_sb->mnt_cifs_flags &
482 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 481 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
483 if(rc == 0) 482 if (rc == 0)
484 cifsFile->invalidHandle = FALSE; 483 cifsFile->invalidHandle = FALSE;
485 if((rc == -EOPNOTSUPP) && 484 if ((rc == -EOPNOTSUPP) &&
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 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
488 goto ffirst_retry; 487 goto ffirst_retry;
@@ -498,7 +497,7 @@ static int cifs_unicode_bytelen(char *str)
498 __le16 * ustr = (__le16 *)str; 497 __le16 * ustr = (__le16 *)str;
499 498
500 for(len=0;len <= PATH_MAX;len++) { 499 for(len=0;len <= PATH_MAX;len++) {
501 if(ustr[len] == 0) 500 if (ustr[len] == 0)
502 return len << 1; 501 return len << 1;
503 } 502 }
504 cFYI(1,("Unicode string longer than PATH_MAX found")); 503 cFYI(1,("Unicode string longer than PATH_MAX found"));
@@ -510,7 +509,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
510 char * new_entry; 509 char * new_entry;
511 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 510 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
512 511
513 if(level == SMB_FIND_FILE_INFO_STANDARD) { 512 if (level == SMB_FIND_FILE_INFO_STANDARD) {
514 FIND_FILE_STANDARD_INFO * pfData; 513 FIND_FILE_STANDARD_INFO * pfData;
515 pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; 514 pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;
516 515
@@ -520,12 +519,12 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
520 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 519 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
521 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 520 cFYI(1,("new entry %p old entry %p",new_entry,old_entry));
522 /* validate that new_entry is not past end of SMB */ 521 /* validate that new_entry is not past end of SMB */
523 if(new_entry >= end_of_smb) { 522 if (new_entry >= end_of_smb) {
524 cERROR(1, 523 cERROR(1,
525 ("search entry %p began after end of SMB %p old entry %p", 524 ("search entry %p began after end of SMB %p old entry %p",
526 new_entry, end_of_smb, old_entry)); 525 new_entry, end_of_smb, old_entry));
527 return NULL; 526 return NULL;
528 } else if(((level == SMB_FIND_FILE_INFO_STANDARD) && 527 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
529 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || 528 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) ||
530 ((level != SMB_FIND_FILE_INFO_STANDARD) && 529 ((level != SMB_FIND_FILE_INFO_STANDARD) &&
531 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { 530 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
@@ -546,39 +545,39 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
546 char * filename = NULL; 545 char * filename = NULL;
547 int len = 0; 546 int len = 0;
548 547
549 if(cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 548 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
550 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 549 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
551 filename = &pFindData->FileName[0]; 550 filename = &pFindData->FileName[0];
552 if(cfile->srch_inf.unicode) { 551 if (cfile->srch_inf.unicode) {
553 len = cifs_unicode_bytelen(filename); 552 len = cifs_unicode_bytelen(filename);
554 } else { 553 } else {
555 /* BB should we make this strnlen of PATH_MAX? */ 554 /* BB should we make this strnlen of PATH_MAX? */
556 len = strnlen(filename, 5); 555 len = strnlen(filename, 5);
557 } 556 }
558 } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { 557 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
559 FILE_DIRECTORY_INFO * pFindData = 558 FILE_DIRECTORY_INFO * pFindData =
560 (FILE_DIRECTORY_INFO *)current_entry; 559 (FILE_DIRECTORY_INFO *)current_entry;
561 filename = &pFindData->FileName[0]; 560 filename = &pFindData->FileName[0];
562 len = le32_to_cpu(pFindData->FileNameLength); 561 len = le32_to_cpu(pFindData->FileNameLength);
563 } else if(cfile->srch_inf.info_level == 562 } else if (cfile->srch_inf.info_level ==
564 SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 563 SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
565 FILE_FULL_DIRECTORY_INFO * pFindData = 564 FILE_FULL_DIRECTORY_INFO * pFindData =
566 (FILE_FULL_DIRECTORY_INFO *)current_entry; 565 (FILE_FULL_DIRECTORY_INFO *)current_entry;
567 filename = &pFindData->FileName[0]; 566 filename = &pFindData->FileName[0];
568 len = le32_to_cpu(pFindData->FileNameLength); 567 len = le32_to_cpu(pFindData->FileNameLength);
569 } else if(cfile->srch_inf.info_level == 568 } else if (cfile->srch_inf.info_level ==
570 SMB_FIND_FILE_ID_FULL_DIR_INFO) { 569 SMB_FIND_FILE_ID_FULL_DIR_INFO) {
571 SEARCH_ID_FULL_DIR_INFO * pFindData = 570 SEARCH_ID_FULL_DIR_INFO * pFindData =
572 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 571 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
573 filename = &pFindData->FileName[0]; 572 filename = &pFindData->FileName[0];
574 len = le32_to_cpu(pFindData->FileNameLength); 573 len = le32_to_cpu(pFindData->FileNameLength);
575 } else if(cfile->srch_inf.info_level == 574 } else if (cfile->srch_inf.info_level ==
576 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 575 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
577 FILE_BOTH_DIRECTORY_INFO * pFindData = 576 FILE_BOTH_DIRECTORY_INFO * pFindData =
578 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 577 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
579 filename = &pFindData->FileName[0]; 578 filename = &pFindData->FileName[0];
580 len = le32_to_cpu(pFindData->FileNameLength); 579 len = le32_to_cpu(pFindData->FileNameLength);
581 } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { 580 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
582 FIND_FILE_STANDARD_INFO * pFindData = 581 FIND_FILE_STANDARD_INFO * pFindData =
583 (FIND_FILE_STANDARD_INFO *)current_entry; 582 (FIND_FILE_STANDARD_INFO *)current_entry;
584 filename = &pFindData->FileName[0]; 583 filename = &pFindData->FileName[0];
@@ -587,25 +586,25 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
587 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); 586 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level));
588 } 587 }
589 588
590 if(filename) { 589 if (filename) {
591 if(cfile->srch_inf.unicode) { 590 if (cfile->srch_inf.unicode) {
592 __le16 *ufilename = (__le16 *)filename; 591 __le16 *ufilename = (__le16 *)filename;
593 if(len == 2) { 592 if (len == 2) {
594 /* check for . */ 593 /* check for . */
595 if(ufilename[0] == UNICODE_DOT) 594 if (ufilename[0] == UNICODE_DOT)
596 rc = 1; 595 rc = 1;
597 } else if(len == 4) { 596 } else if (len == 4) {
598 /* check for .. */ 597 /* check for .. */
599 if((ufilename[0] == UNICODE_DOT) 598 if ((ufilename[0] == UNICODE_DOT)
600 &&(ufilename[1] == UNICODE_DOT)) 599 &&(ufilename[1] == UNICODE_DOT))
601 rc = 2; 600 rc = 2;
602 } 601 }
603 } else /* ASCII */ { 602 } else /* ASCII */ {
604 if(len == 1) { 603 if (len == 1) {
605 if(filename[0] == '.') 604 if (filename[0] == '.')
606 rc = 1; 605 rc = 1;
607 } else if(len == 2) { 606 } else if (len == 2) {
608 if((filename[0] == '.') && (filename[1] == '.')) 607 if((filename[0] == '.') && (filename[1] == '.'))
609 rc = 2; 608 rc = 2;
610 } 609 }
611 } 610 }
@@ -618,20 +617,10 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
618 whether we can use the cached search results from the previous search */ 617 whether we can use the cached search results from the previous search */
619static int is_dir_changed(struct file * file) 618static int is_dir_changed(struct file * file)
620{ 619{
621 struct inode * inode; 620 struct inode *inode = file->f_path.dentry->d_inode;
622 struct cifsInodeInfo *cifsInfo; 621 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
623 622
624 if(file->f_path.dentry == NULL) 623 if (cifsInfo->time == 0)
625 return 0;
626
627 inode = file->f_path.dentry->d_inode;
628
629 if(inode == NULL)
630 return 0;
631
632 cifsInfo = CIFS_I(inode);
633
634 if(cifsInfo->time == 0)
635 return 1; /* directory was changed, perhaps due to unlink */ 624 return 1; /* directory was changed, perhaps due to unlink */
636 else 625 else
637 return 0; 626 return 0;
@@ -654,7 +643,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
654 struct cifsFileInfo * cifsFile = file->private_data; 643 struct cifsFileInfo * cifsFile = file->private_data;
655 /* check if index in the buffer */ 644 /* check if index in the buffer */
656 645
657 if((cifsFile == NULL) || (ppCurrentEntry == NULL) || 646 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
658 (num_to_ret == NULL)) 647 (num_to_ret == NULL))
659 return -ENOENT; 648 return -ENOENT;
660 649
@@ -672,7 +661,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
672#ifdef CONFIG_CIFS_DEBUG2 661#ifdef CONFIG_CIFS_DEBUG2
673 dump_cifs_file_struct(file, "In fce "); 662 dump_cifs_file_struct(file, "In fce ");
674#endif 663#endif
675 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 664 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
676 is_dir_changed(file)) || 665 is_dir_changed(file)) ||
677 (index_to_find < first_entry_in_buffer)) { 666 (index_to_find < first_entry_in_buffer)) {
678 /* close and restart search */ 667 /* close and restart search */
@@ -681,9 +670,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
681 CIFSFindClose(xid, pTcon, cifsFile->netfid); 670 CIFSFindClose(xid, pTcon, cifsFile->netfid);
682 kfree(cifsFile->search_resume_name); 671 kfree(cifsFile->search_resume_name);
683 cifsFile->search_resume_name = NULL; 672 cifsFile->search_resume_name = NULL;
684 if(cifsFile->srch_inf.ntwrk_buf_start) { 673 if (cifsFile->srch_inf.ntwrk_buf_start) {
685 cFYI(1,("freeing SMB ff cache buf on search rewind")); 674 cFYI(1,("freeing SMB ff cache buf on search rewind"));
686 if(cifsFile->srch_inf.smallBuf) 675 if (cifsFile->srch_inf.smallBuf)
687 cifs_small_buf_release(cifsFile->srch_inf. 676 cifs_small_buf_release(cifsFile->srch_inf.
688 ntwrk_buf_start); 677 ntwrk_buf_start);
689 else 678 else
@@ -691,7 +680,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
691 ntwrk_buf_start); 680 ntwrk_buf_start);
692 } 681 }
693 rc = initiate_cifs_search(xid,file); 682 rc = initiate_cifs_search(xid,file);
694 if(rc) { 683 if (rc) {
695 cFYI(1,("error %d reinitiating a search on rewind",rc)); 684 cFYI(1,("error %d reinitiating a search on rewind",rc));
696 return rc; 685 return rc;
697 } 686 }
@@ -702,10 +691,10 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
702 cFYI(1,("calling findnext2")); 691 cFYI(1,("calling findnext2"));
703 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 692 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid,
704 &cifsFile->srch_inf); 693 &cifsFile->srch_inf);
705 if(rc) 694 if (rc)
706 return -ENOENT; 695 return -ENOENT;
707 } 696 }
708 if(index_to_find < cifsFile->srch_inf.index_of_last_entry) { 697 if (index_to_find < cifsFile->srch_inf.index_of_last_entry) {
709 /* we found the buffer that contains the entry */ 698 /* we found the buffer that contains the entry */
710 /* scan and find it */ 699 /* scan and find it */
711 int i; 700 int i;
@@ -851,9 +840,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
851 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) 840 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
852 return -ENOENT; 841 return -ENOENT;
853 842
854 if(file->f_path.dentry == NULL)
855 return -ENOENT;
856
857 rc = cifs_entry_is_dot(pfindEntry,pCifsF); 843 rc = cifs_entry_is_dot(pfindEntry,pCifsF);
858 /* skip . and .. since we added them first */ 844 /* skip . and .. since we added them first */
859 if(rc != 0) 845 if(rc != 0)
@@ -997,11 +983,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
997 983
998 xid = GetXid(); 984 xid = GetXid();
999 985
1000 if(file->f_path.dentry == NULL) {
1001 FreeXid(xid);
1002 return -EIO;
1003 }
1004
1005 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 986 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1006 pTcon = cifs_sb->tcon; 987 pTcon = cifs_sb->tcon;
1007 if(pTcon == NULL) 988 if(pTcon == NULL)