aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/readdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/readdir.c')
-rw-r--r--fs/cifs/readdir.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index f1213799de1a..ab8778469394 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -126,6 +126,22 @@ out:
126 dput(dentry); 126 dput(dentry);
127} 127}
128 128
129/*
130 * Is it possible that this directory might turn out to be a DFS referral
131 * once we go to try and use it?
132 */
133static bool
134cifs_dfs_is_possible(struct cifs_sb_info *cifs_sb)
135{
136#ifdef CONFIG_CIFS_DFS_UPCALL
137 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
138
139 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
140 return true;
141#endif
142 return false;
143}
144
129static void 145static void
130cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) 146cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
131{ 147{
@@ -135,6 +151,19 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
135 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { 151 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
136 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; 152 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
137 fattr->cf_dtype = DT_DIR; 153 fattr->cf_dtype = DT_DIR;
154 /*
155 * Windows CIFS servers generally make DFS referrals look
156 * like directories in FIND_* responses with the reparse
157 * attribute flag also set (since DFS junctions are
158 * reparse points). We must revalidate at least these
159 * directory inodes before trying to use them (if
160 * they are DFS we will get PATH_NOT_COVERED back
161 * when queried directly and can then try to connect
162 * to the DFS target)
163 */
164 if (cifs_dfs_is_possible(cifs_sb) &&
165 (fattr->cf_cifsattrs & ATTR_REPARSE))
166 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
138 } else { 167 } else {
139 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; 168 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
140 fattr->cf_dtype = DT_REG; 169 fattr->cf_dtype = DT_REG;