diff options
Diffstat (limited to 'fs/cifs/readdir.c')
-rw-r--r-- | fs/cifs/readdir.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9b7e0ff9584b..9bdaaecae36f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
142 | tmp_inode->i_gid = cifs_sb->mnt_gid; | 142 | tmp_inode->i_gid = cifs_sb->mnt_gid; |
143 | /* set default mode. will override for dirs below */ | 143 | /* set default mode. will override for dirs below */ |
144 | tmp_inode->i_mode = cifs_sb->mnt_file_mode; | 144 | tmp_inode->i_mode = cifs_sb->mnt_file_mode; |
145 | } else { | ||
146 | /* mask off the type bits since it gets set | ||
147 | below and we do not want to get two type | ||
148 | bits set */ | ||
149 | tmp_inode->i_mode &= ~S_IFMT; | ||
145 | } | 150 | } |
146 | 151 | ||
147 | if (attr & ATTR_DIRECTORY) { | 152 | if (attr & ATTR_DIRECTORY) { |
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
152 | } | 157 | } |
153 | tmp_inode->i_mode |= S_IFDIR; | 158 | tmp_inode->i_mode |= S_IFDIR; |
154 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && | 159 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && |
155 | (attr & ATTR_SYSTEM) && (end_of_file == 0)) { | 160 | (attr & ATTR_SYSTEM)) { |
156 | *pobject_type = DT_FIFO; | 161 | if (end_of_file == 0) { |
157 | tmp_inode->i_mode |= S_IFIFO; | 162 | *pobject_type = DT_FIFO; |
158 | /* BB Finish for SFU style symlinks and devies */ | 163 | tmp_inode->i_mode |= S_IFIFO; |
159 | /* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && | 164 | } else { |
160 | (attr & ATTR_SYSTEM) && ) { */ | 165 | /* rather than get the type here, we mark the |
166 | inode as needing revalidate and get the real type | ||
167 | (blk vs chr vs. symlink) later ie in lookup */ | ||
168 | *pobject_type = DT_REG; | ||
169 | tmp_inode->i_mode |= S_IFREG; | ||
170 | cifsInfo->time = 0; | ||
171 | } | ||
161 | /* we no longer mark these because we could not follow them */ | 172 | /* we no longer mark these because we could not follow them */ |
162 | /* } else if (attr & ATTR_REPARSE) { | 173 | /* } else if (attr & ATTR_REPARSE) { |
163 | *pobject_type = DT_LNK; | 174 | *pobject_type = DT_LNK; |
@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
264 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); | 275 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); |
265 | 276 | ||
266 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); | 277 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); |
278 | /* since we set the inode type below we need to mask off type | ||
279 | to avoid strange results if bits above were corrupt */ | ||
280 | tmp_inode->i_mode &= ~S_IFMT; | ||
267 | if (type == UNIX_FILE) { | 281 | if (type == UNIX_FILE) { |
268 | *pobject_type = DT_REG; | 282 | *pobject_type = DT_REG; |
269 | tmp_inode->i_mode |= S_IFREG; | 283 | tmp_inode->i_mode |= S_IFREG; |
@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
289 | } else if (type == UNIX_SOCKET) { | 303 | } else if (type == UNIX_SOCKET) { |
290 | *pobject_type = DT_SOCK; | 304 | *pobject_type = DT_SOCK; |
291 | tmp_inode->i_mode |= S_IFSOCK; | 305 | tmp_inode->i_mode |= S_IFSOCK; |
306 | } else { | ||
307 | /* safest to just call it a file */ | ||
308 | *pobject_type = DT_REG; | ||
309 | tmp_inode->i_mode |= S_IFREG; | ||
310 | cFYI(1,("unknown inode type %d",type)); | ||
292 | } | 311 | } |
293 | 312 | ||
294 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); | 313 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); |