diff options
| -rw-r--r-- | fs/cifs/CHANGES | 22 | ||||
| -rw-r--r-- | fs/cifs/README | 43 | ||||
| -rw-r--r-- | fs/cifs/TODO | 69 | ||||
| -rw-r--r-- | fs/cifs/cifs_fs_sb.h | 14 | ||||
| -rw-r--r-- | fs/cifs/cifs_unicode.c | 4 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 79 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 32 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 7 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 130 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 140 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 2 | ||||
| -rw-r--r-- | fs/cifs/file.c | 129 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 282 | ||||
| -rw-r--r-- | fs/cifs/netmisc.c | 24 | ||||
| -rw-r--r-- | fs/cifs/readdir.c | 161 |
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 @@ | |||
| 1 | Verison 1.48 | 1 | Version 1.49 |
| 2 | ------------ | ||
| 3 | IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6 | ||
| 4 | address after the "ip=" mount option, at least until mount.cifs is fixed to | ||
| 5 | handle DNS host to ipv6 name translation). Accept override of uid or gid | ||
| 6 | on mount even when Unix Extensions are negotiated (it used to be ignored | ||
| 7 | when Unix Extensions were ignored). This allows users to override the | ||
| 8 | default uid and gid for files when they are certain that the uids or | ||
| 9 | gids on the server do not match those of the client. Make "sec=none" | ||
| 10 | mount override username (so that null user connection is attempted) | ||
| 11 | to match what documentation said. | ||
| 12 | |||
| 13 | Version 1.48 | ||
| 2 | ------------ | 14 | ------------ |
| 3 | Fix mtime bouncing around from local idea of last write times to remote time. | 15 | Fix mtime bouncing around from local idea of last write times to remote time. |
| 4 | Fix hang (in i_size_read) when simultaneous size update of same remote file | 16 | Fix 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). |
| 10 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute | 22 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute |
| 11 | when archive dos attribute not set and we are changing mode back to writeable | 23 | when archive dos attribute not set and we are changing mode back to writeable |
| 12 | on server which does not support the Unix Extensions). | 24 | on server which does not support the Unix Extensions). Remove read only dos |
| 25 | attribute on chmod when adding any write permission (ie on any of | ||
| 26 | user/group/other (not all of user/group/other ie 0222) when | ||
| 27 | mounted to windows. Add support for POSIX MkDir (slight performance | ||
| 28 | enhancement and eliminates the network race between the mkdir and set | ||
| 29 | path info of the mode). | ||
| 30 | |||
| 13 | 31 | ||
| 14 | Version 1.47 | 32 | Version 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 | ||
| 470 | With recent 2.6 kernel versions of modutils, the version of the cifs kernel | 475 | With most 2.6 kernel versions of modutils, the version of the cifs kernel |
| 471 | module can be displayed via modinfo. | 476 | module can be displayed via modinfo. |
| 472 | 477 | ||
| 473 | Misc /proc/fs/cifs Flags and Debug Info | 478 | Misc /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 | ||
| 519 | cifsFYI If set to one, additional debug information is | 524 | cifsFYI 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 | |||
| 521 | traceSMB If set to one, debug information is logged to the | 540 | traceSMB 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 @@ | |||
| 1 | Version 1.39 November 30, 2005 | 1 | Version 1.49 April 26, 2007 |
| 2 | 2 | ||
| 3 | A Partial List of Missing Features | 3 | A Partial List of Missing Features |
| 4 | ================================== | 4 | ================================== |
| @@ -18,7 +18,7 @@ better) | |||
| 18 | 18 | ||
| 19 | d) Kerberos/SPNEGO session setup support - (started) | 19 | d) Kerberos/SPNEGO session setup support - (started) |
| 20 | 20 | ||
| 21 | e) NTLMv2 authentication (mostly implemented - double check | 21 | e) More testing of NTLMv2 authentication (mostly implemented - double check |
| 22 | that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in | 22 | that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in |
| 23 | fs/cifs/connect.c) | 23 | fs/cifs/connect.c) |
| 24 | 24 | ||
| @@ -27,55 +27,44 @@ used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM | |||
| 27 | and raw NTLMSSP already. This is important when enabling | 27 | and raw NTLMSSP already. This is important when enabling |
| 28 | extended security and mounting to Windows 2003 Servers | 28 | extended security and mounting to Windows 2003 Servers |
| 29 | 29 | ||
| 30 | f) Directory entry caching relies on a 1 second timer, rather than | 30 | g) Directory entry caching relies on a 1 second timer, rather than |
| 31 | using FindNotify or equivalent. - (started) | 31 | using FindNotify or equivalent. - (started) |
| 32 | 32 | ||
| 33 | g) A few byte range testcases fail due to POSIX vs. Windows/CIFS | 33 | h) quota support (needs minor kernel change since quota calls |
| 34 | style byte range lock differences. Save byte range locks so | ||
| 35 | reconnect can replay them. | ||
| 36 | |||
| 37 | h) Support unlock all (unlock 0,MAX_OFFSET) | ||
| 38 | by unlocking all known byte range locks that we locked on the file. | ||
| 39 | |||
| 40 | i) quota support (needs minor kernel change since quota calls | ||
| 41 | to make it to network filesystems or deviceless filesystems) | 34 | to make it to network filesystems or deviceless filesystems) |
| 42 | 35 | ||
| 43 | j) investigate sync behavior (including syncpage) and check | 36 | i) investigate sync behavior (including syncpage) and check |
| 44 | for proper behavior of intr/nointr | 37 | for proper behavior of intr/nointr |
| 45 | 38 | ||
| 46 | k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the | 39 | j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the |
| 47 | extra copy in/out of the socket buffers in some cases. | 40 | extra copy in/out of the socket buffers in some cases. |
| 48 | 41 | ||
| 49 | l) finish support for IPv6. This is mostly complete but | 42 | k) Better optimize open (and pathbased setfilesize) to reduce the |
| 50 | needs a simple conversion of ipv6 to sin6_addr from the | ||
| 51 | address in string representation. | ||
| 52 | |||
| 53 | m) Better optimize open (and pathbased setfilesize) to reduce the | ||
| 54 | oplock breaks coming from windows srv. Piggyback identical file | 43 | oplock breaks coming from windows srv. Piggyback identical file |
| 55 | opens on top of each other by incrementing reference count rather | 44 | opens on top of each other by incrementing reference count rather |
| 56 | than resending (helps reduce server resource utilization and avoid | 45 | than resending (helps reduce server resource utilization and avoid |
| 57 | spurious oplock breaks). | 46 | spurious oplock breaks). |
| 58 | 47 | ||
| 59 | o) Improve performance of readpages by sending more than one read | 48 | l) Improve performance of readpages by sending more than one read |
| 60 | at a time when 8 pages or more are requested. In conjuntion | 49 | at a time when 8 pages or more are requested. In conjuntion |
| 61 | add support for async_cifs_readpages. | 50 | add support for async_cifs_readpages. |
| 62 | 51 | ||
| 63 | p) Add support for storing symlink info to Windows servers | 52 | m) Add support for storing symlink info to Windows servers |
| 64 | in the Extended Attribute format their SFU clients would recognize. | 53 | in the Extended Attribute format their SFU clients would recognize. |
| 65 | 54 | ||
| 66 | q) Finish fcntl D_NOTIFY support so kde and gnome file list windows | 55 | n) Finish fcntl D_NOTIFY support so kde and gnome file list windows |
| 67 | will autorefresh (partially complete by Asser). Needs minor kernel | 56 | will autorefresh (partially complete by Asser). Needs minor kernel |
| 68 | vfs change to support removing D_NOTIFY on a file. | 57 | vfs change to support removing D_NOTIFY on a file. |
| 69 | 58 | ||
| 70 | r) Add GUI tool to configure /proc/fs/cifs settings and for display of | 59 | o) Add GUI tool to configure /proc/fs/cifs settings and for display of |
| 71 | the CIFS statistics (started) | 60 | the CIFS statistics (started) |
| 72 | 61 | ||
| 73 | s) implement support for security and trusted categories of xattrs | 62 | p) 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 | ||
| 76 | t) Implement O_DIRECT flag on open (already supported on mount) | 65 | q) Implement O_DIRECT flag on open (already supported on mount) |
| 77 | 66 | ||
| 78 | u) Create UID mapping facility so server UIDs can be mapped on a per | 67 | r) Create UID mapping facility so server UIDs can be mapped on a per |
| 79 | mount or a per server basis to client UIDs or nobody if no mapping | 68 | mount or a per server basis to client UIDs or nobody if no mapping |
| 80 | exists. This is helpful when Unix extensions are negotiated to | 69 | exists. This is helpful when Unix extensions are negotiated to |
| 81 | allow better permission checking when UIDs differ on the server | 70 | allow better permission checking when UIDs differ on the server |
| @@ -83,19 +72,26 @@ and client. Add new protocol request to the CIFS protocol | |||
| 83 | standard for asking the server for the corresponding name of a | 72 | standard for asking the server for the corresponding name of a |
| 84 | particular uid. | 73 | particular uid. |
| 85 | 74 | ||
| 86 | v) Add support for CIFS Unix and also the newer POSIX extensions to the | 75 | s) Add support for CIFS Unix and also the newer POSIX extensions to the |
| 87 | server side for Samba 4. | 76 | server side for Samba 4. |
| 88 | 77 | ||
| 89 | w) Finish up the dos time conversion routines needed to return old server | 78 | t) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) |
| 90 | time to the client (default time, of now or time 0 is used now for these | ||
| 91 | very old servers) | ||
| 92 | |||
| 93 | x) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) | ||
| 94 | need to add ability to set time to server (utimes command) | 79 | need to add ability to set time to server (utimes command) |
| 95 | 80 | ||
| 96 | y) Finish testing of Windows 9x/Windows ME server support (started). | 81 | u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) |
| 82 | |||
| 83 | v) mount check for unmatched uids | ||
| 84 | |||
| 85 | w) Add mount option for Linux extension disable per mount, and partial | ||
| 86 | disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?) | ||
| 97 | 87 | ||
| 98 | KNOWN BUGS (updated February 26, 2007) | 88 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of |
| 89 | processes can proceed better in parallel (on the server) | ||
| 90 | |||
| 91 | y) Fix Samba 3 to handle reads/writes over 127K (and remove the cifs mount | ||
| 92 | restriction of wsize max being 127K) | ||
| 93 | |||
| 94 | KNOWN BUGS (updated April 24, 2007) | ||
| 99 | ==================================== | 95 | ==================================== |
| 100 | See http://bugzilla.samba.org - search on product "CifsVFS" for | 96 | See http://bugzilla.samba.org - search on product "CifsVFS" for |
| 101 | current bug list. | 97 | current bug list. |
| @@ -127,10 +123,3 @@ negotiated size) and send larger write sizes to modern servers. | |||
| 127 | 4) More exhaustively test against less common servers. More testing | 123 | 4) More exhaustively test against less common servers. More testing |
| 128 | against Windows 9x, Windows ME servers. | 124 | against Windows 9x, Windows ME servers. |
| 129 | 125 | ||
| 130 | DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) | ||
| 131 | |||
| 132 | mount check for unmatched uids - and uid override | ||
| 133 | |||
| 134 | Add 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 | |||
| 136 | Free 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 | ||
| 32 | struct cifs_sb_info { | 34 | struct 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 | ||
| 149 | out_mount_failed: | 149 | out_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) | |||
| 724 | static int | 731 | static int |
| 725 | cifs_init_request_bufs(void) | 732 | cifs_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); | |||
| 100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
| 101 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 101 | extern 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 | |||
| 2112 | typedef struct { | 2125 | typedef 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 | ||
| 2120 | typedef struct { | 2132 | typedef 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 | ||
| 2125 | struct file_internal_info { | 2142 | struct file_internal_info { |
| 2126 | __u64 UniqueId; /* inode number */ | 2143 | __u64 UniqueId; /* inode number */ |
| 2127 | } __attribute__((packed)); /* level 0x3ee */ | 2144 | } __attribute__((packed)); /* level 0x3ee */ |
| 2145 | |||
| 2128 | struct file_mode_info { | 2146 | struct 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); |
| 247 | extern 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); | ||
| 247 | extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, | 252 | extern 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 | ||
| 916 | int | ||
| 917 | CIFSPOSIXCreate(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")); | ||
| 933 | PsxCreat: | ||
| 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 | |||
| 1029 | psx_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 | |||
| 916 | static __u16 convert_disposition(int disposition) | 1040 | static __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 | ||
| 341 | static int cifs_reopen_file(struct inode *inode, struct file *file, | 341 | static 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; | ||
| 393 | reopen_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 | ||
| 748 | static 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 | |||
| 737 | int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | 878 | int 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 { |
| 971 | mkdir_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 | } |
| 1024 | mkdir_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 */ | ||
| 134 | int | 135 | int |
| 135 | cifs_inet_pton(int address_family, char *cp,void *dst) | 136 | cifs_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 | ||
| 113 | static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) | 113 | static 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 */ |
| 619 | static int is_dir_changed(struct file * file) | 618 | static 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) |
