diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 13:02:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 13:02:46 -0400 |
commit | ddbb868493abdb71d6c0e3ff93f735923842de38 (patch) | |
tree | d91aed7c58c276dd8f11c9e439027cbe0d948edb | |
parent | 3296ca27f50ecbd71db1d808c7a72d311027f919 (diff) | |
parent | 61b6bc525a34931bb73e4c95bfe009cd9572a288 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: remove never-used in6_addr option
cifs: add addr= mount option alias for ip=
[CIFS] Add mention of new mount parm (forceuid) to cifs readme
cifs: make overriding of ownership conditional on new mount options
cifs: fix IPv6 address length check
cifs: clean up set_cifs_acl interfaces
cifs: reorganize get_cifs_acl
[CIFS] Update readme to indicate change to default mount (serverino)
cifs: make serverino the default when mounting
cifs: rename cifs_iget to cifs_root_iget
cifs: make cnvrtDosUnixTm take a little-endian args and an offset
cifs: have cifs_NTtimeToUnix take a little-endian arg
cifs: tighten up default file_mode/dir_mode
cifs: fix artificial limit on reading symlinks
-rw-r--r-- | fs/cifs/CHANGES | 11 | ||||
-rw-r--r-- | fs/cifs/README | 16 | ||||
-rw-r--r-- | fs/cifs/cifs_spnego.c | 6 | ||||
-rw-r--r-- | fs/cifs/cifsacl.c | 178 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 10 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 7 | ||||
-rw-r--r-- | fs/cifs/connect.c | 34 | ||||
-rw-r--r-- | fs/cifs/file.c | 2 | ||||
-rw-r--r-- | fs/cifs/inode.c | 19 | ||||
-rw-r--r-- | fs/cifs/netmisc.c | 24 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 44 |
13 files changed, 180 insertions, 177 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index f20c4069c220..b48689839428 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,12 @@ | |||
1 | Version 1.59 | ||
2 | ------------ | ||
3 | Client uses server inode numbers (which are persistent) rather than | ||
4 | client generated ones by default (mount option "serverino" turned | ||
5 | on by default if server supports it). Add forceuid and forcegid | ||
6 | mount options (so that when negotiating unix extensions specifying | ||
7 | which uid mounted does not immediately force the server's reported | ||
8 | uids to be overridden). | ||
9 | |||
1 | Version 1.58 | 10 | Version 1.58 |
2 | ------------ | 11 | ------------ |
3 | Guard against buffer overruns in various UCS-2 to UTF-8 string conversions | 12 | Guard against buffer overruns in various UCS-2 to UTF-8 string conversions |
@@ -10,6 +19,8 @@ we converted from). Fix endianness of the vcnum field used during | |||
10 | session setup to distinguish multiple mounts to same server from different | 19 | session setup to distinguish multiple mounts to same server from different |
11 | userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental | 20 | userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental |
12 | flag to be set to 2, and mount must enable krb5 to turn on extended security). | 21 | flag to be set to 2, and mount must enable krb5 to turn on extended security). |
22 | Performance of file create to Samba improved (posix create on lookup | ||
23 | removes 1 of 2 network requests sent on file create) | ||
13 | 24 | ||
14 | Version 1.57 | 25 | Version 1.57 |
15 | ------------ | 26 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index db208ddb9899..ad92921dbde4 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -262,7 +262,8 @@ A partial list of the supported mount options follows: | |||
262 | mount. | 262 | mount. |
263 | domain Set the SMB/CIFS workgroup name prepended to the | 263 | domain Set the SMB/CIFS workgroup name prepended to the |
264 | username during CIFS session establishment | 264 | username during CIFS session establishment |
265 | uid Set the default uid for inodes. For mounts to servers | 265 | forceuid Set the default uid for inodes based on the uid |
266 | passed in. For mounts to servers | ||
266 | which do support the CIFS Unix extensions, such as a | 267 | which do support the CIFS Unix extensions, such as a |
267 | properly configured Samba server, the server provides | 268 | properly configured Samba server, the server provides |
268 | the uid, gid and mode so this parameter should not be | 269 | the uid, gid and mode so this parameter should not be |
@@ -292,6 +293,12 @@ A partial list of the supported mount options follows: | |||
292 | the client. Note that the mount.cifs helper must be | 293 | the client. Note that the mount.cifs helper must be |
293 | at version 1.10 or higher to support specifying the uid | 294 | at version 1.10 or higher to support specifying the uid |
294 | (or gid) in non-numeric form. | 295 | (or gid) in non-numeric form. |
296 | forcegid (similar to above but for the groupid instead of uid) | ||
297 | uid Set the default uid for inodes, and indicate to the | ||
298 | cifs kernel driver which local user mounted . If the server | ||
299 | supports the unix extensions the default uid is | ||
300 | not used to fill in the owner fields of inodes (files) | ||
301 | unless the "forceuid" parameter is specified. | ||
295 | gid Set the default gid for inodes (similar to above). | 302 | gid Set the default gid for inodes (similar to above). |
296 | file_mode If CIFS Unix extensions are not supported by the server | 303 | file_mode If CIFS Unix extensions are not supported by the server |
297 | this overrides the default mode for file inodes. | 304 | this overrides the default mode for file inodes. |
@@ -388,8 +395,13 @@ A partial list of the supported mount options follows: | |||
388 | or the CIFS Unix Extensions equivalent and for those | 395 | or the CIFS Unix Extensions equivalent and for those |
389 | this mount option will have no effect. Exporting cifs mounts | 396 | this mount option will have no effect. Exporting cifs mounts |
390 | under nfsd requires this mount option on the cifs mount. | 397 | under nfsd requires this mount option on the cifs mount. |
398 | This is now the default if server supports the | ||
399 | required network operation. | ||
391 | noserverino Client generates inode numbers (rather than using the actual one | 400 | noserverino Client generates inode numbers (rather than using the actual one |
392 | from the server) by default. | 401 | from the server). These inode numbers will vary after |
402 | unmount or reboot which can confuse some applications, | ||
403 | but not all server filesystems support unique inode | ||
404 | numbers. | ||
393 | setuids If the CIFS Unix extensions are negotiated with the server | 405 | setuids If the CIFS Unix extensions are negotiated with the server |
394 | the client will attempt to set the effective uid and gid of | 406 | the client will attempt to set the effective uid and gid of |
395 | the local process on newly created files, directories, and | 407 | the local process on newly created files, directories, and |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 67bf93a40d2e..4a4581cb2b5e 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
24 | #include <keys/user-type.h> | 24 | #include <keys/user-type.h> |
25 | #include <linux/key-type.h> | 25 | #include <linux/key-type.h> |
26 | #include <linux/inet.h> | ||
26 | #include "cifsglob.h" | 27 | #include "cifsglob.h" |
27 | #include "cifs_spnego.h" | 28 | #include "cifs_spnego.h" |
28 | #include "cifs_debug.h" | 29 | #include "cifs_debug.h" |
@@ -73,9 +74,6 @@ struct key_type cifs_spnego_key_type = { | |||
73 | * strlen(";sec=ntlmsspi") */ | 74 | * strlen(";sec=ntlmsspi") */ |
74 | #define MAX_MECH_STR_LEN 13 | 75 | #define MAX_MECH_STR_LEN 13 |
75 | 76 | ||
76 | /* max possible addr len eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/128 */ | ||
77 | #define MAX_IPV6_ADDR_LEN 43 | ||
78 | |||
79 | /* strlen of "host=" */ | 77 | /* strlen of "host=" */ |
80 | #define HOST_KEY_LEN 5 | 78 | #define HOST_KEY_LEN 5 |
81 | 79 | ||
@@ -102,7 +100,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) | |||
102 | host=hostname sec=mechanism uid=0xFF user=username */ | 100 | host=hostname sec=mechanism uid=0xFF user=username */ |
103 | desc_len = MAX_VER_STR_LEN + | 101 | desc_len = MAX_VER_STR_LEN + |
104 | HOST_KEY_LEN + strlen(hostname) + | 102 | HOST_KEY_LEN + strlen(hostname) + |
105 | IP_KEY_LEN + MAX_IPV6_ADDR_LEN + | 103 | IP_KEY_LEN + INET6_ADDRSTRLEN + |
106 | MAX_MECH_STR_LEN + | 104 | MAX_MECH_STR_LEN + |
107 | UID_KEY_LEN + (sizeof(uid_t) * 2) + | 105 | UID_KEY_LEN + (sizeof(uid_t) * 2) + |
108 | USER_KEY_LEN + strlen(sesInfo->userName) + 1; | 106 | USER_KEY_LEN + strlen(sesInfo->userName) + 1; |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 57ecdc83c26f..1403b5d86a73 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -552,130 +552,138 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
552 | return rc; | 552 | return rc; |
553 | } | 553 | } |
554 | 554 | ||
555 | 555 | static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | |
556 | /* Retrieve an ACL from the server */ | 556 | __u16 fid, u32 *pacllen) |
557 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | ||
558 | const char *path, const __u16 *pfid) | ||
559 | { | 557 | { |
560 | struct cifsFileInfo *open_file = NULL; | ||
561 | bool unlock_file = false; | ||
562 | int xid; | ||
563 | int rc = -EIO; | ||
564 | __u16 fid; | ||
565 | struct super_block *sb; | ||
566 | struct cifs_sb_info *cifs_sb; | ||
567 | struct cifs_ntsd *pntsd = NULL; | 558 | struct cifs_ntsd *pntsd = NULL; |
559 | int xid, rc; | ||
560 | |||
561 | xid = GetXid(); | ||
562 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | ||
563 | FreeXid(xid); | ||
568 | 564 | ||
569 | cFYI(1, ("get mode from ACL for %s", path)); | ||
570 | 565 | ||
571 | if (inode == NULL) | 566 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
572 | return NULL; | 567 | return pntsd; |
568 | } | ||
569 | |||
570 | static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, | ||
571 | const char *path, u32 *pacllen) | ||
572 | { | ||
573 | struct cifs_ntsd *pntsd = NULL; | ||
574 | int oplock = 0; | ||
575 | int xid, rc; | ||
576 | __u16 fid; | ||
573 | 577 | ||
574 | xid = GetXid(); | 578 | xid = GetXid(); |
575 | if (pfid == NULL) | ||
576 | open_file = find_readable_file(CIFS_I(inode)); | ||
577 | else | ||
578 | fid = *pfid; | ||
579 | 579 | ||
580 | sb = inode->i_sb; | 580 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0, |
581 | if (sb == NULL) { | 581 | &fid, &oplock, NULL, cifs_sb->local_nls, |
582 | FreeXid(xid); | 582 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
583 | return NULL; | 583 | if (rc) { |
584 | } | 584 | cERROR(1, ("Unable to open file to get ACL")); |
585 | cifs_sb = CIFS_SB(sb); | 585 | goto out; |
586 | |||
587 | if (open_file) { | ||
588 | unlock_file = true; | ||
589 | fid = open_file->netfid; | ||
590 | } else if (pfid == NULL) { | ||
591 | int oplock = 0; | ||
592 | /* open file */ | ||
593 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
594 | READ_CONTROL, 0, &fid, &oplock, NULL, | ||
595 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
596 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
597 | if (rc != 0) { | ||
598 | cERROR(1, ("Unable to open file to get ACL")); | ||
599 | FreeXid(xid); | ||
600 | return NULL; | ||
601 | } | ||
602 | } | 586 | } |
603 | 587 | ||
604 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | 588 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); |
605 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | 589 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
606 | if (unlock_file == true) /* find_readable_file increments ref count */ | ||
607 | atomic_dec(&open_file->wrtPending); | ||
608 | else if (pfid == NULL) /* if opened above we have to close the handle */ | ||
609 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
610 | /* else handle was passed in by caller */ | ||
611 | 590 | ||
591 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
592 | out: | ||
612 | FreeXid(xid); | 593 | FreeXid(xid); |
613 | return pntsd; | 594 | return pntsd; |
614 | } | 595 | } |
615 | 596 | ||
616 | /* Set an ACL on the server */ | 597 | /* Retrieve an ACL from the server */ |
617 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | 598 | static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, |
618 | struct inode *inode, const char *path) | 599 | struct inode *inode, const char *path, |
600 | u32 *pacllen) | ||
619 | { | 601 | { |
620 | struct cifsFileInfo *open_file; | 602 | struct cifs_ntsd *pntsd = NULL; |
621 | bool unlock_file = false; | 603 | struct cifsFileInfo *open_file = NULL; |
622 | int xid; | ||
623 | int rc = -EIO; | ||
624 | __u16 fid; | ||
625 | struct super_block *sb; | ||
626 | struct cifs_sb_info *cifs_sb; | ||
627 | 604 | ||
628 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | 605 | if (inode) |
606 | open_file = find_readable_file(CIFS_I(inode)); | ||
607 | if (!open_file) | ||
608 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); | ||
629 | 609 | ||
630 | if (!inode) | 610 | pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen); |
631 | return rc; | 611 | atomic_dec(&open_file->wrtPending); |
612 | return pntsd; | ||
613 | } | ||
632 | 614 | ||
633 | sb = inode->i_sb; | 615 | static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid, |
634 | if (sb == NULL) | 616 | struct cifs_ntsd *pnntsd, u32 acllen) |
635 | return rc; | 617 | { |
618 | int xid, rc; | ||
636 | 619 | ||
637 | cifs_sb = CIFS_SB(sb); | ||
638 | xid = GetXid(); | 620 | xid = GetXid(); |
621 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | ||
622 | FreeXid(xid); | ||
639 | 623 | ||
640 | open_file = find_readable_file(CIFS_I(inode)); | 624 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
641 | if (open_file) { | 625 | return rc; |
642 | unlock_file = true; | 626 | } |
643 | fid = open_file->netfid; | 627 | |
644 | } else { | 628 | static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, |
645 | int oplock = 0; | 629 | struct cifs_ntsd *pnntsd, u32 acllen) |
646 | /* open file */ | 630 | { |
647 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | 631 | int oplock = 0; |
648 | WRITE_DAC, 0, &fid, &oplock, NULL, | 632 | int xid, rc; |
649 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 633 | __u16 fid; |
650 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 634 | |
651 | if (rc != 0) { | 635 | xid = GetXid(); |
652 | cERROR(1, ("Unable to open file to set ACL")); | 636 | |
653 | FreeXid(xid); | 637 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, |
654 | return rc; | 638 | &fid, &oplock, NULL, cifs_sb->local_nls, |
655 | } | 639 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
640 | if (rc) { | ||
641 | cERROR(1, ("Unable to open file to set ACL")); | ||
642 | goto out; | ||
656 | } | 643 | } |
657 | 644 | ||
658 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | 645 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); |
659 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); | 646 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
660 | if (unlock_file) | ||
661 | atomic_dec(&open_file->wrtPending); | ||
662 | else | ||
663 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
664 | 647 | ||
648 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
649 | out: | ||
665 | FreeXid(xid); | 650 | FreeXid(xid); |
651 | return rc; | ||
652 | } | ||
666 | 653 | ||
654 | /* Set an ACL on the server */ | ||
655 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | ||
656 | struct inode *inode, const char *path) | ||
657 | { | ||
658 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
659 | struct cifsFileInfo *open_file; | ||
660 | int rc; | ||
661 | |||
662 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | ||
663 | |||
664 | open_file = find_readable_file(CIFS_I(inode)); | ||
665 | if (!open_file) | ||
666 | return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); | ||
667 | |||
668 | rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen); | ||
669 | atomic_dec(&open_file->wrtPending); | ||
667 | return rc; | 670 | return rc; |
668 | } | 671 | } |
669 | 672 | ||
670 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 673 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
671 | void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) | 674 | void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, |
675 | const char *path, const __u16 *pfid) | ||
672 | { | 676 | { |
673 | struct cifs_ntsd *pntsd = NULL; | 677 | struct cifs_ntsd *pntsd = NULL; |
674 | u32 acllen = 0; | 678 | u32 acllen = 0; |
675 | int rc = 0; | 679 | int rc = 0; |
676 | 680 | ||
677 | cFYI(DBG2, ("converting ACL to mode for %s", path)); | 681 | cFYI(DBG2, ("converting ACL to mode for %s", path)); |
678 | pntsd = get_cifs_acl(&acllen, inode, path, pfid); | 682 | |
683 | if (pfid) | ||
684 | pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen); | ||
685 | else | ||
686 | pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); | ||
679 | 687 | ||
680 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 688 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
681 | if (pntsd) | 689 | if (pntsd) |
@@ -698,7 +706,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
698 | cFYI(DBG2, ("set ACL from mode for %s", path)); | 706 | cFYI(DBG2, ("set ACL from mode for %s", path)); |
699 | 707 | ||
700 | /* Get the security descriptor */ | 708 | /* Get the security descriptor */ |
701 | pntsd = get_cifs_acl(&secdesclen, inode, path, NULL); | 709 | pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); |
702 | 710 | ||
703 | /* Add three ACEs for owner, group, everyone getting rid of | 711 | /* Add three ACEs for owner, group, everyone getting rid of |
704 | other ACEs as chmod disables ACEs and set the security descriptor */ | 712 | other ACEs as chmod disables ACEs and set the security descriptor */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5e6d35804d73..0a10a59b6392 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -146,7 +146,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
146 | #endif | 146 | #endif |
147 | sb->s_blocksize = CIFS_MAX_MSGSIZE; | 147 | sb->s_blocksize = CIFS_MAX_MSGSIZE; |
148 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ | 148 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ |
149 | inode = cifs_iget(sb, ROOT_I); | 149 | inode = cifs_root_iget(sb, ROOT_I); |
150 | 150 | ||
151 | if (IS_ERR(inode)) { | 151 | if (IS_ERR(inode)) { |
152 | rc = PTR_ERR(inode); | 152 | rc = PTR_ERR(inode); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 051b71cfdea9..9570a0e8023f 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -36,7 +36,7 @@ extern void cifs_read_inode(struct inode *); | |||
36 | 36 | ||
37 | /* Functions related to inodes */ | 37 | /* Functions related to inodes */ |
38 | extern const struct inode_operations cifs_dir_inode_ops; | 38 | extern const struct inode_operations cifs_dir_inode_ops; |
39 | extern struct inode *cifs_iget(struct super_block *, unsigned long); | 39 | extern struct inode *cifs_root_iget(struct super_block *, unsigned long); |
40 | extern int cifs_create(struct inode *, struct dentry *, int, | 40 | extern int cifs_create(struct inode *, struct dentry *, int, |
41 | struct nameidata *); | 41 | struct nameidata *); |
42 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, | 42 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
@@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
100 | extern const struct export_operations cifs_export_ops; | 100 | extern const struct export_operations cifs_export_ops; |
101 | #endif /* EXPERIMENTAL */ | 101 | #endif /* EXPERIMENTAL */ |
102 | 102 | ||
103 | #define CIFS_VERSION "1.58" | 103 | #define CIFS_VERSION "1.59" |
104 | #endif /* _CIFSFS_H */ | 104 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fae083930eee..f9452329bcce 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -90,10 +90,10 @@ extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | |||
90 | struct cifsTconInfo *); | 90 | struct cifsTconInfo *); |
91 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 91 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
92 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); | 92 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); |
93 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); | 93 | extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); |
94 | extern u64 cifs_UnixTimeToNT(struct timespec); | 94 | extern u64 cifs_UnixTimeToNT(struct timespec); |
95 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 95 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
96 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | 96 | int offset); |
97 | 97 | ||
98 | extern int cifs_posix_open(char *full_path, struct inode **pinode, | 98 | extern int cifs_posix_open(char *full_path, struct inode **pinode, |
99 | struct super_block *sb, int mode, int oflags, | 99 | struct super_block *sb, int mode, int oflags, |
@@ -108,8 +108,8 @@ extern int cifs_get_inode_info(struct inode **pinode, | |||
108 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 108 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
109 | const unsigned char *search_path, | 109 | const unsigned char *search_path, |
110 | struct super_block *sb, int xid); | 110 | struct super_block *sb, int xid); |
111 | extern void acl_to_uid_mode(struct inode *inode, const char *path, | 111 | extern void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, |
112 | const __u16 *pfid); | 112 | const char *path, const __u16 *pfid); |
113 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); | 113 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); |
114 | 114 | ||
115 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 115 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index d06260251c30..b84c61d5bca4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -524,8 +524,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
524 | int val, seconds, remain, result; | 524 | int val, seconds, remain, result; |
525 | struct timespec ts, utc; | 525 | struct timespec ts, utc; |
526 | utc = CURRENT_TIME; | 526 | utc = CURRENT_TIME; |
527 | ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), | 527 | ts = cnvrtDosUnixTm(rsp->SrvTime.Date, |
528 | le16_to_cpu(rsp->SrvTime.Time)); | 528 | rsp->SrvTime.Time, 0); |
529 | cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d", | 529 | cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d", |
530 | (int)ts.tv_sec, (int)utc.tv_sec, | 530 | (int)ts.tv_sec, (int)utc.tv_sec, |
531 | (int)(utc.tv_sec - ts.tv_sec))); | 531 | (int)(utc.tv_sec - ts.tv_sec))); |
@@ -2427,8 +2427,7 @@ querySymLinkRetry: | |||
2427 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; | 2427 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; |
2428 | pSMB->TotalDataCount = 0; | 2428 | pSMB->TotalDataCount = 0; |
2429 | pSMB->MaxParameterCount = cpu_to_le16(2); | 2429 | pSMB->MaxParameterCount = cpu_to_le16(2); |
2430 | /* BB find exact max data count below from sess structure BB */ | 2430 | pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); |
2431 | pSMB->MaxDataCount = cpu_to_le16(4000); | ||
2432 | pSMB->MaxSetupCount = 0; | 2431 | pSMB->MaxSetupCount = 0; |
2433 | pSMB->Reserved = 0; | 2432 | pSMB->Reserved = 0; |
2434 | pSMB->Flags = 0; | 2433 | pSMB->Flags = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4aa81a507b74..97f4311b9a8e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/namei.h> | 35 | #include <linux/namei.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
38 | #include <linux/inet.h> | ||
38 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
39 | #include "cifspdu.h" | 40 | #include "cifspdu.h" |
40 | #include "cifsglob.h" | 41 | #include "cifsglob.h" |
@@ -61,7 +62,6 @@ struct smb_vol { | |||
61 | char *domainname; | 62 | char *domainname; |
62 | char *UNC; | 63 | char *UNC; |
63 | char *UNCip; | 64 | char *UNCip; |
64 | char *in6_addr; /* ipv6 address as human readable form of in6_addr */ | ||
65 | char *iocharset; /* local code page for mapping to and from Unicode */ | 65 | char *iocharset; /* local code page for mapping to and from Unicode */ |
66 | char source_rfc1001_name[16]; /* netbios name of client */ | 66 | char source_rfc1001_name[16]; /* netbios name of client */ |
67 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ | 67 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ |
@@ -827,14 +827,16 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
827 | vol->target_rfc1001_name[0] = 0; | 827 | vol->target_rfc1001_name[0] = 0; |
828 | vol->linux_uid = current_uid(); /* use current_euid() instead? */ | 828 | vol->linux_uid = current_uid(); /* use current_euid() instead? */ |
829 | vol->linux_gid = current_gid(); | 829 | vol->linux_gid = current_gid(); |
830 | vol->dir_mode = S_IRWXUGO; | 830 | |
831 | /* 2767 perms indicate mandatory locking support */ | 831 | /* default to only allowing write access to owner of the mount */ |
832 | vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); | 832 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; |
833 | 833 | ||
834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
835 | vol->rw = true; | 835 | vol->rw = true; |
836 | /* default is always to request posix paths. */ | 836 | /* default is always to request posix paths. */ |
837 | vol->posix_paths = 1; | 837 | vol->posix_paths = 1; |
838 | /* default to using server inode numbers where available */ | ||
839 | vol->server_ino = 1; | ||
838 | 840 | ||
839 | if (!options) | 841 | if (!options) |
840 | return 1; | 842 | return 1; |
@@ -955,10 +957,12 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
955 | } | 957 | } |
956 | strcpy(vol->password, value); | 958 | strcpy(vol->password, value); |
957 | } | 959 | } |
958 | } else if (strnicmp(data, "ip", 2) == 0) { | 960 | } else if (!strnicmp(data, "ip", 2) || |
961 | !strnicmp(data, "addr", 4)) { | ||
959 | if (!value || !*value) { | 962 | if (!value || !*value) { |
960 | vol->UNCip = NULL; | 963 | vol->UNCip = NULL; |
961 | } else if (strnlen(value, 35) < 35) { | 964 | } else if (strnlen(value, INET6_ADDRSTRLEN) < |
965 | INET6_ADDRSTRLEN) { | ||
962 | vol->UNCip = value; | 966 | vol->UNCip = value; |
963 | } else { | 967 | } else { |
964 | printk(KERN_WARNING "CIFS: ip address " | 968 | printk(KERN_WARNING "CIFS: ip address " |
@@ -1092,17 +1096,17 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1092 | return 1; | 1096 | return 1; |
1093 | } | 1097 | } |
1094 | } else if (strnicmp(data, "uid", 3) == 0) { | 1098 | } else if (strnicmp(data, "uid", 3) == 0) { |
1095 | if (value && *value) { | 1099 | if (value && *value) |
1096 | vol->linux_uid = | 1100 | vol->linux_uid = |
1097 | simple_strtoul(value, &value, 0); | 1101 | simple_strtoul(value, &value, 0); |
1102 | } else if (strnicmp(data, "forceuid", 8) == 0) { | ||
1098 | vol->override_uid = 1; | 1103 | vol->override_uid = 1; |
1099 | } | ||
1100 | } else if (strnicmp(data, "gid", 3) == 0) { | 1104 | } else if (strnicmp(data, "gid", 3) == 0) { |
1101 | if (value && *value) { | 1105 | if (value && *value) |
1102 | vol->linux_gid = | 1106 | vol->linux_gid = |
1103 | simple_strtoul(value, &value, 0); | 1107 | simple_strtoul(value, &value, 0); |
1108 | } else if (strnicmp(data, "forcegid", 8) == 0) { | ||
1104 | vol->override_gid = 1; | 1109 | vol->override_gid = 1; |
1105 | } | ||
1106 | } else if (strnicmp(data, "file_mode", 4) == 0) { | 1110 | } else if (strnicmp(data, "file_mode", 4) == 0) { |
1107 | if (value && *value) { | 1111 | if (value && *value) { |
1108 | vol->file_mode = | 1112 | vol->file_mode = |
@@ -1315,16 +1319,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1315 | vol->direct_io = 1; | 1319 | vol->direct_io = 1; |
1316 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { | 1320 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { |
1317 | vol->direct_io = 1; | 1321 | vol->direct_io = 1; |
1318 | } else if (strnicmp(data, "in6_addr", 8) == 0) { | ||
1319 | if (!value || !*value) { | ||
1320 | vol->in6_addr = NULL; | ||
1321 | } else if (strnlen(value, 49) == 48) { | ||
1322 | vol->in6_addr = value; | ||
1323 | } else { | ||
1324 | printk(KERN_WARNING "CIFS: ip v6 address not " | ||
1325 | "48 characters long\n"); | ||
1326 | return 1; | ||
1327 | } | ||
1328 | } else if (strnicmp(data, "noac", 4) == 0) { | 1322 | } else if (strnicmp(data, "noac", 4) == 0) { |
1329 | printk(KERN_WARNING "CIFS: Mount option noac not " | 1323 | printk(KERN_WARNING "CIFS: Mount option noac not " |
1330 | "supported. Instead set " | 1324 | "supported. Instead set " |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 302ea15f02e6..06866841b97f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -241,7 +241,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
241 | /* BB need same check in cifs_create too? */ | 241 | /* BB need same check in cifs_create too? */ |
242 | /* if not oplocked, invalidate inode pages if mtime or file | 242 | /* if not oplocked, invalidate inode pages if mtime or file |
243 | size changed */ | 243 | size changed */ |
244 | temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime)); | 244 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); |
245 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && | 245 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && |
246 | (file->f_path.dentry->d_inode->i_size == | 246 | (file->f_path.dentry->d_inode->i_size == |
247 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 247 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9c869a6dcba1..fad882b075ba 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -85,10 +85,10 @@ static void cifs_unix_info_to_inode(struct inode *inode, | |||
85 | __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); | 85 | __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); |
86 | __u64 end_of_file = le64_to_cpu(info->EndOfFile); | 86 | __u64 end_of_file = le64_to_cpu(info->EndOfFile); |
87 | 87 | ||
88 | inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime)); | 88 | inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime); |
89 | inode->i_mtime = | 89 | inode->i_mtime = |
90 | cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime)); | 90 | cifs_NTtimeToUnix(info->LastModificationTime); |
91 | inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange)); | 91 | inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange); |
92 | inode->i_mode = le64_to_cpu(info->Permissions); | 92 | inode->i_mode = le64_to_cpu(info->Permissions); |
93 | 93 | ||
94 | /* | 94 | /* |
@@ -554,14 +554,11 @@ int cifs_get_inode_info(struct inode **pinode, | |||
554 | 554 | ||
555 | /* Linux can not store file creation time so ignore it */ | 555 | /* Linux can not store file creation time so ignore it */ |
556 | if (pfindData->LastAccessTime) | 556 | if (pfindData->LastAccessTime) |
557 | inode->i_atime = cifs_NTtimeToUnix | 557 | inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime); |
558 | (le64_to_cpu(pfindData->LastAccessTime)); | ||
559 | else /* do not need to use current_fs_time - time not stored */ | 558 | else /* do not need to use current_fs_time - time not stored */ |
560 | inode->i_atime = CURRENT_TIME; | 559 | inode->i_atime = CURRENT_TIME; |
561 | inode->i_mtime = | 560 | inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime); |
562 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 561 | inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime); |
563 | inode->i_ctime = | ||
564 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | ||
565 | cFYI(DBG2, ("Attributes came in as 0x%x", attr)); | 562 | cFYI(DBG2, ("Attributes came in as 0x%x", attr)); |
566 | if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { | 563 | if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { |
567 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; | 564 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; |
@@ -629,7 +626,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
629 | /* fill in 0777 bits from ACL */ | 626 | /* fill in 0777 bits from ACL */ |
630 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 627 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
631 | cFYI(1, ("Getting mode bits from ACL")); | 628 | cFYI(1, ("Getting mode bits from ACL")); |
632 | acl_to_uid_mode(inode, full_path, pfid); | 629 | acl_to_uid_mode(cifs_sb, inode, full_path, pfid); |
633 | } | 630 | } |
634 | #endif | 631 | #endif |
635 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 632 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
@@ -699,7 +696,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) | |||
699 | } | 696 | } |
700 | 697 | ||
701 | /* gets root inode */ | 698 | /* gets root inode */ |
702 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | 699 | struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) |
703 | { | 700 | { |
704 | int xid; | 701 | int xid; |
705 | struct cifs_sb_info *cifs_sb; | 702 | struct cifs_sb_info *cifs_sb; |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index e2fe998989a3..32d6baa0a54f 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -853,12 +853,12 @@ smbCalcSize_LE(struct smb_hdr *ptr) | |||
853 | 853 | ||
854 | #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) | 854 | #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) |
855 | 855 | ||
856 | /* | 856 | /* |
857 | * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) | 857 | * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) |
858 | * into Unix UTC (based 1970-01-01, in seconds). | 858 | * into Unix UTC (based 1970-01-01, in seconds). |
859 | */ | 859 | */ |
860 | struct timespec | 860 | struct timespec |
861 | cifs_NTtimeToUnix(u64 ntutc) | 861 | cifs_NTtimeToUnix(__le64 ntutc) |
862 | { | 862 | { |
863 | struct timespec ts; | 863 | struct timespec ts; |
864 | /* BB what about the timezone? BB */ | 864 | /* BB what about the timezone? BB */ |
@@ -866,7 +866,7 @@ cifs_NTtimeToUnix(u64 ntutc) | |||
866 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ | 866 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ |
867 | u64 t; | 867 | u64 t; |
868 | 868 | ||
869 | t = ntutc - NTFS_TIME_OFFSET; | 869 | t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET; |
870 | ts.tv_nsec = do_div(t, 10000000) * 100; | 870 | ts.tv_nsec = do_div(t, 10000000) * 100; |
871 | ts.tv_sec = t; | 871 | ts.tv_sec = t; |
872 | return ts; | 872 | return ts; |
@@ -883,16 +883,12 @@ cifs_UnixTimeToNT(struct timespec t) | |||
883 | static int total_days_of_prev_months[] = | 883 | static int total_days_of_prev_months[] = |
884 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; | 884 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; |
885 | 885 | ||
886 | 886 | struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) | |
887 | __le64 cnvrtDosCifsTm(__u16 date, __u16 time) | ||
888 | { | ||
889 | return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); | ||
890 | } | ||
891 | |||
892 | struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | ||
893 | { | 887 | { |
894 | struct timespec ts; | 888 | struct timespec ts; |
895 | int sec, min, days, month, year; | 889 | int sec, min, days, month, year; |
890 | u16 date = le16_to_cpu(le_date); | ||
891 | u16 time = le16_to_cpu(le_time); | ||
896 | SMB_TIME *st = (SMB_TIME *)&time; | 892 | SMB_TIME *st = (SMB_TIME *)&time; |
897 | SMB_DATE *sd = (SMB_DATE *)&date; | 893 | SMB_DATE *sd = (SMB_DATE *)&date; |
898 | 894 | ||
@@ -933,7 +929,7 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | |||
933 | days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); | 929 | days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); |
934 | sec += 24 * 60 * 60 * days; | 930 | sec += 24 * 60 * 60 * days; |
935 | 931 | ||
936 | ts.tv_sec = sec; | 932 | ts.tv_sec = sec + offset; |
937 | 933 | ||
938 | /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ | 934 | /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ |
939 | 935 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 964e097c8203..86d0055dc529 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -115,17 +115,6 @@ construct_dentry(struct qstr *qstring, struct file *file, | |||
115 | return rc; | 115 | return rc; |
116 | } | 116 | } |
117 | 117 | ||
118 | static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode) | ||
119 | { | ||
120 | if ((tcon) && (tcon->ses) && (tcon->ses->server)) { | ||
121 | inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; | ||
122 | inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; | ||
123 | inode->i_atime.tv_sec += tcon->ses->server->timeAdj; | ||
124 | } | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | |||
129 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | 118 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, |
130 | char *buf, unsigned int *pobject_type, int isNewInode) | 119 | char *buf, unsigned int *pobject_type, int isNewInode) |
131 | { | 120 | { |
@@ -150,26 +139,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
150 | allocation_size = le64_to_cpu(pfindData->AllocationSize); | 139 | allocation_size = le64_to_cpu(pfindData->AllocationSize); |
151 | end_of_file = le64_to_cpu(pfindData->EndOfFile); | 140 | end_of_file = le64_to_cpu(pfindData->EndOfFile); |
152 | tmp_inode->i_atime = | 141 | tmp_inode->i_atime = |
153 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 142 | cifs_NTtimeToUnix(pfindData->LastAccessTime); |
154 | tmp_inode->i_mtime = | 143 | tmp_inode->i_mtime = |
155 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 144 | cifs_NTtimeToUnix(pfindData->LastWriteTime); |
156 | tmp_inode->i_ctime = | 145 | tmp_inode->i_ctime = |
157 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 146 | cifs_NTtimeToUnix(pfindData->ChangeTime); |
158 | } else { /* legacy, OS2 and DOS style */ | 147 | } else { /* legacy, OS2 and DOS style */ |
159 | /* struct timespec ts;*/ | 148 | int offset = cifs_sb->tcon->ses->server->timeAdj; |
160 | FIND_FILE_STANDARD_INFO *pfindData = | 149 | FIND_FILE_STANDARD_INFO *pfindData = |
161 | (FIND_FILE_STANDARD_INFO *)buf; | 150 | (FIND_FILE_STANDARD_INFO *)buf; |
162 | 151 | ||
163 | tmp_inode->i_mtime = cnvrtDosUnixTm( | 152 | tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate, |
164 | le16_to_cpu(pfindData->LastWriteDate), | 153 | pfindData->LastWriteTime, |
165 | le16_to_cpu(pfindData->LastWriteTime)); | 154 | offset); |
166 | tmp_inode->i_atime = cnvrtDosUnixTm( | 155 | tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate, |
167 | le16_to_cpu(pfindData->LastAccessDate), | 156 | pfindData->LastAccessTime, |
168 | le16_to_cpu(pfindData->LastAccessTime)); | 157 | offset); |
169 | tmp_inode->i_ctime = cnvrtDosUnixTm( | 158 | tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate, |
170 | le16_to_cpu(pfindData->LastWriteDate), | 159 | pfindData->LastWriteTime, |
171 | le16_to_cpu(pfindData->LastWriteTime)); | 160 | offset); |
172 | AdjustForTZ(cifs_sb->tcon, tmp_inode); | ||
173 | attr = le16_to_cpu(pfindData->Attributes); | 161 | attr = le16_to_cpu(pfindData->Attributes); |
174 | allocation_size = le32_to_cpu(pfindData->AllocationSize); | 162 | allocation_size = le32_to_cpu(pfindData->AllocationSize); |
175 | end_of_file = le32_to_cpu(pfindData->DataSize); | 163 | end_of_file = le32_to_cpu(pfindData->DataSize); |
@@ -331,11 +319,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
331 | local_size = tmp_inode->i_size; | 319 | local_size = tmp_inode->i_size; |
332 | 320 | ||
333 | tmp_inode->i_atime = | 321 | tmp_inode->i_atime = |
334 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 322 | cifs_NTtimeToUnix(pfindData->LastAccessTime); |
335 | tmp_inode->i_mtime = | 323 | tmp_inode->i_mtime = |
336 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime)); | 324 | cifs_NTtimeToUnix(pfindData->LastModificationTime); |
337 | tmp_inode->i_ctime = | 325 | tmp_inode->i_ctime = |
338 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); | 326 | cifs_NTtimeToUnix(pfindData->LastStatusChange); |
339 | 327 | ||
340 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); | 328 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); |
341 | /* since we set the inode type below we need to mask off type | 329 | /* since we set the inode type below we need to mask off type |