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
This commit is contained in:
parent
c31159ae1b
commit
14b2dc3952
@ -135,8 +135,49 @@ smbfs_smb_lock(struct smbnode *np, int op, caddr_t id,
|
||||
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, struct statfs *sbp,
|
||||
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, struct statfs *sbp,
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -390,7 +390,7 @@ smbfs_statfs(struct mount *mp, struct statfs *sbp)
|
||||
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 statfs *sbp)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user