aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/Kconfig8
-rw-r--r--fs/cifs/Makefile4
-rw-r--r--fs/cifs/README9
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsacl.c51
-rw-r--r--fs/cifs/cifsacl.h4
-rw-r--r--fs/cifs/cifsfs.c5
-rw-r--r--fs/cifs/cifsglob.h12
-rw-r--r--fs/cifs/cifsproto.h11
-rw-r--r--fs/cifs/cifssmb.c183
-rw-r--r--fs/cifs/connect.c47
-rw-r--r--fs/cifs/dns_resolve.c2
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/cifs/fscache.c12
-rw-r--r--fs/cifs/inode.c57
-rw-r--r--fs/cifs/readdir.c41
-rw-r--r--fs/cifs/xattr.c55
17 files changed, 284 insertions, 224 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 0ed213970ce..ee45648b0d1 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -4,6 +4,7 @@ config CIFS
4 select NLS 4 select NLS
5 select CRYPTO 5 select CRYPTO
6 select CRYPTO_MD5 6 select CRYPTO_MD5
7 select CRYPTO_HMAC
7 select CRYPTO_ARC4 8 select CRYPTO_ARC4
8 help 9 help
9 This is the client VFS module for the Common Internet File System 10 This is the client VFS module for the Common Internet File System
@@ -143,6 +144,13 @@ config CIFS_FSCACHE
143 to be cached locally on disk through the general filesystem cache 144 to be cached locally on disk through the general filesystem cache
144 manager. If unsure, say N. 145 manager. If unsure, say N.
145 146
147config CIFS_ACL
148 bool "Provide CIFS ACL support (EXPERIMENTAL)"
149 depends on EXPERIMENTAL && CIFS_XATTR
150 help
151 Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
152 is handed over to the application/caller.
153
146config CIFS_EXPERIMENTAL 154config CIFS_EXPERIMENTAL
147 bool "CIFS Experimental Features (EXPERIMENTAL)" 155 bool "CIFS Experimental Features (EXPERIMENTAL)"
148 depends on CIFS && EXPERIMENTAL 156 depends on CIFS && EXPERIMENTAL
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index adefa60a9bd..43b19dd3919 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ 7 link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
8 md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 8 md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
9 readdir.o ioctl.o sess.o export.o cifsacl.o 9 readdir.o ioctl.o sess.o export.o
10
11cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
10 12
11cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o 13cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
12 14
diff --git a/fs/cifs/README b/fs/cifs/README
index ee68d103654..46af99ab361 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
337 wsize default write size (default 57344) 337 wsize default write size (default 57344)
338 maximum wsize currently allowed by CIFS is 57344 (fourteen 338 maximum wsize currently allowed by CIFS is 57344 (fourteen
339 4096 byte pages) 339 4096 byte pages)
340 actimeo=n attribute cache timeout in seconds (default 1 second).
341 After this timeout, the cifs client requests fresh attribute
342 information from the server. This option allows to tune the
343 attribute cache timeout to suit the workload needs. Shorter
344 timeouts mean better the cache coherency, but increased number
345 of calls to the server. Longer timeouts mean reduced number
346 of calls to the server at the expense of less stricter cache
347 coherency checks (i.e. incorrect attribute cache for a short
348 period of time).
340 rw mount the network share read-write (note that the 349 rw mount the network share read-write (note that the
341 server may still consider the share read-only) 350 server may still consider the share read-only)
342 ro mount network share read-only 351 ro mount network share read-only
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index e9a393c9c2c..7852cd67705 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -48,6 +48,7 @@ struct cifs_sb_info {
48 struct nls_table *local_nls; 48 struct nls_table *local_nls;
49 unsigned int rsize; 49 unsigned int rsize;
50 unsigned int wsize; 50 unsigned int wsize;
51 unsigned long actimeo; /* attribute cache timeout (jiffies) */
51 atomic_t active; 52 atomic_t active;
52 uid_t mnt_uid; 53 uid_t mnt_uid;
53 gid_t mnt_gid; 54 gid_t mnt_gid;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c9b4792ae82..a437ec391a0 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -30,8 +30,6 @@
30#include "cifs_debug.h" 30#include "cifs_debug.h"
31 31
32 32
33#ifdef CONFIG_CIFS_EXPERIMENTAL
34
35static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { 33static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
36 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, 34 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
37 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, 35 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -560,7 +558,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
560 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 558 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
561 559
562 if (IS_ERR(tlink)) 560 if (IS_ERR(tlink))
563 return NULL; 561 return ERR_CAST(tlink);
564 562
565 xid = GetXid(); 563 xid = GetXid();
566 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen); 564 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
@@ -568,7 +566,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
568 566
569 cifs_put_tlink(tlink); 567 cifs_put_tlink(tlink);
570 568
571 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen); 569 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
570 if (rc)
571 return ERR_PTR(rc);
572 return pntsd; 572 return pntsd;
573} 573}
574 574
@@ -583,7 +583,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
583 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 583 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
584 584
585 if (IS_ERR(tlink)) 585 if (IS_ERR(tlink))
586 return NULL; 586 return ERR_CAST(tlink);
587 587
588 tcon = tlink_tcon(tlink); 588 tcon = tlink_tcon(tlink);
589 xid = GetXid(); 589 xid = GetXid();
@@ -591,23 +591,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
591 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0, 591 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
592 &fid, &oplock, NULL, cifs_sb->local_nls, 592 &fid, &oplock, NULL, cifs_sb->local_nls,
593 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 593 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
594 if (rc) { 594 if (!rc) {
595 cERROR(1, "Unable to open file to get ACL"); 595 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
596 goto out; 596 CIFSSMBClose(xid, tcon, fid);
597 } 597 }
598 598
599 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
600 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
601
602 CIFSSMBClose(xid, tcon, fid);
603 out:
604 cifs_put_tlink(tlink); 599 cifs_put_tlink(tlink);
605 FreeXid(xid); 600 FreeXid(xid);
601
602 cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
603 if (rc)
604 return ERR_PTR(rc);
606 return pntsd; 605 return pntsd;
607} 606}
608 607
609/* Retrieve an ACL from the server */ 608/* Retrieve an ACL from the server */
610static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, 609struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
611 struct inode *inode, const char *path, 610 struct inode *inode, const char *path,
612 u32 *pacllen) 611 u32 *pacllen)
613{ 612{
@@ -695,7 +694,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
695} 694}
696 695
697/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ 696/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
698void 697int
699cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 698cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
700 struct inode *inode, const char *path, const __u16 *pfid) 699 struct inode *inode, const char *path, const __u16 *pfid)
701{ 700{
@@ -711,17 +710,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
711 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); 710 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
712 711
713 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ 712 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
714 if (pntsd) 713 if (IS_ERR(pntsd)) {
714 rc = PTR_ERR(pntsd);
715 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
716 } else {
715 rc = parse_sec_desc(pntsd, acllen, fattr); 717 rc = parse_sec_desc(pntsd, acllen, fattr);
716 if (rc) 718 kfree(pntsd);
717 cFYI(1, "parse sec desc failed rc = %d", rc); 719 if (rc)
720 cERROR(1, "parse sec desc failed rc = %d", rc);
721 }
718 722
719 kfree(pntsd); 723 return rc;
720 return;
721} 724}
722 725
723/* Convert mode bits to an ACL so we can update the ACL on the server */ 726/* Convert mode bits to an ACL so we can update the ACL on the server */
724int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) 727int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
725{ 728{
726 int rc = 0; 729 int rc = 0;
727 __u32 secdesclen = 0; 730 __u32 secdesclen = 0;
@@ -736,7 +739,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
736 /* Add three ACEs for owner, group, everyone getting rid of 739 /* Add three ACEs for owner, group, everyone getting rid of
737 other ACEs as chmod disables ACEs and set the security descriptor */ 740 other ACEs as chmod disables ACEs and set the security descriptor */
738 741
739 if (pntsd) { 742 if (IS_ERR(pntsd)) {
743 rc = PTR_ERR(pntsd);
744 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
745 } else {
740 /* allocate memory for the smb header, 746 /* allocate memory for the smb header,
741 set security descriptor request security descriptor 747 set security descriptor request security descriptor
742 parameters, and secuirty descriptor itself */ 748 parameters, and secuirty descriptor itself */
@@ -766,4 +772,3 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
766 772
767 return rc; 773 return rc;
768} 774}
769#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 6c8096cf515..c4ae7d03656 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -74,11 +74,7 @@ struct cifs_wksid {
74 char sidname[SIDNAMELENGTH]; 74 char sidname[SIDNAMELENGTH];
75} __attribute__((packed)); 75} __attribute__((packed));
76 76
77#ifdef CONFIG_CIFS_EXPERIMENTAL
78
79extern int match_sid(struct cifs_sid *); 77extern int match_sid(struct cifs_sid *);
80extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); 78extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
81 79
82#endif /* CONFIG_CIFS_EXPERIMENTAL */
83
84#endif /* _CIFSACL_H */ 80#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9c3789762ab..3936aa7f2c2 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -458,9 +458,13 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
458 seq_printf(s, ",acl"); 458 seq_printf(s, ",acl");
459 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 459 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
460 seq_printf(s, ",mfsymlinks"); 460 seq_printf(s, ",mfsymlinks");
461 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
462 seq_printf(s, ",fsc");
461 463
462 seq_printf(s, ",rsize=%d", cifs_sb->rsize); 464 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
463 seq_printf(s, ",wsize=%d", cifs_sb->wsize); 465 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
466 /* convert actimeo and display it in seconds */
467 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
464 468
465 return 0; 469 return 0;
466} 470}
@@ -933,7 +937,6 @@ init_cifs(void)
933 GlobalCurrentXid = 0; 937 GlobalCurrentXid = 0;
934 GlobalTotalActiveXid = 0; 938 GlobalTotalActiveXid = 0;
935 GlobalMaxActiveXid = 0; 939 GlobalMaxActiveXid = 0;
936 memset(Local_System_Name, 0, 15);
937 spin_lock_init(&cifs_tcp_ses_lock); 940 spin_lock_init(&cifs_tcp_ses_lock);
938 spin_lock_init(&cifs_file_list_lock); 941 spin_lock_init(&cifs_file_list_lock);
939 spin_lock_init(&GlobalMid_Lock); 942 spin_lock_init(&GlobalMid_Lock);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b577bf0a1bb..7136c0c3e2f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -45,6 +45,16 @@
45#define CIFS_MIN_RCV_POOL 4 45#define CIFS_MIN_RCV_POOL 4
46 46
47/* 47/*
48 * default attribute cache timeout (jiffies)
49 */
50#define CIFS_DEF_ACTIMEO (1 * HZ)
51
52/*
53 * max attribute cache timeout (jiffies) - 2^30
54 */
55#define CIFS_MAX_ACTIMEO (1 << 30)
56
57/*
48 * MAX_REQ is the maximum number of requests that WE will send 58 * MAX_REQ is the maximum number of requests that WE will send
49 * on one socket concurrently. It also matches the most common 59 * on one socket concurrently. It also matches the most common
50 * value of max multiplex returned by servers. We may 60 * value of max multiplex returned by servers. We may
@@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
746GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ 756GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
747GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ 757GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
748 /* on midQ entries */ 758 /* on midQ entries */
749GLOBAL_EXTERN char Local_System_Name[15];
750
751/* 759/*
752 * Global counters, updated atomically 760 * Global counters, updated atomically
753 */ 761 */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7ed69b6b5fe..e6d1481b16c 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -54,7 +54,8 @@ do { \
54 __func__, curr_xid, (int)rc); \ 54 __func__, curr_xid, (int)rc); \
55} while (0) 55} while (0)
56extern char *build_path_from_dentry(struct dentry *); 56extern char *build_path_from_dentry(struct dentry *);
57extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); 57extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
58 struct cifsTconInfo *tcon);
58extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 59extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
59extern char *cifs_compose_mount_options(const char *sb_mountdata, 60extern char *cifs_compose_mount_options(const char *sb_mountdata,
60 const char *fullpath, const struct dfs_info3_param *ref, 61 const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
79 struct TCP_Server_Info *); 80 struct TCP_Server_Info *);
80extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 81extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
81extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 82extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
82#ifdef CONFIG_CIFS_EXPERIMENTAL
83extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 83extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
84#endif
85extern unsigned int smbCalcSize(struct smb_hdr *ptr); 84extern unsigned int smbCalcSize(struct smb_hdr *ptr);
86extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); 85extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
87extern int decode_negTokenInit(unsigned char *security_blob, int length, 86extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -130,10 +129,12 @@ extern int cifs_get_file_info_unix(struct file *filp);
130extern int cifs_get_inode_info_unix(struct inode **pinode, 129extern int cifs_get_inode_info_unix(struct inode **pinode,
131 const unsigned char *search_path, 130 const unsigned char *search_path,
132 struct super_block *sb, int xid); 131 struct super_block *sb, int xid);
133extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, 132extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
134 struct cifs_fattr *fattr, struct inode *inode, 133 struct cifs_fattr *fattr, struct inode *inode,
135 const char *path, const __u16 *pfid); 134 const char *path, const __u16 *pfid);
136extern int mode_to_acl(struct inode *inode, const char *path, __u64); 135extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
136extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
137 const char *, u32 *);
137 138
138extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 139extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
139 const char *); 140 const char *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 2f2632b6df5..67acfb3acad 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2478,95 +2478,6 @@ querySymLinkRetry:
2478} 2478}
2479 2479
2480#ifdef CONFIG_CIFS_EXPERIMENTAL 2480#ifdef CONFIG_CIFS_EXPERIMENTAL
2481/* Initialize NT TRANSACT SMB into small smb request buffer.
2482 This assumes that all NT TRANSACTS that we init here have
2483 total parm and data under about 400 bytes (to fit in small cifs
2484 buffer size), which is the case so far, it easily fits. NB:
2485 Setup words themselves and ByteCount
2486 MaxSetupCount (size of returned setup area) and
2487 MaxParameterCount (returned parms size) must be set by caller */
2488static int
2489smb_init_nttransact(const __u16 sub_command, const int setup_count,
2490 const int parm_len, struct cifsTconInfo *tcon,
2491 void **ret_buf)
2492{
2493 int rc;
2494 __u32 temp_offset;
2495 struct smb_com_ntransact_req *pSMB;
2496
2497 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
2498 (void **)&pSMB);
2499 if (rc)
2500 return rc;
2501 *ret_buf = (void *)pSMB;
2502 pSMB->Reserved = 0;
2503 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
2504 pSMB->TotalDataCount = 0;
2505 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
2506 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
2507 pSMB->ParameterCount = pSMB->TotalParameterCount;
2508 pSMB->DataCount = pSMB->TotalDataCount;
2509 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
2510 (setup_count * 2) - 4 /* for rfc1001 length itself */;
2511 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
2512 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
2513 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
2514 pSMB->SubCommand = cpu_to_le16(sub_command);
2515 return 0;
2516}
2517
2518static int
2519validate_ntransact(char *buf, char **ppparm, char **ppdata,
2520 __u32 *pparmlen, __u32 *pdatalen)
2521{
2522 char *end_of_smb;
2523 __u32 data_count, data_offset, parm_count, parm_offset;
2524 struct smb_com_ntransact_rsp *pSMBr;
2525
2526 *pdatalen = 0;
2527 *pparmlen = 0;
2528
2529 if (buf == NULL)
2530 return -EINVAL;
2531
2532 pSMBr = (struct smb_com_ntransact_rsp *)buf;
2533
2534 /* ByteCount was converted from little endian in SendReceive */
2535 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
2536 (char *)&pSMBr->ByteCount;
2537
2538 data_offset = le32_to_cpu(pSMBr->DataOffset);
2539 data_count = le32_to_cpu(pSMBr->DataCount);
2540 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
2541 parm_count = le32_to_cpu(pSMBr->ParameterCount);
2542
2543 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
2544 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
2545
2546 /* should we also check that parm and data areas do not overlap? */
2547 if (*ppparm > end_of_smb) {
2548 cFYI(1, "parms start after end of smb");
2549 return -EINVAL;
2550 } else if (parm_count + *ppparm > end_of_smb) {
2551 cFYI(1, "parm end after end of smb");
2552 return -EINVAL;
2553 } else if (*ppdata > end_of_smb) {
2554 cFYI(1, "data starts after end of smb");
2555 return -EINVAL;
2556 } else if (data_count + *ppdata > end_of_smb) {
2557 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
2558 *ppdata, data_count, (data_count + *ppdata),
2559 end_of_smb, pSMBr);
2560 return -EINVAL;
2561 } else if (parm_count + data_count > pSMBr->ByteCount) {
2562 cFYI(1, "parm count and data count larger than SMB");
2563 return -EINVAL;
2564 }
2565 *pdatalen = data_count;
2566 *pparmlen = parm_count;
2567 return 0;
2568}
2569
2570int 2481int
2571CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2482CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2572 const unsigned char *searchName, 2483 const unsigned char *searchName,
@@ -3056,7 +2967,97 @@ GetExtAttrOut:
3056 2967
3057#endif /* CONFIG_POSIX */ 2968#endif /* CONFIG_POSIX */
3058 2969
3059#ifdef CONFIG_CIFS_EXPERIMENTAL 2970#ifdef CONFIG_CIFS_ACL
2971/*
2972 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
2973 * all NT TRANSACTS that we init here have total parm and data under about 400
2974 * bytes (to fit in small cifs buffer size), which is the case so far, it
2975 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
2976 * returned setup area) and MaxParameterCount (returned parms size) must be set
2977 * by caller
2978 */
2979static int
2980smb_init_nttransact(const __u16 sub_command, const int setup_count,
2981 const int parm_len, struct cifsTconInfo *tcon,
2982 void **ret_buf)
2983{
2984 int rc;
2985 __u32 temp_offset;
2986 struct smb_com_ntransact_req *pSMB;
2987
2988 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
2989 (void **)&pSMB);
2990 if (rc)
2991 return rc;
2992 *ret_buf = (void *)pSMB;
2993 pSMB->Reserved = 0;
2994 pSMB->TotalParameterCount = cpu_to_le32(parm_len);
2995 pSMB->TotalDataCount = 0;
2996 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
2997 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
2998 pSMB->ParameterCount = pSMB->TotalParameterCount;
2999 pSMB->DataCount = pSMB->TotalDataCount;
3000 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
3001 (setup_count * 2) - 4 /* for rfc1001 length itself */;
3002 pSMB->ParameterOffset = cpu_to_le32(temp_offset);
3003 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
3004 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
3005 pSMB->SubCommand = cpu_to_le16(sub_command);
3006 return 0;
3007}
3008
3009static int
3010validate_ntransact(char *buf, char **ppparm, char **ppdata,
3011 __u32 *pparmlen, __u32 *pdatalen)
3012{
3013 char *end_of_smb;
3014 __u32 data_count, data_offset, parm_count, parm_offset;
3015 struct smb_com_ntransact_rsp *pSMBr;
3016
3017 *pdatalen = 0;
3018 *pparmlen = 0;
3019
3020 if (buf == NULL)
3021 return -EINVAL;
3022
3023 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3024
3025 /* ByteCount was converted from little endian in SendReceive */
3026 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
3027 (char *)&pSMBr->ByteCount;
3028
3029 data_offset = le32_to_cpu(pSMBr->DataOffset);
3030 data_count = le32_to_cpu(pSMBr->DataCount);
3031 parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
3032 parm_count = le32_to_cpu(pSMBr->ParameterCount);
3033
3034 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
3035 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
3036
3037 /* should we also check that parm and data areas do not overlap? */
3038 if (*ppparm > end_of_smb) {
3039 cFYI(1, "parms start after end of smb");
3040 return -EINVAL;
3041 } else if (parm_count + *ppparm > end_of_smb) {
3042 cFYI(1, "parm end after end of smb");
3043 return -EINVAL;
3044 } else if (*ppdata > end_of_smb) {
3045 cFYI(1, "data starts after end of smb");
3046 return -EINVAL;
3047 } else if (data_count + *ppdata > end_of_smb) {
3048 cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
3049 *ppdata, data_count, (data_count + *ppdata),
3050 end_of_smb, pSMBr);
3051 return -EINVAL;
3052 } else if (parm_count + data_count > pSMBr->ByteCount) {
3053 cFYI(1, "parm count and data count larger than SMB");
3054 return -EINVAL;
3055 }
3056 *pdatalen = data_count;
3057 *pparmlen = parm_count;
3058 return 0;
3059}
3060
3060/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3061/* Get Security Descriptor (by handle) from remote server for a file or dir */
3061int 3062int
3062CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3063CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@ setCifsAclRetry:
3214 return (rc); 3215 return (rc);
3215} 3216}
3216 3217
3217#endif /* CONFIG_CIFS_EXPERIMENTAL */ 3218#endif /* CONFIG_CIFS_ACL */
3218 3219
3219/* Legacy Query Path Information call for lookup to old servers such 3220/* Legacy Query Path Information call for lookup to old servers such
3220 as Win9x/WinME */ 3221 as Win9x/WinME */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 251a17c0354..cc1a8604a79 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -105,6 +105,7 @@ struct smb_vol {
105 unsigned int wsize; 105 unsigned int wsize;
106 bool sockopt_tcp_nodelay:1; 106 bool sockopt_tcp_nodelay:1;
107 unsigned short int port; 107 unsigned short int port;
108 unsigned long actimeo; /* attribute cache timeout (jiffies) */
108 char *prepath; 109 char *prepath;
109 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 110 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
110 struct nls_table *local_nls; 111 struct nls_table *local_nls;
@@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname,
806 short int override_gid = -1; 807 short int override_gid = -1;
807 bool uid_specified = false; 808 bool uid_specified = false;
808 bool gid_specified = false; 809 bool gid_specified = false;
810 char *nodename = utsname()->nodename;
809 811
810 separator[0] = ','; 812 separator[0] = ',';
811 separator[1] = 0; 813 separator[1] = 0;
812 814
813 if (Local_System_Name[0] != 0) 815 /*
814 memcpy(vol->source_rfc1001_name, Local_System_Name, 15); 816 * does not have to be perfect mapping since field is
815 else { 817 * informational, only used for servers that do not support
816 char *nodename = utsname()->nodename; 818 * port 445 and it can be overridden at mount time
817 int n = strnlen(nodename, 15); 819 */
818 memset(vol->source_rfc1001_name, 0x20, 15); 820 memset(vol->source_rfc1001_name, 0x20, 15);
819 for (i = 0; i < n; i++) { 821 for (i = 0; i < strnlen(nodename, 15); i++)
820 /* does not have to be perfect mapping since field is 822 vol->source_rfc1001_name[i] = toupper(nodename[i]);
821 informational, only used for servers that do not support 823
822 port 445 and it can be overridden at mount time */
823 vol->source_rfc1001_name[i] = toupper(nodename[i]);
824 }
825 }
826 vol->source_rfc1001_name[15] = 0; 824 vol->source_rfc1001_name[15] = 0;
827 /* null target name indicates to use *SMBSERVR default called name 825 /* null target name indicates to use *SMBSERVR default called name
828 if we end up sending RFC1001 session initialize */ 826 if we end up sending RFC1001 session initialize */
@@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname,
840 /* default to using server inode numbers where available */ 838 /* default to using server inode numbers where available */
841 vol->server_ino = 1; 839 vol->server_ino = 1;
842 840
841 vol->actimeo = CIFS_DEF_ACTIMEO;
842
843 if (!options) 843 if (!options)
844 return 1; 844 return 1;
845 845
@@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname,
1214 printk(KERN_WARNING "CIFS: server net" 1214 printk(KERN_WARNING "CIFS: server net"
1215 "biosname longer than 15 truncated.\n"); 1215 "biosname longer than 15 truncated.\n");
1216 } 1216 }
1217 } else if (strnicmp(data, "actimeo", 7) == 0) {
1218 if (value && *value) {
1219 vol->actimeo = HZ * simple_strtoul(value,
1220 &value, 0);
1221 if (vol->actimeo > CIFS_MAX_ACTIMEO) {
1222 cERROR(1, "CIFS: attribute cache"
1223 "timeout too large");
1224 return 1;
1225 }
1226 }
1217 } else if (strnicmp(data, "credentials", 4) == 0) { 1227 } else if (strnicmp(data, "credentials", 4) == 0) {
1218 /* ignore */ 1228 /* ignore */
1219 } else if (strnicmp(data, "version", 3) == 0) { 1229 } else if (strnicmp(data, "version", 3) == 0) {
@@ -1352,6 +1362,11 @@ cifs_parse_mount_options(char *options, const char *devname,
1352 "supported. Instead set " 1362 "supported. Instead set "
1353 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1363 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1354 } else if (strnicmp(data, "fsc", 3) == 0) { 1364 } else if (strnicmp(data, "fsc", 3) == 0) {
1365#ifndef CONFIG_CIFS_FSCACHE
1366 cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
1367 "kernel config option set");
1368 return 1;
1369#endif
1355 vol->fsc = true; 1370 vol->fsc = true;
1356 } else if (strnicmp(data, "mfsymlinks", 10) == 0) { 1371 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1357 vol->mfsymlinks = true; 1372 vol->mfsymlinks = true;
@@ -2566,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2566 cFYI(1, "file mode: 0x%x dir mode: 0x%x", 2581 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2567 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); 2582 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2568 2583
2584 cifs_sb->actimeo = pvolume_info->actimeo;
2585
2569 if (pvolume_info->noperm) 2586 if (pvolume_info->noperm)
2570 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2587 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2571 if (pvolume_info->setuids) 2588 if (pvolume_info->setuids)
@@ -2816,13 +2833,13 @@ remote_path_check:
2816 /* check if a whole path (including prepath) is not remote */ 2833 /* check if a whole path (including prepath) is not remote */
2817 if (!rc && cifs_sb->prepathlen && tcon) { 2834 if (!rc && cifs_sb->prepathlen && tcon) {
2818 /* build_path_to_root works only when we have a valid tcon */ 2835 /* build_path_to_root works only when we have a valid tcon */
2819 full_path = cifs_build_path_to_root(cifs_sb); 2836 full_path = cifs_build_path_to_root(cifs_sb, tcon);
2820 if (full_path == NULL) { 2837 if (full_path == NULL) {
2821 rc = -ENOMEM; 2838 rc = -ENOMEM;
2822 goto mount_fail_check; 2839 goto mount_fail_check;
2823 } 2840 }
2824 rc = is_path_accessible(xid, tcon, cifs_sb, full_path); 2841 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2825 if (rc != -EREMOTE) { 2842 if (rc != 0 && rc != -EREMOTE) {
2826 kfree(full_path); 2843 kfree(full_path);
2827 goto mount_fail_check; 2844 goto mount_fail_check;
2828 } 2845 }
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 0eb87026cad..548f06230a6 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
66 /* Search for server name delimiter */ 66 /* Search for server name delimiter */
67 sep = memchr(hostname, '\\', len); 67 sep = memchr(hostname, '\\', len);
68 if (sep) 68 if (sep)
69 len = sep - unc; 69 len = sep - hostname;
70 else 70 else
71 cFYI(1, "%s: probably server name is whole unc: %s", 71 cFYI(1, "%s: probably server name is whole unc: %s",
72 __func__, unc); 72 __func__, unc);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 06c3e83fa38..5a28660ca2b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
1108 return total_written; 1108 return total_written;
1109} 1109}
1110 1110
1111#ifdef CONFIG_CIFS_EXPERIMENTAL
1112struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, 1111struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1113 bool fsuid_only) 1112 bool fsuid_only)
1114{ 1113{
@@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1142 spin_unlock(&cifs_file_list_lock); 1141 spin_unlock(&cifs_file_list_lock);
1143 return NULL; 1142 return NULL;
1144} 1143}
1145#endif
1146 1144
1147struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, 1145struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1148 bool fsuid_only) 1146 bool fsuid_only)
@@ -2271,8 +2269,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile)
2271 2269
2272void cifs_oplock_break_put(struct cifsFileInfo *cfile) 2270void cifs_oplock_break_put(struct cifsFileInfo *cfile)
2273{ 2271{
2272 struct super_block *sb = cfile->dentry->d_sb;
2273
2274 cifsFileInfo_put(cfile); 2274 cifsFileInfo_put(cfile);
2275 cifs_sb_deactive(cfile->dentry->d_sb); 2275 cifs_sb_deactive(sb);
2276} 2276}
2277 2277
2278const struct address_space_operations cifs_addr_ops = { 2278const struct address_space_operations cifs_addr_ops = {
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index a2ad94efcfe..297a43d0ff7 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -2,7 +2,7 @@
2 * fs/cifs/fscache.c - CIFS filesystem cache interface 2 * fs/cifs/fscache.c - CIFS filesystem cache interface
3 * 3 *
4 * Copyright (c) 2010 Novell, Inc. 4 * Copyright (c) 2010 Novell, Inc.
5 * Author(s): Suresh Jayaraman (sjayaraman@suse.de> 5 * Author(s): Suresh Jayaraman <sjayaraman@suse.de>
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
8 * it under the terms of the GNU Lesser General Public License as published 8 * it under the terms of the GNU Lesser General Public License as published
@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
67 if (cifsi->fscache) 67 if (cifsi->fscache)
68 return; 68 return;
69 69
70 cifsi->fscache = fscache_acquire_cookie(tcon->fscache, 70 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
71 cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
71 &cifs_fscache_inode_object_def, cifsi); 72 &cifs_fscache_inode_object_def, cifsi);
72 cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache, 73 cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
73 cifsi->fscache); 74 cifsi->fscache);
75 }
74} 76}
75 77
76void cifs_fscache_release_inode_cookie(struct inode *inode) 78void cifs_fscache_release_inode_cookie(struct inode *inode)
@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
101{ 103{
102 if ((filp->f_flags & O_ACCMODE) != O_RDONLY) 104 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
103 cifs_fscache_disable_inode_cookie(inode); 105 cifs_fscache_disable_inode_cookie(inode);
104 else { 106 else
105 cifs_fscache_enable_inode_cookie(inode); 107 cifs_fscache_enable_inode_cookie(inode);
106 cFYI(1, "CIFS: fscache inode cookie set");
107 }
108} 108}
109 109
110void cifs_fscache_reset_inode_cookie(struct inode *inode) 110void cifs_fscache_reset_inode_cookie(struct inode *inode)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index ef3a55bf86b..589f3e3f6e0 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -686,13 +686,18 @@ int cifs_get_inode_info(struct inode **pinode,
686 cFYI(1, "cifs_sfu_type failed: %d", tmprc); 686 cFYI(1, "cifs_sfu_type failed: %d", tmprc);
687 } 687 }
688 688
689#ifdef CONFIG_CIFS_EXPERIMENTAL 689#ifdef CONFIG_CIFS_ACL
690 /* fill in 0777 bits from ACL */ 690 /* fill in 0777 bits from ACL */
691 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 691 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
692 cFYI(1, "Getting mode bits from ACL"); 692 rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
693 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid); 693 pfid);
694 if (rc) {
695 cFYI(1, "%s: Getting ACL failed with error: %d",
696 __func__, rc);
697 goto cgii_exit;
698 }
694 } 699 }
695#endif 700#endif /* CONFIG_CIFS_ACL */
696 701
697 /* fill in remaining high mode bits e.g. SUID, VTX */ 702 /* fill in remaining high mode bits e.g. SUID, VTX */
698 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) 703 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -723,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
723 .lookup = cifs_lookup, 728 .lookup = cifs_lookup,
724}; 729};
725 730
726char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) 731char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
732 struct cifsTconInfo *tcon)
727{ 733{
728 int pplen = cifs_sb->prepathlen; 734 int pplen = cifs_sb->prepathlen;
729 int dfsplen; 735 int dfsplen;
730 char *full_path = NULL; 736 char *full_path = NULL;
731 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
732 737
733 /* if no prefix path, simply set path to the root of share to "" */ 738 /* if no prefix path, simply set path to the root of share to "" */
734 if (pplen == 0) { 739 if (pplen == 0) {
@@ -870,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
870 char *full_path; 875 char *full_path;
871 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 876 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
872 877
873 full_path = cifs_build_path_to_root(cifs_sb); 878 full_path = cifs_build_path_to_root(cifs_sb, tcon);
874 if (full_path == NULL) 879 if (full_path == NULL)
875 return ERR_PTR(-ENOMEM); 880 return ERR_PTR(-ENOMEM);
876 881
@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
881 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 886 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
882 xid, NULL); 887 xid, NULL);
883 888
884 if (!inode) 889 if (!inode) {
885 return ERR_PTR(rc); 890 inode = ERR_PTR(rc);
891 goto out;
892 }
886 893
887#ifdef CONFIG_CIFS_FSCACHE 894#ifdef CONFIG_CIFS_FSCACHE
888 /* populate tcon->resource_id */ 895 /* populate tcon->resource_id */
@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
898 inode->i_uid = cifs_sb->mnt_uid; 905 inode->i_uid = cifs_sb->mnt_uid;
899 inode->i_gid = cifs_sb->mnt_gid; 906 inode->i_gid = cifs_sb->mnt_gid;
900 } else if (rc) { 907 } else if (rc) {
901 kfree(full_path);
902 _FreeXid(xid);
903 iget_failed(inode); 908 iget_failed(inode);
904 return ERR_PTR(rc); 909 inode = ERR_PTR(rc);
905 } 910 }
906 911
907 912out:
908 kfree(full_path); 913 kfree(full_path);
909 /* can not call macro FreeXid here since in a void func 914 /* can not call macro FreeXid here since in a void func
910 * TODO: This is no longer true 915 * TODO: This is no longer true
@@ -1648,6 +1653,7 @@ static bool
1648cifs_inode_needs_reval(struct inode *inode) 1653cifs_inode_needs_reval(struct inode *inode)
1649{ 1654{
1650 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 1655 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1656 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1651 1657
1652 if (cifs_i->clientCanCacheRead) 1658 if (cifs_i->clientCanCacheRead)
1653 return false; 1659 return false;
@@ -1658,19 +1664,21 @@ cifs_inode_needs_reval(struct inode *inode)
1658 if (cifs_i->time == 0) 1664 if (cifs_i->time == 0)
1659 return true; 1665 return true;
1660 1666
1661 /* FIXME: the actimeo should be tunable */ 1667 if (!time_in_range(jiffies, cifs_i->time,
1662 if (time_after_eq(jiffies, cifs_i->time + HZ)) 1668 cifs_i->time + cifs_sb->actimeo))
1663 return true; 1669 return true;
1664 1670
1665 /* hardlinked files w/ noserverino get "special" treatment */ 1671 /* hardlinked files w/ noserverino get "special" treatment */
1666 if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && 1672 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
1667 S_ISREG(inode->i_mode) && inode->i_nlink != 1) 1673 S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1668 return true; 1674 return true;
1669 1675
1670 return false; 1676 return false;
1671} 1677}
1672 1678
1673/* check invalid_mapping flag and zap the cache if it's set */ 1679/*
1680 * Zap the cache. Called when invalid_mapping flag is set.
1681 */
1674static void 1682static void
1675cifs_invalidate_mapping(struct inode *inode) 1683cifs_invalidate_mapping(struct inode *inode)
1676{ 1684{
@@ -2114,11 +2122,16 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2114 2122
2115 if (attrs->ia_valid & ATTR_MODE) { 2123 if (attrs->ia_valid & ATTR_MODE) {
2116 rc = 0; 2124 rc = 0;
2117#ifdef CONFIG_CIFS_EXPERIMENTAL 2125#ifdef CONFIG_CIFS_ACL
2118 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) 2126 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2119 rc = mode_to_acl(inode, full_path, mode); 2127 rc = mode_to_cifs_acl(inode, full_path, mode);
2120 else 2128 if (rc) {
2121#endif 2129 cFYI(1, "%s: Setting ACL failed with error: %d",
2130 __func__, rc);
2131 goto cifs_setattr_exit;
2132 }
2133 } else
2134#endif /* CONFIG_CIFS_ACL */
2122 if (((mode & S_IWUGO) == 0) && 2135 if (((mode & S_IWUGO) == 0) &&
2123 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { 2136 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
2124 2137
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index ef7bb7b50f5..a73eb9f4bda 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file)
226 char *full_path = NULL; 226 char *full_path = NULL;
227 struct cifsFileInfo *cifsFile; 227 struct cifsFileInfo *cifsFile;
228 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 228 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
229 struct tcon_link *tlink; 229 struct tcon_link *tlink = NULL;
230 struct cifsTconInfo *pTcon; 230 struct cifsTconInfo *pTcon;
231 231
232 tlink = cifs_sb_tlink(cifs_sb);
233 if (IS_ERR(tlink))
234 return PTR_ERR(tlink);
235 pTcon = tlink_tcon(tlink);
236
237 if (file->private_data == NULL)
238 file->private_data =
239 kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
240 if (file->private_data == NULL) { 232 if (file->private_data == NULL) {
241 rc = -ENOMEM; 233 tlink = cifs_sb_tlink(cifs_sb);
242 goto error_exit; 234 if (IS_ERR(tlink))
235 return PTR_ERR(tlink);
236
237 cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
238 if (cifsFile == NULL) {
239 rc = -ENOMEM;
240 goto error_exit;
241 }
242 file->private_data = cifsFile;
243 cifsFile->tlink = cifs_get_tlink(tlink);
244 pTcon = tlink_tcon(tlink);
245 } else {
246 cifsFile = file->private_data;
247 pTcon = tlink_tcon(cifsFile->tlink);
243 } 248 }
244 249
245 cifsFile = file->private_data;
246 cifsFile->invalidHandle = true; 250 cifsFile->invalidHandle = true;
247 cifsFile->srch_inf.endOfSearch = false; 251 cifsFile->srch_inf.endOfSearch = false;
248 cifsFile->tlink = cifs_get_tlink(tlink);
249 252
250 full_path = build_path_from_dentry(file->f_path.dentry); 253 full_path = build_path_from_dentry(file->f_path.dentry);
251 if (full_path == NULL) { 254 if (full_path == NULL) {
@@ -756,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
756 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, 759 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
757 ino, fattr.cf_dtype); 760 ino, fattr.cf_dtype);
758 761
759 /*
760 * we can not return filldir errors to the caller since they are
761 * "normal" when the stat blocksize is too small - we return remapped
762 * error instead
763 *
764 * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
765 * case already. Why should we be clobbering other errors from it?
766 */
767 if (rc) {
768 cFYI(1, "filldir rc = %d", rc);
769 rc = -EOVERFLOW;
770 }
771 dput(tmp_dentry); 762 dput(tmp_dentry);
772 return rc; 763 return rc;
773} 764}
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index a264b744bb4..eae2a149160 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -30,10 +30,11 @@
30 30
31#define MAX_EA_VALUE_SIZE 65535 31#define MAX_EA_VALUE_SIZE 65535
32#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" 32#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
33#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
33#define CIFS_XATTR_USER_PREFIX "user." 34#define CIFS_XATTR_USER_PREFIX "user."
34#define CIFS_XATTR_SYSTEM_PREFIX "system." 35#define CIFS_XATTR_SYSTEM_PREFIX "system."
35#define CIFS_XATTR_OS2_PREFIX "os2." 36#define CIFS_XATTR_OS2_PREFIX "os2."
36#define CIFS_XATTR_SECURITY_PREFIX ".security" 37#define CIFS_XATTR_SECURITY_PREFIX "security."
37#define CIFS_XATTR_TRUSTED_PREFIX "trusted." 38#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
38#define XATTR_TRUSTED_PREFIX_LEN 8 39#define XATTR_TRUSTED_PREFIX_LEN 8
39#define XATTR_SECURITY_PREFIX_LEN 9 40#define XATTR_SECURITY_PREFIX_LEN 9
@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
277 cifs_sb->local_nls, 278 cifs_sb->local_nls,
278 cifs_sb->mnt_cifs_flags & 279 cifs_sb->mnt_cifs_flags &
279 CIFS_MOUNT_MAP_SPECIAL_CHR); 280 CIFS_MOUNT_MAP_SPECIAL_CHR);
280#ifdef CONFIG_CIFS_EXPERIMENTAL
281 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
282 __u16 fid;
283 int oplock = 0;
284 struct cifs_ntsd *pacl = NULL;
285 __u32 buflen = 0;
286 if (experimEnabled)
287 rc = CIFSSMBOpen(xid, pTcon, full_path,
288 FILE_OPEN, GENERIC_READ, 0, &fid,
289 &oplock, NULL, cifs_sb->local_nls,
290 cifs_sb->mnt_cifs_flags &
291 CIFS_MOUNT_MAP_SPECIAL_CHR);
292 /* else rc is EOPNOTSUPP from above */
293
294 if (rc == 0) {
295 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
296 &buflen);
297 CIFSSMBClose(xid, pTcon, fid);
298 }
299 }
300#endif /* EXPERIMENTAL */
301#else 281#else
302 cFYI(1, "query POSIX ACL not supported yet"); 282 cFYI(1, "Query POSIX ACL not supported yet");
303#endif /* CONFIG_CIFS_POSIX */ 283#endif /* CONFIG_CIFS_POSIX */
304 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT, 284 } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
305 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { 285 strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
311 cifs_sb->mnt_cifs_flags & 291 cifs_sb->mnt_cifs_flags &
312 CIFS_MOUNT_MAP_SPECIAL_CHR); 292 CIFS_MOUNT_MAP_SPECIAL_CHR);
313#else 293#else
314 cFYI(1, "query POSIX default ACL not supported yet"); 294 cFYI(1, "Query POSIX default ACL not supported yet");
315#endif 295#endif /* CONFIG_CIFS_POSIX */
296 } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
297 strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
298#ifdef CONFIG_CIFS_ACL
299 u32 acllen;
300 struct cifs_ntsd *pacl;
301
302 pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
303 full_path, &acllen);
304 if (IS_ERR(pacl)) {
305 rc = PTR_ERR(pacl);
306 cERROR(1, "%s: error %zd getting sec desc",
307 __func__, rc);
308 } else {
309 if (ea_value) {
310 if (acllen > buf_size)
311 acllen = -ERANGE;
312 else
313 memcpy(ea_value, pacl, acllen);
314 }
315 rc = acllen;
316 kfree(pacl);
317 }
318#else
319 cFYI(1, "Query CIFS ACL not supported yet");
320#endif /* CONFIG_CIFS_ACL */
316 } else if (strncmp(ea_name, 321 } else if (strncmp(ea_name,
317 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { 322 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
318 cFYI(1, "Trusted xattr namespace not supported yet"); 323 cFYI(1, "Trusted xattr namespace not supported yet");