mouse@mcgill-vision.UUCP (der Mouse) (07/09/89)
The ftruncate() call appears to be broken on at least some systems with NFS implementations based on Sun's. I've tried this on a Sun-3 with release 3.5 and on a VAX running mtXinu 4.3+NFS. I also tried it on a MicroVAX running real 4.3, and it did not exhibit the broken behavior. But it's not directly an NFS problem, because it happens even when the file is on a ufs filesystem. The problem is that ftruncate() fails if the file modes prohibit writing, even if the file descriptor used does permit writing. For example, try the following program on a handy Sun. Notice that (unless you try it as super-user), the ftruncate call fails. Try it on a 4.3 machine, though, and everything's fine. (I checked the Sun manpage, and there's not even a note in the BUGS section warning about this, so presumably someone thinks it should work the way it does on 4.3.) Anybody have a simple fix? (Patch a couple of bytes to noops somewhere in the OBJ/ files perhaps?) Will it be fixed in newer releases (4.x)? I'm about ready to try to work out a fix on the mtXinu system, to which we have source, but that's not much help on the Suns. #include <sys/file.h> int fd; char junk[8192]; main() { unlink("test.file"); fd = open("test.file",O_RDWR|O_CREAT|O_TRUNC,0666); if (fd < 0) { perror("open/create test.file"); exit(1); } if (write(fd,&junk[0],8192) != 8192) { perror("write #1"); exit(1); } if (fchmod(fd,0444) < 0) { perror("fchmod"); exit(1); } if (write(fd,&junk[0],8192) != 8192) { perror("write #2"); exit(1); } if (ftruncate(fd,(unsigned long int)16000) < 0) { perror("ftruncate"); exit(1); } if (close(fd) < 0) { perror("close"); exit(1); } exit(0); } der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
guy@auspex.auspex.com (Guy Harris) (07/11/89)
>The problem is that ftruncate() fails if the file modes prohibit >Anybody have a simple fix? (Patch a couple of bytes to noops somewhere >in the OBJ/ files perhaps?) Sure, you can probably no-op out the code in "ufs_setattr" that calls "iaccess" to check whether you have write permission. Of course, this would let you make NFS RPC calls directly to truncate files to which you don't have write access, which I suspect you don't want.... >Will it be fixed in newer releases (4.x)? It's not fixed in 4.0; I've noted the problem to somebody at Sun. The problem is that truncating a file should be treated like writing it - i.e., the permission checks should be made: 1) at the system call layer (which is already done for both calls) and 2) at the NFS server layer (which is already done for "write" but not for "setattr" setting the length) but *not* at the UFS layer. I can't see any problems with making the requisite changes (i.e., get rid of the "iaccess()" call in "ufs_setattr", put in a VOP_ACCESS call in "rfs_setattr" - i.e., in the server code - if you're trying to set the size, and make sure there are no *other* calls to VOP_SETATTR that might set the size and that are relying on the underlying file system to do any permissions checking), but that doesn't mean no such problems exist, so be careful.