The following has be reported by IBM LTC: statfs() fills in statfs struct with zero'ed f_fsid (0-0 pair) Hardware Environment: Dual Pentium III 1266 MHz, 2G RAM Software Environment: Red Hat Linux release 7.2, kernel 2.4.9-31enterprise (Also RHAS 3.0) Steps to Reproduce: 1. call statfs() passing any filename and an empty statfs struct 2. dump filled-in statfs struct 3. f_fsid always (0,0) valued integer pair while f_type, f_bsize, etc. valid Actual Results: f_fsid always (0,0) pair rather than file system ID Expected Results: valid file system ID that can be passed to sysfs() to determine file system identifier (e.g. /home, /, etc.) Additional Information: Attached test code to demonstrate this issue. Simply compile and run passing a valid file name.Created an attachment (id=1150) bug-reproducing test program Vincent, Does problem occur for all file system types ? What is the file system type you are using when you hit the problem ? ThanksIn my limited testing, ext2 and ext3 so far. Vincent Hi Vincent, Thanks. Also please append the output of rpm -qa | grep -i glibc so we know which level of glibc you have. We need to re-create problem here to debug. Thanks. $ rpm -qa | grep -i glibc glibc-2.2.4-13 glibc-common-2.2.4-13 compat-glibc-6.2-2.1.3.2 glibc-devel-2.2.4-13 VincentInstalled RH 7.2 - testcase returns 0 for __fsid_t. This is also 0 on SLES 8 - on IA32 and PowerPC. I did man statfs, I did not get any info about what fsid is supposed to return. I am checking with Steve Best ( jfs team lead ) about whether or not anything valid is even put into the fsid field. I will also check with Mark Brown ( glibc standard, LTC lead ) tomorrow about what the standard says. Vincent, why do you need the fsid field. What do you expect to do with it ? Went to talk to David Kleikamp ( jfs development ). He told me jfs currently does not do anything with that field either. He told me it is easy enough to add something like device number into that field like bfs. checking into the kernel source tree, bfs_statfs in /usr/src/linux-2.4/fs/bfs/inode.c sets the fsid field to device number ------------------------------------------------------------------------- static int bfs_statfs(struct super_block *s, struct statfs *buf) { buf->f_type = BFS_MAGIC; buf->f_bsize = s->s_blocksize; buf->f_blocks = s->su_blocks; buf->f_bfree = buf->f_bavail = s->su_freeb; buf->f_files = s->su_lasti + 1 - BFS_ROOT_INO; buf->f_ffree = s->su_freei; buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev); ----> this is the code buf->f_namelen = BFS_NAMELEN; return 0; } ------------------------------------------------------------------------ It should be easy enough to add to for ext2, ext2_statfs is in /usr/src/linux-2.4/fs/ext2/super.c for ext3, ext3_statfs is in /usr/src/linux-2.4/fs/ext3/super.c for reiserfs, reiserfs_statfs is in /usr/src/linux-2.4/fs/reiserfs/super.c I am not sure this should be done on all filesystems on Linux yet. Mark Brown checked into the standards. fsid of 0 is perfectly legit. LSB does not mention anything about what fsid should be. I'll talk to Mark again next week to see the best way to pursue this. Vincent, please let us know why DB2 needs that fsid field and what do you expect it to be. We'd like a unique way of identifying the file system containing a specified file. This can be accomplished either by obtaining a file system ID value (and pass it to sysfs() to get the file system name) or alternatively, by obtaining the file system name directly. VincentAdded Mark Brown to cc list so he can add comments to this problem. Thanks Mark.Opened problem #3436 against jfs so David Kleikamp can put the changes into jfs_statfs. I'll try to get RedHat AS 3.0 alpha and re-create on there. Salina Additionally, we'd entertain any suggestions on workarounds to getting a file system identifier from the system. However, only APIs calls are satisfactory... invoking other programs (e.g. df <filename>) would not be an option. Thanks, Vincent Glen, I borrowed machine that has RHAS 3.0 alpha from LTC test, this problem is still there, so you can report that to RedHat. Thanks. ---------------------------------------------------------------------- [root@nortel salina]# uname -a Linux nortel.ltc.austin.ibm.com 2.4.20-1.1931.2.231.2.11.entbigmem #1 SMP Tue Jun 17 14:35:18 EDT 2003 i686 i686 i386 GNU/Linux [root@nortel salina]# ./test_statfs /skyline/sglass f_fsid.__val[0] = 0 f_fsid.__val[1] = 0 f_type = 6969 f_bsize = 4096 [root@nortel salina]# ./test_statfs /var/log/messages f_fsid.__val[0] = 0 f_fsid.__val[1] = 0 f_type = EF53 f_bsize = 4096 ----------------------------------------------------------------
Created attachment 92919 [details] test case for statfs
------ Additional Comments From shaggy.com(prefers email via shaggy.com) 2003-14-07 16:26 ------- I can't find any definitive documentation on what f_fsid should contain. It doesn't look like it has ever been used in Linux. Additionally, I don't believe sysfs() will give you what you want. I believe it returns "ext2", "ext3", "jfs", etc. The change I had considered would just have returned the device number. xfs does this, but I don't know that this does anybody any good. Salina points out that you can get the device number from stat().
------ Additional Comments From salina.com 2003-14-07 17:49 ------- Checking other Unix O/S, from http://docs.sun.com and searching for statvfs, Solaris API description for statvfs says u_long f_fsid; /* file system id (dev for now) */ I take that to mean it is a device number ?
------ Additional Comments From plars.com 2003-14-07 18:15 ------- We have a few tests for statfs in LTP, but none of them do anything with f_fsid. From looking at the kernel source it looks fs dependant. It looks like out of all the filesystems Linux supports, only bfs, efs, ntfs, and xfs even use it. It doesn't look like they have a terribly standard way of handling it. The most standard treatment I've seen of it is just to ignore it (thus 0).
since there is no standard and no requirement, I don't think there's anything we'll do with this bug. Clearly such an ABI change needs to be achieved via the upstream kernel.org kernels, esp since there is no sensible definition of what this field ought to mean out there.
------ Additional Comments From vpereira.com 2003-15-07 12:31 ------- Thanks, using stat() would definitely serve our purpose for the moment (as it provides an acceptable level of differentiation). However, we may also need to get the file system name (e.g. /home, /, etc.) to develop other components of the application. Are there any workarounds for this as well? Vincent
------ Additional Comments From salina.com 2003-15-07 14:31 ------- What is the API you are looking for ? API returns the file system name given a fully qualified path name ?
------ Additional Comments From vpereira.com 2003-15-07 14:34 ------- Yes API for resolving file name
------ Additional Comments From shaggy.com(prefers email via shaggy.com) 2003-15-07 14:44 ------- I ran strace to see what system calls df makes when running "df /some/path". df calls stat64("/some/path"), then reads /proc/mounts and then runs stat64() on each mountpoint it comes across until it finds the matching mountpoint (I assume by comparing st_dev). I assume that this wouldn't be a performance-critical operation.