|
@@ -707,6 +707,18 @@ cgfi_exit:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+/* Simple function to return a 64 bit hash of string. Rarely called */
|
|
|
+static __u64 simple_hashstr(const char *str)
|
|
|
+{
|
|
|
+ const __u64 hash_mult = 1125899906842597L; /* a big enough prime */
|
|
|
+ __u64 hash = 0;
|
|
|
+
|
|
|
+ while (*str)
|
|
|
+ hash = (hash + (__u64) *str++) * hash_mult;
|
|
|
+
|
|
|
+ return hash;
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
cifs_get_inode_info(struct inode **inode, const char *full_path,
|
|
|
FILE_ALL_INFO *data, struct super_block *sb, int xid,
|
|
@@ -816,6 +828,14 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
|
|
tmprc);
|
|
|
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
|
|
cifs_autodisable_serverino(cifs_sb);
|
|
|
+ } else if ((fattr.cf_uniqueid == 0) &&
|
|
|
+ strlen(full_path) == 0) {
|
|
|
+ /* some servers ret bad root ino ie 0 */
|
|
|
+ cifs_dbg(FYI, "Invalid (0) inodenum\n");
|
|
|
+ fattr.cf_flags |=
|
|
|
+ CIFS_FATTR_FAKE_ROOT_INO;
|
|
|
+ fattr.cf_uniqueid =
|
|
|
+ simple_hashstr(tcon->treeName);
|
|
|
}
|
|
|
}
|
|
|
} else
|
|
@@ -832,6 +852,16 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
|
|
&fattr.cf_uniqueid, data);
|
|
|
if (tmprc)
|
|
|
fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
|
|
|
+ else if ((fattr.cf_uniqueid == 0) &&
|
|
|
+ strlen(full_path) == 0) {
|
|
|
+ /*
|
|
|
+ * Reuse existing root inode num since
|
|
|
+ * inum zero for root causes ls of . and .. to
|
|
|
+ * not be returned
|
|
|
+ */
|
|
|
+ cifs_dbg(FYI, "Srv ret 0 inode num for root\n");
|
|
|
+ fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
|
|
|
+ }
|
|
|
} else
|
|
|
fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
|
|
|
}
|
|
@@ -893,6 +923,9 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
|
|
}
|
|
|
|
|
|
cgii_exit:
|
|
|
+ if ((*inode) && ((*inode)->i_ino == 0))
|
|
|
+ cifs_dbg(FYI, "inode number of zero returned\n");
|
|
|
+
|
|
|
kfree(buf);
|
|
|
cifs_put_tlink(tlink);
|
|
|
return rc;
|