From mboxrd@z Thu Jan 1 00:00:00 1970 From: "John Muir" Subject: Rename file over another with the same inode number fails silently. Date: Thu, 08 Feb 2007 11:48:16 -0500 Message-ID: <45CB5450.6050604@nortel.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------020701000906030901090807" To: linux-fsdevel@vger.kernel.org Return-path: Received: from zrtps0kp.nortel.com ([47.140.192.56]:49310 "EHLO zrtps0kp.nortel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965717AbXBHRAZ (ORCPT ); Thu, 8 Feb 2007 12:00:25 -0500 Received: from zcarhxs1.corp.nortel.com (zcarhxs1.corp.nortel.com [47.129.230.89]) by zrtps0kp.nortel.com (Switch-2.2.6/Switch-2.2.0) with ESMTP id l18GmNW18373 for ; Thu, 8 Feb 2007 11:48:24 -0500 (EST) Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org This is a multi-part message in MIME format. --------------020701000906030901090807 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit The attached test program creates a file, and then some hard links to that file (file0 - fileN). The test program then attempts to rename(fileN, file) for every hard link created. My expectation is that the hard links file0 - fileN would simply disappear, or that rename would respond with an error result and an appropriate errno value indicating the problem. My observation is that the hard links file0 to fileN do not in fact disappear and rename returns 0. Do I have the wrong expectations? If so, why should I have to stat the files to determine if they are the same inode before I rename? Is this a VFS bug? It seems to apply to all file-systems (I have tried only EXT3, XFS, and TMPFS). This also seems to occur on other unixes. Regards, John -- John Muir NORTEL muirj@nortel.com --------------020701000906030901090807 Content-Type: text/x-csrc; name="renameover.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="renameover.c" // renameover // ------------------------------------------------------------------ // Simple program which renames hard links over each other. #include #include #include #include #include #include #include #include #define FILE_BLOCK_SIZE 4096 // main // ------------------------------------------------------------------ int main ( int argc, char **argv ) { int fd; int count = 0; int i; char *buf; struct stat statBuf; if( argc < 2 ) { fprintf( stderr, "renameover [count]\n" ); return EINVAL; } if( argc >= 3 ) count = atoi( argv[2] ); if( count <= 0 ) count = 10; fd = open( argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR ); if( fd < 0 ) { perror( "open create" ); return errno; } buf = alloca( FILE_BLOCK_SIZE ); memset( buf, ( count % 26 ) + 'A', FILE_BLOCK_SIZE ); buf[ FILE_BLOCK_SIZE - 1 ] = '\n'; write( fd, buf, FILE_BLOCK_SIZE ); if( close( fd ) < 0 ) { perror( "close" ); return errno; } i = 0; while( i < count ) { snprintf( buf, FILE_BLOCK_SIZE, "%s%d", argv[1], i ); if( link( argv[1], buf ) < 0 ) { perror( "link" ); return errno; } ++i; } if( stat( argv[1], &statBuf ) < 0 ) { perror( "stat" ); return errno; } printf( "Hard link count for '%s': %u (expecting %d).\n", argv[1], statBuf.st_nlink, count + 1 ); i = 0; while( i < count ) { snprintf( buf, FILE_BLOCK_SIZE, "%s%d", argv[1], i ); if( rename( buf, argv[1] ) < 0 ) { perror( "rename" ); return errno; } else { if( stat( buf, &statBuf ) < 0 ) { if( errno != ENOENT ) perror( "stat" ); } else { printf( "Unexpected: '%s' still exists. " "Hard link count: %u, expected %d.\n", buf, statBuf.st_nlink, count - i ); } } ++i; } return 0; } --------------020701000906030901090807--