aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifsacl.c14
-rw-r--r--fs/cifs/cifsacl.h1
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/cifssmb.c32
-rw-r--r--fs/cifs/connect.c1
-rw-r--r--fs/cifs/transport.c18
9 files changed, 50 insertions, 24 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index dbd91461853c..05c9da6181c3 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -8,7 +8,8 @@ of second share to disconnected server session (autoreconnect on this).
8Add ability to modify cifs acls for handling chmod (when mounted with 8Add ability to modify cifs acls for handling chmod (when mounted with
9cifsacl flag). Fix prefixpath path separator so we can handle mounts 9cifsacl flag). Fix prefixpath path separator so we can handle mounts
10with prefixpaths longer than one directory (one path component) when 10with prefixpaths longer than one directory (one path component) when
11mounted to Windows servers. 11mounted to Windows servers. Fix slow file open when cifsacl
12enabled.
12 13
13Version 1.51 14Version 1.51
14------------ 15------------
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 56c924033b78..f53f41ff1665 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -23,7 +23,7 @@
23#include "dns_resolve.h" 23#include "dns_resolve.h"
24#include "cifs_debug.h" 24#include "cifs_debug.h"
25 25
26LIST_HEAD(cifs_dfs_automount_list); 26static LIST_HEAD(cifs_dfs_automount_list);
27 27
28/* 28/*
29 * DFS functions 29 * DFS functions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 1cb5b0a9f2ac..e99d4faf5f02 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -516,7 +516,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
516 516
517/* Convert permission bits from mode to equivalent CIFS ACL */ 517/* Convert permission bits from mode to equivalent CIFS ACL */
518static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, 518static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
519 int acl_len, struct inode *inode, __u64 nmode) 519 struct inode *inode, __u64 nmode)
520{ 520{
521 int rc = 0; 521 int rc = 0;
522 __u32 dacloffset; 522 __u32 dacloffset;
@@ -692,14 +692,14 @@ void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid)
692int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) 692int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
693{ 693{
694 int rc = 0; 694 int rc = 0;
695 __u32 acllen = 0; 695 __u32 secdesclen = 0;
696 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ 696 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
697 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ 697 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
698 698
699 cFYI(DBG2, ("set ACL from mode for %s", path)); 699 cFYI(DBG2, ("set ACL from mode for %s", path));
700 700
701 /* Get the security descriptor */ 701 /* Get the security descriptor */
702 pntsd = get_cifs_acl(&acllen, inode, path, NULL); 702 pntsd = get_cifs_acl(&secdesclen, inode, path, NULL);
703 703
704 /* Add three ACEs for owner, group, everyone getting rid of 704 /* Add three ACEs for owner, group, everyone getting rid of
705 other ACEs as chmod disables ACEs and set the security descriptor */ 705 other ACEs as chmod disables ACEs and set the security descriptor */
@@ -709,20 +709,22 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
709 set security descriptor request security descriptor 709 set security descriptor request security descriptor
710 parameters, and secuirty descriptor itself */ 710 parameters, and secuirty descriptor itself */
711 711
712 pnntsd = kmalloc(acllen, GFP_KERNEL); 712 secdesclen = secdesclen < DEFSECDESCLEN ?
713 DEFSECDESCLEN : secdesclen;
714 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
713 if (!pnntsd) { 715 if (!pnntsd) {
714 cERROR(1, ("Unable to allocate security descriptor")); 716 cERROR(1, ("Unable to allocate security descriptor"));
715 kfree(pntsd); 717 kfree(pntsd);
716 return (-ENOMEM); 718 return (-ENOMEM);
717 } 719 }
718 720
719 rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); 721 rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
720 722
721 cFYI(DBG2, ("build_sec_desc rc: %d", rc)); 723 cFYI(DBG2, ("build_sec_desc rc: %d", rc));
722 724
723 if (!rc) { 725 if (!rc) {
724 /* Set the security descriptor */ 726 /* Set the security descriptor */
725 rc = set_cifs_acl(pnntsd, acllen, inode, path); 727 rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
726 cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); 728 cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
727 } 729 }
728 730
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 93a7c3462ea2..6c8096cf5155 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -27,6 +27,7 @@
27#define NUM_SUBAUTHS 5 /* number of sub authority fields */ 27#define NUM_SUBAUTHS 5 /* number of sub authority fields */
28#define NUM_WK_SIDS 7 /* number of well known sids */ 28#define NUM_WK_SIDS 7 /* number of well known sids */
29#define SIDNAMELENGTH 20 /* long enough for the ones we care about */ 29#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
30#define DEFSECDESCLEN 192 /* sec desc len contaiting a dacl with three aces */
30 31
31#define READ_BIT 0x4 32#define READ_BIT 0x4
32#define WRITE_BIT 0x2 33#define WRITE_BIT 0x2
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 68978306c3ca..e1dd9f32e1d7 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -62,11 +62,9 @@ extern int cifs_setattr(struct dentry *, struct iattr *);
62 62
63extern const struct inode_operations cifs_file_inode_ops; 63extern const struct inode_operations cifs_file_inode_ops;
64extern const struct inode_operations cifs_symlink_inode_ops; 64extern const struct inode_operations cifs_symlink_inode_ops;
65extern struct list_head cifs_dfs_automount_list;
66extern struct inode_operations cifs_dfs_referral_inode_operations; 65extern struct inode_operations cifs_dfs_referral_inode_operations;
67 66
68 67
69
70/* Functions related to files and directories */ 68/* Functions related to files and directories */
71extern const struct file_operations cifs_file_ops; 69extern const struct file_operations cifs_file_ops;
72extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ 70extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7e5e0e78cd72..0c83da4a7dab 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -84,6 +84,7 @@ extern __u16 GetNextMid(struct TCP_Server_Info *server);
84extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, 84extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
85 struct cifsTconInfo *); 85 struct cifsTconInfo *);
86extern void DeleteOplockQEntry(struct oplock_q_entry *); 86extern void DeleteOplockQEntry(struct oplock_q_entry *);
87extern void DeleteTconOplockQEntries(struct cifsTconInfo *);
87extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); 88extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601);
88extern u64 cifs_UnixTimeToNT(struct timespec); 89extern u64 cifs_UnixTimeToNT(struct timespec);
89extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); 90extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 30bbe448e260..4728fa982a4e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -165,17 +165,19 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
165 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 165 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
166 tcon, nls_codepage); 166 tcon, nls_codepage);
167 up(&tcon->ses->sesSem); 167 up(&tcon->ses->sesSem);
168 /* tell server which Unix caps we support */
169 if (tcon->ses->capabilities & CAP_UNIX)
170 reset_cifs_unix_caps(0 /* no xid */,
171 tcon,
172 NULL /* we do not know sb */,
173 NULL /* no vol info */);
174 /* BB FIXME add code to check if wsize needs 168 /* BB FIXME add code to check if wsize needs
175 update due to negotiated smb buffer size 169 update due to negotiated smb buffer size
176 shrinking */ 170 shrinking */
177 if (rc == 0) 171 if (rc == 0) {
178 atomic_inc(&tconInfoReconnectCount); 172 atomic_inc(&tconInfoReconnectCount);
173 /* tell server Unix caps we support */
174 if (tcon->ses->capabilities & CAP_UNIX)
175 reset_cifs_unix_caps(
176 0 /* no xid */,
177 tcon,
178 NULL /* we do not know sb */,
179 NULL /* no vol info */);
180 }
179 181
180 cFYI(1, ("reconnect tcon rc = %d", rc)); 182 cFYI(1, ("reconnect tcon rc = %d", rc));
181 /* Removed call to reopen open files here. 183 /* Removed call to reopen open files here.
@@ -310,17 +312,19 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
310 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 312 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
311 tcon, nls_codepage); 313 tcon, nls_codepage);
312 up(&tcon->ses->sesSem); 314 up(&tcon->ses->sesSem);
313 /* tell server which Unix caps we support */
314 if (tcon->ses->capabilities & CAP_UNIX)
315 reset_cifs_unix_caps(0 /* no xid */,
316 tcon,
317 NULL /* do not know sb */,
318 NULL /* no vol info */);
319 /* BB FIXME add code to check if wsize needs 315 /* BB FIXME add code to check if wsize needs
320 update due to negotiated smb buffer size 316 update due to negotiated smb buffer size
321 shrinking */ 317 shrinking */
322 if (rc == 0) 318 if (rc == 0) {
323 atomic_inc(&tconInfoReconnectCount); 319 atomic_inc(&tconInfoReconnectCount);
320 /* tell server Unix caps we support */
321 if (tcon->ses->capabilities & CAP_UNIX)
322 reset_cifs_unix_caps(
323 0 /* no xid */,
324 tcon,
325 NULL /* do not know sb */,
326 NULL /* no vol info */);
327 }
324 328
325 cFYI(1, ("reconnect tcon rc = %d", rc)); 329 cFYI(1, ("reconnect tcon rc = %d", rc));
326 /* Removed call to reopen open files here. 330 /* Removed call to reopen open files here.
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8dbfa97cd18c..e17106730168 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3527,6 +3527,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3527 FreeXid(xid); 3527 FreeXid(xid);
3528 return 0; 3528 return 0;
3529 } 3529 }
3530 DeleteTconOplockQEntries(cifs_sb->tcon);
3530 tconInfoFree(cifs_sb->tcon); 3531 tconInfoFree(cifs_sb->tcon);
3531 if ((ses) && (ses->server)) { 3532 if ((ses) && (ses->server)) {
3532 /* save off task so we do not refer to ses later */ 3533 /* save off task so we do not refer to ses later */
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 3612d6c0a0bb..000ac509c98a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -142,6 +142,24 @@ void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
142 kmem_cache_free(cifs_oplock_cachep, oplockEntry); 142 kmem_cache_free(cifs_oplock_cachep, oplockEntry);
143} 143}
144 144
145
146void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
147{
148 struct oplock_q_entry *temp;
149
150 if (tcon == NULL)
151 return;
152
153 spin_lock(&GlobalMid_Lock);
154 list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
155 if ((temp->tcon) && (temp->tcon == tcon)) {
156 list_del(&temp->qhead);
157 kmem_cache_free(cifs_oplock_cachep, temp);
158 }
159 }
160 spin_unlock(&GlobalMid_Lock);
161}
162
145int 163int
146smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, 164smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
147 unsigned int smb_buf_length, struct sockaddr *sin) 165 unsigned int smb_buf_length, struct sockaddr *sin)