- long flags;
- int fd, res;
-
- if ((fd = open(ent->d_name,O_RDONLY))==-1) {
- fprintf (stderr,"Can't open file %s/%s\n",path,ent->d_name);
- warning ("open failed");
- continue;
- }
-
- flags = 0;
- res = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- close(fd);
-
- if ((res == 0) && (flags & EXT2_IMMUTABLE_LINK_FL)){
- if (verbose)
- printf ("Skipping %s\n",ent->d_name);
- continue;
+ struct stat *val;
+ int nlink;
+
+ /* Check hash table if we've seen this inode
+ * before. Note that the hash maintains a
+ * (inode,struct stat) key value pair.
+ */
+
+ val = &st;
+
+ (void) INOPut(&tbl,&st.st_ino,&val);
+
+ /* Note that after the INOPut call "val" refers to the
+ * value entry in the hash table --- not &st. This
+ * means that if the inode has been put into the hash
+ * table before, val will refer to the first st that
+ * was put into the hashtable. Otherwise, if it is
+ * the first time it is put into the hash table, then
+ * val will be equal to this &st.
+ */
+ nlink = val->st_nlink;
+ nlink --;
+
+ /* val refers to value in hash tbale */
+ if (nlink == 0) {
+
+ /* We saw all hard links to this particular inode
+ * as part of this sweep of vdu. So account for
+ * the size and blocks required by the file.
+ */
+
+ dirsize += val->st_size;
+ dirblocks += val->st_blocks;
+
+ /* Do not delete the (ino,val) tuple from the tbl,
+ * as we need to handle the case when we are
+ * double counting a file due to a bind mount.
+ */
+ val->st_nlink = 0;
+
+ } else if (nlink > 0) {
+ val->st_nlink = nlink;
+ } else /* if(nlink < 0) */ {
+ /* We get here when we are double counting nlinks
+ due a bind mount. */
+
+ /* DO NOTHING */