diff options
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 202 |
1 files changed, 168 insertions, 34 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 923d071163b2..05b525812adb 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 & |
@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
97 | inode = *pinode; | 97 | inode = *pinode; |
98 | cifsInfo = CIFS_I(inode); | 98 | cifsInfo = CIFS_I(inode); |
99 | 99 | ||
100 | cFYI(1, (" Old time %ld ", cifsInfo->time)); | 100 | cFYI(1, ("Old time %ld ", cifsInfo->time)); |
101 | cifsInfo->time = jiffies; | 101 | cifsInfo->time = jiffies; |
102 | cFYI(1, (" New time %ld ", cifsInfo->time)); | 102 | cFYI(1, ("New time %ld ", cifsInfo->time)); |
103 | /* this is ok to set on every inode revalidate */ | 103 | /* this is ok to set on every inode revalidate */ |
104 | atomic_set(&cifsInfo->inUse,1); | 104 | atomic_set(&cifsInfo->inUse,1); |
105 | 105 | ||
@@ -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); |
@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
155 | } | 162 | } |
156 | 163 | ||
157 | if (num_of_bytes < end_of_file) | 164 | if (num_of_bytes < end_of_file) |
158 | cFYI(1, ("allocation size less than end of file ")); | 165 | cFYI(1, ("allocation size less than end of file")); |
159 | cFYI(1, | 166 | cFYI(1, |
160 | ("Size %ld and blocks %ld", | 167 | ("Size %ld and blocks %ld", |
161 | (unsigned long) inode->i_size, inode->i_blocks)); | 168 | (unsigned long) inode->i_size, inode->i_blocks)); |
162 | if (S_ISREG(inode->i_mode)) { | 169 | if (S_ISREG(inode->i_mode)) { |
163 | cFYI(1, (" File inode ")); | 170 | cFYI(1, ("File inode")); |
164 | inode->i_op = &cifs_file_inode_ops; | 171 | inode->i_op = &cifs_file_inode_ops; |
165 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 172 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
166 | inode->i_fop = &cifs_file_direct_ops; | 173 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
167 | else | 174 | inode->i_fop = |
175 | &cifs_file_direct_nobrl_ops; | ||
176 | else | ||
177 | inode->i_fop = &cifs_file_direct_ops; | ||
178 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
179 | inode->i_fop = &cifs_file_nobrl_ops; | ||
180 | else /* not direct, send byte range locks */ | ||
168 | inode->i_fop = &cifs_file_ops; | 181 | inode->i_fop = &cifs_file_ops; |
169 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 182 | |
170 | inode->i_fop->lock = NULL; | ||
171 | inode->i_data.a_ops = &cifs_addr_ops; | 183 | inode->i_data.a_ops = &cifs_addr_ops; |
172 | /* check if server can support readpages */ | 184 | /* check if server can support readpages */ |
173 | if(pTcon->ses->server->maxBuf < | 185 | if(pTcon->ses->server->maxBuf < |
174 | 4096 + MAX_CIFS_HDR_SIZE) | 186 | 4096 + MAX_CIFS_HDR_SIZE) |
175 | inode->i_data.a_ops->readpages = NULL; | 187 | inode->i_data.a_ops->readpages = NULL; |
176 | } else if (S_ISDIR(inode->i_mode)) { | 188 | } else if (S_ISDIR(inode->i_mode)) { |
177 | cFYI(1, (" Directory inode")); | 189 | cFYI(1, ("Directory inode")); |
178 | inode->i_op = &cifs_dir_inode_ops; | 190 | inode->i_op = &cifs_dir_inode_ops; |
179 | inode->i_fop = &cifs_dir_ops; | 191 | inode->i_fop = &cifs_dir_ops; |
180 | } else if (S_ISLNK(inode->i_mode)) { | 192 | } else if (S_ISLNK(inode->i_mode)) { |
181 | cFYI(1, (" Symbolic Link inode ")); | 193 | cFYI(1, ("Symbolic Link inode")); |
182 | inode->i_op = &cifs_symlink_inode_ops; | 194 | inode->i_op = &cifs_symlink_inode_ops; |
183 | /* tmp_inode->i_fop = */ /* do not need to set to anything */ | 195 | /* tmp_inode->i_fop = */ /* do not need to set to anything */ |
184 | } else { | 196 | } else { |
185 | cFYI(1, (" Init special inode ")); | 197 | cFYI(1, ("Init special inode")); |
186 | init_special_inode(inode, inode->i_mode, | 198 | init_special_inode(inode, inode->i_mode, |
187 | inode->i_rdev); | 199 | inode->i_rdev); |
188 | } | 200 | } |
@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
190 | return rc; | 202 | return rc; |
191 | } | 203 | } |
192 | 204 | ||
205 | static int decode_sfu_inode(struct inode * inode, __u64 size, | ||
206 | const unsigned char *path, | ||
207 | struct cifs_sb_info *cifs_sb, int xid) | ||
208 | { | ||
209 | int rc; | ||
210 | int oplock = FALSE; | ||
211 | __u16 netfid; | ||
212 | struct cifsTconInfo *pTcon = cifs_sb->tcon; | ||
213 | char buf[24]; | ||
214 | unsigned int bytes_read; | ||
215 | char * pbuf; | ||
216 | |||
217 | pbuf = buf; | ||
218 | |||
219 | if(size == 0) { | ||
220 | inode->i_mode |= S_IFIFO; | ||
221 | return 0; | ||
222 | } else if (size < 8) { | ||
223 | return -EINVAL; /* EOPNOTSUPP? */ | ||
224 | } | ||
225 | |||
226 | rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, | ||
227 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | ||
228 | cifs_sb->local_nls, | ||
229 | cifs_sb->mnt_cifs_flags & | ||
230 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
231 | if (rc==0) { | ||
232 | /* Read header */ | ||
233 | rc = CIFSSMBRead(xid, pTcon, | ||
234 | netfid, | ||
235 | 24 /* length */, 0 /* offset */, | ||
236 | &bytes_read, &pbuf); | ||
237 | if((rc == 0) && (bytes_read >= 8)) { | ||
238 | if(memcmp("IntxBLK", pbuf, 8) == 0) { | ||
239 | cFYI(1,("Block device")); | ||
240 | inode->i_mode |= S_IFBLK; | ||
241 | if(bytes_read == 24) { | ||
242 | /* we have enough to decode dev num */ | ||
243 | __u64 mjr; /* major */ | ||
244 | __u64 mnr; /* minor */ | ||
245 | mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); | ||
246 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | ||
247 | inode->i_rdev = MKDEV(mjr, mnr); | ||
248 | } | ||
249 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { | ||
250 | cFYI(1,("Char device")); | ||
251 | inode->i_mode |= S_IFCHR; | ||
252 | if(bytes_read == 24) { | ||
253 | /* we have enough to decode dev num */ | ||
254 | __u64 mjr; /* major */ | ||
255 | __u64 mnr; /* minor */ | ||
256 | mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); | ||
257 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | ||
258 | inode->i_rdev = MKDEV(mjr, mnr); | ||
259 | } | ||
260 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { | ||
261 | cFYI(1,("Symlink")); | ||
262 | inode->i_mode |= S_IFLNK; | ||
263 | } else { | ||
264 | inode->i_mode |= S_IFREG; /* file? */ | ||
265 | rc = -EOPNOTSUPP; | ||
266 | } | ||
267 | } else { | ||
268 | inode->i_mode |= S_IFREG; /* then it is a file */ | ||
269 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | ||
270 | } | ||
271 | CIFSSMBClose(xid, pTcon, netfid); | ||
272 | } | ||
273 | return rc; | ||
274 | |||
275 | } | ||
276 | |||
277 | #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ | ||
278 | |||
279 | static int get_sfu_uid_mode(struct inode * inode, | ||
280 | const unsigned char *path, | ||
281 | struct cifs_sb_info *cifs_sb, int xid) | ||
282 | { | ||
283 | #ifdef CONFIG_CIFS_XATTR | ||
284 | ssize_t rc; | ||
285 | char ea_value[4]; | ||
286 | __u32 mode; | ||
287 | |||
288 | rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", | ||
289 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, | ||
290 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
291 | if(rc < 0) | ||
292 | return (int)rc; | ||
293 | else if (rc > 3) { | ||
294 | mode = le32_to_cpu(*((__le32 *)ea_value)); | ||
295 | inode->i_mode &= ~SFBITS_MASK; | ||
296 | cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode)); | ||
297 | inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; | ||
298 | cFYI(1,("special mode bits 0%o", mode)); | ||
299 | return 0; | ||
300 | } else { | ||
301 | return 0; | ||
302 | } | ||
303 | #else | ||
304 | return -EOPNOTSUPP; | ||
305 | #endif | ||
306 | |||
307 | |||
308 | } | ||
309 | |||
193 | int cifs_get_inode_info(struct inode **pinode, | 310 | int cifs_get_inode_info(struct inode **pinode, |
194 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, | 311 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, |
195 | struct super_block *sb, int xid) | 312 | struct super_block *sb, int xid) |
@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
202 | char *buf = NULL; | 319 | char *buf = NULL; |
203 | 320 | ||
204 | pTcon = cifs_sb->tcon; | 321 | pTcon = cifs_sb->tcon; |
205 | cFYI(1,("Getting info on %s ", search_path)); | 322 | cFYI(1,("Getting info on %s", search_path)); |
206 | 323 | ||
207 | if ((pfindData == NULL) && (*pinode != NULL)) { | 324 | if ((pfindData == NULL) && (*pinode != NULL)) { |
208 | if (CIFS_I(*pinode)->clientCanCacheRead) { | 325 | if (CIFS_I(*pinode)->clientCanCacheRead) { |
@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
303 | inode = *pinode; | 420 | inode = *pinode; |
304 | cifsInfo = CIFS_I(inode); | 421 | cifsInfo = CIFS_I(inode); |
305 | cifsInfo->cifsAttrs = attr; | 422 | cifsInfo->cifsAttrs = attr; |
306 | cFYI(1, (" Old time %ld ", cifsInfo->time)); | 423 | cFYI(1, ("Old time %ld ", cifsInfo->time)); |
307 | cifsInfo->time = jiffies; | 424 | cifsInfo->time = jiffies; |
308 | cFYI(1, (" New time %ld ", cifsInfo->time)); | 425 | cFYI(1, ("New time %ld ", cifsInfo->time)); |
309 | 426 | ||
310 | /* blksize needs to be multiple of two. So safer to default to | 427 | /* blksize needs to be multiple of two. So safer to default to |
311 | blksize and blkbits set in superblock so 2**blkbits and blksize | 428 | blksize and blkbits set in superblock so 2**blkbits and blksize |
@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode, | |||
319 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 436 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); |
320 | inode->i_ctime = | 437 | inode->i_ctime = |
321 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 438 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
322 | cFYI(0, (" Attributes came in as 0x%x ", attr)); | 439 | cFYI(0, ("Attributes came in as 0x%x ", attr)); |
323 | 440 | ||
324 | /* set default mode. will override for dirs below */ | 441 | /* set default mode. will override for dirs below */ |
325 | if (atomic_read(&cifsInfo->inUse) == 0) | 442 | if (atomic_read(&cifsInfo->inUse) == 0) |
326 | /* new inode, can safely set these fields */ | 443 | /* new inode, can safely set these fields */ |
327 | inode->i_mode = cifs_sb->mnt_file_mode; | 444 | inode->i_mode = cifs_sb->mnt_file_mode; |
328 | 445 | else /* since we set the inode type below we need to mask off | |
446 | to avoid strange results if type changes and both get orred in */ | ||
447 | inode->i_mode &= ~S_IFMT; | ||
329 | /* if (attr & ATTR_REPARSE) */ | 448 | /* if (attr & ATTR_REPARSE) */ |
330 | /* We no longer handle these as symlinks because we could not | 449 | /* We no longer handle these as symlinks because we could not |
331 | follow them due to the absolute path with drive letter */ | 450 | follow them due to the absolute path with drive letter */ |
@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode, | |||
340 | (pfindData->EndOfFile == 0)) { | 459 | (pfindData->EndOfFile == 0)) { |
341 | inode->i_mode = cifs_sb->mnt_file_mode; | 460 | inode->i_mode = cifs_sb->mnt_file_mode; |
342 | inode->i_mode |= S_IFIFO; | 461 | inode->i_mode |= S_IFIFO; |
343 | /* BB Finish for SFU style symlinks and devies */ | 462 | /* BB Finish for SFU style symlinks and devices */ |
344 | /* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && | 463 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && |
345 | (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ | 464 | (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { |
346 | 465 | if (decode_sfu_inode(inode, | |
466 | le64_to_cpu(pfindData->EndOfFile), | ||
467 | search_path, | ||
468 | cifs_sb, xid)) { | ||
469 | cFYI(1,("Unrecognized sfu inode type")); | ||
470 | } | ||
471 | cFYI(1,("sfu mode 0%o",inode->i_mode)); | ||
347 | } else { | 472 | } else { |
348 | inode->i_mode |= S_IFREG; | 473 | inode->i_mode |= S_IFREG; |
349 | /* treat the dos attribute of read-only as read-only | 474 | /* treat the dos attribute of read-only as read-only |
@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode, | |||
368 | 493 | ||
369 | /* BB fill in uid and gid here? with help from winbind? | 494 | /* BB fill in uid and gid here? with help from winbind? |
370 | or retrieve from NTFS stream extended attribute */ | 495 | or retrieve from NTFS stream extended attribute */ |
371 | if (atomic_read(&cifsInfo->inUse) == 0) { | 496 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
497 | /* fill in uid, gid, mode from server ACL */ | ||
498 | get_sfu_uid_mode(inode, search_path, cifs_sb, xid); | ||
499 | } else if (atomic_read(&cifsInfo->inUse) == 0) { | ||
372 | inode->i_uid = cifs_sb->mnt_uid; | 500 | inode->i_uid = cifs_sb->mnt_uid; |
373 | inode->i_gid = cifs_sb->mnt_gid; | 501 | inode->i_gid = cifs_sb->mnt_gid; |
374 | /* set so we do not keep refreshing these fields with | 502 | /* set so we do not keep refreshing these fields with |
@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode, | |||
377 | } | 505 | } |
378 | 506 | ||
379 | if (S_ISREG(inode->i_mode)) { | 507 | if (S_ISREG(inode->i_mode)) { |
380 | cFYI(1, (" File inode ")); | 508 | cFYI(1, ("File inode")); |
381 | inode->i_op = &cifs_file_inode_ops; | 509 | inode->i_op = &cifs_file_inode_ops; |
382 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 510 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
383 | inode->i_fop = &cifs_file_direct_ops; | 511 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
384 | else | 512 | inode->i_fop = |
513 | &cifs_file_direct_nobrl_ops; | ||
514 | else | ||
515 | inode->i_fop = &cifs_file_direct_ops; | ||
516 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
517 | inode->i_fop = &cifs_file_nobrl_ops; | ||
518 | else /* not direct, send byte range locks */ | ||
385 | inode->i_fop = &cifs_file_ops; | 519 | inode->i_fop = &cifs_file_ops; |
386 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 520 | |
387 | inode->i_fop->lock = NULL; | ||
388 | inode->i_data.a_ops = &cifs_addr_ops; | 521 | inode->i_data.a_ops = &cifs_addr_ops; |
389 | if(pTcon->ses->server->maxBuf < | 522 | if(pTcon->ses->server->maxBuf < |
390 | 4096 + MAX_CIFS_HDR_SIZE) | 523 | 4096 + MAX_CIFS_HDR_SIZE) |
391 | inode->i_data.a_ops->readpages = NULL; | 524 | inode->i_data.a_ops->readpages = NULL; |
392 | } else if (S_ISDIR(inode->i_mode)) { | 525 | } else if (S_ISDIR(inode->i_mode)) { |
393 | cFYI(1, (" Directory inode ")); | 526 | cFYI(1, ("Directory inode")); |
394 | inode->i_op = &cifs_dir_inode_ops; | 527 | inode->i_op = &cifs_dir_inode_ops; |
395 | inode->i_fop = &cifs_dir_ops; | 528 | inode->i_fop = &cifs_dir_ops; |
396 | } else if (S_ISLNK(inode->i_mode)) { | 529 | } else if (S_ISLNK(inode->i_mode)) { |
397 | cFYI(1, (" Symbolic Link inode ")); | 530 | cFYI(1, ("Symbolic Link inode")); |
398 | inode->i_op = &cifs_symlink_inode_ops; | 531 | inode->i_op = &cifs_symlink_inode_ops; |
399 | } else { | 532 | } else { |
400 | init_special_inode(inode, inode->i_mode, | 533 | init_special_inode(inode, inode->i_mode, |
@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
431 | struct cifsInodeInfo *cifsInode; | 564 | struct cifsInodeInfo *cifsInode; |
432 | FILE_BASIC_INFO *pinfo_buf; | 565 | FILE_BASIC_INFO *pinfo_buf; |
433 | 566 | ||
434 | cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); | 567 | cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode)); |
435 | 568 | ||
436 | xid = GetXid(); | 569 | xid = GetXid(); |
437 | 570 | ||
@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
651 | char *full_path = NULL; | 784 | char *full_path = NULL; |
652 | struct cifsInodeInfo *cifsInode; | 785 | struct cifsInodeInfo *cifsInode; |
653 | 786 | ||
654 | cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); | 787 | cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode)); |
655 | 788 | ||
656 | xid = GetXid(); | 789 | xid = GetXid(); |
657 | 790 | ||
@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
970 | 1103 | ||
971 | xid = GetXid(); | 1104 | xid = GetXid(); |
972 | 1105 | ||
973 | cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", | 1106 | cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ", |
974 | direntry->d_name.name, attrs->ia_valid)); | 1107 | direntry->d_name.name, attrs->ia_valid)); |
975 | cifs_sb = CIFS_SB(direntry->d_inode->i_sb); | 1108 | cifs_sb = CIFS_SB(direntry->d_inode->i_sb); |
976 | pTcon = cifs_sb->tcon; | 1109 | pTcon = cifs_sb->tcon; |
@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1086 | cifs_sb->mnt_cifs_flags & | 1219 | cifs_sb->mnt_cifs_flags & |
1087 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1220 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1088 | else if (attrs->ia_valid & ATTR_MODE) { | 1221 | else if (attrs->ia_valid & ATTR_MODE) { |
1222 | rc = 0; | ||
1089 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | 1223 | if ((mode & S_IWUGO) == 0) /* not writeable */ { |
1090 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) | 1224 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) |
1091 | time_buf.Attributes = | 1225 | time_buf.Attributes = |