Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!spool.mu.edu!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.unix.internals Subject: Re: What, exactly, are stat.st_blocks, statfs.f_b Message-ID: <6428@auspex.auspex.com> Date: 5 Mar 91 09:10:35 GMT References: <1991Mar4.001026.3043@athena.mit.edu> <1991Mar04.015451.10436@kithrup.COM> Organization: Auspex Systems, Santa Clara Lines: 116 >Yep. The fact that there is no way in SunOS (prior to 4.0 or 4.1, since >those are supposed to be SysVr4 compatible, Umm, no, they're not. Some Sun Marketoons may have claimed, without proper qualification, that they're completely compatible; they're pretty close, but they're *not* completely compatible. SunOS 4.x has the same "statfs()" call that SunOS releases prior to 4.x did. >which is SysVr3.2 compatible, meaning it should have the statfs() call) S5R4 does, I presume, have the same "statfs()" call as S5R3; however the call you're *supposed* to use in S5R4 is "statvfs()", which is a new call in S5R4, atoning for S5R3's error in having a "statfs()" call with the same name as SunOS's but incompatible semantics. You don't need to use that call to find out the units of "st_blocks", though; the S5R4 manual states that "st_blocks" is "the total number of physical blocks of size 512 bytes actually allocated on disk." Presumably, if the allocation granularity of the disk, or of the file system, is in blocks that are some multiple of 512 bytes in size, the number-of-blocks will be multiplied by that multiple to get the number of 512-byte chunks. If it's the units are less than 512 bytes, the system'd have to *divide* by the ratio of sizes, and if the ratio of sizes isn't integral, you'd have a problem; fortunately, I suspect most UNIX systems have disks whose sector size is some multiple of 512 bytes (the only exceptions may be assorted mainframes, such as IBM mainframes, although the UNIXes on those systems may, when not working on fixed-block-size disks, use some standard block size - I don't think anybody's ported UNIX to the IBM 1130, so that doesn't count... :-)). The SunOS documentation doesn't say what the units are, but "st_blocks" is in units of 512 bytes on UFS and on NFS to most if not all UNIX servers, and should be in units of 512 bytes on any other file systems plugged into your system. The NFS protocol spec does not, alas, do a very good job of explaining the fields of the "fattr" structure, so it's conceivable that a server writer may not return a file size in 512-byte units in the "blocks" field. It *should* have indicated that the "blocksize" field is the block size *recommended for I/O*, rather than the block size used as units for the "blocks" field, as the "blocksize" field is what gets turned into the "st_blksize" field, and that field - in BSD, in SunOS, and in S5R4 - is the recommended block size for I/O operations. It should also have indicated that the "blocks" field should be in units of 512 bytes. As for "statfs()" a la SunOS, "statfs()" a la S5R3, and "statvfs()" a la S5R4 (including, I assume, Sun's current "developer's release" of S5R4, and any future Sun releases of S5R4): SunOS "struct statfs" includes: long f_bsize; /* fundamental file system block size */ long f_blocks; /* total blocks in file system */ long f_bfree; /* free blocks */ long f_bavail; /* free blocks available to non-super-user */ where "f_bsize" is the unit of allocation of the particular file system - i.e., on a BSD/UFS file system, the "fragment size", which may be bigger than the sector size; it's typically 1K on Sun systems, even though the sector size is 512 bytes. "st_bfree" and "st_bavail" are in units of "f_bsize", not units of 512 bytes. (Determined by checking the code; it's not well-documented.) S5R3's "struct statfs" includes: long f_bsize; /* Block size */ long f_frsize; /* Fragment size (if supported) */ long f_blocks; /* Total number of blocks on file system */ long f_bfree; /* Total number of free blocks */ where "f_bsize" is, on S5 file systems, the unit of allocation of the particular file system - i.e., on a 1K file system, it's 1K, and on a 512-byte file system, it's 512 bytes. "f_frsize" is 0. (All as of S5R3.1, from checking the code.) Dunno what's done on S5 systems that support a BSD file system; one presumes the idea is that "fs_bsize" is the "block size", and "fs_fsize" is the "fragment size", the *latter* being the true unit of allocation, and the former being more the suggested unit of I/O. "f_blocks" and "f_bfree" are in units of 512-byte chunks. S5R4's "struct statvfs" includes: ulong f_bsize; /* preferred file system block size */ ulong f_frsize; /* fundamental filesystem block size (if supported) */ ulong f_blocks; /* total # of blocks on file system in units of f_frsize */ ulong f_bfree; /* total # of free blocks */ ulong f_bavail; /* # of free blocks avail to non-superuser */ I'm not sure what this "(if supported)" nonsense is for "f_frsize"; if it's not "supported", the "f_blocks" and, presumably, "f_bfree" and "f_bavail" fields are meaningless, as the former is documented as being in units of "f_frsize" and the other two are, I assume, also in those units. I suspect that, for an S5 file system, both "f_bsize" and "f_frsize" are supported; dunno whether the latter is 512 or the block size of the file system. Dunno whether "f_bsize" is the block size of the file system, or 512, or 1024, or what. For a BSD/UFS file system, "f_bsize" is probably the block size (recommended I/O size) and "f_frsize" is probably the fragment size (unit of allocation). (Determined from reading the documentation.)