diff options
-rw-r--r-- | fs/cifs/inode.c | 47 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 31 |
2 files changed, 56 insertions, 22 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 93dd705577bc..ffc7305841b3 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
41 | char *tmp_path; | 41 | char *tmp_path; |
42 | 42 | ||
43 | pTcon = cifs_sb->tcon; | 43 | pTcon = cifs_sb->tcon; |
44 | cFYI(1, (" Getting info on %s ", search_path)); | 44 | cFYI(1, ("Getting info on %s ", search_path)); |
45 | /* could have done a find first instead but this returns more info */ | 45 | /* could have done a find first instead but this returns more info */ |
46 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, | 46 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, |
47 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 47 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
111 | inode->i_ctime = | 111 | inode->i_ctime = |
112 | cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); | 112 | cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); |
113 | inode->i_mode = le64_to_cpu(findData.Permissions); | 113 | inode->i_mode = le64_to_cpu(findData.Permissions); |
114 | /* since we set the inode type below we need to mask off | ||
115 | to avoid strange results if bits set above */ | ||
116 | inode->i_mode &= ~S_IFMT; | ||
114 | if (type == UNIX_FILE) { | 117 | if (type == UNIX_FILE) { |
115 | inode->i_mode |= S_IFREG; | 118 | inode->i_mode |= S_IFREG; |
116 | } else if (type == UNIX_SYMLINK) { | 119 | } else if (type == UNIX_SYMLINK) { |
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
129 | inode->i_mode |= S_IFIFO; | 132 | inode->i_mode |= S_IFIFO; |
130 | } else if (type == UNIX_SOCKET) { | 133 | } else if (type == UNIX_SOCKET) { |
131 | inode->i_mode |= S_IFSOCK; | 134 | inode->i_mode |= S_IFSOCK; |
135 | } else { | ||
136 | /* safest to call it a file if we do not know */ | ||
137 | inode->i_mode |= S_IFREG; | ||
138 | cFYI(1,("unknown type %d",type)); | ||
132 | } | 139 | } |
133 | inode->i_uid = le64_to_cpu(findData.Uid); | 140 | inode->i_uid = le64_to_cpu(findData.Uid); |
134 | inode->i_gid = le64_to_cpu(findData.Gid); | 141 | inode->i_gid = le64_to_cpu(findData.Gid); |
@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
228 | 8 /* length */, 0 /* offset */, | 235 | 8 /* length */, 0 /* offset */, |
229 | &bytes_read, &pbuf); | 236 | &bytes_read, &pbuf); |
230 | if((rc == 0) && (bytes_read == 8)) { | 237 | if((rc == 0) && (bytes_read == 8)) { |
231 | cERROR(1,("intx %s" ,pbuf)); | ||
232 | if(memcmp("IntxBLK", pbuf, 8) == 0) { | 238 | if(memcmp("IntxBLK", pbuf, 8) == 0) { |
233 | cFYI(1,("Block device")); | 239 | cFYI(1,("Block device")); |
234 | inode->i_mode = S_IFBLK; | 240 | inode->i_mode |= S_IFBLK; |
235 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { | 241 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { |
236 | cFYI(1,("Char device")); | 242 | cFYI(1,("Char device")); |
237 | inode->i_mode = S_IFCHR; | 243 | inode->i_mode |= S_IFCHR; |
238 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { | 244 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { |
239 | cFYI(1,("Symlink")); | 245 | cFYI(1,("Symlink")); |
240 | inode->i_mode = S_IFLNK; | 246 | inode->i_mode |= S_IFLNK; |
241 | } else | 247 | } |
242 | inode->i_mode = S_IFREG; /* then it is a file */ | 248 | } else { |
243 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | 249 | inode->i_mode |= S_IFREG; /* then it is a file */ |
244 | 250 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | |
245 | } | 251 | } |
246 | 252 | ||
247 | CIFSSMBClose(xid, pTcon, netfid); | 253 | CIFSSMBClose(xid, pTcon, netfid); |
@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode, | |||
261 | const unsigned char *path, | 267 | const unsigned char *path, |
262 | struct cifs_sb_info *cifs_sb, int xid) | 268 | struct cifs_sb_info *cifs_sb, int xid) |
263 | { | 269 | { |
270 | #ifdef CONFIG_CIFS_XATTR | ||
264 | ssize_t rc; | 271 | ssize_t rc; |
265 | char ea_value[4]; | 272 | char ea_value[4]; |
266 | __u32 mode; | 273 | __u32 mode; |
@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode, | |||
272 | return (int)rc; | 279 | return (int)rc; |
273 | else if (rc > 3) { | 280 | else if (rc > 3) { |
274 | mode = le32_to_cpu(*((__le32 *)ea_value)); | 281 | mode = le32_to_cpu(*((__le32 *)ea_value)); |
282 | cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode)); | ||
275 | inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; | 283 | inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; |
276 | cFYI(1,("special mode bits 0%o", mode)); | 284 | cFYI(1,("special mode bits 0%o", mode)); |
277 | return 0; | 285 | return 0; |
278 | } else { | 286 | } else { |
279 | return 0; | 287 | return 0; |
280 | } | 288 | } |
289 | #else | ||
290 | return -EOPNOTSUPP; | ||
291 | #endif | ||
292 | |||
281 | 293 | ||
282 | } | 294 | } |
283 | 295 | ||
@@ -394,9 +406,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
394 | inode = *pinode; | 406 | inode = *pinode; |
395 | cifsInfo = CIFS_I(inode); | 407 | cifsInfo = CIFS_I(inode); |
396 | cifsInfo->cifsAttrs = attr; | 408 | cifsInfo->cifsAttrs = attr; |
397 | cFYI(1, (" Old time %ld ", cifsInfo->time)); | 409 | cFYI(1, ("Old time %ld ", cifsInfo->time)); |
398 | cifsInfo->time = jiffies; | 410 | cifsInfo->time = jiffies; |
399 | cFYI(1, (" New time %ld ", cifsInfo->time)); | 411 | cFYI(1, ("New time %ld ", cifsInfo->time)); |
400 | 412 | ||
401 | /* blksize needs to be multiple of two. So safer to default to | 413 | /* blksize needs to be multiple of two. So safer to default to |
402 | blksize and blkbits set in superblock so 2**blkbits and blksize | 414 | blksize and blkbits set in superblock so 2**blkbits and blksize |
@@ -410,13 +422,15 @@ int cifs_get_inode_info(struct inode **pinode, | |||
410 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 422 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); |
411 | inode->i_ctime = | 423 | inode->i_ctime = |
412 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 424 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
413 | cFYI(0, (" Attributes came in as 0x%x ", attr)); | 425 | cFYI(0, ("Attributes came in as 0x%x ", attr)); |
414 | 426 | ||
415 | /* set default mode. will override for dirs below */ | 427 | /* set default mode. will override for dirs below */ |
416 | if (atomic_read(&cifsInfo->inUse) == 0) | 428 | if (atomic_read(&cifsInfo->inUse) == 0) |
417 | /* new inode, can safely set these fields */ | 429 | /* new inode, can safely set these fields */ |
418 | inode->i_mode = cifs_sb->mnt_file_mode; | 430 | inode->i_mode = cifs_sb->mnt_file_mode; |
419 | 431 | else /* since we set the inode type below we need to mask off | |
432 | to avoid strange results if type changes and both get orred in */ | ||
433 | inode->i_mode &= ~S_IFMT; | ||
420 | /* if (attr & ATTR_REPARSE) */ | 434 | /* if (attr & ATTR_REPARSE) */ |
421 | /* We no longer handle these as symlinks because we could not | 435 | /* We no longer handle these as symlinks because we could not |
422 | follow them due to the absolute path with drive letter */ | 436 | follow them due to the absolute path with drive letter */ |
@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
440 | cifs_sb, xid)) { | 454 | cifs_sb, xid)) { |
441 | cFYI(1,("Unrecognized sfu inode type")); | 455 | cFYI(1,("Unrecognized sfu inode type")); |
442 | } | 456 | } |
457 | cFYI(1,("sfu mode 0%o",inode->i_mode)); | ||
443 | } else { | 458 | } else { |
444 | inode->i_mode |= S_IFREG; | 459 | inode->i_mode |= S_IFREG; |
445 | /* treat the dos attribute of read-only as read-only | 460 | /* treat the dos attribute of read-only as read-only |
@@ -535,7 +550,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
535 | struct cifsInodeInfo *cifsInode; | 550 | struct cifsInodeInfo *cifsInode; |
536 | FILE_BASIC_INFO *pinfo_buf; | 551 | FILE_BASIC_INFO *pinfo_buf; |
537 | 552 | ||
538 | cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); | 553 | cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode)); |
539 | 554 | ||
540 | xid = GetXid(); | 555 | xid = GetXid(); |
541 | 556 | ||
@@ -755,7 +770,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
755 | char *full_path = NULL; | 770 | char *full_path = NULL; |
756 | struct cifsInodeInfo *cifsInode; | 771 | struct cifsInodeInfo *cifsInode; |
757 | 772 | ||
758 | cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); | 773 | cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode)); |
759 | 774 | ||
760 | xid = GetXid(); | 775 | xid = GetXid(); |
761 | 776 | ||
@@ -1074,7 +1089,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1074 | 1089 | ||
1075 | xid = GetXid(); | 1090 | xid = GetXid(); |
1076 | 1091 | ||
1077 | cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", | 1092 | cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ", |
1078 | direntry->d_name.name, attrs->ia_valid)); | 1093 | direntry->d_name.name, attrs->ia_valid)); |
1079 | cifs_sb = CIFS_SB(direntry->d_inode->i_sb); | 1094 | cifs_sb = CIFS_SB(direntry->d_inode->i_sb); |
1080 | pTcon = cifs_sb->tcon; | 1095 | pTcon = cifs_sb->tcon; |
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); |