diff options
Diffstat (limited to 'fs/cifs/readdir.c')
-rw-r--r-- | fs/cifs/readdir.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index a86bd1c07602..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; |
@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
193 | if (S_ISREG(tmp_inode->i_mode)) { | 204 | if (S_ISREG(tmp_inode->i_mode)) { |
194 | cFYI(1, ("File inode")); | 205 | cFYI(1, ("File inode")); |
195 | tmp_inode->i_op = &cifs_file_inode_ops; | 206 | tmp_inode->i_op = &cifs_file_inode_ops; |
196 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 207 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
197 | tmp_inode->i_fop = &cifs_file_direct_ops; | 208 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
209 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
210 | else | ||
211 | tmp_inode->i_fop = &cifs_file_direct_ops; | ||
212 | |||
213 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
214 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | ||
198 | else | 215 | else |
199 | tmp_inode->i_fop = &cifs_file_ops; | 216 | tmp_inode->i_fop = &cifs_file_ops; |
200 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 217 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
@@ -258,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
258 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); | 275 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); |
259 | 276 | ||
260 | 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; | ||
261 | if (type == UNIX_FILE) { | 281 | if (type == UNIX_FILE) { |
262 | *pobject_type = DT_REG; | 282 | *pobject_type = DT_REG; |
263 | tmp_inode->i_mode |= S_IFREG; | 283 | tmp_inode->i_mode |= S_IFREG; |
@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
283 | } else if (type == UNIX_SOCKET) { | 303 | } else if (type == UNIX_SOCKET) { |
284 | *pobject_type = DT_SOCK; | 304 | *pobject_type = DT_SOCK; |
285 | 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)); | ||
286 | } | 311 | } |
287 | 312 | ||
288 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); | 313 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); |
@@ -699,7 +724,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, | |||
699 | (__le16 *)filename, len/2, nlt); | 724 | (__le16 *)filename, len/2, nlt); |
700 | else | 725 | else |
701 | pqst->len = cifs_strfromUCS_le((char *)pqst->name, | 726 | pqst->len = cifs_strfromUCS_le((char *)pqst->name, |
702 | (wchar_t *)filename,len/2,nlt); | 727 | (__le16 *)filename,len/2,nlt); |
703 | } else { | 728 | } else { |
704 | pqst->name = filename; | 729 | pqst->name = filename; |
705 | pqst->len = len; | 730 | pqst->len = len; |