aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r--fs/cifs/cifsfs.c63
1 files changed, 29 insertions, 34 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index db8a404a51dd..a41044a31083 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -36,6 +36,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/namei.h>
+#include <linux/random.h>
#include <net/ipv6.h>
#include "cifsfs.h"
#include "cifspdu.h"
@@ -51,7 +52,6 @@
#ifdef CONFIG_CIFS_SMB2
#include "smb2pdu.h"
#endif
-#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
int cifsFYI = 0;
int cifsERROR = 1;
@@ -89,6 +89,10 @@ extern mempool_t *cifs_mid_poolp;
struct workqueue_struct *cifsiod_wq;
+#ifdef CONFIG_CIFS_SMB2
+__u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE];
+#endif
+
static int
cifs_read_super(struct super_block *sb)
{
@@ -160,13 +164,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- int rc = -EOPNOTSUPP;
+ struct TCP_Server_Info *server = tcon->ses->server;
unsigned int xid;
+ int rc = 0;
xid = get_xid();
- buf->f_type = CIFS_MAGIC_NUMBER;
-
/*
* PATH_MAX may be too long - it would presumably be total path,
* but note that some servers (includinng Samba 3) have a shorter
@@ -178,27 +181,8 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_files = 0; /* undefined */
buf->f_ffree = 0; /* unlimited */
- /*
- * We could add a second check for a QFS Unix capability bit
- */
- if ((tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
- rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
-
- /*
- * Only need to call the old QFSInfo if failed on newer one,
- * e.g. by OS/2.
- **/
- if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
- rc = CIFSSMBQFSInfo(xid, tcon, buf);
-
- /*
- * Some old Windows servers also do not support level 103, retry with
- * older level one if old server failed the previous call or we
- * bypassed it because we detected that this was an older LANMAN sess
- */
- if (rc)
- rc = SMBOldQFSInfo(xid, tcon, buf);
+ if (server->ops->queryfs)
+ rc = server->ops->queryfs(xid, tcon, buf);
free_xid(xid);
return 0;
@@ -239,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb)
return NULL;
cifs_inode->cifsAttrs = 0x20; /* default */
cifs_inode->time = 0;
- /* Until the file is open and we have gotten oplock
- info back from the server, can not assume caching of
- file data or metadata */
+ /*
+ * Until the file is open and we have gotten oplock info back from the
+ * server, can not assume caching of file data or metadata.
+ */
cifs_set_oplock_level(cifs_inode, 0);
cifs_inode->delete_pending = false;
cifs_inode->invalid_mapping = false;
@@ -249,11 +234,16 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->server_eof = 0;
cifs_inode->uniqueid = 0;
cifs_inode->createtime = 0;
-
- /* Can not set i_flags here - they get immediately overwritten
- to zero by the VFS */
-/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
+#ifdef CONFIG_CIFS_SMB2
+ get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE);
+#endif
+ /*
+ * Can not set i_flags here - they get immediately overwritten to zero
+ * by the VFS.
+ */
+ /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */
INIT_LIST_HEAD(&cifs_inode->openFileList);
+ INIT_LIST_HEAD(&cifs_inode->llist);
return &cifs_inode->vfs_inode;
}
@@ -360,7 +350,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
cifs_show_security(s, tcon->ses->server);
cifs_show_cache_flavor(s, cifs_sb);
- seq_printf(s, ",unc=%s", tcon->treeName);
+ seq_printf(s, ",unc=");
+ seq_escape(s, tcon->treeName, " \t\n\\");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
seq_printf(s, ",multiuser");
@@ -957,7 +948,7 @@ cifs_init_once(void *inode)
struct cifsInodeInfo *cifsi = inode;
inode_init_once(&cifsi->vfs_inode);
- mutex_init(&cifsi->lock_mutex);
+ init_rwsem(&cifsi->lock_sem);
}
static int
@@ -1127,6 +1118,10 @@ init_cifs(void)
spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);
+#ifdef CONFIG_CIFS_SMB2
+ get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE);
+#endif
+
if (cifs_max_pending < 2) {
cifs_max_pending = 2;
cFYI(1, "cifs_max_pending set to min of 2");