tests/hardlink1 fails
Assar Westerlund
assar at stacken.kth.se
Sat Aug 7 08:56:14 CEST 1999
Simon Josefsson <jas at pdc.kth.se> writes:
> hardlink1 from "make check" fails, xfs debug logs attached.
>
> $ /scratch/arla/tests/hardlink1
> hardlink1: foo.st_nlink != 1
> $
Can you try the first appended patch and see if it solves that problem?
> Has anyone experienced problems running cpp on lots of files in afs?
> (I.e building large programs) Sometimes it decides not to open() some
> files (causing a multitude of compile errors), stracing cpp show it
> fstat()s right before deciding not to read a file, so with any luck
> it's the same bug as hardlink1 triggers.
Sounds unlikely, the hardlink problem is keeping the link count of
nodes up-to-date. It might however be caused by inode-number
collision. I can think of two ways of figuring out what is going on:
1. instrumenting cpp to see why it doesn't want to read a file.
2. get the -current code and apply the second appended patch to your
linux kernel and see if that gets rid of the problem. Then it's
fairly likely to be that problem.
/assar
Index: arlad/messages.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/messages.c,v
retrieving revision 1.152
diff -u -w -u -w -r1.152 messages.c
--- messages.c 1999/08/04 13:45:28 1.152
+++ messages.c 1999/08/07 06:39:18
@@ -1064,13 +1064,14 @@
CredCacheEntry *ce;
int ret;
struct xfs_message_installdata msg1;
- struct xfs_message_installattr msg2;
+ struct xfs_message_installnode msg2;
struct xfs_message_header *h0 = NULL;
size_t h0_len = 0;
struct xfs_message_header *h1 = NULL;
size_t h1_len = 0;
FCacheEntry *limbo_entry = NULL;
unsigned link_count;
+ int limbo_entry_in_kernelp;
parent_fid = (VenusFid *)&h->parent_handle;
@@ -1100,6 +1101,7 @@
if (ret)
goto out;
link_count = limbo_entry->status.LinkCount;
+ limbo_entry_in_kernelp = limbo_entry->flags.kernelp;
fcache_release (limbo_entry);
limbo_entry = NULL;
@@ -1173,14 +1175,16 @@
if (link_count == 1)
limbo_entry->flags.silly = TRUE;
- if (limbo_entry->flags.kernelp) {
+ if (/* limbo_entry_in_kernelp */ 1) {
ret = fcache_get_attr (limbo_entry, ce);
if (ret)
goto out;
- msg2.header.opcode = XFS_MSG_INSTALLATTR;
+ msg2.header.opcode = XFS_MSG_INSTALLNODE;
msg2.node.tokens = limbo_entry->tokens;
+ msg2.parent_handle = h->parent_handle;
+ strcpy(msg2.name, h->name);
if (link_count == 1 && limbo_entry->status.LinkCount == 1)
--limbo_entry->status.LinkCount;
fcacheentry2xfsnode (&fid,
--- fs/stat.c.orig Tue Jul 13 20:17:22 1999
+++ fs/stat.c Thu Jul 15 18:14:00 1999
@@ -24,56 +24,22 @@
}
-#if !defined(__alpha__) && !defined(__sparc__)
-
-/*
- * For backward compatibility? Maybe this should be moved
- * into arch/i386 instead?
- */
-static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
-{
- static int warncount = 5;
- struct __old_kernel_stat tmp;
-
- if (warncount) {
- warncount--;
- printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
- current->comm);
- }
-
- tmp.st_dev = kdev_t_to_nr(inode->i_dev);
- tmp.st_ino = inode->i_ino;
- tmp.st_mode = inode->i_mode;
- tmp.st_nlink = inode->i_nlink;
- tmp.st_uid = inode->i_uid;
- tmp.st_gid = inode->i_gid;
- tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
- tmp.st_ctime = inode->i_ctime;
- return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
-}
-
-#endif
-
-static int cp_new_stat(struct inode * inode, struct stat * statbuf)
+int generic_getattr(struct inode * inode, struct stat * statbuf)
{
- struct stat tmp;
unsigned int blocks, indirect;
- memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = kdev_t_to_nr(inode->i_dev);
- tmp.st_ino = inode->i_ino;
- tmp.st_mode = inode->i_mode;
- tmp.st_nlink = inode->i_nlink;
- tmp.st_uid = inode->i_uid;
- tmp.st_gid = inode->i_gid;
- tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
- tmp.st_ctime = inode->i_ctime;
+ memset(statbuf, 0, sizeof(*statbuf));
+ statbuf->st_dev = kdev_t_to_nr(inode->i_dev);
+ statbuf->st_ino = inode->i_ino;
+ statbuf->st_mode = inode->i_mode;
+ statbuf->st_nlink = inode->i_nlink;
+ statbuf->st_uid = inode->i_uid;
+ statbuf->st_gid = inode->i_gid;
+ statbuf->st_rdev = kdev_t_to_nr(inode->i_rdev);
+ statbuf->st_size = inode->i_size;
+ statbuf->st_atime = inode->i_atime;
+ statbuf->st_mtime = inode->i_mtime;
+ statbuf->st_ctime = inode->i_ctime;
/*
* st_blocks and st_blksize are approximated with a simple algorithm if
* they aren't supported directly by the filesystem. The minix and msdos
@@ -87,13 +53,13 @@
* Use minix fs values for the number of direct and indirect blocks. The
* count is now exact for the minix fs except that it counts zero blocks.
* Everything is in units of BLOCK_SIZE until the assignment to
- * tmp.st_blksize.
+ * statbuf->st_blksize.
*/
#define D_B 7
#define I_B (BLOCK_SIZE / sizeof(unsigned short))
if (!inode->i_blksize) {
- blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ blocks = (statbuf->st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (blocks > D_B) {
indirect = (blocks - D_B + I_B - 1) / I_B;
blocks += indirect;
@@ -104,15 +70,72 @@
blocks++;
}
}
- tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
- tmp.st_blksize = BLOCK_SIZE;
+ statbuf->st_blocks = (BLOCK_SIZE / 512) * blocks;
+ statbuf->st_blksize = BLOCK_SIZE;
} else {
- tmp.st_blocks = inode->i_blocks;
- tmp.st_blksize = inode->i_blksize;
+ statbuf->st_blocks = inode->i_blocks;
+ statbuf->st_blksize = inode->i_blksize;
+ }
+ return 0;
+}
+
+int vfs_getattr(struct inode * inode, struct stat * statbuf)
+{
+ if (inode->i_op && inode->i_op->getattr)
+ return inode->i_op->getattr (inode, statbuf);
+ else
+ return generic_getattr (inode, statbuf);
}
+
+#if !defined(__alpha__) && !defined(__sparc__)
+
+/*
+ * For backward compatibility? Maybe this should be moved
+ * into arch/i386 instead?
+ */
+static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
+{
+ static int warncount = 5;
+ struct __old_kernel_stat tmp;
+ struct stat new_tmp;
+ int ret;
+
+ if (warncount) {
+ warncount--;
+ printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
+ current->comm);
+ }
+
+ ret = vfs_getattr (inode, &new_tmp);
+ if (ret)
+ return ret;
+ tmp.st_dev = new_tmp.st_dev;
+ tmp.st_ino = new_tmp.st_ino;
+ tmp.st_mode = new_tmp.st_mode;
+ tmp.st_nlink = new_tmp.st_nlink;
+ tmp.st_uid = new_tmp.st_uid;
+ tmp.st_gid = new_tmp.st_gid;
+ tmp.st_rdev = new_tmp.st_rdev;
+ tmp.st_size = new_tmp.st_size;
+ tmp.st_atime = new_tmp.st_atime;
+ tmp.st_mtime = new_tmp.st_mtime;
+ tmp.st_ctime = new_tmp.st_ctime;
+
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
+#endif
+
+static int cp_new_stat(struct inode * inode, struct stat * statbuf)
+{
+ struct stat tmp;
+ int ret;
+
+ ret = vfs_getattr (inode, &tmp);
+ if (ret)
+ return ret;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
#if !defined(__alpha__) && !defined(__sparc__)
/*
--- include/linux/fs.h.orig Tue Jan 26 05:00:51 1999
+++ include/linux/fs.h Thu Jul 15 18:10:10 1999
@@ -613,6 +613,7 @@
int (*smap) (struct inode *,int);
int (*updatepage) (struct file *, struct page *, unsigned long, unsigned int, int);
int (*revalidate) (struct dentry *);
+ int (*getattr) (struct inode *, struct stat *);
};
struct super_operations {
@@ -876,6 +877,9 @@
extern int inode_change_ok(struct inode *, struct iattr *);
extern void inode_setattr(struct inode *, struct iattr *);
+
+extern int generic_getattr(struct inode *, struct stat *);
+extern int vfs_getattr(struct inode * inode, struct stat * statbuf);
/* kludge to get SCSI modules working */
#include <linux/minix_fs.h>
More information about the Arla-drinkers
mailing list