diff options
| -rw-r--r-- | fs/cifs/CHANGES | 3 | ||||
| -rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsacl.c | 14 | ||||
| -rw-r--r-- | fs/cifs/cifsacl.h | 1 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 32 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 1 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 18 |
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). | |||
| 8 | Add ability to modify cifs acls for handling chmod (when mounted with | 8 | Add ability to modify cifs acls for handling chmod (when mounted with |
| 9 | cifsacl flag). Fix prefixpath path separator so we can handle mounts | 9 | cifsacl flag). Fix prefixpath path separator so we can handle mounts |
| 10 | with prefixpaths longer than one directory (one path component) when | 10 | with prefixpaths longer than one directory (one path component) when |
| 11 | mounted to Windows servers. | 11 | mounted to Windows servers. Fix slow file open when cifsacl |
| 12 | enabled. | ||
| 12 | 13 | ||
| 13 | Version 1.51 | 14 | Version 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 | ||
| 26 | LIST_HEAD(cifs_dfs_automount_list); | 26 | static 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 */ |
| 518 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 518 | static 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) | |||
| 692 | int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | 692 | int 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 | ||
| 63 | extern const struct inode_operations cifs_file_inode_ops; | 63 | extern const struct inode_operations cifs_file_inode_ops; |
| 64 | extern const struct inode_operations cifs_symlink_inode_ops; | 64 | extern const struct inode_operations cifs_symlink_inode_ops; |
| 65 | extern struct list_head cifs_dfs_automount_list; | ||
| 66 | extern struct inode_operations cifs_dfs_referral_inode_operations; | 65 | extern 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 */ |
| 71 | extern const struct file_operations cifs_file_ops; | 69 | extern const struct file_operations cifs_file_ops; |
| 72 | extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ | 70 | extern 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); | |||
| 84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | 84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, |
| 85 | struct cifsTconInfo *); | 85 | struct cifsTconInfo *); |
| 86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
| 87 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); | ||
| 87 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); | 88 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); |
| 88 | extern u64 cifs_UnixTimeToNT(struct timespec); | 89 | extern u64 cifs_UnixTimeToNT(struct timespec); |
| 89 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 90 | extern __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 | |||
| 146 | void 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 | |||
| 145 | int | 163 | int |
| 146 | smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | 164 | smb_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) |
