Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Apr 2014 09:10:01 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264494 - head/sys/fs/smbfs
Message-ID:  <201404150910.s3F9A1TF036749@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Apr 15 09:10:01 2014
New Revision: 264494
URL: http://svnweb.freebsd.org/changeset/base/264494

Log:
  Use SMB_QUERY_FS_SIZE_INFO request to populate statfs structure.
  When server doesn't support this request, try to use SMB_INFO_ALLOCATION.
  And use SMB_COM_QUERY_INFORMATION_DISK request as fallback.
  
  MFC after:	2 weeks

Modified:
  head/sys/fs/smbfs/smbfs_smb.c
  head/sys/fs/smbfs/smbfs_subr.h
  head/sys/fs/smbfs/smbfs_vfsops.c

Modified: head/sys/fs/smbfs/smbfs_smb.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_smb.c	Tue Apr 15 08:08:44 2014	(r264493)
+++ head/sys/fs/smbfs/smbfs_smb.c	Tue Apr 15 09:10:01 2014	(r264494)
@@ -135,8 +135,49 @@ smbfs_smb_lock(struct smbnode *np, int o
 		return smbfs_smb_lockandx(np, op, (uintptr_t)id, start, end, scred);
 }
 
-int
-smbfs_smb_statfs2(struct smb_share *ssp, struct statfs *sbp,
+static int
+smbfs_query_info_fs(struct smb_share *ssp, struct statfs *sbp,
+	struct smb_cred *scred)
+{
+	struct smb_t2rq *t2p;
+	struct mbchain *mbp;
+	struct mdchain *mdp;
+	uint32_t bsize, bpu;
+	int64_t units, funits;
+	int error;
+
+	error = smb_t2_alloc(SSTOCP(ssp), SMB_TRANS2_QUERY_FS_INFORMATION,
+	    scred, &t2p);
+	if (error)
+		return (error);
+	mbp = &t2p->t2_tparam;
+	mb_init(mbp);
+	mb_put_uint16le(mbp, SMB_QUERY_FS_SIZE_INFO);
+	t2p->t2_maxpcount = 2;
+	t2p->t2_maxdcount = sizeof(int64_t) * 2 + sizeof(uint32_t) * 2;
+	error = smb_t2_request(t2p);
+	if (error) {
+		smb_t2_done(t2p);
+		return (error);
+	}
+	mdp = &t2p->t2_rdata;
+	md_get_int64le(mdp, &units);
+	md_get_int64le(mdp, &funits);
+	md_get_uint32le(mdp, &bpu);
+	md_get_uint32le(mdp, &bsize);
+	sbp->f_bsize = bpu * bsize;	/* fundamental filesystem block size */
+	sbp->f_blocks= (uint64_t)units;	/* total data blocks in filesystem */
+	sbp->f_bfree = (uint64_t)funits;/* free blocks in fs */
+	sbp->f_bavail= (uint64_t)funits;/* free blocks avail to non-superuser */
+	sbp->f_files = 0xffff;		/* total file nodes in filesystem */
+	sbp->f_ffree = 0xffff;		/* free file nodes in fs */
+	smb_t2_done(t2p);
+	return (0);
+}
+
+
+static int
+smbfs_query_info_alloc(struct smb_share *ssp, struct statfs *sbp,
 	struct smb_cred *scred)
 {
 	struct smb_t2rq *t2p;
@@ -176,8 +217,8 @@ smbfs_smb_statfs2(struct smb_share *ssp,
 	return 0;
 }
 
-int
-smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
+static int
+smbfs_query_info_disk(struct smb_share *ssp, struct statfs *sbp,
 	struct smb_cred *scred)
 {
 	struct smb_rq *rqp;
@@ -213,6 +254,20 @@ smbfs_smb_statfs(struct smb_share *ssp, 
 	return 0;
 }
 
+int
+smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
+	struct smb_cred *scred)
+{
+
+	if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0) {
+		if (smbfs_query_info_fs(ssp, sbp, scred) == 0)
+			return (0);
+		if (smbfs_query_info_alloc(ssp, sbp, scred) == 0)
+			return (0);
+	}
+	return (smbfs_query_info_disk(ssp, sbp, scred));
+}
+
 static int
 smbfs_smb_seteof(struct smbnode *np, int64_t newsize, struct smb_cred *scred)
 {

Modified: head/sys/fs/smbfs/smbfs_subr.h
==============================================================================
--- head/sys/fs/smbfs/smbfs_subr.h	Tue Apr 15 08:08:44 2014	(r264493)
+++ head/sys/fs/smbfs/smbfs_subr.h	Tue Apr 15 09:10:01 2014	(r264494)
@@ -126,8 +126,6 @@ struct smbfs_fctx {
  */
 int  smbfs_smb_lock(struct smbnode *np, int op, caddr_t id,
 	off_t start, off_t end,	struct smb_cred *scred);
-int  smbfs_smb_statfs2(struct smb_share *ssp, struct statfs *sbp,
-	struct smb_cred *scred);
 int  smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
 	struct smb_cred *scred);
 int  smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred);

Modified: head/sys/fs/smbfs/smbfs_vfsops.c
==============================================================================
--- head/sys/fs/smbfs/smbfs_vfsops.c	Tue Apr 15 08:08:44 2014	(r264493)
+++ head/sys/fs/smbfs/smbfs_vfsops.c	Tue Apr 15 09:10:01 2014	(r264494)
@@ -390,7 +390,7 @@ smbfs_statfs(struct mount *mp, struct st
 	struct smbnode *np = smp->sm_root;
 	struct smb_share *ssp = smp->sm_share;
 	struct smb_cred *scred;
-	int error = 0;
+	int error;
 
 	if (np == NULL) {
 		vfs_mount_error(mp, "np == NULL");
@@ -400,16 +400,9 @@ smbfs_statfs(struct mount *mp, struct st
 	sbp->f_iosize = SSTOVC(ssp)->vc_txmax;		/* optimal transfer block size */
 	scred = smbfs_malloc_scred();
 	smb_makescred(scred, td, td->td_ucred);
-
-	if (SMB_DIALECT(SSTOVC(ssp)) >= SMB_DIALECT_LANMAN2_0)
-		error = smbfs_smb_statfs2(ssp, sbp, scred);
-	else
-		error = smbfs_smb_statfs(ssp, sbp, scred);
-	if (error) {
-		smbfs_free_scred(scred);
-		return error;
-	}
-	sbp->f_flags = 0;		/* copy of mount exported flags */
+	error = smbfs_smb_statfs(ssp, sbp, scred);
+	if (error == 0)
+		sbp->f_flags = 0;	/* copy of mount exported flags */
 	smbfs_free_scred(scred);
-	return 0;
+	return (error);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404150910.s3F9A1TF036749>