diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d4ce77a02327..e7931cc55d0c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
39 | #include <linux/random.h> | ||
39 | #include <net/ipv6.h> | 40 | #include <net/ipv6.h> |
40 | #include "cifsfs.h" | 41 | #include "cifsfs.h" |
41 | #include "cifspdu.h" | 42 | #include "cifspdu.h" |
@@ -51,7 +52,6 @@ | |||
51 | #ifdef CONFIG_CIFS_SMB2 | 52 | #ifdef CONFIG_CIFS_SMB2 |
52 | #include "smb2pdu.h" | 53 | #include "smb2pdu.h" |
53 | #endif | 54 | #endif |
54 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ | ||
55 | 55 | ||
56 | int cifsFYI = 0; | 56 | int cifsFYI = 0; |
57 | int cifsERROR = 1; | 57 | int cifsERROR = 1; |
@@ -89,6 +89,10 @@ extern mempool_t *cifs_mid_poolp; | |||
89 | 89 | ||
90 | struct workqueue_struct *cifsiod_wq; | 90 | struct workqueue_struct *cifsiod_wq; |
91 | 91 | ||
92 | #ifdef CONFIG_CIFS_SMB2 | ||
93 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; | ||
94 | #endif | ||
95 | |||
92 | static int | 96 | static int |
93 | cifs_read_super(struct super_block *sb) | 97 | cifs_read_super(struct super_block *sb) |
94 | { | 98 | { |
@@ -160,13 +164,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
160 | struct super_block *sb = dentry->d_sb; | 164 | struct super_block *sb = dentry->d_sb; |
161 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 165 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
162 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | 166 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
163 | int rc = -EOPNOTSUPP; | 167 | struct TCP_Server_Info *server = tcon->ses->server; |
164 | unsigned int xid; | 168 | unsigned int xid; |
169 | int rc = 0; | ||
165 | 170 | ||
166 | xid = get_xid(); | 171 | xid = get_xid(); |
167 | 172 | ||
168 | buf->f_type = CIFS_MAGIC_NUMBER; | ||
169 | |||
170 | /* | 173 | /* |
171 | * PATH_MAX may be too long - it would presumably be total path, | 174 | * PATH_MAX may be too long - it would presumably be total path, |
172 | * but note that some servers (includinng Samba 3) have a shorter | 175 | * but note that some servers (includinng Samba 3) have a shorter |
@@ -178,27 +181,8 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
178 | buf->f_files = 0; /* undefined */ | 181 | buf->f_files = 0; /* undefined */ |
179 | buf->f_ffree = 0; /* unlimited */ | 182 | buf->f_ffree = 0; /* unlimited */ |
180 | 183 | ||
181 | /* | 184 | if (server->ops->queryfs) |
182 | * We could add a second check for a QFS Unix capability bit | 185 | rc = server->ops->queryfs(xid, tcon, buf); |
183 | */ | ||
184 | if ((tcon->ses->capabilities & CAP_UNIX) && | ||
185 | (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability))) | ||
186 | rc = CIFSSMBQFSPosixInfo(xid, tcon, buf); | ||
187 | |||
188 | /* | ||
189 | * Only need to call the old QFSInfo if failed on newer one, | ||
190 | * e.g. by OS/2. | ||
191 | **/ | ||
192 | if (rc && (tcon->ses->capabilities & CAP_NT_SMBS)) | ||
193 | rc = CIFSSMBQFSInfo(xid, tcon, buf); | ||
194 | |||
195 | /* | ||
196 | * Some old Windows servers also do not support level 103, retry with | ||
197 | * older level one if old server failed the previous call or we | ||
198 | * bypassed it because we detected that this was an older LANMAN sess | ||
199 | */ | ||
200 | if (rc) | ||
201 | rc = SMBOldQFSInfo(xid, tcon, buf); | ||
202 | 186 | ||
203 | free_xid(xid); | 187 | free_xid(xid); |
204 | return 0; | 188 | return 0; |
@@ -239,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb) | |||
239 | return NULL; | 223 | return NULL; |
240 | cifs_inode->cifsAttrs = 0x20; /* default */ | 224 | cifs_inode->cifsAttrs = 0x20; /* default */ |
241 | cifs_inode->time = 0; | 225 | cifs_inode->time = 0; |
242 | /* Until the file is open and we have gotten oplock | 226 | /* |
243 | info back from the server, can not assume caching of | 227 | * Until the file is open and we have gotten oplock info back from the |
244 | file data or metadata */ | 228 | * server, can not assume caching of file data or metadata. |
229 | */ | ||
245 | cifs_set_oplock_level(cifs_inode, 0); | 230 | cifs_set_oplock_level(cifs_inode, 0); |
246 | cifs_inode->delete_pending = false; | 231 | cifs_inode->delete_pending = false; |
247 | cifs_inode->invalid_mapping = false; | 232 | cifs_inode->invalid_mapping = false; |
@@ -249,11 +234,16 @@ cifs_alloc_inode(struct super_block *sb) | |||
249 | cifs_inode->server_eof = 0; | 234 | cifs_inode->server_eof = 0; |
250 | cifs_inode->uniqueid = 0; | 235 | cifs_inode->uniqueid = 0; |
251 | cifs_inode->createtime = 0; | 236 | cifs_inode->createtime = 0; |
252 | 237 | #ifdef CONFIG_CIFS_SMB2 | |
253 | /* Can not set i_flags here - they get immediately overwritten | 238 | get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); |
254 | to zero by the VFS */ | 239 | #endif |
255 | /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/ | 240 | /* |
241 | * Can not set i_flags here - they get immediately overwritten to zero | ||
242 | * by the VFS. | ||
243 | */ | ||
244 | /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */ | ||
256 | INIT_LIST_HEAD(&cifs_inode->openFileList); | 245 | INIT_LIST_HEAD(&cifs_inode->openFileList); |
246 | INIT_LIST_HEAD(&cifs_inode->llist); | ||
257 | return &cifs_inode->vfs_inode; | 247 | return &cifs_inode->vfs_inode; |
258 | } | 248 | } |
259 | 249 | ||
@@ -360,7 +350,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
360 | cifs_show_security(s, tcon->ses->server); | 350 | cifs_show_security(s, tcon->ses->server); |
361 | cifs_show_cache_flavor(s, cifs_sb); | 351 | cifs_show_cache_flavor(s, cifs_sb); |
362 | 352 | ||
363 | seq_printf(s, ",unc=%s", tcon->treeName); | 353 | seq_printf(s, ",unc="); |
354 | seq_escape(s, tcon->treeName, " \t\n\\"); | ||
364 | 355 | ||
365 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) | 356 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) |
366 | seq_printf(s, ",multiuser"); | 357 | seq_printf(s, ",multiuser"); |
@@ -957,7 +948,7 @@ cifs_init_once(void *inode) | |||
957 | struct cifsInodeInfo *cifsi = inode; | 948 | struct cifsInodeInfo *cifsi = inode; |
958 | 949 | ||
959 | inode_init_once(&cifsi->vfs_inode); | 950 | inode_init_once(&cifsi->vfs_inode); |
960 | mutex_init(&cifsi->lock_mutex); | 951 | init_rwsem(&cifsi->lock_sem); |
961 | } | 952 | } |
962 | 953 | ||
963 | static int | 954 | static int |
@@ -1132,6 +1123,10 @@ init_cifs(void) | |||
1132 | spin_lock_init(&cifs_file_list_lock); | 1123 | spin_lock_init(&cifs_file_list_lock); |
1133 | spin_lock_init(&GlobalMid_Lock); | 1124 | spin_lock_init(&GlobalMid_Lock); |
1134 | 1125 | ||
1126 | #ifdef CONFIG_CIFS_SMB2 | ||
1127 | get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE); | ||
1128 | #endif | ||
1129 | |||
1135 | if (cifs_max_pending < 2) { | 1130 | if (cifs_max_pending < 2) { |
1136 | cifs_max_pending = 2; | 1131 | cifs_max_pending = 2; |
1137 | cFYI(1, "cifs_max_pending set to min of 2"); | 1132 | cFYI(1, "cifs_max_pending set to min of 2"); |