aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsfs.c29
-rw-r--r--fs/cifs/cifsglob.h5
-rw-r--r--fs/cifs/smb1ops.c34
3 files changed, 43 insertions, 25 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 2829f374dbf7..4dda4890d776 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -51,7 +51,6 @@
51#ifdef CONFIG_CIFS_SMB2 51#ifdef CONFIG_CIFS_SMB2
52#include "smb2pdu.h" 52#include "smb2pdu.h"
53#endif 53#endif
54#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
55 54
56int cifsFYI = 0; 55int cifsFYI = 0;
57int cifsERROR = 1; 56int cifsERROR = 1;
@@ -164,13 +163,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
164 struct super_block *sb = dentry->d_sb; 163 struct super_block *sb = dentry->d_sb;
165 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 164 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
166 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 165 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
167 int rc = -EOPNOTSUPP; 166 struct TCP_Server_Info *server = tcon->ses->server;
168 unsigned int xid; 167 unsigned int xid;
168 int rc = 0;
169 169
170 xid = get_xid(); 170 xid = get_xid();
171 171
172 buf->f_type = CIFS_MAGIC_NUMBER;
173
174 /* 172 /*
175 * PATH_MAX may be too long - it would presumably be total path, 173 * PATH_MAX may be too long - it would presumably be total path,
176 * but note that some servers (includinng Samba 3) have a shorter 174 * but note that some servers (includinng Samba 3) have a shorter
@@ -182,27 +180,8 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
182 buf->f_files = 0; /* undefined */ 180 buf->f_files = 0; /* undefined */
183 buf->f_ffree = 0; /* unlimited */ 181 buf->f_ffree = 0; /* unlimited */
184 182
185 /* 183 if (server->ops->queryfs)
186 * We could add a second check for a QFS Unix capability bit 184 rc = server->ops->queryfs(xid, tcon, buf);
187 */
188 if ((tcon->ses->capabilities & CAP_UNIX) &&
189 (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
190 rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
191
192 /*
193 * Only need to call the old QFSInfo if failed on newer one,
194 * e.g. by OS/2.
195 **/
196 if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
197 rc = CIFSSMBQFSInfo(xid, tcon, buf);
198
199 /*
200 * Some old Windows servers also do not support level 103, retry with
201 * older level one if old server failed the previous call or we
202 * bypassed it because we detected that this was an older LANMAN sess
203 */
204 if (rc)
205 rc = SMBOldQFSInfo(xid, tcon, buf);
206 185
207 free_xid(xid); 186 free_xid(xid);
208 return 0; 187 return 0;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a95c56dc7058..3c007fe641f9 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -32,6 +32,8 @@
32#include "smb2pdu.h" 32#include "smb2pdu.h"
33#endif 33#endif
34 34
35#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
36
35/* 37/*
36 * The sizes of various internal tables and strings 38 * The sizes of various internal tables and strings
37 */ 39 */
@@ -334,6 +336,9 @@ struct smb_version_operations {
334 /* send oplock break response */ 336 /* send oplock break response */
335 int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, 337 int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *,
336 struct cifsInodeInfo *); 338 struct cifsInodeInfo *);
339 /* query remote filesystem */
340 int (*queryfs)(const unsigned int, struct cifs_tcon *,
341 struct kstatfs *);
337}; 342};
338 343
339struct smb_version_values { 344struct smb_version_values {
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index f55b2e3476e8..f6c7a1c9a1b6 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/pagemap.h> 20#include <linux/pagemap.h>
21#include <linux/vfs.h>
21#include "cifsglob.h" 22#include "cifsglob.h"
22#include "cifsproto.h" 23#include "cifsproto.h"
23#include "cifs_debug.h" 24#include "cifs_debug.h"
@@ -872,6 +873,38 @@ cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
872 cinode->clientCanCacheRead ? 1 : 0); 873 cinode->clientCanCacheRead ? 1 : 0);
873} 874}
874 875
876static int
877cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
878 struct kstatfs *buf)
879{
880 int rc = -EOPNOTSUPP;
881
882 buf->f_type = CIFS_MAGIC_NUMBER;
883
884 /*
885 * We could add a second check for a QFS Unix capability bit
886 */
887 if ((tcon->ses->capabilities & CAP_UNIX) &&
888 (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
889 rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
890
891 /*
892 * Only need to call the old QFSInfo if failed on newer one,
893 * e.g. by OS/2.
894 **/
895 if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
896 rc = CIFSSMBQFSInfo(xid, tcon, buf);
897
898 /*
899 * Some old Windows servers also do not support level 103, retry with
900 * older level one if old server failed the previous call or we
901 * bypassed it because we detected that this was an older LANMAN sess
902 */
903 if (rc)
904 rc = SMBOldQFSInfo(xid, tcon, buf);
905 return rc;
906}
907
875struct smb_version_operations smb1_operations = { 908struct smb_version_operations smb1_operations = {
876 .send_cancel = send_nt_cancel, 909 .send_cancel = send_nt_cancel,
877 .compare_fids = cifs_compare_fids, 910 .compare_fids = cifs_compare_fids,
@@ -932,6 +965,7 @@ struct smb_version_operations smb1_operations = {
932 .close_dir = cifs_close_dir, 965 .close_dir = cifs_close_dir,
933 .calc_smb_size = smbCalcSize, 966 .calc_smb_size = smbCalcSize,
934 .oplock_response = cifs_oplock_response, 967 .oplock_response = cifs_oplock_response,
968 .queryfs = cifs_queryfs,
935}; 969};
936 970
937struct smb_version_values smb1_values = { 971struct smb_version_values smb1_values = {