]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/cifs/readdir.c
be2net: Initialize "status" in be_cmd_get_die_temperature()
[karo-tx-linux.git] / fs / cifs / readdir.c
index f1213799de1a2603b1f8f1c8d42f8b0fb2cb5a64..ab877846939499c18cb454c83ed26c43dc60040c 100644 (file)
@@ -126,6 +126,22 @@ out:
        dput(dentry);
 }
 
+/*
+ * Is it possible that this directory might turn out to be a DFS referral
+ * once we go to try and use it?
+ */
+static bool
+cifs_dfs_is_possible(struct cifs_sb_info *cifs_sb)
+{
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+
+       if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
+               return true;
+#endif
+       return false;
+}
+
 static void
 cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
 {
@@ -135,6 +151,19 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
        if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
                fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
                fattr->cf_dtype = DT_DIR;
+               /*
+                * Windows CIFS servers generally make DFS referrals look
+                * like directories in FIND_* responses with the reparse
+                * attribute flag also set (since DFS junctions are
+                * reparse points). We must revalidate at least these
+                * directory inodes before trying to use them (if
+                * they are DFS we will get PATH_NOT_COVERED back
+                * when queried directly and can then try to connect
+                * to the DFS target)
+                */
+               if (cifs_dfs_is_possible(cifs_sb) &&
+                   (fattr->cf_cifsattrs & ATTR_REPARSE))
+                       fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
        } else {
                fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
                fattr->cf_dtype = DT_REG;