Changeset View
Changeset View
Standalone View
Standalone View
smb/kio_smb_browse.cpp
Show First 20 Lines • Show All 646 Lines • ▼ Show 20 Line(s) | 643 | { | |||
---|---|---|---|---|---|
647 | // requesting free space for smb:// which doesn't | 647 | // requesting free space for smb:// which doesn't | ||
648 | // make sense to do to begin with | 648 | // make sense to do to begin with | ||
649 | if (url.host().isEmpty()) { | 649 | if (url.host().isEmpty()) { | ||
650 | error(KIO::ERR_COULD_NOT_STAT, url.url()); | 650 | error(KIO::ERR_COULD_NOT_STAT, url.url()); | ||
651 | return; | 651 | return; | ||
652 | } | 652 | } | ||
653 | 653 | | |||
654 | SMBUrl smbcUrl = url; | 654 | SMBUrl smbcUrl = url; | ||
655 | int handle = smbc_opendir(smbcUrl.toSmbcUrl()); | | |||
656 | if (handle < 0) { | | |||
657 | error(KIO::ERR_COULD_NOT_STAT, url.url()); | | |||
658 | return; | | |||
659 | } | | |||
660 | 655 | | |||
661 | struct statvfs dirStat; | 656 | struct statvfs dirStat; | ||
662 | memset(&dirStat, 0, sizeof(struct statvfs)); | 657 | memset(&dirStat, 0, sizeof(struct statvfs)); | ||
663 | int err = smbc_fstatvfs(handle, &dirStat); | 658 | const int err = smbc_statvfs(smbcUrl.toSmbcUrl().data(), &dirStat); | ||
664 | smbc_closedir(handle); | | |||
665 | | ||||
666 | if (err < 0) { | 659 | if (err < 0) { | ||
667 | error(KIO::ERR_COULD_NOT_STAT, url.url()); | 660 | error(KIO::ERR_COULD_NOT_STAT, url.url()); | ||
668 | return; | 661 | return; | ||
669 | } | 662 | } | ||
670 | 663 | | |||
671 | KIO::filesize_t blockSize; | 664 | // libsmb_stat.c has very awkward conditional branching that results | ||
672 | if (dirStat.f_frsize != 0) { | 665 | // in data meaning different things based on context: | ||
673 | blockSize = dirStat.f_frsize; | 666 | // A samba host with unix extensions has f_frsize==0 and the f_bsize is | ||
674 | } else { | 667 | // the actual block size. Any other server (such as windows) has a non-zero | ||
675 | blockSize = dirStat.f_bsize; | 668 | // f_frsize denoting the amount of sectors in a block and the f_bsize is | ||
676 | } | 669 | // the amount of bytes in a sector. As such frsize*bsize is the actual | ||
670 | // block size. | ||||
671 | // This was also broken in different ways throughout history, so depending | ||||
672 | // on the specific libsmbc versions the milage will vary. 4.7 to 4.11 are | ||||
673 | // at least behaving as described though. | ||||
674 | // https://bugs.kde.org/show_bug.cgi?id=298801 | ||||
675 | const auto frames = (dirStat.f_frsize == 0) ? 1 : dirStat.f_frsize; | ||||
676 | const auto blockSize = dirStat.f_bsize * frames; | ||||
677 | // Further more on older versions of samba f_bavail may not be set... | ||||
678 | const auto total = blockSize * dirStat.f_blocks; | ||||
679 | const auto available = blockSize * ((dirStat.f_bavail != 0) ? dirStat.f_bavail : dirStat.f_bfree); | ||||
677 | 680 | | |||
678 | setMetaData("total", QString::number(blockSize * dirStat.f_blocks)); | 681 | setMetaData("total", QString::number(total)); | ||
679 | setMetaData("available", QString::number(blockSize * dirStat.f_bavail)); | 682 | setMetaData("available", QString::number(available)); | ||
680 | 683 | | |||
681 | finished(); | 684 | finished(); | ||
682 | } | 685 | } | ||
683 | 686 | | |||
684 | bool SMBSlave::workaroundEEXIST(const int errNum) const | 687 | bool SMBSlave::workaroundEEXIST(const int errNum) const | ||
685 | { | 688 | { | ||
686 | return (errNum == EEXIST) && m_enableEEXISTWorkaround; | 689 | return (errNum == EEXIST) && m_enableEEXISTWorkaround; | ||
687 | } | 690 | } | ||
688 | 691 | |