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